Import performous_0.7.0+git20140715.orig.tar.xz
authorMarkus Koschany <apo@gambaru.de>
Tue, 15 Jul 2014 14:42:04 +0000 (15:42 +0100)
committerMarkus Koschany <apo@gambaru.de>
Tue, 15 Jul 2014 14:42:04 +0000 (15:42 +0100)
[dgit import orig performous_0.7.0+git20140715.orig.tar.xz]

443 files changed:
.gitignore [new file with mode: 0644]
CMakeLists.txt [new file with mode: 0644]
README.txt [new file with mode: 0644]
cmake/Modules/FindALSA.cmake [new file with mode: 0644]
cmake/Modules/FindAVCodec.cmake [new file with mode: 0644]
cmake/Modules/FindAVFormat.cmake [new file with mode: 0644]
cmake/Modules/FindAVResample.cmake [new file with mode: 0644]
cmake/Modules/FindAVUtil.cmake [new file with mode: 0644]
cmake/Modules/FindAtk.cmake [new file with mode: 0644]
cmake/Modules/FindAtkmm.cmake [new file with mode: 0644]
cmake/Modules/FindCairo.cmake [new file with mode: 0644]
cmake/Modules/FindCairomm.cmake [new file with mode: 0644]
cmake/Modules/FindClanLib.cmake [new file with mode: 0644]
cmake/Modules/FindDL.cmake [new file with mode: 0644]
cmake/Modules/FindFAAC.cmake [new file with mode: 0644]
cmake/Modules/FindFontconfig.cmake [new file with mode: 0644]
cmake/Modules/FindFreetype.cmake [new file with mode: 0644]
cmake/Modules/FindGDK-PixBuf.cmake [new file with mode: 0644]
cmake/Modules/FindGDK.cmake [new file with mode: 0644]
cmake/Modules/FindGDKmm.cmake [new file with mode: 0644]
cmake/Modules/FindGIO.cmake [new file with mode: 0644]
cmake/Modules/FindGIOmm.cmake [new file with mode: 0644]
cmake/Modules/FindGLEW.cmake [new file with mode: 0644]
cmake/Modules/FindGLFW.cmake [new file with mode: 0644]
cmake/Modules/FindGObject.cmake [new file with mode: 0644]
cmake/Modules/FindGStreamer.cmake [new file with mode: 0644]
cmake/Modules/FindGTK.cmake [new file with mode: 0644]
cmake/Modules/FindGTKmm.cmake [new file with mode: 0644]
cmake/Modules/FindGettext.cmake [new file with mode: 0644]
cmake/Modules/FindGlib.cmake [new file with mode: 0644]
cmake/Modules/FindGlibmm.cmake [new file with mode: 0644]
cmake/Modules/FindJack.cmake [new file with mode: 0644]
cmake/Modules/FindJpeg.cmake [new file with mode: 0644]
cmake/Modules/FindLibPulse.cmake [new file with mode: 0644]
cmake/Modules/FindLibPulseSimple.cmake [new file with mode: 0644]
cmake/Modules/FindLibRSVG.cmake [new file with mode: 0644]
cmake/Modules/FindLibXML++.cmake [new file with mode: 0644]
cmake/Modules/FindLibXML2.cmake [new file with mode: 0644]
cmake/Modules/FindMagick++.cmake [new file with mode: 0644]
cmake/Modules/FindMagick.cmake [new file with mode: 0644]
cmake/Modules/FindMsgfmt.cmake [new file with mode: 0644]
cmake/Modules/FindOpenGL.cmake [new file with mode: 0644]
cmake/Modules/FindPThread.cmake [new file with mode: 0644]
cmake/Modules/FindPango.cmake [new file with mode: 0644]
cmake/Modules/FindPangoCairo.cmake [new file with mode: 0644]
cmake/Modules/FindPangomm.cmake [new file with mode: 0644]
cmake/Modules/FindPng.cmake [new file with mode: 0644]
cmake/Modules/FindPortAudio.cmake [new file with mode: 0644]
cmake/Modules/FindPortMidi.cmake [new file with mode: 0644]
cmake/Modules/FindProjectM.cmake [new file with mode: 0644]
cmake/Modules/FindSDL.cmake [new file with mode: 0644]
cmake/Modules/FindSDL2.cmake [new file with mode: 0644]
cmake/Modules/FindSDL_image.cmake [new file with mode: 0644]
cmake/Modules/FindSDL_mixer.cmake [new file with mode: 0644]
cmake/Modules/FindSWScale.cmake [new file with mode: 0644]
cmake/Modules/FindSigC++.cmake [new file with mode: 0644]
cmake/Modules/FindTiff.cmake [new file with mode: 0644]
cmake/Modules/FindZ.cmake [new file with mode: 0644]
cmake/Modules/LibFindMacros.cmake [new file with mode: 0644]
cmake/performous.sh.cmake [new file with mode: 0644]
data/CMakeLists.txt [new file with mode: 0644]
data/backgrounds/blue_band.svg [new file with mode: 0644]
data/backgrounds/classic_bg.svg [new file with mode: 0644]
data/backgrounds/default_bg.svg [new file with mode: 0644]
data/backgrounds/flying_notes.svg [new file with mode: 0644]
data/backgrounds/guitar_bg.svg [new file with mode: 0644]
data/backgrounds/singer_bg.svg [new file with mode: 0644]
data/config/controllers.xml [new file with mode: 0644]
data/config/schema.xml [new file with mode: 0644]
data/database.xml [new file with mode: 0644]
data/fonts/GoblinOne.otf [new file with mode: 0644]
data/fonts/NewRocker-Regular.otf [new file with mode: 0644]
data/performous.desktop [new file with mode: 0755]
data/shaders/core.frag [new file with mode: 0644]
data/shaders/core.vert [new file with mode: 0644]
data/shaders/dancenote.vert [new file with mode: 0644]
data/shaders/stereo3d.geom [new file with mode: 0644]
data/sounds/drum_bass.ogg [new file with mode: 0644]
data/sounds/drum_cymbal.ogg [new file with mode: 0644]
data/sounds/drum_hi-hat.ogg [new file with mode: 0644]
data/sounds/drum_snare.ogg [new file with mode: 0644]
data/sounds/drum_tom1.ogg [new file with mode: 0644]
data/sounds/drum_tom2.ogg [new file with mode: 0644]
data/sounds/guitar_fail1.ogg [new file with mode: 0644]
data/sounds/guitar_fail2.ogg [new file with mode: 0644]
data/sounds/guitar_fail3.ogg [new file with mode: 0644]
data/sounds/guitar_fail4.ogg [new file with mode: 0644]
data/sounds/guitar_fail5.ogg [new file with mode: 0644]
data/sounds/guitar_fail6.ogg [new file with mode: 0644]
data/themes/default/arrow_button_down.svg [new file with mode: 0644]
data/themes/default/arrow_button_left.svg [new file with mode: 0644]
data/themes/default/arrow_button_right.svg [new file with mode: 0644]
data/themes/default/arrow_button_up.svg [new file with mode: 0644]
data/themes/default/arrows.svg [new file with mode: 0644]
data/themes/default/arrows_cursor.svg [new file with mode: 0644]
data/themes/default/arrows_hold.svg [new file with mode: 0644]
data/themes/default/audiodevices_bg.svg [new file with mode: 0644]
data/themes/default/audiodevices_dev_bg.svg [new file with mode: 0644]
data/themes/default/band_cover.svg [new file with mode: 0644]
data/themes/default/bassneck.svg [new file with mode: 0644]
data/themes/default/button.svg [new file with mode: 0644]
data/themes/default/dance_cover.svg [new file with mode: 0644]
data/themes/default/dancebeat.svg [new file with mode: 0644]
data/themes/default/device_selector.svg [new file with mode: 0644]
data/themes/default/dialog_txt.svg [new file with mode: 0644]
data/themes/default/drumneck.svg [new file with mode: 0644]
data/themes/default/flame.svg [new file with mode: 0644]
data/themes/default/flame_godmode.svg [new file with mode: 0644]
data/themes/default/fret.obj [new file with mode: 0644]
data/themes/default/fret_tap.obj [new file with mode: 0644]
data/themes/default/guitarneck.svg [new file with mode: 0644]
data/themes/default/icon.bmp [new file with mode: 0644]
data/themes/default/icon.png [new file with mode: 0644]
data/themes/default/icon.svg [new file with mode: 0644]
data/themes/default/icon_pdev.svg [new file with mode: 0644]
data/themes/default/instrument_cover.svg [new file with mode: 0644]
data/themes/default/instrumenthelp.svg [new file with mode: 0644]
data/themes/default/instrumentmenu_back_highlight.svg [new file with mode: 0644]
data/themes/default/instrumentmenu_bg.svg [new file with mode: 0644]
data/themes/default/instrumentmenu_comment.svg [new file with mode: 0644]
data/themes/default/instrumentmenu_option.svg [new file with mode: 0644]
data/themes/default/instrumentmenu_option_selected.svg [new file with mode: 0644]
data/themes/default/instruments.svg [new file with mode: 0644]
data/themes/default/intro_bg.svg [new file with mode: 0644]
data/themes/default/intro_configure.svg [new file with mode: 0644]
data/themes/default/intro_practice.svg [new file with mode: 0644]
data/themes/default/intro_quit.svg [new file with mode: 0644]
data/themes/default/intro_sing.svg [new file with mode: 0644]
data/themes/default/logo.svg [new file with mode: 0644]
data/themes/default/mainmenu_back_highlight.svg [new file with mode: 0644]
data/themes/default/mainmenu_comment.svg [new file with mode: 0644]
data/themes/default/mainmenu_comment_bg.svg [new file with mode: 0644]
data/themes/default/mainmenu_option.svg [new file with mode: 0644]
data/themes/default/mainmenu_option_selected.svg [new file with mode: 0644]
data/themes/default/mainmenu_scomment_bg.svg [new file with mode: 0644]
data/themes/default/mainmenu_short_comment.svg [new file with mode: 0644]
data/themes/default/menu.ogg [new file with mode: 0644]
data/themes/default/message_text.svg [new file with mode: 0644]
data/themes/default/mine.svg [new file with mode: 0644]
data/themes/default/neck_glow.svg [new file with mode: 0644]
data/themes/default/no_cover.svg [new file with mode: 0644]
data/themes/default/no_player_image.svg [new file with mode: 0644]
data/themes/default/notebar.png [new file with mode: 0644]
data/themes/default/notebar.svg [new file with mode: 0644]
data/themes/default/notebar_hi.svg [new file with mode: 0644]
data/themes/default/notebarfs-hl.png [new file with mode: 0644]
data/themes/default/notebarfs.svg [new file with mode: 0644]
data/themes/default/notebargold.png [new file with mode: 0644]
data/themes/default/notebargold.svg [new file with mode: 0644]
data/themes/default/notebargold_hi.svg [new file with mode: 0644]
data/themes/default/notelines.svg [new file with mode: 0644]
data/themes/default/practice.ogg [new file with mode: 0644]
data/themes/default/practice_bg.svg [new file with mode: 0644]
data/themes/default/practice_note.svg [new file with mode: 0644]
data/themes/default/practice_peak.svg [new file with mode: 0644]
data/themes/default/practice_sharp.svg [new file with mode: 0644]
data/themes/default/practice_txt.svg [new file with mode: 0644]
data/themes/default/score_bar_bg.svg [new file with mode: 0644]
data/themes/default/score_bar_fg.svg [new file with mode: 0644]
data/themes/default/score_level.svg [new file with mode: 0644]
data/themes/default/score_rank.svg [new file with mode: 0644]
data/themes/default/score_txt.svg [new file with mode: 0644]
data/themes/default/score_window.svg [new file with mode: 0644]
data/themes/default/sing-songinfo.svg [new file with mode: 0644]
data/themes/default/sing_bg_bottom.svg [new file with mode: 0644]
data/themes/default/sing_bg_top.svg [new file with mode: 0644]
data/themes/default/sing_lyricscurrent.svg [new file with mode: 0644]
data/themes/default/sing_lyricshighlight.svg [new file with mode: 0644]
data/themes/default/sing_lyricsnext.svg [new file with mode: 0644]
data/themes/default/sing_pause.svg [new file with mode: 0644]
data/themes/default/sing_pbox.svg [new file with mode: 0644]
data/themes/default/sing_popup_text.svg [new file with mode: 0644]
data/themes/default/sing_progressbg.svg [new file with mode: 0644]
data/themes/default/sing_progressfg.svg [new file with mode: 0644]
data/themes/default/sing_score_text.svg [new file with mode: 0644]
data/themes/default/sing_timetxt.svg [new file with mode: 0644]
data/themes/default/sing_tostartfg.svg [new file with mode: 0644]
data/themes/default/songs_bg.svg [new file with mode: 0644]
data/themes/default/songs_bg_default.svg [new file with mode: 0644]
data/themes/default/songs_bg_ground.svg [new file with mode: 0644]
data/themes/default/songs_has_hiscore.svg [new file with mode: 0644]
data/themes/default/songs_hiscores.svg [new file with mode: 0644]
data/themes/default/songs_order.svg [new file with mode: 0644]
data/themes/default/songs_song.svg [new file with mode: 0644]
data/themes/default/star.svg [new file with mode: 0644]
data/themes/default/star_glow.svg [new file with mode: 0644]
data/themes/default/tail.svg [new file with mode: 0644]
data/themes/default/tail_drumfill.svg [new file with mode: 0644]
data/themes/default/tail_glow.svg [new file with mode: 0644]
data/themes/default/tap.svg [new file with mode: 0644]
data/themes/default/vumeter_bg.svg [new file with mode: 0644]
data/themes/default/vumeter_fg.svg [new file with mode: 0644]
data/themes/default/warning.svg [new file with mode: 0644]
data/themes/default/wave.png [new file with mode: 0644]
data/xsl/songlist-to-tex.xsl [new file with mode: 0644]
data/xsl/songlist-to-xhtml.xsl [new file with mode: 0644]
docs/Authors.txt [new file with mode: 0644]
docs/CMakeLists.txt [new file with mode: 0644]
docs/Compiling.txt [new file with mode: 0644]
docs/doxygen.config [new file with mode: 0644]
docs/instruments.txt [new file with mode: 0644]
docs/license/Performous.txt [new file with mode: 0644]
docs/license/SIL OFL Font License New Rocker.txt [new file with mode: 0644]
docs/license/SIL OFL Goblin.txt [new file with mode: 0644]
docs/man/CMakeLists.txt [new file with mode: 0644]
docs/man/gh_fsb_decrypt.1 [new file with mode: 0644]
docs/man/gh_xen_decrypt.1 [new file with mode: 0644]
docs/man/performous.h2m [new file with mode: 0644]
docs/man/ss_adpcm_decode.1 [new file with mode: 0644]
docs/man/ss_chc_decode.1 [new file with mode: 0644]
docs/man/ss_cover_conv.1 [new file with mode: 0644]
docs/man/ss_extract.1 [new file with mode: 0644]
docs/man/ss_ipu_conv.1 [new file with mode: 0644]
docs/man/ss_pak_extract.1 [new file with mode: 0644]
game/3dobject.cc [new file with mode: 0644]
game/3dobject.hh [new file with mode: 0644]
game/CMakeLists.txt [new file with mode: 0644]
game/animvalue.hh [new file with mode: 0644]
game/audio.cc [new file with mode: 0644]
game/audio.hh [new file with mode: 0644]
game/backgrounds.cc [new file with mode: 0644]
game/backgrounds.hh [new file with mode: 0644]
game/cache.cc [new file with mode: 0644]
game/cache.hh [new file with mode: 0644]
game/cachemap.hh [new file with mode: 0644]
game/color.cc [new file with mode: 0644]
game/color.hh [new file with mode: 0644]
game/config.cmake.hh [new file with mode: 0644]
game/configuration.cc [new file with mode: 0644]
game/configuration.hh [new file with mode: 0644]
game/controllers-buttons.ii [new file with mode: 0644]
game/controllers-joystick.cc [new file with mode: 0644]
game/controllers-keyboard.cc [new file with mode: 0644]
game/controllers-midi.cc [new file with mode: 0644]
game/controllers.cc [new file with mode: 0644]
game/controllers.hh [new file with mode: 0644]
game/dancegraph.cc [new file with mode: 0644]
game/dancegraph.hh [new file with mode: 0644]
game/database.cc [new file with mode: 0644]
game/database.hh [new file with mode: 0644]
game/dialog.hh [new file with mode: 0644]
game/engine.cc [new file with mode: 0644]
game/engine.hh [new file with mode: 0644]
game/execname.cc [new file with mode: 0644]
game/execname.hh [new file with mode: 0644]
game/fbo.hh [new file with mode: 0644]
game/ffmpeg.cc [new file with mode: 0644]
game/ffmpeg.hh [new file with mode: 0644]
game/fs.cc [new file with mode: 0644]
game/fs.hh [new file with mode: 0644]
game/game.cc [new file with mode: 0644]
game/glmath.hh [new file with mode: 0644]
game/glshader.cc [new file with mode: 0644]
game/glshader.hh [new file with mode: 0644]
game/glutil.cc [new file with mode: 0644]
game/glutil.hh [new file with mode: 0644]
game/guitargraph.cc [new file with mode: 0644]
game/guitargraph.hh [new file with mode: 0644]
game/hiscore.cc [new file with mode: 0644]
game/hiscore.hh [new file with mode: 0644]
game/i18n.hh [new file with mode: 0644]
game/image.cc [new file with mode: 0644]
game/image.hh [new file with mode: 0644]
game/instrumentgraph.cc [new file with mode: 0644]
game/instrumentgraph.hh [new file with mode: 0644]
game/layout_singer.cc [new file with mode: 0644]
game/layout_singer.hh [new file with mode: 0644]
game/libda/fft.hpp [new file with mode: 0644]
game/libda/mixer.hpp [new file with mode: 0644]
game/libda/portaudio.hpp [new file with mode: 0644]
game/libda/sample.hpp [new file with mode: 0644]
game/log.cc [new file with mode: 0644]
game/log.hh [new file with mode: 0644]
game/main.cc [new file with mode: 0644]
game/menu.cc [new file with mode: 0644]
game/menu.hh [new file with mode: 0644]
game/midifile.cc [new file with mode: 0644]
game/midifile.hh [new file with mode: 0644]
game/musicalscale.cc [new file with mode: 0644]
game/musicalscale.hh [new file with mode: 0644]
game/notegraph.cc [new file with mode: 0644]
game/notegraph.hh [new file with mode: 0644]
game/notes.cc [new file with mode: 0644]
game/notes.hh [new file with mode: 0644]
game/opengl_text.cc [new file with mode: 0644]
game/opengl_text.hh [new file with mode: 0644]
game/osx/SDLMain.h [new file with mode: 0644]
game/osx/SDLMain.m [new file with mode: 0644]
game/pitch.cc [new file with mode: 0644]
game/pitch.hh [new file with mode: 0644]
game/player.cc [new file with mode: 0644]
game/player.hh [new file with mode: 0644]
game/players.cc [new file with mode: 0644]
game/players.hh [new file with mode: 0644]
game/playlist.cc [new file with mode: 0644]
game/playlist.hh [new file with mode: 0644]
game/portmidi.hh [new file with mode: 0644]
game/profiler.hh [new file with mode: 0644]
game/progressbar.cc [new file with mode: 0644]
game/progressbar.hh [new file with mode: 0644]
game/screen.hh [new file with mode: 0644]
game/screen_audiodevices.cc [new file with mode: 0644]
game/screen_audiodevices.hh [new file with mode: 0644]
game/screen_intro.cc [new file with mode: 0644]
game/screen_intro.hh [new file with mode: 0644]
game/screen_paths.cc [new file with mode: 0644]
game/screen_paths.hh [new file with mode: 0644]
game/screen_players.cc [new file with mode: 0644]
game/screen_players.hh [new file with mode: 0644]
game/screen_playlist.cc [new file with mode: 0644]
game/screen_playlist.hh [new file with mode: 0644]
game/screen_practice.cc [new file with mode: 0644]
game/screen_practice.hh [new file with mode: 0644]
game/screen_sing.cc [new file with mode: 0644]
game/screen_sing.hh [new file with mode: 0644]
game/screen_songs.cc [new file with mode: 0644]
game/screen_songs.hh [new file with mode: 0644]
game/singleton.hh [new file with mode: 0644]
game/song.cc [new file with mode: 0644]
game/song.hh [new file with mode: 0644]
game/songitems.cc [new file with mode: 0644]
game/songitems.hh [new file with mode: 0644]
game/songparser-ini.cc [new file with mode: 0644]
game/songparser-mid.cc [new file with mode: 0644]
game/songparser-sm.cc [new file with mode: 0644]
game/songparser-txt.cc [new file with mode: 0644]
game/songparser-xml.cc [new file with mode: 0644]
game/songparser.cc [new file with mode: 0644]
game/songparser.hh [new file with mode: 0644]
game/songs.cc [new file with mode: 0644]
game/songs.hh [new file with mode: 0644]
game/surface.cc [new file with mode: 0644]
game/surface.hh [new file with mode: 0644]
game/textinput.hh [new file with mode: 0644]
game/theme.cc [new file with mode: 0644]
game/theme.hh [new file with mode: 0644]
game/unicode.cc [new file with mode: 0644]
game/unicode.hh [new file with mode: 0644]
game/util.cc [new file with mode: 0644]
game/util.hh [new file with mode: 0644]
game/video.cc [new file with mode: 0644]
game/video.hh [new file with mode: 0644]
game/video_driver.cc [new file with mode: 0644]
game/video_driver.hh [new file with mode: 0644]
game/webcam.cc [new file with mode: 0644]
game/webcam.hh [new file with mode: 0644]
game/xtime.hh [new file with mode: 0644]
lang/CMakeLists.txt [new file with mode: 0644]
lang/README [new file with mode: 0644]
lang/TRANSLATORS [new file with mode: 0644]
lang/ast.po [new file with mode: 0644]
lang/da.po [new file with mode: 0644]
lang/de.po [new file with mode: 0644]
lang/es.po [new file with mode: 0644]
lang/fa.po [new file with mode: 0644]
lang/fi.po [new file with mode: 0644]
lang/fr.po [new file with mode: 0644]
lang/hu.po [new file with mode: 0644]
lang/it.po [new file with mode: 0644]
lang/ja.po [new file with mode: 0644]
lang/nl.po [new file with mode: 0644]
lang/performous.pot [new file with mode: 0644]
lang/pl.po [new file with mode: 0644]
lang/pt_BR.po [new file with mode: 0644]
lang/sv.po [new file with mode: 0644]
lang/zh.po [new file with mode: 0644]
osx-utils/CMakeCache.txt [new file with mode: 0644]
osx-utils/CMakeFiles/cmake.check_cache [new file with mode: 0644]
osx-utils/performous-app-build.sh [new file with mode: 0755]
osx-utils/performous.icns [new file with mode: 0644]
osx-utils/resources/Info.plist [new file with mode: 0644]
osx-utils/resources/performous-launcher [new file with mode: 0755]
osx-utils/resources/performous.icns [new file with mode: 0644]
portage-overlay/games-arcade/performous/files/performous-gentoopaths.patch [new file with mode: 0644]
portage-overlay/games-arcade/performous/performous-0.4.0.ebuild [new file with mode: 0644]
portage-overlay/games-arcade/performous/performous-0.5.1.ebuild [new file with mode: 0644]
portage-overlay/games-arcade/performous/performous-0.6.0.ebuild [new file with mode: 0644]
portage-overlay/games-arcade/performous/performous-0.7.0.ebuild [new file with mode: 0644]
portage-overlay/games-arcade/performous/performous-9999.ebuild [new file with mode: 0644]
portage-overlay/games-util/eof/eof-1.65.ebuild [new file with mode: 0644]
portage-overlay/games-util/eof/eof-9999.ebuild [new file with mode: 0644]
portage-overlay/games-util/foflc/foflc-9999.ebuild [new file with mode: 0644]
tools/CMakeLists.txt [new file with mode: 0644]
tools/adpcm.h [new file with mode: 0644]
tools/adpcm_decode.cc [new file with mode: 0644]
tools/adpcm_play.cc [new file with mode: 0644]
tools/archive_extract.cc [new file with mode: 0644]
tools/bitfiles.h [new file with mode: 0644]
tools/chc_decode.hh [new file with mode: 0644]
tools/cover_conv.cc [new file with mode: 0644]
tools/gh_fsb/fsb.h [new file with mode: 0644]
tools/gh_fsb/fsbext.c [new file with mode: 0644]
tools/gh_fsb/mywav.h [new file with mode: 0644]
tools/gh_fsb/show_dump.h [new file with mode: 0644]
tools/gh_fsb/xma_header.h [new file with mode: 0644]
tools/gh_xen_decrypt.cc [new file with mode: 0644]
tools/ipu_conv.cc [new file with mode: 0644]
tools/ipuconv.hh [new file with mode: 0644]
tools/ipuconvmain.cc [new file with mode: 0644]
tools/itg_pck.cc [new file with mode: 0644]
tools/pak.cc [new file with mode: 0644]
tools/pak.h [new file with mode: 0644]
tools/pak_extract.cc [new file with mode: 0644]
tools/ppa/control.patch [new file with mode: 0644]
tools/ppa/ppa.sh [new file with mode: 0755]
tools/ppa/ppastats.py [new file with mode: 0755]
tools/scripts/create-archive.sh [new file with mode: 0755]
tools/scripts/fix-songfiles.sh [new file with mode: 0755]
tools/scripts/setvocals.sh [new file with mode: 0644]
tools/scripts/setvocals_recursively.sh [new file with mode: 0644]
tools/scripts/translation_wiki_helper.sh [new file with mode: 0755]
tools/scripts/txts2duet [new file with mode: 0755]
tools/scripts/usdb.sh [new file with mode: 0755]
tools/scripts/xml_gettext.sh [new file with mode: 0755]
tools/ss_binary.hh [new file with mode: 0644]
tools/ss_chc_decode.cc [new file with mode: 0644]
tools/ss_cover.cc [new file with mode: 0644]
tools/ss_cover.hh [new file with mode: 0644]
tools/ss_extract.cc [new file with mode: 0644]
tools/ss_helpers.hh [new file with mode: 0644]
win32/ConfigureSongDirectory.bat [new file with mode: 0755]
win32/cross-from-debian/.gitignore [new file with mode: 0644]
win32/cross-from-debian/README [new file with mode: 0644]
win32/cross-from-debian/Toolchain.cmake [new file with mode: 0644]
win32/cross-from-debian/copydlls.py [new file with mode: 0755]
win32/cross-from-debian/makebuilddir.sh [new file with mode: 0755]
win32/cross-from-debian/makedeps.sh [new file with mode: 0755]
win32/cross-from-debian/makepackage.py [new file with mode: 0755]
win32/gcc/README [new file with mode: 0644]
win32/gcc/gettext-0.17-variables.patch [new file with mode: 0644]
win32/gcc/install.sh [new file with mode: 0644]
win32/gcc/mingw-cwchar.patch [new file with mode: 0644]
win32/gcc/mingw-libstdc++.patch [new file with mode: 0644]
win32/gcc/portaudio.patch [new file with mode: 0644]
win32/msvc/fontconfig-cmake.patch [new file with mode: 0644]
win32/msvc/install-msvc.sh [new file with mode: 0644]
win32/mxe/.gitignore [new file with mode: 0644]
win32/mxe/copydlls.py [new file with mode: 0755]
win32/mxe/libs.sh [new file with mode: 0755]
win32/mxe/make-installer.py [new file with mode: 0755]
win32/mxe/make-performous.sh [new file with mode: 0755]
win32/performous.cmake.rc [new file with mode: 0644]
win32/performous.ico [new file with mode: 0644]

diff --git a/.gitignore b/.gitignore
new file mode 100644 (file)
index 0000000..37d1104
--- /dev/null
@@ -0,0 +1,10 @@
+build
+build32
+build64
+CMakeLists.txt.user*
+
+#dummy files you may create when translating
+*~
+*.mo
+dylibbundler.log
+performous-app-build.sh
diff --git a/CMakeLists.txt b/CMakeLists.txt
new file mode 100644 (file)
index 0000000..42e5b41
--- /dev/null
@@ -0,0 +1,79 @@
+cmake_minimum_required(VERSION 2.8)
+project(Performous CXX C)
+set(PROJECT_VERSION "0.8")
+set(BUILD_SHARED_LIBS OFF)
+
+# Avoid source tree pollution
+if(CMAKE_SOURCE_DIR STREQUAL CMAKE_BINARY_DIR)
+       message(FATAL_ERROR "In-source builds are not permitted. Make a separate folder for building:\nmkdir build; cd build; cmake ..\nBefore that, remove the files already created:\nrm -rf CMakeCache.txt CMakeFiles")
+endif(CMAKE_SOURCE_DIR STREQUAL CMAKE_BINARY_DIR)
+
+set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/cmake/Modules/")
+
+# Add a sensible build type default and warning because empty means no optimization and no debug info.
+if(NOT CMAKE_BUILD_TYPE)
+       message("WARNING: CMAKE_BUILD_TYPE is not defined!\n         Defaulting to CMAKE_BUILD_TYPE=RelWithDebInfo. Use ccmake to set a proper value.")
+       SET(CMAKE_BUILD_TYPE RelWithDebInfo CACHE STRING "Choose the type of build, options are: None Debug Release RelWithDebInfo MinSizeRel." FORCE)
+endif(NOT CMAKE_BUILD_TYPE)
+
+if(CMAKE_BUILD_TYPE STREQUAL "Release")
+       add_definitions("-DNDEBUG")
+endif()
+
+# Enable C++11 support and other compiler flags...
+if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
+       execute_process(COMMAND ${CMAKE_CXX_COMPILER} -dumpversion OUTPUT_VARIABLE GCC_VERSION)
+       message("Detected GCC version ${GCC_VERSION}")
+       if (GCC_VERSION VERSION_GREATER 4.7 OR GCC_VERSION VERSION_EQUAL 4.7)
+               set(CMAKE_CXX_FLAGS "-std=c++11 -Wall -Wextra -fcx-limited-range ${CMAKE_CXX_FLAGS}")
+       elseif (GCC_VERSION VERSION_GREATER 4.6 OR GCC_VERSION VERSION_EQUAL 4.6)
+               set(CMAKE_CXX_FLAGS "-std=c++0x -Wall -Wextra -fcx-limited-range ${CMAKE_CXX_FLAGS}")
+               add_definitions("-Doverride=")  # Hack: GCC 4.6 doesn't understand C++11 "override" keyword
+       else()
+               message(FATAL_ERROR "Your GCC compiler does not support c++11, please install at least gcc 4.6")
+       endif()
+endif()
+
+if(CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
+       set(CMAKE_CXX_FLAGS "-std=c++11 -Wall -Wextra ${CMAKE_CXX_FLAGS}")
+endif()
+
+if(WIN32)
+       set(CMAKE_CXX_FLAGS "-DWIN32_LEAN_AND_MEAN ${CMAKE_CXX_FLAGS}")
+       set(SHARE_INSTALL_DEFAULT ".")
+       SET(LOCALE_DIR_DEFAULT "locale")
+else()
+       set(SHARE_INSTALL_DEFAULT "share/games/performous")
+       SET(LOCALE_DIR_DEFAULT "share/locale")
+endif()
+
+set(SHARE_INSTALL "${SHARE_INSTALL_DEFAULT}" CACHE STRING "Data file install path. Must be a relative path (from CMAKE_INSTALL_PREFIX), with no trailing slash.")
+mark_as_advanced(SHARE_INSTALL)
+
+set(LOCALE_DIR "${LOCALE_DIR_DEFAULT}" CACHE STRING "Locale file install path. Must be a relative path (from CMAKE_INSTALL_PREFIX), with no trailing slash.")
+mark_as_advanced(LOCALE_DIR)
+
+find_package(Gettext)
+find_package(Msgfmt)
+if(Gettext_FOUND AND Msgfmt_FOUND)
+       message(STATUS "Localization enabled: Building and installing .mo files")
+       add_subdirectory(lang)
+else()
+       message(STATUS "Localization disabled: Gettext or Msgfmt missing")
+endif()
+
+add_subdirectory(data)
+add_subdirectory(game)
+
+option(ENABLE_TOOLS "Enable building of song extraction utilities for SingStar and Guitar Hero." ON)
+if(ENABLE_TOOLS)
+       add_subdirectory(tools)
+endif()
+
+add_subdirectory(docs)
+
+if(WIN32)
+       option(ENABLE_VERSIONING "Add version number information. This allows adding version information to the EXE. Be careful, in beta." OFF)
+       install(FILES win32/ConfigureSongDirectory.bat DESTINATION .)
+endif()
+
diff --git a/README.txt b/README.txt
new file mode 100644 (file)
index 0000000..cf54fa9
--- /dev/null
@@ -0,0 +1,8 @@
+Performous
+==========
+An open-source karaoke, band and dancing game where one or more players perform a song and the game scores their performances. Supports songs in UltraStar, Frets on Fire and StepMania formats. Microphones and instruments from SingStar, Guitar Hero and Rock Band as well as some dance pads are autodetected.
+
+Website at http://performous.org/
+Wiki at http://wiki.performous.org/
+
+For compiling instructions, see docs/Compiling.txt or visit the wiki page: https://github.com/performous/performous/wiki/Building-and-installing-from-source
diff --git a/cmake/Modules/FindALSA.cmake b/cmake/Modules/FindALSA.cmake
new file mode 100644 (file)
index 0000000..1bda438
--- /dev/null
@@ -0,0 +1,16 @@
+# - Try to find ALSA
+# Once done, this will define
+#
+#  ALSA_FOUND - system has ALSA
+#  ALSA_INCLUDE_DIRS - the ALSA include directories
+#  ALSA_LIBRARIES - link these to use ALSA
+#  ALSA_VERSION - the library version string
+#
+# See documentation on how to write CMake scripts at
+# http://www.cmake.org/Wiki/CMake:How_To_Find_Libraries
+
+include(LibFindMacros)
+libfind_pkg_detect(ALSA alsa FIND_PATH alsa/version.h FIND_LIBRARY asound)
+libfind_version_header(ALSA alsa/version.h SND_LIB_VERSION_STR)
+libfind_process(ALSA)
+
diff --git a/cmake/Modules/FindAVCodec.cmake b/cmake/Modules/FindAVCodec.cmake
new file mode 100644 (file)
index 0000000..2a6fa27
--- /dev/null
@@ -0,0 +1,46 @@
+# - Try to find FFMPEG libavcodec
+# Once done, this will define
+#
+#  AVCodec_FOUND - the library is available
+#  AVCodec_INCLUDE_DIRS - the include directories
+#  AVCodec_LIBRARIES - the libraries
+#  AVCodec_INCLUDE - the file to #include (may be used in config.h)
+#
+# See documentation on how to write CMake scripts at
+# http://www.cmake.org/Wiki/CMake:How_To_Find_Libraries
+
+include(LibFindMacros)
+
+libfind_package(AVCodec AVUtil)
+
+# TODO: pkg-config extra deps: libraw1394 theora vorbisenc
+
+libfind_pkg_check_modules(AVCodec_PKGCONF libavcodec)
+
+find_path(AVCodec_INCLUDE_DIR
+  NAMES libavcodec/avcodec.h ffmpeg/avcodec.h avcodec.h
+  PATHS ${AVCodec_PKGCONF_INCLUDE_DIRS}
+  PATH_SUFFIXES ffmpeg
+)
+
+if(AVCodec_INCLUDE_DIR)
+  foreach(suffix libavcodec/ ffmpeg/ "")
+    if(NOT AVCodec_INCLUDE)
+      if(EXISTS "${AVCodec_INCLUDE_DIR}/${suffix}avcodec.h")
+        set(AVCodec_INCLUDE "${suffix}avcodec.h" CACHE INTERNAL "")
+      endif(EXISTS "${AVCodec_INCLUDE_DIR}/${suffix}avcodec.h")
+    endif(NOT AVCodec_INCLUDE)
+  endforeach(suffix)
+
+  if(NOT AVCodec_INCLUDE)
+    message(FATAL_ERROR "Found avcodec.h include dir, but not the header file. Perhaps you need to clear CMake cache?")
+  endif(NOT AVCodec_INCLUDE)
+endif(AVCodec_INCLUDE_DIR)
+
+find_library(AVCodec_LIBRARY
+  NAMES libavcodec.dll.a avcodec
+  PATHS ${AVCodec_PKGCONF_LIBRARY_DIRS}
+)
+
+libfind_process(AVCodec)
+
diff --git a/cmake/Modules/FindAVFormat.cmake b/cmake/Modules/FindAVFormat.cmake
new file mode 100644 (file)
index 0000000..600948e
--- /dev/null
@@ -0,0 +1,44 @@
+# - Try to find FFMPEG libavformat
+# Once done, this will define
+#
+#  AVFormat_FOUND - the library is available
+#  AVFormat_INCLUDE_DIRS - the include directories
+#  AVFormat_LIBRARIES - the libraries
+#  AVFormat_INCLUDE - the file to include (may be used in config.h)
+#
+# See documentation on how to write CMake scripts at
+# http://www.cmake.org/Wiki/CMake:How_To_Find_Libraries
+
+include(LibFindMacros)
+
+libfind_package(AVFormat AVCodec)
+
+libfind_pkg_check_modules(AVFormat_PKGCONF libavformat)
+
+find_path(AVFormat_INCLUDE_DIR
+  NAMES libavformat/avformat.h ffmpeg/avformat.h avformat.h
+  PATHS ${AVFormat_PKGCONF_INCLUDE_DIRS}
+  PATH_SUFFIXES ffmpeg
+)
+
+if(AVFormat_INCLUDE_DIR)
+  foreach(suffix libavformat/ ffmpeg/ "")
+    if(NOT AVFormat_INCLUDE)
+      if(EXISTS "${AVFormat_INCLUDE_DIR}/${suffix}avformat.h")
+        set(AVFormat_INCLUDE "${suffix}avformat.h")
+      endif(EXISTS "${AVFormat_INCLUDE_DIR}/${suffix}avformat.h")
+    endif(NOT AVFormat_INCLUDE)
+  endforeach(suffix)
+
+  if(NOT AVFormat_INCLUDE)
+    message(FATAL_ERROR "Found avformat.h include dir, but not the header file. Perhaps you need to clear CMake cache?")
+  endif(NOT AVFormat_INCLUDE)
+endif(AVFormat_INCLUDE_DIR)
+
+find_library(AVFormat_LIBRARY
+  NAMES libavformat.dll.a avformat
+  PATHS ${AVFormat_PKGCONF_LIBRARY_DIRS}
+)
+
+libfind_process(AVFormat)
+
diff --git a/cmake/Modules/FindAVResample.cmake b/cmake/Modules/FindAVResample.cmake
new file mode 100644 (file)
index 0000000..32246ad
--- /dev/null
@@ -0,0 +1,46 @@
+# - Try to find libav libavresample
+# Once done, this will define
+#
+#  AVResample_FOUND - the library is available
+#  AVResample_INCLUDE_DIRS - the include directories
+#  AVResample_LIBRARIES - the libraries
+#  AVResample_INCLUDE - the file to #include (may be used in config.h)
+#
+# See documentation on how to write CMake scripts at
+# http://www.cmake.org/Wiki/CMake:How_To_Find_Libraries
+
+include(LibFindMacros)
+
+libfind_package(AVResample AVUtil)
+
+
+
+libfind_pkg_check_modules(AVResample_PKGCONF libavresample)
+
+find_path(AVResample_INCLUDE_DIR
+  NAMES libavresample/avresample.h ffmpeg/avresample.h avresample.h
+  PATHS ${AVResample_PKGCONF_INCLUDE_DIRS}
+  PATH_SUFFIXES ffmpeg
+)
+if(AVResample_INCLUDE_DIR)
+  foreach(suffix libavresample/ ffmpeg/ "")
+    if(NOT AVResample_INCLUDE)
+      if(EXISTS "${AVResample_INCLUDE_DIR}/${suffix}avresample.h")
+        set(AVResample_INCLUDE "${suffix}avresample.h")
+      endif(EXISTS "${AVResample_INCLUDE_DIR}/${suffix}avresample.h")
+    endif(NOT AVResample_INCLUDE)
+  endforeach(suffix)
+
+    if(NOT AVResample_INCLUDE)
+    message(FATAL_ERROR "Found avresample.h include dir, but not the header file. Perhaps you need to clear CMake cache?")
+  endif(NOT AVResample_INCLUDE)
+endif(AVResample_INCLUDE_DIR)
+
+find_library(AVResample_LIBRARY
+  NAMES libavresample.dll.a avresample
+  PATHS ${AVResample_PKGCONF_LIBRARY_DIRS}
+)
+
+set(AVResample_PROCESS_INCLUDES AVResample_INCLUDE_DIR AVUtil_INCLUDE_DIRS)
+set(AVResample_PROCESS_LIBS AVResample_LIBRARY AVUtil_LIBRARIES)
+libfind_process(AVResample)
diff --git a/cmake/Modules/FindAVUtil.cmake b/cmake/Modules/FindAVUtil.cmake
new file mode 100644 (file)
index 0000000..f62dcdd
--- /dev/null
@@ -0,0 +1,42 @@
+# - Try to find FFMPEG libavutil
+# Once done, this will define
+#
+#  AVUtil_FOUND - the library is available
+#  AVUtil_INCLUDE_DIRS - the include directories
+#  AVUtil_LIBRARIES - the libraries
+#  AVUtil_INCLUDE - the file to #include (may be used in config.h)
+#
+# See documentation on how to write CMake scripts at
+# http://www.cmake.org/Wiki/CMake:How_To_Find_Libraries
+
+include(LibFindMacros)
+
+libfind_pkg_check_modules(AVUtil_PKGCONF libavutil)
+
+find_path(AVUtil_INCLUDE_DIR
+  NAMES libavutil/avutil.h ffmpeg/avutil.h avutil.h
+  PATHS ${AVUtil_PKGCONF_INCLUDE_DIRS}
+  PATH_SUFFIXES ffmpeg
+)
+
+if(AVUtil_INCLUDE_DIR)
+  foreach(suffix libavutil/ ffmpeg/ "")
+    if(NOT AVUtil_INCLUDE)
+      if(EXISTS "${AVUtil_INCLUDE_DIR}/${suffix}avutil.h")
+        set(AVUtil_INCLUDE "${suffix}avutil.h")
+      endif(EXISTS "${AVUtil_INCLUDE_DIR}/${suffix}avutil.h")
+    endif(NOT AVUtil_INCLUDE)
+  endforeach(suffix)
+
+  if(NOT AVUtil_INCLUDE)
+    message(FATAL_ERROR "Found avutil.h include dir, but not the header file. Perhaps you need to clear CMake cache?")
+  endif(NOT AVUtil_INCLUDE)
+endif(AVUtil_INCLUDE_DIR)
+
+find_library(AVUtil_LIBRARY
+  NAMES libavutil.dll.a avutil
+  PATHS ${AVUtil_PKGCONF_LIBRARY_DIRS}
+)
+
+libfind_process(AVUtil)
+
diff --git a/cmake/Modules/FindAtk.cmake b/cmake/Modules/FindAtk.cmake
new file mode 100644 (file)
index 0000000..f9071f3
--- /dev/null
@@ -0,0 +1,34 @@
+# - Try to find Atk 1.0
+# Once done, this will define
+#
+#  Atk_FOUND - system has Atk
+#  Atk_INCLUDE_DIRS - the Atk include directories
+#  Atk_LIBRARIES - link these to use Atk
+
+include(LibFindMacros)
+
+# Dependencies
+libfind_package(Atk GObject)
+
+# Use pkg-config to get hints about paths
+libfind_pkg_check_modules(Atk_PKGCONF atk)
+
+# Main include dir
+find_path(Atk_INCLUDE_DIR
+  NAMES atk/atk.h
+  PATHS ${Atk_PKGCONF_INCLUDE_DIRS}
+  PATH_SUFFIXES atk-1.0
+)
+
+# Find the library
+find_library(Atk_LIBRARY
+  NAMES atk-1.0
+  PATHS ${Atk_PKGCONF_LIBRARY_DIRS}
+)
+
+# Set the include dir variables and the libraries and let libfind_process do the rest.
+# NOTE: Singular variables for this library, plural for libraries this this lib depends on.
+set(Atk_PROCESS_INCLUDES Atk_INCLUDE_DIR)
+set(Atk_PROCESS_LIBS Atk_LIBRARY GObject_LIBRARIES)
+libfind_process(Atk)
+
diff --git a/cmake/Modules/FindAtkmm.cmake b/cmake/Modules/FindAtkmm.cmake
new file mode 100644 (file)
index 0000000..2d853c7
--- /dev/null
@@ -0,0 +1,35 @@
+# - Try to find Atkmm 1.6
+# Once done, this will define
+#
+#  Atkmm_FOUND - system has Atkmm
+#  Atkmm_INCLUDE_DIRS - the Atkmm include directories
+#  Atkmm_LIBRARIES - link these to use Atkmm
+
+include(LibFindMacros)
+
+# Dependencies
+libfind_package(Atkmm Atk)
+libfind_package(Atkmm Glibmm)
+
+# Use pkg-config to get hints about paths
+libfind_pkg_check_modules(Atkmm_PKGCONF atkmm-1.6)
+
+# Main include dir
+find_path(Atkmm_INCLUDE_DIR
+  NAMES atkmm.h
+  PATHS ${Atkmm_PKGCONF_INCLUDE_DIRS}
+  PATH_SUFFIXES atkmm-1.6
+)
+
+# Finally the library itself
+find_library(Atkmm_LIBRARY
+  NAMES atkmm-1.6
+  PATHS ${Atkmm_PKGCONF_LIBRARY_DIRS}
+)
+
+# Set the include dir variables and the libraries and let libfind_process do the rest.
+# NOTE: Singular variables for this library, plural for libraries this this lib depends on.
+set(Atkmm_PROCESS_INCLUDES Atkmm_INCLUDE_DIR Atk_INCLUDE_DIRS Glibmm_INCLUDE_DIRS)
+set(Atkmm_PROCESS_LIBS Atkmm_LIBRARY Atk_LIBRARIES Glibmm_LIBRARIES)
+libfind_process(Atkmm)
+
diff --git a/cmake/Modules/FindCairo.cmake b/cmake/Modules/FindCairo.cmake
new file mode 100644 (file)
index 0000000..923fbc2
--- /dev/null
@@ -0,0 +1,14 @@
+# - Try to find Cairo
+# Once done, this will define
+#
+#  Cairo_FOUND - system has Cairo
+#  Cairo_INCLUDE_DIRS - the Cairo include directories
+#  Cairo_LIBRARIES - link these to use Cairo
+
+include(LibFindMacros)
+libfind_package(Cairo Freetype)  # Cairo depends on Freetype
+libfind_pkg_detect(Cairo cairo FIND_PATH cairo.h PATH_SUFFIXES cairo FIND_LIBRARY cairo)
+libfind_process(Cairo)
+
+
+
diff --git a/cmake/Modules/FindCairomm.cmake b/cmake/Modules/FindCairomm.cmake
new file mode 100644 (file)
index 0000000..2764dae
--- /dev/null
@@ -0,0 +1,34 @@
+# - Try to find Cairomm 1.0
+# Once done, this will define
+#
+#  Cairomm_FOUND - system has Cairomm
+#  Cairomm_INCLUDE_DIRS - the Cairomm include directories
+#  Cairomm_LIBRARIES - link these to use Cairomm
+
+include(LibFindMacros)
+
+# Dependencies
+libfind_package(Cairomm Cairo)
+
+# Use pkg-config to get hints about paths
+libfind_pkg_check_modules(Cairomm_PKGCONF cairomm-1.0)
+
+# Main include dir
+find_path(Cairomm_INCLUDE_DIR
+  NAMES cairomm/cairomm.h
+  PATHS ${Cairomm_PKGCONF_INCLUDE_DIRS}
+  PATH_SUFFIXES cairomm-1.0
+)
+
+# Finally the library itself
+find_library(Cairomm_LIBRARY
+  NAMES cairomm-1.0
+  PATHS ${Cairomm_PKGCONF_LIBRARY_DIRS}
+)
+
+# Set the include dir variables and the libraries and let libfind_process do the rest.
+# NOTE: Singular variables for this library, plural for libraries this this lib depends on.
+set(Cairomm_PROCESS_INCLUDES Cairomm_INCLUDE_DIR Cairo_INCLUDE_DIRS)
+set(Cairomm_PROCESS_LIBS Cairomm_LIBRARY Cairo_LIBRARIES)
+libfind_process(Cairomm)
+
diff --git a/cmake/Modules/FindClanLib.cmake b/cmake/Modules/FindClanLib.cmake
new file mode 100644 (file)
index 0000000..a78329a
--- /dev/null
@@ -0,0 +1,48 @@
+# - Try to find ClanLib
+# Example usage: find_package(ClanLib 0.8 REQUIRED COMPONENTS Core App Display GL Sound)
+#
+# Once done, this will define
+#
+#  ClanLib_FOUND - system has ClanLib (all the components requested)
+#  ClanLib_INCLUDE_DIRS - the ClanLib include directories
+#  ClanLib_LIBRARIES - link these to use ClanLib
+#
+# See documentation on how to write CMake scripts at
+# http://www.cmake.org/Wiki/CMake:How_To_Find_Libraries
+
+include(LibFindMacros)
+
+if (ClanLib_FIND_VERSION_MAJOR AND ClanLib_FIND_VERSION_MINOR)
+  set(ClanLib_VERSION "${ClanLib_FIND_VERSION_MAJOR}.${ClanLib_FIND_VERSION_MINOR}")
+else (ClanLib_FIND_VERSION_MAJOR AND ClanLib_FIND_VERSION_MINOR)
+  set(ClanLib_VERSION "0.8")
+endif (ClanLib_FIND_VERSION_MAJOR AND ClanLib_FIND_VERSION_MINOR)
+
+libfind_pkg_check_modules(ClanLib_PKGCONF clanCore-${ClanLib_VERSION})
+
+find_path(ClanLib_INCLUDE_DIR
+  NAMES ClanLib/core.h
+  PATHS ${ClanLib_PKGCONF_INCLUDE_DIRS}
+  PATH_SUFFIXES ClanLib-${ClanLib_VERSION}
+)
+
+# Extract the actual version number
+if (ClanLib_INCLUDE_DIR)
+  file(READ "${ClanLib_INCLUDE_DIR}/ClanLib/core.h" _ClanLib_CORE_H_CONTENTS)
+  set(_ClanLib_VERSION_REGEX ".*#define CL_VERSION_STRING \"([^\n]*)\".*")
+  if ("${_ClanLib_CORE_H_CONTENTS}" MATCHES "${_ClanLib_VERSION_REGEX}")
+    string(REGEX REPLACE "${_ClanLib_VERSION_REGEX}" "\\1" ClanLib_VERSION "${_ClanLib_CORE_H_CONTENTS}")
+  endif ("${_ClanLib_CORE_H_CONTENTS}" MATCHES "${_ClanLib_VERSION_REGEX}")
+endif (ClanLib_INCLUDE_DIR)
+
+foreach(COMPONENT ${ClanLib_FIND_COMPONENTS})
+  find_library(ClanLib_${COMPONENT}_LIBRARY
+    NAMES clan${COMPONENT}
+    PATHS ${ClanLib_PKGCONF_LIBRARY_DIRS}
+  )
+  set(ClanLib_PROCESS_LIBS ${ClanLib_PROCESS_LIBS} ClanLib_${COMPONENT}_LIBRARY)
+endforeach(COMPONENT)
+
+set(ClanLib_PROCESS_INCLUDES ClanLib_INCLUDE_DIR)
+libfind_process(ClanLib)
+
diff --git a/cmake/Modules/FindDL.cmake b/cmake/Modules/FindDL.cmake
new file mode 100644 (file)
index 0000000..17352df
--- /dev/null
@@ -0,0 +1,23 @@
+# - Try to find dynamic linker library. Does nothing on Windows
+# Once done, this will define
+#
+#  DL_FOUND - system has dl (always set on Windows)
+#  DL_INCLUDE_DIRS - dlfcn.h include dir
+#  DL_LIBRARIES - link these to use dl
+#
+# See documentation on how to write CMake scripts at
+# http://www.cmake.org/Wiki/CMake:How_To_Find_Libraries
+
+if(WIN32)
+       set(DL_FOUND TRUE)
+else()
+       include(LibFindMacros)
+
+       find_path(DL_INCLUDE_DIR NAMES dlfcn.h)
+       find_library(DL_LIBRARY NAMES dl)
+
+       set(DL_PROCESS_INCLUDES DL_INCLUDE_DIR)
+       set(DL_PROCESS_LIBS DL_LIBRARY)
+       libfind_process(DL)
+endif()
+
diff --git a/cmake/Modules/FindFAAC.cmake b/cmake/Modules/FindFAAC.cmake
new file mode 100644 (file)
index 0000000..84dc13c
--- /dev/null
@@ -0,0 +1,24 @@
+# - Try to find FAAC
+# Once done, this will define
+#
+#  FAAC_FOUND - system has FAAC
+#  FAAC_INCLUDE_DIRS - the FAAC include directories
+#  FAAC_LIBRARIES - link these to use FAAC
+#
+# See documentation on how to write CMake scripts at
+# http://www.cmake.org/Wiki/CMake:How_To_Find_Libraries
+
+include(LibFindMacros)
+
+find_path(FAAC_INCLUDE_DIR
+  NAMES faac.h
+)
+
+find_library(FAAC_LIBRARY
+  NAMES faac
+)
+
+set(FAAC_PROCESS_INCLUDES FAAC_INCLUDE_DIR)
+set(FAAC_PROCESS_LIBS FAAC_LIBRARY)
+libfind_process(FAAC)
+
diff --git a/cmake/Modules/FindFontconfig.cmake b/cmake/Modules/FindFontconfig.cmake
new file mode 100644 (file)
index 0000000..c2d0aa2
--- /dev/null
@@ -0,0 +1,28 @@
+# - Try to find Fontconfig
+# Once done, this will define
+#
+#  Fontconfig_FOUND - system has Fontconfig
+#  Fontconfig_INCLUDE_DIRS - the Fontconfig include directories
+#  Fontconfig_LIBRARIES - link these to use Fontconfig
+#
+# See documentation on how to write CMake scripts at
+# http://www.cmake.org/Wiki/CMake:How_To_Find_Libraries
+
+include(LibFindMacros)
+
+libfind_pkg_check_modules(Fontconfig_PKGCONF Fontconfig)
+
+find_path(Fontconfig_INCLUDE_DIR
+  NAMES fontconfig/fontconfig.h
+  PATHS ${Fontconfig_PKGCONF_INCLUDE_DIRS}
+)
+
+find_library(Fontconfig_LIBRARY
+  NAMES fontconfig
+  PATHS ${Fontconfig_PKGCONF_LIBRARY_DIRS}
+)
+
+set(Fontconfig_PROCESS_INCLUDES Fontconfig_INCLUDE_DIR)
+set(Fontconfig_PROCESS_LIBS Fontconfig_LIBRARY)
+libfind_process(Fontconfig)
+
diff --git a/cmake/Modules/FindFreetype.cmake b/cmake/Modules/FindFreetype.cmake
new file mode 100644 (file)
index 0000000..84e4952
--- /dev/null
@@ -0,0 +1,31 @@
+# - Try to find Freetype2
+# Once done, this will define
+#
+#  Freetype_FOUND - system has Freetype
+#  Freetype_INCLUDE_DIRS - the Freetype include directories
+#  Freetype_LIBRARIES - link these to use Freetype
+
+include(LibFindMacros)
+
+# Use pkg-config to get hints about paths
+libfind_pkg_check_modules(Freetype_PKGCONF freetype2)
+
+# Include dir
+find_path(Freetype_INCLUDE_DIR
+  NAMES freetype/freetype.h freetype2/freetype.h
+  PATHS ${Freetype_PKGCONF_INCLUDE_DIRS}
+  PATH_SUFFIXES freetype2
+)
+
+# Finally the library itself
+find_library(Freetype_LIBRARY
+  NAMES freetype
+  PATHS ${Freetype_PKGCONF_LIBRARY_DIRS}
+)
+
+# Set the include dir variables and the libraries and let libfind_process do the rest.
+# NOTE: Singular variables for this library, plural for libraries this this lib depends on.
+set(Freetype_PROCESS_INCLUDES Freetype_INCLUDE_DIR)
+set(Freetype_PROCESS_LIBS Freetype_LIBRARY)
+libfind_process(Freetype)
+
diff --git a/cmake/Modules/FindGDK-PixBuf.cmake b/cmake/Modules/FindGDK-PixBuf.cmake
new file mode 100644 (file)
index 0000000..37da00c
--- /dev/null
@@ -0,0 +1,32 @@
+# - Try to find gdk-pixbuf 2.0
+# Once done, this will define
+#
+#  GDK-PixBuf_FOUND - system has GDK-PixBuf
+#  GDK-PixBuf_INCLUDE_DIRS - the GDK-PixBuf include directories
+#  GDK-PixBuf_LIBRARIES - link these to use GDK-PixBuf
+
+include(LibFindMacros)
+
+# Use pkg-config to get hints about paths
+libfind_pkg_check_modules(GDK-PixBuf_PKGCONF gdk-pixbuf-2.0)
+
+# Main include dir
+find_path(GDK-PixBuf_INCLUDE_DIR
+  NAMES gdk-pixbuf/gdk-pixbuf.h
+  PATHS ${GDK-PixBuf_PKGCONF_INCLUDE_DIRS}
+  PATH_SUFFIXES gtk-2.0 gdk-pixbuf-2.0
+)
+
+# Finally the library itself
+find_library(GDK-PixBuf_LIBRARY
+  NAMES gdk_pixbuf-2.0
+  PATHS ${GDK-PixBuf_PKGCONF_LIBRARY_DIRS}
+)
+
+# Set the include dir variables and the libraries and let libfind_process do the rest.
+# NOTE: Singular variables for this library, plural for libraries this this lib depends on.
+set(GDK-PixBuf_PROCESS_INCLUDES GDK-PixBuf_INCLUDE_DIR)
+set(GDK-PixBuf_PROCESS_LIBS GDK-PixBuf_LIBRARY)
+libfind_process(GDK-PixBuf)
+
+
diff --git a/cmake/Modules/FindGDK.cmake b/cmake/Modules/FindGDK.cmake
new file mode 100644 (file)
index 0000000..4955fb4
--- /dev/null
@@ -0,0 +1,43 @@
+# - Try to find GDK 2.0
+# Once done, this will define
+#
+#  GDK_FOUND - system has GDK
+#  GDK_INCLUDE_DIRS - the GDK include directories
+#  GDK_LIBRARIES - link these to use GDK
+
+include(LibFindMacros)
+
+# Dependencies
+libfind_package(GDK GDK-PixBuf)
+libfind_package(GDK Pango)
+libfind_package(GDK GIO)
+
+# Use pkg-config to get hints about paths
+libfind_pkg_check_modules(GDK_PKGCONF gdk-2.0)
+
+# Main include dir
+find_path(GDK_INCLUDE_DIR
+  NAMES gdk/gdk.h
+  PATHS ${GDK_PKGCONF_INCLUDE_DIRS}
+  PATH_SUFFIXES gtk-2.0
+)
+
+# Glib-related libraries also use a separate config header, which is in lib dir
+find_path(GDKConfig_INCLUDE_DIR
+  NAMES gdkconfig.h
+  PATHS ${GDK_PKGCONF_INCLUDE_DIRS} /usr
+  PATH_SUFFIXES lib/gtk-2.0/include
+)
+
+# Finally the library itself
+find_library(GDK_LIBRARY
+  NAMES gdk-x11-2.0
+  PATHS ${GDK_PKGCONF_LIBRARY_DIRS}
+)
+
+# Set the include dir variables and the libraries and let libfind_process do the rest.
+# NOTE: Singular variables for this library, plural for libraries this this lib depends on.
+set(GDK_PROCESS_INCLUDES GDK_INCLUDE_DIR GDKConfig_INCLUDE_DIR GDK-PixBuf_INCLUDE_DIRS Pango_INCLUDE_DIRS GIO_INCLUDE_DIRS)
+set(GDK_PROCESS_LIBS GDK_LIBRARY GDK-PixBuf_LIBRARIES Pango_LIBRARIES GIO_LIBRARIES)
+libfind_process(GDK)
+
diff --git a/cmake/Modules/FindGDKmm.cmake b/cmake/Modules/FindGDKmm.cmake
new file mode 100644 (file)
index 0000000..b0a0c48
--- /dev/null
@@ -0,0 +1,44 @@
+# - Try to find GDKmm 2.4
+# Once done, this will define
+#
+#  GDKmm_FOUND - system has GDKmm
+#  GDKmm_INCLUDE_DIRS - the GDKmm include directories
+#  GDKmm_LIBRARIES - link these to use GDKmm
+
+include(LibFindMacros)
+
+# Dependencies
+libfind_package(GDKmm GDK)
+libfind_package(GDKmm Glibmm)
+libfind_package(GDKmm Pangomm)
+libfind_package(GDKmm Cairomm)
+
+# Use pkg-config to get hints about paths
+libfind_pkg_check_modules(GDKmm_PKGCONF gdkmm-2.4)
+
+# Main include dir
+find_path(GDKmm_INCLUDE_DIR
+  NAMES gdkmm.h
+  PATHS ${GDKmm_PKGCONF_INCLUDE_DIRS}
+  PATH_SUFFIXES gdkmm-2.4
+)
+
+# Glib-related libraries also use a separate config header, which is in lib dir
+find_path(GDKmmConfig_INCLUDE_DIR
+  NAMES gdkmmconfig.h
+  PATHS ${GDKmm_PKGCONF_INCLUDE_DIRS} /usr
+  PATH_SUFFIXES lib/gdkmm-2.4/include
+)
+
+# Finally the library itself
+find_library(GDKmm_LIBRARY
+  NAMES gdkmm-2.4
+  PATHS ${GDKmm_PKGCONF_LIBRARY_DIRS}
+)
+
+# Set the include dir variables and the libraries and let libfind_process do the rest.
+# NOTE: Singular variables for this library, plural for libraries this this lib depends on.
+set(GDKmm_PROCESS_INCLUDES GDKmm_INCLUDE_DIR GDKmmConfig_INCLUDE_DIR GDK_INCLUDE_DIRS Glibmm_INCLUDE_DIRS Pangomm_INCLUDE_DIRS Cairomm_INCLUDE_DIRS)
+set(GDKmm_PROCESS_LIBS GDKmm_LIBRARY GDK_LIBRARIES Glibmm_LIBRARIES Pangomm_LIBRARIES Cairomm_LIBRARIES)
+libfind_process(GDKmm)
+
diff --git a/cmake/Modules/FindGIO.cmake b/cmake/Modules/FindGIO.cmake
new file mode 100644 (file)
index 0000000..c32a3bf
--- /dev/null
@@ -0,0 +1,27 @@
+# - Try to find GIO 2.0
+# Once done, this will define
+#
+#  GIO_FOUND - system has GIO
+#  GIO_INCLUDE_DIRS - the GIO include directories
+#  GIO_LIBRARIES - link these to use GIO
+
+include(LibFindMacros)
+
+# Dependencies
+libfind_package(GIO Glib)
+
+# Use pkg-config to get hints about paths
+libfind_pkg_check_modules(GIO_PKGCONF gio-2.0)
+
+# Find the library
+find_library(GIO_LIBRARY
+  NAMES gio-2.0
+  PATHS ${GIO_PKGCONF_LIBRARY_DIRS}
+)
+
+# Set the include dir variables and the libraries and let libfind_process do the rest.
+# NOTE: Singular variables for this library, plural for libraries this this lib depends on.
+set(GIO_PROCESS_INCLUDES Glib_INCLUDE_DIRS)
+set(GIO_PROCESS_LIBS GIO_LIBRARY Glib_LIBRARIES)
+libfind_process(GIO)
+
diff --git a/cmake/Modules/FindGIOmm.cmake b/cmake/Modules/FindGIOmm.cmake
new file mode 100644 (file)
index 0000000..59ff7f0
--- /dev/null
@@ -0,0 +1,35 @@
+# - Try to find GIOmm 2.4
+# Once done, this will define
+#
+#  GIOmm_FOUND - system has GIOmm
+#  GIOmm_INCLUDE_DIRS - the GIOmm include directories
+#  GIOmm_LIBRARIES - link these to use GIOmm
+
+include(LibFindMacros)
+
+# Dependencies
+libfind_package(GIOmm GIO)
+libfind_package(GIOmm Glibmm)
+
+# Use pkg-config to get hints about paths
+libfind_pkg_check_modules(GIOmm_PKGCONF giomm-2.4)
+
+# Main include dir
+find_path(GIOmm_INCLUDE_DIR
+  NAMES giomm.h
+  PATHS ${GIOmm_PKGCONF_INCLUDE_DIRS}
+  PATH_SUFFIXES giomm-2.4
+)
+
+# Finally the library itself
+find_library(GIOmm_LIBRARY
+  NAMES giomm-2.4
+  PATHS ${GIOmm_PKGCONF_LIBRARY_DIRS}
+)
+
+# Set the include dir variables and the libraries and let libfind_process do the rest.
+# NOTE: Singular variables for this library, plural for libraries this this lib depends on.
+set(GIOmm_PROCESS_INCLUDES GIOmm_INCLUDE_DIR GIO_INCLUDE_DIRS Glibmm_INCLUDE_DIRS)
+set(GIOmm_PROCESS_LIBS GIOmm_LIBRARY GIO_LIBRARIES Glibmm_LIBRARIES)
+libfind_process(GIOmm)
+
diff --git a/cmake/Modules/FindGLEW.cmake b/cmake/Modules/FindGLEW.cmake
new file mode 100644 (file)
index 0000000..8040c33
--- /dev/null
@@ -0,0 +1,30 @@
+# - Try to find GLEW
+# Once done, this will define
+#
+#  GLEW_FOUND - system has OpenGL (GL and GLU)
+#  GLEW_INCLUDE_DIRS - the OpenGL include directories
+#  GLEW_LIBRARIES - link these to use OpenGL
+#
+# See documentation on how to write CMake scripts at
+# http://www.cmake.org/Wiki/CMake:How_To_Find_Libraries
+
+include(LibFindMacros)
+
+# GLEW is often installed in the same place as OpenGL
+libfind_pkg_check_modules(OpenGL_PKGCONF gl)
+
+find_path(GLEW_INCLUDE_DIR
+  NAMES glew.h
+  PATHS ${OpenGL_INCLUDE_DIRS}
+  PATH_SUFFIXES GL
+)
+
+find_library(GLEW_LIBRARY
+  NAMES GLEW GLEW32.a GLEW32
+  PATHS ${OpenGL_PKGCONF_LIBRARY_DIRS}
+)
+
+set(GLEW_PROCESS_INCLUDES GLEW_INCLUDE_DIR)
+set(GLEW_PROCESS_LIBS GLEW_LIBRARY)
+libfind_process(GLEW)
+
diff --git a/cmake/Modules/FindGLFW.cmake b/cmake/Modules/FindGLFW.cmake
new file mode 100644 (file)
index 0000000..f83f448
--- /dev/null
@@ -0,0 +1,38 @@
+# - Try to find GLFW
+# Once done, this will define
+#
+#  GLFW_FOUND - system has OpenGL (GL and GLU)
+#  GLFW_INCLUDE_DIRS - the OpenGL include directories
+#  GLFW_LIBRARIES - link these to use OpenGL
+#
+# See documentation on how to write CMake scripts at
+# http://www.cmake.org/Wiki/CMake:How_To_Find_Libraries
+
+include(LibFindMacros)
+
+# Dependencies
+libfind_package(GDK OpenGL)
+
+libfind_pkg_check_modules(GLFW_PKGCONF libglfw)
+
+find_path(GLFW_INCLUDE_DIR
+  NAMES GL/glfw.h
+  PATHS ${GLFW_PKGCONF_INCLUDE_DIRS}
+)
+
+find_library(GLFW_LIBRARY
+  NAMES glfw
+  PATHS ${GLFW_PKGCONF_LIBRARY_DIRS}
+)
+
+set(GLFW_PROCESS_INCLUDES GLFW_INCLUDE_DIR OpenGL_INCLUDE_DIRS)
+set(GLFW_PROCESS_LIBS GLFW_LIBRARY OpenGL_LIBRARIES)
+
+if(UNIX)
+  find_library(X11_LIBRARY NAMES X11)
+  find_library(Xrandr_LIBRARY NAMES Xrandr)
+  set(GLFW_PROCESS_LIBS ${GLFW_PROCESS_LIBS} X11_LIBRARY Xrandr_LIBRARY)
+endif(UNIX)
+
+libfind_process(GLFW)
+
diff --git a/cmake/Modules/FindGObject.cmake b/cmake/Modules/FindGObject.cmake
new file mode 100644 (file)
index 0000000..0461be3
--- /dev/null
@@ -0,0 +1,31 @@
+# - Try to find GObject 2.0
+# Once done, this will define
+#
+#  GObject_FOUND - system has GObject
+#  GObject_INCLUDE_DIRS - the GObject include directories
+#  GObject_LIBRARIES - link these to use GObject
+
+include(LibFindMacros)
+
+# Dependencies
+libfind_package(GObject Glib)
+
+# Use pkg-config to get hints about paths
+libfind_pkg_check_modules(GObject_PKGCONF gobject-2.0)
+
+# Find the library
+find_library(GObject_LIBRARY
+  NAMES gobject-2.0
+  PATHS ${GObject_PKGCONF_LIBRARY_DIRS}
+)
+
+find_path(GObject_INCLUDE_DIR
+  NAMES gobject/gobject.h
+  PATHS ${GObject_PKGCONF_INCLUDE_DIRS}
+  PATHS ${Glib_INCLUDE_DIRS}
+)
+
+set(GObject_PROCESS_INCLUDES GObject_INCLUDE_DIR Glib_INCLUDE_DIR)
+set(GObject_PROCESS_LIBS GObject_LIBRARY Glib_LIBRARY)
+libfind_process(GObject)
+
diff --git a/cmake/Modules/FindGStreamer.cmake b/cmake/Modules/FindGStreamer.cmake
new file mode 100644 (file)
index 0000000..fbaa857
--- /dev/null
@@ -0,0 +1,33 @@
+# - Try to find GStreamer
+# Once done, this will define
+#
+#  GStreamer_FOUND - system has GStreamer
+#  GStreamer_INCLUDE_DIRS - the GStreamer include directories
+#  GStreamer_LIBRARIES - link these to use GStreamer
+
+include(LibFindMacros)
+
+# Dependencies
+libfind_package(GStreamer GObject)
+libfind_package(GStreamer LibXML2)
+
+# Use pkg-config to get hints about paths
+libfind_pkg_check_modules(GStreamer_PKGCONF gstreamer-0.10)
+
+# Include dir
+find_path(GStreamer_INCLUDE_DIR
+  NAMES gst/gst.h
+  PATHS ${GStreamer_PKGCONF_INCLUDE_DIRS}
+)
+
+# Finally the library itself
+find_library(GStreamer_LIBRARY
+  NAMES gstreamer-0.10
+  PATHS ${GStreamer_PKGCONF_LIBRARY_DIRS}
+)
+
+# Set the include dir variables and the libraries and let libfind_process do the rest.
+# NOTE: Singular variables for this library, plural for libraries this this lib depends on.
+set(GStreamer_PROCESS_INCLUDES GStreamer_INCLUDE_DIR GObject_INCLUDE_DIRS LibXML2_INCLUDE_DIRS)
+set(GStreamer_PROCESS_LIBS GStreamer_LIBRARY GObject_LIBRARIES LibXML2_LIBRARIES)
+libfind_process(GStreamer)
diff --git a/cmake/Modules/FindGTK.cmake b/cmake/Modules/FindGTK.cmake
new file mode 100644 (file)
index 0000000..1eec88e
--- /dev/null
@@ -0,0 +1,38 @@
+# - Try to find GTK 2.0
+# Once done, this will define
+#
+#  GTK_FOUND - system has GTK
+#  GTK_INCLUDE_DIRS - the GTK include directories
+#  GTK_LIBRARIES - link these to use GTK
+
+include(LibFindMacros)
+
+# Dependencies
+libfind_package(GTK GDK)
+libfind_package(GTK Cairo)
+libfind_package(GTK Atk)
+libfind_package(GTK GIO)
+libfind_package(GTK Pango)
+
+# Use pkg-config to get hints about paths
+libfind_pkg_check_modules(GTK_PKGCONF gtk+-2.0)
+
+# Main include dir
+find_path(GTK_INCLUDE_DIR
+  NAMES gtk/gtk.h
+  PATHS ${GTK_PKGCONF_INCLUDE_DIRS}
+  PATH_SUFFIXES gtk-2.0
+)
+
+# Finally the library itself
+find_library(GTK_LIBRARY
+  NAMES gtk-x11-2.0
+  PATHS ${GTK_PKGCONF_LIBRARY_DIRS}
+)
+
+# Set the include dir variables and the libraries and let libfind_process do the rest.
+# NOTE: Singular variables for this library, plural for libraries this this lib depends on.
+set(GTK_PROCESS_INCLUDES GTK_INCLUDE_DIR GDK_INCLUDE_DIRS Cairo_INCLUDE_DIRS Atk_INCLUDE_DIRS GIO_INCLUDE_DIRS Pango_INCLUDE_DIRS)
+set(GTK_PROCESS_LIBS GTK_LIBRARY GDK_LIBRARIES Cairo_LIBRARIES Atk_LIBRARIES GIO_LIBRARIES Pango_LIBRARIES)
+libfind_process(GTK)
+
diff --git a/cmake/Modules/FindGTKmm.cmake b/cmake/Modules/FindGTKmm.cmake
new file mode 100644 (file)
index 0000000..8a56f93
--- /dev/null
@@ -0,0 +1,46 @@
+# - Try to find GTKmm 2.4
+# Once done, this will define
+#
+#  GTKmm_FOUND - system has GTKmm
+#  GTKmm_INCLUDE_DIRS - the GTKmm include directories
+#  GTKmm_LIBRARIES - link these to use GTKmm
+
+include(LibFindMacros)
+
+# Dependencies
+libfind_package(GTKmm GTK)
+libfind_package(GTKmm Glibmm)
+libfind_package(GTKmm GIOmm)
+libfind_package(GTKmm GDKmm)
+libfind_package(GTKmm Pangomm)
+libfind_package(GTKmm Atkmm)
+
+# Use pkg-config to get hints about paths
+libfind_pkg_check_modules(GTKmm_PKGCONF gtkmm-2.4)
+
+# Main include dir
+find_path(GTKmm_INCLUDE_DIR
+  NAMES gtkmm.h
+  PATHS ${GTKmm_PKGCONF_INCLUDE_DIRS}
+  PATH_SUFFIXES gtkmm-2.4
+)
+
+# Glib-related libraries also use a separate config header, which is in lib dir
+find_path(GTKmmConfig_INCLUDE_DIR
+  NAMES gtkmmconfig.h
+  PATHS ${GTKmm_PKGCONF_INCLUDE_DIRS} /usr
+  PATH_SUFFIXES lib/gtkmm-2.4/include
+)
+
+# Finally the library itself
+find_library(GTKmm_LIBRARY
+  NAMES gtkmm-2.4
+  PATHS ${GTKmm_PKGCONF_LIBRARY_DIRS}
+)
+
+# Set the include dir variables and the libraries and let libfind_process do the rest.
+# NOTE: Singular variables for this library, plural for libraries this this lib depends on.
+set(GTKmm_PROCESS_INCLUDES GTKmm_INCLUDE_DIR GTKmmConfig_INCLUDE_DIR GTK_INCLUDE_DIRS Glibmm_INCLUDE_DIRS GIOmm_INCLUDE_DIRS GDKmm_INCLUDE_DIRS Pangomm_INCLUDE_DIRS Atkmm_INCLUDE_DIRS)
+set(GTKmm_PROCESS_LIBS GTKmm_LIBRARY GTK_LIBRARIES Glibmm_LIBRARIES GIOmm_LIBRARIES GDKmm_LIBRARIES Pangomm_LIBRARIES Atkmm_LIBRARIES)
+libfind_process(GTKmm)
+
diff --git a/cmake/Modules/FindGettext.cmake b/cmake/Modules/FindGettext.cmake
new file mode 100644 (file)
index 0000000..251dc88
--- /dev/null
@@ -0,0 +1,36 @@
+# - Try to find Gettext
+# Once done, this will define
+#
+#  Gettext_FOUND - system has Gettext
+#  Gettext_INCLUDE_DIRS - the Gettext include directories
+#  Gettext_LIBRARIES - link these to use Gettext
+#
+# See documentation on how to write CMake scripts at
+# http://www.cmake.org/Wiki/CMake:How_To_Find_Libraries
+
+include(LibFindMacros)
+
+# On Linux there is no pkgconfig script, but with this we force Gettext_PKGCONF_INCLUDE_DIRS to ""
+libfind_pkg_check_modules(Gettext_PKGCONF Gettext)
+if(WIN32 OR APPLE)
+  set(Gettext_LIBRARY_SEARCH_DIRS
+    ${Gettext_PKGCONF_LIBRARY_DIRS}
+    /opt/local/lib
+    /sw/local/lib
+  )
+  
+  find_library(Gettext_LIBRARY
+    NAMES intl
+    PATHS ${Gettext_LIBRARY_SEARCH_DIRS}
+  )
+
+  set(Gettext_PROCESS_LIBS Gettext_LIBRARY)
+endif()
+
+find_path(Gettext_INCLUDE_DIR
+  NAMES libintl.h
+  PATHS ${Gettext_PKGCONF_INCLUDE_DIRS}
+)
+
+set(Gettext_PROCESS_INCLUDES Gettext_INCLUDE_DIR)
+libfind_process(Gettext)
diff --git a/cmake/Modules/FindGlib.cmake b/cmake/Modules/FindGlib.cmake
new file mode 100644 (file)
index 0000000..b00d63e
--- /dev/null
@@ -0,0 +1,39 @@
+# - Try to find Glib-2.0
+# Once done, this will define
+#
+#  Glib_FOUND - system has Glib
+#  Glib_INCLUDE_DIRS - the Glib include directories
+#  Glib_LIBRARIES - link these to use Glib
+
+include(LibFindMacros)
+
+# Use pkg-config to get hints about paths
+libfind_pkg_check_modules(Glib_PKGCONF glib-2.0)
+
+# Main include dir
+find_path(Glib_INCLUDE_DIR
+  NAMES glib.h
+  PATHS ${Glib_PKGCONF_INCLUDE_DIRS}
+  PATH_SUFFIXES glib-2.0
+)
+
+# Glib-related libraries also use a separate config header, which is in lib dir
+find_path(GlibConfig_INCLUDE_DIR
+  NAMES glibconfig.h
+  PATHS ${Glib_PKGCONF_INCLUDE_DIRS} /usr
+  PATH_SUFFIXES lib/glib-2.0/include ../lib/glib-2.0/include
+)
+
+# Finally the library itself
+find_library(Glib_LIBRARY
+  NAMES glib-2.0
+  PATHS ${Glib_PKGCONF_LIBRARY_DIRS}
+)
+
+# Set the include dir variables and the libraries and let libfind_process do the rest.
+# NOTE: Singular variables for this library, plural for libraries this this lib depends on.
+set(Glib_PROCESS_INCLUDES Glib_INCLUDE_DIR GlibConfig_INCLUDE_DIR)
+set(Glib_PROCESS_LIBS Glib_LIBRARY)
+libfind_process(Glib)
+
+
diff --git a/cmake/Modules/FindGlibmm.cmake b/cmake/Modules/FindGlibmm.cmake
new file mode 100644 (file)
index 0000000..8431c0e
--- /dev/null
@@ -0,0 +1,39 @@
+# - Try to find Glibmm-2.4
+# Once done, this will define
+#
+#  Glibmm_FOUND - system has Glibmm
+#  Glibmm_INCLUDE_DIRS - the Glibmm include directories
+#  Glibmm_LIBRARIES - link these to use Glibmm
+
+include(LibFindMacros)
+
+# Dependencies
+libfind_package(Glibmm Glib)
+libfind_package(Glibmm SigC++)
+
+# Use pkg-config to get hints about paths
+libfind_pkg_check_modules(Glibmm_PKGCONF glibmm-2.4)
+
+# Main include dir
+find_path(Glibmm_INCLUDE_DIR
+  NAMES glibmm/main.h
+  PATHS ${Glibmm_PKGCONF_INCLUDE_DIRS}
+  PATH_SUFFIXES glibmm-2.4
+)
+
+# Glib-related libraries also use a separate config header, which is in lib dir
+find_path(GlibmmConfig_INCLUDE_DIR
+  NAMES glibmmconfig.h
+  PATHS ${Glibmm_PKGCONF_INCLUDE_DIRS} /usr
+  PATH_SUFFIXES lib/glibmm-2.4/include ../lib/glibmm-2.4/include
+)
+
+# Finally the library itself
+find_library(Glibmm_LIBRARY
+  NAMES glibmm-2.4
+  PATHS ${Glibmm_PKGCONF_LIBRARY_DIRS}
+)
+
+set(Glibmm_PROCESS_INCLUDES GlibmmConfig_INCLUDE_DIR)
+libfind_process(Glibmm)
+
diff --git a/cmake/Modules/FindJack.cmake b/cmake/Modules/FindJack.cmake
new file mode 100644 (file)
index 0000000..e2309f1
--- /dev/null
@@ -0,0 +1,28 @@
+# - Try to find Jack
+# Once done, this will define
+#
+#  Jack_FOUND - system has Jack
+#  Jack_INCLUDE_DIRS - the Jack include directories
+#  Jack_LIBRARIES - link these to use Jack
+#
+# See documentation on how to write CMake scripts at
+# http://www.cmake.org/Wiki/CMake:How_To_Find_Libraries
+
+include(LibFindMacros)
+
+libfind_pkg_check_modules(Jack_PKGCONF jack)
+
+find_path(Jack_INCLUDE_DIR
+  NAMES jack/jack.h
+  PATHS ${Jack_PKGCONF_INCLUDE_DIRS}
+)
+
+find_library(Jack_LIBRARY
+  NAMES jack
+  PATHS ${Jack_PKGCONF_LIBRARY_DIRS}
+)
+
+set(Jack_PROCESS_INCLUDES Jack_INCLUDE_DIR)
+set(Jack_PROCESS_LIBS Jack_LIBRARY)
+libfind_process(Jack)
+
diff --git a/cmake/Modules/FindJpeg.cmake b/cmake/Modules/FindJpeg.cmake
new file mode 100644 (file)
index 0000000..e1b1be2
--- /dev/null
@@ -0,0 +1,28 @@
+# - Try to find Jpeg
+# Once done, this will define
+#
+#  Jpeg_FOUND - system has Jpeg
+#  Jpeg_INCLUDE_DIRS - the Jpeg include directories
+#  Jpeg_LIBRARIES - link these to use Jpeg
+#
+# See documentation on how to write CMake scripts at
+# http://www.cmake.org/Wiki/CMake:How_To_Find_Libraries
+
+include(LibFindMacros)
+
+libfind_pkg_check_modules(Jpeg_PKGCONF jpeg)
+
+find_path(Jpeg_INCLUDE_DIR
+  NAMES jconfig.h jpeglib.h
+  PATHS ${Jpeg_PKGCONF_INCLUDE_DIRS}
+)
+
+find_library(Jpeg_LIBRARY
+  NAMES jpeg
+  PATHS ${Jpeg_PKGCONF_LIBRARY_DIRS}
+)
+
+set(Jpeg_PROCESS_INCLUDES Jpeg_INCLUDE_DIR)
+set(Jpeg_PROCESS_LIBS Jpeg_LIBRARY)
+libfind_process(Jpeg)
+
diff --git a/cmake/Modules/FindLibPulse.cmake b/cmake/Modules/FindLibPulse.cmake
new file mode 100644 (file)
index 0000000..aebeac0
--- /dev/null
@@ -0,0 +1,28 @@
+# - Try to find LibPulse
+# Once done, this will define
+#
+#  LibPulse_FOUND - system has LibPulse
+#  LibPulse_INCLUDE_DIRS - the LibPulse include directories
+#  LibPulse_LIBRARIES - link these to use LibPulse
+#
+# See documentation on how to write CMake scripts at
+# http://www.cmake.org/Wiki/CMake:How_To_Find_Libraries
+
+include(LibFindMacros)
+
+libfind_pkg_check_modules(LibPulse_PKGCONF libpulse)
+
+find_path(LibPulse_INCLUDE_DIR
+  NAMES pulse/pulseaudio.h
+  PATHS ${LibPulse_PKGCONF_INCLUDE_DIRS}
+)
+
+find_library(LibPulse_LIBRARY
+  NAMES pulse
+  PATHS ${LibPulse_PKGCONF_LIBRARY_DIRS}
+)
+
+set(LibPulse_PROCESS_INCLUDES LibPulse_INCLUDE_DIR)
+set(LibPulse_PROCESS_LIBS LibPulse_LIBRARY)
+libfind_process(LibPulse)
+
diff --git a/cmake/Modules/FindLibPulseSimple.cmake b/cmake/Modules/FindLibPulseSimple.cmake
new file mode 100644 (file)
index 0000000..738c831
--- /dev/null
@@ -0,0 +1,28 @@
+# - Try to find LibPulseSimple
+# Once done, this will define
+#
+#  LibPulseSimple_FOUND - system has LibPulseSimple
+#  LibPulseSimple_INCLUDE_DIRS - the LibPulseSimple include directories
+#  LibPulseSimple_LIBRARIES - link these to use LibPulseSimple
+#
+# See documentation on how to write CMake scripts at
+# http://www.cmake.org/Wiki/CMake:How_To_Find_Libraries
+
+include(LibFindMacros)
+
+libfind_pkg_check_modules(LibPulseSimple_PKGCONF libpulse-simple)
+
+find_path(LibPulseSimple_INCLUDE_DIR
+  NAMES pulse/simple.h
+  PATHS ${LibPulseSimple_PKGCONF_INCLUDE_DIRS}
+)
+
+find_library(LibPulseSimple_LIBRARY
+  NAMES pulse-simple
+  PATHS ${LibPulseSimple_PKGCONF_LIBRARY_DIRS}
+)
+
+set(LibPulseSimple_PROCESS_INCLUDES LibPulseSimple_INCLUDE_DIR)
+set(LibPulseSimple_PROCESS_LIBS LibPulseSimple_LIBRARY)
+libfind_process(LibPulseSimple)
+
diff --git a/cmake/Modules/FindLibRSVG.cmake b/cmake/Modules/FindLibRSVG.cmake
new file mode 100644 (file)
index 0000000..1a9698e
--- /dev/null
@@ -0,0 +1,16 @@
+# - Try to find LibRSVG
+# Once done, this will define
+#
+#  LibRSVG_FOUND - system has LibRSVG
+#  LibRSVG_INCLUDE_DIRS - the LibRSVG include directories
+#  LibRSVG_LIBRARIES - link these to use LibRSVG
+
+include(LibFindMacros)
+libfind_package(LibRSVG Cairo)
+libfind_package(LibRSVG GDK-PixBuf)
+libfind_pkg_detect(LibRSVG librsvg-2.0
+  FIND_PATH librsvg/rsvg.h PATH_SUFFIXES librsvg-2
+  FIND_LIBRARY rsvg-2
+)
+libfind_process(LibRSVG)
+
diff --git a/cmake/Modules/FindLibXML++.cmake b/cmake/Modules/FindLibXML++.cmake
new file mode 100644 (file)
index 0000000..4449cce
--- /dev/null
@@ -0,0 +1,39 @@
+# - Try to find LibXML++ 2.6
+# Once done, this will define
+#
+#  LibXML++_FOUND - system has LibXML++
+#  LibXML++_INCLUDE_DIRS - the LibXML++ include directories
+#  LibXML++_LIBRARIES - link these to use LibXML++
+
+include(LibFindMacros)
+
+# Dependencies
+libfind_package(LibXML++ LibXML2)
+libfind_package(LibXML++ Glibmm)
+
+# Use pkg-config to get hints about paths
+libfind_pkg_check_modules(LibXML++_PKGCONF libxml++-2.6)
+
+# Main include dir
+find_path(LibXML++_INCLUDE_DIR
+  NAMES libxml++/libxml++.h
+  PATHS ${LibXML++_PKGCONF_INCLUDE_DIRS}
+  PATH_SUFFIXES libxml++-2.6
+)
+
+# Glib-related libraries also use a separate config header, which is in lib dir
+find_path(LibXML++Config_INCLUDE_DIR
+  NAMES libxml++config.h
+  PATHS ${LibXML++_PKGCONF_INCLUDE_DIRS} /usr
+  PATH_SUFFIXES lib/libxml++-2.6/include ../lib/libxml++-2.6/include
+)
+
+# Finally the library itself
+find_library(LibXML++_LIBRARY
+  NAMES xml++-2.6
+  PATHS ${LibXML++_PKGCONF_LIBRARY_DIRS}
+)
+
+set(LibXML++_PROCESS_INCLUDES LibXML++Config_INCLUDE_DIR)
+libfind_process(LibXML++)
+
diff --git a/cmake/Modules/FindLibXML2.cmake b/cmake/Modules/FindLibXML2.cmake
new file mode 100644 (file)
index 0000000..8163e70
--- /dev/null
@@ -0,0 +1,30 @@
+# - Try to find LibXML2
+# Once done, this will define
+#
+#  LibXML2_FOUND - system has LibXML2
+#  LibXML2_INCLUDE_DIRS - the LibXML2 include directories
+#  LibXML2_LIBRARIES - link these to use LibXML2
+#
+# See documentation on how to write CMake scripts at
+# http://www.cmake.org/Wiki/CMake:How_To_Find_Libraries
+
+include(LibFindMacros)
+
+libfind_pkg_check_modules(LibXML2_PKGCONF libxml-2.0)
+
+find_path(LibXML2_INCLUDE_DIR
+  NAMES libxml/xpath.h
+  PATHS ${LibXML2_PKGCONF_INCLUDE_DIRS}
+  PATHS ${LibXML2_PKGCONF_INCLUDE_DIRS}/libxml2
+  PATH_SUFFIXES libxml2
+)
+
+find_library(LibXML2_LIBRARY
+  NAMES xml2
+  PATHS ${LibXML2_PKGCONF_LIBRARY_DIRS}
+)
+
+set(LibXML2_PROCESS_INCLUDES LibXML2_INCLUDE_DIR)
+set(LibXML2_PROCESS_LIBS LibXML2_LIBRARY)
+libfind_process(LibXML2)
+
diff --git a/cmake/Modules/FindMagick++.cmake b/cmake/Modules/FindMagick++.cmake
new file mode 100644 (file)
index 0000000..f5793df
--- /dev/null
@@ -0,0 +1,30 @@
+# - Try to find ImageMagick++
+# Once done, this will define
+#
+#  Magick++_FOUND - system has Magick++
+#  Magick++_INCLUDE_DIRS - the Magick++ include directories
+#  Magick++_LIBRARIES - link these to use Magick++
+
+include(LibFindMacros)
+
+# Dependencies
+libfind_package(Magick++ Magick)
+
+# Use pkg-config to get hints about paths
+libfind_pkg_check_modules(Magick++_PKGCONF ImageMagick++)
+
+# Include dir
+find_path(Magick++_INCLUDE_DIR
+  NAMES Magick++.h
+  PATHS ${Magick++_PKGCONF_INCLUDE_DIRS}
+)
+
+# Finally the library itself
+find_library(Magick++_LIBRARY
+  NAMES Magick++ CORE_RL_magick++_
+  PATHS ${Magick++_PKGCONF_LIBRARY_DIRS}
+)
+
+# Process Magick++, depends on Magick
+libfind_process(Magick++ Magick)
+
diff --git a/cmake/Modules/FindMagick.cmake b/cmake/Modules/FindMagick.cmake
new file mode 100644 (file)
index 0000000..a107f0d
--- /dev/null
@@ -0,0 +1,35 @@
+# - Try to find ImageMagick
+# Once done, this will define
+#
+#  Magick_FOUND - system has Magick
+#  Magick_INCLUDE_DIRS - the Magick include directories
+#  Magick_LIBRARIES - link these to use Magick
+
+include(LibFindMacros)
+
+# Use pkg-config to get hints about paths
+libfind_pkg_check_modules(Magick_PKGCONF ImageMagick)
+
+# Include dir
+find_path(Magick_INCLUDE_DIR
+  NAMES magick/magick.h
+  PATHS ${Magick_PKGCONF_INCLUDE_DIRS}
+)
+
+# Finally the library itself
+find_library(Magick_LIBRARY
+  NAMES Magick MagickCore CORE_RL_magick_
+  PATHS ${Magick_PKGCONF_LIBRARY_DIRS}
+)
+
+if(MINGW)
+  find_library(MagickWand_LIBRARY
+    NAMES MagickWand
+    PATHS ${Magick_PKGCONF_LIBRARY_DIRS}
+  )
+  set(Magick_PROCESS_LIBS MagickWand_LIBRARY)
+endif(MINGW)
+
+libfind_version_header(Magick magick/version.h MagickLibVersionText)
+libfind_process(Magick)
+
diff --git a/cmake/Modules/FindMsgfmt.cmake b/cmake/Modules/FindMsgfmt.cmake
new file mode 100644 (file)
index 0000000..14de5bd
--- /dev/null
@@ -0,0 +1,16 @@
+# - Try to find Msgfmt
+# Once done, this will define
+#
+#  Msgfmt_FOUND - system has Gettext
+#  Msgfmt_BIN - path to binary file
+
+find_program(Msgfmt_BIN msgfmt)
+
+if(Msgfmt_BIN)
+       set(Msgfmt_FOUND 1)
+else()
+       set(Msgfmt_FOUND 0)
+endif(Msgfmt_BIN)
+
+mark_as_advanced(Msgfmt_BIN)
+
diff --git a/cmake/Modules/FindOpenGL.cmake b/cmake/Modules/FindOpenGL.cmake
new file mode 100644 (file)
index 0000000..a6236e5
--- /dev/null
@@ -0,0 +1,44 @@
+# - Try to find OpenGL
+# Once done, this will define
+#
+#  OpenGL_FOUND - system has OpenGL (GL and GLU)
+#  OpenGL_INCLUDE_DIRS - the OpenGL include directories
+#  OpenGL_LIBRARIES - link these to use OpenGL
+#  OpenGL_GL_LIBRARY - only GL
+#  OpenGL_GLU_LIBRARY - only GLU
+#
+# See documentation on how to write CMake scripts at
+# http://www.cmake.org/Wiki/CMake:How_To_Find_Libraries
+
+include(LibFindMacros)
+
+libfind_pkg_check_modules(OpenGL_PKGCONF gl)
+
+find_path(OpenGL_INCLUDE_DIR
+  NAMES GL/gl.h
+  PATHS ${OpenGL_PKGCONF_INCLUDE_DIRS}
+)
+
+if(MSVC) #In MSVC, no need to link, just this hack to get CMake happy
+  find_file(OpenGL_GL_LIBRARY
+    opengl32.dll
+  )
+
+  find_file(OpenGL_GLU_LIBRARY
+    glu32.dll
+  )
+else()
+  find_library(OpenGL_GL_LIBRARY
+    NAMES GL libopengl32.a opengl32
+    PATHS ${OpenGL_PKGCONF_LIBRARY_DIRS}
+  )
+
+  find_library(OpenGL_GLU_LIBRARY
+    NAMES GLU libglu32.a glu32
+    PATHS ${OpenGL_PKGCONF_LIBRARY_DIRS}
+  )
+endif(MSVC)
+set(OpenGL_PROCESS_INCLUDES OpenGL_INCLUDE_DIR)
+set(OpenGL_PROCESS_LIBS OpenGL_GL_LIBRARY OpenGL_GLU_LIBRARY)
+libfind_process(OpenGL)
+
diff --git a/cmake/Modules/FindPThread.cmake b/cmake/Modules/FindPThread.cmake
new file mode 100644 (file)
index 0000000..a404e28
--- /dev/null
@@ -0,0 +1,21 @@
+# - Try to find PThread
+# Once done, this will define
+#
+#  PThread_FOUND - system has PThread
+#  PThread_LIBRARIES - link these to use PThread
+#
+# See documentation on how to write CMake scripts at
+# http://www.cmake.org/Wiki/CMake:How_To_Find_Libraries
+
+include(LibFindMacros)
+
+libfind_pkg_check_modules(Png_PKGCONF PThread)
+
+find_library(PThread_LIBRARY
+  NAMES pthreadGC2
+  PATHS ${PThread_PKGCONF_LIBRARY_DIRS}
+)
+
+set(PThread_PROCESS_LIBS PThread_LIBRARY)
+libfind_process(PThread)
+
diff --git a/cmake/Modules/FindPango.cmake b/cmake/Modules/FindPango.cmake
new file mode 100644 (file)
index 0000000..ba0ed55
--- /dev/null
@@ -0,0 +1,32 @@
+# - Try to find Pango
+# Once done, this will define
+#
+#  Pango_FOUND - system has Pango
+#  Pango_INCLUDE_DIRS - the Pango include directories
+#  Pango_LIBRARIES - link these to use Pango
+
+include(LibFindMacros)
+
+# Dependencies
+libfind_package(Pango Freetype)
+libfind_package(Pango Glib)
+libfind_package(Pango GObject)
+
+# Use pkg-config to get hints about paths
+libfind_pkg_check_modules(Pango_PKGCONF pango)
+
+# Include dir
+find_path(Pango_INCLUDE_DIR
+  NAMES pango/pango.h
+  PATHS ${Pango_PKGCONF_INCLUDE_DIRS}
+  PATH_SUFFIXES pango-1.0
+)
+
+# Finally the library itself
+find_library(Pango_LIBRARY
+  NAMES pango-1.0
+  PATHS ${Pango_PKGCONF_LIBRARY_DIRS}
+)
+
+libfind_process(Pango)
+
diff --git a/cmake/Modules/FindPangoCairo.cmake b/cmake/Modules/FindPangoCairo.cmake
new file mode 100644 (file)
index 0000000..b7944b6
--- /dev/null
@@ -0,0 +1,35 @@
+# - Try to find PangoCairo
+# Once done, this will define
+#
+#  PangoCairo_FOUND - system has Pango
+#  PangoCairo_INCLUDE_DIRS - the Pango include directories
+#  PangoCairo_LIBRARIES - link these to use Pango
+
+include(LibFindMacros)
+
+# Dependencies
+libfind_package(PangoCairo Pango)
+libfind_package(PangoCairo Cairo)
+
+# Use pkg-config to get hints about paths
+libfind_pkg_check_modules(PangoCairo_PKGCONF pangocairo)
+
+# Include dir
+find_path(PangoCairo_INCLUDE_DIR
+  NAMES pango/pangocairo.h
+  PATHS ${PangoCairo_PKGCONF_INCLUDE_DIRS}
+  PATH_SUFFIXES pango-1.0
+)
+
+# Finally the library itself
+find_library(PangoCairo_LIBRARY
+  NAMES pangocairo-1.0
+  PATHS ${PangoCairo_PKGCONF_LIBRARY_DIRS}
+)
+
+# Set the include dir variables and the libraries and let libfind_process do the rest.
+# NOTE: Singular variables for this library, plural for libraries this this lib depends on.
+set(PangoCairo_PROCESS_INCLUDES PangoCairo_INCLUDE_DIR Pango_INCLUDE_DIR Cairo_INCLUDE_DIR)
+set(PangoCairo_PROCESS_LIBS PangoCairo_LIBRARY Pango_LIBRARY Cairo_LIBRARY)
+libfind_process(PangoCairo)
+
diff --git a/cmake/Modules/FindPangomm.cmake b/cmake/Modules/FindPangomm.cmake
new file mode 100644 (file)
index 0000000..693a3c8
--- /dev/null
@@ -0,0 +1,36 @@
+# - Try to find Pangomm 1.4
+# Once done, this will define
+#
+#  Pangomm_FOUND - system has Pangomm
+#  Pangomm_INCLUDE_DIRS - the Pangomm include directories
+#  Pangomm_LIBRARIES - link these to use Pangomm
+
+include(LibFindMacros)
+
+# Dependencies
+libfind_package(Pangomm Pango)
+libfind_package(Pangomm Cairomm)
+libfind_package(Pangomm Glibmm)
+
+# Use pkg-config to get hints about paths
+libfind_pkg_check_modules(Pangomm_PKGCONF pangomm-1.4)
+
+# Main include dir
+find_path(Pangomm_INCLUDE_DIR
+  NAMES pangomm.h
+  PATHS ${Pangomm_PKGCONF_INCLUDE_DIRS}
+  PATH_SUFFIXES pangomm-1.4
+)
+
+# Finally the library itself
+find_library(Pangomm_LIBRARY
+  NAMES pangomm-1.4
+  PATHS ${Pangomm_PKGCONF_LIBRARY_DIRS}
+)
+
+# Set the include dir variables and the libraries and let libfind_process do the rest.
+# NOTE: Singular variables for this library, plural for libraries this this lib depends on.
+set(Pangomm_PROCESS_INCLUDES Pangomm_INCLUDE_DIR Pango_INCLUDE_DIRS Cairomm_INCLUDE_DIRS Glibmm_INCLUDE_DIRS)
+set(Pangomm_PROCESS_LIBS Pangomm_LIBRARY Pango_LIBRARIES Cairomm_LIBRARIES Glibmm_LIBRARIES)
+libfind_process(Pangomm)
+
diff --git a/cmake/Modules/FindPng.cmake b/cmake/Modules/FindPng.cmake
new file mode 100644 (file)
index 0000000..dfe81c1
--- /dev/null
@@ -0,0 +1,28 @@
+# - Try to find Png
+# Once done, this will define
+#
+#  Png_FOUND - system has Png
+#  Png_INCLUDE_DIRS - the Png include directories
+#  Png_LIBRARIES - link these to use Png
+#
+# See documentation on how to write CMake scripts at
+# http://www.cmake.org/Wiki/CMake:How_To_Find_Libraries
+
+include(LibFindMacros)
+
+libfind_pkg_check_modules(Png_PKGCONF Png)
+
+find_path(Png_INCLUDE_DIR
+  NAMES pngconf.h
+  PATHS ${Png_PKGCONF_INCLUDE_DIRS}
+)
+
+find_library(Png_LIBRARY
+  NAMES png png12 png14
+  PATHS ${Png_PKGCONF_LIBRARY_DIRS}
+)
+
+set(Png_PROCESS_INCLUDES Png_INCLUDE_DIR)
+set(Png_PROCESS_LIBS Png_LIBRARY)
+libfind_process(Png)
+
diff --git a/cmake/Modules/FindPortAudio.cmake b/cmake/Modules/FindPortAudio.cmake
new file mode 100644 (file)
index 0000000..6443037
--- /dev/null
@@ -0,0 +1,35 @@
+# - Try to find PortAudio
+# Once done, this will define
+#
+#  PortAudio_FOUND - system has PortAudio
+#  PortAudio_INCLUDE_DIRS - the PortAudio include directories
+#  PortAudio_LIBRARIES - link these to use PortAudio
+#  PortAudio_VERSION - detected version of PortAudio
+#
+# See documentation on how to write CMake scripts at
+# http://www.cmake.org/Wiki/CMake:How_To_Find_Libraries
+
+include(LibFindMacros)
+
+libfind_pkg_check_modules(PortAudio_PKGCONF portaudio-2.0)
+
+if(PortAudio_PKGCONF_FOUND)
+  set(PortAudio_VERSION 19)
+else(PortAudio_PKGCONF_FOUND)
+  set(PortAudio_VERSION 18)
+endif(PortAudio_PKGCONF_FOUND)
+
+find_path(PortAudio_INCLUDE_DIR
+  NAMES portaudio.h
+  PATHS ${PortAudio_PKGCONF_INCLUDE_DIRS}
+)
+
+find_library(PortAudio_LIBRARY
+  NAMES portaudio
+  PATHS ${PortAudio_PKGCONF_LIBRARY_DIRS}
+)
+
+set(PortAudio_PROCESS_INCLUDES PortAudio_INCLUDE_DIR)
+set(PortAudio_PROCESS_LIBS PortAudio_LIBRARY)
+libfind_process(PortAudio)
+
diff --git a/cmake/Modules/FindPortMidi.cmake b/cmake/Modules/FindPortMidi.cmake
new file mode 100644 (file)
index 0000000..ef3fa1f
--- /dev/null
@@ -0,0 +1,28 @@
+# - Try to find PortMidi
+# Once done, this will define
+#
+#  PortMidi_FOUND - system has PortMidi
+#  PortMidi_INCLUDE_DIRS - the PortMidi include directories
+#  PortMidi_LIBRARIES - link these to use PortMidi
+#  PortMidi_VERSION - detected version of PortMidi
+#
+# See documentation on how to write CMake scripts at
+# http://www.cmake.org/Wiki/CMake:How_To_Find_Libraries
+
+include(LibFindMacros)
+
+find_path(PortMidi_INCLUDE_DIR NAMES portmidi.h)
+find_library(PortMidi_LIBRARY NAMES portmidi)
+find_library(PortTime_LIBRARY NAMES porttime)
+
+set(PortMidi_PROCESS_INCLUDES PortMidi_INCLUDE_DIR)
+set(PortMidi_PROCESS_LIBS PortMidi_LIBRARY)
+# Porttime library is merged to Portmidi in new versions, so
+# we work around problems by adding it only if it's present
+if (${PortTime_LIBRARY})
+       set(PortMidi_PROCESS_LIBS PortMidi_PROCESS_LIBS PortTime_LIBRARY)
+endif (${PortTime_LIBRARY})
+
+libfind_process(PortMidi)
+mark_as_advanced(PortTime_LIBRARY)
+
diff --git a/cmake/Modules/FindProjectM.cmake b/cmake/Modules/FindProjectM.cmake
new file mode 100644 (file)
index 0000000..862082e
--- /dev/null
@@ -0,0 +1,30 @@
+# - Try to find ProjectM
+# Once done, this will define
+#
+#  ProjectM_FOUND - system has ProjectM
+#  ProjectM_INCLUDE_DIRS - the ProjectM include directories
+#  ProjectM_LIBRARIES - link these to use ProjectM
+
+include(LibFindMacros)
+
+# Use pkg-config to get hints about paths
+libfind_pkg_check_modules(ProjectM_PKGCONF libprojectM)
+
+# Include dir
+find_path(ProjectM_INCLUDE_DIR
+  NAMES libprojectM/projectM.hpp
+  PATHS ${ProjectM_PKGCONF_INCLUDE_DIRS}
+)
+
+# Finally the library itself
+find_library(ProjectM_LIBRARY
+  NAMES projectM
+  PATHS ${ProjectM_PKGCONF_LIBRARY_DIRS}
+)
+
+# Set the include dir variables and the libraries and let libfind_process do the rest.
+# NOTE: Singular variables for this library, plural for libraries this this lib depends on.
+set(ProjectM_PROCESS_INCLUDES ProjectM_INCLUDE_DIR)
+set(ProjectM_PROCESS_LIBS ProjectM_LIBRARY)
+libfind_process(ProjectM)
+
diff --git a/cmake/Modules/FindSDL.cmake b/cmake/Modules/FindSDL.cmake
new file mode 100644 (file)
index 0000000..2d4e557
--- /dev/null
@@ -0,0 +1,59 @@
+# - Try to find SDL
+# Once done, this will define
+#
+#  SDL_FOUND - system has SDL
+#  SDL_INCLUDE_DIRS - the SDL include directories
+#  SDL_LIBRARIES - link these to use SDL
+#  SDL_SDL_LIBRARY - only libSDL
+#  SDL_SDLmain_LIBRARY - only libSDLmain
+#  SDL_SOURCES - add this in the source file list of your target (hack for OSX)
+#
+# See documentation on how to write CMake scripts at
+# http://www.cmake.org/Wiki/CMake:How_To_Find_Libraries
+
+include(LibFindMacros)
+
+libfind_pkg_check_modules(SDL_PKGCONF sdl)
+
+find_path(SDL_INCLUDE_DIR
+  NAMES SDL.h
+  PATH_SUFFIXES SDL
+  HINTS ${SDL_PKGCONF_INCLUDE_DIRS}
+)
+
+find_library(SDL_SDL_LIBRARY
+  NAMES SDL
+  HINTS ${SDL_PKGCONF_LIBRARY_DIRS}
+)
+
+# Process others than OSX with native SDL normally
+if(NOT "${SDL_SDL_LIBRARY}" MATCHES "framework")
+  if(MINGW)
+    set(MINGW32_LIBRARY mingw32)
+    set(SDL_PROCESS_LIBS ${SDL_PROCESS_LIBS} MINGW32_LIBRARY)
+  endif(MINGW)
+  find_library(SDL_SDLmain_LIBRARY
+    NAMES libSDLmain.a SDLmain
+    HINTS ${SDL_PKGCONF_LIBRARY_DIRS}
+  )
+  if (SDL_SDLmain_LIBRARY)
+    set(SDL_PROCESS_LIBS ${SDL_PROCESS_LIBS} SDL_SDLmain_LIBRARY)
+  endif (SDL_SDLmain_LIBRARY)
+  set(SDL_PROCESS_LIBS ${SDL_PROCESS_LIBS} SDL_SDL_LIBRARY)
+endif(NOT "${SDL_SDL_LIBRARY}" MATCHES "framework")
+
+set(SDL_PROCESS_INCLUDES SDL_INCLUDE_DIR)
+libfind_process(SDL)
+
+# Special processing for OSX native SDL
+if("${SDL_SDL_LIBRARY}" MATCHES "SDL.framework")
+  set(SDL_SOURCES "osx/SDLmain.m")
+  set(SDL_LIBRARIES "-framework SDL")
+endif("${SDL_SDL_LIBRARY}" MATCHES "SDL.framework")
+
+# All OSX versions need Cocoa
+if(APPLE)
+  set(SDL_LIBRARIES ${SDL_LIBRARIES} "-framework Cocoa")
+endif(APPLE)
+
diff --git a/cmake/Modules/FindSDL2.cmake b/cmake/Modules/FindSDL2.cmake
new file mode 100644 (file)
index 0000000..b3889d5
--- /dev/null
@@ -0,0 +1,45 @@
+# - Try to find SDL2
+# Once done, this will define
+#
+#  SDL2_FOUND - system has SDL2
+#  SDL2_INCLUDE_DIRS - the SDL2 include directories
+#  SDL2_LIBRARIES - link these to use SDL2
+#  SDL2_SDL_LIBRARY - only libSDL2
+#  SDL2_SDLmain_LIBRARY - only libSDL2main
+#  SDL2_SOURCES - add this in the source file list of your target (hack for OSX)
+#
+# See documentation on how to write CMake scripts at
+# http://www.cmake.org/Wiki/CMake:How_To_Find_Libraries
+
+include(LibFindMacros)
+libfind_pkg_detect(SDL2 sdl2 FIND_PATH SDL.h PATH_SUFFIXES SDL2 FIND_LIBRARY SDL2)
+
+# Process others than OSX with native SDL normally
+if(NOT "${SDL2_SDL_LIBRARY}" MATCHES "framework")
+  if(MINGW)
+    set(MINGW32_LIBRARY mingw32)
+    set(SDL2_PROCESS_LIBS ${SDL2_PROCESS_LIBS} MINGW32_LIBRARY)
+  endif()
+  find_library(SDL2_SDLmain_LIBRARY
+    NAMES libSDL2main.a SDL2main
+    HINTS ${SDL2_PKGCONF_LIBRARY_DIRS}
+  )
+  if (SDL2_SDLmain_LIBRARY)
+    set(SDL2_PROCESS_LIBS ${SDL2_PROCESS_LIBS} SDL2_SDLmain_LIBRARY)
+  endif()
+  set(SDL2_PROCESS_LIBS ${SDL2_PROCESS_LIBS} SDL2_SDL_LIBRARY)
+endif()
+
+libfind_process(SDL2)
+
+# Special processing for OSX native SDL
+if("${SDL2_SDL_LIBRARY}" MATCHES "SDL.framework")
+  set(SDL2_SOURCES "osx/SDLmain.m")
+  set(SDL2_LIBRARIES "-framework SDL2")
+endif()
+
+# All OSX versions need Cocoa
+if(APPLE)
+  set(SDL2_LIBRARIES ${SDL2_LIBRARIES} "-framework Cocoa")
+endif(APPLE)
+
diff --git a/cmake/Modules/FindSDL_image.cmake b/cmake/Modules/FindSDL_image.cmake
new file mode 100644 (file)
index 0000000..34e7011
--- /dev/null
@@ -0,0 +1,29 @@
+# - Try to find SDL_image
+# Once done, this will define
+#
+#  SDL_image_FOUND - system has SDL_image
+#  SDL_image_INCLUDE_DIRS - the SDL include directories
+#  SDL_image_LIBRARIES - link these to use SDL_image
+#
+# See documentation on how to write CMake scripts at
+# http://www.cmake.org/Wiki/CMake:How_To_Find_Libraries
+
+include(LibFindMacros)
+
+libfind_pkg_check_modules(SDL_image_PKGCONF sdl)
+
+find_path(SDL_image_INCLUDE_DIR
+  NAMES SDL_image.h
+  PATH_SUFFIXES SDL
+  HINTS ${SDL_PKGCONF_INCLUDE_DIRS}
+)
+
+find_library(SDL_image_LIBRARY
+  NAMES SDL_image
+  HINTS ${SDL_PKGCONF_LIBRARY_DIRS}
+)
+
+set(SDL_image_PROCESS_INCLUDES SDL_image_INCLUDE_DIR)
+set(SDL_image_PROCESS_LIBS SDL_image_LIBRARY)
+libfind_process(SDL_image)
+
diff --git a/cmake/Modules/FindSDL_mixer.cmake b/cmake/Modules/FindSDL_mixer.cmake
new file mode 100644 (file)
index 0000000..5e369a5
--- /dev/null
@@ -0,0 +1,32 @@
+# - Try to find SDL
+# Once done, this will define
+#
+#  SDL_mixer_FOUND - system has SDL
+#  SDL_mixer_INCLUDE_DIRS - the SDL include directories
+#  SDL_mixer_LIBRARIES - link these to use SDL
+#  SDL_mixer_SDL_mixer_LIBRARY - only libSDL
+#  SDL_mixer_SDLmain_LIBRARY - only libSDLmain
+#  SDL_mixer_SOURCES - add this in the source file list of your target (hack for OSX)
+#
+# See documentation on how to write CMake scripts at
+# http://www.cmake.org/Wiki/CMake:How_To_Find_Libraries
+
+include(LibFindMacros)
+
+libfind_pkg_check_modules(SDL_mixer_PKGCONF sdl)
+
+find_path(SDL_mixer_INCLUDE_DIR
+  NAMES SDL_mixer.h
+  PATH_SUFFIXES SDL
+  HINTS ${SDL_PKGCONF_INCLUDE_DIRS}
+)
+
+find_library(SDL_mixer_LIBRARY
+  NAMES SDL_mixer
+  HINTS ${SDL_PKGCONF_LIBRARY_DIRS}
+)
+
+set(SDL_mixer_PROCESS_INCLUDES SDL_mixer_INCLUDE_DIR)
+set(SDL_mixer_PROCESS_LIBS SDL_mixer_LIBRARY)
+libfind_process(SDL_mixer)
+
diff --git a/cmake/Modules/FindSWScale.cmake b/cmake/Modules/FindSWScale.cmake
new file mode 100644 (file)
index 0000000..af0f1ef
--- /dev/null
@@ -0,0 +1,44 @@
+# - Try to find FFMPEG libswscale
+# Once done, this will define
+#
+#  SWScale_FOUND - the library is available
+#  SWScale_INCLUDE_DIRS - the include directories
+#  SWScale_LIBRARIES - the libraries
+#  SWScale_INCLUDE - the file to include (may be used in config.h)
+#
+# See documentation on how to write CMake scripts at
+# http://www.cmake.org/Wiki/CMake:How_To_Find_Libraries
+
+include(LibFindMacros)
+
+libfind_package(SWScale AVUtil)
+
+libfind_pkg_check_modules(SWScale_PKGCONF libswscale)
+
+find_path(SWScale_INCLUDE_DIR
+  NAMES libswscale/swscale.h ffmpeg/swscale.h swscale.h
+  PATHS ${SWScale_PKGCONF_INCLUDE_DIRS}
+  PATH_SUFFIXES ffmpeg
+)
+
+if(SWScale_INCLUDE_DIR)
+  foreach(suffix libswscale/ ffmpeg/ "")
+    if(NOT SWScale_INCLUDE)
+      if(EXISTS "${SWScale_INCLUDE_DIR}/${suffix}swscale.h")
+        set(SWScale_INCLUDE "${suffix}swscale.h")
+      endif(EXISTS "${SWScale_INCLUDE_DIR}/${suffix}swscale.h")
+    endif(NOT SWScale_INCLUDE)
+  endforeach(suffix)
+
+  if(NOT SWScale_INCLUDE)
+    message(FATAL_ERROR "Found swscale.h include dir, but not the header file. Maybe you need to clear CMake cache?")
+  endif(NOT SWScale_INCLUDE)
+endif(SWScale_INCLUDE_DIR)
+
+find_library(SWScale_LIBRARY
+  NAMES libswscale.dll.a swscale
+  PATHS ${SWScale_PKGCONF_LIBRARY_DIRS}
+)
+
+libfind_process(SWScale)
+
diff --git a/cmake/Modules/FindSigC++.cmake b/cmake/Modules/FindSigC++.cmake
new file mode 100644 (file)
index 0000000..0d7ea0c
--- /dev/null
@@ -0,0 +1,36 @@
+# - Try to find SigC++-2.0
+# Once done, this will define
+#
+#  SigC++_FOUND - system has SigC++
+#  SigC++_INCLUDE_DIRS - the SigC++ include directories
+#  SigC++_LIBRARIES - link these to use SigC++
+
+include(LibFindMacros)
+
+# Use pkg-config to get hints about paths
+libfind_pkg_check_modules(SigC++_PKGCONF sigc++-2.0)
+
+# Main include dir
+find_path(SigC++_INCLUDE_DIR
+  NAMES sigc++/sigc++.h
+  HINTS ${SigC++_PKGCONF_INCLUDE_DIRS}
+  PATH_SUFFIXES sigc++-2.0
+)
+
+# Glib-related libraries also use a separate config header, which is in lib dir
+find_path(SigC++Config_INCLUDE_DIR
+  NAMES sigc++config.h
+  HINTS ${SigC++_PKGCONF_INCLUDE_DIRS} /usr
+  PATH_SUFFIXES lib/sigc++-2.0/include ../lib/sigc++-2.0/include
+)
+
+# Finally the library itself
+find_library(SigC++_LIBRARY
+  NAMES sigc-2.0
+  HINTS ${SigC++_PKGCONF_LIBRARY_DIRS}
+)
+
+set(SigC++_PROCESS_INCLUDES SigC++_INCLUDE_DIR SigC++Config_INCLUDE_DIR)
+set(SigC++_PROCESS_LIBS SigC++_LIBRARY)
+libfind_process(SigC++)
+
diff --git a/cmake/Modules/FindTiff.cmake b/cmake/Modules/FindTiff.cmake
new file mode 100644 (file)
index 0000000..bc4f92d
--- /dev/null
@@ -0,0 +1,28 @@
+# - Try to find Tiff
+# Once done, this will define
+#
+#  Tiff_FOUND - system has Tiff
+#  Tiff_INCLUDE_DIRS - the Tiff include directories
+#  Tiff_LIBRARIES - link these to use Tiff
+#
+# See documentation on how to write CMake scripts at
+# http://www.cmake.org/Wiki/CMake:How_To_Find_Libraries
+
+include(LibFindMacros)
+
+libfind_pkg_check_modules(Tiff_PKGCONF tiff)
+
+find_path(Tiff_INCLUDE_DIR
+  NAMES tiffconf.h
+  PATHS ${Tiff_PKGCONF_INCLUDE_DIRS}
+)
+
+find_library(Tiff_LIBRARY
+  NAMES tiff
+  PATHS ${Tiff_PKGCONF_LIBRARY_DIRS}
+)
+
+set(Tiff_PROCESS_INCLUDES Tiff_INCLUDE_DIR)
+set(Tiff_PROCESS_LIBS Tiff_LIBRARY)
+libfind_process(Tiff)
+
diff --git a/cmake/Modules/FindZ.cmake b/cmake/Modules/FindZ.cmake
new file mode 100644 (file)
index 0000000..f0bad3a
--- /dev/null
@@ -0,0 +1,28 @@
+# - Try to find Z
+# Once done, this will define
+#
+#  Z_FOUND - system has Z
+#  Z_INCLUDE_DIRS - the Z include directories
+#  Z_LIBRARIES - link these to use Z
+#
+# See documentation on how to write CMake scripts at
+# http://www.cmake.org/Wiki/CMake:How_To_Find_Libraries
+
+include(LibFindMacros)
+
+libfind_pkg_check_modules(Z_PKGCONF Z)
+
+find_path(Z_INCLUDE_DIR
+  NAMES zlib.h
+  PATHS ${Z_PKGCONF_INCLUDE_DIRS}
+)
+
+find_library(Z_LIBRARY
+  NAMES z
+  PATHS ${Z_PKGCONF_LIBRARY_DIRS}
+)
+
+set(Z_PROCESS_INCLUDES Z_INCLUDE_DIR)
+set(Z_PROCESS_LIBS Z_LIBRARY)
+libfind_process(Z)
+
diff --git a/cmake/Modules/LibFindMacros.cmake b/cmake/Modules/LibFindMacros.cmake
new file mode 100644 (file)
index 0000000..3ef5844
--- /dev/null
@@ -0,0 +1,266 @@
+# Version 2.2
+# Public Domain, originally written by Lasse Kärkkäinen <tronic>
+# Maintained at https://github.com/Tronic/cmake-modules
+# Please send your improvements as pull requests on Github.
+
+# Find another package and make it a dependency of the current package.
+# This also automatically forwards the "REQUIRED" argument.
+# Usage: libfind_package(<prefix> <another package> [extra args to find_package])
+macro (libfind_package PREFIX PKG)
+  set(${PREFIX}_args ${PKG} ${ARGN})
+  if (${PREFIX}_FIND_REQUIRED)
+    set(${PREFIX}_args ${${PREFIX}_args} REQUIRED)
+  endif()
+  find_package(${${PREFIX}_args})
+  set(${PREFIX}_DEPENDENCIES ${${PREFIX}_DEPENDENCIES};${PKG})
+  unset(${PREFIX}_args)
+endmacro()
+
+# A simple wrapper to make pkg-config searches a bit easier.
+# Works the same as CMake's internal pkg_check_modules but is always quiet.
+macro (libfind_pkg_check_modules)
+  find_package(PkgConfig QUIET)
+  if (PKG_CONFIG_FOUND)
+    pkg_check_modules(${ARGN} QUIET)
+  endif()
+endmacro()
+
+# Avoid useless copy&pasta by doing what most simple libraries do anyway:
+# pkg-config, find headers, find library.
+# Usage: libfind_pkg_detect(<prefix> <pkg-config args> FIND_PATH <name> [other args] FIND_LIBRARY <name> [other args])
+# E.g. libfind_pkg_detect(SDL2 sdl2 FIND_PATH SDL.h PATH_SUFFIXES SDL2 FIND_LIBRARY SDL2)
+function (libfind_pkg_detect PREFIX)
+  # Parse arguments
+  set(argname pkgargs)
+  foreach (i ${ARGN})
+    if ("${i}" STREQUAL "FIND_PATH")
+      set(argname pathargs)
+    elseif ("${i}" STREQUAL "FIND_LIBRARY")
+      set(argname libraryargs)
+    else()
+      set(${argname} ${${argname}} ${i})
+    endif()
+  endforeach()
+  if (NOT pkgargs)
+    message(FATAL_ERROR "libfind_pkg_detect requires at least a pkg_config package name to be passed.")
+  endif()
+  # Find library
+  libfind_pkg_check_modules(${PREFIX}_PKGCONF ${pkgargs})
+  if (pathargs)
+    find_path(${PREFIX}_INCLUDE_DIR NAMES ${pathargs} HINTS ${${PREFIX}_PKGCONF_INCLUDE_DIRS})
+  endif()
+  if (libraryargs)
+    find_library(${PREFIX}_LIBRARY NAMES ${libraryargs} HINTS ${${PREFIX}_PKGCONF_LIBRARY_DIRS})
+  endif()
+endfunction()
+
+# Extracts a version #define from a version.h file, output stored to <PREFIX>_VERSION.
+# Usage: libfind_version_header(Foobar foobar/version.h FOOBAR_VERSION_STR)
+# Fourth argument "QUIET" may be used for silently testing different define names.
+# This function does nothing if the version variable is already defined.
+function (libfind_version_header PREFIX VERSION_H DEFINE_NAME)
+  # Skip processing if we already have a version or if the include dir was not found
+  if (${PREFIX}_VERSION OR NOT ${PREFIX}_INCLUDE_DIR)
+    return()
+  endif()
+  set(quiet ${${PREFIX}_FIND_QUIETLY})
+  # Process optional arguments
+  foreach(arg ${ARGN})
+    if (arg STREQUAL "QUIET")
+      set(quiet TRUE)
+    else()
+      message(AUTHOR_WARNING "Unknown argument ${arg} to libfind_version_header ignored.")
+    endif()
+  endforeach()
+  # Read the header and parse for version number
+  set(filename "${${PREFIX}_INCLUDE_DIR}/${VERSION_H}")
+  if (NOT EXISTS ${filename})
+    if (NOT quiet)
+      message(AUTHOR_WARNING "Unable to find ${${PREFIX}_INCLUDE_DIR}/${VERSION_H}")
+    endif()
+    return()
+  endif()
+  file(READ "${filename}" header)
+  string(REGEX REPLACE ".*#[ \t]*define[ \t]*${DEFINE_NAME}[ \t]*\"([^\n]*)\".*" "\\1" match "${header}")
+  # No regex match?
+  if (match STREQUAL header)
+    if (NOT quiet)
+      message(AUTHOR_WARNING "Unable to find \#define ${DEFINE_NAME} \"<version>\" from ${${PREFIX}_INCLUDE_DIR}/${VERSION_H}")
+    endif()
+    return()
+  endif()
+  # Export the version string
+  set(${PREFIX}_VERSION "${match}" PARENT_SCOPE)
+endfunction()
+
+# Do the final processing once the paths have been detected.
+# If include dirs are needed, ${PREFIX}_PROCESS_INCLUDES should be set to contain
+# all the variables, each of which contain one include directory.
+# Ditto for ${PREFIX}_PROCESS_LIBS and library files.
+# Will set ${PREFIX}_FOUND, ${PREFIX}_INCLUDE_DIRS and ${PREFIX}_LIBRARIES.
+# Also handles errors in case library detection was required, etc.
+function (libfind_process PREFIX)
+  # Skip processing if already processed during this configuration run
+  if (${PREFIX}_FOUND)
+    return()
+  endif()
+
+  set(found TRUE)  # Start with the assumption that the package was found
+
+  # Did we find any files? Did we miss includes? These are for formatting better error messages.
+  set(some_files FALSE)
+  set(missing_headers FALSE)
+
+  # Shorthands for some variables that we need often
+  set(quiet ${${PREFIX}_FIND_QUIETLY})
+  set(required ${${PREFIX}_FIND_REQUIRED})
+  set(exactver ${${PREFIX}_FIND_VERSION_EXACT})
+  set(findver "${${PREFIX}_FIND_VERSION}")
+  set(version "${${PREFIX}_VERSION}")
+
+  # Lists of config option names (all, includes, libs)
+  unset(configopts)
+  set(includeopts ${${PREFIX}_PROCESS_INCLUDES})
+  set(libraryopts ${${PREFIX}_PROCESS_LIBS})
+
+  # Process deps to add to 
+  foreach (i ${PREFIX} ${${PREFIX}_DEPENDENCIES})
+    if (DEFINED ${i}_INCLUDE_OPTS OR DEFINED ${i}_LIBRARY_OPTS)
+      # The package seems to export option lists that we can use, woohoo!
+      list(APPEND includeopts ${${i}_INCLUDE_OPTS})
+      list(APPEND libraryopts ${${i}_LIBRARY_OPTS})
+    else()
+      # If plural forms don't exist or they equal singular forms
+      if ((NOT DEFINED ${i}_INCLUDE_DIRS AND NOT DEFINED ${i}_LIBRARIES) OR
+          ({i}_INCLUDE_DIR STREQUAL ${i}_INCLUDE_DIRS AND ${i}_LIBRARY STREQUAL ${i}_LIBRARIES))
+        # Singular forms can be used
+        if (DEFINED ${i}_INCLUDE_DIR)
+          list(APPEND includeopts ${i}_INCLUDE_DIR)
+        endif()
+        if (DEFINED ${i}_LIBRARY)
+          list(APPEND libraryopts ${i}_LIBRARY)
+        endif()
+      else()
+        # Oh no, we don't know the option names
+        message(FATAL_ERROR "We couldn't determine config variable names for ${i} includes and libs. Aieeh!")
+      endif()
+    endif()
+  endforeach()
+  
+  if (includeopts)
+    list(REMOVE_DUPLICATES includeopts)
+  endif()
+  
+  if (libraryopts)
+    list(REMOVE_DUPLICATES libraryopts)
+  endif()
+
+  string(REGEX REPLACE ".*[ ;]([^ ;]*(_INCLUDE_DIRS|_LIBRARIES))" "\\1" tmp "${includeopts} ${libraryopts}")
+  if (NOT tmp STREQUAL "${includeopts} ${libraryopts}")
+    message(AUTHOR_WARNING "Plural form ${tmp} found in config options of ${PREFIX}. This works as before but is now deprecated. Please only use singular forms INCLUDE_DIR and LIBRARY, and update your find scripts for LibFindMacros > 2.0 automatic dependency system (most often you can simply remove the PROCESS variables entirely).")
+  endif()
+
+  # Include/library names separated by spaces (notice: not CMake lists)
+  unset(includes)
+  unset(libs)
+
+  # Process all includes and set found false if any are missing
+  foreach (i ${includeopts})
+    list(APPEND configopts ${i})
+    if (NOT "${${i}}" STREQUAL "${i}-NOTFOUND")
+      list(APPEND includes "${${i}}")
+    else()
+      set(found FALSE)
+      set(missing_headers TRUE)
+    endif()
+  endforeach()
+
+  # Process all libraries and set found false if any are missing
+  foreach (i ${libraryopts})
+    list(APPEND configopts ${i})
+    if (NOT "${${i}}" STREQUAL "${i}-NOTFOUND")
+      list(APPEND libs "${${i}}")
+    else()
+      set (found FALSE)
+    endif()
+  endforeach()
+
+  # Version checks
+  if (found AND findver)
+    if (NOT version)
+      message(WARNING "The find module for ${PREFIX} does not provide version information, so we'll just assume that it is OK. Please fix the module or remove package version requirements to get rid of this warning.")
+    elseif (version VERSION_LESS findver OR (exactver AND NOT version VERSION_EQUAL findver))
+      set(found FALSE)
+      set(version_unsuitable TRUE)
+    endif()
+  endif()
+
+  # If all-OK, hide all config options, export variables, print status and exit
+  if (found)
+    foreach (i ${configopts})
+      mark_as_advanced(${i})
+    endforeach()
+    if (NOT quiet)
+      message(STATUS "Found ${PREFIX} ${${PREFIX}_VERSION}")
+      if (LIBFIND_DEBUG)
+        message(STATUS "  ${PREFIX}_DEPENDENCIES=${${PREFIX}_DEPENDENCIES}")
+        message(STATUS "  ${PREFIX}_INCLUDE_OPTS=${includeopts}")
+        message(STATUS "  ${PREFIX}_INCLUDE_DIRS=${includes}")
+        message(STATUS "  ${PREFIX}_LIBRARY_OPTS=${libraryopts}")
+        message(STATUS "  ${PREFIX}_LIBRARIES=${libs}")
+      endif()
+      set (${PREFIX}_INCLUDE_OPTS ${includeopts} PARENT_SCOPE)
+      set (${PREFIX}_LIBRARY_OPTS ${libraryopts} PARENT_SCOPE)
+      set (${PREFIX}_INCLUDE_DIRS ${includes} PARENT_SCOPE)
+      set (${PREFIX}_LIBRARIES ${libs} PARENT_SCOPE)
+      set (${PREFIX}_FOUND TRUE PARENT_SCOPE)
+    endif()
+    return()    
+  endif()
+
+  # Format messages for debug info and the type of error
+  set(vars "Relevant CMake configuration variables:\n")
+  foreach (i ${configopts})
+    mark_as_advanced(CLEAR ${i})
+    set(val ${${i}})
+    if ("${val}" STREQUAL "${i}-NOTFOUND")
+      set (val "<not found>")
+    elseif (val AND NOT EXISTS ${val})
+      set (val "${val}  (does not exist)")
+    else()
+      set(some_files TRUE)
+    endif()
+    set(vars "${vars}  ${i}=${val}\n")
+  endforeach()
+  set(vars "${vars}You may use CMake GUI, cmake -D or ccmake to modify the values. Delete CMakeCache.txt to discard all values and force full re-detection if necessary.\n")
+  if (version_unsuitable)
+    set(msg "${PREFIX} ${${PREFIX}_VERSION} was found but")
+    if (exactver)
+      set(msg "${msg} only version ${findver} is acceptable.")
+    else()
+      set(msg "${msg} version ${findver} is the minimum requirement.")
+    endif()
+  else()
+    if (missing_headers)
+      set(msg "We could not find development headers for ${PREFIX}. Do you have the necessary dev package installed?")
+    elseif (some_files)
+      set(msg "We only found some files of ${PREFIX}, not all of them. Perhaps your installation is incomplete or maybe we just didn't look in the right place?")
+      if(findver)
+        set(msg "${msg} This could also be caused by incompatible version (if it helps, at least ${PREFIX} ${findver} should work).")
+      endif()
+    else()
+      set(msg "We were unable to find package ${PREFIX}.")
+    endif()
+  endif()
+
+  # Fatal error out if REQUIRED
+  if (required)
+    set(msg "REQUIRED PACKAGE NOT FOUND\n${msg} This package is REQUIRED and you need to install it or adjust CMake configuration in order to continue building ${CMAKE_PROJECT_NAME}.")
+    message(FATAL_ERROR "${msg}\n${vars}")
+  endif()
+  # Otherwise just print a nasty warning
+  if (NOT quiet)
+    message(WARNING "WARNING: MISSING PACKAGE\n${msg} This package is NOT REQUIRED and you may ignore this warning but by doing so you may miss some functionality of ${CMAKE_PROJECT_NAME}. \n${vars}")
+  endif()
+endfunction()
+
diff --git a/cmake/performous.sh.cmake b/cmake/performous.sh.cmake
new file mode 100644 (file)
index 0000000..a8896b2
--- /dev/null
@@ -0,0 +1,4 @@
+#!/bin/sh
+
+env DYLD_LIBRARY_PATH='@CMAKE_INSTALL_PREFIX@/lib@LIB_SUFFIX@:$DYLD_LIBRARY_PATH' LD_LIBRARY_PATH='@CMAKE_INSTALL_PREFIX@/lib@LIB_SUFFIX@:$LD_LIBRARY_PATH' PERFORMOUS_DATA_DIR='@CMAKE_INSTALL_PREFIX@/@SHARE_INSTALL@' PLUGIN_PATH='@PERFORMOUS_PLUGIN_PATH@' '@PERFORMOUS_EXECUTABLE@' "$@"
+
diff --git a/data/CMakeLists.txt b/data/CMakeLists.txt
new file mode 100644 (file)
index 0000000..cf1e5a4
--- /dev/null
@@ -0,0 +1,18 @@
+set(APPLICATION_FILE "performous.desktop")
+set(PIXMAP_FILE      "themes/default/icon.svg")
+
+# Install launcher and fonts on system level
+if(APPLE)
+       install(FILES ${APPLICATION_FILE} DESTINATION "Resources/applications/")
+       install(FILES ${PIXMAP_FILE} DESTINATION "Resources/pixmaps/" RENAME "performous.svg")
+       #file(GLOB FONT_FILES "fonts/*")
+       #install(FILES ${FONT_FILES} DESTINATION "Resources/fonts/truetype/performous")
+elseif(UNIX)
+       install(FILES ${APPLICATION_FILE} DESTINATION "share/applications/")
+       install(FILES ${PIXMAP_FILE} DESTINATION "share/pixmaps/" RENAME "performous.svg")
+       #file(GLOB FONT_FILES "fonts/*")
+       #install(FILES ${FONT_FILES} DESTINATION "share/fonts/truetype/performous")
+endif()
+
+install(DIRECTORY backgrounds config fonts shaders sounds themes xsl DESTINATION ${SHARE_INSTALL})
+
diff --git a/data/backgrounds/blue_band.svg b/data/backgrounds/blue_band.svg
new file mode 100644 (file)
index 0000000..b2af087
--- /dev/null
@@ -0,0 +1,321 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Sodipodi ("http://www.sodipodi.com/") -->
+
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://creativecommons.org/ns#"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:xlink="http://www.w3.org/1999/xlink"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   version="1.0"
+   x="0"
+   y="0"
+   width="1000"
+   height="800"
+   id="svg559"
+   sodipodi:version="0.32"
+   inkscape:version="0.48.0 r9654"
+   sodipodi:docname="blue_band.svg"
+   inkscape:output_extension="org.inkscape.output.svg.inkscape">
+  <metadata
+     id="metadata35">
+    <rdf:RDF>
+      <cc:Work
+         rdf:about="">
+        <dc:format>image/svg+xml</dc:format>
+        <dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+      </cc:Work>
+    </rdf:RDF>
+  </metadata>
+  <sodipodi:namedview
+     inkscape:window-height="1026"
+     inkscape:window-width="1920"
+     inkscape:pageshadow="2"
+     inkscape:pageopacity="0.0"
+     guidetolerance="10.0"
+     gridtolerance="10.0"
+     objecttolerance="10.0"
+     borderopacity="1.0"
+     bordercolor="#666666"
+     pagecolor="#ffffff"
+     id="base"
+     inkscape:zoom="0.87006002"
+     inkscape:cx="551.04461"
+     inkscape:cy="380.19238"
+     inkscape:window-x="0"
+     inkscape:window-y="0"
+     inkscape:current-layer="g5712"
+     showgrid="false"
+     showguides="true"
+     inkscape:guide-bbox="true"
+     inkscape:window-maximized="1"
+     borderlayer="true" />
+  <defs
+     id="defs561">
+    <linearGradient
+       id="linearGradient5859">
+      <stop
+         style="stop-color:#3011ff;stop-opacity:0.03045685;"
+         offset="0"
+         id="stop5861" />
+      <stop
+         id="stop5867"
+         offset="0.5"
+         style="stop-color:#2f0ed4;stop-opacity:0.13197969;" />
+      <stop
+         style="stop-color:#3700f8;stop-opacity:0.05076142;"
+         offset="1"
+         id="stop5863" />
+    </linearGradient>
+    <filter
+       id="filter5083"
+       inkscape:collect="always">
+      <feGaussianBlur
+         id="feGaussianBlur5085"
+         stdDeviation="2.8444007"
+         inkscape:collect="always" />
+    </filter>
+    <filter
+       inkscape:collect="always"
+       id="filter5839">
+      <feGaussianBlur
+         inkscape:collect="always"
+         stdDeviation="4.1497249"
+         id="feGaussianBlur5841" />
+    </filter>
+    <radialGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient5859"
+       id="radialGradient5865"
+       cx="862.00952"
+       cy="-39.022575"
+       fx="862.00952"
+       fy="-39.022575"
+       r="156.0404"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(0.99999689,-0.00249522,0.00249523,1,0.10005383,2.1509078)" />
+  </defs>
+  <text
+     xml:space="preserve"
+     style="font-size:21.12607765px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;font-family:Bitstream Vera Sans"
+     x="225.09085"
+     y="770.20593"
+     id="text2508-0"
+     transform="scale(1.181198,0.84659815)"><tspan
+       sodipodi:role="line"
+       id="tspan2510-6"
+       x="225.09085"
+       y="770.20593" /></text>
+  <g
+     id="g3955"
+     transform="matrix(1.0023828,0,0,0.71843624,16.811257,63.593811)"
+     style="opacity:0.6;filter:url(#filter5083)" />
+  <g
+     id="g4892"
+     transform="matrix(0.99958974,0,0,0.71843624,-0.03697497,106.10154)">
+    <g
+       transform="matrix(1.2468256,0,0,1.1986102,1.2039301,52.246604)"
+       id="g2836" />
+    <g
+       transform="matrix(1.2468256,0,0,1.1986102,0.760128,231.91957)"
+       id="g2209" />
+    <g
+       transform="matrix(5.0734563,0,0,5.3232265,22.200477,397.25206)"
+       id="g2411">
+      <g
+         transform="translate(-230.9546,-533.6597)"
+         style="fill:#000000;fill-opacity:1"
+         id="g2883" />
+      <g
+         transform="translate(-230.9546,-533.6597)"
+         style="fill:#000000;fill-opacity:1"
+         id="g2887" />
+      <g
+         transform="translate(-230.9546,-533.6597)"
+         style="fill:#000000;fill-opacity:1"
+         id="g2891" />
+    </g>
+    <g
+       inkscape:label="Calque 1"
+       id="layer1-4"
+       transform="matrix(1.2842911,0,0,1.3475176,-322.83945,-416.05452)" />
+  </g>
+  <g
+     id="g3873"
+     transform="matrix(0.98299439,0,0,0.7023051,37.837667,110.80445)" />
+  <rect
+     style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1.17483747;stroke-opacity:1"
+     id="rect3853"
+     width="1008.9509"
+     height="810.11407"
+     x="-2.2112732"
+     y="-1.0067407" />
+  <text
+     xml:space="preserve"
+     style="font-size:24.89476013px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;font-family:Bitstream Vera Sans"
+     x="266.96185"
+     y="736.90112"
+     id="text2508"><tspan
+       sodipodi:role="line"
+       id="tspan2510"
+       x="266.96185"
+       y="736.90112" /></text>
+  <g
+     id="g5712"
+     transform="translate(-5.9229528,166.37207)">
+    <path
+       id="path5714"
+       d="m 89,134 c 0,-0.667 0,-1.333 0,-2 2.134,-0.467 1.905,1.429 2,3 -0.81,-0.19 -0.997,-1.003 -2,-1 z"
+       clip-rule="evenodd"
+       inkscape:connector-curvature="0"
+       style="fill-rule:evenodd" />
+    <path
+       id="path5716"
+       d="m 101,137 c -2.974,0.212 -3.526,-3.566 -2,-5 3.462,-0.701 3.586,3.506 2,5 z"
+       clip-rule="evenodd"
+       inkscape:connector-curvature="0"
+       style="fill-rule:evenodd" />
+    <path
+       id="path5718"
+       d="m 98,137 c -1.464,-0.87 -3.169,-1.497 -3,-4 1.464,0.87 3.169,1.497 3,4 z"
+       clip-rule="evenodd"
+       inkscape:connector-curvature="0"
+       style="fill-rule:evenodd" />
+    <path
+       id="path5720"
+       d="m 89,134 c 0.55,2.217 -1.91,1.424 -2,3 -2.491,-0.407 -0.06,-3.877 2,-3 z"
+       clip-rule="evenodd"
+       inkscape:connector-curvature="0"
+       style="fill-rule:evenodd" />
+    <path
+       id="path5722"
+       d="m 101,137 c 3.131,-0.464 4.464,0.869 4,4 -1.333,0 -2.667,0 -4,0 0,-1.333 0,-2.667 0,-4 z"
+       clip-rule="evenodd"
+       inkscape:connector-curvature="0"
+       style="fill-rule:evenodd" />
+    <path
+       id="path5724"
+       d="m 91,138 c 3.952,0.319 -0.741,3.095 2,4 -1.697,3.502 -2.569,-1.954 -2,-4 z"
+       clip-rule="evenodd"
+       inkscape:connector-curvature="0"
+       style="fill-rule:evenodd" />
+    <path
+       id="path5726"
+       d="m 427,158 c 0.345,-1.206 2.661,-0.809 3,0 0.907,2.163 -3.662,2.317 -3,0 z"
+       clip-rule="evenodd"
+       inkscape:connector-curvature="0"
+       style="fill-rule:evenodd" />
+    <path
+       id="path5728"
+       d="m 414,161 c 2.917,-1.47 2.917,4.47 0,3 0,-1 0,-2 0,-3 z"
+       clip-rule="evenodd"
+       inkscape:connector-curvature="0"
+       style="fill-rule:evenodd" />
+    <path
+       id="path5730"
+       d="m 99,216 c 1.519,2.481 3.929,4.071 4,8 -3.245,-0.756 -4.344,-3.656 -4,-8 z"
+       clip-rule="evenodd"
+       inkscape:connector-curvature="0"
+       style="fill-rule:evenodd" />
+    <path
+       id="path5732"
+       d="m 95,223 c 1.342,0.658 1.862,2.138 2,4 -1.759,-0.241 -2.279,-1.721 -2,-4 z"
+       clip-rule="evenodd"
+       inkscape:connector-curvature="0"
+       style="fill-rule:evenodd" />
+    <path
+       id="path5734"
+       d="m 251,228 c -1.742,-0.924 -5.367,0.034 -5,-3 1.481,-1.497 5.169,-0.093 5,3 z"
+       clip-rule="evenodd"
+       inkscape:connector-curvature="0"
+       style="fill-rule:evenodd" />
+    <path
+       id="path5736"
+       d="m 250,233 c -0.318,-1.766 5.603,-1.785 4,1 -1.794,0.127 -2.109,-1.224 -4,-1 z"
+       clip-rule="evenodd"
+       inkscape:connector-curvature="0"
+       style="fill-rule:evenodd" />
+    <path
+       id="path5738"
+       d="m 242,261 c 1.975,0.691 2.666,2.667 3,5 -1.278,1.367 -4.722,1.367 -6,0 -0.424,-2.09 0.686,-2.647 1,-4 2.59,1.366 3.143,3.23 2,-1 z"
+       clip-rule="evenodd"
+       inkscape:connector-curvature="0"
+       style="fill-rule:evenodd" />
+    <path
+       id="path5740"
+       d="m 231,265 c 2.398,-2.502 4.72,3.898 3,-2 4.581,-1.656 3.16,4.855 2,6 -3.418,0.418 -5.698,-0.302 -5,-4 z"
+       clip-rule="evenodd"
+       inkscape:connector-curvature="0"
+       style="fill-rule:evenodd" />
+    <path
+       id="path5742"
+       d="m 378,295 c 4.754,3.094 -0.701,10.583 0,16 -2.341,-3.715 1.356,-9.946 0,-16 z"
+       clip-rule="evenodd"
+       inkscape:connector-curvature="0"
+       style="fill-rule:evenodd" />
+    <path
+       id="path5744"
+       d="m 135,303 c -0.733,1.78 -1.818,0.145 -3,0 0.733,-1.78 1.818,-0.145 3,0 z"
+       clip-rule="evenodd"
+       inkscape:connector-curvature="0"
+       style="fill-rule:evenodd" />
+    <path
+       sodipodi:type="star"
+       style="fill:url(#radialGradient5865);fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path5855"
+       sodipodi:sides="16"
+       sodipodi:cx="862.00952"
+       sodipodi:cy="-39.022575"
+       sodipodi:r1="173.08147"
+       sodipodi:r2="59.541275"
+       sodipodi:arg1="0.6267365"
+       sodipodi:arg2="1.2882254"
+       inkscape:flatsided="false"
+       inkscape:rounded="0"
+       inkscape:randomized="0"
+       d="M 1002.1961,62.490506 878.61115,18.157398 952.6777,108.41038 855.4656,20.158 889.35584,131.88492 833.3163,13.148895 821.87076,129.34035 815.53528,-1.8028426 760.49644,101.16404 804.82955,-22.420947 714.57657,51.645599 802.82895,-45.5665 691.10202,-11.676254 809.83805,-67.715799 693.6466,-79.161336 824.78979,-85.496815 721.8229,-140.53566 l 123.58499,44.333111 -74.06654,-90.252981 97.2121,88.252379 -33.89025,-111.726919 56.03954,118.736024 11.44554,-116.191454 6.33548,131.143192 55.03884,-102.966892 -44.3331,123.584997 90.253,-74.066547 -88.2524,97.212099 L 1032.917,-66.368897 914.18099,-10.329352 1030.3724,1.1161856 899.22925,7.451664 z"
+       transform="matrix(3.4159314,0,0,2.8005976,-2458.2158,330.87392)"
+       inkscape:transform-center-x="37.629367"
+       inkscape:transform-center-y="-11.399679" />
+    <path
+       id="path5746"
+       d="m 344.72097,0.94398594 c -2.91745,3.67813996 -8.50391,4.68726496 -6.59559,13.19117806 10.60571,3.27581 4.56415,-10.0912511 13.19118,-8.7941191 -2.96362,8.3104431 0.88161,10.6760611 -4.39706,17.5882381 -5.66781,-0.529845 3.01858,-3.783669 0,-8.794119 -14.96979,5.102788 3.8936,38.705116 -26.38236,35.176476 -8.54128,16.381245 -0.4375,29.636181 8.79412,39.573536 4.99286,7.888324 -5.84589,6.07014 -8.79412,10.992648 -3.77048,6.294386 -0.0484,18.496226 -10.99265,19.786766 2.89107,10.81897 1.68628,21.93913 0,32.97795 -6.93856,-1.07508 -7.763,3.96175 -15.3897,2.19853 9.15907,4.08486 12.08971,20.94539 10.99265,28.58088 -3.04717,-5.90965 -6.22844,-3.23184 -8.79412,2.19853 -3.91559,-1.61152 -0.31659,-3.99692 0,-6.59559 -6.37574,0.39574 -5.29846,10.44962 2.19853,8.79412 -1.61153,2.05343 -3.99693,3.33077 -6.59559,4.39706 19.76698,18.34014 22.99442,53.22201 41.77206,72.55148 28.35884,-20.74093 23.38576,-74.81596 41.77207,-105.52942 -6.95835,-11.36201 -29.60541,-7.0353 -37.37501,-17.58824 0,-49.236074 39.56254,-15.56999 54.96324,-2.19853 27.35411,-10.59691 58.0302,7.87513 61.55884,35.17647 3.94196,-0.27921 4.6367,2.691 8.79412,2.19853 2.093,-18.09609 1.91931,-54.4224 15.3897,-68.15442 14.31243,-2.32604 35.67115,-22.429397 46.16913,-2.19853 5.29626,0.8992 4.7796,-4.01451 10.99265,-2.19853 5.74695,8.90845 10.11543,19.19976 19.78676,24.18383 4.51578,29.4537 11.77531,65.10946 -8.79412,81.3456 0,3.66495 0,7.3277 0,10.99265 6.27901,6.95615 20.9102,17.13754 17.58824,26.38235 5.3468,9.30858 15.01594,14.29704 17.58822,26.38236 -10.1682,-0.0923 -7.06168,-13.4594 -13.19118,-17.58824 -2.61185,18.02355 7.28153,42.53496 13.19118,59.36031 0.94976,-6.14489 -0.67495,-28.58968 0,-41.77207 8.27746,1.98308 8.32143,12.19744 8.79412,21.9853 12.01056,17.30243 14.91922,43.70896 21.98529,65.95588 17.44754,-17.72894 28.18735,-42.16559 48.36766,-57.16176 1.45103,-18.33574 -2.91086,-42.48439 2.19853,-57.16178 -2.20073,-3.02737 -3.62318,0.93878 -6.59559,-4.39705 -2.61625,-15.2644 7.59812,-23.77051 2.19853,-35.17648 -16.63188,-3.5858 -31.63245,6.78906 -50.56619,0 -3.59459,-7.27054 -2.21391,-16.79897 2.19853,-21.9853 27.23759,-1.58734 40.20012,11.09818 68.15443,8.79412 -0.98275,9.2778 -9.4339,11.08499 -6.59559,24.18383 0.32978,4.06728 7.44642,1.3499 8.79412,4.39706 2.96581,24.45644 -5.27867,48.62708 0,68.15442 9.32836,-6.85941 22.68882,-7.42883 26.38235,-21.9853 4.88294,-19.24593 -11.13775,-44.80823 -2.19853,-65.95589 7.20678,-17.0518 25.28749,-14.07059 46.16913,-24.18383 8.04442,3.8892 15.07092,9.26241 21.98529,8.79412 4.0475,10.23416 10.18139,24.04972 2.19853,37.37501 0.68155,2.9834 5.50512,1.82478 8.79412,2.19853 -2.93064,19.78676 -12.74707,32.68994 -17.58824,50.56618 1.91712,5.41058 9.73509,4.92251 8.79412,13.19118 23.68696,3.42751 21.67091,32.56022 35.17648,46.16912 -4.66968,17.86085 10.05388,16.32848 8.79412,30.77941 34.21132,-17.81908 62.68008,-41.38292 96.73535,-59.36029 3.5264,-12.95594 -3.2583,-22.56791 4.397,-30.77942 7.9785,7.76521 10.764,0.14291 17.5883,-4.39706 8.4203,4.3377 18.1268,-1.30812 26.3823,-8.79412 11.085,5.03903 20.4134,11.83029 26.3824,21.9853 -2.2249,5.8371 -3.6166,12.50744 -10.9927,13.19118 2.049,-5.28087 8.8359,-5.81951 6.5956,-15.38971 -2.8647,-6.06354 -11.883,-4.39486 -17.5882,-2.19853 0,-4.39706 0,-8.79412 0,-13.19118 -4.595,-0.92998 -5.8195,1.50819 -8.7942,2.19853 -3.1812,8.31264 6.0416,4.21898 4.3971,10.99265 -7.5146,0.91899 -12.5272,-0.66396 -10.9926,-8.79412 -4.8566,0.27482 -0.9344,9.32616 -2.1986,13.19118 -6.213,-1.81599 -5.6964,3.09773 -10.9926,2.19853 0,-3.66495 0,-7.3277 0,-10.99265 -11.982,-1.03111 -2.5767,12.78005 -6.5956,15.38971 -9.5702,-2.2403 -10.1088,4.54656 -15.3897,6.59559 1.706,1.95669 2.3634,4.96428 2.1985,8.79412 -26.5318,20.55844 -67.93895,43.40336 -98.93382,63.75735 -10.4738,6.8792 -27.68829,13.96067 -28.58089,28.58089 -5.29626,-0.8992 -4.7796,4.01451 -10.99265,2.19853 -0.8992,5.29626 4.01452,4.7796 2.19853,10.99265 -9.7219,0.34956 -15.96352,10.39684 -21.98529,2.19853 2.00945,17.0452 16.97264,21.13446 24.18382,32.97794 1.9501,-5.3776 10.71344,-3.94196 13.19118,-8.79412 5.11378,3.2978 3.35496,5.37541 2.19853,10.99265 3.85402,-2.00945 7.63989,-4.08706 6.59559,-10.99265 -5.681,-6.94735 -13.77599,2.19853 -19.78677,2.19853 -8.10598,-1.42025 -11.53129,-7.52337 -13.19118,-15.3897 29.83405,-20.00003 56.29116,-43.3748 87.94119,-61.55884 1.59394,-5.00165 1.96109,-11.23009 4.39706,-15.3897 3.55063,-0.61779 3.78587,2.07761 6.59559,2.19852 4.22338,-2.8273 -5.18853,-4.54436 0,-10.99264 13.87052,-1.25756 10.3155,-7.37387 21.98531,-8.79412 3.9178,4.87634 8.6578,8.93042 6.5956,19.78676 4.0013,-2.73497 4.3992,-20.37597 -4.3971,-17.58823 15.9591,3.39673 28.0686,-25.97343 46.1691,-13.19117 7.1607,-6.76268 13.9981,-13.85074 19.7868,-21.9853 9.2932,-1.71925 19.2218,2.92844 4.3971,2.19853 -8.3698,7.0199 -15.2402,15.53921 -21.9853,24.18382 -18.4061,-7.80917 -42.7592,3.79906 -39.5736,30.77941 -11.3818,4.74003 -12.4502,19.79557 -17.5882,30.77942 -27.38269,15.8536 -49.87365,36.60112 -94.53678,35.17648 -3.5814,4.4806 -4.61911,11.5027 -8.79412,15.3897 9.5658,0.0396 12.25681,-6.79785 24.18383,-4.39706 7.93889,18.71829 -12.14688,25.05665 -24.18383,30.77942 3.80126,20.38257 20.26385,28.10381 24.18383,48.36765 1.60932,2.05343 3.99693,3.33078 6.59559,4.39706 9.61857,24.8236 19.87471,49.01183 28.58088,74.75001 -9.43828,-6.68353 -8.63142,-23.6122 -17.58823,-30.77941 -1.13005,-28.18295 -20.36059,-38.26761 -26.38236,-61.55883 -2.15896,-2.97242 -5.86568,-4.39267 -8.79412,-6.59559 0,-2.93064 0,-5.86348 0,-8.79412 -0.32978,-4.06728 -7.44642,-1.3499 -8.79412,-4.39706 1.76322,-7.6267 -3.27361,-8.45115 -2.19853,-15.38971 -15.35013,-1.42685 -19.05905,8.78972 -17.58824,24.18383 0.57162,8.2225 18.21262,-0.62439 17.58824,8.79412 -4.00352,-3.35936 -17.98177,-3.35936 -21.98529,0 -0.97395,11.23448 15.55239,4.96867 24.18382,6.59559 10.33529,2.73716 -27.77622,5.03903 -28.58088,-2.19853 -10.23636,24.6631 20.44852,27.48821 24.18382,39.57353 6.2812,-1.14543 -3.54842,-3.25162 -4.39706,-4.39706 4.58394,-6.54942 8.95461,5.5293 15.38971,4.39706 -2.40079,0.80246 -9.19865,9.62516 0,8.79412 -15.20723,3.44729 -24.61254,-17.86745 -35.17647,-26.38236 -2.61186,13.44841 13.72322,24.75105 21.98529,37.37501 8.05102,12.29857 20.35179,26.50327 21.9853,46.16912 1.89513,6.16688 11.44555,4.67628 15.38971,8.79412 -3.18347,0.55183 -20.21988,0.27262 -10.99265,10.99265 -2.75696,-3.17688 -47.03974,-11.31803 -52.76471,2.19853 -1.9523,-46.78471 -9.09092,-90.83226 0,-131.91178 -7.34969,12.44148 -28.50394,24.41027 -46.16913,13.19117 -1.29053,-7.71903 10.39245,-7.23096 4.39706,-13.19117 -11.98858,-3.46928 -2.32824,9.12609 -6.59559,8.79412 -10.70244,1.17401 -10.28912,-8.76554 -17.58824,-10.99265 -5.06321,11.27845 7.0419,15.02915 8.79412,21.98529 0.57602,2.28208 -4.34429,3.92658 -4.39706,6.59559 -0.17808,9.00298 9.66254,16.26033 10.99265,28.58089 -2.55469,-0.35836 -3.91118,0.48587 -4.39706,2.19853 5.41278,20.23747 11.16853,40.12976 8.79412,68.15442 -12.45907,0 -24.91594,0 -37.375,0 -5.06102,-32.31399 -0.78268,-73.96733 -2.19853,-109.92649 -6.54063,31.56649 2.12817,78.34461 -4.39706,109.92649 -9.31957,1.67308 -26.03719,-4.05189 -28.58089,4.39706 -17.23647,-9.88019 -54.05965,-0.17149 -74.74999,-6.59559 -2.57667,0.35396 -1.85556,4.00792 -2.19853,6.59559 -11.25647,-1.58074 -39.36687,-7.55415 -41.77206,2.19853 -8.89525,-13.82216 -42.11064,-3.32638 -61.55883,-6.59559 -2.57668,0.35396 -1.85336,4.00792 -2.19853,6.59559 -0.18908,-3.91998 -18.35553,-6.80225 -13.19118,-2.19853 -6.36035,6.21304 -10.27593,-8.6688 -13.19118,-13.19118 -11.42796,-16.42082 -23.65398,-32.04137 -32.97795,-50.56618 -10.753,-11.23009 -22.24692,-21.72367 -26.38235,-39.57354 -14.02003,-3.02298 -34.64004,7.12544 -50.56619,2.19853 -4.99066,2.33704 -0.83764,13.81996 -2.19853,19.78677 7.42664,-2.83171 6.01518,-14.5059 15.38971,-15.38971 -0.64637,4.4828 -5.94922,4.31132 -6.59559,8.79412 1.97428,5.94483 5.30725,-4.6367 6.59559,-6.59559 9.00958,8.44675 -10.40124,7.06168 -6.59559,17.58824 10.85414,-5.26768 17.2035,-15.04014 26.38236,-21.9853 -4.05629,15.26879 -29.19428,20.66838 -37.37501,35.17648 11.03662,9.82743 27.60694,-9.62956 48.36766,-4.39706 -11.57306,7.63549 -34.6972,16.51755 -48.36766,8.79412 -3.64076,2.22271 -2.3876,9.33715 -4.39705,13.19118 4.97307,7.48379 13.54074,11.37739 21.98529,15.3897 2.49533,-0.41772 1.22019,-2.20512 0,-2.19853 6.15589,-1.68847 24.85438,2.93944 32.97795,6.59559 6.59559,0 13.19118,0 19.78677,0 6.99792,3.02958 -7.76961,2.17435 -10.99265,2.19853 -12.45907,0 -24.91594,0 -37.37501,0 -7.9191,-6.73629 -19.34706,-9.96593 -26.38235,-17.58823 -8.57867,10.87612 5.81071,17.56625 8.79411,24.18382 -4.01231,5.27867 -6.50764,-9.46907 -13.19117,-8.79412 -7.9257,5.26548 -4.39706,21.9853 -10.99265,28.58089 -12.15787,-3.22305 1.0399,-13.12962 2.19853,-17.58824 3.95295,-15.20063 6.96714,-35.23583 10.99265,-50.56618 14.40916,-3.51545 4.08486,-18.11369 6.59558,-32.97795 -6.34275,-6.11411 -19.19096,-5.72497 -30.77941,-6.59559 -5.06102,-0.80246 -2.1018,-9.62516 -8.79412,-8.79412 -3.26262,0.96076 0.86842,2.81192 0,6.59559 -5.18633,-12.06113 -13.93208,0.16269 -24.18383,-4.39706 -0.70133,-5.09839 0.35397,-8.44015 2.19853,-10.99264 -7.70365,0.98274 -4.49819,9.46027 -6.59559,10.99264 -12.51843,1.52578 -18.26098,-3.72431 -30.77941,-2.19853 -5.81292,7.16281 -1.81819,12.32716 -10.99265,17.58824 7.76301,1.76322 7.39585,11.65881 8.79412,19.78677 -3.16589,-0.49907 -0.76729,-6.56041 -4.39706,-6.59559 1.71485,11.42796 9.68452,31.75556 0,43.97059 0.96076,3.26262 2.81412,-0.86841 6.59559,0 -1.69947,13.42643 2.88007,20.56945 2.19853,32.97795 -6.87041,-2.40959 -7.0287,-2.2491 -6.59559,6.59559 -6.45928,-21.34772 -10.31331,-71.35768 -8.79412,-112.12502 -16.18558,2.13697 -17.58164,19.06126 -26.38236,28.58089 6.36035,14.57405 0.52545,29.16789 4.39706,43.97059 8.43796,0.37815 4.75322,-11.37079 13.19118,-10.99264 0.34737,16.11302 -16.93308,22.55691 -8.79412,39.57353 4.68507,-3.37474 6.35375,-9.76807 8.79412,-15.38971 3.77927,7.52337 -7.30352,19.01948 -8.79412,28.58089 -20.04839,-8.19832 -63.00768,-5.5359 -83.544148,0 33.032928,-58.57323 77.876338,-105.33596 109.926508,-164.88973 -13.23955,2.71738 -17.75753,17.45193 -24.18383,26.38236 -7.05288,9.80104 -17.0452,18.25219 -19.78677,30.77941 -29.4559,29.9066 -46.01744,72.70318 -76.948558,101.13237 0,-10.26054 0,-20.51888 0,-30.77942 8.16094,-1.36528 22.627268,3.57481 24.183828,-4.39706 -3.76169,-5.03023 -16.781378,-0.80686 -24.183828,-2.19852 0,-6.59559 0,-13.19118 0,-19.78677 13.92329,0 27.848778,0 41.772088,0 -6.14491,-9.24482 -28.589698,-2.18974 -41.772088,-4.39706 0,-4.39706 0,-8.79412 0,-13.19118 16.121818,0 32.245838,0 48.367678,0 23.28463,-19.21955 34.40039,-50.61015 46.16912,-81.3456 -58.36659,-28.18955 -122.579048,-42.89991 -164.889748,-90.13972 1.71925,-45.18418 30.04731,-63.75735 41.77206,-98.93383 23.39016,-21.31474 35.71952,-53.68809 46.169128,-87.94119 -9.616368,-2.8427 -13.604498,-11.31363 -21.985298,-15.38971 -0.7387,-8.0664 3.37694,-11.28065 8.79412,-13.19117 -3.4341,-3.16149 -7.65088,-5.5403 -8.79412,-10.99265 6.98913,-14.78951 -2.82511,-22.81854 2.19853,-39.57354 1.76762,1.16302 3.57041,2.29307 6.59559,2.19853 0,-4.39706 0,-8.79412 0,-13.191176 -2.70419,0.960756 -4.51578,2.814116 -4.39706,6.595586 -6.67254,-10.416631 14.47732,-11.845675 13.19118,-24.183824 4.641098,2.921846 6.498848,-1.083875 13.191178,2.19853 -1.24437,-2.053427 -6.11191,-3.330772 -2.19853,-4.39706 -0.24404,-5.382001 -7.26834,-0.466088 -6.59559,2.19853 -6.791258,-4.091464 7.65528,-12.072127 10.99265,-6.595589 9.32836,-3.862817 5.6832,-20.699158 19.78679,-19.786768 2.2447,-11.366399 0.80026,-14.292642 0,-26.382357 6.59778,-2.196331 9.14808,-8.440155 15.3897,-10.992648 0.0484,-5.179736 -3.78806,-6.472472 -2.19852,-13.1911791 6.91877,-4.39705896 12.12049,-4.014515 15.3897,-15.3897079 4.7972,-0.400132 6.99572,1.7983979 6.59559,6.5955899 6.21085,-25.3028789 32.01939,-31.0058649 50.56619,-43.9705949 18.19723,1.343302 32.99333,-0.716721 43.97059,-6.595589 6.37354,2.420581 14.86866,2.719581 15.38971,10.992649 2.09959,-3.763883 7.29692,-4.430038 8.79412,-8.794119 10.32209,4.3355 25.7162,3.596794 28.58088,15.389708 9.18986,-7.039692 14.54328,4.957684 21.9853,6.595589 1.4906,15.838208 0.23085,20.9673779 6.59559,30.77941594 z M 335.92685,31.723402 c -9.42729,12.058936 5.48533,8.114773 0,0 l 0,0 z M 300.75038,277.95873 c -4.82138,-29.62079 -7.97847,-60.90807 -19.78677,-83.54413 -7.46621,0.13851 -12.07872,-2.57887 -15.38971,-6.59559 -5.70079,2.82072 1.69287,13.14501 -2.19853,13.19118 -8.35881,1.76322 -2.79433,-10.39685 -4.39706,-15.38971 11.23888,-7.81577 6.2768,-31.83031 17.58824,-39.57353 7.86414,3.12851 15.7041,6.2812 26.38236,6.59559 0.46389,-2.46675 2.44036,-3.42311 4.39705,-4.39706 -0.80466,-10.14842 -2.70639,-12.65254 0,-21.9853 -5.61724,-3.77268 -7.69485,2.51952 -10.99264,-2.19853 -0.93878,-11.19711 0.97175,-19.54933 6.59559,-24.183826 0.37375,3.288996 -0.78488,8.112576 2.19853,8.794116 -0.36936,-4.76641 7.79818,-0.99593 10.99264,-2.19853 2.17435,-11.597241 2.35023,-8.314836 -4.39706,-10.992645 3.75949,-6.595589 8.00265,-2.442567 15.38971,-2.19853 -2.36562,-14.059598 -21.99849,-19.06565 -13.19118,-37.375006 -4.15742,-0.492471 -4.84995,2.477743 -8.79411,2.19853 -3.18348,8.312641 6.04155,4.218978 4.39705,10.992648 -6.92536,-1.061889 -4.97747,6.747288 -13.19117,4.39706 -2.58767,-3.275809 -5.51831,-6.20645 -8.79412,-8.794119 6.96274,-1.831375 11.17512,-6.413111 15.38971,-10.992649 -7.41125,-2.10839 -15.01816,6.734097 -19.78677,0 5.2237,-3.570412 12.64154,-4.946692 17.58824,-8.794119 -12.54262,3.939766 -22.24913,-2.941632 -28.58089,6.59559 6.60218,-0.820052 -3.34616,16.17898 -13.19118,13.191178 2.88667,6.824236 -0.5958,6.274604 0,15.389708 2.58767,0.345169 6.23943,-0.378147 6.59559,2.19853 -10.27373,0.246236 1.56096,4.029905 2.19853,6.59559 -2.80313,4.526772 -3.50666,11.150944 -10.99265,10.992648 -0.32758,-2.928441 8.93922,-6.635163 2.19853,-8.794119 -0.70133,2.545898 -6.80445,10.355075 -8.79412,4.39706 -2.71738,-7.114443 7.11444,-1.679677 4.39706,-8.794119 -8.01584,-7.37387 -20.94539,-9.834024 -24.18383,-21.985298 -4.39705,0 -8.79411,0 -13.19117,0 -0.63318,16.754996 1.95229,30.293542 13.19117,35.176476 -0.11872,-3.781471 1.69287,-5.634832 4.39706,-6.595589 7.14523,14.840075 13.06806,30.902535 17.58824,48.367655 -5.2347,5.74695 -7.71464,18.45885 -17.58824,13.19118 0.9014,14.09257 -15.58977,10.79258 -24.18382,15.3897 8.75454,16.1614 35.5898,14.24428 43.97059,30.77942 -12.54921,-7.99165 -33.75842,-18.97771 -43.97059,-21.9853 27.96749,35.05776 64.01898,62.03152 90.13972,98.93384 z M 258.97831,86.686646 c -7.48819,-11.592848 -4.54656,4.188199 0,0 l 0,0 z m -17.58824,37.375004 c -2.27548,6.18886 -1.06189,17.42555 2.19853,24.18383 7.50578,-7.36508 7.28593,-18.37751 -2.19853,-24.18383 z m 103.3309,149.50002 c -1.70606,-0.49247 -4.3377,-0.0594 -4.39706,-2.19853 9.38113,-4.34429 24.70488,-19.34486 15.38971,-28.58088 -7.09686,9.75927 -14.9522,18.75785 -19.78677,30.77941 4.09366,-2.10179 7.34749,6.5846 8.79412,0 z m 35.17648,-118.7206 c 2.56128,0.36935 2.3876,3.47587 2.19853,6.59559 -6.91658,-2.51952 -5.34243,3.45169 -8.79412,4.39706 -0.65517,21.34772 -14.71037,40.9608 -10.99265,59.3603 2.27548,-3.02738 8.71717,-13.03289 10.99265,-8.79412 1.6445,6.77367 -7.58053,2.68001 -4.39706,10.99265 6.59778,5.95362 10.99484,-3.62538 13.19118,-8.79412 -3.26702,-2.59647 -9.82304,-1.90173 -8.79412,-8.79412 9.82303,-16.98144 14.08598,-37.2387 19.78676,-48.36765 6.25262,2.40299 17.32222,16.38564 24.18383,4.39706 -6.18446,-3.34177 -13.12742,-5.92724 -15.38971,-13.19118 -13.32529,1.82038 -14.96759,2.25349 -21.98529,2.19853 z m 15.3897,-4.39706 c 0.32319,-10.15061 -11.19051,-13.73202 -13.19117,-4.39706 4.4762,0.65296 5.85688,4.40365 8.79411,6.59559 0.48588,-1.71266 1.84017,-2.55689 4.39706,-2.19853 z m 151.69855,76.94854 c 0.4485,6.8792 -1.484,16.1394 2.19853,19.78676 7.17601,0.57822 6.35376,-6.83962 10.99265,-8.79411 -5.39739,-2.66462 -5.87887,-10.24515 -13.19118,-10.99265 z m 70.35293,164.88972 c -13.08784,-27.94991 -11.11796,-70.95974 -30.77941,-92.33824 1.57414,14.31243 7.60471,24.05191 -2.19853,32.97794 7.1716,19.94286 13.69684,40.53429 21.98529,59.3603 -10.11983,6.03716 -20.43973,23.48909 -13.19117,39.57353 21.64012,-8.40717 47.71029,-12.38211 68.15442,-21.98529 -8.83809,0.20446 -17.65859,-9.22943 -35.17648,-6.59559 2.87348,-9.46907 -6.23942,-6.95175 -8.79412,-10.99265 z M 758.04454,187.81901 c -12.52503,-5.94482 -31.76216,4.00572 -43.9706,8.79412 -0.28581,15.48205 -13.83535,25.65464 -6.59559,41.77207 6.65495,-2.57448 11.77972,-6.67254 19.78677,-2.19853 2.05782,-24.09809 21.19383,-22.23813 32.97795,-32.97795 9.33715,2.51072 10.19897,1.06849 13.19117,-6.59559 -3.91338,-1.31472 -9.13049,6.44389 -10.99264,0 5.09619,1.91712 5.05441,-11.18612 2.19852,-4.39706 -7.87293,10.15281 -2.47334,-2.44037 -6.59558,-4.39706 z m 134.11031,175.88237 c -3.02958,-2.8339 -2.17655,-9.55041 -2.19853,-15.3897 -5.45235,2.85369 -10.66947,-4.90492 -10.99265,0 4.84116,1.75442 8.77653,4.41464 8.79412,10.99264 -0.3034,4.09367 -1.44663,7.34749 -4.39706,8.79412 -4.4828,-1.38067 -0.61779,-11.10917 -8.79412,-8.79412 -1.13004,10.93989 2.15236,31.82812 -8.79412,26.38236 3.20546,15.19624 16.41203,-1.71705 24.18383,-2.19853 -0.7431,-16.86492 12.6591,-19.5867 8.7941,-39.57353 -2.7987,-0.44631 -10.76838,-6.39113 -10.99263,-2.19853 8.66883,-1.23338 8.59623,17.6388 4.39706,21.98529 z M 744.85336,493.41464 c -0.0594,5.24349 -9.83842,11.91383 -6.59559,13.19118 3.06915,-2.23371 11.58625,-10.16601 6.59559,-13.19118 z m -43.9706,0 c -15.68871,-1.89953 -17.9466,-17.22988 -28.58088,-24.18383 4.83456,10.69585 15.5524,36.00312 28.58088,24.18383 z m -30.77941,-15.38971 c 0,23.45172 0,46.90123 0,70.35295 7.3277,0 14.65759,0 21.98529,0 -7.40025,-23.37917 -6.44389,-55.11494 -21.98529,-70.35295 z M 89.691502,176.82636 c -0.92558,-4.20359 -0.79587,-9.46247 -6.59559,-8.79412 -0.61998,5.74916 0.80246,9.45588 6.59559,8.79412 z m -2.19853,-46.16912 c -0.97395,-4.15522 2.99,-13.25054 -4.39706,-10.99265 -0.32318,5.45235 -0.40893,10.66947 4.39706,10.99265 z M 151.25035,5.3410449 c -0.69033,2.9724126 -3.1285,4.1991922 -2.19853,8.7941191 6.12291,3.522045 6.07894,-9.4954501 2.19853,-8.7941191 z M 322.73567,-27.6369 c 2.90206,-6.083332 -8.69298,-7.547553 -2.19853,-4.39706 -0.16489,3.08014 0.49028,8.407178 2.19853,4.39706 z m -54.96324,59.360302 c 2.85369,-2.921846 2.89766,-8.180729 -2.19853,-8.794119 0.37375,3.289001 -0.78487,8.112575 2.19853,8.794119 z m 39.57353,-6.595589 c 5.31165,11.307038 5.68101,-7.569538 0,0 l 0,0 z m -13.19117,2.19853 c -7.40685,-6.676935 -6.66595,8.127964 0,0 l 0,0 z m -162.6912,39.573535 c 0.52545,-3.137302 3.61878,-3.70892 4.39706,-6.59559 -4.15742,0.492471 -4.85216,-2.477743 -8.79412,-2.198529 -0.61339,5.010449 0.52984,8.264273 4.39706,8.794119 z m 6.59559,2.198529 c 3.78147,0.118721 5.63483,-1.692868 6.59559,-4.397059 -3.78148,-0.118721 -5.63484,1.692868 -6.59559,4.397059 z m 347.36769,85.742663 c 1.88634,-8.3742 14.64001,-5.88107 19.78677,-10.99265 1.95669,5.3732 5.12477,9.53282 4.39706,17.58824 -8.74575,-3.24284 -15.11269,4.67407 -26.38236,0 -4.88513,12.30956 2.56569,19.29869 10.99265,24.18382 6.10532,-10.0165 11.17952,-21.06631 26.38236,-21.98529 1.65769,9.84721 16.48897,3.11971 19.78677,15.3897 14.71915,-20.50568 -4.74443,-37.64322 -10.99265,-59.3603 -12.4129,3.71112 -6.1317,26.11194 -26.38236,21.9853 0.31879,-2.59866 3.91338,-4.98407 0,-6.59559 -4.02771,7.0265 -21.78083,11.85007 -17.58824,19.78677 z M 91.890032,128.45871 c 6.41311,3.23184 6.41311,-9.82743 0,-6.59559 0,2.19853 0,4.39706 0,6.59559 z m 281.411828,13.19118 c 5.50292,0.37155 6.88139,-3.37694 8.79412,-6.59559 -3.82984,0.16489 -6.83743,-0.49027 -8.79412,-2.19853 0,2.93064 0,5.86348 0,8.79412 z m 48.36765,10.99265 c 0.8948,-4.23657 8.5237,-1.73684 6.59559,-8.79412 -12.32056,4.88513 -12.91636,-13.32089 -21.9853,-4.39706 7.98506,2.61185 -9.04035,9.52623 0,13.19118 -0.73211,-13.45281 14.94781,-9.08653 15.38971,0 z m -274.81621,8.79412 c 1.46641,0 2.93064,0 4.39705,0 0,-1.46642 0,-2.93064 0,-4.39706 -1.46641,0 -2.93064,0 -4.39705,0 0,1.46642 0,2.93064 0,4.39706 z m 2.19852,-8.79412 c -2.34143,-2.5437 -10.12642,-0.80686 -13.19117,2.19853 4.36848,0.0286 2.79433,5.99978 8.79412,4.39706 0.52544,-3.13731 3.61878,-3.70892 4.39705,-6.59559 z m 21.9853,4.39706 c 2.20513,-0.007 2.61625,1.78081 4.39706,2.19853 -0.007,-2.20513 1.78081,-2.61625 2.19853,-4.39706 -2.20512,0.007 -2.61625,-1.78081 -4.39706,-2.19853 0.007,2.20512 -1.78081,2.61625 -2.19853,4.39706 z m 19.78677,-2.19853 c -7.40685,-6.67694 -6.66594,8.12796 0,0 l 0,0 z m 230.84562,6.59559 c 6.76707,-1.53898 4.22557,-1.53898 10.99265,0 0.11872,-3.78148 -1.69287,-5.63484 -4.39706,-6.59559 -0.24404,4.15302 -7.26834,1.52578 -6.59559,6.59559 z m -285.80886,35.17647 c 3.21864,1.91272 6.96714,3.2912 6.59559,8.79412 -11.24109,-3.54403 -13.12962,16.00969 -24.18385,10.99265 -2.51952,9.1151 4.6257,8.56547 4.39706,15.38971 -2.20513,-0.007 -2.61625,1.78081 -4.39706,2.19853 -3.13731,-0.52545 -3.70892,-3.61878 -6.59559,-4.39706 -3.50666,1.62251 0.50126,10.7618 -6.59559,8.79412 -2.40519,9.73289 3.72431,10.93328 4.39706,17.58823 -5.52491,1.805 -10.216568,4.43884 -13.191178,8.79412 12.127088,1.83797 -2.28867,18.29617 -6.59559,10.99265 3.64736,5.14676 6.32737,11.26087 10.992648,15.38971 0.68374,-6.64616 -2.440368,-17.09797 4.39706,-17.58824 2.76355,0.9014 4.49379,2.83391 4.39706,6.59559 -3.16588,-2.46015 -5.36441,-2.37001 -6.59559,2.19853 3.82984,-0.16489 6.83743,0.49247 8.79412,2.19853 3.5924,-12.29198 -0.77608,-19.15799 8.79412,-24.18383 -4.26955,-10.39904 4.23436,-7.15401 -2.19853,-15.3897 9.75709,-1.96989 7.13423,-16.31749 17.58826,-17.58824 -4.30912,1.06189 -7.08147,-10.07806 -2.19853,-10.99265 5.06981,-0.67275 2.44256,6.35155 6.59559,6.59559 6.17786,-5.96022 1.73683,-5.47214 0,-13.19118 4.64109,-1.95449 6.49885,-6.69232 13.19117,-6.59559 1.63791,-6.76707 -6.03496,-4.22557 -4.39706,-10.99265 7.1782,0.58261 4.66089,-8.53029 10.99265,-8.79412 3.21865,-0.0374 6.96714,9.2712 6.59559,0 6.78906,-2.20732 -6.31417,-2.07981 -4.39706,-6.59559 -0.76289,-6.52963 8.21371,-15.18524 0,-19.78676 0.28361,3.94636 -2.18314,5.14456 -6.59559,4.39706 4.58614,11.28725 -6.09432,6.60438 -8.79411,8.79411 -5.53151,4.48501 -3.81226,11.73356 -6.59559,15.38971 5.17973,0.0484 6.47247,-3.78806 13.19117,-2.19853 0,1.46642 0,2.93064 0,4.39706 -6.19106,2.60306 -12.56899,5.01925 -17.58823,8.79412 z m 316.58828,-28.58089 c -3.70672,-1.59833 -10.09785,-11.6522 -15.38971,-4.39705 5.32923,-0.0264 9.06893,12.68331 15.38971,4.39705 z m 96.7353,10.99265 c 6.26362,0.299 8.40278,-11.13775 2.19853,-10.99265 0.70133,5.0984 -0.35176,8.44016 -2.19853,10.99265 z m -160.49267,6.59559 c 2.58767,0.34517 6.23943,-0.37814 6.59559,2.19853 -7.1738,-0.57821 -6.35155,6.83963 -10.99264,8.79412 2.05122,2.34583 8.11037,0.68374 6.59558,6.59559 -5.35561,-1.42025 -11.30923,-4.44103 -10.99264,4.39706 5.51611,5.25668 7.36287,-5.55568 15.3897,-4.39706 -0.033,5.8283 1.22019,12.94494 -4.39706,13.19118 2.11719,-6.53843 -10.80137,-2.01605 -10.99264,-2.19853 2.57887,3.2846 9.13489,2.58987 8.79411,8.79412 -6.09652,16.55493 -18.9909,28.46216 -21.98529,37.375 0.64637,-1.95449 5.94922,-9.62516 6.59559,-4.39706 -2.9966,2.79873 -3.39453,10.7684 2.19853,10.99265 0.40892,-3.25602 5.31384,-2.01605 8.79412,-2.19853 1.58513,-8.6732 3.49566,-17.02321 6.59558,-24.18382 -4.23656,38.2698 -7.31231,77.69823 -19.78676,107.72795 4.85435,0.27481 0.93437,9.32616 2.19853,13.19117 -8.74575,11.04102 -7.76741,31.80833 -17.58824,41.77207 1.17401,-6.36694 -8.56767,3.37254 -2.19853,2.19853 5.15555,-1.06629 0.43531,23.08456 -6.59559,24.18382 -5.86348,0 -11.72476,0 -17.58824,0 11.74675,25.62827 17.33981,57.41021 26.38236,85.74266 7.25075,3.7419 15.82721,6.16028 15.38971,17.58824 25.5601,-7.41784 42.93948,-23.01641 63.75736,-35.17647 1.27734,-8.60505 -1.89074,-12.76687 -4.39706,-17.58824 8.25768,-3.46708 9.40091,-14.0508 10.99265,-24.18383 -21.18723,0.077 -33.38907,-13.50337 -26.38236,-35.17647 -9.40531,-8.91724 -16.37245,-20.27045 -24.18383,-30.77942 5.61945,-57.1156 8.95901,-133.18912 46.16913,-160.49266 9.42729,-6.91658 40.54528,-1.91053 35.17647,-19.78677 -17.84326,9.73509 -23.75071,-11.39058 -35.17647,-15.38971 -18.74467,2.50852 -18.86778,23.63639 -37.37501,26.38236 0.38694,9.18106 -6.81544,10.77279 -8.79412,17.58824 4.16182,-24.41907 27.79821,-29.36357 39.57354,-46.16913 -4.38607,-2.20952 -3.46928,-9.7219 -10.99265,-8.79412 -3.00759,3.86062 -10.66507,8.86228 -15.38971,4.39706 2.02045,5.5293 4.21898,15.07972 -4.39706,15.38971 -2.46675,-0.46389 -3.42311,-2.44037 -4.39706,-4.39706 0.81566,-15.66452 8.69739,-10.6101 13.19118,-21.9853 -7.89052,-1.29493 -10.63648,2.5547 -15.38971,4.39706 0.61339,-3.30219 9.45368,-9.25801 4.39706,-10.99265 -3.39453,4.66748 -6.32517,9.79665 -8.79412,15.38971 z m -270.41917,-4.39706 c 5.06981,-0.67275 2.44256,6.35156 6.59559,6.59559 -1.02452,-8.65561 4.60814,-11.41696 -2.19853,-15.38971 2.51951,6.91658 -3.4517,5.34243 -4.39706,8.79412 z m 360.55889,0 c -0.65296,-1.94789 -4.40365,-11.17073 -6.59559,-4.39706 4.51578,-1.91711 4.38827,11.18612 6.59559,4.39706 z m -37.375,6.59559 c -3.21865,0.0374 -6.96714,-9.2712 -6.59559,0 6.43729,1.97428 6.75388,1.97428 13.19118,0 1.96109,11.23009 12.95373,13.42862 21.98529,17.58824 -4.09366,0.3034 -7.34748,1.44663 -8.79411,4.39706 9.4163,1.35649 8.9634,-7.15841 17.58823,-6.59559 1.37628,-6.67913 -1.95889,-19.79336 -6.59559,-13.19118 4.80599,0.32319 4.72025,5.5403 4.39706,10.99265 -2.80972,0.12092 -3.04496,2.81852 -6.59559,2.19853 -0.70133,-5.16215 -3.47367,-8.25108 -2.19853,-15.38971 -6.37793,-1.68407 -12.64594,-3.47807 -15.3897,-8.79412 1.22018,0.007 2.49533,-1.78081 0,-2.19853 -5.03684,2.29087 -6.10972,8.54789 -10.99265,10.99265 z m 90.13972,2.19853 c -1.06629,-2.59866 -2.34364,-4.98406 -4.39706,-6.59559 -4.53997,7.06608 -12.63715,7.187 -21.9853,4.39706 0.73431,5.12917 2.25349,9.47347 6.59559,10.99265 2.66901,-6.85941 11.63682,-7.41784 17.58824,-10.99265 -0.0945,2.33704 1.0355,5.58427 2.19853,2.19853 z m -334.17652,4.39706 c 3.11532,8.89086 -1.22898,10.02969 4.39706,10.99265 -0.46389,2.46675 -2.44037,3.42311 -4.39706,4.39706 -2.34583,-2.05123 -0.68374,-8.11038 -6.59559,-6.59559 4.76421,6.37794 -4.00132,12.64594 4.39706,15.38971 -0.1583,-7.486 6.46587,-8.18952 10.99265,-10.99265 -0.91899,-8.75894 -3.35716,-17.31782 -4.39706,-15.38971 -0.48588,1.71266 -1.84017,2.55689 -4.39706,2.19853 z m 248.43386,0 c 11.23668,15.73268 -3.2978,-4.61911 0,0 l 0,0 z m -320.98536,6.59559 c 0.598,-2.9922 -1.36089,-8.58306 -2.19853,-4.39706 -0.598,2.9922 1.36089,8.58306 2.19853,4.39706 z m 2.19855,2.19853 c 1.46642,0 2.93064,0 4.39706,0 0,-1.46642 0,-2.93064 0,-4.39706 -1.46642,0 -2.93064,0 -4.39706,0 0,1.46642 0,2.93064 0,4.39706 z m 384.7427,30.77942 c -2.60746,15.79643 5.84149,20.53866 8.79412,30.77941 8.06201,0 16.12182,0 24.18382,0 3.68034,-4.7796 3.52864,-19.80875 -2.19853,-21.98529 -0.50126,3.89579 2.21612,11.01023 -4.39705,8.79411 -2.11719,-16.77478 2.9768,-26.33838 4.39705,-39.57353 -9.31517,9.04475 -40.59804,14.74994 -48.36765,0 0.98055,12.21063 13.47919,12.90317 17.58824,21.9853 z m -32.97795,-24.18383 c 0,1.46642 0,2.93064 0,4.39706 -1.3411,0.12532 -2.60306,0.32758 -2.19853,2.19853 9.46467,1.52798 10.12863,11.85667 17.58824,15.38971 1.84457,-2.5525 2.89986,-5.89426 2.19853,-10.99265 -8.88646,-0.64197 -8.34122,-10.71124 -17.58824,-10.99265 z m 263.82355,10.99265 c -3.00979,5.78433 -9.25581,8.33462 -10.99265,15.38971 12.05454,-6.77807 26.42193,-5.39959 39.57353,-6.59559 -2.56568,-6.96055 -1.74563,-17.30903 -8.79411,-19.78677 -1.15643,8.71497 -16.04707,18.47644 -19.78677,10.99265 z m -485.87505,19.78677 c 2.56129,0.36935 2.3876,3.47587 2.19853,6.59558 -2.93064,0 -5.86348,0 -8.79412,0 -1.20259,-3.19446 2.56788,-11.362 -2.19853,-10.99264 -5.50951,4.64769 -8.16094,-12.2634 -15.38971,-13.19118 1.18061,7.7762 -1.86435,11.32682 -6.59558,13.19118 -0.52545,-3.13731 -3.61878,-3.70892 -4.39706,-6.59559 2.93064,0 5.86347,0 8.79411,0 -0.70133,-5.09839 0.35397,-8.44016 2.19853,-10.99265 -8.17633,-2.31505 -4.31131,7.41564 -8.79411,8.79412 0.11872,-3.78147 -1.69287,-5.63483 -4.39706,-6.59559 -0.24624,5.61724 -4.02991,7.69485 -6.59559,10.99265 -0.49247,-4.15742 2.47774,-4.85216 2.19853,-8.79412 -6.1317,3.49786 -17.97079,13.27912 -8.79412,13.19118 -1.40266,4.46081 -10.27813,1.44883 -10.99265,6.59559 6.41311,4.53776 8.27526,7.08586 17.58824,4.39705 -9.7307,10.94209 10.06706,17.30243 2.19853,26.38236 10.07586,-8.12137 12.7075,2.93724 19.78676,0 -4.9247,-4.60372 -8.0708,-10.98385 -10.99264,-17.58824 7.49039,0.87722 3.62317,6.76928 8.79411,0 0,2.93064 0,5.86348 0,8.79412 8.76994,1.207 6.61978,1.207 15.38971,0 -0.66835,-5.12917 -4.69386,-9.47346 2.19853,-10.99265 3.52644,3.19667 14.67519,10.07367 8.79412,15.38971 -0.24843,-2.6822 -0.65736,-5.20612 -4.39706,-4.39706 -3.44509,3.70672 2.82072,10.10005 4.39706,15.38971 0.49247,-1.70606 0.0594,-4.3377 2.19853,-4.39706 0.16489,3.82984 -0.49027,6.83743 -2.19853,8.79412 2.19853,0 4.39706,0 6.59559,0 -0.22425,-2.46675 3.19666,-3.42311 0,-4.39706 -0.12532,1.3411 -0.32758,2.60306 -2.19853,2.19853 4.73343,-12.01716 2.74596,-17.60363 2.19853,-26.38236 -3.78147,-0.86842 -5.63483,3.26262 -6.59559,0 5.39519,-1.3433 1.56755,-23.20768 -2.19853,-15.3897 z m 411.12504,0 c -2.10619,-6.68793 4.70925,-22.29749 -4.39706,-21.9853 2.10619,6.68793 -4.70925,22.29749 4.39706,21.9853 z m -208.8603,-10.99265 c 5.8283,1.91052 13.34067,-5.36881 8.79411,-6.59559 -0.598,4.53337 -9.73509,0.52325 -8.79411,6.59559 z m -255.02945,-2.19853 c -12.52942,-3.81885 -8.01804,7.51237 0,0 l 0,0 z m 474.8824,8.79412 c 0.2902,-2.88887 0.33197,-15.90637 -2.19853,-8.79412 -0.29021,2.88887 -0.33198,15.90636 2.19853,8.79412 z M 368.9048,231.78961 c 13.10763,11.03881 -4.91152,-4.13764 0,0 l 0,0 z m 54.96324,21.98529 c 13.74741,-3.84083 14.22009,-20.95638 28.58089,-24.18382 -16.22515,1.36309 -21.13667,14.03981 -28.58089,24.18382 z m 21.9853,15.38971 c -1.6555,-7.22437 -14.12775,-15.07312 -19.78677,-10.99265 9.06014,1.2004 12.8658,7.65309 19.78677,10.99265 z m 15.38971,19.78677 c -10.75301,-12.69651 -20.66399,-26.23945 -41.77207,-28.58089 -2.89326,9.90218 -8.79412,18.23681 -10.99265,24.18383 -5.70958,15.43368 -6.41091,48.8799 -8.79412,72.55147 -0.98274,9.75708 -5.14236,21.32354 -4.39706,26.38236 2.62065,17.7993 22.52174,38.23683 39.57354,37.37501 13.97166,11.43015 45.38645,22.20515 65.95589,13.19117 2.60746,-6.92097 4.30692,-14.74553 8.79412,-19.78676 1.78301,12.04134 -6.5736,13.94527 -6.59559,24.18382 13.06806,-10.40784 16.64727,6.19546 26.38236,2.19853 -5.71618,-8.01584 2.36122,-21.01574 4.39706,-28.58088 -6.38234,-2.41179 -15.60297,-1.98528 -21.9853,-4.39706 -5.31605,5.01045 -14.36959,17.7861 -24.18383,10.99265 4.00572,-5.72498 21.32574,-1.05969 21.9853,-15.38971 -2.79873,-5.26328 -7.1716,-8.95022 -15.38971,-8.79412 -9.68013,10.10664 -19.30749,20.26605 -32.97794,26.38236 -5.80632,-0.055 -13.77599,2.05122 -10.99265,-6.59559 14.71036,9.73948 32.10952,-10.39465 39.57353,-21.9853 -11.16193,-3.37035 -14.96319,-10.72443 -21.9853,-13.19118 5.56009,-12.22822 -3.48906,-13.10983 -8.79411,-19.78677 7.57173,-16.53294 1.83797,-44.80163 2.19853,-70.35294 z m -41.77207,131.91178 c -2.27768,5.78433 -2.63164,13.49237 -2.19853,21.98529 5.50952,1.21139 14.47952,10.26934 17.58824,6.59559 -7.11225,-2.53051 5.90525,-2.48873 8.79412,-2.19853 1.69067,-8.28626 -2.68221,-10.50897 -2.19853,-17.58824 -11.28066,1.02012 -13.50997,-7.00891 -21.9853,-8.79411 z m 41.77207,19.78676 c 6.1207,0.67495 16.46918,9.73289 19.78676,0 -2.78114,-2.51951 -17.3354,-4.41684 -19.78676,0 z M 531.596,429.65727 c -5.70079,17.55087 6.61317,-14.66859 0,0 l 0,0 z m -50.56619,-43.97059 c 23.41434,5.89866 41.89299,16.73521 61.55883,26.38236 -2.11058,-36.73084 -1.85116,-75.82949 -13.19117,-103.33089 -1.30813,4.55315 2.71738,14.44213 -2.19853,15.3897 0.066,-9.94614 -10.1792,-0.69254 -13.19118,0 0.62658,13.29671 -2.6866,30.53538 6.59559,35.17647 17.01222,-2.35682 4.46521,-20.6354 10.99265,-32.97794 1.1938,9.79885 2.15895,19.82634 4.39706,28.58088 -15.77226,7.51018 -27.88616,13.12523 -46.16913,4.39706 6.59559,0 13.19118,0 19.78677,0 0.97834,-12.7031 -0.92338,-22.52833 -2.19853,-32.97794 -8.80291,0.32098 -15.90197,-8.87546 -24.18383,-2.19853 -0.39134,11.44335 6.69233,26.93858 2.19853,35.17647 -2.34143,-15.2468 -5.5271,-29.64717 -4.39706,-48.36764 -11.43455,4.68726 -10.65847,21.58515 -17.58823,30.77941 9.89118,2.9878 1.58733,23.95737 8.79411,19.78676 1.2048,-2.11938 21.56758,13.20437 26.38236,21.9853 -6.279,-6.91218 -18.23241,-8.14995 -24.18383,-15.38971 0.16489,3.82984 -0.49027,6.83743 -2.19853,8.79412 7.37167,-1.51039 8.03783,3.68913 8.79412,8.79412 z m 4.39706,-76.94853 c 1.87755,-4.47841 -1.91492,-13.65947 -4.39706,-6.59559 5.17534,2.15236 1.96989,12.68771 6.59559,15.38971 -1.31032,-13.54515 11.09378,1.07728 17.58824,0 1.98087,-12.98232 5.77334,-1.48841 10.99265,0 0.48587,-1.71266 1.84237,-2.55689 4.39706,-2.19853 6.2812,-28.79195 -20.39576,-17.73334 -32.97795,-19.78677 8.11038,-3.61438 20.68157,-2.77015 30.77942,-4.39706 -8.80291,-18.46765 -26.45931,-33.03071 -30.77942,-61.55883 -20.91681,-4.06069 -21.69289,12.01716 -41.77206,8.79412 -1.85116,6.94295 -6.94296,10.64528 -8.79412,17.58823 8.53029,8.32584 21.73246,11.97759 24.18383,26.38236 8.65341,3.52204 0.76508,-9.49325 6.59558,-8.79412 3.8936,18.96232 -10.42542,35.39193 2.19853,43.9706 4.02112,-9.90438 5.79093,-22.05565 15.38971,-26.38236 -1.27075,5.87447 6.50325,13.73641 0,17.58824 z M 362.30921,238.3852 c 1.46642,0 2.93064,0 4.39706,0 0,-1.46642 0,-2.93064 0,-4.39706 -1.46642,0 -2.93064,0 -4.39706,0 0,1.46642 0,2.93064 0,4.39706 z m 158.29414,43.97059 c 0.8926,-22.8779 -18.76445,-25.20614 -17.58824,-48.36765 -16.38784,11.30923 17.39037,35.90638 4.39706,37.375 7.31231,0.7475 7.79379,8.32803 13.19118,10.99265 z m -384.7427,-39.57353 c 1.46642,0 2.93064,0 4.39706,0 0,-1.46642 0,-2.93064 0,-4.39706 -1.46642,0 -2.93064,0 -4.39706,0 0,1.46642 0,2.93064 0,4.39706 z m 587.00741,17.58823 c 2.46015,10.52217 -5.42157,10.70025 -6.59559,17.58824 9.22063,16.8957 6.19766,22.22714 6.59559,43.9706 8.03563,6.12949 36.87814,7.96306 41.77206,-2.19853 0.56942,-13.02849 -4.53116,-20.38477 -8.79411,-28.58089 0.32318,5.45235 0.41112,10.66946 -4.39706,10.99265 -5.991,-6.63736 1.52138,-13.09884 2.19853,-19.78677 -5.5403,-1.7896 -8.75015,-5.90525 -13.19118,-8.79412 8.74135,-0.56062 28.04005,9.16127 26.38235,-6.59559 -7.21117,3.68034 -12.97572,0.22425 -13.19117,-8.79412 2.93064,0 5.86347,0 8.79412,0 -0.26823,-5.59306 -3.19887,-8.52589 -8.79412,-8.79412 0.61339,5.01045 -0.52985,8.26428 -4.39706,8.79412 -3.71992,-8.00704 -8.73696,-14.71476 -17.58824,-17.58823 -6.94735,-1.08388 -0.81566,10.9091 -8.79412,8.79411 1.89293,-5.5249 2.88007,-11.77972 -6.59559,-10.99264 0.0506,10.43202 6.77147,17.57944 10.99265,17.58823 1.7918,7.73663 6.03716,13.0153 10.99265,17.58824 -10.30231,0.77608 -9.93296,-9.1217 -15.38971,-13.19118 z m 41.77206,-10.99265 c 4.88294,-0.91458 2.11059,-12.05453 -2.19852,-10.99264 -1.69727,1.50379 -5.72498,13.09884 2.19852,10.99264 z m -457.29416,6.59559 c 7.3387,4.09147 9.25581,-7.90371 4.39706,-8.79412 1.60273,5.99979 -4.36847,4.42565 -4.39706,8.79412 z M 197.41948,253.7749 c 1.46642,0 2.93064,0 4.39706,0 0,-1.46642 0,-2.93064 0,-4.39706 -1.46642,0 -2.93064,0 -4.39706,0 0,1.46642 0,2.93064 0,4.39706 z m 474.8824,39.57354 c 10.44301,-8.55448 0.41992,-27.93452 2.19853,-41.77207 -0.48588,-1.71265 -1.84017,-2.55689 -4.39706,-2.19853 1.44003,13.94968 -2.89767,33.67708 2.19853,43.9706 z M 274.36802,264.76755 c -6.8836,-3.02517 9.31077,-10.95967 -2.19853,-13.19118 0.8948,5.86788 -5.69859,19.61309 2.19853,13.19118 z m 389.13974,213.25738 c -0.8992,7.9279 4.01451,3.01198 2.19853,-2.19853 0,-4.39706 0,-8.79412 0,-13.19118 8.24448,-11.3642 1.40706,-23.04499 0,-32.97795 -7.37387,-52.0304 5.41937,-120.60913 2.19853,-173.68384 -0.48588,-1.71265 -1.84237,-2.55689 -4.39706,-2.19853 1.02671,75.36999 -1.56096,155.25797 0,224.25003 z M 564.57394,284.55432 c -3.16368,-7.09685 -4.20798,-16.31089 -6.59559,-24.18383 -2.82071,-6.82423 -2.82071,6.23723 0,6.59559 -3.04496,6.99133 1.73464,22.44479 6.59559,28.58089 0,-3.66495 0,-7.3277 0,-10.99265 z M 193.02242,275.7602 c 1.29273,-6.25921 8.13896,-11.16193 -2.19853,-13.19118 1.26415,3.86502 -2.65582,12.91636 2.19853,13.19118 z m 129.71325,-4.39706 c -1.32131,-4.53996 -3.39892,-8.32583 -10.99265,-6.59559 -0.51005,5.11598 12.40631,7.83117 10.99265,6.59559 z M 91.890032,352.70873 c 26.388948,30.77283 58.999768,55.32381 101.132388,70.35296 6.06574,-11.5203 -1.55436,-21.00036 -4.39706,-30.77942 -11.16633,-38.40392 -28.8601,-73.80903 -46.16912,-107.72795 -0.48588,-1.71265 -1.84017,-2.55469 -4.39706,-2.19853 -10.37926,28.45997 -36.25378,41.42689 -46.169148,70.35294 z M 329.33126,286.75285 c -12.67672,7.84435 -19.03927,21.99849 -28.58088,32.97795 -1.87095,-9.30638 11.87206,-14.363 6.59558,-19.78677 -5.86567,12.10071 -14.54547,18.87657 -13.19117,32.97794 -18.37531,14.60263 -25.81954,40.13636 -43.9706,54.96324 0.14291,12.59977 -11.72696,13.19118 -10.99265,26.38236 4.61032,3.96614 11.59725,-3.02298 10.99265,-10.99265 8.87547,-4.6345 14.48392,-16.83634 17.58824,-24.18383 1.08168,-2.55909 7.07267,-3.97714 8.79412,-6.59559 3.68034,-5.60185 5.43037,-15.38091 8.79412,-19.78677 1.02231,-1.3389 5.72497,-0.96295 6.59559,-2.19852 2.57008,-3.65176 1.7852,-9.13929 4.39706,-13.19118 1.03111,-1.60053 5.47434,-0.81786 6.59559,-2.19853 1.09266,-1.34111 -0.98055,-5.15556 0,-6.59559 6.23063,-9.17006 18.87437,-16.80336 19.78676,-28.58088 6.63077,-1.52578 13.69245,-14.02882 10.99265,-17.58824 -1.95669,1.88414 -16.49117,0.20666 -10.99265,6.59559 0.24404,-1.74783 7.26834,-6.66374 6.59559,-2.19853 z m 595.80156,4.39706 c 0.6134,-5.01045 -0.5299,-8.26427 -4.3971,-8.79412 0.5013,3.89579 -2.2161,11.01024 4.3971,8.79412 z M 74.301792,319.7308 c 0.25723,2.24909 -9.48445,4.44761 -2.19853,6.59558 0.70133,-5.16214 6.80445,-4.9203 8.79412,-8.79411 -2.58767,-0.34297 -6.23943,0.37814 -6.59559,-2.19853 0,-2.19853 0,-4.39706 0,-6.59559 2.93064,0 5.86348,0 8.79412,0 0.3034,4.09366 1.44663,7.34748 4.39706,8.79412 4.41025,-4.47621 0.57382,-5.85689 -2.19853,-8.79412 6.24602,0.51006 10.04948,-24.48503 2.19853,-17.58824 2.56129,0.36935 2.3876,3.47587 2.19853,6.59559 -11.29605,3.31538 -33.92111,9.70431 -24.18383,15.38971 0.31879,6.18226 -5.3842,6.34056 -10.99265,6.59559 -0.22425,-2.46675 3.19667,-3.42312 0,-4.39706 -0.46388,2.65582 -2.44036,1.35209 -4.39705,0 -0.70573,8.76773 8.26207,7.85973 10.99264,13.19117 -1.53017,-7.39365 4.52018,-7.20458 6.59559,-10.99264 2.58767,0.34297 6.23943,-0.37815 6.59559,2.19853 z m 0,-24.18383 c 1.46642,0 2.93064,0 4.39706,0 0,-1.46642 0,-2.93064 0,-4.39706 -1.46642,0 -2.93064,0 -4.39706,0 0,1.46642 0,2.93064 0,4.39706 z m 303.397128,13.19118 c -5.03244,-0.97835 8.33902,-13.30111 0,-17.58824 3.20106,8.61824 -10.46061,21.9831 0,17.58824 z m 147.30149,-13.19118 c 7.84875,19.06345 -5.25669,-12.76686 0,0 l 0,0 z m -263.82357,10.99265 c 1.46642,0 2.93064,0 4.39706,0 0,-1.46642 0,-2.93064 0,-4.39706 -1.46642,0 -2.93064,0 -4.39706,0 0,1.46642 0,2.93064 0,4.39706 z m 266.0221,2.19853 c -3.62978,-0.0352 -1.23118,-6.09653 -4.39706,-6.59559 -1.88414,4.485 3.46048,12.1139 4.39706,6.59559 z m 35.17647,0 c -2.77454,-10.57933 -1.13444,-1.14983 0,4.39706 3.23184,15.80522 1.71046,2.12378 0,-4.39706 z m -349.56622,8.79412 c -6.91658,2.51951 -5.34243,-3.4517 -8.79412,-4.39706 -5.3798,5.18413 3.2824,4.08926 2.19853,10.99264 -2.80972,0.12092 -3.04497,2.81631 -6.59559,2.19853 -0.0374,-3.21865 9.2712,-6.96933 0,-6.59558 -3.62977,0.0352 -1.23118,6.09651 -4.39706,6.59558 -0.24624,-5.61724 -4.02991,-7.69485 -6.59559,-10.99264 0.32318,5.45235 0.40893,10.66945 -4.39706,10.99264 -0.34517,-2.58767 0.37815,-6.24162 -2.19853,-6.59558 -5.15555,5.88545 4.3421,10.4518 -6.59559,6.59558 8.71058,7.53216 5.13577,6.69672 6.59559,15.38971 -0.40013,-4.7972 1.7984,-6.99573 6.59559,-6.59559 0.25503,5.60845 0.41332,11.31363 6.59559,10.99265 1.6379,-6.76708 -6.03496,-4.22558 -4.39706,-10.99265 4.68946,-4.83677 13.89471,-5.15995 21.9853,-6.59559 -0.0945,3.02737 1.0355,4.82577 2.19853,6.59559 0.67275,5.06981 -6.35156,2.44256 -6.59559,6.59559 3.82984,-0.16489 6.83742,0.49247 8.79412,2.19853 -0.40014,-4.7972 1.79839,-6.99573 6.59559,-6.59559 -2.44257,9.45148 -1.02892,2.81192 2.19853,6.59559 -0.61339,5.09619 -5.87228,5.05442 -8.79412,2.19853 -2.74817,9.82962 6.22623,19.30089 -4.39706,19.78676 1.71265,0.48588 2.55689,1.84237 2.19853,4.39706 3.82984,0.16489 6.83742,-0.49247 8.79412,-2.19853 4.43003,7.9367 -0.21986,10.64309 -2.19853,17.58824 9.83842,-1.0465 11.00144,6.5868 10.99264,15.38971 -2.92844,5.39079 -6.63516,-3.96175 -8.79411,2.19853 2.97241,0.69034 4.19919,3.1307 8.79411,2.19853 5.94043,-8.25328 1.11466,-14.21789 0,-19.78677 -3.27141,-16.33947 8.6732,-16.40103 6.59559,-24.18383 -2.00286,5.32484 -8.83589,5.81951 -15.3897,6.59559 -7.0287,-10.35507 13.91669,-8.71937 15.3897,-17.58823 -5.12917,0.66835 -9.47346,4.69386 -10.99265,-2.19853 0.52545,-3.13731 3.61878,-3.70892 4.39706,-6.59559 -8.43356,-6.22184 -19.4372,-9.8758 -19.78676,-24.18382 z m 17.58823,17.58823 c 0.11873,-3.78367 -1.69286,-5.63483 -4.39705,-6.59559 0.20886,3.45389 -0.29461,7.6223 4.39705,6.59559 z m 349.56621,-8.79412 c -1.70606,-4.88953 -1.26855,-11.92262 -6.59559,-13.19117 1.33231,3.97054 4.66748,17.08476 6.59559,13.19117 z m -2.19853,28.58088 c -0.58921,-15.53481 0.93657,-33.1824 -10.99265,-37.37499 0.69913,15.42268 -2.87565,35.1193 10.99265,37.37499 z M 322.73567,326.32638 c -11.23668,16.0031 5.5359,-1.9523 0,0 l 0,0 z m 50.56619,8.79412 c -0.37375,-3.289 0.78487,-8.11258 -2.19853,-8.79412 -2.85369,2.92184 -2.89767,8.18073 2.19853,8.79412 z m 356.16179,10.99265 c -0.37595,-3.289 0.78487,-8.11258 -2.19853,-8.79412 -2.85589,2.92184 -2.89766,8.18073 2.19853,8.79412 z m 6.59559,4.39706 c -2.08421,-5.47654 7.84875,-13.26373 -2.19853,-13.19118 1.26415,3.86501 -2.65802,12.91636 2.19853,13.19118 z M 41.323852,348.31168 c 3.02517,0.0945 4.82797,-1.03551 6.59559,-2.19853 0.34516,2.58767 -0.37815,6.24162 2.19853,6.59558 1.85555,-10.18358 11.33561,-1.30812 13.19117,-8.79411 -2.90645,-0.0264 -2.00945,-3.85403 -4.39706,-4.39706 -0.57161,8.2225 -18.21262,-0.62439 -17.58823,8.79412 z m 707.926568,-2.19853 c 1.51259,-5.90965 -4.54436,-4.24976 -6.59559,-6.59559 -0.40013,4.79719 1.79839,6.99572 6.59559,6.59559 z M 72.103262,343.91462 c -10.50677,-6.11192 -5.32484,7.21117 0,0 l 0,0 z m -37.375,15.3897 c 4.35309,-1.4906 6.98912,-9.98572 0,-10.99264 2.85369,5.45235 -4.90492,10.66946 0,10.99264 z m 285.808878,-4.39706 c 0.598,-2.99219 -1.36089,-8.58086 -2.19853,-4.39705 -0.598,2.99219 1.36089,8.58086 2.19853,4.39705 z m -248.433878,4.39706 c 0,-2.93064 0,-5.86347 0,-8.79411 -4.55535,1.30812 -14.44214,-2.71739 -15.38971,2.19852 6.68354,4.59053 8.75675,1.03991 15.38971,6.59559 z m 503.463308,26.38236 c -3.48027,-8.97879 1.37628,-26.29441 -6.59559,-30.77942 0.86622,14.12336 -5.81069,25.91407 6.59559,30.77942 z m 4.39706,-2.19853 c 5.29626,0.8992 4.7796,-4.01451 10.99265,-2.19853 0.75189,-11.74454 -4.67188,-17.31342 -8.79412,-24.18383 -8.30385,6.12951 -0.7475,14.85987 -2.19853,26.38236 z M 83.095912,359.30432 c -2.93064,0 -5.86348,0 -8.79412,0 -3.48906,10.22097 11.35981,7.6311 8.79412,0 z m 2.19853,17.58824 c 1.44663,-2.95043 4.70046,-4.09366 8.79412,-4.39706 -0.12092,2.80972 -2.81852,3.04497 -2.19853,6.59559 5.74916,0.61999 9.455878,-0.80246 8.794118,-6.59559 -8.075198,-0.71892 -7.771798,-9.81643 -15.389708,-10.99265 4.98187,8.61164 -3.2868,5.61285 -6.59559,10.99265 2.58767,0.34297 6.23943,-0.37814 6.59559,2.19853 -1.22018,-0.007 -2.49533,1.78081 0,2.19853 z M 197.41948,365.89991 c 1.46642,0 2.93064,0 4.39706,0 0,-1.46642 0,-2.93064 0,-4.39706 -1.46642,0 -2.93064,0 -4.39706,0 0,1.46642 0,2.93064 0,4.39706 z m 565.02212,8.79412 c 9.61197,-5.93603 11.052,3.53084 21.98529,2.19853 -0.55183,-6.41311 4.13983,-7.58493 6.59559,-10.99265 -7.79818,-6.93856 -25.10501,-1.31252 -28.58088,8.79412 z m -30.77942,-6.59559 c -0.69034,-3.30439 -2.16555,-0.52325 -2.19853,0 -1.29274,21.64233 3.63417,6.8792 2.19853,0 z m 10.99265,8.79412 c 6.34276,-12.74048 -5.42597,-5.78653 0,0 l 0,0 z m -479.27946,30.77942 c -4.88513,5.80851 -17.16172,13.22635 -13.19118,19.78677 11.61264,-15.51723 30.55077,-35.38974 30.77942,-54.96325 -5.42158,12.14248 -11.47193,27.90374 -17.58824,35.17648 z m -50.56618,-26.38236 c 0.64636,-7.65968 5.94922,0.18468 6.59559,-4.39706 -1.70167,-4.58393 -13.21976,1.62032 -6.59559,4.39706 z m -92.33827,10.99265 c -4.29593,4.13983 -15.13468,-15.48864 -21.985298,-8.79412 3.267008,2.59646 9.823028,1.90173 8.794118,8.79412 -2.05123,-1.3433 -8.110378,-5.11598 -6.59559,2.19853 7.51457,-0.91899 12.52722,0.66396 10.99265,8.79412 13.80017,3.05595 30.02754,3.68473 32.97797,17.58824 2.93064,0 5.86347,0 8.79411,0 3.10653,-12.18645 -20.03959,-6.39113 -10.99264,-17.58824 -12.8724,1.26635 -16.83637,-2.9878 -21.98532,-4.39706 0.23964,-2.93944 4.12004,-12.1205 0,-6.59559 z m 584.8089,6.59559 c 11.08719,-0.63757 16.41642,-7.0353 21.9853,-13.19118 -6.76707,1.53897 -4.22557,1.53897 -10.99265,0 -0.7475,7.31231 -8.32803,7.79379 -10.99265,13.19118 z m 30.77942,-4.39706 c 5.69639,2.36562 8.17413,7.94768 15.38971,8.79412 10.23635,-4.31572 17.26065,-11.60164 26.38235,-6.59559 -8.80511,-13.79358 -28.04444,-7.73443 -41.77206,-2.19853 z m -523.25005,-4.39706 c -6.67694,7.40685 8.12796,6.66594 0,0 l 0,0 z m 26.38235,4.39706 c -6.67693,7.40685 8.12797,6.66594 0,0 l 0,0 z m 492.47064,19.78677 c 3.36155,10.34848 0.77168,-4.50039 0,-8.79412 -3.82984,0.16489 -6.83743,-0.49247 -8.79412,-2.19853 -2.87348,9.46907 6.23943,6.95175 8.79412,10.99265 z m 8.79412,-2.19853 c 1.46642,0 2.93064,0 4.39706,0 0,-2.93064 0,-5.86348 0,-8.79412 -1.46642,0 -2.93064,0 -4.39706,0 0,2.93064 0,5.86348 0,8.79412 z m -505.66182,43.97059 c 9.17227,-1.08607 11.41697,-9.10411 15.38971,-15.38971 -6.52304,-12.86359 -10.41004,-27.03532 -21.9853,-28.58088 -11.69397,-1.56096 -30.01432,20.74972 -46.16912,19.78676 -4.4828,-0.26602 -3.52644,-5.969 -10.99265,-2.19853 14.24208,6.60659 5.66561,12.85261 4.39706,26.38236 2.74597,7.51458 10.26494,10.25394 21.9853,8.79412 3.04716,-1.3477 0.32978,-8.46434 4.39706,-8.79412 9.76367,3.42971 9.90657,16.47578 19.78677,19.78677 7.763,-15.3963 -14.64661,-22.37224 -10.99265,-32.97795 4.50039,7.22437 11.77093,11.67859 13.19118,21.9853 10.54195,3.94856 7.08586,-6.10532 10.99264,-8.79412 z m 490.27211,-30.77941 c -13.69464,-9.33496 -33.51219,7.44422 -50.56618,8.79411 0,5.86348 0,11.72476 0,17.58824 7.774,-3.95076 7.57613,-15.87558 21.98529,-13.19118 0.34297,-2.58767 -0.37814,-6.24162 2.19853,-6.59559 12.30078,1.9435 30.64091,4.82578 32.97795,-8.79411 -3.76388,-2.0996 -4.43004,-7.29473 -8.79412,-8.79412 -1.81599,6.21304 3.09773,5.69639 2.19853,10.99265 z m -556.228,4.39705 c -4.4828,-1.38067 -0.61778,-11.10917 -8.79412,-8.79411 0,2.93064 0,5.86347 0,8.79411 5.01045,-3.01858 8.26428,5.66781 8.79412,0 z m 360.55888,17.58824 c 9.58119,1.41146 14.61802,7.36728 21.98529,10.99265 -0.0264,2.90426 -3.85402,2.00946 -4.39706,4.39706 7.95428,0.18028 13.9145,18.00816 19.78675,6.59559 -3.15267,-3.4429 -11.46091,-1.73024 -10.99263,-8.79412 6.07454,2.71958 11.16851,6.41971 19.78675,6.59559 3.21865,-2.79213 14.43115,-8.8227 8.79412,-13.19118 -1.85776,3.12411 -11.33342,-4.64109 -13.19118,-8.79412 4.4916,-4.69386 8.69958,0.61779 13.19118,2.19853 1.97428,-3.887 5.30725,-6.41751 6.59559,-10.99265 -6.71431,2.48654 -17.98837,-0.11212 -17.58824,-10.99264 -9.46465,-3.72651 -20.73651,-5.64583 -35.17645,-4.39706 0.35176,12.07652 -5.31385,18.13787 -8.79412,26.38235 z m -200.06621,-6.59559 c -3.87381,-1.98967 -3.63197,-8.09278 -8.79412,-8.79412 -0.67934,8.00925 0.34957,14.30804 2.19853,19.78677 -1.70606,0.49247 -4.3377,0.0594 -4.39706,2.19853 5.06981,4.36188 2.44257,-0.55183 6.59559,-2.19853 2.20513,-0.007 2.61625,1.78081 4.39706,2.19853 3.00319,-9.59878 -8.51271,-4.67847 -6.59559,-13.19118 3.78147,-0.86842 5.63483,3.26262 6.59559,0 z m 367.15444,6.59559 c 4.69826,7.0265 11.2235,12.22823 19.78677,15.38971 0.86842,-3.78367 -3.26262,-5.63483 0,-6.59559 7.05728,-1.92811 4.55755,5.70299 8.79412,6.59559 5.57327,-5.36881 -4.6345,-4.68507 -2.19853,-13.19118 4.0321,-0.11432 7.44422,11.26747 10.99265,4.39706 -3.26702,-1.86215 -3.18127,-7.07926 -4.39706,-10.99265 3.1373,0.52545 3.70892,3.61878 6.59559,4.39706 1.6379,-6.76707 -6.03497,-4.22557 -4.39706,-10.99265 -15.16326,3.20546 -31.71379,-5.80851 -35.17648,10.99265 z m -206.66177,-2.19853 c 4.52897,1.92811 9.8736,-5.70298 4.39706,-6.59559 -0.52545,3.13731 -3.61878,3.70892 -4.39706,6.59559 z m -219.85297,0 c 1.46642,0 2.93064,0 4.39706,0 0,-1.46642 0,-2.93064 0,-4.39706 -1.46642,0 -2.93064,0 -4.39706,0 0,1.46642 0,2.93064 0,4.39706 z m 382.54415,-4.39706 c -9.22723,7.6267 -27.57396,6.1361 -35.17648,15.38971 13.54954,0.99154 27.28815,12.96473 39.57354,2.19853 -1.80939,-5.51831 4.27394,-18.92934 -4.39706,-17.58824 z m -400.13239,15.38971 c 0.24404,-4.15302 7.26834,-1.52578 6.59559,-6.59559 -3.1373,-0.52545 -3.70892,-3.61878 -6.59559,-4.39706 -1.26635,1.33231 -5.14456,10.42763 0,10.99265 z m 342.97062,4.39706 c 1.59613,21.12128 24.84998,20.58483 30.77941,37.37501 -6.31637,13.21976 -29.34817,0.95856 -39.57353,6.59559 -0.37595,11.78192 11.02343,29.71093 15.38971,43.97059 19.05465,0 38.10711,0 57.16177,0 3.41871,-27.58715 0.79147,-61.73691 0,-87.94119 -19.70982,15.71949 -51.2939,-7.60471 -63.75736,0 z m 103.33089,4.39706 c 2.77455,-2.57887 1.76322,-9.13489 -4.39706,-8.79412 -0.61339,5.01045 0.52985,8.26427 4.39706,8.79412 z m -373.75003,2.19853 c 2.85369,-2.92185 2.89766,-8.18073 -2.19853,-8.79412 -2.85589,2.92185 -2.89766,8.18073 2.19853,8.79412 z m 13.19118,-2.19853 c 0.11872,-3.78367 -1.69287,-5.63483 -4.39706,-6.59559 -0.11872,3.78367 1.69287,5.63483 4.39706,6.59559 z m 367.15444,8.79412 c 0.61339,-5.01045 -0.52984,-8.26427 -4.39706,-8.79412 -0.61339,5.01045 0.52985,8.26427 4.39706,8.79412 z m -446.30151,0 c 1.46642,0 2.93064,0 4.39706,0 0,-1.46642 0,-2.93064 0,-4.39706 -1.46642,0 -2.93064,0 -4.39706,0 0,1.46642 0,2.93064 0,4.39706 z m 74.75001,2.19853 c -2.23151,-5.66781 -10.166,-8.42257 -13.19118,-2.19853 7.91031,-3.99033 12.39971,6.30978 13.19118,2.19853 z m 136.30884,6.59559 c -0.23084,-5.63263 -1.24436,-10.48259 -4.39706,-13.19118 -3.74189,3.70672 1.27735,9.88019 4.39706,13.19118 z M 245.78713,471.42934 c -2.31505,12.76027 9.52843,0.91679 0,0 l 0,0 z m -8.79412,6.59559 c 1.46642,0 2.93064,0 4.39706,0 0,-1.46642 0,-2.93064 0,-4.39706 -1.46642,0 -2.93064,0 -4.39706,0 0,1.46642 0,2.93064 0,4.39706 z m 270.41916,30.77941 c -3.24283,5.55129 -7.76741,9.82084 -8.79412,17.58824 3.25382,7.73883 12.48325,9.50205 17.58824,15.38971 52.86802,5.2325 66.67479,-28.59408 74.74999,-68.15442 -19.49876,10.54635 -52.37336,7.71904 -65.95587,24.18383 21.16085,4.94889 40.8135,-12.28319 50.56616,-4.39706 -4.35529,8.15215 -29.24482,7.33209 -26.38234,15.3897 5.34903,-1.84896 20.85084,-7.33209 21.98528,0 -15.91294,9.68453 -51.09381,11.2279 -63.75734,0 z m 26.38236,-32.97794 c -1.76762,13.3099 10.07806,1.46642 0,0 l 0,0 z m -325.3824,6.59559 c 1.69067,8.28626 -2.68221,10.50897 -2.19853,17.58824 8.17633,-2.31506 4.31131,7.41344 8.79412,8.79411 5.9712,-6.61757 -4.81039,-9.80983 -2.19853,-19.78676 5.09839,0.70133 8.44015,-0.35177 10.99265,-2.19853 1.02891,-6.89239 -5.52711,-6.19766 -8.79412,-8.79412 0.37155,8.69079 -3.37695,-0.70353 -6.59559,4.39706 z m 532.04417,6.59559 c 1.46642,-4.37728 7.58273,-9.38992 0,-10.99265 2.86029,5.45895 -6.45049,9.1239 0,10.99265 z m -499.06623,-6.59559 c 3.46269,5.74036 -4.99506,16.69563 8.79412,15.38971 -3.95515,-8.2357 3.42531,-14.13875 -4.39706,-17.58824 -0.48587,1.71265 -1.84017,2.55689 -4.39706,2.19853 z m 15.38971,6.59559 c 5.35782,-2.5459 -2.45356,-10.35508 -4.39706,-4.39706 2.90646,0.0264 2.00946,3.85402 4.39706,4.39706 z m 503.46329,6.59559 c -2.08421,-5.47654 7.84875,-13.26373 -2.19853,-13.19118 1.26415,3.86501 -2.65803,12.91636 2.19853,13.19118 z m -92.33825,6.59559 c -0.26163,-3.65616 1.20039,-19.91209 -2.19853,-13.19118 0.26162,3.65615 -1.2004,19.91208 2.19853,13.19118 z m -171.4853,-8.79412 c 1.46642,0 2.93064,0 4.39706,0 0,-1.46642 0,-2.93064 0,-4.39706 -1.46642,0 -2.93064,0 -4.39706,0 0,1.46642 0,2.93064 0,4.39706 z m 8.79412,-2.19853 c 0,2.19853 0,4.39706 0,6.59559 4.14863,-2.44697 10.10224,-3.08894 10.99265,-8.79412 -5.29626,-0.8992 -4.77961,4.01451 -10.99265,2.19853 z m -266.0221,4.39706 c -5.09839,0.70133 -8.44015,-0.35397 -10.99265,-2.19853 -3.39013,6.63736 11.3752,5.78433 10.99265,2.19853 z m 237.44121,8.79412 c -0.66175,-5.79313 3.04497,-7.21558 8.79412,-6.59559 -0.31659,2.59866 -3.91558,4.98406 0,6.59559 2.82072,-2.88667 2.82072,-8.10598 0,-10.99265 -5.29626,-0.8992 -4.7796,4.01451 -10.99265,2.19853 -0.12531,-1.34111 -0.32758,-2.60306 -2.19853,-2.19853 -0.32978,5.45895 1.13664,9.1239 4.39706,10.99265 z m 46.16913,0 c -3.1373,-0.52545 -3.70892,-3.61878 -6.59559,-4.39706 -1.92811,4.52897 5.70298,9.87139 6.59559,4.39706 z m -263.82357,0 c -2.31505,12.76026 9.52843,0.91678 0,0 l 0,0 z m 472.68387,4.39705 c -7.52337,-2.18753 -6.60658,0.92778 -10.99265,-4.39705 -0.9014,2.76355 -2.8339,4.49379 -6.59559,4.39705 0.17588,-3.42091 -6.39112,-1.52358 -2.19853,0 2.78334,2.51952 17.33541,4.41685 19.78677,0 z m -463.88975,2.19853 c 3.78147,0.11873 5.63483,-1.69286 6.59559,-4.39705 -3.45389,0.21105 -7.6223,-0.29461 -6.59559,4.39705 z m 70.35295,0 c 1.46642,0 2.93064,0 4.39706,0 0,-1.46641 0,-2.93064 0,-4.39705 -1.46642,0 -2.93064,0 -4.39706,0 0,1.46641 0,2.93064 0,4.39705 z m 8.79412,4.39706 c 5.46774,2.07322 0.64197,-12.58438 0,-4.39706 0.19787,3.5946 -3.66275,9.56361 0,4.39706 z m 81.3456,-6.59559 c -9.96813,15.81843 -49.83407,18.50943 -46.16912,39.57354 18.32034,0 36.64289,0 54.96324,0 -8.16974,-9.32396 4.9313,-32.68774 -8.79412,-39.57354 z m 63.75736,19.78677 c 0,-1.46642 0,-2.93064 0,-4.39706 1.3411,-0.12531 2.60306,-0.32758 2.19853,-2.19853 -6.44609,2.52831 -8.16534,-10.54634 -10.99265,-4.39706 3.77708,2.81852 2.72398,10.4672 8.79412,10.99265 z m -13.19118,-8.79412 c 3.52425,12.57339 11.02783,5.06981 0,0 l 0,0 z m -149.50002,4.39706 c 1.46642,0 2.93064,0 4.39706,0 0,-1.46642 0,-2.93064 0,-4.39706 -1.46642,0 -2.93064,0 -4.39706,0 0,1.46642 0,2.93064 0,4.39706 z m 147.30149,-2.19853 c -3.19446,1.2026 -11.362,-2.57008 -10.99265,2.19853 3.19447,-1.20259 11.36201,2.57008 10.99265,-2.19853 z m -312.19122,21.9853 c 3.55503,-4.57514 18.96892,-18.03454 10.99265,-19.78677 -0.42212,8.45555 -14.22009,14.98078 -10.99265,19.78677 z m 309.99269,-4.39706 c 0.52545,-3.1373 3.61878,-3.70892 4.39706,-6.59559 -4.52897,-1.92811 -9.87359,5.70299 -4.39706,6.59559 z m 13.19118,0 c 5.46775,2.07321 0.64197,-12.58438 0,-4.39706 0.19787,3.5946 -3.66275,9.56361 0,4.39706 z m 266.02208,8.79412 c 6.41311,3.23184 6.41311,-9.82743 0,-6.59559 0,2.19853 0,4.39706 0,6.59559 z m -598.00007,6.59559 c -1.11905,-4.36408 12.12929,-5.03024 4.39706,-8.79412 0.62878,3.87601 -10.35287,6.80885 -4.39706,8.79412 z m 13.19118,8.79412 c -2.8339,-3.02958 -9.55041,-2.17435 -15.38971,-2.19853 -2.70419,7.30791 14.86207,5.3776 15.38971,2.19853 z m 230.84562,-2.19853 c -17.42994,1.0443 43.45174,9.79445 41.77207,2.19853 -9.64935,-3.71772 -39.68127,-2.32385 -41.77207,-2.19853 z m 233.04413,4.39706 c 9.24482,0.066 25.4238,3.24503 26.38236,-4.39706 -16.85613,0 -33.71006,0 -50.56619,0 0.65517,7.71024 15.2556,4.3333 24.18383,4.39706 z m 61.55883,0 c -0.26822,-9.25801 -16.87151,-2.18314 -24.18382,-4.39706 0.26822,9.26021 16.87151,2.18314 24.18382,4.39706 z m 76.94854,-2.19853 c -3.19666,-3.39893 -11.25427,-1.93691 -17.58823,-2.19853 -2.23151,7.53436 16.51535,5.2369 17.58823,2.19853 z m -637.57359,24.18382 c 2.91525,7.21558 34.45975,7.21558 37.375,0 -7.70145,-3.95735 -29.55703,-3.23623 -37.375,0 z m 309.99269,-2.19852 c -10.99265,0 -21.9853,0 -32.97795,0 -0.71672,10.33968 33.69467,10.33968 32.97795,0 z m 76.94854,4.39705 c 0.27481,4.85656 9.32616,0.93438 13.19118,2.19853 3.44509,-7.55634 -14.71916,-10.43422 -13.19118,-2.19853 z m 101.13234,2.19853 c 12.05674,-2.60086 34.72358,5.40839 39.57354,-4.39706 -10.30671,-3.65615 -35.86242,-3.65615 -46.16913,0 3.46489,0.20007 1.72145,5.60845 6.59559,4.39706 z m 48.36766,-2.19853 c 4.21678,2.63824 27.85317,5.95142 28.58088,-2.19853 -4.21678,-2.63823 -27.85317,-5.95142 -28.58088,2.19853 z m 83.54413,0 c 6.75828,3.01419 31.73797,5.41498 35.17647,-2.19853 -6.68573,-2.10179 -32.1447,-6.43069 -35.17647,2.19853 z"
+       clip-rule="evenodd"
+       inkscape:connector-curvature="0"
+       style="fill:#3700f8;fill-opacity:1;fill-rule:evenodd;filter:url(#filter5839);opacity:1" />
+    <path
+       id="path5748"
+       d="m 136,303 c 3.021,1.312 4.707,3.96 7,6 -3.397,-0.733 -9.837,-2.185 -7,-6 z"
+       clip-rule="evenodd"
+       inkscape:connector-curvature="0"
+       style="fill-rule:evenodd" />
+    <path
+       id="path5750"
+       d="m 354,277 c 0.911,-2.117 4.019,1.887 7,1 -1.645,2.85 -5.426,-0.479 -7,-1 z"
+       clip-rule="evenodd"
+       inkscape:connector-curvature="0"
+       style="fill-rule:evenodd" />
+    <path
+       id="path5752"
+       d="m 370,303 c 3.943,0.567 -2.763,6.119 -4,8 -2.068,-2.135 4.56,-4.058 4,-8 z"
+       clip-rule="evenodd"
+       inkscape:connector-curvature="0"
+       style="fill-rule:evenodd" />
+    <path
+       id="path5754"
+       d="m 239,91 c -0.529,0.804 -1.043,1.624 -1,3 -3.453,-0.787 -4.398,0.935 -5,3 -2.531,-2.135 -6.746,-2.587 -7,-7 3.762,-0.528 9.351,-2.396 13,1 z"
+       clip-rule="evenodd"
+       inkscape:connector-curvature="0"
+       style="fill-rule:evenodd" />
+    <path
+       id="path5756"
+       d="m 229,267 c -0.804,-0.529 -1.623,-1.043 -3,-1 0.016,-2.651 -0.555,-5.889 2,-6 4.8,-0.469 2.879,5.813 1,7 z"
+       clip-rule="evenodd"
+       inkscape:connector-curvature="0"
+       style="fill-rule:evenodd" />
+  </g>
+</svg>
diff --git a/data/backgrounds/classic_bg.svg b/data/backgrounds/classic_bg.svg
new file mode 100644 (file)
index 0000000..b6e7299
--- /dev/null
@@ -0,0 +1,237 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Sodipodi ("http://www.sodipodi.com/") -->
+
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://creativecommons.org/ns#"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:xlink="http://www.w3.org/1999/xlink"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   version="1.0"
+   x="0"
+   y="0"
+   width="1000"
+   height="800"
+   id="svg559"
+   sodipodi:version="0.32"
+   inkscape:version="0.48.0 r9654"
+   sodipodi:docname="classic_bg.svg"
+   inkscape:output_extension="org.inkscape.output.svg.inkscape">
+  <metadata
+     id="metadata35">
+    <rdf:RDF>
+      <cc:Work
+         rdf:about="">
+        <dc:format>image/svg+xml</dc:format>
+        <dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+      </cc:Work>
+    </rdf:RDF>
+  </metadata>
+  <sodipodi:namedview
+     inkscape:window-height="432"
+     inkscape:window-width="675"
+     inkscape:pageshadow="2"
+     inkscape:pageopacity="0.0"
+     guidetolerance="10.0"
+     gridtolerance="10.0"
+     objecttolerance="10.0"
+     borderopacity="1.0"
+     bordercolor="#666666"
+     pagecolor="#ffffff"
+     id="base"
+     inkscape:zoom="0.87006002"
+     inkscape:cx="497.56002"
+     inkscape:cy="393.92889"
+     inkscape:window-x="293"
+     inkscape:window-y="145"
+     inkscape:current-layer="g3955"
+     showgrid="false"
+     showguides="true"
+     inkscape:guide-bbox="true"
+     inkscape:window-maximized="0" />
+  <defs
+     id="defs561">
+    <linearGradient
+       id="linearGradient4557">
+      <stop
+         style="stop-color:#ffffff;stop-opacity:1;"
+         offset="0"
+         id="stop4559" />
+      <stop
+         style="stop-color:#0300da;stop-opacity:1;"
+         offset="1"
+         id="stop4561" />
+    </linearGradient>
+    <linearGradient
+       id="linearGradient3751"
+       inkscape:collect="always">
+      <stop
+         id="stop3753"
+         offset="0"
+         style="stop-color:black;stop-opacity:1;" />
+      <stop
+         id="stop3755"
+         offset="1"
+         style="stop-color:black;stop-opacity:0;" />
+    </linearGradient>
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient3751"
+       id="linearGradient2518"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(0.9434139,0,0,0.9434139,62.279262,39.359798)"
+       x1="665.12128"
+       y1="684.16162"
+       x2="381.28015"
+       y2="449.80624" />
+    <radialGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient4557"
+       id="radialGradient4563"
+       cx="754.52362"
+       cy="248.26866"
+       fx="754.52362"
+       fy="248.26866"
+       r="648.54285"
+       gradientTransform="matrix(-0.6867835,-1.4236353,1.4876169,-0.7176493,903.38936,1551.3895)"
+       gradientUnits="userSpaceOnUse" />
+  </defs>
+  <rect
+     style="opacity:1;fill:url(#radialGradient4563);fill-opacity:1.0;stroke:none;stroke-width:10.01399993999999971;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+     id="rect4231"
+     width="1297.0857"
+     height="1042.5737"
+     x="-56.077015"
+     y="-14.202133" />
+  <text
+     xml:space="preserve"
+     style="font-size:24.89476013px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans"
+     x="266.96185"
+     y="759.88806"
+     id="text2508"><tspan
+       sodipodi:role="line"
+       id="tspan2510"
+       x="266.96185"
+       y="759.88806" /></text>
+  <g
+     id="g3955"
+     transform="translate(18.488319,-59.198001)">
+    <path
+       id="path1939"
+       d="M 794.42889,322.92369 L 780.83033,322.92369 L 778.11066,329.72293 L 780.83033,337.2021 L 779.47049,345.36119 L 772.67131,341.28164 L 767.23197,331.08278 L 755.67315,328.36307 L 750.91373,323.60361 L 740.71485,318.84413 L 729.15616,299.80625 L 729.83607,290.96723 L 758.39293,269.20965 L 771.9913,275.32896 L 774.03114,280.08844 L 774.03114,285.52784 L 777.43073,290.2873 L 784.23001,292.32708 L 788.98944,288.24753 L 789.66936,283.48806 L 787.62961,279.40852 L 783.5501,277.36875 L 780.83033,273.96912 L 786.94969,271.24943 L 785.58985,264.45018 L 785.58985,260.37062 L 781.51034,256.29108 L 779.47049,250.17177 L 771.31147,248.132 L 764.51219,246.77214 L 750.23372,256.97101 L 714.19776,271.24943 L 706.03865,279.40852 L 699.91938,284.16799 L 698.55944,295.04678 L 701.27921,300.48618 L 708.07849,318.84413 L 716.91743,335.84224 L 726.43638,348.08088 L 711.47808,372.55817 L 694.47994,409.27408 L 684.28107,425.59226 L 667.28301,446.66993 L 666.60309,456.18888 L 657.76406,464.34796 L 671.36253,476.58662 L 667.96293,490.86501 L 669.32277,522.82147 L 675.44203,559.53739 L 681.56139,592.17377 L 688.36057,603.05256 L 697.87963,622.77036 L 712.83793,645.20787 L 716.91743,659.48624 L 720.99703,669.68512 L 708.75832,686.68323 L 687.00074,695.52225 L 684.96098,702.32155 L 726.43638,700.9617 L 720.31712,711.84046 L 727.79623,718.63969 L 747.51405,720.6795 L 763.15236,707.08098 L 768.5918,688.04314 L 777.43073,671.72493 L 788.30953,662.206 L 791.70912,651.32718 L 780.15051,650.64727 L 787.62961,643.16809 L 772.67131,647.92757 L 783.5501,637.04877 L 775.39099,635.009 L 769.27162,627.52983 L 759.07276,606.45217 L 735.27542,586.73436 L 730.51599,585.37452 L 735.27542,581.29497 L 734.5955,569.73625 L 739.35502,559.53739 L 735.27542,560.21731 L 742.75461,547.29875 L 742.75461,534.38018 L 747.51405,527.58094 L 747.51405,518.74192 L 757.71291,505.14342 L 758.39293,493.58472 L 756.35308,484.06577 L 761.1126,473.18698 L 766.55195,464.34796 L 766.55195,458.90857 L 772.67131,458.22865 L 778.11066,452.78925 L 782.87018,439.19077 L 793.74896,426.95212 L 806.66752,422.19265 L 814.82653,428.99189 L 834.54445,435.11122 L 850.18266,443.2703 L 857.66177,452.78925 L 870.58031,454.1491 L 911.37589,471.82713 L 932.45346,479.30631 L 949.4516,492.22487 L 953.53121,490.86501 L 953.53121,486.78547 L 944.01225,479.30631 L 962.37014,484.06577 L 964.41,480.66614 L 960.3304,476.58662 L 967.12968,476.58662 L 967.80959,472.50706 L 955.57096,469.78736 L 965.08982,467.06766 L 965.08982,462.30819 L 961.69023,461.62828 L 951.49136,462.30819 L 943.33234,458.90857 L 937.8929,456.18888 L 946.05201,449.38963 L 948.09177,444.63016 L 946.73193,441.23053 L 939.25283,442.59039 L 923.61442,450.74947 L 921.57476,454.82902 L 916.13532,453.46918 L 896.41749,442.59039 L 895.73758,435.11122 L 884.17887,428.99189 L 864.46105,418.79302 L 859.70161,422.19265 L 860.38154,417.43318 L 849.50275,407.23431 L 839.98379,404.51461 L 831.14476,394.31575 L 828.4251,390.91612 L 837.26412,397.03545 L 835.90429,390.23619 L 842.70347,393.63582 L 840.66371,383.43695 L 850.18266,392.27598 L 846.10316,386.15666 L 855.62201,390.23619 L 847.46299,378.67749 L 853.58226,380.71726 L 850.86259,369.83847 L 855.62201,373.91801 L 848.82283,363.71914 L 855.62201,365.75891 L 849.50275,357.59983 L 857.66177,356.9199 L 848.82283,351.4805 L 854.26218,348.76082 L 848.14292,348.08088 L 856.30194,340.60172 L 848.82283,341.28164 L 849.50275,336.52217 L 850.18266,322.92369 L 846.10316,332.44263 L 841.34364,318.84413 L 842.02355,329.72293 L 839.30388,330.40285 L 832.5046,330.40285 L 825.02541,319.52406 L 817.5463,319.52406 L 808.70726,312.04489 L 804.62766,316.12443 L 794.42889,322.92369 z"
+       style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:0.67309088px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
+    <path
+       style="opacity:0.22790701;fill:url(#linearGradient2518);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.44754833px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+       d="M 435.88424,549.14748 L 422.27662,549.14748 L 425.93151,551.82116 L 435.66696,554.76219 L 441.95775,557.97059 L 431.32821,556.36638 L 416.32067,552.3559 L 402.20371,551.28642 L 392.97758,549.41486 L 378.30844,547.54329 L 348.88817,540.05702 L 341.27935,536.58125 L 349.45101,528.02552 L 368.79722,530.43182 L 375.30188,532.30338 L 380.40291,534.44231 L 388.26826,536.31389 L 396.98502,537.11598 L 397.92173,535.51178 L 394.13874,533.64022 L 388.27174,532.03601 L 382.27663,531.23392 L 376.3669,529.89708 L 379.9398,528.82762 L 372.20267,526.15395 L 368.37693,524.54974 L 360.46886,522.94554 L 352.689,520.53924 L 342.61155,519.73714 L 334.53244,519.20241 L 329.80904,523.21292 L 307.13918,528.82762 L 306.62625,532.03601 L 304.96631,533.90758 L 313.80771,538.18545 L 321.6303,540.32439 L 345.65028,547.54329 L 370.43602,554.22746 L 391.43879,559.04006 L 399.42525,568.66525 L 416.84803,583.10307 L 421.94558,589.51986 L 424.70281,597.80824 L 432.94938,601.55137 L 431.75595,604.75978 L 456.84095,609.57239 L 466.82945,615.18708 L 498.15899,627.75333 L 538.71466,642.19113 L 575.44459,655.02474 L 592.45048,659.3026 L 620.46723,667.05624 L 656.47743,675.87935 L 673.95003,681.49403 L 687.59688,685.50454 L 691.29082,692.1887 L 677.80792,695.66447 L 682.14329,698.33816 L 722.37112,697.80343 L 726.44988,702.08128 L 740.31033,704.75495 L 761.95422,705.55705 L 764.85022,700.20971 L 752.43961,692.72346 L 745.98128,686.30664 L 747.94047,682.56352 L 741.14016,678.28565 L 728.93615,678.01828 L 729.40635,675.07723 L 718.90144,676.94881 L 719.58531,672.67094 L 709.50786,671.86884 L 696.37054,668.92781 L 666.39809,660.63943 L 624.09342,652.8858 L 618.05549,652.35107 L 618.99239,650.74686 L 607.47217,646.20163 L 602.67029,642.19113 L 599.2257,642.4585 L 594.59486,637.37853 L 582.47972,632.29855 L 580.86601,629.62488 L 572.5768,626.14912 L 570.02977,620.80179 L 559.87043,616.25656 L 548.9024,612.51341 L 543.46287,608.23555 L 540.61667,604.75978 L 535.51554,602.62085 L 541.0014,602.35348 L 541.34329,600.21455 L 533.35333,594.86722 L 532.7619,590.05461 L 541.22564,588.18304 L 555.76648,590.8567 L 581.2363,593.26301 L 604.53655,596.4714 L 620.94761,600.21455 L 635.15005,600.74928 L 692.55132,607.70081 L 720.65703,610.64185 L 749.78154,615.72183 L 752.58866,615.18708 L 748.76284,613.58289 L 732.22347,610.64185 L 755.0572,612.51341 L 753.91011,611.17659 L 746.00213,609.57239 L 752.80584,609.57239 L 749.6605,607.96818 L 734.86305,606.89872 L 741.83781,605.82925 L 737.37432,603.95767 L 733.3349,603.69031 L 723.7668,603.95767 L 712.41413,602.62085 L 704.42049,601.55137 L 706.20874,598.87771 L 703.78643,597.00615 L 699.23748,595.6693 L 693.02859,596.20404 L 685.03145,599.41243 L 686.81611,601.01664 L 680.09788,600.48191 L 650.16467,596.20404 L 642.47038,593.26301 L 625.16523,590.8567 L 595.86969,586.8462 L 594.29523,588.18304 L 590.51213,586.31147 L 570.06157,582.30096 L 557.98578,581.23151 L 539.57628,577.22099 L 533.66664,575.88417 L 548.25021,578.29047 L 540.51318,575.61679 L 550.50506,576.95363 L 538.89937,572.94314 L 556.71396,576.4189 L 546.89301,574.0126 L 560.24412,575.61679 L 541.2398,571.07157 L 549.27608,571.87367 L 536.35245,567.59579 L 544.9409,569.2 L 528.57258,565.18949 L 537.28925,565.9916 L 523.51419,562.78319 L 531.04112,562.51582 L 517.0952,560.37689 L 519.9876,559.30743 L 513.22664,559.04006 L 514.37712,556.09902 L 507.53068,556.36638 L 503.74758,554.49483 L 491.67529,549.14748 L 496.51991,552.89062 L 479.00458,547.54329 L 489.88705,551.82116 L 487.80313,552.08853 L 480.99942,552.08853 L 463.31306,547.81066 L 455.82886,547.81066 L 439.97007,544.86963 L 439.71346,546.47381 L 435.88424,549.14748 z"
+       id="path2864" />
+    <path
+       sodipodi:nodetypes="cssc"
+       id="path3759"
+       d="M 763.90087,255.09122 C 737.27952,245.25132 726.24864,281.2444 731.7447,302.74821 C 738.17651,327.91326 740.1544,358.76892 728.57172,381.46481 C 720.27205,397.72776 681.88886,403.81659 682.37312,426.6734"
+       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:#ffffff;stroke-width:1.60380363;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
+  </g>
+  <g
+     id="g4087"
+     transform="translate(9.4333253,-20.40528)">
+    <path
+       transform="matrix(0.6171045,-0.2551458,0.2551458,0.6171045,-48.77856,487.49674)"
+       d="m 179.80715,418.82535 -43.79473,-23.34656 -48.057629,12.38974 8.670585,-48.86575 -26.633969,-41.87688 49.153453,-6.85413 31.59693,-38.27107 21.70791,44.62966 46.16195,18.22405 -35.73722,34.43678 z"
+       inkscape:randomized="0"
+       inkscape:rounded="0"
+       inkscape:flatsided="false"
+       sodipodi:arg2="1.6895226"
+       sodipodi:arg1="1.0612041"
+       sodipodi:r2="45.665279"
+       sodipodi:r1="78.688225"
+       sodipodi:cy="350.13498"
+       sodipodi:cx="141.42136"
+       sodipodi:sides="5"
+       id="path5574"
+       style="opacity:0.22790701;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:#ffffff;stroke-width:1.70000005;stroke-linecap:round;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:block;overflow:visible"
+       sodipodi:type="star" />
+    <path
+       sodipodi:type="star"
+       style="opacity:0.22790701;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:#ffffff;stroke-width:1.70000005;stroke-linecap:round;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:block;overflow:visible"
+       id="path5576"
+       sodipodi:sides="5"
+       sodipodi:cx="141.42136"
+       sodipodi:cy="350.13498"
+       sodipodi:r1="78.688225"
+       sodipodi:r2="45.665279"
+       sodipodi:arg1="1.0612041"
+       sodipodi:arg2="1.6895226"
+       inkscape:flatsided="false"
+       inkscape:rounded="0"
+       inkscape:randomized="0"
+       d="m 179.80715,418.82535 -43.79473,-23.34656 -48.057629,12.38974 8.670585,-48.86575 -26.633969,-41.87688 49.153453,-6.85413 31.59693,-38.27107 21.70791,44.62966 46.16195,18.22405 -35.73722,34.43678 z"
+       transform="matrix(0.5368229,1.5964048e-2,-1.5964048e-2,0.5368229,6.5592731,406.45942)" />
+    <path
+       transform="matrix(0.3852517,-0.1964008,0.1964008,0.3852517,15.210382,430.94873)"
+       d="m 179.80715,418.82535 -43.79473,-23.34656 -48.057629,12.38974 8.670585,-48.86575 -26.633969,-41.87688 49.153453,-6.85413 31.59693,-38.27107 21.70791,44.62966 46.16195,18.22405 -35.73722,34.43678 z"
+       inkscape:randomized="0"
+       inkscape:rounded="0"
+       inkscape:flatsided="false"
+       sodipodi:arg2="1.6895226"
+       sodipodi:arg1="1.0612041"
+       sodipodi:r2="45.665279"
+       sodipodi:r1="78.688225"
+       sodipodi:cy="350.13498"
+       sodipodi:cx="141.42136"
+       sodipodi:sides="5"
+       id="path5578"
+       style="opacity:0.22790701;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:#ffffff;stroke-width:1.70000005;stroke-linecap:round;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:block;overflow:visible"
+       sodipodi:type="star" />
+    <path
+       sodipodi:type="star"
+       style="opacity:0.22790701;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:#ffffff;stroke-width:1.70000005;stroke-linecap:round;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:block;overflow:visible"
+       id="path5580"
+       sodipodi:sides="5"
+       sodipodi:cx="141.42136"
+       sodipodi:cy="350.13498"
+       sodipodi:r1="78.688225"
+       sodipodi:r2="45.665279"
+       sodipodi:arg1="1.0612041"
+       sodipodi:arg2="1.6895226"
+       inkscape:flatsided="false"
+       inkscape:rounded="0"
+       inkscape:randomized="0"
+       d="m 179.80715,418.82535 -43.79473,-23.34656 -48.057629,12.38974 8.670585,-48.86575 -26.633969,-41.87688 49.153453,-6.85413 31.59693,-38.27107 21.70791,44.62966 46.16195,18.22405 -35.73722,34.43678 z"
+       transform="matrix(0.2727826,6.8080206e-2,-6.8080206e-2,0.2727826,71.260436,381.71532)" />
+    <path
+       transform="matrix(0.2047873,1.2440148e-2,-1.2440148e-2,0.2047873,101.54119,377.50775)"
+       d="m 179.80715,418.82535 -43.79473,-23.34656 -48.057629,12.38974 8.670585,-48.86575 -26.633969,-41.87688 49.153453,-6.85413 31.59693,-38.27107 21.70791,44.62966 46.16195,18.22405 -35.73722,34.43678 z"
+       inkscape:randomized="0"
+       inkscape:rounded="0"
+       inkscape:flatsided="false"
+       sodipodi:arg2="1.6895226"
+       sodipodi:arg1="1.0612041"
+       sodipodi:r2="45.665279"
+       sodipodi:r1="78.688225"
+       sodipodi:cy="350.13498"
+       sodipodi:cx="141.42136"
+       sodipodi:sides="5"
+       id="path5582"
+       style="opacity:0.22790701;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:#ffffff;stroke-width:1.70000005;stroke-linecap:round;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:block;overflow:visible"
+       sodipodi:type="star" />
+    <path
+       sodipodi:type="star"
+       style="opacity:0.22790701;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:#ffffff;stroke-width:1.70000005;stroke-linecap:round;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:block;overflow:visible"
+       id="path6523"
+       sodipodi:sides="5"
+       sodipodi:cx="141.42136"
+       sodipodi:cy="350.13498"
+       sodipodi:r1="78.688225"
+       sodipodi:r2="45.665279"
+       sodipodi:arg1="1.0612041"
+       sodipodi:arg2="1.6895226"
+       inkscape:flatsided="false"
+       inkscape:rounded="0"
+       inkscape:randomized="0"
+       d="m 179.80715,418.82535 -43.79473,-23.34656 -48.057629,12.38974 8.670585,-48.86575 -26.633969,-41.87688 49.153453,-6.85413 31.59693,-38.27107 21.70791,44.62966 46.16195,18.22405 -35.73722,34.43678 z"
+       transform="matrix(0.9554143,6.4781284e-2,-6.4781284e-2,0.9554143,-54.464507,409.68654)" />
+  </g>
+</svg>
diff --git a/data/backgrounds/default_bg.svg b/data/backgrounds/default_bg.svg
new file mode 100644 (file)
index 0000000..17d94d9
--- /dev/null
@@ -0,0 +1,1333 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Sodipodi ("http://www.sodipodi.com/") -->
+
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://creativecommons.org/ns#"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:xlink="http://www.w3.org/1999/xlink"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   version="1.0"
+   x="0"
+   y="0"
+   width="1000"
+   height="800"
+   id="svg559"
+   sodipodi:version="0.32"
+   inkscape:version="0.48.0 r9654"
+   sodipodi:docname="default_bg.svg"
+   inkscape:output_extension="org.inkscape.output.svg.inkscape">
+  <metadata
+     id="metadata35">
+    <rdf:RDF>
+      <cc:Work
+         rdf:about="">
+        <dc:format>image/svg+xml</dc:format>
+        <dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+      </cc:Work>
+    </rdf:RDF>
+  </metadata>
+  <sodipodi:namedview
+     inkscape:window-height="1026"
+     inkscape:window-width="1920"
+     inkscape:pageshadow="2"
+     inkscape:pageopacity="0.0"
+     guidetolerance="10.0"
+     gridtolerance="10.0"
+     objecttolerance="10.0"
+     borderopacity="1.0"
+     bordercolor="#666666"
+     pagecolor="#ffffff"
+     id="base"
+     inkscape:zoom="0.61522534"
+     inkscape:cx="535.68141"
+     inkscape:cy="409.90349"
+     inkscape:window-x="0"
+     inkscape:window-y="0"
+     inkscape:current-layer="svg559"
+     showgrid="false"
+     showguides="true"
+     inkscape:guide-bbox="true"
+     inkscape:window-maximized="1"
+     borderlayer="true" />
+  <defs
+     id="defs561">
+    <linearGradient
+       inkscape:collect="always"
+       id="linearGradient4286">
+      <stop
+         style="stop-color:#000000;stop-opacity:1;"
+         offset="0"
+         id="stop4288" />
+      <stop
+         style="stop-color:#000000;stop-opacity:0;"
+         offset="1"
+         id="stop4290" />
+    </linearGradient>
+    <radialGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient6239"
+       id="radialGradient6297"
+       cx="73.08477"
+       cy="-64.148376"
+       fx="73.08477"
+       fy="-64.148376"
+       r="139.13554"
+       gradientTransform="matrix(1.2783381,0.4169453,-0.272318,0.846931,-30.398528,-33.221331)"
+       gradientUnits="userSpaceOnUse"
+       spreadMethod="reflect" />
+    <linearGradient
+       id="linearGradient6239">
+      <stop
+         style="stop-color:#1f1f1f;stop-opacity:1;"
+         offset="0"
+         id="stop6241" />
+      <stop
+         style="stop-color:#000000;stop-opacity:1;"
+         offset="1"
+         id="stop6243" />
+    </linearGradient>
+    <filter
+       color-interpolation-filters="sRGB"
+       inkscape:collect="always"
+       id="filter6439">
+      <feGaussianBlur
+         inkscape:collect="always"
+         stdDeviation="6.8900544"
+         id="feGaussianBlur6441" />
+    </filter>
+    <radialGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient6239"
+       id="radialGradient6475"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(1,0,0,0.8902338,0,0.1024869)"
+       spreadMethod="reflect"
+       cx="0.00033175375"
+       cy="0.93368369"
+       fx="0.00033175375"
+       fy="0.93368369"
+       r="139.13554" />
+    <radialGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient6239"
+       id="radialGradient6295"
+       cx="-54.119453"
+       cy="-33.586506"
+       fx="-54.119453"
+       fy="-33.586506"
+       r="85.972984"
+       gradientTransform="matrix(1,0,0,1.2958795,0,-0.2762501)"
+       gradientUnits="userSpaceOnUse"
+       spreadMethod="reflect" />
+    <filter
+       color-interpolation-filters="sRGB"
+       inkscape:collect="always"
+       id="filter6435">
+      <feGaussianBlur
+         inkscape:collect="always"
+         stdDeviation="5.8924159"
+         id="feGaussianBlur6437" />
+    </filter>
+    <radialGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient6239"
+       id="radialGradient6473"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(1,0,0,1.2958795,0,-0.2762501)"
+       spreadMethod="reflect"
+       cx="-0.00043312719"
+       cy="0.93365741"
+       fx="-0.00043312719"
+       fy="0.93365741"
+       r="85.972984" />
+    <radialGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient6239"
+       id="radialGradient6471"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(1,0,0,1.2958795,0,-0.2762501)"
+       spreadMethod="reflect"
+       cx="-0.00043312719"
+       cy="0.93365741"
+       fx="-0.00043312719"
+       fy="0.93365741"
+       r="85.972984" />
+    <radialGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient6239"
+       id="radialGradient6293"
+       cx="121.82938"
+       cy="29.891867"
+       fx="121.82938"
+       fy="29.891867"
+       r="85.972984"
+       gradientTransform="matrix(1,0,0,1.2958795,0,-0.2762501)"
+       gradientUnits="userSpaceOnUse"
+       spreadMethod="reflect" />
+    <filter
+       color-interpolation-filters="sRGB"
+       inkscape:collect="always"
+       id="filter6593">
+      <feGaussianBlur
+         inkscape:collect="always"
+         stdDeviation="3.9535839"
+         id="feGaussianBlur6595" />
+    </filter>
+    <radialGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient6239"
+       id="radialGradient6469"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(1,0,0,1.2958795,0,-0.2762501)"
+       spreadMethod="reflect"
+       cx="-0.00043312719"
+       cy="0.93365741"
+       fx="-0.00043312719"
+       fy="0.93365741"
+       r="85.972984" />
+    <radialGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient6239"
+       id="radialGradient6467"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(1,0,0,1.2958795,0,-0.2762501)"
+       spreadMethod="reflect"
+       cx="-0.00043312719"
+       cy="0.93365741"
+       fx="-0.00043312719"
+       fy="0.93365741"
+       r="85.972984" />
+    <radialGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient6239"
+       id="radialGradient6291"
+       cx="-84.775795"
+       cy="102.82321"
+       fx="-84.775795"
+       fy="102.82321"
+       r="139.13554"
+       gradientTransform="matrix(0.609306,0,-1.7525848e-8,0.8902338,-33.121388,0.102488)"
+       gradientUnits="userSpaceOnUse"
+       spreadMethod="reflect" />
+    <filter
+       color-interpolation-filters="sRGB"
+       inkscape:collect="always"
+       id="filter6609">
+      <feGaussianBlur
+         inkscape:collect="always"
+         stdDeviation="3.7116756"
+         id="feGaussianBlur6611" />
+    </filter>
+    <radialGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient6239"
+       id="radialGradient6465"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(1,0,0,0.8902338,0,0.1024869)"
+       spreadMethod="reflect"
+       cx="0.00033175375"
+       cy="0.93368369"
+       fx="0.00033175375"
+       fy="0.93368369"
+       r="139.13554" />
+    <radialGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient6239"
+       id="radialGradient6463"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(1,0,0,0.8902338,0,0.1024869)"
+       spreadMethod="reflect"
+       cx="0.00033175375"
+       cy="0.93368369"
+       fx="0.00033175375"
+       fy="0.93368369"
+       r="139.13554" />
+    <radialGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient6239"
+       id="radialGradient6289"
+       cx="-55.975525"
+       cy="110.75415"
+       fx="-55.975525"
+       fy="110.75415"
+       r="139.13554"
+       gradientTransform="matrix(0.4023117,1.7847586e-8,-2.8882931e-8,0.8902338,-33.455913,0.1024879)"
+       gradientUnits="userSpaceOnUse"
+       spreadMethod="reflect" />
+    <filter
+       color-interpolation-filters="sRGB"
+       inkscape:collect="always"
+       id="filter6781">
+      <feGaussianBlur
+         inkscape:collect="always"
+         stdDeviation="5.8770044"
+         id="feGaussianBlur6783" />
+    </filter>
+    <radialGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient6239"
+       id="radialGradient6461"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(1,0,0,0.8902338,0,0.1024869)"
+       spreadMethod="reflect"
+       cx="0.00033175375"
+       cy="0.93368369"
+       fx="0.00033175375"
+       fy="0.93368369"
+       r="139.13554" />
+    <radialGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient6239"
+       id="radialGradient6459"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(1,0,0,0.8902338,0,0.1024869)"
+       spreadMethod="reflect"
+       cx="0.00033175375"
+       cy="0.93368369"
+       fx="0.00033175375"
+       fy="0.93368369"
+       r="139.13554" />
+    <radialGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient6239"
+       id="radialGradient6287"
+       cx="-0.00043312719"
+       cy="0.93365741"
+       fx="-0.00043312719"
+       fy="0.93365741"
+       r="85.972984"
+       gradientTransform="matrix(0.7054225,-0.6154847,1,0.8642415,-0.933785,0.1264853)"
+       gradientUnits="userSpaceOnUse"
+       spreadMethod="reflect" />
+    <filter
+       color-interpolation-filters="sRGB"
+       inkscape:collect="always"
+       id="filter6529">
+      <feGaussianBlur
+         inkscape:collect="always"
+         stdDeviation="4.8307749"
+         id="feGaussianBlur6531" />
+    </filter>
+    <radialGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient6239"
+       id="radialGradient6457"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(1,0,0,1.2958795,0,-0.2762501)"
+       spreadMethod="reflect"
+       cx="-0.00043312719"
+       cy="0.93365741"
+       fx="-0.00043312719"
+       fy="0.93365741"
+       r="85.972984" />
+    <radialGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient6239"
+       id="radialGradient6455"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(1,0,0,1.2958795,0,-0.2762501)"
+       spreadMethod="reflect"
+       cx="-0.00043312719"
+       cy="0.93365741"
+       fx="-0.00043312719"
+       fy="0.93365741"
+       r="85.972984" />
+    <radialGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient6239"
+       id="radialGradient6285"
+       cx="-108.65945"
+       cy="46.669819"
+       fx="-108.65945"
+       fy="46.669819"
+       r="85.972984"
+       gradientTransform="matrix(1,0,0,1.2958795,0,-0.2762501)"
+       gradientUnits="userSpaceOnUse"
+       spreadMethod="reflect" />
+    <filter
+       color-interpolation-filters="sRGB"
+       inkscape:collect="always"
+       id="filter6415">
+      <feGaussianBlur
+         inkscape:collect="always"
+         stdDeviation="5.5378501"
+         id="feGaussianBlur6417" />
+    </filter>
+    <radialGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient6239"
+       id="radialGradient6453"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(1,0,0,1.2958795,0,-0.2762501)"
+       spreadMethod="reflect"
+       cx="-0.00043312719"
+       cy="0.93365741"
+       fx="-0.00043312719"
+       fy="0.93365741"
+       r="85.972984" />
+    <radialGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient6239"
+       id="radialGradient6451"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(1,0,0,1.2958795,0,-0.2762501)"
+       spreadMethod="reflect"
+       cx="-0.00043312719"
+       cy="0.93365741"
+       fx="-0.00043312719"
+       fy="0.93365741"
+       r="85.972984" />
+    <radialGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient6239"
+       id="radialGradient6283"
+       cx="54.552696"
+       cy="61.81908"
+       fx="54.552696"
+       fy="61.81908"
+       r="85.972984"
+       gradientTransform="matrix(0.8491493,-0.5169578,0.3359319,0.5286533,-12.537687,75.354409)"
+       gradientUnits="userSpaceOnUse"
+       spreadMethod="reflect" />
+    <filter
+       color-interpolation-filters="sRGB"
+       inkscape:collect="always"
+       id="filter6693">
+      <feGaussianBlur
+         inkscape:collect="always"
+         stdDeviation="4.3837536"
+         id="feGaussianBlur6695" />
+    </filter>
+    <radialGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient6239"
+       id="radialGradient6449"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(1,0,0,1.2958795,0,-0.2762501)"
+       spreadMethod="reflect"
+       cx="-0.00043312719"
+       cy="0.93365741"
+       fx="-0.00043312719"
+       fy="0.93365741"
+       r="85.972984" />
+    <radialGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient6239"
+       id="radialGradient6447"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(1,0,0,1.2958795,0,-0.2762501)"
+       spreadMethod="reflect"
+       cx="-0.00043312719"
+       cy="0.93365741"
+       fx="-0.00043312719"
+       fy="0.93365741"
+       r="85.972984" />
+    <radialGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient6239"
+       id="radialGradient6281"
+       cx="-52.682827"
+       cy="22.638672"
+       fx="-52.682827"
+       fy="22.638672"
+       r="139.13554"
+       gradientTransform="matrix(0.5485002,0.04758875,-0.03800873,0.486111,-22.925821,11.758401)"
+       gradientUnits="userSpaceOnUse"
+       spreadMethod="reflect" />
+    <filter
+       color-interpolation-filters="sRGB"
+       inkscape:collect="always"
+       id="filter6557">
+      <feGaussianBlur
+         inkscape:collect="always"
+         stdDeviation="6.374635"
+         id="feGaussianBlur6559" />
+    </filter>
+    <radialGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient6239"
+       id="radialGradient6445"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(1,0,0,0.8902338,0,0.1024869)"
+       spreadMethod="reflect"
+       cx="0.00033175375"
+       cy="0.93368369"
+       fx="0.00033175375"
+       fy="0.93368369"
+       r="139.13554" />
+    <radialGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient6239"
+       id="radialGradient6443"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(1,0,0,0.8902338,0,0.1024869)"
+       spreadMethod="reflect"
+       cx="0.00033175375"
+       cy="0.93368369"
+       fx="0.00033175375"
+       fy="0.93368369"
+       r="139.13554" />
+    <radialGradient
+       r="139.13554"
+       fy="0.93368369"
+       fx="0.00033175375"
+       cy="0.93368369"
+       cx="0.00033175375"
+       spreadMethod="reflect"
+       gradientTransform="matrix(1,0,0,0.8902338,0,0.1024869)"
+       gradientUnits="userSpaceOnUse"
+       id="radialGradient3137"
+       xlink:href="#linearGradient6239"
+       inkscape:collect="always" />
+    <linearGradient
+       id="linearGradient3629-3">
+      <stop
+         id="stop3631-1"
+         offset="0"
+         style="stop-color:#00a3cd;stop-opacity:0;" />
+      <stop
+         id="stop3633-4"
+         offset="1"
+         style="stop-color:#000000;stop-opacity:1;" />
+    </linearGradient>
+    <filter
+       id="filter5083"
+       inkscape:collect="always">
+      <feGaussianBlur
+         id="feGaussianBlur5085"
+         stdDeviation="2.8444007"
+         inkscape:collect="always" />
+    </filter>
+    <filter
+       inkscape:collect="always"
+       id="filter4095">
+      <feGaussianBlur
+         inkscape:collect="always"
+         stdDeviation="5.8306714"
+         id="feGaussianBlur4097" />
+    </filter>
+    <radialGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient6239"
+       id="radialGradient4230"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(1,0,0,0.8902338,0,0.1024869)"
+       spreadMethod="reflect"
+       cx="0.00033175375"
+       cy="0.93368369"
+       fx="0.00033175375"
+       fy="0.93368369"
+       r="139.13554" />
+    <radialGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient6239"
+       id="radialGradient4232"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(1,0,0,0.8902338,0,0.1024869)"
+       spreadMethod="reflect"
+       cx="0.00033175375"
+       cy="0.93368369"
+       fx="0.00033175375"
+       fy="0.93368369"
+       r="139.13554" />
+    <radialGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient6239"
+       id="radialGradient4234"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(1.2783381,0.4169453,-0.272318,0.846931,-30.398528,-33.221331)"
+       spreadMethod="reflect"
+       cx="73.08477"
+       cy="-64.148376"
+       fx="73.08477"
+       fy="-64.148376"
+       r="139.13554" />
+    <radialGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient6239"
+       id="radialGradient4236"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(1,0,0,1.2958795,0,-0.2762501)"
+       spreadMethod="reflect"
+       cx="-0.00043312719"
+       cy="0.93365741"
+       fx="-0.00043312719"
+       fy="0.93365741"
+       r="85.972984" />
+    <radialGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient6239"
+       id="radialGradient4238"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(1,0,0,1.2958795,0,-0.2762501)"
+       spreadMethod="reflect"
+       cx="-0.00043312719"
+       cy="0.93365741"
+       fx="-0.00043312719"
+       fy="0.93365741"
+       r="85.972984" />
+    <radialGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient6239"
+       id="radialGradient4240"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(1,0,0,1.2958795,0,-0.2762501)"
+       spreadMethod="reflect"
+       cx="-54.119453"
+       cy="-33.586506"
+       fx="-54.119453"
+       fy="-33.586506"
+       r="85.972984" />
+    <radialGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient6239"
+       id="radialGradient4242"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(1,0,0,1.2958795,0,-0.2762501)"
+       spreadMethod="reflect"
+       cx="-0.00043312719"
+       cy="0.93365741"
+       fx="-0.00043312719"
+       fy="0.93365741"
+       r="85.972984" />
+    <radialGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient6239"
+       id="radialGradient4244"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(1,0,0,1.2958795,0,-0.2762501)"
+       spreadMethod="reflect"
+       cx="-0.00043312719"
+       cy="0.93365741"
+       fx="-0.00043312719"
+       fy="0.93365741"
+       r="85.972984" />
+    <radialGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient6239"
+       id="radialGradient4246"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(1,0,0,1.2958795,0,-0.2762501)"
+       spreadMethod="reflect"
+       cx="121.82938"
+       cy="29.891867"
+       fx="121.82938"
+       fy="29.891867"
+       r="85.972984" />
+    <radialGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient6239"
+       id="radialGradient4248"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(1,0,0,0.8902338,0,0.1024869)"
+       spreadMethod="reflect"
+       cx="0.00033175375"
+       cy="0.93368369"
+       fx="0.00033175375"
+       fy="0.93368369"
+       r="139.13554" />
+    <radialGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient6239"
+       id="radialGradient4250"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(1,0,0,0.8902338,0,0.1024869)"
+       spreadMethod="reflect"
+       cx="0.00033175375"
+       cy="0.93368369"
+       fx="0.00033175375"
+       fy="0.93368369"
+       r="139.13554" />
+    <radialGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient6239"
+       id="radialGradient4252"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(0.609306,0,-1.7525848e-8,0.8902338,-33.121388,0.102488)"
+       spreadMethod="reflect"
+       cx="-84.775795"
+       cy="102.82321"
+       fx="-84.775795"
+       fy="102.82321"
+       r="139.13554" />
+    <radialGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient6239"
+       id="radialGradient4254"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(1,0,0,0.8902338,0,0.1024869)"
+       spreadMethod="reflect"
+       cx="0.00033175375"
+       cy="0.93368369"
+       fx="0.00033175375"
+       fy="0.93368369"
+       r="139.13554" />
+    <radialGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient6239"
+       id="radialGradient4256"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(1,0,0,0.8902338,0,0.1024869)"
+       spreadMethod="reflect"
+       cx="0.00033175375"
+       cy="0.93368369"
+       fx="0.00033175375"
+       fy="0.93368369"
+       r="139.13554" />
+    <radialGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient6239"
+       id="radialGradient4258"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(0.4023117,1.7847586e-8,-2.8882931e-8,0.8902338,-33.455913,0.1024879)"
+       spreadMethod="reflect"
+       cx="-55.975525"
+       cy="110.75415"
+       fx="-55.975525"
+       fy="110.75415"
+       r="139.13554" />
+    <radialGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient6239"
+       id="radialGradient4260"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(1,0,0,1.2958795,0,-0.2762501)"
+       spreadMethod="reflect"
+       cx="-0.00043312719"
+       cy="0.93365741"
+       fx="-0.00043312719"
+       fy="0.93365741"
+       r="85.972984" />
+    <radialGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient6239"
+       id="radialGradient4262"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(1,0,0,1.2958795,0,-0.2762501)"
+       spreadMethod="reflect"
+       cx="-0.00043312719"
+       cy="0.93365741"
+       fx="-0.00043312719"
+       fy="0.93365741"
+       r="85.972984" />
+    <radialGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient6239"
+       id="radialGradient4264"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(0.7054225,-0.6154847,1,0.8642415,-0.933785,0.1264853)"
+       spreadMethod="reflect"
+       cx="-0.00043312719"
+       cy="0.93365741"
+       fx="-0.00043312719"
+       fy="0.93365741"
+       r="85.972984" />
+    <radialGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient6239"
+       id="radialGradient4266"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(1,0,0,1.2958795,0,-0.2762501)"
+       spreadMethod="reflect"
+       cx="-0.00043312719"
+       cy="0.93365741"
+       fx="-0.00043312719"
+       fy="0.93365741"
+       r="85.972984" />
+    <radialGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient6239"
+       id="radialGradient4268"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(1,0,0,1.2958795,0,-0.2762501)"
+       spreadMethod="reflect"
+       cx="-0.00043312719"
+       cy="0.93365741"
+       fx="-0.00043312719"
+       fy="0.93365741"
+       r="85.972984" />
+    <radialGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient6239"
+       id="radialGradient4270"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(1,0,0,1.2958795,0,-0.2762501)"
+       spreadMethod="reflect"
+       cx="-108.65945"
+       cy="46.669819"
+       fx="-108.65945"
+       fy="46.669819"
+       r="85.972984" />
+    <radialGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient6239"
+       id="radialGradient4272"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(1,0,0,1.2958795,0,-0.2762501)"
+       spreadMethod="reflect"
+       cx="-0.00043312719"
+       cy="0.93365741"
+       fx="-0.00043312719"
+       fy="0.93365741"
+       r="85.972984" />
+    <radialGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient6239"
+       id="radialGradient4274"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(1,0,0,1.2958795,0,-0.2762501)"
+       spreadMethod="reflect"
+       cx="-0.00043312719"
+       cy="0.93365741"
+       fx="-0.00043312719"
+       fy="0.93365741"
+       r="85.972984" />
+    <radialGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient6239"
+       id="radialGradient4276"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(0.8491493,-0.5169578,0.3359319,0.5286533,-12.537687,75.354409)"
+       spreadMethod="reflect"
+       cx="54.552696"
+       cy="61.81908"
+       fx="54.552696"
+       fy="61.81908"
+       r="85.972984" />
+    <radialGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient6239"
+       id="radialGradient4278"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(1,0,0,0.8902338,0,0.1024869)"
+       spreadMethod="reflect"
+       cx="0.00033175375"
+       cy="0.93368369"
+       fx="0.00033175375"
+       fy="0.93368369"
+       r="139.13554" />
+    <radialGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient6239"
+       id="radialGradient4280"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(1,0,0,0.8902338,0,0.1024869)"
+       spreadMethod="reflect"
+       cx="0.00033175375"
+       cy="0.93368369"
+       fx="0.00033175375"
+       fy="0.93368369"
+       r="139.13554" />
+    <radialGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient6239"
+       id="radialGradient4282"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(0.5485002,0.04758875,-0.03800873,0.486111,-22.925821,11.758401)"
+       spreadMethod="reflect"
+       cx="-52.682827"
+       cy="22.638672"
+       fx="-52.682827"
+       fy="22.638672"
+       r="139.13554" />
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient4286"
+       id="linearGradient4292"
+       x1="627.09814"
+       y1="652.71136"
+       x2="627.09814"
+       y2="572.54468"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(0.80171169,0,0,1.0619067,27.135255,9.429704)" />
+    <radialGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient3629-3"
+       id="radialGradient4313"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(0.43458478,-0.60711143,1.8098112,0.66550087,-984.93862,492.67693)"
+       cx="727.25122"
+       cy="757.60583"
+       fx="727.25122"
+       fy="757.60583"
+       r="500" />
+  </defs>
+  <rect
+     style="fill:#000000;fill-opacity:1;stroke:none"
+     id="rect4231"
+     width="1000"
+     height="698.85754"
+     x="0"
+     y="101.14243" />
+  <rect
+     style="fill:#ffffff;fill-opacity:1;stroke:none"
+     id="rect2855-8"
+     width="1002.3828"
+     height="574.74896"
+     x="-1.7211162"
+     y="106.1238" />
+  <rect
+     style="fill:url(#radialGradient4313);fill-opacity:1;stroke:none"
+     id="rect2855"
+     width="1002.3828"
+     height="574.74896"
+     x="-1.7211162"
+     y="106.1238" />
+  <text
+     xml:space="preserve"
+     style="font-size:21.12607765px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;font-family:Bitstream Vera Sans"
+     x="225.09085"
+     y="770.20593"
+     id="text2508-0"
+     transform="scale(1.181198,0.84659815)"><tspan
+       sodipodi:role="line"
+       id="tspan2510-6"
+       x="225.09085"
+       y="770.20593" /></text>
+  <g
+     id="g3955"
+     transform="matrix(1.0023828,0,0,0.71843624,16.811257,63.593811)"
+     style="opacity:0.6;filter:url(#filter5083)" />
+  <g
+     id="g4892"
+     transform="matrix(0.99958974,0,0,0.71843624,-0.03697497,106.10154)">
+    <g
+       transform="matrix(1.2468256,0,0,1.1986102,1.2039301,52.246604)"
+       id="g2836" />
+    <g
+       transform="matrix(1.2468256,0,0,1.1986102,0.760128,231.91957)"
+       id="g2209" />
+    <g
+       transform="matrix(5.0734563,0,0,5.3232265,22.200477,397.25206)"
+       id="g2411">
+      <g
+         transform="translate(-230.9546,-533.6597)"
+         style="fill:#000000;fill-opacity:1"
+         id="g2883" />
+      <g
+         transform="translate(-230.9546,-533.6597)"
+         style="fill:#000000;fill-opacity:1"
+         id="g2887" />
+      <g
+         transform="translate(-230.9546,-533.6597)"
+         style="fill:#000000;fill-opacity:1"
+         id="g2891" />
+    </g>
+    <g
+       inkscape:label="Calque 1"
+       id="layer1-4"
+       transform="matrix(1.2842911,0,0,1.3475176,-322.83945,-416.05452)" />
+  </g>
+  <g
+     id="g3873"
+     transform="matrix(0.98299439,0,0,0.7023051,37.837667,110.80445)" />
+  <rect
+     y="554.6637"
+     x="-56.077015"
+     height="195.56619"
+     width="1297.0857"
+     id="rect4093"
+     style="fill:#000000;fill-opacity:1;stroke:none;filter:url(#filter4095)"
+     transform="matrix(0.80171169,0,0,1.0619067,27.135255,-36.570296)" />
+  <g
+     id="g4139"
+     transform="matrix(2.5900086,0,0,2.5900086,1026.5846,971.89115)"
+     style="fill:#424d58;fill-opacity:1">
+    <path
+       sodipodi:nodetypes="csscccccccccsccccccsssssssssssssscccsscccccccccssssccccccccccccssccccccsssccccccsscccscccscccssssscccsssssscccssssscccsssssscccccccccccssssssssscccscccccccscccccssssscccsscccssssssssssssssssscccscccccscccccccscccccccsssssscccccsscccccccsscccccscccssssssssssssssccccccccssccccccccccsscccsscccsscccccccccscccsssccccccccsssssssssssssssssssssssscccsssssssssssscccssssssssssscccssssssssssssccsssccccccccccsscccccccccccccccssssssccsssscccccsssccssssccssssssssccccccccccssssssscccsssssccccccccccssssccccccccccscccccsssscccccscccssccsssssssccccccssscccccccccccssscccccccssscccsccccccsccsssssssssssssccssssccsssssssssssssccccccccccssssscccccssscccsccsssscccccscccssssssscccssssssssssscccssscccccccssssccssssssccccccccscccccccsccccccsssssscccssscccccscccsssccccccssssssscccscccssscccsccccccccssssscccccccsssc"
+       id="path2384"
+       d="m -143.59532,-162.16068 c -2.34276,-0.11225 -4.63933,-0.94832 -6.50122,-2.36675 -0.58151,-0.44301 -1.42772,-1.25317 -1.86542,-1.78596 -1.33335,-1.62302 -2.13321,-3.43647 -2.41697,-5.47985 l -0.0289,-0.20795 -0.24943,0.007 -0.24944,0.007 -0.22753,0.66527 -0.22754,0.66527 0.005,0.91371 0.005,0.91373 0.42535,0.10752 c 0.4427,0.11191 0.60087,0.17919 0.64312,0.27355 0.0137,0.0307 0.0329,0.17019 0.0427,0.31004 l 0.0177,0.25427 -0.0692,0.0268 c -0.0381,0.0147 -0.13663,0.0235 -0.21902,0.0194 l -0.1498,-0.007 -0.0351,-0.14122 c -0.0284,-0.11413 -0.045,-0.14136 -0.0864,-0.14204 -0.0861,-0.001 -0.84331,-0.19921 -0.93853,-0.24518 -0.1035,-0.05 -0.16126,-0.14746 -0.16126,-0.27217 0,-0.0482 -0.009,-0.0934 -0.0204,-0.10045 -0.0289,-0.0182 -0.12765,0.0113 -0.12765,0.0381 0,0.0123 -0.35709,1.06444 -0.79354,2.33805 -0.67045,1.95641 -0.79416,2.339 -0.79751,2.46625 -0.003,0.12581 -0.0353,0.22698 -0.19398,0.61394 -0.23807,0.58046 -0.28355,0.65977 -0.4276,0.74567 -0.20474,0.12208 -0.50643,0.0786 -0.71811,-0.10341 -0.10377,-0.0892 -0.16076,-0.20067 -0.13917,-0.27211 0.0227,-0.0752 0.79397,-1.99256 0.82595,-2.05334 0.0209,-0.0397 0.0346,-0.0436 0.0759,-0.0211 0.0277,0.0151 0.0532,0.0237 0.0566,0.0191 0.003,-0.005 0.3139,-0.9107 0.69002,-2.01363 l 0.68385,-2.00532 -0.0506,-0.0548 c -0.0279,-0.0302 -0.0506,-0.0787 -0.0506,-0.10783 0,-0.0576 0.16701,-0.55338 0.20218,-0.60014 0.0119,-0.0158 0.0573,-0.0356 0.10093,-0.044 l 0.0793,-0.0152 0.29061,-0.8472 0.29059,-0.8472 -6.9e-4,-0.79707 -7e-4,-0.79705 -0.24672,0 -0.24673,0 -0.002,0.19455 c -0.004,0.30115 -0.0126,0.31866 -0.16429,0.32765 -0.12145,0.007 -0.12869,0.004 -0.14704,-0.0628 -0.0251,-0.0916 -0.0251,-1.12858 0,-1.22013 0.0183,-0.0669 0.0256,-0.07 0.14704,-0.0628 0.1517,0.009 0.16049,0.0265 0.16429,0.32765 l 0.002,0.19456 0.24673,0 0.24672,0 0,-1.06985 0,-1.06987 -0.1542,0.0154 c -0.59685,0.0598 -1.04662,0.0762 -2.1095,0.0772 l -1.19045,10e-4 -10e-6,3.13709 0,3.13709 0.0591,0.0512 c 0.0526,0.0455 0.0607,0.0782 0.0734,0.29592 0.012,0.20543 0.008,0.24477 -0.0221,0.24477 -0.0306,0 -0.0363,0.0662 -0.0363,0.41485 l 0,0.41484 -0.0678,0.0267 c -0.0962,0.0378 -0.56767,0.017 -0.66,-0.0292 l -0.074,-0.037 -0.007,-0.36095 c -0.005,-0.28516 5.4e-4,-0.36944 0.0285,-0.40137 0.0217,-0.0249 0.0417,-0.12744 0.052,-0.26636 0.0201,-0.27205 0.0302,-0.3138 0.0761,-0.3138 0.0305,0 0.0353,-0.4357 0.0353,-3.17355 l 0,-3.17354 -0.17889,-0.0142 c -0.81285,-0.0646 -1.44997,-0.11981 -1.51441,-0.13134 l -0.0772,-0.0138 -0.0187,1.10055 c -0.0103,0.60529 -0.0161,1.81224 -0.013,2.6821 0.006,1.64107 -0.003,1.92202 -0.0626,1.97235 -0.0223,0.0189 -0.035,0.0786 -0.035,0.1646 l 0,0.13499 -0.12953,-3.9e-4 c -0.0713,-2e-4 -0.14305,-0.009 -0.15958,-0.0198 -0.05,-0.0324 -0.0591,-0.45792 -0.0708,-3.33715 l -0.0112,-2.7423 -0.055,-0.0119 c -0.0302,-0.007 -0.16046,-0.0245 -0.28937,-0.0399 -0.36409,-0.0434 -1.42292,-0.21766 -1.88745,-0.31056 l -0.41945,-0.0839 -0.0816,0.0784 c -0.0779,0.0749 -0.0909,0.0784 -0.28375,0.078 -0.38785,-9.5e-4 -0.69942,-0.15285 -0.74481,-0.3631 -0.009,-0.0417 -0.0295,-0.0757 -0.0456,-0.0757 -0.0161,0 -0.23448,-0.0634 -0.48532,-0.14081 -0.25085,-0.0775 -0.47551,-0.14655 -0.49926,-0.15356 -0.0409,-0.0121 -0.0432,0.11362 -0.0427,2.39393 l 4.9e-4,2.40666 0.96791,1.40829 c 3.03481,4.41558 3.6361,5.2807 3.6749,5.28732 0.0411,0.007 1.10063,1.52139 1.12299,1.60506 0.0302,0.11312 -0.13232,0.22239 -0.3302,0.22198 -0.14794,-3e-4 -0.33775,-0.0876 -0.44316,-0.20378 -0.12508,-0.13788 -0.55745,-0.77926 -0.59864,-0.888 -0.0209,-0.0552 -0.57736,-0.88556 -1.23655,-1.84517 -0.6592,-0.95961 -1.63669,-2.38238 -2.17221,-3.16171 l -0.97368,-1.41695 -0.0131,1.16591 c -0.0101,0.89455 -0.0207,1.18125 -0.0457,1.23178 -0.0518,0.10463 -0.18318,0.16143 -0.64879,0.28044 -0.37775,0.0966 -0.4404,0.1066 -0.47099,0.0755 -0.0306,-0.0311 -0.0395,-0.0157 -0.067,0.11607 -0.0174,0.0836 -0.047,0.16491 -0.0658,0.18075 -0.0219,0.0185 -0.0922,0.024 -0.19622,0.0155 l -0.16214,-0.0132 0.0173,0.35502 c 0.01,0.19526 0.0248,0.45504 0.034,0.5773 0.0166,0.22114 0.0164,0.22243 -0.046,0.24931 -0.0345,0.0149 -0.14408,0.0278 -0.24354,0.0288 -0.14466,0.001 -0.18715,-0.007 -0.21224,-0.0419 -0.0396,-0.0551 -0.0745,-0.56517 -0.0414,-0.60569 0.0155,-0.0189 0.003,-0.29364 -0.0355,-0.78197 -0.0326,-0.41402 -0.0595,-0.78666 -0.0598,-0.82807 l -5.3e-4,-0.0753 -0.17893,0.009 c -0.22596,0.0111 -0.58711,-0.0379 -0.72615,-0.0986 l -0.10661,-0.0465 -5.9e-4,-0.15779 -5.9e-4,-0.1578 -0.92758,-0.67781 c -0.51017,-0.37281 -0.9861,-0.72021 -1.05764,-0.77201 l -0.13008,-0.0942 -1.9323,2.51675 c -1.06276,1.38423 -2.093,2.72576 -2.2894,2.98119 -0.19641,0.25544 -0.40504,0.51761 -0.46361,0.58261 -0.0654,0.0725 -0.10652,0.14208 -0.10652,0.18008 0,0.0635 -0.0326,0.11181 -0.38504,0.57036 -0.21094,0.27448 -0.33077,0.39716 -0.44832,0.45901 -0.0908,0.0478 -0.27903,0.0747 -0.37391,0.0535 -0.1026,-0.0229 -0.22379,-0.1298 -0.22357,-0.19716 1e-4,-0.0322 0.22171,-0.34536 0.54465,-0.76973 0.58935,-0.77442 0.63709,-0.8329 0.66545,-0.81506 0.0103,0.007 1.60751,-2.05659 3.54927,-4.58465 l 3.53045,-4.59648 0,-0.17156 c 0,-0.1557 0.006,-0.1764 0.0654,-0.2239 0.036,-0.0288 0.10813,-0.0593 0.16036,-0.0678 l 0.095,-0.0155 -2.8e-4,-2.92771 -2.7e-4,-2.92772 -0.12926,-0.0502 -0.12925,-0.0502 -0.007,-0.56169 c -0.004,-0.36072 0.002,-0.5729 0.0189,-0.59303 0.0141,-0.0172 0.092,-0.0503 0.1732,-0.0735 l 0.1476,-0.0421 -5.3e-4,-5.31454 -5.4e-4,-5.31452 -0.0796,-0.0377 c -0.0778,-0.0368 -0.0808,-0.0444 -0.13185,-0.33344 -0.0287,-0.16268 -0.057,-0.30071 -0.063,-0.30672 -0.006,-0.006 -0.65795,1.07897 -1.449,2.41107 -0.79104,1.3321 -1.46188,2.43883 -1.49074,2.45941 -0.09,0.0641 -0.23243,0.0479 -0.31482,-0.036 -0.15196,-0.15463 -0.22324,-0.0148 1.40839,-2.76178 l 1.48051,-2.49252 -0.0778,-0.0902 c -0.26447,-0.30648 -0.2916,-0.8292 -0.0661,-1.2724 0.19542,-0.38399 0.47628,-0.63707 0.86903,-0.7831 0.0556,-0.0207 0.21135,-0.045 0.3461,-0.054 l 0.245,-0.0164 2.01896,-3.39927 c 1.11043,-1.86961 2.01392,-3.4044 2.00777,-3.41066 -0.006,-0.006 -0.39764,-0.11068 -0.86997,-0.23204 -3.09532,-0.7953 -5.6967,-1.71695 -7.6684,-2.71682 -1.31222,-0.66544 -2.14742,-1.2401 -2.63309,-1.81167 -0.42444,-0.49952 -0.50309,-0.96567 -0.22742,-1.34778 0.27343,-0.37898 1.01607,-0.68189 2.05866,-0.83966 1.13773,-0.17216 2.96353,-0.19039 4.81115,-0.048 4.75452,0.36633 10.7921,1.7427 14.95157,3.4085 2.63454,1.05508 4.29525,2.10462 4.74784,3.00053 0.32055,0.63454 -0.0388,1.17428 -1.01034,1.51733 -0.46074,0.1627 -1.26036,0.31868 -1.84388,0.3597 -0.1323,0.009 -0.24056,0.0244 -0.24056,0.0336 0,0.009 0.0583,0.0317 0.12953,0.0501 0.2224,0.0574 1.12238,0.36459 1.5482,0.52842 2.80935,1.08079 5.07344,2.66212 5.38892,3.76384 0.0796,0.27804 0.0624,0.37254 -0.19534,1.0693 -0.12892,0.34855 -0.2343,0.64351 -0.23419,0.65545 1.3e-4,0.0119 0.37484,0.16329 0.83271,0.33634 l 0.83247,0.31461 0.008,-0.0884 c 0.01,-0.10975 0.0427,-0.15175 0.11837,-0.15175 0.0586,0 0.0587,-2.9e-4 0.0587,-0.31081 l 0,-0.31081 -0.19121,-0.0218 -0.19121,-0.0218 -0.007,-0.11599 c -0.009,-0.14828 -0.0145,-0.14692 0.53785,-0.14692 0.55226,0 0.54729,-0.001 0.53783,0.14692 l -0.007,0.11599 -0.20427,0.0224 -0.20429,0.0224 0.007,0.30378 0.007,0.30379 0.074,0.0129 c 0.0679,0.0118 0.0746,0.0221 0.0813,0.12572 0.007,0.1105 0.01,0.11363 0.12338,0.1505 l 0.11604,0.0377 0,0.27581 0,0.27581 -0.0678,0.0331 -0.0678,0.0331 0,0.53916 c 0,0.49053 0.004,0.54063 0.0432,0.55548 0.0237,0.009 0.13753,0.0785 0.25288,0.15441 0.48049,0.31635 0.43455,0.29785 0.67407,0.27172 0.13314,-0.0145 0.27382,-0.0141 0.37844,0.001 0.18914,0.0277 0.17485,0.0338 0.61939,-0.26394 0.12569,-0.0842 0.25061,-0.16018 0.27756,-0.16889 0.0469,-0.0151 0.049,-0.0391 0.049,-0.54935 l 0,-0.53352 -0.0802,-0.0359 -0.0802,-0.0359 -0.007,-0.22593 c -0.01,-0.31096 -0.002,-0.3332 0.13115,-0.36946 0.10897,-0.0297 0.1105,-0.0315 0.1105,-0.13712 0,-0.0997 0.005,-0.10849 0.0802,-0.12814 l 0.0802,-0.0211 0.007,-0.30244 0.007,-0.30244 -0.20428,-0.0224 -0.20429,-0.0224 -0.007,-0.11585 c -0.007,-0.11219 -0.005,-0.11637 0.0709,-0.1318 0.10176,-0.0207 0.85676,-0.0207 0.95851,0 0.0758,0.0154 0.0781,0.0196 0.0709,0.1318 l -0.007,0.11585 -0.20357,0.0223 -0.20354,0.0223 0,0.29858 c 0,0.26246 0.005,0.30023 0.0432,0.31216 0.0948,0.0298 0.11771,0.0568 0.12952,0.1528 l 0.0123,0.10009 0.84918,-0.32235 c 0.46707,-0.17729 0.85246,-0.32566 0.85644,-0.32971 0.004,-0.004 -0.12648,-0.36835 -0.28991,-0.80957 -0.27329,-0.73775 -0.29712,-0.81574 -0.29651,-0.97064 0.001,-0.31003 0.18089,-0.64669 0.55818,-1.04603 0.58139,-0.61537 1.3967,-1.18661 2.55397,-1.78942 1.4853,-0.77368 3.40045,-1.43 4.88518,-1.67412 0.64075,-0.10537 0.77511,-0.11632 1.41866,-0.1157 0.57405,5.6e-4 0.66599,0.007 0.87464,0.0562 0.24674,0.0588 0.50225,0.16783 0.63538,0.27115 0.1123,0.0872 0.18039,0.21754 0.33939,0.64994 0.11552,0.31411 0.15478,0.39258 0.23867,0.47698 0.0552,0.0556 0.11502,0.12976 0.13294,0.16489 0.0485,0.0952 0.1042,0.33447 0.13696,0.58847 0.026,0.20147 0.1606,0.58126 1.25962,3.55422 0.97028,2.62459 1.23056,3.35302 1.23056,3.44386 l 0,0.1152 0.42678,0.008 c 0.46878,0.009 0.52235,0.0245 0.60566,0.17353 l 0.0408,0.073 0.33796,1.6e-4 0.33797,1.5e-4 0.007,-0.13144 c 0.007,-0.12516 0.0123,-0.13416 0.10877,-0.18818 0.0978,-0.0547 0.1019,-0.0622 0.1172,-0.21118 0.0176,-0.17141 0.0389,-0.21015 0.12767,-0.23284 l 0.0605,-0.0154 0.006,-1.26013 0.006,-1.26013 0.089,-0.0214 c 0.0499,-0.012 0.12574,-0.0117 0.17271,6.5e-4 l 0.0837,0.0221 0.006,1.25695 0.006,1.25695 0.073,0.0308 c 0.0809,0.0341 0.0883,0.0511 0.11108,0.25523 0.0138,0.12377 0.0237,0.144 0.0767,0.15754 0.10534,0.0269 0.15826,0.10301 0.15826,0.22764 l 0,0.11297 0.49271,0 c 2.20298,0 5.41393,0.21317 6.66233,0.4423 0.58097,0.10663 0.96157,0.23958 1.00342,0.3505 0.0261,0.0692 -0.0157,0.15083 -0.10344,0.20183 l -0.0887,0.0516 0.0892,0.0692 c 0.19406,0.15062 0.061,0.30427 -0.37004,0.42717 -0.71125,0.20284 -2.29545,0.37942 -4.28069,0.47718 -0.96938,0.0477 -2.29593,0.0891 -2.85436,0.0891 l -0.42412,-5e-5 -0.008,0.0941 c -0.007,0.0849 -0.0198,0.10049 -0.1308,0.15846 l -0.12313,0.0643 -0.0348,0.21183 c -0.0264,0.16089 -0.0369,0.57789 -0.0438,1.73379 l -0.009,1.52195 0.0641,0.0427 c 0.0353,0.0235 0.0852,0.0899 0.11086,0.14748 0.0446,0.10005 0.0468,0.19762 0.0473,2.18045 l 5.6e-4,2.07572 0.10273,0.0707 c 0.17755,0.1222 0.20436,0.20801 0.21422,0.68575 0.0109,0.52859 -0.0113,0.63949 -0.15846,0.79138 -0.075,0.0774 -0.10932,0.13424 -0.1097,0.18156 -7.9e-4,0.10148 -0.0847,0.27217 -0.15776,0.32087 l -0.0637,0.0425 0,2.85502 0,2.85502 0.0983,0.03 c 0.1263,0.0385 0.14844,0.0847 0.14844,0.30964 l 0,0.18433 1.95211,2.83611 c 1.07365,1.55986 2.43919,3.54365 3.03454,4.40842 0.59533,0.86477 1.10195,1.57761 1.1258,1.58408 0.0639,0.0173 1.06727,1.48831 1.06727,1.56468 0,0.0956 -0.12649,0.16162 -0.30841,0.16106 -0.17612,-5.4e-4 -0.31293,-0.0582 -0.42302,-0.17829 -0.11941,-0.13025 -0.55419,-0.77661 -0.58889,-0.87545 -0.0169,-0.0483 -0.31135,-0.49454 -0.65417,-0.99161 -0.34284,-0.49706 -0.9177,-1.33304 -1.27747,-1.85772 -2.38912,-3.48435 -2.22807,-3.25616 -2.27136,-3.21822 -0.0382,0.0335 -1.04384,0.87335 -1.05914,0.88457 -0.004,0.003 0.0662,0.077 0.15596,0.1647 0.0897,0.0877 0.15126,0.16346 0.13674,0.16839 -0.0185,0.006 -0.0264,0.72467 -0.0264,2.4058 0,1.59152 0.008,2.39164 0.0247,2.38133 0.0136,-0.008 0.0247,-0.0713 0.0247,-0.13955 0,-0.0682 0.008,-0.1236 0.0185,-0.12306 0.0102,5.4e-4 0.11288,0.0486 0.22823,0.1067 0.24122,0.12159 0.28363,0.18315 0.32843,0.4768 0.0214,0.1403 0.0198,0.17609 -0.009,0.20352 -0.0194,0.0183 -0.52338,0.14831 -1.11989,0.28894 -0.59649,0.14061 -1.08911,0.26031 -1.09469,0.26598 -0.006,0.006 0.03,0.0581 0.0792,0.11645 0.0491,0.0584 0.0893,0.13152 0.0893,0.16255 0,0.089 -0.11068,0.16049 -0.24845,0.16049 -0.1629,0 -0.22674,-0.0298 -0.38027,-0.17756 l -0.1325,-0.12751 -0.35656,0.0831 c -0.25363,0.0591 -0.35309,0.0923 -0.34458,0.11488 0.007,0.0174 1.7e-4,0.0317 -0.0143,0.0317 -0.0144,0 -0.31262,-0.20713 -0.66262,-0.46029 -1.59965,-1.15703 -2.43249,-1.7498 -2.44317,-1.73894 -0.006,0.007 10e-4,0.0517 0.0172,0.10052 0.0256,0.0789 0.034,0.0854 0.0759,0.0588 0.0303,-0.0193 0.0547,-0.0212 0.0684,-0.005 0.0358,0.041 0.84341,2.05496 0.84341,2.10322 0,0.0709 -0.0627,0.17579 -0.13947,0.23323 -0.36747,0.27512 -0.76431,0.21395 -0.93901,-0.14474 -0.0291,-0.0598 -0.13146,-0.304 -0.22741,-0.54271 -0.13984,-0.34784 -0.1744,-0.45999 -0.17418,-0.56484 2.2e-4,-0.10314 -0.069,-0.33493 -0.32692,-1.09485 l -0.32719,-0.96404 -0.17758,-0.13428 c -0.0977,-0.0739 -0.18303,-0.13428 -0.18974,-0.13428 -0.007,0 -0.28346,0.35327 -0.615,0.78506 -0.33153,0.43178 -0.61969,0.79933 -0.64036,0.81678 -0.0207,0.0174 -0.0448,0.0708 -0.0536,0.11848 -0.0107,0.0578 -0.11581,0.21732 -0.3151,0.47796 -0.31755,0.41533 -0.43491,0.51602 -0.64331,0.55183 -0.18644,0.032 -0.43016,-0.0933 -0.4072,-0.20951 0.004,-0.0198 0.25692,-0.36185 0.56225,-0.76018 0.37818,-0.49339 0.57085,-0.72532 0.60447,-0.72761 0.0272,-0.002 0.003,-0.0164 -0.0545,-0.0323 -0.15365,-0.0428 -0.15707,-0.0508 -0.13006,-0.30568 0.0457,-0.43136 0.12292,-1.49274 0.12292,-1.68888 l 0,-0.19744 -0.67235,-0.56604 c -0.50278,-0.42331 -0.67949,-0.55889 -0.7007,-0.53769 -0.0691,0.069 -3.364,4.88743 -3.3969,4.96755 -0.0444,0.10815 -0.36216,0.57712 -0.46716,0.68948 -0.1032,0.11043 -0.21204,0.15787 -0.36226,0.15787 -0.10308,0 -0.13871,-0.012 -0.1897,-0.0639 -0.0345,-0.0351 -0.0568,-0.0796 -0.0496,-0.0988 0.0303,-0.0804 0.84494,-1.24233 0.87128,-1.24274 0.0158,-2.6e-4 0.14252,-0.16709 0.28158,-0.37074 0.139,-0.20366 0.29242,-0.42626 0.34091,-0.49467 0.10495,-0.14806 0.0809,-0.13594 -0.19484,0.0983 -1.20055,1.01978 -2.74458,1.83437 -4.30536,2.27139 -0.90554,0.25354 -1.69767,0.38003 -2.67698,0.42744 -0.57218,0.0277 -0.55634,0.0277 -1.15962,-0.001 z m 21.21842,-3.36192 c 0,-0.31758 -0.005,-0.5774 -0.0119,-0.5774 -0.0249,0 -1.60068,0.37721 -1.60833,0.385 -0.008,0.009 1.56954,0.7653 1.60173,0.76816 0.0102,9e-4 0.0185,-0.25819 0.0185,-0.57576 z m -7.76345,-0.55229 0.35793,-0.46443 -0.0611,-0.0502 c -0.0565,-0.0465 -0.0605,-0.0641 -0.0536,-0.23584 l 0.007,-0.18563 0.25383,-0.0615 c 0.28643,-0.0694 0.26925,-0.0373 0.1682,-0.31476 l -0.0528,-0.14501 -0.10313,0.0772 c -0.0922,0.069 -0.10392,0.0896 -0.1106,0.19396 -0.006,0.0996 -0.0184,0.12328 -0.0818,0.16084 -0.0929,0.055 -0.39202,0.10372 -0.56794,0.0925 l -0.13294,-0.008 -0.0134,0.12553 c -0.0431,0.40359 -0.0837,1.12589 -0.0704,1.25263 l 0.0155,0.14805 0.0435,-0.0602 c 0.0239,-0.0331 0.20452,-0.26917 0.40141,-0.5246 z m 5.27152,-1.7141 0,-0.50908 0.16045,-0.16183 c 0.14191,-0.1431 0.18545,-0.17061 0.37627,-0.23776 l 0.2158,-0.0759 0.007,-0.11301 0.007,-0.11302 -0.1923,-0.1397 c -0.10578,-0.0768 -0.55217,-0.40323 -0.99199,-0.7253 -0.55652,-0.40755 -0.80921,-0.57878 -0.83112,-0.56318 -0.0173,0.0123 -0.19614,0.23708 -0.3974,0.49942 -0.66178,0.86263 -1.02402,1.33875 -1.02764,1.35067 -0.007,0.0228 0.85324,1.12586 0.88877,1.13973 0.0266,0.0104 1.22893,0.11737 1.74144,0.15493 0.0398,0.003 0.0432,-0.0366 0.0432,-0.50592 z m -2.7081,0.28953 c 0.13803,0.0112 0.26399,0.0172 0.2799,0.0133 0.0264,-0.007 -0.48868,-0.70384 -0.5279,-0.71475 -0.0141,-0.004 -0.61893,0.77223 -0.64079,0.82226 -0.004,0.009 0.13808,-0.0193 0.31543,-0.0626 0.30064,-0.0733 0.33937,-0.0773 0.57336,-0.0582 z m -3.29474,-0.51368 c 0.0634,-0.0718 0.15787,-1.44658 0.14971,-2.17729 l -0.007,-0.59009 -0.66355,0.96455 c -0.36496,0.5305 -0.66471,0.97754 -0.66615,0.99344 -0.001,0.0159 0.25275,0.24577 0.56486,0.51085 0.5443,0.46229 0.5678,0.47911 0.5757,0.4117 0.005,-0.0387 0.0253,-0.0896 0.046,-0.11316 z m 0.94568,-0.002 c 0.0125,-0.51744 0.008,-0.72087 -0.0155,-0.72086 -0.0171,0 -0.0328,0.0997 -0.0423,0.26988 -0.008,0.14842 -0.0228,0.3305 -0.0322,0.40461 -0.0166,0.13224 -0.016,0.1342 0.0362,0.1058 0.0292,-0.0159 0.0534,-0.0426 0.0538,-0.0594 z m 1.30893,-0.5514 c 0.17496,-0.12773 0.31548,-0.24403 0.31227,-0.25847 -0.006,-0.0289 -1.45635,-1.92044 -1.46515,-1.91148 -0.008,0.008 0.2959,0.87753 0.31964,0.91478 0.011,0.0172 0.0457,0.0313 0.0772,0.0313 0.0803,0 0.0978,0.0291 0.21034,0.34881 0.101,0.28688 0.10193,0.30205 0.024,0.39177 -0.042,0.0484 -0.0395,0.0623 0.0682,0.38284 0.0615,0.18296 0.1171,0.33264 0.12362,0.33264 0.006,0 0.15496,-0.1045 0.32992,-0.23222 z m 2.08671,-2.2029 c 0.70487,-0.91819 1.53362,-1.99847 1.84165,-2.40062 l 0.56006,-0.73119 0,-0.16321 c 0,-0.18474 0.0157,-0.20737 0.17807,-0.25614 l 0.10566,-0.0317 0.006,-2.84119 0.006,-2.8412 -0.0988,-0.0956 c -0.0883,-0.0855 -0.0988,-0.10829 -0.0988,-0.21538 0,-0.10938 -0.0102,-0.13009 -0.11719,-0.23907 -0.0645,-0.0656 -0.14645,-0.1547 -0.1822,-0.19793 -0.0548,-0.0662 -0.0822,-0.0786 -0.17395,-0.0786 -0.12828,0 -0.16809,0.0324 -0.16824,0.13681 -1.2e-4,0.10096 -0.0783,0.22779 -0.17029,0.27619 -0.10352,0.0545 -0.26933,0.049 -0.36772,-0.012 -0.13312,-0.0826 -0.16101,-0.18499 -0.17248,-0.63324 l -0.0101,-0.39539 -0.0914,0 c -0.0726,0 -0.14177,0.0353 -0.33666,0.17189 -0.13492,0.0945 -0.2675,0.17751 -0.29464,0.18438 -0.0272,0.007 -0.58913,0.39228 -1.24889,0.85647 -1.08038,0.76014 -1.19844,0.84984 -1.18843,0.90311 0.009,0.0454 -0.01,0.0752 -0.0784,0.12861 -0.0751,0.0583 -0.16513,0.22348 -0.55716,1.02212 l -0.46761,0.95262 0,0.26096 c 0,0.29393 -0.0118,0.31886 -0.1738,0.36827 l -0.0976,0.0297 0,1.60269 0,1.60271 0.18141,0 0.18138,0 0.0142,-0.21966 c 0.0198,-0.30653 0.0226,-0.3115 0.17343,-0.30246 0.11513,0.007 0.12636,0.0133 0.14537,0.0828 0.026,0.0948 0.0261,1.04915 1.9e-4,1.16734 -0.0186,0.0849 -0.0235,0.0881 -0.14479,0.0953 -0.1503,0.009 -0.14852,0.012 -0.17136,-0.29581 l -0.0168,-0.22631 -0.18149,0 -0.18152,0 0,0.67734 0,0.67734 0.0679,0.0164 c 0.1191,0.0288 0.15419,0.0799 0.15419,0.22461 l 0,0.13187 0.90673,1.18085 c 0.84203,1.09663 0.90953,1.17781 0.94636,1.13828 0.0218,-0.0234 0.61635,-0.79381 1.32122,-1.71199 z m 2.46925,0.99953 c 0.0168,-0.0206 0.0751,-0.051 0.12953,-0.0676 l 0.099,-0.0302 0,-1.65587 c 0,-1.30779 -0.006,-1.65595 -0.0308,-1.65623 -0.017,-1.8e-4 -0.0536,-0.006 -0.0813,-0.0141 -0.0426,-0.0117 -0.19526,0.17472 -0.98461,1.20226 -0.5138,0.66883 -0.93291,1.22377 -0.93136,1.23321 0.002,0.009 0.39466,0.30405 0.8736,0.65469 l 0.87078,0.63754 0.0123,-0.13311 c 0.007,-0.0732 0.0261,-0.14996 0.0429,-0.17056 z m -44.24641,0.14045 c 0.19618,-0.0808 0.37121,-0.21993 0.58047,-0.46159 0.14714,-0.16989 0.17467,-0.21588 0.17467,-0.29173 l 0,-0.09 -0.11719,0.0984 c -0.0644,0.0541 -0.31705,0.26574 -0.56131,0.47031 -0.24425,0.20455 -0.45474,0.38171 -0.46772,0.39368 -0.0316,0.0291 0.20971,-0.0443 0.39108,-0.11901 z m 46.38633,-0.53428 c 0.36679,-0.30892 0.66924,-0.5744 0.67213,-0.58995 0.007,-0.0351 -1.62615,-2.40644 -1.66623,-2.42003 -0.0517,-0.0175 -0.0349,0.88569 0.0323,1.73906 0.0337,0.42803 0.0745,0.96361 0.0906,1.19018 0.0245,0.34415 0.0367,0.4184 0.0743,0.45118 0.0309,0.0269 0.045,0.0738 0.045,0.1497 0,0.10111 0.004,0.10754 0.0425,0.076 0.0234,-0.019 0.34256,-0.28722 0.70933,-0.59615 z m -48.20358,-0.14123 0.12926,-0.0502 2.7e-4,-1.73534 2.8e-4,-1.73533 -0.0789,-0.0161 c -0.0502,-0.0102 -0.0901,-0.004 -0.10958,0.0157 -0.0169,0.0175 -0.46459,0.5966 -0.99498,1.28697 -0.86804,1.12987 -0.95997,1.25825 -0.9205,1.28565 0.0241,0.0168 0.44352,0.32313 0.93204,0.68087 l 0.88821,0.65042 0.0123,-0.16622 0.0123,-0.16624 0.12925,-0.0502 z m 2.02218,-0.2598 0.54533,-0.46064 -0.0638,-0.14186 c -0.0567,-0.12605 -0.0641,-0.17544 -0.0662,-0.44312 l -0.002,-0.30125 -0.66153,-0.96024 c -0.36384,-0.52813 -0.67156,-0.96023 -0.68383,-0.96023 -0.0543,0 -0.0209,0.98968 0.0759,2.24717 0.0899,1.16761 0.10244,1.28031 0.14802,1.32969 0.0317,0.0343 0.0498,0.0882 0.0498,0.14828 l 0,0.0943 0.0567,-0.0457 c 0.0312,-0.0252 0.30211,-0.25305 0.60204,-0.5064 z m 0.55021,-4.26928 0,-2.10653 -0.28101,-0.13749 c -0.31568,-0.15445 -0.53784,-0.29987 -0.71439,-0.46763 -0.13676,-0.12995 -0.20493,-0.25121 -0.22909,-0.40749 -0.009,-0.0599 -0.0309,-0.13159 -0.048,-0.1592 -0.077,-0.1242 -0.0891,-0.26251 -0.0612,-0.70349 l 0.0273,-0.43202 -0.062,-0.12562 c -0.0341,-0.0691 -0.0781,-0.18639 -0.0977,-0.26068 -0.0319,-0.1206 -0.0359,0.11701 -0.0373,2.2165 l -0.002,2.35158 0.0925,0.0303 c 0.14791,0.0485 0.1542,0.0603 0.1542,0.2907 l 0,0.21055 0.62176,0.9035 c 0.34196,0.49694 0.62508,0.90352 0.62915,0.90352 0.004,0 0.007,-0.94794 0.007,-2.10653 z m 36.44237,0.26919 c 0.061,-0.0459 0.073,-0.0725 0.073,-0.16169 0,-0.0587 0.0111,-0.11376 0.0247,-0.12229 0.0156,-0.01 0.0247,-0.29732 0.0247,-0.77972 0,-0.49272 -0.009,-0.76419 -0.0247,-0.76419 -0.0136,0 -0.0247,-0.0135 -0.0247,-0.03 0,-0.0165 -0.0283,-0.0601 -0.063,-0.0968 -0.0346,-0.0368 -0.0908,-0.15034 -0.1249,-0.25241 -0.0639,-0.19132 -0.776,-1.78644 -0.7908,-1.77137 -0.0154,0.0157 0.23875,2.1869 0.27527,2.35147 0.0199,0.0898 0.0644,0.41171 0.099,0.71547 0.0345,0.30376 0.0732,0.63136 0.0861,0.72802 0.0128,0.0967 0.0236,0.18986 0.0241,0.20711 5.8e-4,0.0221 0.0524,0.0314 0.17453,0.0314 0.13997,0 0.18789,-0.0107 0.24671,-0.0549 z m 1.57788,-3.83589 c 0.0951,-0.19313 0.17289,-0.36137 0.17289,-0.37388 0,-0.067 -0.0914,-0.0324 -0.299,0.11315 -0.12731,0.0893 -0.23566,0.17457 -0.24079,0.18959 -0.008,0.0223 0.16788,0.41487 0.18804,0.42057 0.003,9.2e-4 0.0838,-0.15632 0.17886,-0.34943 z m -0.15557,-0.87188 c -0.004,-0.0609 0.0335,-0.0947 0.3631,-0.32625 0.31882,-0.22395 0.37956,-0.25746 0.45664,-0.252 0.0802,0.006 0.19138,-0.0657 1.14211,-0.73357 0.57925,-0.40693 1.04907,-0.74406 1.04403,-0.74919 -0.005,-0.005 -0.20703,0.009 -0.44892,0.0309 -0.56568,0.0517 -1.56649,0.11479 -1.82492,0.11494 -0.19302,1.1e-4 -0.20148,0.002 -0.21616,0.0622 -0.008,0.0341 -0.0354,0.0821 -0.06,0.10669 -0.0246,0.0246 -0.18592,0.41001 -0.35856,0.8566 -0.25159,0.65081 -0.30805,0.81912 -0.2845,0.84801 0.0224,0.0274 0.0226,0.0512 10e-4,0.0993 -0.0156,0.0348 -0.0283,0.0858 -0.0283,0.11343 0,0.0463 0.009,0.0442 0.10949,-0.0264 0.0879,-0.0616 0.10858,-0.09 0.10486,-0.1446 z m -1.02853,-0.14273 c 0,-0.0492 0.12981,-0.0912 0.33306,-0.1078 l 0.17272,-0.0141 0.282,-0.73107 c 0.15508,-0.40208 0.29564,-0.76494 0.31232,-0.80637 l 0.0303,-0.0753 -1.37667,0 -1.37667,0 -0.0283,0.0796 c -0.0235,0.066 -0.018,0.12532 0.0324,0.34749 0.0334,0.14734 0.0643,0.27122 0.0687,0.2753 0.0587,0.0542 0.40286,0.28929 0.42386,0.28948 0.13517,0.001 0.66353,0.37383 0.84919,0.59894 0.0642,0.0778 0.12772,0.14968 0.14129,0.15983 0.0428,0.032 0.13571,0.021 0.13571,-0.016 z m -38.21633,-0.92846 c 0.0924,-0.28193 0.31505,-0.75928 0.43052,-0.92282 l 0.086,-0.12186 -0.12333,0 c -0.10687,0 -0.12331,0.007 -0.12331,0.0502 0,0.0276 -0.0222,0.0728 -0.0493,0.10041 -0.0271,0.0276 -0.0494,0.0703 -0.0494,0.0948 0,0.0799 -0.0696,0.14844 -0.184,0.18101 l -0.11208,0.0319 0.003,0.54276 c 0.002,0.41121 0.008,0.50998 0.025,0.40753 0.0121,-0.0744 0.0558,-0.23818 0.097,-0.36401 z m 44.52334,-1.23543 c 0.0289,-0.008 0.0653,-0.043 0.081,-0.078 0.0226,-0.0505 0.022,-0.0611 -0.003,-0.0513 -0.0174,0.007 -0.0955,0.0269 -0.17352,0.0447 -0.1367,0.0311 -0.16069,0.047 -0.12541,0.0829 0.02,0.0204 0.14912,0.0214 0.22111,0.002 z m -43.95654,-0.12933 c 4.4e-4,-0.0242 0.12061,-1.1228 0.26703,-2.44139 l 0.26621,-2.39746 -0.0582,-0.17573 c -0.0844,-0.25484 -0.17199,-0.62151 -0.20593,-0.86212 -0.0497,-0.35254 -0.005,-0.5347 0.17319,-0.70689 l 0.091,-0.0879 0.0391,-0.45692 c 0.0352,-0.41124 0.046,-0.46976 0.10795,-0.58552 0.0378,-0.0707 0.0983,-0.14995 0.13428,-0.17605 0.0572,-0.0414 0.0675,-0.0707 0.0817,-0.23037 0.0126,-0.14123 0.0318,-0.2058 0.0844,-0.28334 0.23645,-0.34876 1.06371,-0.62164 2.31405,-0.76335 0.79088,-0.0896 1.27582,-0.11242 2.36056,-0.11093 0.58011,8e-4 1.05474,-0.007 1.05474,-0.0176 0,-0.0105 0.0266,-0.0452 0.0591,-0.077 l 0.0591,-0.0579 -0.0554,-0.0765 c -0.19678,-0.27169 -0.29402,-0.54944 -0.28012,-0.80016 0.009,-0.1655 0.1205,-0.47871 1.37216,-3.8604 1.20089,-3.24456 1.3652,-3.70525 1.38776,-3.89116 0.0443,-0.36477 0.11288,-0.54922 0.25592,-0.68786 0.0614,-0.0595 0.12098,-0.19279 0.28387,-0.63514 0.1134,-0.3079 0.23787,-0.60434 0.27661,-0.65877 0.0387,-0.0544 0.0704,-0.10302 0.0704,-0.10801 0,-0.005 -0.0971,-0.0166 -0.21588,-0.0258 -0.32718,-0.0254 -1.51691,-0.18023 -2.25137,-0.29293 -1.11987,-0.17185 -2.28041,-0.38852 -3.51167,-0.65561 -0.25553,-0.0554 -0.46773,-0.097 -0.47155,-0.0923 -0.008,0.009 -3.84733,6.47619 -3.93469,6.62687 l -0.0529,0.0913 0.12824,0.0468 c 0.43686,0.15926 0.63647,0.6788 0.47628,1.23971 -0.082,0.28724 -0.37575,0.69042 -0.6153,0.84462 -0.0596,0.0384 -0.11349,0.0927 -0.11974,0.12068 -0.006,0.028 -0.0477,0.25707 -0.092,0.50904 l -0.0806,0.45812 -0.082,0.0302 -0.082,0.0302 0,5.31658 0,5.31659 0.0678,0.0151 c 0.24859,0.0552 0.30225,0.1064 0.30225,0.28834 0,0.10059 0.0105,0.14814 0.0347,0.15759 0.0191,0.007 0.0422,0.0482 0.0513,0.0906 0.0163,0.0754 0.0197,0.077 0.1627,0.077 0.12237,0 0.14621,-0.007 0.14689,-0.0439 z m 16.01612,-1.94941 c 0.91685,-1.4077 2.30351,-2.63244 3.88707,-3.43318 0.23719,-0.11993 0.25348,-0.13302 0.25348,-0.20347 0,-0.106 0.0793,-0.22405 0.1948,-0.29012 0.13415,-0.0767 0.86109,-0.35385 1.22386,-0.46658 0.69042,-0.21454 1.53658,-0.39188 2.28224,-0.47831 0.58814,-0.0682 0.77183,-0.0433 0.86116,0.11649 0.0305,0.0545 0.0576,0.0705 0.11971,0.0706 l 0.0803,1.5e-4 -0.006,-1.9393 -0.006,-1.93931 -0.20714,-0.0707 c -0.11393,-0.0389 -0.26104,-0.0771 -0.3269,-0.0851 l -0.11979,-0.0144 0,0.8838 c 0,0.53663 -0.01,0.90208 -0.0245,0.93034 -0.0584,0.11111 -0.47844,0.14921 -0.65848,0.0597 l -0.0942,-0.0468 -0.0124,-0.94792 -0.0123,-0.94793 -0.0802,-0.0496 -0.0802,-0.0496 0,-0.28517 c 0,-0.29934 0.0118,-0.33376 0.12952,-0.37622 0.0393,-0.0142 0.0432,-0.0638 0.0432,-0.5523 l 0,-0.53671 -0.0925,-0.041 c -0.0509,-0.0226 -0.43122,-0.16869 -0.84519,-0.32472 l -0.75264,-0.28369 0.008,0.0903 c 0.01,0.10433 -0.0965,0.44859 -0.17166,0.55596 -0.0581,0.083 -0.16635,0.14618 -0.25047,0.14618 -0.0553,0 -0.13012,0.19339 -1.2996,3.3577 -0.73725,1.99477 -1.26942,3.39978 -1.31106,3.46137 -0.25548,0.37788 -1.11695,0.5864 -2.14429,0.51902 -0.21034,-0.0138 -0.38424,-0.024 -0.38644,-0.0226 -0.002,0.001 -0.0118,0.1832 -0.0213,0.40412 l -0.0173,0.40167 0.0755,0.0958 c 0.16084,0.20435 0.16582,0.43628 0.0189,0.88323 -0.0947,0.28825 -0.33515,0.82007 -0.46124,1.02028 -0.0638,0.10136 -0.078,0.15856 -0.1091,0.43932 -0.0196,0.17754 -0.0417,0.37363 -0.049,0.43577 l -0.0133,0.11296 0.0807,-0.13562 c 0.0444,-0.0746 0.1771,-0.28358 0.29489,-0.46443 z m 16.68655,-3.06529 c 1.54086,-0.31627 4.48059,-0.5191 6.94534,-0.47922 2.22171,0.036 3.9445,0.19988 4.74329,0.45135 l 0.19121,0.0602 -1.4e-4,-1.4596 c -6e-5,-0.80278 -0.0102,-1.49914 -0.0225,-1.54747 -0.0123,-0.0483 -0.0296,-0.15187 -0.0384,-0.2301 -0.0153,-0.13636 -0.0199,-0.14384 -0.11101,-0.18093 -0.10662,-0.0434 -0.17332,-0.12409 -0.17332,-0.2096 l 0,-0.0572 -0.46262,-3.1e-4 c -0.51543,-3.5e-4 -1.61694,-0.0327 -2.64613,-0.0778 l -0.67851,-0.0297 -0.30839,0.18085 c -0.40839,0.23949 -1.19732,0.63346 -1.70242,0.85015 -1.43348,0.61496 -2.87116,1.033 -4.21901,1.22675 -0.40206,0.0578 -1.52614,0.065 -1.78875,0.0114 -0.39863,-0.0813 -0.71795,-0.24158 -0.84191,-0.42265 -0.0356,-0.0519 -0.53412,-1.36533 -1.10789,-2.91866 -0.8322,-2.25285 -1.05248,-2.8257 -1.08877,-2.83148 -0.12229,-0.0195 -0.15561,-0.0355 -0.22602,-0.10881 -0.0432,-0.0449 -0.10441,-0.15833 -0.14168,-0.2623 l -0.0657,-0.18319 -0.18851,0.0714 c -0.10367,0.0393 -0.4272,0.16172 -0.71896,0.27208 -0.29175,0.11037 -0.57764,0.21993 -0.63532,0.24347 l -0.10485,0.0428 0,0.53533 c 0,0.51274 0.002,0.53599 0.0492,0.55121 0.10982,0.0355 0.12351,0.077 0.12351,0.37451 0,0.29699 -0.012,0.33165 -0.12953,0.37406 -0.0401,0.0145 -0.0432,0.0831 -0.0432,0.9572 l 0,0.94162 -0.059,0.0393 c -0.0879,0.0586 -0.30242,0.0856 -0.46692,0.0589 -0.26035,-0.0423 -0.23896,0.0469 -0.23896,-0.99778 l 0,-0.91378 -0.1322,0.0139 c -0.0727,0.008 -0.22536,0.0462 -0.33925,0.0857 l -0.20704,0.0718 -0.006,1.93525 -0.006,1.93526 0.16204,0.0132 c 0.15167,0.0124 0.17098,0.008 0.30138,-0.0721 0.24096,-0.14763 0.34111,-0.15977 0.8005,-0.097 0.47362,0.0647 0.62591,0.10599 0.71115,0.19274 0.0415,0.0423 0.0814,0.1065 0.0885,0.14274 0.0123,0.0623 0.0304,0.0697 0.33802,0.13801 1.14764,0.25472 2.36261,0.74172 3.34596,1.3412 l 0.28228,0.17208 0.19884,-0.0594 c 0.10936,-0.0327 0.38758,-0.0981 0.61828,-0.14549 z m 13.87832,20.08354 0,-0.38912 0.0836,0 c 0.046,0 0.1065,0.0198 0.13446,0.0439 0.10127,0.0875 0.19472,0.52671 0.13307,0.6253 -0.0147,0.0235 -0.27846,0.109 -0.33622,0.109 -0.008,0 -0.0149,-0.17511 -0.0149,-0.38912 z"
+       style="fill:#424d58;fill-opacity:1;stroke:none" />
+    <path
+       id="path1939"
+       d="m -185.92324,-212.40978 -1.83663,0 -0.36732,0.91642 0.36732,1.00807 -0.18366,1.09971 -0.9183,-0.54985 -0.73465,-1.37464 -1.56114,-0.36657 -0.64281,-0.6415 -1.37747,-0.6415 -1.56113,-2.566 0.0918,-1.19135 3.85692,-2.93257 1.8366,0.82478 0.2755,0.6415 0,0.73314 0.45916,0.6415 0.91831,0.27493 0.64282,-0.54986 0.0918,-0.64149 -0.2755,-0.54986 -0.55097,-0.27493 -0.36734,-0.45821 0.82648,-0.36657 -0.18366,-0.91643 0,-0.54986 -0.55097,-0.54985 -0.27551,-0.82479 -1.10196,-0.27492 -0.91832,-0.18329 -1.92846,1.37464 -4.86704,1.9245 -1.10198,1.09971 -0.82647,0.6415 -0.18368,1.46628 0.36734,0.73315 0.91831,2.47435 1.19379,2.29106 1.28564,1.64957 -2.02028,3.29914 -2.29578,4.94871 -1.37747,2.19942 -2.29577,2.84093 -0.0918,1.283 -1.19381,1.09971 1.83662,1.64957 -0.45915,1.92449 0.18366,4.30722 0.82647,4.9487 0.82649,4.39885 0.9183,1.46628 1.28565,2.65765 2.02028,3.02421 0.55098,1.92448 0.55099,1.37465 -1.65297,2.29107 -2.93859,1.19135 -0.27549,0.91643 5.6017,-0.18328 -0.82648,1.46628 1.01014,0.91642 2.6631,0.27494 2.11213,-1.83286 0.73466,-2.56599 1.19379,-2.19943 1.46929,-1.283 0.45916,-1.46628 -1.56112,-0.0916 1.01013,-1.00807 -2.02027,0.6415 1.4693,-1.46629 -1.10198,-0.27492 -0.82649,-1.00807 -1.37747,-2.84093 -3.21408,-2.65764 -0.64282,-0.18328 0.64282,-0.54986 -0.0918,-1.55793 0.64282,-1.37464 -0.55099,0.0916 1.01014,-1.74121 0,-1.74121 0.64282,-0.91643 0,-1.19135 1.37746,-1.83286 0.0918,-1.55792 -0.2755,-1.283 0.64282,-1.46629 0.73465,-1.19135 0,-0.73314 0.82648,-0.0916 0.73465,-0.73314 0.64282,-1.83286 1.46929,-1.64957 1.7448,-0.6415 1.10196,0.91643 2.66312,0.82479 2.11211,1.09971 1.01013,1.283 1.74479,0.18328 5.50988,2.38271 2.84676,1.00807 2.29578,1.74122 0.551,-0.18329 0,-0.54986 -1.28564,-1.00807 2.47943,0.6415 0.27551,-0.45821 -0.551,-0.54986 0.91832,0 0.0918,-0.54985 -1.65296,-0.36657 1.28562,-0.36658 0,-0.6415 -0.45915,-0.0916 -1.37747,0.0916 -1.10196,-0.45821 -0.73466,-0.36657 1.10198,-0.91643 0.27549,-0.6415 -0.18366,-0.45821 -1.01014,0.18329 -2.11213,1.09971 -0.27548,0.54985 -0.73465,-0.18328 -2.66311,-1.46628 -0.0918,-1.00807 -1.56113,-0.82479 -2.66311,-1.37464 -0.64281,0.45821 0.0918,-0.64149 -1.4693,-1.37465 -1.28564,-0.36657 -1.1938,-1.37464 -0.36732,-0.45821 1.1938,0.82478 -0.18366,-0.91642 0.9183,0.45821 -0.27549,-1.37464 1.28564,1.19136 -0.55098,-0.82479 1.28562,0.54986 -1.10196,-1.55793 0.82647,0.27493 -0.36732,-1.46629 0.64281,0.54986 -0.9183,-1.37464 0.9183,0.27493 -0.82647,-1.09971 1.10197,-0.0916 -1.1938,-0.73315 0.73464,-0.36656 -0.82647,-0.0916 1.10196,-1.00807 -1.01013,0.0916 0.0918,-0.6415 0.0918,-1.83286 -0.55098,1.283 -0.64283,-1.83285 0.0918,1.46628 -0.36732,0.0916 -0.91831,0 -1.01015,-1.46628 -1.01014,0 -1.1938,-1.00807 -0.55099,0.54985 -1.37746,0.91643 z"
+       style="fill:#424d58;fill-opacity:1;fill-rule:evenodd;stroke:none" />
+    <path
+       id="path2875"
+       d="m -88.320686,-160.98565 c -1.64224,-0.59082 -1.07731,-2.30121 -1.23657,-3.5506 0.16088,-0.81913 -0.29218,-1.47644 -0.54804,-2.20156 -0.23201,-1.04386 0.11486,-2.11908 0.70842,-3.01074 -0.04,-2.36208 -0.61702,-4.67526 -1.01104,-6.98938 -0.20081,-1.67877 0.97857,-3.31083 0.30218,-4.95353 -0.52361,-1.54789 -0.50752,-3.15125 -0.48245,-4.75552 0.13332,-2.16234 -0.81536,-4.21833 -0.89569,-6.37324 -1.76414,-0.71678 -1.6331,2.34885 -2.66915,3.18479 -0.6906,2.06804 -2.34152,3.68888 -3.26221,5.64668 -0.3848,1.14612 -0.76536,2.29157 -1.66802,3.19192 -1.406084,1.77788 -1.103334,4.23685 -2.630144,5.97056 -0.86006,1.72166 -2.22849,3.36891 -2.69143,5.18826 -0.26347,0.89856 0.96969,1.58793 0.3077,2.44577 -0.69465,1.33298 -0.31821,2.85043 -0.66651,4.25761 -1.14853,0.009 -0.8175,1.23159 -1.6579,1.60091 -0.71494,0.34059 -1.7442,0.45901 -2.44534,0.13064 -0.80671,-0.58509 -0.18427,-1.86094 0.20037,-2.60562 0.57759,-0.88513 0.95045,-1.82468 0.9229,-2.87064 0.14486,-0.83651 0.70374,-1.57418 0.66633,-2.46294 -0.16365,-0.98381 0.4709,-1.75071 0.7039,-2.61385 0.55222,-2.58439 1.72785,-5.0337 2.18804,-7.65104 0.8687,-1.76698 2.15976,-3.4277 2.58127,-5.33722 0.16376,-2.35392 1.09966,-4.57264 2.243694,-6.65258 0.31288,-1.44379 1.44587,-2.54241 1.87575,-3.93923 -0.18533,-1.23238 -0.31336,-2.46569 -0.11867,-3.7043 -0.7457,-2.1142 -2.1826,-3.96379 -2.642804,-6.17116 -0.29091,0.78422 -0.13408,2.19501 -0.25738,3.21833 -0.50134,2.02432 -1.18727,4.04778 -1.57487,6.07263 0.61867,1.01168 0.51566,2.18119 0.0374,3.22556 0.27295,0.57823 -0.38722,1.70529 -0.50557,0.59978 0.2569,-1.49057 -0.90077,-0.54475 -0.22815,0.35309 0.43136,0.73323 1.85861,1.77762 -0.0195,0.80198 -0.8445,-0.44001 -1.04717,-1.546 -1.28338,-2.35258 0.33008,-1.12034 0.70048,-2.21323 0.60198,-3.39344 0.10749,-2.06217 -0.0353,-4.15501 0.67158,-6.14375 0.21552,-2.44758 -0.0541,-4.95416 0.18936,-7.39489 0.0891,-1.06236 0.97473,-1.96429 2.15275,-1.86205 1.343544,0.008 1.381264,-1.38713 0.490934,-0.76672 0.50368,-0.52196 2.03248,-3.53166 0.9306,-2.92055 -0.55505,-0.138 0.18207,-1.16067 -0.79694,-1.66415 1.1295,0.37535 0.20818,-0.90772 0.73468,-1.29562 -0.67228,-1.11228 3.14616,0.87598 0.97053,-0.50258 -1.38531,-1.30219 1.06432,0.31736 1.92583,0.01 -0.78505,-0.58657 -2.53808,-2.13141 -1.79342,-2.21987 -0.69716,-0.81466 0.56578,0.0965 0.22342,-0.91702 0.90757,0.58371 2.63056,2.12928 1.1881,0.23299 -0.90154,-1.26205 -0.4822,-0.98758 0.42747,-0.95503 0.47057,1.53016 1.87258,1.44268 0.59725,0.01 0.86456,0.46368 2.11637,2.83874 1.41041,0.60722 0.82156,0.51834 1.13796,0.30278 1.55761,0.72742 0.15611,-0.92632 0.45317,1.23043 1.41999,0.062 0.97164,-0.25893 1.28159,0.80472 1.80951,1.33854 1.02399,0.58231 1.94723,2.03172 0.69383,2.83567 -0.67047,0.65428 -0.0153,1.98443 0.26393,2.37355 -1.36234,-0.0114 0.17092,2.06401 0.15849,3.1566 -0.28329,1.44192 -1.179,-2.25774 -1.68467,-1.37642 0.14982,0.92455 0.0406,1.84567 -0.48996,0.77957 -0.85219,1.20895 -0.72946,-1.03237 -0.95289,0.49989 0.37431,0.61242 -1.72401,0.44432 -0.19085,0.98442 1.04148,0.16478 2.75897,0.13353 2.801,1.43209 0.10846,1.0537 -0.0912,2.05981 -0.55709,3.02488 -0.15163,1.48177 -0.11179,3.0305 0.16071,4.46988 1.36964,1.31973 2.08044,3.05283 2.94288,4.66586 0.5339,1.28311 0.19932,2.74354 0.53098,4.01776 0.5571,0.50566 0.50001,1.5341 0.26967,2.13793 -0.8314,0.89336 -0.17427,2.25286 -0.54777,3.3329 -0.42125,2.71656 -0.6049,5.47969 -0.35762,8.21316 0.54092,2.24439 -0.55406,4.47815 -0.56259,6.73405 0.0917,1.11449 -0.75451,2.3016 0.007,3.30356 -1.02372,1.11373 -0.0985,2.65358 -0.0917,3.94124 0.0848,1.5524 1.54735,3.01841 0.82246,4.57175 -0.62483,0.50244 -1.33928,0.69527 -2.17043,0.25697 z m -10.72641,-51.26782 c 0.0161,-0.42493 -0.38604,0.46353 0,0 z"
+       style="fill:#424d58;fill-opacity:1;stroke:none" />
+    <path
+       sodipodi:nodetypes="csssssssssssssssssssscccsssssscccssssssssssssscccssssssssssssssssssscccsssscccsssscccssssscccsssssssssscccsssscccsssssssssssssssscccssssssssssssssssssssssscccssssssssssssssssssssssssscccccssc"
+       id="path3250"
+       d="m -103.93622,-187.60087 c 0.0283,-0.13648 0.13935,-0.19875 0.24793,-0.13902 0.0345,0.0189 0.0767,0.0306 0.0938,0.0258 0.0297,-0.008 0.12463,-0.11279 0.13573,-0.1495 0.003,-0.01 -0.0341,-0.19558 -0.0823,-0.41309 -0.10881,-0.49097 -0.19514,-0.9481 -0.2708,-1.4339 -0.11938,-0.76666 -0.23489,-1.79447 -0.24984,-2.22318 -0.037,-1.06046 0.15553,-2.0921 0.55758,-2.98795 0.15722,-0.35033 0.53316,-1.00896 0.71147,-1.24649 0.56723,-0.75565 1.27209,-1.2231 2.35392,-1.56106 0.652711,-0.20388 1.72103,-0.40462 2.334677,-0.43865 1.133816,-0.0629 2.452273,0.0267 4.573718,0.31073 1.199424,0.1606 1.550756,0.19509 2.034336,0.1997 1.262324,0.0121 2.387625,-0.34681 3.684254,-1.17495 0.720823,-0.46038 2.327656,-1.44971 2.51912,-1.55104 1.67389,-0.88581 3.0518,-1.25128 4.15897,-1.10312 0.220798,0.0295 0.625073,0.12823 0.816684,0.19936 0.358664,0.13312 0.648948,0.35182 0.809617,0.60996 0.06023,0.0967 0.07673,0.13824 0.106214,0.26711 0.0337,0.14719 0.03558,0.15111 0.05215,0.11117 0.0096,-0.0227 0.01601,-0.0465 0.01455,-0.0529 -0.0086,-0.0373 0.03405,-0.006 0.110302,0.0808 l 0.08728,0.0994 0.05222,-0.0265 c 0.125856,-0.0638 0.205041,-0.0445 0.256022,0.0623 0.02876,0.0602 0.0236,0.11254 -0.02625,0.26799 -0.04936,0.15372 -0.08533,0.19865 -0.180798,0.22532 -0.08621,0.0241 -0.138994,0.002 -0.173355,-0.0717 -0.04783,-0.10295 -0.112264,-0.10858 -0.249316,-0.0218 -0.03767,0.0239 -0.07078,0.0441 -0.07368,0.045 -0.0028,6.9e-4 0.0021,-0.0256 0.01177,-0.0589 l 0.01699,-0.0606 -0.05842,0.064 c -0.137149,0.15038 -0.238225,0.20172 -0.741933,0.37699 -0.441191,0.15351 -0.820186,0.30405 -1.118895,0.44442 -0.119394,0.0561 -0.279221,0.13002 -0.355169,0.16427 -0.165577,0.0746 -0.247255,0.12653 -0.366517,0.23285 -0.172791,0.15406 -0.309578,0.33421 -0.469905,0.61902 -0.264154,0.4693 -0.404666,0.99057 -0.402396,1.49286 5.57e-4,0.12346 0.01079,0.18504 0.0658,0.3963 0.07511,0.28832 0.110852,0.36065 0.27191,0.55012 0.119471,0.14057 0.245689,0.24132 0.412074,0.329 0.155182,0.0817 0.437007,0.17368 0.488419,0.15931 0.02144,-0.006 0.804297,-0.20288 1.739679,-0.43754 4.45057,-1.11653 7.385434,-1.85984 11.806385,-2.99022 0.796604,-0.20367 2.632179,-0.67843 3.90487,-1.00998 0.831375,-0.21655 2.601829,-0.68822 4.376405,-1.16589 l 0.858237,-0.231 0.05584,-0.10109 c 0.07428,-0.13445 0.138549,-0.27845 0.193734,-0.43245 0.06782,-0.18916 0.134908,-0.3017 0.214281,-0.35941 0.154493,-0.11199 0.320787,-0.14804 0.614859,-0.13327 0.215242,0.0108 0.626661,0.002 0.635601,-0.0134 0.01511,-0.0262 0.01372,-0.19192 -0.0021,-0.22304 -0.0096,-0.0193 -0.05069,-0.0437 -0.09872,-0.0587 -0.07197,-0.0226 -0.08481,-0.0331 -0.102782,-0.0841 -0.02263,-0.0644 -0.0172,-0.20851 0.01518,-0.39795 0.02541,-0.14872 0.03391,-0.15459 0.274729,-0.18964 0.186827,-0.0272 0.269975,-0.0258 0.391834,0.007 0.101884,0.0271 0.151325,0.0649 0.183255,0.14021 0.03217,0.0757 0.04672,0.28233 0.02646,0.37572 -0.01957,0.0903 -0.09012,0.17351 -0.164804,0.19438 -0.06294,0.0175 -0.06357,0.02 -0.03976,0.16868 0.01274,0.0798 0.01358,0.0808 0.06531,0.0824 0.214448,0.007 0.846561,0.0114 0.848789,0.006 0.0014,-0.003 0.0049,-0.045 0.0072,-0.092 0.0056,-0.10526 -0.02117,-0.14883 -0.101174,-0.16556 -0.03119,-0.006 -0.06782,-0.0204 -0.08145,-0.0309 -0.05855,-0.0449 -0.06357,-0.19408 -0.01539,-0.45896 l 0.02458,-0.1352 0.171648,-0.0376 c 0.29307,-0.0642 0.524931,-0.0344 0.616419,0.0792 0.04658,0.0578 0.05104,0.0713 0.0651,0.19458 0.01685,0.14805 0.0097,0.23167 -0.02555,0.29936 -0.03098,0.0596 -0.122994,0.13505 -0.165411,0.13574 -0.04017,6.7e-4 -0.04352,0.0196 -0.02555,0.14221 l 0.0133,0.0909 0.422163,0.0121 c 0.232181,0.007 0.425525,0.009 0.429633,0.006 0.01734,-0.0154 0.01796,-0.17876 6.97e-4,-0.20983 -0.01024,-0.0186 -0.04143,-0.0386 -0.06921,-0.0444 -0.08086,-0.0169 -0.123823,-0.0488 -0.13786,-0.10227 -0.01629,-0.0622 -0.0028,-0.264 0.02688,-0.41005 l 0.02298,-0.11215 0.106465,-0.0279 c 0.243419,-0.0638 0.371733,-0.0688 0.542017,-0.0211 0.08112,0.0227 0.107795,0.0393 0.143631,0.0889 0.03857,0.0535 0.04588,0.0771 0.05918,0.19036 0.02061,0.17617 -0.0042,0.2931 -0.07806,0.36869 -0.04094,0.0419 -0.07025,0.0595 -0.10329,0.062 -0.0509,0.004 -0.05159,0.007 -0.02945,0.16833 l 0.01072,0.0783 0.452694,0.0187 c 0.248968,0.0103 0.454037,0.0152 0.45568,0.0109 0.01232,-0.0313 0.007,-0.20604 -0.007,-0.23026 -0.0094,-0.0166 -0.055,-0.0416 -0.101257,-0.0554 -0.07204,-0.0216 -0.08681,-0.0329 -0.103088,-0.0789 -0.02214,-0.0624 -0.01553,-0.20992 0.01761,-0.39558 0.02813,-0.15775 0.03286,-0.16115 0.273519,-0.19704 0.269382,-0.0402 0.46666,-0.005 0.546556,0.0973 0.03251,0.0416 0.04129,0.0703 0.05674,0.18542 0.02381,0.17729 0.0081,0.27139 -0.05932,0.35514 -0.04157,0.0516 -0.06559,0.0683 -0.110183,0.0763 -0.06413,0.0116 -0.06399,0.0109 -0.03829,0.18455 l 0.01386,0.0937 0.434493,0.0242 c 0.238984,0.0133 0.437529,0.0218 0.441206,0.0188 0.0094,-0.008 0.0181,-0.23798 0.01023,-0.26953 -0.0035,-0.0142 -0.02715,-0.0332 -0.05243,-0.0422 -0.129023,-0.046 -0.153553,-0.0624 -0.166412,-0.1114 -0.01511,-0.0575 -0.0049,-0.22729 0.02486,-0.40504 l 0.02096,-0.12607 0.180046,-0.0401 c 0.193073,-0.0429 0.319499,-0.0436 0.47512,-0.002 0.09374,0.0249 0.136954,0.0585 0.169664,0.1321 0.03064,0.0688 0.05069,0.28106 0.03384,0.35786 -0.02611,0.11913 -0.114591,0.22114 -0.193449,0.22328 -0.04282,0.001 -0.04115,-0.01 -0.02994,0.19529 0.0035,0.0652 0.0087,0.11948 0.01142,0.12065 0.0028,0.001 0.121574,6.3e-4 0.264154,-10e-4 0.142587,-0.002 0.342901,-0.001 0.445181,4.4e-4 0.102239,0.002 0.186611,0.001 0.18744,-0.001 0.0085,-0.0291 0.0056,-0.19882 -0.0042,-0.23275 -0.01,-0.0353 -0.02855,-0.049 -0.09473,-0.0697 -0.13694,-0.0429 -0.149821,-0.0952 -0.103854,-0.42234 0.02924,-0.20814 0.03175,-0.21117 0.199757,-0.23959 0.05709,-0.01 0.133647,-0.0227 0.170208,-0.029 0.139934,-0.0241 0.364818,0.0205 0.433678,0.086 0.04811,0.0458 0.07868,0.1441 0.08927,0.28739 0.01393,0.18827 -0.05173,0.32291 -0.174288,0.35714 l -0.06419,0.018 0.01936,0.14639 c 0.01065,0.0805 0.02214,0.1478 0.02555,0.14953 0.0035,0.002 0.06935,0.0155 0.146548,0.0305 0.235698,0.0461 0.372638,0.0976 0.503375,0.18949 0.360397,0.25336 0.57474,0.61022 0.605028,1.00729 0.0056,0.07 0.0077,0.17185 0.0049,0.2262 -0.0056,0.1196 -0.05744,0.37906 -0.102719,0.51302 -0.08758,0.25885 -0.277041,0.48778 -0.531997,0.64266 -0.252227,0.15324 -0.612402,0.29416 -0.791096,0.3095 -0.373606,0.0321 -0.816789,-0.0633 -1.066314,-0.22957 -0.07469,-0.0498 -0.198099,-0.16748 -0.323524,-0.30857 -0.156908,-0.17652 -0.318287,-0.23164 -0.545484,-0.18634 -0.149862,0.0299 -0.222844,0.0651 -1.096538,0.52955 -0.906772,0.48202 -1.46724,0.77237 -1.911892,0.99043 -0.307906,0.151 -0.336891,0.16232 -0.632697,0.24692 -0.222977,0.0637 -0.324415,0.0868 -0.361407,0.082 -0.03795,-0.005 -0.08248,-0.0373 -0.169644,-0.12336 -0.173591,-0.17137 -0.42753,-0.38821 -0.562598,-0.48041 -0.147363,-0.1006 -0.278503,-0.1632 -0.480202,-0.22927 -0.299496,-0.0981 -0.35824,-0.10562 -0.602696,-0.0774 -0.121497,0.014 -0.281901,0.03 -0.356422,0.0357 -0.141132,0.0106 -0.827343,0.20427 -13.137841,3.70865 -1.052451,0.2996 -3.499898,0.99513 -5.438777,1.54563 -1.938872,0.55049 -3.97075,1.1291 -4.515287,1.28579 -0.544537,0.15669 -1.319063,0.37692 -1.721138,0.48939 l -0.731093,0.20451 -0.0075,0.0435 c -0.0042,0.0239 -0.02764,0.069 -0.05208,0.10018 -0.242674,0.30538 -0.282465,0.99869 -0.09215,1.6065 0.224272,0.71621 0.644297,1.2253 1.222032,1.48118 0.149396,0.0662 0.359576,0.0963 0.826174,0.11848 0.263346,0.0125 0.804784,10e-4 1.05935,-0.021 0.312662,-0.028 0.487284,0.001 0.690083,0.11666 0.233595,0.13263 0.356415,0.30288 0.414323,0.57431 0.05403,0.25341 0.0172,0.43968 -0.141688,0.71571 -0.05528,0.096 -0.138319,0.21674 -0.18453,0.26827 -0.18682,0.20821 -0.720475,0.5516 -1.200448,0.77256 -0.229111,0.10546 -0.942706,0.30469 -1.211769,0.33831 -0.547607,0.0684 -0.878309,0.0715 -2.278597,0.0213 -0.08576,-0.003 -0.313184,-0.0334 -0.505387,-0.0672 -0.533146,-0.0941 -0.845613,-0.12116 -1.264357,-0.10967 -0.674974,0.0185 -1.296149,0.17805 -1.903836,0.48891 -0.419462,0.21456 -0.783034,0.47469 -1.197573,0.85682 -0.136766,0.12609 -0.309716,0.27549 -0.3843,0.33199 -0.177399,0.1344 -0.37552,0.29562 -0.91267,0.74269 -0.859364,0.71524 -1.280044,1.0368 -1.812591,1.38553 -0.978522,0.64076 -1.934709,1.06388 -2.920604,1.29235 -0.674654,0.15634 -1.127654,0.22168 -1.597504,0.23041 -0.874299,0.0162 -1.532625,-0.15245 -2.41395,-0.61851 -0.377061,-0.19939 -0.396091,-0.21248 -0.678631,-0.46668 -0.64054,-0.57636 -0.94402,-0.92885 -1.28095,-1.4879 -0.41887,-0.69499 -0.78805,-1.60591 -1.04055,-2.56755 -0.0771,-0.2936 -0.24518,-0.91529 -0.37351,-1.38154 l -0.23333,-0.84773 -0.111,-0.0294 -0.11099,-0.0294 -0.0462,0.0714 c -0.0506,0.0789 -0.094,0.0992 -0.17474,0.0822 -0.092,-0.0193 -0.13135,-0.0726 -0.17325,-0.23539 -0.0269,-0.10423 -0.0338,-0.16041 -0.0249,-0.20301 z"
+       style="fill:#424d58;fill-opacity:1;stroke:none" />
+  </g>
+  <text
+     xml:space="preserve"
+     style="font-size:24.89476013px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;font-family:Bitstream Vera Sans"
+     x="266.96185"
+     y="736.90112"
+     id="text2508"><tspan
+       sodipodi:role="line"
+       id="tspan2510"
+       x="266.96185"
+       y="736.90112" /></text>
+  <g
+     id="g4145">
+    <g
+       style="fill:url(#radialGradient6297);fill-opacity:1;filter:url(#filter6439)"
+       transform="matrix(0.7163845,0,0,0.71128503,499.45401,591.13983)"
+       inkscape:label="Layer 1"
+       id="layer1">
+      <g
+         id="yleiso1"
+         transform="matrix(0.7844778,0,0,0.7844778,-1023.124,-443.46103)"
+         style="fill:url(#radialGradient3137);fill-opacity:1"
+         inkscape:export-filename="H:\new\rect2273.png"
+         inkscape:export-xdpi="90"
+         inkscape:export-ydpi="90">
+        <path
+           style="fill:url(#radialGradient6475);fill-opacity:1"
+           d="m 1181.224,723.79257 c 17.8661,-5.1827 3.8156,-26.068 6.1451,-38.9613 -2.6811,-18.56792 -15.9987,-33.39896 -20.3878,-51.57126 -6.8606,-15.87369 -8.1323,-33.33072 -13.6211,-49.48749 -4.5966,-12.71726 -9.3908,-25.46798 -16.5487,-36.62423 -8.2626,-12.91413 -13.2192,-27.92799 -7.4933,-43.22144 2.7035,-18.14405 7.7047,-35.78277 10.4398,-53.93215 7.4171,-11.14202 -5.8674,-36.22176 5.2186,-41.10752 -2.3197,22.42403 5.0015,2.60799 11.9276,11.6082 7.0053,-5.59071 5.4872,1.85751 8.2299,3.91882 5.932,-16.05448 9.7357,-3.85379 2.8631,5.00313 -9.8818,12.56195 -16.6266,32.14007 -15.296,48.89211 -1.4747,7.65925 1.4117,26.30935 3.6016,7.87451 2.6364,-8.08828 3.9759,7.07011 6.1598,7.5432 -13.0443,13.63184 20.3862,-2.18868 6.6467,10.94557 -3.039,8.74305 -19.6494,14.16534 -10.5833,23.66988 9.7308,11.67224 15.9374,26.7058 28.0739,36.1503 4.168,-0.62987 17.2037,-10.21636 14.9916,-15.40038 -3.7473,-12.40615 -10.4687,-27.14869 3.4638,-38.99508 11.3759,-6.02073 27.7425,-16.02154 38.4941,-5.54071 3.1119,16.39526 10.7156,33.21291 6.8445,50.16753 -1.9278,7.23379 -10.0675,25.98563 4.5899,18.54624 16.5134,-6.70982 20.1994,-21.1921 21.762,-37.42171 2.7436,-15.10347 11.0587,-31.98909 2.3918,-46.56641 -5.3185,-7.59752 -4.9737,-18.57102 2.3855,-6.93359 4.5245,-4.57537 5.5908,-33.1298 8.0527,-13.59432 1.503,4.2079 6.7245,-11.21855 7.2771,2.5917 12.0837,11.81526 0.4373,26.77552 1.5752,40.85819 -0.014,7.78552 -4.7837,31.21381 7.5539,16.0691 11.9958,-9.6748 14.597,-25.80379 23.3684,-37.95453 8.3733,-15.34917 16.6062,-32.68858 15.9268,-50.43155 1.9069,-10.49015 -7.0382,-31.20329 6.6909,-20.54154 -0.2582,-10.75897 20.2058,-15.99327 6.9602,-3.43085 -6.5561,15.27727 21.0159,-20.22468 11.6813,1.41398 -6.6548,5.39657 -5.312,15.53618 5.7754,2.9525 6.4909,1.94151 -10.0792,20.7174 -11.8877,28.74115 -11.2917,20.12314 -14.4477,43.50898 -22.3348,64.94192 -5.8098,15.78781 -13.6934,29.6345 -22.3551,43.97912 -9.5882,15.87913 -19.7814,31.59179 -31.1869,46.15679 -8.9458,10.99517 14.8617,1.14758 21.0201,6.78637 12.518,-7.87375 29.385,-1.07316 31.7442,13.9051 8.5354,6.87189 -2.959,27.20699 4.826,28.253 6.9599,-8.35669 30.6898,-10.22278 16.3911,-23.6599 -4.8799,-13.60995 -13.4899,-32.95924 2.9589,-42.5777 18.9802,-11.06226 29.1286,12.4481 34.5443,24.513 -1.1144,6.3124 -10.9945,24.16482 1.2989,23.0916 11.9703,5.11124 17.1415,-2.56675 9.7766,-12.99185 -5.6125,-7.61373 -1.994,-15.69956 2.4401,-3.88548 5.3211,8.43408 -3.2996,-25.65986 4.9774,-6.97215 1.2142,-0.66102 4.7324,-10.09149 5.0899,1.39026 1.3293,10.43455 4.5795,7.41882 7.2281,0.22402 3.133,9.794 -0.6183,21.94637 3.857,31.04505 15.1548,17.0439 34.661,30.4834 46.3055,50.3897 2.0219,10.6027 -2.3476,23.8758 -9.9945,30.7373 -96.6193,-0.1457 -193.2469,0.4071 -289.8601,-0.5562 z m 273.9725,-30.6938 c -5.4576,-7.6635 -15.9194,-5.3671 -3.5491,0.3557 0.497,0.7237 3.5906,1.4873 3.5491,-0.3557 z m -137.0451,-21.3848 c 8.1886,-16.11829 -15.8898,-22.27477 -13.8783,-38.63465 -0.2795,-7.03902 -1.2234,-20.4328 -8.3873,-7.61676 -8.7788,6.78734 8.6785,17.01782 2.351,27.10748 1.7752,8.92004 -7.3166,21.13593 7.9872,20.12463 3.789,1.2155 9.1084,3.1197 11.9274,-0.9807 z"
+           id="path2504"
+           sodipodi:nodetypes="ccccccccccccccccccccccccccccccccccccsscccccccccccccccccccccccccc" />
+      </g>
+    </g>
+    <g
+       style="fill:url(#radialGradient6295);fill-opacity:1;filter:url(#filter6435)"
+       transform="matrix(0.88812969,0,0,0.78446215,382.76315,569.603)"
+       inkscape:label="Layer 1"
+       id="g2670">
+      <g
+         id="yleiso2"
+         transform="matrix(0.6938009,0,0,0.6938009,-870.0051,-393.95863)"
+         style="fill:url(#radialGradient6473);fill-opacity:1"
+         inkscape:export-filename="H:\new\rect2273.png"
+         inkscape:export-xdpi="90"
+         inkscape:export-ydpi="90">
+        <path
+           style="fill:url(#radialGradient6471);fill-opacity:1"
+           d="m 1326.7136,723.79257 c -17.8661,-5.1827 -3.8156,-26.068 -6.1451,-38.9613 2.6811,-18.56792 15.9987,-33.39896 20.3878,-51.57126 6.8606,-15.87369 6.0596,-29.18523 11.5484,-45.342 8.742,-12.02634 14.9181,-19.24974 18.6214,-31.78782 5.4989,-17.05962 9.7646,-28.6189 4.0387,-43.91235 -2.7035,-18.14405 -7.7047,-35.78277 -10.4398,-53.93215 -7.4171,-11.14202 5.8674,-36.22176 -5.2186,-41.10752 2.3197,22.42403 -5.0015,2.60799 -11.9276,11.6082 -7.0053,-5.59071 -5.4872,1.85751 -8.2299,3.91882 -5.932,-16.05448 -9.7357,-3.85379 -2.8631,5.00313 9.8818,12.56195 16.6266,32.14007 15.296,48.89211 3.6034,32.14781 4.038,28.50478 -5.8248,50.03316 -9.7308,11.67224 -15.2465,26.01488 -27.383,35.45938 -4.168,-0.62987 -35.1675,23.6385 -12.2279,-23.00045 3.7473,-12.40615 10.4687,-27.14869 -3.4638,-38.99508 -11.3759,-6.02073 -27.7425,-16.02154 -38.4941,-5.54071 -3.1119,16.39526 -10.7156,33.21291 -6.8445,50.16753 1.9278,7.23379 10.0675,25.98563 -4.5899,18.54624 -22.93,-21.01361 -16.6495,-14.53032 -50.9982,-44.99704 -11.9958,-9.6748 -14.597,-25.80379 -23.3684,-37.95453 -8.3733,-15.34917 -16.6062,-32.68858 -15.9268,-50.43155 -1.9069,-10.49015 7.0382,-31.20329 -6.6909,-20.54154 0.2582,-10.75897 -20.2058,-15.99327 -6.9602,-3.43085 6.5561,15.27727 -21.0159,-20.22468 -11.6813,1.41398 6.6548,5.39657 5.312,15.53618 -5.7754,2.9525 -6.4909,1.94151 10.0792,20.7174 11.8877,28.74115 11.2917,20.12314 14.4477,43.50898 22.3348,64.94192 5.8098,15.78781 13.6934,29.6345 22.3551,43.97912 9.5882,15.87913 19.7814,31.59179 31.1869,46.15679 11.6035,54.34138 -4.3092,81.97365 -15.4445,111.81778 32.5872,16.89142 6.6287,16.78124 122.841,7.87434 z"
+           id="path2270"
+           sodipodi:nodetypes="cccccccccccccccccccccccccccssccc" />
+      </g>
+    </g>
+    <g
+       style="fill:url(#radialGradient6293);fill-opacity:1;filter:url(#filter6593)"
+       transform="matrix(-0.88812969,0,0,0.77373787,530.91675,562.04598)"
+       inkscape:label="Layer 1"
+       id="g2674">
+      <g
+         id="g2676"
+         transform="matrix(0.6938009,0,0,0.6938009,-870.0051,-393.95863)"
+         style="fill:url(#radialGradient6469);fill-opacity:1"
+         inkscape:export-filename="H:\new\rect2273.png"
+         inkscape:export-xdpi="90"
+         inkscape:export-ydpi="90">
+        <path
+           style="fill:url(#radialGradient6467);fill-opacity:1"
+           d="m 1326.7136,723.79257 c -17.8661,-5.1827 -3.8156,-26.068 -6.1451,-38.9613 2.6811,-18.56792 15.9987,-33.39896 20.3878,-51.57126 6.8606,-15.87369 6.0596,-29.18523 11.5484,-45.342 8.742,-12.02634 14.9181,-19.24974 18.6214,-31.78782 5.4989,-17.05962 9.7646,-28.6189 4.0387,-43.91235 -2.7035,-18.14405 -7.7047,-35.78277 -10.4398,-53.93215 -7.4171,-11.14202 5.8674,-36.22176 -5.2186,-41.10752 2.3197,22.42403 -5.0015,2.60799 -11.9276,11.6082 -7.0053,-5.59071 -5.4872,1.85751 -8.2299,3.91882 -5.932,-16.05448 -9.7357,-3.85379 -2.8631,5.00313 9.8818,12.56195 16.6266,32.14007 15.296,48.89211 3.6034,32.14781 4.038,28.50478 -5.8248,50.03316 -9.7308,11.67224 -15.2465,26.01488 -27.383,35.45938 -4.168,-0.62987 -35.1675,23.6385 -12.2279,-23.00045 3.7473,-12.40615 10.4687,-27.14869 -3.4638,-38.99508 -11.3759,-6.02073 -27.7425,-16.02154 -38.4941,-5.54071 -3.1119,16.39526 -10.7156,33.21291 -6.8445,50.16753 1.9278,7.23379 10.0675,25.98563 -4.5899,18.54624 -22.93,-21.01361 -16.6495,-14.53032 -50.9982,-44.99704 -11.9958,-9.6748 -14.597,-25.80379 -23.3684,-37.95453 -8.3733,-15.34917 -16.6062,-32.68858 -15.9268,-50.43155 -1.9069,-10.49015 7.0382,-31.20329 -6.6909,-20.54154 0.2582,-10.75897 -20.2058,-15.99327 -6.9602,-3.43085 6.5561,15.27727 -21.0159,-20.22468 -11.6813,1.41398 6.6548,5.39657 5.312,15.53618 -5.7754,2.9525 -6.4909,1.94151 10.0792,20.7174 11.8877,28.74115 11.2917,20.12314 14.4477,43.50898 22.3348,64.94192 5.8098,15.78781 13.6934,29.6345 22.3551,43.97912 9.5882,15.87913 19.7814,31.59179 31.1869,46.15679 11.6035,54.34138 -4.3092,81.97365 -15.4445,111.81778 32.5872,16.89142 6.6287,16.78124 122.841,7.87434 z"
+           id="path2678"
+           sodipodi:nodetypes="cccccccccccccccccccccccccccssccc" />
+      </g>
+    </g>
+    <g
+       style="fill:url(#radialGradient6291);fill-opacity:1;filter:url(#filter6609)"
+       transform="matrix(0.76594607,0,0,0.76594607,334.6978,587.54216)"
+       inkscape:label="Layer 1"
+       id="g2680">
+      <g
+         id="g2682"
+         transform="matrix(0.7844778,0,0,0.7844778,-1023.124,-443.46103)"
+         style="fill:url(#radialGradient6465);fill-opacity:1"
+         inkscape:export-filename="H:\new\rect2273.png"
+         inkscape:export-xdpi="90"
+         inkscape:export-ydpi="90">
+        <path
+           style="fill:url(#radialGradient6463);fill-opacity:1"
+           d="m 1181.224,723.79257 c 17.8661,-5.1827 3.8156,-26.068 6.1451,-38.9613 -2.6811,-18.56792 -15.9987,-33.39896 -20.3878,-51.57126 -6.8606,-15.87369 -8.1323,-33.33072 -13.6211,-49.48749 -4.5966,-12.71726 -9.3908,-25.46798 -16.5487,-36.62423 -8.2626,-12.91413 -13.2192,-27.92799 -7.4933,-43.22144 2.7035,-18.14405 7.7047,-35.78277 10.4398,-53.93215 7.4171,-11.14202 -5.8674,-36.22176 5.2186,-41.10752 -2.3197,22.42403 5.0015,2.60799 11.9276,11.6082 7.0053,-5.59071 5.4872,1.85751 8.2299,3.91882 5.932,-16.05448 9.7357,-3.85379 2.8631,5.00313 -9.8818,12.56195 -16.6266,32.14007 -15.296,48.89211 -1.4747,7.65925 1.4117,26.30935 3.6016,7.87451 2.6364,-8.08828 3.9759,7.07011 6.1598,7.5432 -13.0443,13.63184 20.3862,-2.18868 6.6467,10.94557 -3.039,8.74305 -19.6494,14.16534 -10.5833,23.66988 9.7308,11.67224 15.9374,26.7058 28.0739,36.1503 4.168,-0.62987 17.2037,-10.21636 14.9916,-15.40038 -3.7473,-12.40615 -10.4687,-27.14869 3.4638,-38.99508 11.3759,-6.02073 27.7425,-16.02154 38.4941,-5.54071 3.1119,16.39526 10.7156,33.21291 6.8445,50.16753 -1.9278,7.23379 -10.0675,25.98563 4.5899,18.54624 16.5134,-6.70982 20.1994,-21.1921 21.762,-37.42171 2.7436,-15.10347 11.0587,-31.98909 2.3918,-46.56641 -5.3185,-7.59752 -4.9737,-18.57102 2.3855,-6.93359 4.5245,-4.57537 5.5908,-33.1298 8.0527,-13.59432 1.503,4.2079 6.7245,-11.21855 7.2771,2.5917 12.0837,11.81526 0.4373,26.77552 1.5752,40.85819 -0.014,7.78552 -4.7837,31.21381 7.5539,16.0691 11.9958,-9.6748 14.597,-25.80379 23.3684,-37.95453 8.3733,-15.34917 16.6062,-32.68858 15.9268,-50.43155 1.9069,-10.49015 -7.0382,-31.20329 6.6909,-20.54154 -0.2582,-10.75897 20.2058,-15.99327 6.9602,-3.43085 -6.5561,15.27727 21.0159,-20.22468 11.6813,1.41398 -6.6548,5.39657 -5.312,15.53618 5.7754,2.9525 6.4909,1.94151 -10.0792,20.7174 -11.8877,28.74115 -11.2917,20.12314 -14.4477,43.50898 -22.3348,64.94192 -5.8098,15.78781 -13.6934,29.6345 -22.3551,43.97912 -9.5882,15.87913 -19.7814,31.59179 -31.1869,46.15679 -8.9458,10.99517 14.8617,1.14758 21.0201,6.78637 12.518,-7.87375 29.385,-1.07316 31.7442,13.9051 8.5354,6.87189 -2.959,27.20699 4.826,28.253 6.9599,-8.35669 30.6898,-10.22278 16.3911,-23.6599 -4.8799,-13.60995 -13.4899,-32.95924 2.9589,-42.5777 18.9802,-11.06226 29.1286,12.4481 34.5443,24.513 -1.1144,6.3124 -10.9945,24.16482 1.2989,23.0916 11.9703,5.11124 17.1415,-2.56675 9.7766,-12.99185 -5.6125,-7.61373 -1.994,-15.69956 2.4401,-3.88548 5.3211,8.43408 -3.2996,-25.65986 4.9774,-6.97215 1.2142,-0.66102 4.7324,-10.09149 5.0899,1.39026 1.3293,10.43455 4.5795,7.41882 7.2281,0.22402 3.133,9.794 -0.6183,21.94637 3.857,31.04505 15.1548,17.0439 34.661,30.4834 46.3055,50.3897 2.0219,10.6027 -2.3476,23.8758 -9.9945,30.7373 -96.6193,-0.1457 -193.2469,0.4071 -289.8601,-0.5562 z m 273.9725,-30.6938 c -5.4576,-7.6635 -15.9194,-5.3671 -3.5491,0.3557 0.497,0.7237 3.5906,1.4873 3.5491,-0.3557 z m -137.0451,-21.3848 c 8.1886,-16.11829 -15.8898,-22.27477 -13.8783,-38.63465 -0.2795,-7.03902 -1.2234,-20.4328 -8.3873,-7.61676 -8.7788,6.78734 8.6785,17.01782 2.351,27.10748 1.7752,8.92004 -7.3166,21.13593 7.9872,20.12463 3.789,1.2155 9.1084,3.1197 11.9274,-0.9807 z"
+           id="path2684"
+           sodipodi:nodetypes="ccccccccccccccccccccccccccccccccccccsscccccccccccccccccccccccccc" />
+      </g>
+    </g>
+    <g
+       style="fill:url(#radialGradient6289);fill-opacity:1;filter:url(#filter6781)"
+       transform="matrix(0.88812969,0,0,0.75951536,146.19341,582.76899)"
+       inkscape:label="Layer 1"
+       id="g2686">
+      <g
+         id="g2688"
+         transform="matrix(0.7844778,0,0,0.7844778,-1023.124,-443.46103)"
+         style="fill:url(#radialGradient6461);fill-opacity:1"
+         inkscape:export-filename="H:\new\rect2273.png"
+         inkscape:export-xdpi="90"
+         inkscape:export-ydpi="90">
+        <path
+           style="fill:url(#radialGradient6459);fill-opacity:1"
+           d="m 1181.224,723.79257 c 17.8661,-5.1827 3.8156,-26.068 6.1451,-38.9613 -2.6811,-18.56792 -15.9987,-33.39896 -20.3878,-51.57126 -6.8606,-15.87369 -8.1323,-33.33072 -13.6211,-49.48749 -4.5966,-12.71726 -9.3908,-25.46798 -16.5487,-36.62423 -8.2626,-12.91413 -13.2192,-27.92799 -7.4933,-43.22144 2.7035,-18.14405 7.7047,-35.78277 10.4398,-53.93215 7.4171,-11.14202 -5.8674,-36.22176 5.2186,-41.10752 -2.3197,22.42403 5.0015,2.60799 11.9276,11.6082 7.0053,-5.59071 5.4872,1.85751 8.2299,3.91882 5.932,-16.05448 9.7357,-3.85379 2.8631,5.00313 -9.8818,12.56195 -16.6266,32.14007 -15.296,48.89211 -1.4747,7.65925 1.4117,26.30935 3.6016,7.87451 2.6364,-8.08828 3.9759,7.07011 6.1598,7.5432 -13.0443,13.63184 20.3862,-2.18868 6.6467,10.94557 -3.039,8.74305 -19.6494,14.16534 -10.5833,23.66988 9.7308,11.67224 15.9374,26.7058 28.0739,36.1503 4.168,-0.62987 17.2037,-10.21636 14.9916,-15.40038 -3.7473,-12.40615 -10.4687,-27.14869 3.4638,-38.99508 11.3759,-6.02073 27.7425,-16.02154 38.4941,-5.54071 3.1119,16.39526 10.7156,33.21291 6.8445,50.16753 -1.9278,7.23379 -10.0675,25.98563 4.5899,18.54624 16.5134,-6.70982 20.1994,-21.1921 21.762,-37.42171 2.7436,-15.10347 11.0587,-31.98909 2.3918,-46.56641 -5.3185,-7.59752 -4.9737,-18.57102 2.3855,-6.93359 4.5245,-4.57537 5.5908,-33.1298 8.0527,-13.59432 1.503,4.2079 6.7245,-11.21855 7.2771,2.5917 12.0837,11.81526 0.4373,26.77552 1.5752,40.85819 -0.014,7.78552 -4.7837,31.21381 7.5539,16.0691 11.9958,-9.6748 14.597,-25.80379 23.3684,-37.95453 8.3733,-15.34917 16.6062,-32.68858 15.9268,-50.43155 1.9069,-10.49015 -7.0382,-31.20329 6.6909,-20.54154 -0.2582,-10.75897 20.2058,-15.99327 6.9602,-3.43085 -6.5561,15.27727 21.0159,-20.22468 11.6813,1.41398 -6.6548,5.39657 -5.312,15.53618 5.7754,2.9525 6.4909,1.94151 -10.0792,20.7174 -11.8877,28.74115 -11.2917,20.12314 -14.4477,43.50898 -22.3348,64.94192 -5.8098,15.78781 -13.6934,29.6345 -22.3551,43.97912 -9.5882,15.87913 -19.7814,31.59179 -31.1869,46.15679 -8.9458,10.99517 14.8617,1.14758 21.0201,6.78637 12.518,-7.87375 29.385,-1.07316 31.7442,13.9051 8.5354,6.87189 -2.959,27.20699 4.826,28.253 6.9599,-8.35669 30.6898,-10.22278 16.3911,-23.6599 -4.8799,-13.60995 -13.4899,-32.95924 2.9589,-42.5777 18.9802,-11.06226 29.1286,12.4481 34.5443,24.513 -1.1144,6.3124 -10.9945,24.16482 1.2989,23.0916 11.9703,5.11124 17.1415,-2.56675 9.7766,-12.99185 -5.6125,-7.61373 -1.994,-15.69956 2.4401,-3.88548 5.3211,8.43408 -3.2996,-25.65986 4.9774,-6.97215 1.2142,-0.66102 4.7324,-10.09149 5.0899,1.39026 1.3293,10.43455 4.5795,7.41882 7.2281,0.22402 3.133,9.794 -0.6183,21.94637 3.857,31.04505 15.1548,17.0439 34.661,30.4834 46.3055,50.3897 2.0219,10.6027 -2.3476,23.8758 -9.9945,30.7373 -96.6193,-0.1457 -193.2469,0.4071 -289.8601,-0.5562 z m 273.9725,-30.6938 c -5.4576,-7.6635 -15.9194,-5.3671 -3.5491,0.3557 0.497,0.7237 3.5906,1.4873 3.5491,-0.3557 z m -137.0451,-21.3848 c 8.1886,-16.11829 -15.8898,-22.27477 -13.8783,-38.63465 -0.2795,-7.03902 -1.2234,-20.4328 -8.3873,-7.61676 -8.7788,6.78734 8.6785,17.01782 2.351,27.10748 1.7752,8.92004 -7.3166,21.13593 7.9872,20.12463 3.789,1.2155 9.1084,3.1197 11.9274,-0.9807 z"
+           id="path2690"
+           sodipodi:nodetypes="ccccccccccccccccccccccccccccccccccccsscccccccccccccccccccccccccc" />
+      </g>
+    </g>
+    <g
+       style="fill:url(#radialGradient6287);fill-opacity:1;filter:url(#filter6529)"
+       transform="matrix(-0.68430241,0,0,0.78803687,598.62179,591.5042)"
+       inkscape:label="Layer 1"
+       id="g2692">
+      <g
+         id="g2694"
+         transform="matrix(0.6938009,0,0,0.6938009,-870.0051,-393.95863)"
+         style="fill:url(#radialGradient6457);fill-opacity:1"
+         inkscape:export-filename="H:\new\rect2273.png"
+         inkscape:export-xdpi="90"
+         inkscape:export-ydpi="90">
+        <path
+           style="fill:url(#radialGradient6455);fill-opacity:1"
+           d="m 1326.7136,723.79257 c -17.8661,-5.1827 -3.8156,-26.068 -6.1451,-38.9613 2.6811,-18.56792 15.9987,-33.39896 20.3878,-51.57126 6.8606,-15.87369 6.0596,-29.18523 11.5484,-45.342 8.742,-12.02634 14.9181,-19.24974 18.6214,-31.78782 5.4989,-17.05962 9.7646,-28.6189 4.0387,-43.91235 -2.7035,-18.14405 -7.7047,-35.78277 -10.4398,-53.93215 -7.4171,-11.14202 5.8674,-36.22176 -5.2186,-41.10752 2.3197,22.42403 -5.0015,2.60799 -11.9276,11.6082 -7.0053,-5.59071 -5.4872,1.85751 -8.2299,3.91882 -5.932,-16.05448 -9.7357,-3.85379 -2.8631,5.00313 9.8818,12.56195 16.6266,32.14007 15.296,48.89211 3.6034,32.14781 4.038,28.50478 -5.8248,50.03316 -9.7308,11.67224 -15.2465,26.01488 -27.383,35.45938 -4.168,-0.62987 -35.1675,23.6385 -12.2279,-23.00045 3.7473,-12.40615 10.4687,-27.14869 -3.4638,-38.99508 -11.3759,-6.02073 -27.7425,-16.02154 -38.4941,-5.54071 -3.1119,16.39526 -10.7156,33.21291 -6.8445,50.16753 1.9278,7.23379 10.0675,25.98563 -4.5899,18.54624 -22.93,-21.01361 -16.6495,-14.53032 -50.9982,-44.99704 -11.9958,-9.6748 -14.597,-25.80379 -23.3684,-37.95453 -8.3733,-15.34917 -16.6062,-32.68858 -15.9268,-50.43155 -1.9069,-10.49015 7.0382,-31.20329 -6.6909,-20.54154 0.2582,-10.75897 -20.2058,-15.99327 -6.9602,-3.43085 6.5561,15.27727 -21.0159,-20.22468 -11.6813,1.41398 6.6548,5.39657 5.312,15.53618 -5.7754,2.9525 -6.4909,1.94151 10.0792,20.7174 11.8877,28.74115 11.2917,20.12314 14.4477,43.50898 22.3348,64.94192 5.8098,15.78781 13.6934,29.6345 22.3551,43.97912 9.5882,15.87913 19.7814,31.59179 31.1869,46.15679 11.6035,54.34138 -4.3092,81.97365 -15.4445,111.81778 32.5872,16.89142 6.6287,16.78124 122.841,7.87434 z"
+           id="path2696"
+           sodipodi:nodetypes="cccccccccccccccccccccccccccssccc" />
+      </g>
+    </g>
+    <g
+       style="fill:url(#radialGradient6285);fill-opacity:1;filter:url(#filter6415)"
+       transform="matrix(-0.88812969,0,0,0.88812969,669.51278,580.25934)"
+       inkscape:label="Layer 1"
+       id="g2698">
+      <g
+         id="g2700"
+         transform="matrix(0.6938009,0,0,0.6938009,-870.0051,-393.95863)"
+         style="fill:url(#radialGradient6453);fill-opacity:1"
+         inkscape:export-filename="H:\new\rect2273.png"
+         inkscape:export-xdpi="90"
+         inkscape:export-ydpi="90">
+        <path
+           style="fill:url(#radialGradient6451);fill-opacity:1"
+           d="m 1326.7136,723.79257 c -17.8661,-5.1827 -3.8156,-26.068 -6.1451,-38.9613 2.6811,-18.56792 15.9987,-33.39896 20.3878,-51.57126 6.8606,-15.87369 6.0596,-29.18523 11.5484,-45.342 8.742,-12.02634 14.9181,-19.24974 18.6214,-31.78782 5.4989,-17.05962 9.7646,-28.6189 4.0387,-43.91235 -2.7035,-18.14405 -7.7047,-35.78277 -10.4398,-53.93215 -7.4171,-11.14202 5.8674,-36.22176 -5.2186,-41.10752 2.3197,22.42403 -5.0015,2.60799 -11.9276,11.6082 -7.0053,-5.59071 -5.4872,1.85751 -8.2299,3.91882 -5.932,-16.05448 -9.7357,-3.85379 -2.8631,5.00313 9.8818,12.56195 16.6266,32.14007 15.296,48.89211 3.6034,32.14781 4.038,28.50478 -5.8248,50.03316 -9.7308,11.67224 -15.2465,26.01488 -27.383,35.45938 -4.168,-0.62987 -35.1675,23.6385 -12.2279,-23.00045 3.7473,-12.40615 10.4687,-27.14869 -3.4638,-38.99508 -11.3759,-6.02073 -27.7425,-16.02154 -38.4941,-5.54071 -3.1119,16.39526 -10.7156,33.21291 -6.8445,50.16753 1.9278,7.23379 10.0675,25.98563 -4.5899,18.54624 -22.93,-21.01361 -16.6495,-14.53032 -50.9982,-44.99704 -11.9958,-9.6748 -14.597,-25.80379 -23.3684,-37.95453 -8.3733,-15.34917 -16.6062,-32.68858 -15.9268,-50.43155 -1.9069,-10.49015 7.0382,-31.20329 -6.6909,-20.54154 0.2582,-10.75897 -20.2058,-15.99327 -6.9602,-3.43085 6.5561,15.27727 -21.0159,-20.22468 -11.6813,1.41398 6.6548,5.39657 5.312,15.53618 -5.7754,2.9525 -6.4909,1.94151 10.0792,20.7174 11.8877,28.74115 11.2917,20.12314 14.4477,43.50898 22.3348,64.94192 5.8098,15.78781 13.6934,29.6345 22.3551,43.97912 9.5882,15.87913 19.7814,31.59179 31.1869,46.15679 11.6035,54.34138 -4.3092,81.97365 -15.4445,111.81778 32.5872,16.89142 6.6287,16.78124 122.841,7.87434 z"
+           id="path2702"
+           sodipodi:nodetypes="cccccccccccccccccccccccccccssccc" />
+      </g>
+    </g>
+    <g
+       style="fill:url(#radialGradient6283);fill-opacity:1;filter:url(#filter6693)"
+       transform="matrix(0.91129181,0,0,0.93102658,947.10383,583.40541)"
+       inkscape:label="Layer 1"
+       id="g2704">
+      <g
+         id="g2706"
+         transform="matrix(0.6938009,0,0,0.6938009,-870.0051,-393.95863)"
+         style="fill:url(#radialGradient6449);fill-opacity:1"
+         inkscape:export-filename="H:\new\rect2273.png"
+         inkscape:export-xdpi="90"
+         inkscape:export-ydpi="90">
+        <path
+           style="fill:url(#radialGradient6447);fill-opacity:1"
+           d="m 1326.7136,723.79257 c -17.8661,-5.1827 -3.8156,-26.068 -6.1451,-38.9613 2.6811,-18.56792 15.9987,-33.39896 20.3878,-51.57126 6.8606,-15.87369 6.0596,-29.18523 11.5484,-45.342 8.742,-12.02634 14.9181,-19.24974 18.6214,-31.78782 5.4989,-17.05962 9.7646,-28.6189 4.0387,-43.91235 -2.7035,-18.14405 -7.7047,-35.78277 -10.4398,-53.93215 -7.4171,-11.14202 5.8674,-36.22176 -5.2186,-41.10752 2.3197,22.42403 -5.0015,2.60799 -11.9276,11.6082 -7.0053,-5.59071 -5.4872,1.85751 -8.2299,3.91882 -5.932,-16.05448 -9.7357,-3.85379 -2.8631,5.00313 9.8818,12.56195 16.6266,32.14007 15.296,48.89211 3.6034,32.14781 4.038,28.50478 -5.8248,50.03316 -9.7308,11.67224 -15.2465,26.01488 -27.383,35.45938 -4.168,-0.62987 -35.1675,23.6385 -12.2279,-23.00045 3.7473,-12.40615 10.4687,-27.14869 -3.4638,-38.99508 -11.3759,-6.02073 -27.7425,-16.02154 -38.4941,-5.54071 -3.1119,16.39526 -10.7156,33.21291 -6.8445,50.16753 1.9278,7.23379 10.0675,25.98563 -4.5899,18.54624 -22.93,-21.01361 -16.6495,-14.53032 -50.9982,-44.99704 -11.9958,-9.6748 -14.597,-25.80379 -23.3684,-37.95453 -8.3733,-15.34917 -16.6062,-32.68858 -15.9268,-50.43155 -1.9069,-10.49015 7.0382,-31.20329 -6.6909,-20.54154 0.2582,-10.75897 -20.2058,-15.99327 -6.9602,-3.43085 6.5561,15.27727 -21.0159,-20.22468 -11.6813,1.41398 6.6548,5.39657 5.312,15.53618 -5.7754,2.9525 -6.4909,1.94151 10.0792,20.7174 11.8877,28.74115 11.2917,20.12314 14.4477,43.50898 22.3348,64.94192 5.8098,15.78781 13.6934,29.6345 22.3551,43.97912 9.5882,15.87913 19.7814,31.59179 31.1869,46.15679 11.6035,54.34138 -4.3092,81.97365 -15.4445,111.81778 32.5872,16.89142 6.6287,16.78124 122.841,7.87434 z"
+           id="path2708"
+           sodipodi:nodetypes="cccccccccccccccccccccccccccssccc" />
+      </g>
+    </g>
+    <g
+       style="fill:url(#radialGradient6281);fill-opacity:1;filter:url(#filter6557)"
+       transform="matrix(0.88812969,0,0,0.84311465,808.10889,574.72565)"
+       inkscape:label="Layer 1"
+       id="g2710">
+      <g
+         id="g2712"
+         transform="matrix(0.7844778,0,0,0.7844778,-1023.124,-443.46103)"
+         style="fill:url(#radialGradient6445);fill-opacity:1"
+         inkscape:export-filename="H:\new\rect2273.png"
+         inkscape:export-xdpi="90"
+         inkscape:export-ydpi="90">
+        <path
+           style="fill:url(#radialGradient6443);fill-opacity:1"
+           d="m 1181.224,723.79257 c 17.8661,-5.1827 3.8156,-26.068 6.1451,-38.9613 -2.6811,-18.56792 -15.9987,-33.39896 -20.3878,-51.57126 -6.8606,-15.87369 -8.1323,-33.33072 -13.6211,-49.48749 -4.5966,-12.71726 -9.3908,-25.46798 -16.5487,-36.62423 -8.2626,-12.91413 -13.2192,-27.92799 -7.4933,-43.22144 2.7035,-18.14405 7.7047,-35.78277 10.4398,-53.93215 7.4171,-11.14202 -5.8674,-36.22176 5.2186,-41.10752 -2.3197,22.42403 5.0015,2.60799 11.9276,11.6082 7.0053,-5.59071 5.4872,1.85751 8.2299,3.91882 5.932,-16.05448 9.7357,-3.85379 2.8631,5.00313 -9.8818,12.56195 -16.6266,32.14007 -15.296,48.89211 -1.4747,7.65925 1.4117,26.30935 3.6016,7.87451 2.6364,-8.08828 3.9759,7.07011 6.1598,7.5432 -13.0443,13.63184 20.3862,-2.18868 6.6467,10.94557 -3.039,8.74305 -19.6494,14.16534 -10.5833,23.66988 9.7308,11.67224 15.9374,26.7058 28.0739,36.1503 4.168,-0.62987 17.2037,-10.21636 14.9916,-15.40038 -3.7473,-12.40615 -10.4687,-27.14869 3.4638,-38.99508 11.3759,-6.02073 27.7425,-16.02154 38.4941,-5.54071 3.1119,16.39526 10.7156,33.21291 6.8445,50.16753 -1.9278,7.23379 -10.0675,25.98563 4.5899,18.54624 16.5134,-6.70982 20.1994,-21.1921 21.762,-37.42171 2.7436,-15.10347 11.0587,-31.98909 2.3918,-46.56641 -5.3185,-7.59752 -4.9737,-18.57102 2.3855,-6.93359 4.5245,-4.57537 5.5908,-33.1298 8.0527,-13.59432 1.503,4.2079 6.7245,-11.21855 7.2771,2.5917 12.0837,11.81526 0.4373,26.77552 1.5752,40.85819 -0.014,7.78552 -4.7837,31.21381 7.5539,16.0691 11.9958,-9.6748 14.597,-25.80379 23.3684,-37.95453 8.3733,-15.34917 16.6062,-32.68858 15.9268,-50.43155 1.9069,-10.49015 -7.0382,-31.20329 6.6909,-20.54154 -0.2582,-10.75897 20.2058,-15.99327 6.9602,-3.43085 -6.5561,15.27727 21.0159,-20.22468 11.6813,1.41398 -6.6548,5.39657 -5.312,15.53618 5.7754,2.9525 6.4909,1.94151 -10.0792,20.7174 -11.8877,28.74115 -11.2917,20.12314 -14.4477,43.50898 -22.3348,64.94192 -5.8098,15.78781 -13.6934,29.6345 -22.3551,43.97912 -9.5882,15.87913 -19.7814,31.59179 -31.1869,46.15679 -8.9458,10.99517 14.8617,1.14758 21.0201,6.78637 12.518,-7.87375 29.385,-1.07316 31.7442,13.9051 8.5354,6.87189 -2.959,27.20699 4.826,28.253 6.9599,-8.35669 30.6898,-10.22278 16.3911,-23.6599 -4.8799,-13.60995 -13.4899,-32.95924 2.9589,-42.5777 18.9802,-11.06226 29.1286,12.4481 34.5443,24.513 -1.1144,6.3124 -10.9945,24.16482 1.2989,23.0916 11.9703,5.11124 17.1415,-2.56675 9.7766,-12.99185 -5.6125,-7.61373 -1.994,-15.69956 2.4401,-3.88548 5.3211,8.43408 -3.2996,-25.65986 4.9774,-6.97215 1.2142,-0.66102 4.7324,-10.09149 5.0899,1.39026 1.3293,10.43455 4.5795,7.41882 7.2281,0.22402 3.133,9.794 -0.6183,21.94637 3.857,31.04505 15.1548,17.0439 34.661,30.4834 46.3055,50.3897 2.0219,10.6027 -2.3476,23.8758 -9.9945,30.7373 -96.6193,-0.1457 -193.2469,0.4071 -289.8601,-0.5562 z m 273.9725,-30.6938 c -5.4576,-7.6635 -15.9194,-5.3671 -3.5491,0.3557 0.497,0.7237 3.5906,1.4873 3.5491,-0.3557 z m -137.0451,-21.3848 c 8.1886,-16.11829 -15.8898,-22.27477 -13.8783,-38.63465 -0.2795,-7.03902 -1.2234,-20.4328 -8.3873,-7.61676 -8.7788,6.78734 8.6785,17.01782 2.351,27.10748 1.7752,8.92004 -7.3166,21.13593 7.9872,20.12463 3.789,1.2155 9.1084,3.1197 11.9274,-0.9807 z"
+           id="path2714"
+           sodipodi:nodetypes="ccccccccccccccccccccccccccccccccccccsscccccccccccccccccccccccccc" />
+      </g>
+    </g>
+  </g>
+  <g
+     id="g4174"
+     transform="matrix(-1.3393756,0,0,1.3393756,1222.4805,-114.77091)">
+    <g
+       id="g4176"
+       inkscape:label="Layer 1"
+       transform="matrix(0.7163845,0,0,0.71128503,499.45401,591.13983)"
+       style="fill:url(#radialGradient4234);fill-opacity:1;filter:url(#filter6439)">
+      <g
+         inkscape:export-ydpi="90"
+         inkscape:export-xdpi="90"
+         inkscape:export-filename="H:\new\rect2273.png"
+         style="fill:url(#radialGradient4232);fill-opacity:1"
+         transform="matrix(0.7844778,0,0,0.7844778,-1023.124,-443.46103)"
+         id="g4178">
+        <path
+           sodipodi:nodetypes="ccccccccccccccccccccccccccccccccccccsscccccccccccccccccccccccccc"
+           id="path4180"
+           d="m 1181.224,723.79257 c 17.8661,-5.1827 3.8156,-26.068 6.1451,-38.9613 -2.6811,-18.56792 -15.9987,-33.39896 -20.3878,-51.57126 -6.8606,-15.87369 -8.1323,-33.33072 -13.6211,-49.48749 -4.5966,-12.71726 -9.3908,-25.46798 -16.5487,-36.62423 -8.2626,-12.91413 -13.2192,-27.92799 -7.4933,-43.22144 2.7035,-18.14405 7.7047,-35.78277 10.4398,-53.93215 7.4171,-11.14202 -5.8674,-36.22176 5.2186,-41.10752 -2.3197,22.42403 5.0015,2.60799 11.9276,11.6082 7.0053,-5.59071 5.4872,1.85751 8.2299,3.91882 5.932,-16.05448 9.7357,-3.85379 2.8631,5.00313 -9.8818,12.56195 -16.6266,32.14007 -15.296,48.89211 -1.4747,7.65925 1.4117,26.30935 3.6016,7.87451 2.6364,-8.08828 3.9759,7.07011 6.1598,7.5432 -13.0443,13.63184 20.3862,-2.18868 6.6467,10.94557 -3.039,8.74305 -19.6494,14.16534 -10.5833,23.66988 9.7308,11.67224 15.9374,26.7058 28.0739,36.1503 4.168,-0.62987 17.2037,-10.21636 14.9916,-15.40038 -3.7473,-12.40615 -10.4687,-27.14869 3.4638,-38.99508 11.3759,-6.02073 27.7425,-16.02154 38.4941,-5.54071 3.1119,16.39526 10.7156,33.21291 6.8445,50.16753 -1.9278,7.23379 -10.0675,25.98563 4.5899,18.54624 16.5134,-6.70982 20.1994,-21.1921 21.762,-37.42171 2.7436,-15.10347 11.0587,-31.98909 2.3918,-46.56641 -5.3185,-7.59752 -4.9737,-18.57102 2.3855,-6.93359 4.5245,-4.57537 5.5908,-33.1298 8.0527,-13.59432 1.503,4.2079 6.7245,-11.21855 7.2771,2.5917 12.0837,11.81526 0.4373,26.77552 1.5752,40.85819 -0.014,7.78552 -4.7837,31.21381 7.5539,16.0691 11.9958,-9.6748 14.597,-25.80379 23.3684,-37.95453 8.3733,-15.34917 16.6062,-32.68858 15.9268,-50.43155 1.9069,-10.49015 -7.0382,-31.20329 6.6909,-20.54154 -0.2582,-10.75897 20.2058,-15.99327 6.9602,-3.43085 -6.5561,15.27727 21.0159,-20.22468 11.6813,1.41398 -6.6548,5.39657 -5.312,15.53618 5.7754,2.9525 6.4909,1.94151 -10.0792,20.7174 -11.8877,28.74115 -11.2917,20.12314 -14.4477,43.50898 -22.3348,64.94192 -5.8098,15.78781 -13.6934,29.6345 -22.3551,43.97912 -9.5882,15.87913 -19.7814,31.59179 -31.1869,46.15679 -8.9458,10.99517 14.8617,1.14758 21.0201,6.78637 12.518,-7.87375 29.385,-1.07316 31.7442,13.9051 8.5354,6.87189 -2.959,27.20699 4.826,28.253 6.9599,-8.35669 30.6898,-10.22278 16.3911,-23.6599 -4.8799,-13.60995 -13.4899,-32.95924 2.9589,-42.5777 18.9802,-11.06226 29.1286,12.4481 34.5443,24.513 -1.1144,6.3124 -10.9945,24.16482 1.2989,23.0916 11.9703,5.11124 17.1415,-2.56675 9.7766,-12.99185 -5.6125,-7.61373 -1.994,-15.69956 2.4401,-3.88548 5.3211,8.43408 -3.2996,-25.65986 4.9774,-6.97215 1.2142,-0.66102 4.7324,-10.09149 5.0899,1.39026 1.3293,10.43455 4.5795,7.41882 7.2281,0.22402 3.133,9.794 -0.6183,21.94637 3.857,31.04505 15.1548,17.0439 34.661,30.4834 46.3055,50.3897 2.0219,10.6027 -2.3476,23.8758 -9.9945,30.7373 -96.6193,-0.1457 -193.2469,0.4071 -289.8601,-0.5562 z m 273.9725,-30.6938 c -5.4576,-7.6635 -15.9194,-5.3671 -3.5491,0.3557 0.497,0.7237 3.5906,1.4873 3.5491,-0.3557 z m -137.0451,-21.3848 c 8.1886,-16.11829 -15.8898,-22.27477 -13.8783,-38.63465 -0.2795,-7.03902 -1.2234,-20.4328 -8.3873,-7.61676 -8.7788,6.78734 8.6785,17.01782 2.351,27.10748 1.7752,8.92004 -7.3166,21.13593 7.9872,20.12463 3.789,1.2155 9.1084,3.1197 11.9274,-0.9807 z"
+           style="fill:url(#radialGradient4230);fill-opacity:1" />
+      </g>
+    </g>
+    <g
+       id="g4182"
+       inkscape:label="Layer 1"
+       transform="matrix(0.88812969,0,0,0.78446215,382.76315,569.603)"
+       style="fill:url(#radialGradient4240);fill-opacity:1;filter:url(#filter6435)">
+      <g
+         inkscape:export-ydpi="90"
+         inkscape:export-xdpi="90"
+         inkscape:export-filename="H:\new\rect2273.png"
+         style="fill:url(#radialGradient4238);fill-opacity:1"
+         transform="matrix(0.6938009,0,0,0.6938009,-870.0051,-393.95863)"
+         id="g4184">
+        <path
+           sodipodi:nodetypes="cccccccccccccccccccccccccccssccc"
+           id="path4186"
+           d="m 1326.7136,723.79257 c -17.8661,-5.1827 -3.8156,-26.068 -6.1451,-38.9613 2.6811,-18.56792 15.9987,-33.39896 20.3878,-51.57126 6.8606,-15.87369 6.0596,-29.18523 11.5484,-45.342 8.742,-12.02634 14.9181,-19.24974 18.6214,-31.78782 5.4989,-17.05962 9.7646,-28.6189 4.0387,-43.91235 -2.7035,-18.14405 -7.7047,-35.78277 -10.4398,-53.93215 -7.4171,-11.14202 5.8674,-36.22176 -5.2186,-41.10752 2.3197,22.42403 -5.0015,2.60799 -11.9276,11.6082 -7.0053,-5.59071 -5.4872,1.85751 -8.2299,3.91882 -5.932,-16.05448 -9.7357,-3.85379 -2.8631,5.00313 9.8818,12.56195 16.6266,32.14007 15.296,48.89211 3.6034,32.14781 4.038,28.50478 -5.8248,50.03316 -9.7308,11.67224 -15.2465,26.01488 -27.383,35.45938 -4.168,-0.62987 -35.1675,23.6385 -12.2279,-23.00045 3.7473,-12.40615 10.4687,-27.14869 -3.4638,-38.99508 -11.3759,-6.02073 -27.7425,-16.02154 -38.4941,-5.54071 -3.1119,16.39526 -10.7156,33.21291 -6.8445,50.16753 1.9278,7.23379 10.0675,25.98563 -4.5899,18.54624 -22.93,-21.01361 -16.6495,-14.53032 -50.9982,-44.99704 -11.9958,-9.6748 -14.597,-25.80379 -23.3684,-37.95453 -8.3733,-15.34917 -16.6062,-32.68858 -15.9268,-50.43155 -1.9069,-10.49015 7.0382,-31.20329 -6.6909,-20.54154 0.2582,-10.75897 -20.2058,-15.99327 -6.9602,-3.43085 6.5561,15.27727 -21.0159,-20.22468 -11.6813,1.41398 6.6548,5.39657 5.312,15.53618 -5.7754,2.9525 -6.4909,1.94151 10.0792,20.7174 11.8877,28.74115 11.2917,20.12314 14.4477,43.50898 22.3348,64.94192 5.8098,15.78781 13.6934,29.6345 22.3551,43.97912 9.5882,15.87913 19.7814,31.59179 31.1869,46.15679 11.6035,54.34138 -4.3092,81.97365 -15.4445,111.81778 32.5872,16.89142 6.6287,16.78124 122.841,7.87434 z"
+           style="fill:url(#radialGradient4236);fill-opacity:1" />
+      </g>
+    </g>
+    <g
+       id="g4188"
+       inkscape:label="Layer 1"
+       transform="matrix(-0.88812969,0,0,0.77373787,530.91675,562.04598)"
+       style="fill:url(#radialGradient4246);fill-opacity:1;filter:url(#filter6593)">
+      <g
+         inkscape:export-ydpi="90"
+         inkscape:export-xdpi="90"
+         inkscape:export-filename="H:\new\rect2273.png"
+         style="fill:url(#radialGradient4244);fill-opacity:1"
+         transform="matrix(0.6938009,0,0,0.6938009,-870.0051,-393.95863)"
+         id="g4190">
+        <path
+           sodipodi:nodetypes="cccccccccccccccccccccccccccssccc"
+           id="path4192"
+           d="m 1326.7136,723.79257 c -17.8661,-5.1827 -3.8156,-26.068 -6.1451,-38.9613 2.6811,-18.56792 15.9987,-33.39896 20.3878,-51.57126 6.8606,-15.87369 6.0596,-29.18523 11.5484,-45.342 8.742,-12.02634 14.9181,-19.24974 18.6214,-31.78782 5.4989,-17.05962 9.7646,-28.6189 4.0387,-43.91235 -2.7035,-18.14405 -7.7047,-35.78277 -10.4398,-53.93215 -7.4171,-11.14202 5.8674,-36.22176 -5.2186,-41.10752 2.3197,22.42403 -5.0015,2.60799 -11.9276,11.6082 -7.0053,-5.59071 -5.4872,1.85751 -8.2299,3.91882 -5.932,-16.05448 -9.7357,-3.85379 -2.8631,5.00313 9.8818,12.56195 16.6266,32.14007 15.296,48.89211 3.6034,32.14781 4.038,28.50478 -5.8248,50.03316 -9.7308,11.67224 -15.2465,26.01488 -27.383,35.45938 -4.168,-0.62987 -35.1675,23.6385 -12.2279,-23.00045 3.7473,-12.40615 10.4687,-27.14869 -3.4638,-38.99508 -11.3759,-6.02073 -27.7425,-16.02154 -38.4941,-5.54071 -3.1119,16.39526 -10.7156,33.21291 -6.8445,50.16753 1.9278,7.23379 10.0675,25.98563 -4.5899,18.54624 -22.93,-21.01361 -16.6495,-14.53032 -50.9982,-44.99704 -11.9958,-9.6748 -14.597,-25.80379 -23.3684,-37.95453 -8.3733,-15.34917 -16.6062,-32.68858 -15.9268,-50.43155 -1.9069,-10.49015 7.0382,-31.20329 -6.6909,-20.54154 0.2582,-10.75897 -20.2058,-15.99327 -6.9602,-3.43085 6.5561,15.27727 -21.0159,-20.22468 -11.6813,1.41398 6.6548,5.39657 5.312,15.53618 -5.7754,2.9525 -6.4909,1.94151 10.0792,20.7174 11.8877,28.74115 11.2917,20.12314 14.4477,43.50898 22.3348,64.94192 5.8098,15.78781 13.6934,29.6345 22.3551,43.97912 9.5882,15.87913 19.7814,31.59179 31.1869,46.15679 11.6035,54.34138 -4.3092,81.97365 -15.4445,111.81778 32.5872,16.89142 6.6287,16.78124 122.841,7.87434 z"
+           style="fill:url(#radialGradient4242);fill-opacity:1" />
+      </g>
+    </g>
+    <g
+       id="g4194"
+       inkscape:label="Layer 1"
+       transform="matrix(0.76594607,0,0,0.76594607,334.6978,587.54216)"
+       style="fill:url(#radialGradient4252);fill-opacity:1;filter:url(#filter6609)">
+      <g
+         inkscape:export-ydpi="90"
+         inkscape:export-xdpi="90"
+         inkscape:export-filename="H:\new\rect2273.png"
+         style="fill:url(#radialGradient4250);fill-opacity:1"
+         transform="matrix(0.7844778,0,0,0.7844778,-1023.124,-443.46103)"
+         id="g4196">
+        <path
+           sodipodi:nodetypes="ccccccccccccccccccccccccccccccccccccsscccccccccccccccccccccccccc"
+           id="path4198"
+           d="m 1181.224,723.79257 c 17.8661,-5.1827 3.8156,-26.068 6.1451,-38.9613 -2.6811,-18.56792 -15.9987,-33.39896 -20.3878,-51.57126 -6.8606,-15.87369 -8.1323,-33.33072 -13.6211,-49.48749 -4.5966,-12.71726 -9.3908,-25.46798 -16.5487,-36.62423 -8.2626,-12.91413 -13.2192,-27.92799 -7.4933,-43.22144 2.7035,-18.14405 7.7047,-35.78277 10.4398,-53.93215 7.4171,-11.14202 -5.8674,-36.22176 5.2186,-41.10752 -2.3197,22.42403 5.0015,2.60799 11.9276,11.6082 7.0053,-5.59071 5.4872,1.85751 8.2299,3.91882 5.932,-16.05448 9.7357,-3.85379 2.8631,5.00313 -9.8818,12.56195 -16.6266,32.14007 -15.296,48.89211 -1.4747,7.65925 1.4117,26.30935 3.6016,7.87451 2.6364,-8.08828 3.9759,7.07011 6.1598,7.5432 -13.0443,13.63184 20.3862,-2.18868 6.6467,10.94557 -3.039,8.74305 -19.6494,14.16534 -10.5833,23.66988 9.7308,11.67224 15.9374,26.7058 28.0739,36.1503 4.168,-0.62987 17.2037,-10.21636 14.9916,-15.40038 -3.7473,-12.40615 -10.4687,-27.14869 3.4638,-38.99508 11.3759,-6.02073 27.7425,-16.02154 38.4941,-5.54071 3.1119,16.39526 10.7156,33.21291 6.8445,50.16753 -1.9278,7.23379 -10.0675,25.98563 4.5899,18.54624 16.5134,-6.70982 20.1994,-21.1921 21.762,-37.42171 2.7436,-15.10347 11.0587,-31.98909 2.3918,-46.56641 -5.3185,-7.59752 -4.9737,-18.57102 2.3855,-6.93359 4.5245,-4.57537 5.5908,-33.1298 8.0527,-13.59432 1.503,4.2079 6.7245,-11.21855 7.2771,2.5917 12.0837,11.81526 0.4373,26.77552 1.5752,40.85819 -0.014,7.78552 -4.7837,31.21381 7.5539,16.0691 11.9958,-9.6748 14.597,-25.80379 23.3684,-37.95453 8.3733,-15.34917 16.6062,-32.68858 15.9268,-50.43155 1.9069,-10.49015 -7.0382,-31.20329 6.6909,-20.54154 -0.2582,-10.75897 20.2058,-15.99327 6.9602,-3.43085 -6.5561,15.27727 21.0159,-20.22468 11.6813,1.41398 -6.6548,5.39657 -5.312,15.53618 5.7754,2.9525 6.4909,1.94151 -10.0792,20.7174 -11.8877,28.74115 -11.2917,20.12314 -14.4477,43.50898 -22.3348,64.94192 -5.8098,15.78781 -13.6934,29.6345 -22.3551,43.97912 -9.5882,15.87913 -19.7814,31.59179 -31.1869,46.15679 -8.9458,10.99517 14.8617,1.14758 21.0201,6.78637 12.518,-7.87375 29.385,-1.07316 31.7442,13.9051 8.5354,6.87189 -2.959,27.20699 4.826,28.253 6.9599,-8.35669 30.6898,-10.22278 16.3911,-23.6599 -4.8799,-13.60995 -13.4899,-32.95924 2.9589,-42.5777 18.9802,-11.06226 29.1286,12.4481 34.5443,24.513 -1.1144,6.3124 -10.9945,24.16482 1.2989,23.0916 11.9703,5.11124 17.1415,-2.56675 9.7766,-12.99185 -5.6125,-7.61373 -1.994,-15.69956 2.4401,-3.88548 5.3211,8.43408 -3.2996,-25.65986 4.9774,-6.97215 1.2142,-0.66102 4.7324,-10.09149 5.0899,1.39026 1.3293,10.43455 4.5795,7.41882 7.2281,0.22402 3.133,9.794 -0.6183,21.94637 3.857,31.04505 15.1548,17.0439 34.661,30.4834 46.3055,50.3897 2.0219,10.6027 -2.3476,23.8758 -9.9945,30.7373 -96.6193,-0.1457 -193.2469,0.4071 -289.8601,-0.5562 z m 273.9725,-30.6938 c -5.4576,-7.6635 -15.9194,-5.3671 -3.5491,0.3557 0.497,0.7237 3.5906,1.4873 3.5491,-0.3557 z m -137.0451,-21.3848 c 8.1886,-16.11829 -15.8898,-22.27477 -13.8783,-38.63465 -0.2795,-7.03902 -1.2234,-20.4328 -8.3873,-7.61676 -8.7788,6.78734 8.6785,17.01782 2.351,27.10748 1.7752,8.92004 -7.3166,21.13593 7.9872,20.12463 3.789,1.2155 9.1084,3.1197 11.9274,-0.9807 z"
+           style="fill:url(#radialGradient4248);fill-opacity:1" />
+      </g>
+    </g>
+    <g
+       id="g4200"
+       inkscape:label="Layer 1"
+       transform="matrix(0.88812969,0,0,0.75951536,146.19341,582.76899)"
+       style="fill:url(#radialGradient4258);fill-opacity:1;filter:url(#filter6781)">
+      <g
+         inkscape:export-ydpi="90"
+         inkscape:export-xdpi="90"
+         inkscape:export-filename="H:\new\rect2273.png"
+         style="fill:url(#radialGradient4256);fill-opacity:1"
+         transform="matrix(0.7844778,0,0,0.7844778,-1023.124,-443.46103)"
+         id="g4202">
+        <path
+           sodipodi:nodetypes="ccccccccccccccccccccccccccccccccccccsscccccccccccccccccccccccccc"
+           id="path4204"
+           d="m 1181.224,723.79257 c 17.8661,-5.1827 3.8156,-26.068 6.1451,-38.9613 -2.6811,-18.56792 -15.9987,-33.39896 -20.3878,-51.57126 -6.8606,-15.87369 -8.1323,-33.33072 -13.6211,-49.48749 -4.5966,-12.71726 -9.3908,-25.46798 -16.5487,-36.62423 -8.2626,-12.91413 -13.2192,-27.92799 -7.4933,-43.22144 2.7035,-18.14405 7.7047,-35.78277 10.4398,-53.93215 7.4171,-11.14202 -5.8674,-36.22176 5.2186,-41.10752 -2.3197,22.42403 5.0015,2.60799 11.9276,11.6082 7.0053,-5.59071 5.4872,1.85751 8.2299,3.91882 5.932,-16.05448 9.7357,-3.85379 2.8631,5.00313 -9.8818,12.56195 -16.6266,32.14007 -15.296,48.89211 -1.4747,7.65925 1.4117,26.30935 3.6016,7.87451 2.6364,-8.08828 3.9759,7.07011 6.1598,7.5432 -13.0443,13.63184 20.3862,-2.18868 6.6467,10.94557 -3.039,8.74305 -19.6494,14.16534 -10.5833,23.66988 9.7308,11.67224 15.9374,26.7058 28.0739,36.1503 4.168,-0.62987 17.2037,-10.21636 14.9916,-15.40038 -3.7473,-12.40615 -10.4687,-27.14869 3.4638,-38.99508 11.3759,-6.02073 27.7425,-16.02154 38.4941,-5.54071 3.1119,16.39526 10.7156,33.21291 6.8445,50.16753 -1.9278,7.23379 -10.0675,25.98563 4.5899,18.54624 16.5134,-6.70982 20.1994,-21.1921 21.762,-37.42171 2.7436,-15.10347 11.0587,-31.98909 2.3918,-46.56641 -5.3185,-7.59752 -4.9737,-18.57102 2.3855,-6.93359 4.5245,-4.57537 5.5908,-33.1298 8.0527,-13.59432 1.503,4.2079 6.7245,-11.21855 7.2771,2.5917 12.0837,11.81526 0.4373,26.77552 1.5752,40.85819 -0.014,7.78552 -4.7837,31.21381 7.5539,16.0691 11.9958,-9.6748 14.597,-25.80379 23.3684,-37.95453 8.3733,-15.34917 16.6062,-32.68858 15.9268,-50.43155 1.9069,-10.49015 -7.0382,-31.20329 6.6909,-20.54154 -0.2582,-10.75897 20.2058,-15.99327 6.9602,-3.43085 -6.5561,15.27727 21.0159,-20.22468 11.6813,1.41398 -6.6548,5.39657 -5.312,15.53618 5.7754,2.9525 6.4909,1.94151 -10.0792,20.7174 -11.8877,28.74115 -11.2917,20.12314 -14.4477,43.50898 -22.3348,64.94192 -5.8098,15.78781 -13.6934,29.6345 -22.3551,43.97912 -9.5882,15.87913 -19.7814,31.59179 -31.1869,46.15679 -8.9458,10.99517 14.8617,1.14758 21.0201,6.78637 12.518,-7.87375 29.385,-1.07316 31.7442,13.9051 8.5354,6.87189 -2.959,27.20699 4.826,28.253 6.9599,-8.35669 30.6898,-10.22278 16.3911,-23.6599 -4.8799,-13.60995 -13.4899,-32.95924 2.9589,-42.5777 18.9802,-11.06226 29.1286,12.4481 34.5443,24.513 -1.1144,6.3124 -10.9945,24.16482 1.2989,23.0916 11.9703,5.11124 17.1415,-2.56675 9.7766,-12.99185 -5.6125,-7.61373 -1.994,-15.69956 2.4401,-3.88548 5.3211,8.43408 -3.2996,-25.65986 4.9774,-6.97215 1.2142,-0.66102 4.7324,-10.09149 5.0899,1.39026 1.3293,10.43455 4.5795,7.41882 7.2281,0.22402 3.133,9.794 -0.6183,21.94637 3.857,31.04505 15.1548,17.0439 34.661,30.4834 46.3055,50.3897 2.0219,10.6027 -2.3476,23.8758 -9.9945,30.7373 -96.6193,-0.1457 -193.2469,0.4071 -289.8601,-0.5562 z m 273.9725,-30.6938 c -5.4576,-7.6635 -15.9194,-5.3671 -3.5491,0.3557 0.497,0.7237 3.5906,1.4873 3.5491,-0.3557 z m -137.0451,-21.3848 c 8.1886,-16.11829 -15.8898,-22.27477 -13.8783,-38.63465 -0.2795,-7.03902 -1.2234,-20.4328 -8.3873,-7.61676 -8.7788,6.78734 8.6785,17.01782 2.351,27.10748 1.7752,8.92004 -7.3166,21.13593 7.9872,20.12463 3.789,1.2155 9.1084,3.1197 11.9274,-0.9807 z"
+           style="fill:url(#radialGradient4254);fill-opacity:1" />
+      </g>
+    </g>
+    <g
+       id="g4206"
+       inkscape:label="Layer 1"
+       transform="matrix(-0.68430241,0,0,0.78803687,598.62179,591.5042)"
+       style="fill:url(#radialGradient4264);fill-opacity:1;filter:url(#filter6529)">
+      <g
+         inkscape:export-ydpi="90"
+         inkscape:export-xdpi="90"
+         inkscape:export-filename="H:\new\rect2273.png"
+         style="fill:url(#radialGradient4262);fill-opacity:1"
+         transform="matrix(0.6938009,0,0,0.6938009,-870.0051,-393.95863)"
+         id="g4208">
+        <path
+           sodipodi:nodetypes="cccccccccccccccccccccccccccssccc"
+           id="path4210"
+           d="m 1326.7136,723.79257 c -17.8661,-5.1827 -3.8156,-26.068 -6.1451,-38.9613 2.6811,-18.56792 15.9987,-33.39896 20.3878,-51.57126 6.8606,-15.87369 6.0596,-29.18523 11.5484,-45.342 8.742,-12.02634 14.9181,-19.24974 18.6214,-31.78782 5.4989,-17.05962 9.7646,-28.6189 4.0387,-43.91235 -2.7035,-18.14405 -7.7047,-35.78277 -10.4398,-53.93215 -7.4171,-11.14202 5.8674,-36.22176 -5.2186,-41.10752 2.3197,22.42403 -5.0015,2.60799 -11.9276,11.6082 -7.0053,-5.59071 -5.4872,1.85751 -8.2299,3.91882 -5.932,-16.05448 -9.7357,-3.85379 -2.8631,5.00313 9.8818,12.56195 16.6266,32.14007 15.296,48.89211 3.6034,32.14781 4.038,28.50478 -5.8248,50.03316 -9.7308,11.67224 -15.2465,26.01488 -27.383,35.45938 -4.168,-0.62987 -35.1675,23.6385 -12.2279,-23.00045 3.7473,-12.40615 10.4687,-27.14869 -3.4638,-38.99508 -11.3759,-6.02073 -27.7425,-16.02154 -38.4941,-5.54071 -3.1119,16.39526 -10.7156,33.21291 -6.8445,50.16753 1.9278,7.23379 10.0675,25.98563 -4.5899,18.54624 -22.93,-21.01361 -16.6495,-14.53032 -50.9982,-44.99704 -11.9958,-9.6748 -14.597,-25.80379 -23.3684,-37.95453 -8.3733,-15.34917 -16.6062,-32.68858 -15.9268,-50.43155 -1.9069,-10.49015 7.0382,-31.20329 -6.6909,-20.54154 0.2582,-10.75897 -20.2058,-15.99327 -6.9602,-3.43085 6.5561,15.27727 -21.0159,-20.22468 -11.6813,1.41398 6.6548,5.39657 5.312,15.53618 -5.7754,2.9525 -6.4909,1.94151 10.0792,20.7174 11.8877,28.74115 11.2917,20.12314 14.4477,43.50898 22.3348,64.94192 5.8098,15.78781 13.6934,29.6345 22.3551,43.97912 9.5882,15.87913 19.7814,31.59179 31.1869,46.15679 11.6035,54.34138 -4.3092,81.97365 -15.4445,111.81778 32.5872,16.89142 6.6287,16.78124 122.841,7.87434 z"
+           style="fill:url(#radialGradient4260);fill-opacity:1" />
+      </g>
+    </g>
+    <g
+       id="g4212"
+       inkscape:label="Layer 1"
+       transform="matrix(-0.88812969,0,0,0.88812969,669.51278,580.25934)"
+       style="fill:url(#radialGradient4270);fill-opacity:1;filter:url(#filter6415)">
+      <g
+         inkscape:export-ydpi="90"
+         inkscape:export-xdpi="90"
+         inkscape:export-filename="H:\new\rect2273.png"
+         style="fill:url(#radialGradient4268);fill-opacity:1"
+         transform="matrix(0.6938009,0,0,0.6938009,-870.0051,-393.95863)"
+         id="g4214">
+        <path
+           sodipodi:nodetypes="cccccccccccccccccccccccccccssccc"
+           id="path4216"
+           d="m 1326.7136,723.79257 c -17.8661,-5.1827 -3.8156,-26.068 -6.1451,-38.9613 2.6811,-18.56792 15.9987,-33.39896 20.3878,-51.57126 6.8606,-15.87369 6.0596,-29.18523 11.5484,-45.342 8.742,-12.02634 14.9181,-19.24974 18.6214,-31.78782 5.4989,-17.05962 9.7646,-28.6189 4.0387,-43.91235 -2.7035,-18.14405 -7.7047,-35.78277 -10.4398,-53.93215 -7.4171,-11.14202 5.8674,-36.22176 -5.2186,-41.10752 2.3197,22.42403 -5.0015,2.60799 -11.9276,11.6082 -7.0053,-5.59071 -5.4872,1.85751 -8.2299,3.91882 -5.932,-16.05448 -9.7357,-3.85379 -2.8631,5.00313 9.8818,12.56195 16.6266,32.14007 15.296,48.89211 3.6034,32.14781 4.038,28.50478 -5.8248,50.03316 -9.7308,11.67224 -15.2465,26.01488 -27.383,35.45938 -4.168,-0.62987 -35.1675,23.6385 -12.2279,-23.00045 3.7473,-12.40615 10.4687,-27.14869 -3.4638,-38.99508 -11.3759,-6.02073 -27.7425,-16.02154 -38.4941,-5.54071 -3.1119,16.39526 -10.7156,33.21291 -6.8445,50.16753 1.9278,7.23379 10.0675,25.98563 -4.5899,18.54624 -22.93,-21.01361 -16.6495,-14.53032 -50.9982,-44.99704 -11.9958,-9.6748 -14.597,-25.80379 -23.3684,-37.95453 -8.3733,-15.34917 -16.6062,-32.68858 -15.9268,-50.43155 -1.9069,-10.49015 7.0382,-31.20329 -6.6909,-20.54154 0.2582,-10.75897 -20.2058,-15.99327 -6.9602,-3.43085 6.5561,15.27727 -21.0159,-20.22468 -11.6813,1.41398 6.6548,5.39657 5.312,15.53618 -5.7754,2.9525 -6.4909,1.94151 10.0792,20.7174 11.8877,28.74115 11.2917,20.12314 14.4477,43.50898 22.3348,64.94192 5.8098,15.78781 13.6934,29.6345 22.3551,43.97912 9.5882,15.87913 19.7814,31.59179 31.1869,46.15679 11.6035,54.34138 -4.3092,81.97365 -15.4445,111.81778 32.5872,16.89142 6.6287,16.78124 122.841,7.87434 z"
+           style="fill:url(#radialGradient4266);fill-opacity:1" />
+      </g>
+    </g>
+    <g
+       id="g4218"
+       inkscape:label="Layer 1"
+       transform="matrix(0.91129181,0,0,0.93102658,947.10383,583.40541)"
+       style="fill:url(#radialGradient4276);fill-opacity:1;filter:url(#filter6693)">
+      <g
+         inkscape:export-ydpi="90"
+         inkscape:export-xdpi="90"
+         inkscape:export-filename="H:\new\rect2273.png"
+         style="fill:url(#radialGradient4274);fill-opacity:1"
+         transform="matrix(0.6938009,0,0,0.6938009,-870.0051,-393.95863)"
+         id="g4220">
+        <path
+           sodipodi:nodetypes="cccccccccccccccccccccccccccssccc"
+           id="path4222"
+           d="m 1326.7136,723.79257 c -17.8661,-5.1827 -3.8156,-26.068 -6.1451,-38.9613 2.6811,-18.56792 15.9987,-33.39896 20.3878,-51.57126 6.8606,-15.87369 6.0596,-29.18523 11.5484,-45.342 8.742,-12.02634 14.9181,-19.24974 18.6214,-31.78782 5.4989,-17.05962 9.7646,-28.6189 4.0387,-43.91235 -2.7035,-18.14405 -7.7047,-35.78277 -10.4398,-53.93215 -7.4171,-11.14202 5.8674,-36.22176 -5.2186,-41.10752 2.3197,22.42403 -5.0015,2.60799 -11.9276,11.6082 -7.0053,-5.59071 -5.4872,1.85751 -8.2299,3.91882 -5.932,-16.05448 -9.7357,-3.85379 -2.8631,5.00313 9.8818,12.56195 16.6266,32.14007 15.296,48.89211 3.6034,32.14781 4.038,28.50478 -5.8248,50.03316 -9.7308,11.67224 -15.2465,26.01488 -27.383,35.45938 -4.168,-0.62987 -35.1675,23.6385 -12.2279,-23.00045 3.7473,-12.40615 10.4687,-27.14869 -3.4638,-38.99508 -11.3759,-6.02073 -27.7425,-16.02154 -38.4941,-5.54071 -3.1119,16.39526 -10.7156,33.21291 -6.8445,50.16753 1.9278,7.23379 10.0675,25.98563 -4.5899,18.54624 -22.93,-21.01361 -16.6495,-14.53032 -50.9982,-44.99704 -11.9958,-9.6748 -14.597,-25.80379 -23.3684,-37.95453 -8.3733,-15.34917 -16.6062,-32.68858 -15.9268,-50.43155 -1.9069,-10.49015 7.0382,-31.20329 -6.6909,-20.54154 0.2582,-10.75897 -20.2058,-15.99327 -6.9602,-3.43085 6.5561,15.27727 -21.0159,-20.22468 -11.6813,1.41398 6.6548,5.39657 5.312,15.53618 -5.7754,2.9525 -6.4909,1.94151 10.0792,20.7174 11.8877,28.74115 11.2917,20.12314 14.4477,43.50898 22.3348,64.94192 5.8098,15.78781 13.6934,29.6345 22.3551,43.97912 9.5882,15.87913 19.7814,31.59179 31.1869,46.15679 11.6035,54.34138 -4.3092,81.97365 -15.4445,111.81778 32.5872,16.89142 6.6287,16.78124 122.841,7.87434 z"
+           style="fill:url(#radialGradient4272);fill-opacity:1" />
+      </g>
+    </g>
+    <g
+       id="g4224"
+       inkscape:label="Layer 1"
+       transform="matrix(0.88812969,0,0,0.84311465,808.10889,574.72565)"
+       style="fill:url(#radialGradient4282);fill-opacity:1;filter:url(#filter6557)">
+      <g
+         inkscape:export-ydpi="90"
+         inkscape:export-xdpi="90"
+         inkscape:export-filename="H:\new\rect2273.png"
+         style="fill:url(#radialGradient4280);fill-opacity:1"
+         transform="matrix(0.7844778,0,0,0.7844778,-1023.124,-443.46103)"
+         id="g4226">
+        <path
+           sodipodi:nodetypes="ccccccccccccccccccccccccccccccccccccsscccccccccccccccccccccccccc"
+           id="path4228"
+           d="m 1181.224,723.79257 c 17.8661,-5.1827 3.8156,-26.068 6.1451,-38.9613 -2.6811,-18.56792 -15.9987,-33.39896 -20.3878,-51.57126 -6.8606,-15.87369 -8.1323,-33.33072 -13.6211,-49.48749 -4.5966,-12.71726 -9.3908,-25.46798 -16.5487,-36.62423 -8.2626,-12.91413 -13.2192,-27.92799 -7.4933,-43.22144 2.7035,-18.14405 7.7047,-35.78277 10.4398,-53.93215 7.4171,-11.14202 -5.8674,-36.22176 5.2186,-41.10752 -2.3197,22.42403 5.0015,2.60799 11.9276,11.6082 7.0053,-5.59071 5.4872,1.85751 8.2299,3.91882 5.932,-16.05448 9.7357,-3.85379 2.8631,5.00313 -9.8818,12.56195 -16.6266,32.14007 -15.296,48.89211 -1.4747,7.65925 1.4117,26.30935 3.6016,7.87451 2.6364,-8.08828 3.9759,7.07011 6.1598,7.5432 -13.0443,13.63184 20.3862,-2.18868 6.6467,10.94557 -3.039,8.74305 -19.6494,14.16534 -10.5833,23.66988 9.7308,11.67224 15.9374,26.7058 28.0739,36.1503 4.168,-0.62987 17.2037,-10.21636 14.9916,-15.40038 -3.7473,-12.40615 -10.4687,-27.14869 3.4638,-38.99508 11.3759,-6.02073 27.7425,-16.02154 38.4941,-5.54071 3.1119,16.39526 10.7156,33.21291 6.8445,50.16753 -1.9278,7.23379 -10.0675,25.98563 4.5899,18.54624 16.5134,-6.70982 20.1994,-21.1921 21.762,-37.42171 2.7436,-15.10347 11.0587,-31.98909 2.3918,-46.56641 -5.3185,-7.59752 -4.9737,-18.57102 2.3855,-6.93359 4.5245,-4.57537 5.5908,-33.1298 8.0527,-13.59432 1.503,4.2079 6.7245,-11.21855 7.2771,2.5917 12.0837,11.81526 0.4373,26.77552 1.5752,40.85819 -0.014,7.78552 -4.7837,31.21381 7.5539,16.0691 11.9958,-9.6748 14.597,-25.80379 23.3684,-37.95453 8.3733,-15.34917 16.6062,-32.68858 15.9268,-50.43155 1.9069,-10.49015 -7.0382,-31.20329 6.6909,-20.54154 -0.2582,-10.75897 20.2058,-15.99327 6.9602,-3.43085 -6.5561,15.27727 21.0159,-20.22468 11.6813,1.41398 -6.6548,5.39657 -5.312,15.53618 5.7754,2.9525 6.4909,1.94151 -10.0792,20.7174 -11.8877,28.74115 -11.2917,20.12314 -14.4477,43.50898 -22.3348,64.94192 -5.8098,15.78781 -13.6934,29.6345 -22.3551,43.97912 -9.5882,15.87913 -19.7814,31.59179 -31.1869,46.15679 -8.9458,10.99517 14.8617,1.14758 21.0201,6.78637 12.518,-7.87375 29.385,-1.07316 31.7442,13.9051 8.5354,6.87189 -2.959,27.20699 4.826,28.253 6.9599,-8.35669 30.6898,-10.22278 16.3911,-23.6599 -4.8799,-13.60995 -13.4899,-32.95924 2.9589,-42.5777 18.9802,-11.06226 29.1286,12.4481 34.5443,24.513 -1.1144,6.3124 -10.9945,24.16482 1.2989,23.0916 11.9703,5.11124 17.1415,-2.56675 9.7766,-12.99185 -5.6125,-7.61373 -1.994,-15.69956 2.4401,-3.88548 5.3211,8.43408 -3.2996,-25.65986 4.9774,-6.97215 1.2142,-0.66102 4.7324,-10.09149 5.0899,1.39026 1.3293,10.43455 4.5795,7.41882 7.2281,0.22402 3.133,9.794 -0.6183,21.94637 3.857,31.04505 15.1548,17.0439 34.661,30.4834 46.3055,50.3897 2.0219,10.6027 -2.3476,23.8758 -9.9945,30.7373 -96.6193,-0.1457 -193.2469,0.4071 -289.8601,-0.5562 z m 273.9725,-30.6938 c -5.4576,-7.6635 -15.9194,-5.3671 -3.5491,0.3557 0.497,0.7237 3.5906,1.4873 3.5491,-0.3557 z m -137.0451,-21.3848 c 8.1886,-16.11829 -15.8898,-22.27477 -13.8783,-38.63465 -0.2795,-7.03902 -1.2234,-20.4328 -8.3873,-7.61676 -8.7788,6.78734 8.6785,17.01782 2.351,27.10748 1.7752,8.92004 -7.3166,21.13593 7.9872,20.12463 3.789,1.2155 9.1084,3.1197 11.9274,-0.9807 z"
+           style="fill:url(#radialGradient4278);fill-opacity:1" />
+      </g>
+    </g>
+  </g>
+  <rect
+     style="fill:url(#linearGradient4292);fill-opacity:1;stroke:none"
+     id="rect4284"
+     width="1039.8888"
+     height="207.67305"
+     x="-17.822344"
+     y="598.43079" />
+  <rect
+     style="fill:#000000;fill-opacity:1;stroke:none"
+     id="rect4298"
+     width="1039.8888"
+     height="145.90706"
+     x="-17.822344"
+     y="-35.971493" />
+</svg>
diff --git a/data/backgrounds/flying_notes.svg b/data/backgrounds/flying_notes.svg
new file mode 100644 (file)
index 0000000..95850a0
--- /dev/null
@@ -0,0 +1,334 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://creativecommons.org/ns#"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:xlink="http://www.w3.org/1999/xlink"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   width="1280"
+   height="800"
+   id="svg1901"
+   sodipodi:version="0.32"
+   inkscape:version="0.48.0 r9654"
+   sodipodi:docname="flying_notes.svg"
+   version="1.1">
+  <defs
+     id="defs1903">
+    <linearGradient
+       id="linearGradient3905">
+      <stop
+         style="stop-color:#ffe000;stop-opacity:1;"
+         offset="0"
+         id="stop3907" />
+      <stop
+         style="stop-color:#ff6900;stop-opacity:1;"
+         offset="1"
+         id="stop3909" />
+    </linearGradient>
+    <linearGradient
+       id="linearGradient3752">
+      <stop
+         style="stop-color:#ffd231;stop-opacity:1;"
+         offset="0"
+         id="stop3754" />
+      <stop
+         style="stop-color:#ff7600;stop-opacity:1;"
+         offset="1"
+         id="stop3756" />
+    </linearGradient>
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient3752"
+       id="linearGradient3760"
+       x1="927.14288"
+       y1="320.93362"
+       x2="158.57146"
+       y2="963.79077"
+       gradientUnits="userSpaceOnUse" />
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient3905"
+       id="linearGradient3911"
+       x1="44.101855"
+       y1="118.35866"
+       x2="185.40168"
+       y2="118.35866"
+       gradientUnits="userSpaceOnUse" />
+    <linearGradient
+       id="linearGradient3905-3">
+      <stop
+         style="stop-color:#ffe000;stop-opacity:1;"
+         offset="0"
+         id="stop3907-0" />
+      <stop
+         style="stop-color:#ff6900;stop-opacity:1;"
+         offset="1"
+         id="stop3909-7" />
+    </linearGradient>
+    <linearGradient
+       y2="159.76331"
+       x2="171.80338"
+       y1="84.621536"
+       x1="49.54118"
+       gradientUnits="userSpaceOnUse"
+       id="linearGradient3928"
+       xlink:href="#linearGradient3905-3"
+       inkscape:collect="always" />
+    <linearGradient
+       id="linearGradient3905-0">
+      <stop
+         style="stop-color:#ffe000;stop-opacity:1;"
+         offset="0"
+         id="stop3907-7" />
+      <stop
+         style="stop-color:#ff6900;stop-opacity:1;"
+         offset="1"
+         id="stop3909-2" />
+    </linearGradient>
+    <linearGradient
+       y2="118.35866"
+       x2="185.40169"
+       y1="118.35866"
+       x1="44.101856"
+       gradientUnits="userSpaceOnUse"
+       id="linearGradient3928-3"
+       xlink:href="#linearGradient3905-0"
+       inkscape:collect="always" />
+    <linearGradient
+       id="linearGradient3905-6">
+      <stop
+         style="stop-color:#ffe000;stop-opacity:1;"
+         offset="0"
+         id="stop3907-07" />
+      <stop
+         style="stop-color:#ff6900;stop-opacity:1;"
+         offset="1"
+         id="stop3909-3" />
+    </linearGradient>
+    <linearGradient
+       y2="69.003647"
+       x2="174.91753"
+       y1="129.32645"
+       x1="65.07016"
+       gradientUnits="userSpaceOnUse"
+       id="linearGradient3928-6"
+       xlink:href="#linearGradient3905-6"
+       inkscape:collect="always" />
+  </defs>
+  <sodipodi:namedview
+     id="base"
+     pagecolor="#ffffff"
+     bordercolor="#666666"
+     borderopacity="1.0"
+     inkscape:pageopacity="0.0"
+     inkscape:pageshadow="2"
+     inkscape:zoom="0.7"
+     inkscape:cx="638.46604"
+     inkscape:cy="387.38216"
+     inkscape:document-units="px"
+     inkscape:current-layer="layer1"
+     inkscape:window-width="1480"
+     inkscape:window-height="843"
+     inkscape:window-x="145"
+     inkscape:window-y="129"
+     showgrid="false"
+     inkscape:window-maximized="0" />
+  <metadata
+     id="metadata1906">
+    <rdf:RDF>
+      <cc:Work
+         rdf:about="">
+        <dc:format>image/svg+xml</dc:format>
+        <dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+        <dc:title />
+      </cc:Work>
+    </rdf:RDF>
+  </metadata>
+  <g
+     inkscape:label="Taso 1"
+     inkscape:groupmode="layer"
+     id="layer1"
+     transform="translate(0,-252.36218)">
+    <rect
+       style="fill:url(#linearGradient3760);fill-rule:evenodd;stroke:#000000;stroke-width:0.99898540999999996;stroke-opacity:1;fill-opacity:1"
+       id="rect2982"
+       width="1279.001"
+       height="799.00104"
+       x="0.4994927"
+       y="252.86165" />
+    <g
+       id="layer1-2"
+       transform="matrix(2.3382286,-0.69794294,0.93580254,1.7439042,-717.83419,433.76858)">
+      <path
+         style="fill:#000000;fill-opacity:1;stroke:none"
+         id="path2159"
+         d="m 218.57946,368.81594 c -18.68248,-12.87627 -30.13055,0.34948 -27.1493,16.99614 1.91308,10.68237 18.46167,20.61154 32.20704,1.42146 2.00075,-20.7316 4.62327,-41.56303 6.62403,-62.29463 21.12743,22.43771 14.38019,36.01294 10.01214,51.64531 8.98015,-4.45792 23.04606,-24.13948 7.67882,-51.89958 -7.27191,-12.29741 -6.58964,-3.61429 -13.63362,-28.14454 -2.48328,-0.49406 -4.96657,-0.98812 -7.44985,-1.48217 -2.96066,25.27836 -5.3286,48.47964 -8.28926,73.75801 z"
+         inkscape:connector-curvature="0" />
+    </g>
+    <g
+       id="layer1-2-2"
+       transform="matrix(1.3436196,-0.51378089,0.5377415,1.2837507,-18.62594,233.84302)">
+      <path
+         style="fill:#000000;fill-opacity:1;stroke:none"
+         id="path2159-5"
+         d="m 274.83608,339.25503 c -2.60293,-19.66526 -16.1199,-18.06094 -23.94306,-5.48699 -5.02024,8.06884 -1.88104,24.53326 16.21736,20.46638 12.76226,-12.19178 25.90946,-24.07075 38.67172,-36.26252 -1.50336,27.33206 -12.73346,32.01542 -23.86773,39.47302 7.26251,2.56754 25.80779,-1.62261 33.36014,-28.9004 3.10018,-12.3656 -1.44171,-6.33658 8.68553,-26.47421 -1.03336,-1.82664 -2.06672,-3.65329 -3.10008,-5.47993 -15.8366,14.54935 -30.18726,28.11529 -46.02388,42.66465 z"
+         inkscape:connector-curvature="0" />
+    </g>
+    <g
+       id="layer1-8"
+       transform="matrix(0.29488438,0,0,0.26870123,329.38685,476.68223)">
+      <path
+         style="fill:#000000;fill-opacity:1;stroke:none"
+         id="path5076"
+         d="m 409.12315,637.11709 c -136.80609,-1.54759 -166.4007,94.83508 -107.09079,162.34156 38.05994,43.3198 155.44807,37.88525 182.479,-93.09694 L 310.87414,255.27491 c -15.05728,5.40597 -30.11462,10.81199 -45.17188,16.21804 48.48825,125.67736 94.93261,239.9468 143.42089,365.62414 z"
+         inkscape:connector-curvature="0" />
+    </g>
+    <g
+       id="layer1-9"
+       transform="matrix(0.13446628,-0.04333757,0.03840384,0.11915808,614.91287,410.68409)">
+      <path
+         style="fill:#000000;fill-opacity:1;stroke:none"
+         id="path5065"
+         d="m 374.44027,235.14714 c -28.09375,122.13341 -59.79626,271.36767 -87.88998,393.50115 -104.64634,-72.4596 -177.63194,-13.56495 -167.08109,69.36663 6.77066,53.21823 100.11352,110.19707 189.18223,23.31493 16.55572,-80.97898 46.36721,-214.48243 68.94394,-319.25223 l 164.99181,117.07957 c -16.83818,75.89794 -33.38271,151.30022 -51.511,230.1103 -104.64627,-72.4596 -177.70447,-13.58063 -167.15361,69.35096 6.77068,53.21822 100.12906,110.12465 189.19778,23.2425 L 614.20931,403.76291 c -0.67183,-0.17126 -1.34401,-0.33661 -2.01583,-0.50786 l 0.20729,-0.25911 C 597.91963,391.58023 388.86286,238.8239 374.44027,235.14714 z m 19.70186,90.42226 165.12136,119.30791 c -2.51106,11.12859 -4.94588,22.14141 -7.41055,33.16529 L 386.6383,360.23232 c 2.13232,-10.11484 5.70651,-25.87164 7.50383,-34.66292 z"
+         inkscape:connector-curvature="0" />
+    </g>
+    <g
+       id="layer1-9-3"
+       transform="matrix(0.1131453,0.01162684,-0.01073483,0.09623289,767.96953,369.75807)">
+      <path
+         style="fill:#000000;fill-opacity:1;stroke:none"
+         id="path5065-4"
+         d="m 374.44027,235.14714 c -28.09375,122.13341 -59.79626,271.36767 -87.88998,393.50115 -104.64634,-72.4596 -177.63194,-13.56495 -167.08109,69.36663 6.77066,53.21823 100.11352,110.19707 189.18223,23.31493 16.55572,-80.97898 46.36721,-214.48243 68.94394,-319.25223 l 164.99181,117.07957 c -16.83818,75.89794 -33.38271,151.30022 -51.511,230.1103 -104.64627,-72.4596 -177.70447,-13.58063 -167.15361,69.35096 6.77068,53.21822 100.12906,110.12465 189.19778,23.2425 L 614.20931,403.76291 c -0.67183,-0.17126 -1.34401,-0.33661 -2.01583,-0.50786 l 0.20729,-0.25911 C 597.91963,391.58023 388.86286,238.8239 374.44027,235.14714 z m 19.70186,90.42226 165.12136,119.30791 c -2.51106,11.12859 -4.94588,22.14141 -7.41055,33.16529 L 386.6383,360.23232 c 2.13232,-10.11484 5.70651,-25.87164 7.50383,-34.66292 z"
+         inkscape:connector-curvature="0" />
+    </g>
+    <g
+       id="layer1-9-1"
+       transform="matrix(0.26823199,-0.02623845,0.02571071,0.21495865,143.91667,564.53479)">
+      <path
+         style="fill:#000000;fill-opacity:1;stroke:none"
+         id="path5065-7"
+         d="m 374.44027,235.14714 c -28.09375,122.13341 -59.79626,271.36767 -87.88998,393.50115 -104.64634,-72.4596 -177.63194,-13.56495 -167.08109,69.36663 6.77066,53.21823 100.11352,110.19707 189.18223,23.31493 16.55572,-80.97898 46.36721,-214.48243 68.94394,-319.25223 l 164.99181,117.07957 c -16.83818,75.89794 -33.38271,151.30022 -51.511,230.1103 -104.64627,-72.4596 -177.70447,-13.58063 -167.15361,69.35096 6.77068,53.21822 100.12906,110.12465 189.19778,23.2425 L 614.20931,403.76291 c -0.67183,-0.17126 -1.34401,-0.33661 -2.01583,-0.50786 l 0.20729,-0.25911 C 597.91963,391.58023 388.86286,238.8239 374.44027,235.14714 z m 19.70186,90.42226 165.12136,119.30791 c -2.51106,11.12859 -4.94588,22.14141 -7.41055,33.16529 L 386.6383,360.23232 c 2.13232,-10.11484 5.70651,-25.87164 7.50383,-34.66292 z"
+         inkscape:connector-curvature="0" />
+    </g>
+    <g
+       id="layer1-8-4"
+       transform="matrix(0.27948313,0.24353958,-0.20359786,0.2762579,349.50348,551.9365)">
+      <path
+         style="fill:#000000;fill-opacity:1;stroke:none"
+         id="path5076-6"
+         d="m 409.12315,637.11709 c -136.80609,-1.54759 -166.4007,94.83508 -107.09079,162.34156 38.05994,43.3198 155.44807,37.88525 182.479,-93.09694 L 310.87414,255.27491 c -15.05728,5.40597 -30.11462,10.81199 -45.17188,16.21804 48.48825,125.67736 94.93261,239.9468 143.42089,365.62414 z"
+         inkscape:connector-curvature="0" />
+    </g>
+    <g
+       id="layer1-2-2-4"
+       transform="matrix(0.5931245,-0.36389074,0.35328484,0.63766008,609.41289,278.9766)"
+       inkscape:transform-center-x="-18.913802">
+      <path
+         style="fill:#000000;fill-opacity:1;stroke:none"
+         id="path2159-5-1"
+         d="m 274.83608,339.25503 c -2.60293,-19.66526 -16.1199,-18.06094 -23.94306,-5.48699 -5.02024,8.06884 -1.88104,24.53326 16.21736,20.46638 12.76226,-12.19178 25.90946,-24.07075 38.67172,-36.26252 -1.50336,27.33206 -12.73346,32.01542 -23.86773,39.47302 7.26251,2.56754 25.80779,-1.62261 33.36014,-28.9004 3.10018,-12.3656 -1.44171,-6.33658 8.68553,-26.47421 -1.03336,-1.82664 -2.06672,-3.65329 -3.10008,-5.47993 -15.8366,14.54935 -30.18726,28.11529 -46.02388,42.66465 z"
+         inkscape:connector-curvature="0" />
+    </g>
+    <path
+       sodipodi:type="star"
+       style="opacity:0.75;fill:url(#linearGradient3911);fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:0;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+       id="path3901"
+       sodipodi:sides="5"
+       sodipodi:cx="108.57143"
+       sodipodi:cy="117.14286"
+       sodipodi:r1="76.930923"
+       sodipodi:r2="33.122696"
+       sodipodi:arg1="1.3078016"
+       sodipodi:arg2="1.9361201"
+       inkscape:flatsided="false"
+       inkscape:rounded="0"
+       inkscape:randomized="0"
+       d="M 128.57143,191.42857 96.738286,148.07973 44.101855,159.11954 75.492075,115.44889 48.727041,68.800161 99.960403,85.159063 136.05513,45.288752 l 0.27374,53.781002 49.07281,22.007526 -51.06419,16.87958 z"
+       transform="matrix(1.5762822,0,0,1.4985441,934.58489,739.78374)"
+       inkscape:transform-center-x="32.644854"
+       inkscape:transform-center-y="8.0869362" />
+    <path
+       sodipodi:type="star"
+       style="opacity:0.66;fill:url(#linearGradient3928);fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:0;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+       id="path3901-1"
+       sodipodi:sides="5"
+       sodipodi:cx="108.57143"
+       sodipodi:cy="117.14286"
+       sodipodi:r1="76.930923"
+       sodipodi:r2="33.122696"
+       sodipodi:arg1="1.3078016"
+       sodipodi:arg2="1.9361201"
+       inkscape:flatsided="false"
+       inkscape:rounded="0"
+       inkscape:randomized="0"
+       d="M 128.57143,191.42857 96.738286,148.07973 44.101855,159.11954 75.492075,115.44889 48.727041,68.800161 99.960403,85.159063 136.05513,45.288752 l 0.27374,53.781002 49.07281,22.007526 -51.06419,16.87958 z"
+       transform="matrix(0.83148904,-0.64209313,0.56937377,0.73731991,740.51855,843.88193)"
+       inkscape:transform-center-x="25.559331"
+       inkscape:transform-center-y="21.208229" />
+    <path
+       sodipodi:type="star"
+       style="opacity:0.5;fill:url(#linearGradient3928-3);fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:0;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+       id="path3901-3"
+       sodipodi:sides="5"
+       sodipodi:cx="108.57143"
+       sodipodi:cy="117.14286"
+       sodipodi:r1="76.930923"
+       sodipodi:r2="33.122696"
+       sodipodi:arg1="1.3078016"
+       sodipodi:arg2="1.9361201"
+       inkscape:flatsided="false"
+       inkscape:rounded="0"
+       inkscape:randomized="0"
+       d="M 128.57143,191.42857 96.738286,148.07973 44.101855,159.11954 75.492075,115.44889 48.727041,68.800161 99.960403,85.159063 136.05513,45.288752 l 0.27374,53.781002 49.07281,22.007526 -51.06419,16.87958 z"
+       transform="matrix(0.32877262,-0.67772342,0.64542271,0.28213266,603.70917,891.6636)"
+       inkscape:transform-center-x="4.3202496"
+       inkscape:transform-center-y="21.691705" />
+    <path
+       sodipodi:type="star"
+       style="opacity:0.50000000000000000;fill:url(#linearGradient3928-6);fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:0;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+       id="path3901-5"
+       sodipodi:sides="5"
+       sodipodi:cx="108.57143"
+       sodipodi:cy="117.14286"
+       sodipodi:r1="76.930923"
+       sodipodi:r2="33.122696"
+       sodipodi:arg1="1.3078016"
+       sodipodi:arg2="1.9361201"
+       inkscape:flatsided="false"
+       inkscape:rounded="0"
+       inkscape:randomized="0"
+       d="M 128.57143,191.42857 96.738286,148.07973 44.101855,159.11954 75.492075,115.44889 48.727041,68.800161 99.960403,85.159063 136.05513,45.288752 l 0.27374,53.781002 49.07281,22.007526 -51.06419,16.87958 z"
+       transform="matrix(0.54504037,0,0,0.52100668,496.02709,800.69653)"
+       inkscape:transform-center-x="11.287802"
+       inkscape:transform-center-y="2.8116293" />
+    <path
+       style="fill:#000000;fill-opacity:1;stroke:none"
+       id="path2159-5-1-7"
+       d="m 966.42711,405.14573 c -6.56724,-8.28801 -12.32948,-4.04003 -12.48256,3.72757 -0.0982,4.98457 5.84045,11.67383 13.03145,5.1113 2.52317,-8.87834 5.30844,-17.71422 7.83161,-26.59255 6.77848,12.85151 2.90658,17.90823 -0.16342,24.20477 4.0331,-0.71891 11.3954,-7.4539 7.4067,-21.85438 -1.9565,-6.44389 -2.3927,-2.51371 -3.2494,-14.32895 -0.9731,-0.5639 -1.9462,-1.12781 -2.9194,-1.69172 -3.28929,10.75295 -6.16567,20.67099 -9.45498,31.42396 z"
+       inkscape:connector-curvature="0" />
+    <g
+       id="layer1-8-6"
+       transform="matrix(0.08874176,0.02606366,-0.01977386,0.06732619,1002.3805,301.2627)">
+      <path
+         style="fill:#000000;fill-opacity:1;stroke:none"
+         id="path5076-5"
+         d="m 409.12315,637.11709 c -136.80609,-1.54759 -166.4007,94.83508 -107.09079,162.34156 38.05994,43.3198 155.44807,37.88525 182.479,-93.09694 L 310.87414,255.27491 c -15.05728,5.40597 -30.11462,10.81199 -45.17188,16.21804 48.48825,125.67736 94.93261,239.9468 143.42089,365.62414 z"
+         inkscape:connector-curvature="0" />
+    </g>
+    <g
+       id="layer1-8-6-5"
+       transform="matrix(0.07019619,0.06022383,-0.04569034,0.05325612,1069.5814,258.80887)">
+      <path
+         style="fill:#000000;fill-opacity:1;stroke:none"
+         id="path5076-5-5"
+         d="m 409.12315,637.11709 c -136.80609,-1.54759 -166.4007,94.83508 -107.09079,162.34156 38.05994,43.3198 155.44807,37.88525 182.479,-93.09694 L 310.87414,255.27491 c -15.05728,5.40597 -30.11462,10.81199 -45.17188,16.21804 48.48825,125.67736 94.93261,239.9468 143.42089,365.62414 z"
+         inkscape:connector-curvature="0" />
+    </g>
+  </g>
+</svg>
diff --git a/data/backgrounds/guitar_bg.svg b/data/backgrounds/guitar_bg.svg
new file mode 100644 (file)
index 0000000..ebd9f0c
--- /dev/null
@@ -0,0 +1,331 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Sodipodi ("http://www.sodipodi.com/") -->
+
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://creativecommons.org/ns#"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:xlink="http://www.w3.org/1999/xlink"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   version="1.0"
+   x="0"
+   y="0"
+   width="1000"
+   height="800"
+   id="svg559"
+   sodipodi:version="0.32"
+   inkscape:version="0.48.1 r9760"
+   sodipodi:docname="guitar_bg.svg"
+   inkscape:output_extension="org.inkscape.output.svg.inkscape">
+  <metadata
+     id="metadata35">
+    <rdf:RDF>
+      <cc:Work
+         rdf:about="">
+        <dc:format>image/svg+xml</dc:format>
+        <dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+        <dc:title />
+      </cc:Work>
+    </rdf:RDF>
+  </metadata>
+  <sodipodi:namedview
+     inkscape:window-height="1026"
+     inkscape:window-width="1626"
+     inkscape:pageshadow="2"
+     inkscape:pageopacity="0.0"
+     guidetolerance="10.0"
+     gridtolerance="10.0"
+     objecttolerance="10.0"
+     borderopacity="1.0"
+     bordercolor="#666666"
+     pagecolor="#ffffff"
+     id="base"
+     inkscape:zoom="0.61522535"
+     inkscape:cx="416.18137"
+     inkscape:cy="566.15726"
+     inkscape:window-x="54"
+     inkscape:window-y="24"
+     inkscape:current-layer="svg559"
+     showgrid="false"
+     showguides="true"
+     inkscape:guide-bbox="true"
+     inkscape:window-maximized="1" />
+  <defs
+     id="defs561">
+    <linearGradient
+       id="linearGradient3893">
+      <stop
+         id="stop3895"
+         offset="0"
+         style="stop-color:#32e4ff;stop-opacity:1;" />
+      <stop
+         id="stop3897"
+         offset="1"
+         style="stop-color:#0000ff;stop-opacity:0;" />
+    </linearGradient>
+    <linearGradient
+       id="linearGradient3835">
+      <stop
+         style="stop-color:#3232ff;stop-opacity:1;"
+         offset="0"
+         id="stop3837" />
+      <stop
+         style="stop-color:#0000ff;stop-opacity:0;"
+         offset="1"
+         id="stop3839" />
+    </linearGradient>
+    <linearGradient
+       id="linearGradient3819">
+      <stop
+         style="stop-color:#879fbe;stop-opacity:1;"
+         offset="0"
+         id="stop3821" />
+      <stop
+         style="stop-color:#1f2c66;stop-opacity:0;"
+         offset="1"
+         id="stop3823" />
+    </linearGradient>
+    <linearGradient
+       id="linearGradient3941">
+      <stop
+         style="stop-color:#ffffff;stop-opacity:0.27388534;"
+         offset="0"
+         id="stop3943" />
+      <stop
+         style="stop-color:#ffffff;stop-opacity:0;"
+         offset="1"
+         id="stop3945" />
+    </linearGradient>
+    <linearGradient
+       id="linearGradient3856">
+      <stop
+         style="stop-color:#101010;stop-opacity:1;"
+         offset="0"
+         id="stop3858" />
+      <stop
+         style="stop-color:#181818;stop-opacity:0.22929937;"
+         offset="1"
+         id="stop3860" />
+    </linearGradient>
+    <radialGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient3819"
+       id="radialGradient3825"
+       cx="166.40443"
+       cy="669.5387"
+       fx="166.40443"
+       fy="669.5387"
+       r="532.3253"
+       gradientTransform="matrix(0.78201664,-0.74648279,0.29264917,0.30657977,-130.20775,573.81603)"
+       gradientUnits="userSpaceOnUse" />
+    <linearGradient
+       y2="449.80624"
+       x2="381.28015"
+       y1="684.16162"
+       x1="665.12128"
+       gradientTransform="matrix(0.336682,0,0,0.336682,-81.3739,-51.8729)"
+       gradientUnits="userSpaceOnUse"
+       id="linearGradient3484"
+       xlink:href="#linearGradient3751-2"
+       inkscape:collect="always" />
+    <linearGradient
+       inkscape:collect="always"
+       id="linearGradient3751-2">
+      <stop
+         style="stop-color:black;stop-opacity:1;"
+         offset="0"
+         id="stop3753-4" />
+      <stop
+         style="stop-color:black;stop-opacity:0;"
+         offset="1"
+         id="stop3755-7" />
+    </linearGradient>
+    <inkscape:perspective
+       id="perspective17"
+       inkscape:persp3d-origin="128 : 85.333333 : 1"
+       inkscape:vp_z="256 : 128 : 1"
+       inkscape:vp_y="0 : 1000 : 0"
+       inkscape:vp_x="0 : 128 : 1"
+       sodipodi:type="inkscape:persp3d" />
+    <filter
+       inkscape:collect="always"
+       id="filter3798"
+       x="-0.40963855"
+       width="1.8192771"
+       y="-0.40963855"
+       height="1.8192771">
+      <feGaussianBlur
+         inkscape:collect="always"
+         stdDeviation="0.97100936"
+         id="feGaussianBlur3800" />
+    </filter>
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient3835"
+       id="linearGradient3841"
+       x1="128.72675"
+       y1="140.27541"
+       x2="275.84305"
+       y2="381.63806"
+       gradientUnits="userSpaceOnUse" />
+    <filter
+       inkscape:collect="always"
+       id="filter3853"
+       x="-0.10079435"
+       width="1.2015887"
+       y="-0.083886182"
+       height="1.1677724">
+      <feGaussianBlur
+         inkscape:collect="always"
+         stdDeviation="15.837691"
+         id="feGaussianBlur3855" />
+    </filter>
+    <filter
+       inkscape:collect="always"
+       id="filter3869"
+       x="-0.11588358"
+       width="1.2317672"
+       y="-0.11544256"
+       height="1.2308851">
+      <feGaussianBlur
+         inkscape:collect="always"
+         stdDeviation="6.5926282"
+         id="feGaussianBlur3871" />
+    </filter>
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient3893"
+       id="linearGradient3883"
+       gradientUnits="userSpaceOnUse"
+       x1="128.72675"
+       y1="140.27541"
+       x2="275.84305"
+       y2="381.63806" />
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient3835"
+       id="linearGradient3891"
+       gradientUnits="userSpaceOnUse"
+       x1="128.72675"
+       y1="140.27541"
+       x2="275.84305"
+       y2="381.63806" />
+    <filter
+       inkscape:collect="always"
+       id="filter3928">
+      <feGaussianBlur
+         inkscape:collect="always"
+         stdDeviation="1.7001047"
+         id="feGaussianBlur3930" />
+    </filter>
+  </defs>
+  <rect
+     style="fill:#000000;fill-opacity:1;stroke:none"
+     id="rect3045"
+     width="1000"
+     height="800"
+     x="0"
+     y="0" />
+  <path
+     style="fill:url(#radialGradient3825);fill-opacity:1;stroke:none"
+     d="m 991.50663,629.33083 c -349.19022,2.16226 -664.78717,9.39214 -1051.647196,4.87626 L -19.505049,206.72145 993.13206,218.09939 z"
+     id="path3049"
+     inkscape:connector-curvature="0"
+     sodipodi:nodetypes="ccccc" />
+  <path
+     style="fill:#000000;stroke:none"
+     d="m 328.61326,487.17719 c -4.61194,0.0867 -9.8807,2.94925 -15.3125,6.5 l -12.6875,4.28125 1.6875,2.96875 -3.4375,1.21875 -10.625,-1.4375 -8.0625,2 -6.875,2.875 -0.59375,4.03125 -4,0.28125 -4.59375,8.90625 -7.78125,8.34375 -7.75,11.21875 0,4.59375 c 5.26196,5.58425 11.64703,8.33074 18.0625,11.03125 l -1.6875,5.0625 -2.59375,4.59375 -1.71875,1.71875 -3.15625,5.75 -12.625,18.96875 -10.0625,3.71875 -11.78125,9.5 -20.40625,12.625 -6.625,1.71875 0.59375,3.46875 -4.59375,1.4375 0.84375,1.71875 -2.5625,0.84375 -3.1875,4.3125 0.875,4.03125 1.15625,0.28125 0.28125,6.03125 5.46875,9.5 8.03125,2.59375 4.875,-0.3125 -0.5625,-7.15625 -2.59375,-10.0625 4.03125,0.84375 1.15625,-2.875 3.15625,1.4375 4.875,-8.90625 5.1875,-3.15625 c 5.26231,-8.75861 18.76992,-10.91561 28.15625,-16.375 l 7.46875,-5.75 21.84375,-15.21875 49.125,-3.15625 c 0,0 -2.3547,2.16711 -3.75,6.875 -1.3953,4.7079 -1.71875,21.5625 -1.71875,21.5625 l -2.5625,6.59375 1.40625,2.875 -2,2.3125 0.59375,2.28125 -1.4375,3.1875 0.28125,3.71875 -0.59375,5.46875 8.625,1.4375 2.3125,-1.4375 7.46875,3.71875 14.9375,-0.28125 -2,-4.59375 -12.09375,-7.1875 0,-2.59375 -2,-2.5625 1.71875,-2.03125 -1.4375,-3.4375 8.34375,-38.5 c 0.94593,-7.73436 -0.20293,-11.31414 -2.3125,-12.9375 l -38.78125,-5.46875 -2.84375,-7.0625 3.40625,0.1875 10.65625,-21.84375 3.15625,16.65625 19.53125,10.0625 4.59375,2.875 11.78125,-0.875 -1.15625,-12.0625 -5.75,0.875 -7.46875,-0.59375 -11.78125,-9.1875 0.59375,-11.1875 2.59375,-2.3125 -1.75,-2.875 3.46875,-4.3125 -0.0937,-0.0937 2.46875,-2.9375 0.5625,5.5 1.34375,-3.65625 0.3125,4.625 3.25,-6.8125 0.59375,-10.03125 c -2.6929,-13.56437 -7.53912,-18.04891 -13.46875,-17.9375 z m -54.15625,42.5625 -1.75,10.90625 -5.15625,-4.3125 c 0.86201,-1.14935 6.90625,-6.59375 6.90625,-6.59375 z"
+     id="path4578"
+     inkscape:connector-curvature="0" />
+  <path
+     inkscape:connector-curvature="0"
+     style="fill:#000000"
+     d="m 264.91227,575.73428 c 0.071,-0.35846 0.36271,-0.52061 0.65112,-0.36203 0.0918,0.0502 0.20348,0.0816 0.24849,0.0692 0.0785,-0.0215 0.32619,-0.29475 0.35457,-0.39111 0.008,-0.0256 -0.0953,-0.51469 -0.2285,-1.08727 -0.3006,-1.29241 -0.54092,-2.49555 -0.75379,-3.77388 -0.33595,-2.01745 -0.66866,-4.72144 -0.71966,-5.84883 -0.1262,-2.78875 0.35456,-5.49842 1.39238,-7.84818 0.40581,-0.91888 1.38106,-2.64528 1.84559,-3.26728 1.47791,-1.97878 3.32708,-3.19784 6.1754,-4.0711 1.71848,-0.52684 4.53478,-1.03952 6.15466,-1.12035 2.99302,-0.14934 6.47781,0.10482 12.08871,0.88168 3.17233,0.43922 4.10123,0.53488 5.37859,0.55385 3.33447,0.0495 6.29701,-0.8781 9.69948,-3.03714 1.89151,-1.20028 6.10899,-3.77874 6.61197,-4.04244 4.39734,-2.30533 8.02695,-3.24677 10.95526,-2.84157 0.58397,0.0807 1.65442,0.346 2.16243,0.53573 0.95089,0.35509 1.7235,0.9342 2.15481,1.61518 0.16167,0.25519 0.20638,0.36455 0.28772,0.70381 0.093,0.38746 0.098,0.3978 0.14075,0.29302 0.0246,-0.0597 0.0411,-0.1222 0.037,-0.13879 -0.0239,-0.0983 0.0898,-0.0156 0.29352,0.21394 l 0.2332,0.26262 0.1372,-0.0689 c 0.33072,-0.16606 0.54038,-0.11427 0.67792,0.16743 0.0774,0.15869 0.0653,0.2962 -0.0622,0.70423 -0.12616,0.40347 -0.22011,0.52104 -0.47152,0.58982 -0.22715,0.0622 -0.36708,0.004 -0.45981,-0.19096 -0.1291,-0.27137 -0.29945,-0.28708 -0.6591,-0.0609 -0.0989,0.0622 -0.18579,0.11489 -0.19339,0.11723 -0.008,0.002 0.006,-0.0673 0.0296,-0.15472 l 0.0433,-0.15894 -0.15251,0.16754 c -0.35822,0.39342 -0.62378,0.52701 -1.9495,0.98072 -1.16116,0.39737 -2.15816,0.78781 -2.94334,1.15264 -0.31385,0.14583 -0.73401,0.33793 -0.93368,0.42688 -0.43533,0.19393 -0.64966,0.32921 -0.96181,0.60705 -0.45231,0.40257 -0.8087,0.87432 -1.22448,1.62089 -0.68513,1.23018 -1.04222,2.59874 -1.02273,3.91942 0.004,0.32462 0.0335,0.48667 0.18449,1.0429 0.20614,0.75914 0.30247,0.9498 0.73297,1.45025 0.31933,0.37125 0.65542,0.63797 1.09723,0.87082 0.41206,0.21714 1.15891,0.46287 1.29431,0.42581 0.0565,-0.0155 2.11893,-0.52207 4.58321,-1.12582 11.72507,-2.87267 19.45683,-4.78552 31.10332,-7.69504 2.09857,-0.52425 6.93401,-1.74656 10.28665,-2.60024 2.19001,-0.55765 6.85359,-1.77274 11.52783,-3.00354 l 2.26062,-0.59523 0.14436,-0.26524 c 0.19206,-0.3528 0.35845,-0.73019 0.50008,-1.1343 0.17397,-0.4964 0.34819,-0.79136 0.55667,-0.94173 0.40503,-0.29229 0.84329,-0.38471 1.62039,-0.34173 0.56882,0.0315 1.65524,0.0145 1.67845,-0.0263 0.0394,-0.0684 0.031,-0.5044 -0.0111,-0.58642 -0.026,-0.0508 -0.13502,-0.11567 -0.26232,-0.15594 -0.19072,-0.0604 -0.22492,-0.0883 -0.27376,-0.2226 -0.0616,-0.16966 -0.051,-0.54845 0.0294,-1.0461 0.0631,-0.39063 0.0854,-0.40591 0.72054,-0.49472 0.49271,-0.0689 0.71236,-0.0641 1.03508,0.0229 0.26987,0.0727 0.40144,0.17281 0.48782,0.37122 0.0869,0.19959 0.13089,0.74299 0.08,0.98826 -0.0491,0.23711 -0.23335,0.45494 -0.43001,0.50875 -0.1658,0.0453 -0.1672,0.0518 -0.10041,0.44296 0.0359,0.2099 0.0381,0.21268 0.17474,0.21771 0.56659,0.0208 2.23627,0.0419 2.24202,0.0283 0.004,-0.009 0.0114,-0.11812 0.0166,-0.24183 0.0116,-0.27668 -0.0599,-0.39162 -0.27167,-0.43675 -0.0825,-0.0176 -0.1797,-0.0546 -0.21595,-0.0823 -0.15591,-0.11902 -0.17315,-0.51121 -0.0529,-1.20695 l 0.0613,-0.35508 0.45235,-0.0964 c 0.77236,-0.16462 1.38557,-0.0831 1.63026,0.21694 0.12454,0.15273 0.13679,0.18814 0.17715,0.51252 0.0485,0.38952 0.0318,0.60927 -0.0595,0.78673 -0.0805,0.15614 -0.32129,0.35331 -0.43322,0.35457 -0.10604,8.3e-4 -0.11451,0.051 -0.0637,0.37353 l 0.0377,0.23911 1.11539,0.0379 c 0.61344,0.0209 1.12415,0.03 1.13492,0.0204 0.0454,-0.0402 0.0426,-0.46976 -0.003,-0.55168 -0.0276,-0.049 -0.11035,-0.10196 -0.18393,-0.11767 -0.21404,-0.0457 -0.32839,-0.13005 -0.36691,-0.27087 -0.0448,-0.16367 -0.0153,-0.69415 0.06,-1.07773 l 0.0577,-0.29453 0.28046,-0.0719 c 0.64121,-0.16425 0.97999,-0.17559 1.43101,-0.0477 0.21492,0.0609 0.28576,0.10471 0.38181,0.23587 0.10328,0.14113 0.12331,0.20329 0.16134,0.50131 0.0591,0.46349 -0.003,0.77059 -0.19625,0.96828 -0.10703,0.10958 -0.18401,0.1555 -0.27113,0.16157 -0.13446,0.009 -0.13597,0.0183 -0.0733,0.44214 l 0.0305,0.20605 1.19618,0.0554 c 0.65786,0.0305 1.19965,0.0463 1.2039,0.035 0.0314,-0.0823 0.013,-0.54163 -0.0241,-0.60554 -0.0254,-0.0437 -0.14638,-0.1099 -0.2689,-0.1472 -0.19089,-0.058 -0.23019,-0.0879 -0.27442,-0.20898 -0.06,-0.16417 -0.0465,-0.55215 0.0359,-1.03984 0.07,-0.41438 0.0824,-0.42326 0.71713,-0.5142 0.71044,-0.10184 1.23245,-0.007 1.44624,0.26357 0.0869,0.1099 0.11087,0.18538 0.15492,0.48831 0.0677,0.46647 0.0287,0.71367 -0.1471,0.93292 -0.10836,0.13508 -0.17148,0.17862 -0.28891,0.19911 -0.1691,0.0295 -0.1687,0.0276 -0.0962,0.48473 l 0.0391,0.24656 1.14827,0.0699 c 0.63157,0.0384 1.15619,0.0635 1.16582,0.0558 0.0246,-0.0198 0.0415,-0.62545 0.0197,-0.70848 -0.01,-0.0374 -0.0727,-0.0878 -0.13967,-0.11185 -0.34203,-0.12265 -0.40726,-0.16617 -0.44254,-0.29525 -0.0414,-0.15135 -0.0185,-0.59768 0.0548,-1.06462 l 0.0519,-0.33119 0.47446,-0.10272 c 0.50882,-0.11024 0.84274,-0.10991 1.25487,8.1e-4 0.24822,0.0668 0.36332,0.15589 0.45167,0.34972 0.0827,0.18141 0.14145,0.7397 0.099,0.94137 -0.0658,0.31282 -0.29664,0.57988 -0.50502,0.58431 -0.11298,0.002 -0.10891,-0.0257 -0.0738,0.51303 0.0112,0.17142 0.0263,0.31426 0.0334,0.31739 0.008,0.003 0.32115,0.003 0.69767,5.1e-4 0.37657,-0.002 0.90567,5.1e-4 1.17585,0.008 0.27011,0.007 0.49294,0.007 0.49506,-8.3e-4 0.0216,-0.0763 0.01,-0.52267 -0.0166,-0.61202 -0.0273,-0.0929 -0.0767,-0.12908 -0.25204,-0.18455 -0.36286,-0.11477 -0.39829,-0.25255 -0.28567,-1.11191 0.0717,-0.54686 0.0782,-0.55478 0.52116,-0.62713 0.15046,-0.0245 0.35241,-0.0578 0.44879,-0.0738 0.36895,-0.0613 0.96415,0.0591 1.14779,0.23232 0.12841,0.12114 0.21169,0.37997 0.24351,0.75688 0.0419,0.4952 -0.12807,0.84824 -0.45074,0.93652 l -0.16899,0.0462 0.055,0.38517 c 0.0303,0.21184 0.0624,0.38893 0.0716,0.39352 0.009,0.004 0.18366,0.0416 0.38787,0.0823 0.62379,0.12438 0.98687,0.26186 1.33464,0.50534 0.95873,0.67124 1.53448,1.61252 1.62513,2.65694 0.0159,0.18427 0.0249,0.45195 0.0199,0.59485 -0.0113,0.31438 -0.14146,0.99581 -0.25753,1.34737 -0.22429,0.67938 -0.71864,1.27856 -1.38784,1.68222 -0.66209,0.39932 -1.60961,0.76476 -2.08118,0.80254 -0.98595,0.0791 -2.15906,-0.17804 -2.82258,-0.61866 -0.1986,-0.1319 -0.52776,-0.44317 -0.86279,-0.81589 -0.41919,-0.46632 -0.84691,-0.61356 -1.4458,-0.49766 -0.39501,0.0764 -0.58681,0.16807 -2.88198,1.37683 -2.38208,1.25451 -3.85461,2.01 -5.0232,2.57702 -0.8092,0.3927 -0.88545,0.42203 -1.66446,0.64029 -0.58724,0.1645 -0.85455,0.22363 -0.95237,0.21059 -0.1003,-0.0134 -0.21882,-0.0993 -0.45141,-0.32675 -0.46309,-0.45301 -1.13964,-1.02674 -1.49888,-1.27108 -0.3919,-0.2666 -0.73995,-0.43305 -1.27451,-0.60956 -0.79366,-0.26211 -0.94903,-0.28279 -1.59396,-0.21213 -0.32051,0.0351 -0.74375,0.075 -0.94043,0.0887 -0.37248,0.0259 -2.17975,0.5254 -34.60073,9.56517 -2.77176,0.77284 -9.21739,2.56695 -14.32367,3.9869 -5.10627,1.41996 -10.45742,2.91253 -11.89149,3.31681 -1.43404,0.40428 -3.47384,0.97236 -4.53282,1.26242 l -1.92549,0.52735 -0.0185,0.11428 c -0.01,0.0629 -0.0711,0.18085 -0.13556,0.26221 -0.63283,0.79946 -0.71923,2.62181 -0.20022,4.22258 0.61162,1.88628 1.73469,3.23072 3.26753,3.91166 0.39632,0.17615 0.95232,0.25828 2.18531,0.32319 0.6959,0.0366 2.1257,0.016 2.79745,-0.0404 0.82509,-0.0693 1.28709,0.011 1.82584,0.31648 0.62056,0.35203 0.94952,0.8014 1.10976,1.51586 0.1496,0.66704 0.0572,1.15628 -0.355,1.87976 -0.14331,0.25171 -0.3595,0.56792 -0.48024,0.70273 -0.48789,0.54473 -1.88813,1.44011 -3.1499,2.01426 -0.60232,0.27407 -2.48175,0.78779 -3.19152,0.87238 -1.44453,0.17212 -2.31791,0.17556 -6.01779,0.0237 -0.2266,-0.009 -0.8281,-0.0921 -1.33667,-0.18395 -1.4107,-0.25483 -2.23675,-0.33051 -3.34244,-0.3062 -1.78229,0.0391 -3.41868,0.44982 -5.01539,1.25852 -1.10212,0.55821 -2.05544,1.23702 -3.14007,2.23586 -0.35788,0.32959 -0.81064,0.71997 -1.00609,0.86745 -0.46494,0.35085 -0.98389,0.77193 -2.39064,1.93979 -2.25058,1.8684 -3.35305,2.70792 -4.75028,3.61728 -2.56729,1.67089 -5.08147,2.76984 -7.67934,3.35661 -1.77774,0.40151 -2.97247,0.5669 -4.21322,0.58321 -2.30882,0.0303 -4.05216,-0.4225 -6.3925,-1.66034 -1.00125,-0.5296 -1.05189,-0.56426 -1.80496,-1.23662 -1.70735,-1.52446 -2.51837,-2.45552 -3.42333,-3.93014 -1.12503,-1.83323 -2.12461,-4.23349 -2.8174,-6.76546 -0.21152,-0.77304 -0.67216,-2.40999 -1.02364,-3.6377 l -0.63908,-2.23217 -0.29397,-0.0789 -0.29398,-0.0789 -0.11975,0.18727 c -0.132,0.20634 -0.24578,0.25931 -0.4593,0.21374 -0.24362,-0.0519 -0.34888,-0.19287 -0.46393,-0.62133 -0.0737,-0.27445 -0.0935,-0.42226 -0.0712,-0.53413 z"
+     id="path3250"
+     sodipodi:nodetypes="csssssssssssssssssssscccsssssscccssssssssssssscccssssssssssssssssssscccsssscccsssscccssssscccsssssssssscccsssscccsssssssssssssssscccssssssssssssssssssssssscccssssssssssssssssssssssssscccccssc" />
+  <g
+     id="g3873">
+    <path
+       sodipodi:nodetypes="ccccccccccccccc"
+       inkscape:connector-curvature="0"
+       id="path3830"
+       d="M 85.773653,-14.509381 110.11884,117.56622 -21.956757,93.221026 104.59118,138.17142 17.465985,240.3977 119.69226,153.27249 136.81622,201.49244 174.8009,438.61004 355.15225,353.63547 156.08067,150.66156 272.37306,172.09003 145.80159,127.13964 232.92679,24.936883 130.72404,112.06209 z"
+       style="fill:url(#linearGradient3841);stroke:none;fill-opacity:1;filter:url(#filter3853)" />
+    <path
+       transform="matrix(0.77069935,-0.20064204,0.20064204,0.77069935,-10.783852,70.628776)"
+       d="m 206.14358,80.732563 -51.41214,35.406577 51.41214,35.40657 -56.36906,-26.82094 -4.95692,62.22752 -4.95692,-62.22752 -56.369069,26.82094 51.412149,-35.40657 -51.412149,-35.406577 56.369069,26.820937 4.95692,-62.227511 4.95692,62.227511 z"
+       inkscape:randomized="0"
+       inkscape:rounded="0"
+       inkscape:flatsided="false"
+       sodipodi:arg2="3.7025504e-17"
+       sodipodi:arg1="-0.52359878"
+       sodipodi:r2="9.9138403"
+       sodipodi:r1="70.813148"
+       sodipodi:cy="116.13914"
+       sodipodi:cx="144.8176"
+       sodipodi:sides="6"
+       id="path3843"
+       style="fill:#ffffff;fill-opacity:1;stroke:none;filter:url(#filter3869)"
+       sodipodi:type="star" />
+  </g>
+  <g
+     id="g3877"
+     transform="matrix(0.56401321,0.82576576,-0.82576576,0.56401321,517.83463,-60.061071)">
+    <path
+       style="fill:url(#linearGradient3883);fill-opacity:1.0;stroke:none;filter:url(#filter3853)"
+       d="M 85.773653,-14.509381 110.11884,117.56622 -21.956757,93.221026 104.59118,138.17142 17.465985,240.3977 119.69226,153.27249 136.81622,201.49244 174.8009,438.61004 355.15225,353.63547 156.08067,150.66156 272.37306,172.09003 145.80159,127.13964 232.92679,24.936883 130.72404,112.06209 z"
+       id="path3879"
+       inkscape:connector-curvature="0"
+       sodipodi:nodetypes="ccccccccccccccc" />
+    <path
+       sodipodi:type="star"
+       style="fill:#ffffff;fill-opacity:1;stroke:none;filter:url(#filter3869)"
+       id="path3881"
+       sodipodi:sides="6"
+       sodipodi:cx="144.8176"
+       sodipodi:cy="116.13914"
+       sodipodi:r1="70.813148"
+       sodipodi:r2="9.9138403"
+       sodipodi:arg1="-0.52359878"
+       sodipodi:arg2="3.7025504e-17"
+       inkscape:flatsided="false"
+       inkscape:rounded="0"
+       inkscape:randomized="0"
+       d="m 206.14358,80.732563 -51.41214,35.406577 51.41214,35.40657 -56.36906,-26.82094 -4.95692,62.22752 -4.95692,-62.22752 -56.369069,26.82094 51.412149,-35.40657 -51.412149,-35.406577 56.369069,26.820937 4.95692,-62.227511 4.95692,62.227511 z"
+       transform="matrix(0.77069935,-0.20064204,0.20064204,0.77069935,-10.783852,70.628776)" />
+  </g>
+  <g
+     transform="matrix(0.66878841,0.7434528,-0.7434528,0.66878841,675.2038,-81.671637)"
+     id="g3885">
+    <path
+       sodipodi:nodetypes="ccccccccccccccc"
+       inkscape:connector-curvature="0"
+       id="path3887"
+       d="M 85.773653,-14.509381 110.11884,117.56622 -21.956757,93.221026 104.59118,138.17142 17.465985,240.3977 119.69226,153.27249 136.81622,201.49244 174.8009,438.61004 355.15225,353.63547 156.08067,150.66156 272.37306,172.09003 145.80159,127.13964 232.92679,24.936883 130.72404,112.06209 z"
+       style="fill:url(#linearGradient3891);fill-opacity:1;stroke:none;filter:url(#filter3853)" />
+    <path
+       transform="matrix(0.77069935,-0.20064204,0.20064204,0.77069935,-10.783852,70.628776)"
+       d="m 206.14358,80.732563 -51.41214,35.406577 51.41214,35.40657 -56.36906,-26.82094 -4.95692,62.22752 -4.95692,-62.22752 -56.369069,26.82094 51.412149,-35.40657 -51.412149,-35.406577 56.369069,26.820937 4.95692,-62.227511 4.95692,62.227511 z"
+       inkscape:randomized="0"
+       inkscape:rounded="0"
+       inkscape:flatsided="false"
+       sodipodi:arg2="3.7025504e-17"
+       sodipodi:arg1="-0.52359878"
+       sodipodi:r2="9.9138403"
+       sodipodi:r1="70.813148"
+       sodipodi:cy="116.13914"
+       sodipodi:cx="144.8176"
+       sodipodi:sides="6"
+       id="path3889"
+       style="fill:#ffffff;fill-opacity:1;stroke:none;filter:url(#filter3869)"
+       sodipodi:type="star" />
+  </g>
+  <path
+     id="path3909"
+     style="fill:none;stroke:#ffffff;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;filter:url(#filter3928)"
+     d="m 196.53816,617.25399 6.89608,-0.86201 23.27425,-14.9415 7.75809,-7.47075 10.34411,-3.44803 12.35547,-18.96421 m 62.92669,-29.59566 c -3.1607,-0.28734 -3.1607,-0.86201 -17.24018,8.62009 m -27.5714,3.20511 c -2.82349,1.46124 -5.03089,4.06574 -5.75964,8.00102 -1.43668,7.75808 -1.14934,8.04542 -1.14934,8.04542 m 59.76599,-29.59566 11.20612,8.90743 4.31005,1.14935 3.1607,-1.43669 1.43668,1.43669 4.02271,-2.01136 1.14935,0.57467 m 1.72402,0.86201 28.15897,-7.75808 1.43669,-2.87337 22.69958,0.57468 0,0 0,0 m -105.70025,-42.2813 12.67288,-3.94525 c 9.52652,-6.98529 21.01821,-8.04159 24.07848,2.73133 l 2.53459,6.67656 m -65.76049,1.47627 13.21748,-3.73537 8.62009,2.29869" />
+</svg>
diff --git a/data/backgrounds/singer_bg.svg b/data/backgrounds/singer_bg.svg
new file mode 100644 (file)
index 0000000..c96e712
--- /dev/null
@@ -0,0 +1,730 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Sodipodi ("http://www.sodipodi.com/") -->
+
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://creativecommons.org/ns#"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:xlink="http://www.w3.org/1999/xlink"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   version="1.0"
+   x="0"
+   y="0"
+   width="1000"
+   height="800"
+   id="svg559"
+   sodipodi:version="0.32"
+   inkscape:version="0.48.1 r9760"
+   sodipodi:docname="singer_bg.svg"
+   inkscape:output_extension="org.inkscape.output.svg.inkscape">
+  <metadata
+     id="metadata35">
+    <rdf:RDF>
+      <cc:Work
+         rdf:about="">
+        <dc:format>image/svg+xml</dc:format>
+        <dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+      </cc:Work>
+    </rdf:RDF>
+  </metadata>
+  <sodipodi:namedview
+     inkscape:window-height="1026"
+     inkscape:window-width="1626"
+     inkscape:pageshadow="2"
+     inkscape:pageopacity="0.0"
+     guidetolerance="10.0"
+     gridtolerance="10.0"
+     objecttolerance="10.0"
+     borderopacity="1.0"
+     bordercolor="#666666"
+     pagecolor="#ffffff"
+     id="base"
+     inkscape:zoom="0.61522534"
+     inkscape:cx="550.44941"
+     inkscape:cy="498.29024"
+     inkscape:window-x="54"
+     inkscape:window-y="24"
+     inkscape:current-layer="svg559"
+     showgrid="false"
+     showguides="true"
+     inkscape:guide-bbox="true"
+     inkscape:window-maximized="1" />
+  <defs
+     id="defs561">
+    <linearGradient
+       id="linearGradient3845">
+      <stop
+         style="stop-color:#ffffff;stop-opacity:1;"
+         offset="0"
+         id="stop3847" />
+      <stop
+         id="stop3853"
+         offset="0.36726889"
+         style="stop-color:#ffffff;stop-opacity:0.33757961;" />
+      <stop
+         style="stop-color:#ababab;stop-opacity:0;"
+         offset="1"
+         id="stop3849" />
+    </linearGradient>
+    <linearGradient
+       id="linearGradient3941">
+      <stop
+         style="stop-color:#22b7ff;stop-opacity:0.27388534;"
+         offset="0"
+         id="stop3943" />
+      <stop
+         style="stop-color:#ffffff;stop-opacity:0;"
+         offset="1"
+         id="stop3945" />
+    </linearGradient>
+    <linearGradient
+       id="linearGradient3856">
+      <stop
+         style="stop-color:#0f0f0f;stop-opacity:1;"
+         offset="0"
+         id="stop3858" />
+      <stop
+         style="stop-color:#181818;stop-opacity:0.22929937;"
+         offset="1"
+         id="stop3860" />
+    </linearGradient>
+    <linearGradient
+       id="linearGradient4557">
+      <stop
+         style="stop-color:#ffffff;stop-opacity:1;"
+         offset="0"
+         id="stop4559" />
+      <stop
+         style="stop-color:#0300da;stop-opacity:1;"
+         offset="1"
+         id="stop4561" />
+    </linearGradient>
+    <linearGradient
+       id="linearGradient3751"
+       inkscape:collect="always">
+      <stop
+         id="stop3753"
+         offset="0"
+         style="stop-color:black;stop-opacity:1;" />
+      <stop
+         id="stop3755"
+         offset="1"
+         style="stop-color:black;stop-opacity:0;" />
+    </linearGradient>
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient3751"
+       id="linearGradient3814"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(0.9434139,0,0,0.35574295,80.767581,395.14908)"
+       x1="665.12128"
+       y1="684.16162"
+       x2="381.28015"
+       y2="449.80624" />
+    <linearGradient
+       id="linearGradient3629-3">
+      <stop
+         style="stop-color:#00cbff;stop-opacity:0;"
+         offset="0"
+         id="stop3631-1" />
+      <stop
+         style="stop-color:#0000ce;stop-opacity:1;"
+         offset="1"
+         id="stop3633-4" />
+    </linearGradient>
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient3856"
+       id="linearGradient3862"
+       x1="505.71225"
+       y1="632.85657"
+       x2="505.71225"
+       y2="593.08313"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(1,0,0,1.0718184,0,-57.454753)" />
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient3751"
+       id="linearGradient3930"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(0.9434139,0,0,0.35574295,41.689817,426.18142)"
+       x1="665.12128"
+       y1="684.16162"
+       x2="381.28015"
+       y2="449.80624" />
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient3941"
+       id="linearGradient3947"
+       x1="489.6214"
+       y1="522.79633"
+       x2="489.6214"
+       y2="292.00479"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="translate(-1.149346,0)" />
+    <filter
+       inkscape:collect="always"
+       id="filter3838"
+       x="-0.1060241"
+       width="1.2120482"
+       y="-0.1060241"
+       height="1.2120482">
+      <feGaussianBlur
+         inkscape:collect="always"
+         stdDeviation="4.5860944"
+         id="feGaussianBlur3840" />
+    </filter>
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient3845"
+       id="linearGradient3851"
+       x1="294.80725"
+       y1="129.35661"
+       x2="556.94904"
+       y2="397.24515"
+       gradientUnits="userSpaceOnUse" />
+    <filter
+       inkscape:collect="always"
+       id="filter3879"
+       x="-0.11566265"
+       width="1.2313253"
+       y="-0.11566265"
+       height="1.2313253">
+      <feGaussianBlur
+         inkscape:collect="always"
+         stdDeviation="5.0030121"
+         id="feGaussianBlur3881" />
+    </filter>
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient3845"
+       id="linearGradient3891"
+       gradientUnits="userSpaceOnUse"
+       x1="294.80725"
+       y1="129.35661"
+       x2="556.94904"
+       y2="397.24515" />
+    <filter
+       inkscape:collect="always"
+       id="filter3917"
+       x="-0.10227577"
+       width="1.2045515"
+       y="-0.075312157"
+       height="1.1506243">
+      <feGaussianBlur
+         inkscape:collect="always"
+         stdDeviation="2.3869056"
+         id="feGaussianBlur3919" />
+    </filter>
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient3845"
+       id="linearGradient3927"
+       gradientUnits="userSpaceOnUse"
+       x1="294.80725"
+       y1="129.35661"
+       x2="370.68124"
+       y2="184.80293" />
+    <filter
+       inkscape:collect="always"
+       id="filter3952">
+      <feGaussianBlur
+         inkscape:collect="always"
+         stdDeviation="1.6061188"
+         id="feGaussianBlur3954" />
+    </filter>
+    <filter
+       inkscape:collect="always"
+       id="filter3904">
+      <feGaussianBlur
+         inkscape:collect="always"
+         stdDeviation="4.1384667"
+         id="feGaussianBlur3906" />
+    </filter>
+    <filter
+       inkscape:collect="always"
+       id="filter3938">
+      <feGaussianBlur
+         inkscape:collect="always"
+         stdDeviation="5.4949042"
+         id="feGaussianBlur3940" />
+    </filter>
+    <filter
+       inkscape:collect="always"
+       id="filter3958"
+       x="-0.10076561"
+       width="1.2015312"
+       y="-0.093878103"
+       height="1.1877562">
+      <feGaussianBlur
+         inkscape:collect="always"
+         stdDeviation="5.538841"
+         id="feGaussianBlur3960" />
+    </filter>
+    <filter
+       inkscape:collect="always"
+       id="filter3966">
+      <feGaussianBlur
+         inkscape:collect="always"
+         stdDeviation="5.517956"
+         id="feGaussianBlur3968" />
+    </filter>
+  </defs>
+  <rect
+     style="fill:#0e1e2c;fill-opacity:1;stroke:none"
+     id="rect3835"
+     width="1000"
+     height="800"
+     x="0"
+     y="0" />
+  <rect
+     style="fill:url(#linearGradient3862);fill-opacity:1;stroke:none"
+     id="rect3854"
+     width="1000"
+     height="222.98692"
+     x="-1.7215696e-23"
+     y="577.01306" />
+  <path
+     id="path3794"
+     d="m 237.50337,797.90249 9.7335,0 1.94667,-2.63393 -1.94667,-2.89733 0.97334,-3.16072 4.86668,1.58036 3.89334,3.9509 8.2735,1.05358 3.40668,1.84377 7.30009,1.84375 8.27341,7.37503 -0.48666,3.42413 -20.44026,8.42859 -9.73337,-2.37054 -1.46006,-1.84375 0,-2.10716 -2.43334,-1.84375 -4.86675,-0.79019 -3.40668,1.58036 -0.48667,1.84377 1.46,1.58036 2.92001,0.79018 1.94674,1.31697 -4.38008,1.05358 0.97334,2.63394 0,1.58036 2.92001,1.58036 1.46007,2.37054 5.84002,0.79019 4.86675,0.52679 10.22016,-3.95091 25.79361,-5.53127 5.84008,-3.16073 4.38002,-1.84377 0.97341,-4.2143 -1.94674,-2.10714 -4.86675,-7.11164 -6.32669,-6.58486 -6.81342,-4.74108 10.70677,-9.48219 12.16683,-14.22327 7.30009,-6.32145 12.16678,-8.16522 0.48667,-3.68752 6.32675,-3.16072 -9.73344,-4.7411 2.43335,-5.53126 -0.97334,-12.37952 -4.38001,-14.22328 -4.38008,-12.64292 -4.86668,-4.21429 -6.8135,-7.63844 -10.70677,-8.69199 -2.92,-5.53125 -2.92007,-3.95093 8.76015,-6.58484 15.57352,-3.42413 1.46001,-2.63395 -29.68703,0.52678 4.38001,-4.21429 -5.35335,-2.63393 -14.11351,-0.7902 -11.1935,5.2679 -3.89341,7.37501 -6.32668,6.32146 -7.78677,3.68751 -2.43334,4.21432 8.27336,0.26339 -5.35335,2.89733 10.70677,-1.84375 -7.78676,4.2143 5.84008,0.79018 4.38009,2.89733 7.30008,8.16522 17.03353,7.63842 3.40667,0.52679 -3.40667,1.58037 0.48667,4.47769 -3.40675,3.95091 2.92008,-0.26339 -5.35342,5.00448 0,5.00449 -3.40668,2.63393 0,3.42413 -7.30008,5.26788 -0.48674,4.4777 1.46007,3.6875 -3.40674,4.21431 -3.89335,3.42413 0,2.10714 -4.38008,0.26339 -3.89335,2.10716 -3.40674,5.26789 -7.78675,4.74108 -9.24678,1.84376 -5.84001,-2.63393 -14.11358,-2.37055 -11.19342,-3.16073 -5.35336,-3.68752 -9.24676,-0.52678 -29.20043,-6.84825 -15.08678,-2.89733 -12.16683,-5.00449 -2.92008,0.5268 0,1.58036 6.81343,2.89733 -13.14011,-1.84377 -1.46008,1.31699 2.92007,1.58035 -4.86675,0 -0.48666,1.58037 8.7601,1.05357 -6.81336,1.05358 0,1.84377 2.43334,0.26337 7.30009,-0.26337 5.84002,1.31695 3.89341,1.05358 -5.84008,2.63394 -1.46001,1.84376 0.97334,1.31697 5.35335,-0.52678 11.19357,-3.16073 1.45993,-1.58036 3.89342,0.52678 14.11351,4.21431 0.48666,2.89733 8.27343,2.37055 14.11351,3.95091 3.40669,-1.31698 -0.48668,1.84376 7.78676,3.95092 6.81342,1.05356 6.32676,3.95091 1.94666,1.31697 -6.32675,-2.37055 0.97334,2.63396 -4.86668,-1.31699 1.46001,3.95092 -6.81342,-3.42412 2.92,2.37054 -6.81335,-1.58035 5.84002,4.47768 -4.38002,-0.79017 1.94667,4.2143 -3.40667,-1.58036 4.86668,3.95091 -4.86668,-0.79019 4.38001,3.16073 -5.84002,0.26339 6.32669,2.10716 -3.89335,1.05356 4.38001,0.26341 -5.84002,2.89733 5.35336,-0.26339 -0.48667,1.84375 -0.48666,5.26787 2.92,-3.6875 3.40674,5.26788 -0.48666,-4.21431 1.94667,-0.2634 4.86675,0 5.35341,4.2143 5.35335,0 6.32676,2.89735 2.92007,-1.58036 7.30002,-2.63396 z"
+     style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:0.35443315px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+     inkscape:connector-curvature="0" />
+  <path
+     style="fill:url(#linearGradient3947);fill-opacity:1;stroke:none"
+     d="m 0,1.204533 999.99995,0 0,290.839717 c 0,0 -165.53066,169.52275 -498.8851,167.80451 C 167.76041,458.13052 0,292.04425 0,292.04425 z"
+     id="rect3851"
+     inkscape:connector-curvature="0"
+     sodipodi:nodetypes="ccczcc" />
+  <path
+     style="fill:none;stroke:#0e1e2c;stroke-width:1.89999998;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+     d="m 665.01008,446.17873 46.30646,-20.02889 -66.66207,-25.28561 62.06469,-28.15898 -61.49001,-17.24019 56.31795,-29.30832 -54.01926,-24.71094 48.27253,-19.53888 -44.82449,-14.36682 39.65243,-10.91879"
+     id="path3824"
+     inkscape:connector-curvature="0"
+     sodipodi:nodetypes="cccccccccc" />
+  <path
+     style="fill:none;stroke:#0e1e2c;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+     d="m 652.69989,245.70252 40.22711,17.81486 -44.82449,19.53889 49.99655,25.86028 -51.1459,19.53888 56.89263,20.11356 -59.76599,27.5843 64.36338,21.2629 -64.36338,26.43496 46.77459,16.79299"
+     id="path3822"
+     inkscape:connector-curvature="0"
+     sodipodi:nodetypes="cccccccccc" />
+  <text
+     xml:space="preserve"
+     style="font-size:24.89476013px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;font-family:Bitstream Vera Sans"
+     x="-702.95752"
+     y="774.51685"
+     id="text2508"
+     transform="scale(-1,1)"><tspan
+       sodipodi:role="line"
+       id="tspan2510"
+       x="-702.95752"
+       y="774.51685" /></text>
+  <path
+     inkscape:connector-curvature="0"
+     style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:0.48178115px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+     d="m 237.50337,381.52588 9.7335,0 1.94667,4.86672 -1.94667,5.35339 0.97334,5.84007 4.86668,-2.92004 3.89334,-7.30008 8.2735,-1.9467 3.40668,-3.4067 7.30009,-3.40671 8.27341,-13.62682 -0.48666,-6.32675 -20.44026,-15.57351 -9.73337,4.38004 -1.46006,3.40671 0,3.89339 -2.43334,3.4067 -4.86675,1.46002 -3.40668,-2.92004 -0.48667,-3.40671 1.46,-2.92003 2.92001,-1.46001 1.94674,-2.43337 -4.38008,-1.94668 0.97334,-4.86673 0,-2.92004 2.92001,-2.92003 1.46007,-4.38005 5.84002,-1.46001 4.86675,-0.97336 10.22016,7.30009 25.79361,10.22013 5.84008,5.84006 4.38002,3.40671 0.97341,7.78676 -1.94674,3.89338 -4.86675,13.14015 -6.32669,12.16681 -6.81342,8.76011 10.70677,17.52021 12.16683,26.28031 7.30009,11.68013 12.16678,15.08686 0.48667,6.81341 6.32675,5.84006 -9.73344,8.76012 2.43335,10.22011 -0.97334,22.87361 -4.38001,26.28031 -4.38008,23.36029 -4.86668,7.78675 -6.8135,14.1135 -10.70677,16.06019 -2.92,10.22009 -2.92007,7.3001 8.76015,12.16681 15.57352,6.32674 1.46001,4.86677 -29.68703,-0.97335 4.38001,7.78674 -5.35335,4.86671 -14.11351,1.46005 -11.1935,-9.73348 -3.89341,-13.62679 -6.32668,-11.68016 -7.78677,-6.8134 -2.43334,-7.78678 8.27336,-0.48667 -5.35335,-5.3534 10.70677,3.40671 -7.78676,-7.78676 5.84008,-1.46002 4.38009,-5.35339 7.30008,-15.08685 17.03353,-14.1135 3.40667,-0.97334 -3.40667,-2.92004 0.48667,-8.27343 -3.40675,-7.30009 2.92008,0.48667 -5.35342,-9.24677 0,-9.24678 -3.40668,-4.86672 0,-6.32675 -7.30008,-9.73345 -0.48674,-8.27342 1.46007,-6.81342 -3.40674,-7.78676 -3.89335,-6.32675 0,-3.89337 -4.38008,-0.48667 -3.89335,-3.89338 -3.40674,-9.73345 -7.78675,-8.76011 -9.24678,-3.4067 -5.84001,4.86672 -14.11358,4.38006 -11.19342,5.84006 -5.35336,6.81342 -9.24676,0.97334 -29.20043,12.65348 -15.08678,5.35341 -12.16683,9.24677 -2.92008,-0.97335 0,-2.92003 6.81343,-5.35339 -13.14011,3.4067 -1.46008,-2.43337 2.92007,-2.92002 -4.86675,0 -0.48666,-2.92004 8.7601,-1.94669 -6.81336,-1.94669 0,-3.40671 2.43334,-0.48666 7.30009,0.48666 5.84002,-2.43336 3.89341,-1.94669 -5.84008,-4.86672 -1.46001,-3.40671 0.97334,-2.43337 5.35335,0.97336 11.19357,5.84006 1.45993,2.92003 3.89342,-0.97334 14.11351,-7.78675 0.48666,-5.3534 8.27343,-4.38006 14.11351,-7.30009 3.40669,2.43337 -0.48668,-3.40671 7.78676,-7.30009 6.81342,-1.94669 6.32676,-7.30008 1.94666,-2.43337 -6.32675,4.38006 0.97334,-4.86674 -4.86668,2.43337 1.46001,-7.30009 -6.81342,6.32675 2.92,-4.38005 -6.81335,2.92002 5.84002,-8.27342 -4.38002,1.46002 1.94667,-7.78676 -3.40667,2.92003 4.86668,-7.30009 -4.86668,1.46002 4.38001,-5.84006 -5.84002,-0.48668 6.32669,-3.89338 -3.89335,-1.94668 4.38001,-0.48668 -5.84002,-5.35339 5.35336,0.48666 -0.48667,-3.4067 -0.48666,-9.73344 2.92,6.81341 3.40674,-9.73346 -0.48666,7.78677 1.94667,0.48667 4.86675,0 5.35341,-7.78676 5.35335,0 6.32676,-5.3534 2.92007,2.92003 7.30002,4.86674 z"
+     id="path1939" />
+  <path
+     inkscape:connector-curvature="0"
+     style="fill:none;stroke:#ffffff;stroke-width:1.1479615;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+     d="m 259.35454,332.97314 c 19.05488,-7.04315 26.9505,18.71977 23.01656,34.11165 -4.60372,18.01249 -6.01944,40.09818 2.27114,56.34332 5.94069,11.6406 33.41439,15.99883 33.06777,32.35914"
+     id="path3759"
+     sodipodi:nodetypes="cssc" />
+  <g
+     id="g3810"
+     transform="matrix(-1,0,0,1,969.91939,14.628786)">
+    <path
+       sodipodi:nodetypes="cc"
+       inkscape:connector-curvature="0"
+       id="path3802"
+       d="m 255.63227,421.10072 23.94009,-193.2488"
+       style="fill:#ffffff;fill-opacity:0;stroke:#0c1925;stroke-width:5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
+    <path
+       sodipodi:nodetypes="cc"
+       inkscape:connector-curvature="0"
+       id="path3804"
+       d="m 291.56239,428.98432 7.84224,-199.63461"
+       style="fill:#ffffff;fill-opacity:0;stroke:#0c1925;stroke-width:5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
+    <path
+       sodipodi:nodetypes="cc"
+       inkscape:connector-curvature="0"
+       id="path3806"
+       d="M 369.54361,440.60826 333.31034,228.77504"
+       style="fill:#ffffff;fill-opacity:0;stroke:#0c1925;stroke-width:5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
+    <path
+       sodipodi:nodetypes="cc"
+       inkscape:connector-curvature="0"
+       id="path3808"
+       d="M 327.73193,435.16928 319.51819,228.20037"
+       style="fill:#ffffff;fill-opacity:0;stroke:#0c1925;stroke-width:5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
+  </g>
+  <rect
+     style="fill:#b2bfcb;fill-opacity:1;stroke:#0c1925;stroke-width:3.00820851;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;filter:url(#filter3917)"
+     id="rect3816"
+     width="56.011051"
+     height="76.064392"
+     x="278.86987"
+     y="126.95414"
+     transform="matrix(-1,0,0,1.2488274,969.91939,-35.887796)" />
+  <path
+     style="fill:none;stroke:#0c1925;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+     d="m 637.7584,248.00121 33.33103,27.00963 -44.82449,24.71094 47.12318,29.883 -57.4673,24.13627 58.04198,34.48038 -68.38609,38.50309 39.36459,22.80664"
+     id="path3818"
+     inkscape:connector-curvature="0"
+     sodipodi:nodetypes="cccccccc" />
+  <path
+     style="fill:none;stroke:#0c1925;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+     d="m 618.99839,452.97321 57.2631,-29.12206 -62.06469,-40.22711 58.61665,-29.30832 -50.57122,-29.30832 47.69785,-25.28562 -38.50309,-26.43495 37.92842,-22.41225"
+     id="path3820"
+     inkscape:connector-curvature="0"
+     sodipodi:nodetypes="cccccccc" />
+  <g
+     id="g3887"
+     transform="matrix(-1,0,0,1,911.87742,54.281223)">
+    <path
+       id="path3826"
+       d="m 267.6875,64.21875 8.59375,46.59375 -46.59375,-8.59375 44.625,15.875 -30.71875,36.03125 36.0625,-30.71875 15.84375,44.625 -6.78125,-36.75 171.03125,392.875 243.65625,-241.375 -398.0625,-157.90625 28.15625,5.1875 -44.65625,-15.875 30.75,-36.03125 -36.0625,30.71875 -15.84375,-44.65625 z"
+       style="fill:url(#linearGradient3891);fill-opacity:1;stroke:none;filter:url(#filter3838)"
+       inkscape:connector-curvature="0" />
+    <path
+       transform="matrix(0.54607407,0,0,0.54607407,127.8209,52.718563)"
+       sodipodi:type="star"
+       style="fill:#ffffff;fill-opacity:1;stroke:none"
+       id="path3828"
+       sodipodi:sides="6"
+       sodipodi:cx="281.58978"
+       sodipodi:cy="116.13913"
+       sodipodi:r1="53.737305"
+       sodipodi:r2="7.523222"
+       sodipodi:arg1="-0.78539816"
+       sodipodi:arg2="-0.26179939"
+       inkscape:flatsided="false"
+       inkscape:rounded="0"
+       inkscape:randomized="0"
+       d="m 319.5878,78.141117 -30.73114,36.050863 44.63937,15.85539 -46.58653,-8.58852 8.58852,46.58653 -15.85539,-44.63938 -36.05086,30.73114 30.73114,-36.05086 -44.63938,-15.85539 46.58653,8.58852 -8.58851,-46.586531 15.85539,44.639381 z" />
+  </g>
+  <g
+     transform="matrix(-1,0,0,1,965.89668,13.47944)"
+     id="g3893">
+    <path
+       d="m 319.5878,78.141117 -30.73114,36.050863 44.63937,15.85539 -46.58653,-8.58852 8.58852,46.58653 -15.85539,-44.63938 -36.05086,30.73114 30.73114,-36.05086 -44.63938,-15.85539 46.58653,8.58852 -8.58851,-46.586531 15.85539,44.639381 z"
+       inkscape:randomized="0"
+       inkscape:rounded="0"
+       inkscape:flatsided="false"
+       sodipodi:arg2="-0.26179939"
+       sodipodi:arg1="-0.78539816"
+       sodipodi:r2="7.523222"
+       sodipodi:r1="53.737305"
+       sodipodi:cy="116.13913"
+       sodipodi:cx="281.58978"
+       sodipodi:sides="6"
+       id="path3895"
+       style="fill:#ffffff;fill-opacity:1;stroke:none;filter:url(#filter3879)"
+       sodipodi:type="star"
+       transform="matrix(0.88928636,0,0,0.88928636,82.321727,12.858187)" />
+    <path
+       transform="matrix(0.47964589,0,0,0.47964589,197.6723,60.433475)"
+       sodipodi:type="star"
+       style="fill:#ffffff;fill-opacity:1;stroke:none"
+       id="path3897"
+       sodipodi:sides="6"
+       sodipodi:cx="281.58978"
+       sodipodi:cy="116.13913"
+       sodipodi:r1="53.737305"
+       sodipodi:r2="7.523222"
+       sodipodi:arg1="-0.78539816"
+       sodipodi:arg2="-0.26179939"
+       inkscape:flatsided="false"
+       inkscape:rounded="0"
+       inkscape:randomized="0"
+       d="m 319.5878,78.141117 -30.73114,36.050863 44.63937,15.85539 -46.58653,-8.58852 8.58852,46.58653 -15.85539,-44.63938 -36.05086,30.73114 30.73114,-36.05086 -44.63938,-15.85539 46.58653,8.58852 -8.58851,-46.586531 15.85539,44.639381 z" />
+  </g>
+  <g
+     transform="matrix(-1,0,0,1,1025.6627,14.628786)"
+     id="g3899">
+    <path
+       d="m 319.5878,78.141117 -30.73114,36.050863 44.63937,15.85539 -46.58653,-8.58852 8.58852,46.58653 -15.85539,-44.63938 -36.05086,30.73114 30.73114,-36.05086 -44.63938,-15.85539 46.58653,8.58852 -8.58851,-46.586531 15.85539,44.639381 z"
+       inkscape:randomized="0"
+       inkscape:rounded="0"
+       inkscape:flatsided="false"
+       sodipodi:arg2="-0.26179939"
+       sodipodi:arg1="-0.78539816"
+       sodipodi:r2="7.523222"
+       sodipodi:r1="53.737305"
+       sodipodi:cy="116.13913"
+       sodipodi:cx="281.58978"
+       sodipodi:sides="6"
+       id="path3901"
+       style="fill:#ffffff;fill-opacity:1;stroke:none;filter:url(#filter3879)"
+       sodipodi:type="star"
+       transform="matrix(0.88928636,0,0,0.88928636,82.321727,12.858187)" />
+    <path
+       transform="matrix(0.42428906,0,0,0.42428906,213.26021,66.862568)"
+       sodipodi:type="star"
+       style="fill:#ffffff;fill-opacity:1;stroke:none"
+       id="path3903"
+       sodipodi:sides="6"
+       sodipodi:cx="281.58978"
+       sodipodi:cy="116.13913"
+       sodipodi:r1="53.737305"
+       sodipodi:r2="7.523222"
+       sodipodi:arg1="-0.78539816"
+       sodipodi:arg2="-0.26179939"
+       inkscape:flatsided="false"
+       inkscape:rounded="0"
+       inkscape:randomized="0"
+       d="m 319.5878,78.141117 -30.73114,36.050863 44.63937,15.85539 -46.58653,-8.58852 8.58852,46.58653 -15.85539,-44.63938 -36.05086,30.73114 30.73114,-36.05086 -44.63938,-15.85539 46.58653,8.58852 -8.58851,-46.586531 15.85539,44.639381 z" />
+  </g>
+  <g
+     transform="matrix(-1,0,0,1,1022.2146,53.131877)"
+     id="g3905">
+    <path
+       d="m 319.5878,78.141117 -30.73114,36.050863 44.63937,15.85539 -46.58653,-8.58852 8.58852,46.58653 -15.85539,-44.63938 -36.05086,30.73114 30.73114,-36.05086 -44.63938,-15.85539 46.58653,8.58852 -8.58851,-46.586531 15.85539,44.639381 z"
+       inkscape:randomized="0"
+       inkscape:rounded="0"
+       inkscape:flatsided="false"
+       sodipodi:arg2="-0.26179939"
+       sodipodi:arg1="-0.78539816"
+       sodipodi:r2="7.523222"
+       sodipodi:r1="53.737305"
+       sodipodi:cy="116.13913"
+       sodipodi:cx="281.58978"
+       sodipodi:sides="6"
+       id="path3907"
+       style="fill:#ffffff;fill-opacity:1;stroke:none;filter:url(#filter3879)"
+       sodipodi:type="star"
+       transform="matrix(0.88928636,0,0,0.88928636,82.321727,12.858187)" />
+    <path
+       transform="matrix(0.42428906,0,0,0.42428906,213.26021,66.862568)"
+       sodipodi:type="star"
+       style="fill:#ffffff;fill-opacity:1;stroke:none"
+       id="path3909"
+       sodipodi:sides="6"
+       sodipodi:cx="281.58978"
+       sodipodi:cy="116.13913"
+       sodipodi:r1="53.737305"
+       sodipodi:r2="7.523222"
+       sodipodi:arg1="-0.78539816"
+       sodipodi:arg2="-0.26179939"
+       inkscape:flatsided="false"
+       inkscape:rounded="0"
+       inkscape:randomized="0"
+       d="m 319.5878,78.141117 -30.73114,36.050863 44.63937,15.85539 -46.58653,-8.58852 8.58852,46.58653 -15.85539,-44.63938 -36.05086,30.73114 30.73114,-36.05086 -44.63938,-15.85539 46.58653,8.58852 -8.58851,-46.586531 15.85539,44.639381 z" />
+  </g>
+  <g
+     id="g3883"
+     transform="matrix(-1,0,0,1,967.6207,96.232352)">
+    <path
+       transform="matrix(0.88928636,0,0,0.88928636,82.321727,12.858187)"
+       sodipodi:type="star"
+       style="fill:#ffffff;fill-opacity:1;stroke:none;filter:url(#filter3879)"
+       id="path3857"
+       sodipodi:sides="6"
+       sodipodi:cx="281.58978"
+       sodipodi:cy="116.13913"
+       sodipodi:r1="53.737305"
+       sodipodi:r2="7.523222"
+       sodipodi:arg1="-0.78539816"
+       sodipodi:arg2="-0.26179939"
+       inkscape:flatsided="false"
+       inkscape:rounded="0"
+       inkscape:randomized="0"
+       d="m 319.5878,78.141117 -30.73114,36.050863 44.63937,15.85539 -46.58653,-8.58852 8.58852,46.58653 -15.85539,-44.63938 -36.05086,30.73114 30.73114,-36.05086 -44.63938,-15.85539 46.58653,8.58852 -8.58851,-46.586531 15.85539,44.639381 z" />
+    <path
+       d="m 319.5878,78.141117 -30.73114,36.050863 44.63937,15.85539 -46.58653,-8.58852 8.58852,46.58653 -15.85539,-44.63938 -36.05086,30.73114 30.73114,-36.05086 -44.63938,-15.85539 46.58653,8.58852 -8.58851,-46.586531 15.85539,44.639381 z"
+       inkscape:randomized="0"
+       inkscape:rounded="0"
+       inkscape:flatsided="false"
+       sodipodi:arg2="-0.26179939"
+       sodipodi:arg1="-0.78539816"
+       sodipodi:r2="7.523222"
+       sodipodi:r1="53.737305"
+       sodipodi:cy="116.13913"
+       sodipodi:cx="281.58978"
+       sodipodi:sides="6"
+       id="path3855"
+       style="fill:#ffffff;fill-opacity:1;stroke:none"
+       sodipodi:type="star"
+       transform="matrix(0.42428906,0,0,0.42428906,213.26021,66.862568)" />
+  </g>
+  <g
+     transform="matrix(-0.46697012,0.88427309,0.88427309,0.46697012,710.9342,-89.097404)"
+     id="g3921"
+     inkscape:transform-center-x="-108.58025"
+     inkscape:transform-center-y="198.20461">
+    <path
+       inkscape:connector-curvature="0"
+       style="fill:url(#linearGradient3927);fill-opacity:1;stroke:none;filter:url(#filter3838)"
+       d="m 267.6875,64.21875 8.59375,46.59375 -46.59375,-8.59375 44.625,15.875 -30.71875,36.03125 36.0625,-30.71875 15.84375,44.625 -6.78125,-36.75 171.03125,392.875 243.65625,-241.375 -398.0625,-157.90625 28.15625,5.1875 -44.65625,-15.875 30.75,-36.03125 -36.0625,30.71875 -15.84375,-44.65625 z"
+       id="path3923" />
+    <path
+       d="m 319.5878,78.141117 -30.73114,36.050863 44.63937,15.85539 -46.58653,-8.58852 8.58852,46.58653 -15.85539,-44.63938 -36.05086,30.73114 30.73114,-36.05086 -44.63938,-15.85539 46.58653,8.58852 -8.58851,-46.586531 15.85539,44.639381 z"
+       inkscape:randomized="0"
+       inkscape:rounded="0"
+       inkscape:flatsided="false"
+       sodipodi:arg2="-0.26179939"
+       sodipodi:arg1="-0.78539816"
+       sodipodi:r2="7.523222"
+       sodipodi:r1="53.737305"
+       sodipodi:cy="116.13913"
+       sodipodi:cx="281.58978"
+       sodipodi:sides="6"
+       id="path3925"
+       style="fill:#ffffff;fill-opacity:1;stroke:none"
+       sodipodi:type="star"
+       transform="matrix(0.54607407,0,0,0.54607407,127.8209,52.718563)" />
+  </g>
+  <path
+     id="path3933"
+     style="fill:none;stroke:#ffffff;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;filter:url(#filter3952)"
+     d="m 721.28044,383.28277 1.11747,-6.50168 -1.62542,-5.18103 1.72701,-4.87627 10.15888,-0.30476 7.61916,-4.77467 2.33654,-3.04767 m -105.44917,109.41113 4.46991,-5.28261 0,-8.93982 13.40972,-13.81607 18.28598,-38.60375 10.56524,-16.2542 -8.93982,-12.59701 -10.97159,-26.00673 0,-6.90804 10.97159,-9.34617 29.25758,-13.81608 4.4699,-3.65719 13.00337,1.21906 m -75.58206,214.55553 -2.84449,-42.26093 3.25084,-8.12711"
+     inkscape:connector-curvature="0"
+     transform="matrix(-1,0,0,1,969.91939,14.628786)" />
+  <g
+     id="g3912"
+     transform="matrix(0.92473919,0.5761673,-0.5761673,0.92473919,347.46333,-11.762828)">
+    <path
+       sodipodi:type="star"
+       style="fill:#ffffff;fill-opacity:1;stroke:none;filter:url(#filter3904)"
+       id="path3914"
+       sodipodi:sides="6"
+       sodipodi:cx="102.4015"
+       sodipodi:cy="588.69531"
+       sodipodi:r1="71.4076"
+       sodipodi:r2="9.9970636"
+       sodipodi:arg1="-0.78539816"
+       sodipodi:arg2="-0.26179939"
+       inkscape:flatsided="false"
+       inkscape:rounded="0"
+       inkscape:randomized="0"
+       d="m 152.8943,538.20251 -40.83638,47.90537 59.31802,21.06908 -61.90545,-11.41266 11.41265,61.90546 -21.069074,-59.31803 -47.905368,40.83638 40.836377,-47.90537 -59.318023,-21.06907 61.905453,11.41265 -11.412655,-61.90545 21.06908,59.31802 z"
+       transform="matrix(2.7837608,0,0,2.7837608,-187.53604,-1048.4662)" />
+    <path
+       transform="matrix(0.98545106,0,0,0.98545106,-3.3864181,10.190337)"
+       d="m 152.8943,538.20251 -40.83638,47.90537 59.31802,21.06908 -61.90545,-11.41266 11.41265,61.90546 -21.069074,-59.31803 -47.905368,40.83638 40.836377,-47.90537 -59.318023,-21.06907 61.905453,11.41265 -11.412655,-61.90545 21.06908,59.31802 z"
+       inkscape:randomized="0"
+       inkscape:rounded="0"
+       inkscape:flatsided="false"
+       sodipodi:arg2="-0.26179939"
+       sodipodi:arg1="-0.78539816"
+       sodipodi:r2="9.9970636"
+       sodipodi:r1="71.4076"
+       sodipodi:cy="588.69531"
+       sodipodi:cx="102.4015"
+       sodipodi:sides="6"
+       id="path3916"
+       style="fill:#ffffff;fill-opacity:1;stroke:none"
+       sodipodi:type="star" />
+  </g>
+  <g
+     transform="matrix(0.92403252,0.38231387,-0.38231387,0.92403252,946.65622,-7.0688592)"
+     id="g3924">
+    <path
+       transform="matrix(2.7837608,0,0,2.7837608,-187.53604,-1048.4662)"
+       d="m 152.8943,538.20251 -40.83638,47.90537 59.31802,21.06908 -61.90545,-11.41266 11.41265,61.90546 -21.069074,-59.31803 -47.905368,40.83638 40.836377,-47.90537 -59.318023,-21.06907 61.905453,11.41265 -11.412655,-61.90545 21.06908,59.31802 z"
+       inkscape:randomized="0"
+       inkscape:rounded="0"
+       inkscape:flatsided="false"
+       sodipodi:arg2="-0.26179939"
+       sodipodi:arg1="-0.78539816"
+       sodipodi:r2="9.9970636"
+       sodipodi:r1="71.4076"
+       sodipodi:cy="588.69531"
+       sodipodi:cx="102.4015"
+       sodipodi:sides="6"
+       id="path3926"
+       style="fill:#ffffff;fill-opacity:1;stroke:none;filter:url(#filter3958)"
+       sodipodi:type="star" />
+    <path
+       sodipodi:type="star"
+       style="fill:#ffffff;fill-opacity:1;stroke:none"
+       id="path3928"
+       sodipodi:sides="6"
+       sodipodi:cx="102.4015"
+       sodipodi:cy="588.69531"
+       sodipodi:r1="71.4076"
+       sodipodi:r2="9.9970636"
+       sodipodi:arg1="-0.78539816"
+       sodipodi:arg2="-0.26179939"
+       inkscape:flatsided="false"
+       inkscape:rounded="0"
+       inkscape:randomized="0"
+       d="m 152.8943,538.20251 -40.83638,47.90537 59.31802,21.06908 -61.90545,-11.41266 11.41265,61.90546 -21.069074,-59.31803 -47.905368,40.83638 40.836377,-47.90537 -59.318023,-21.06907 61.905453,11.41265 -11.412655,-61.90545 21.06908,59.31802 z"
+       transform="matrix(0.98545106,0,0,0.98545106,-3.3864181,10.190337)" />
+  </g>
+  <g
+     id="g3918"
+     transform="matrix(0.5511002,0.25418892,-0.25418892,0.5511002,642.44815,232.07792)">
+    <path
+       sodipodi:type="star"
+       style="fill:#ffffff;fill-opacity:1;stroke:none;filter:url(#filter3938)"
+       id="path3920"
+       sodipodi:sides="6"
+       sodipodi:cx="102.4015"
+       sodipodi:cy="588.69531"
+       sodipodi:r1="71.4076"
+       sodipodi:r2="9.9970636"
+       sodipodi:arg1="-0.78539816"
+       sodipodi:arg2="-0.26179939"
+       inkscape:flatsided="false"
+       inkscape:rounded="0"
+       inkscape:randomized="0"
+       d="m 152.8943,538.20251 -40.83638,47.90537 59.31802,21.06908 -61.90545,-11.41266 11.41265,61.90546 -21.069074,-59.31803 -47.905368,40.83638 40.836377,-47.90537 -59.318023,-21.06907 61.905453,11.41265 -11.412655,-61.90545 21.06908,59.31802 z"
+       transform="matrix(2.7837608,0,0,2.7837608,-187.53604,-1048.4662)" />
+    <path
+       transform="matrix(0.98545106,0,0,0.98545106,-3.3864181,10.190337)"
+       d="m 152.8943,538.20251 -40.83638,47.90537 59.31802,21.06908 -61.90545,-11.41266 11.41265,61.90546 -21.069074,-59.31803 -47.905368,40.83638 40.836377,-47.90537 -59.318023,-21.06907 61.905453,11.41265 -11.412655,-61.90545 21.06908,59.31802 z"
+       inkscape:randomized="0"
+       inkscape:rounded="0"
+       inkscape:flatsided="false"
+       sodipodi:arg2="-0.26179939"
+       sodipodi:arg1="-0.78539816"
+       sodipodi:r2="9.9970636"
+       sodipodi:r1="71.4076"
+       sodipodi:cy="588.69531"
+       sodipodi:cx="102.4015"
+       sodipodi:sides="6"
+       id="path3922"
+       style="fill:#ffffff;fill-opacity:1;stroke:none"
+       sodipodi:type="star" />
+  </g>
+  <g
+     id="g3908"
+     transform="matrix(0.70503302,0.34610836,-0.34610836,0.70503302,480.1456,132.24373)">
+    <path
+       transform="matrix(2.7837608,0,0,2.7837608,-187.53604,-1048.4662)"
+       d="m 152.8943,538.20251 -40.83638,47.90537 59.31802,21.06908 -61.90545,-11.41266 11.41265,61.90546 -21.069074,-59.31803 -47.905368,40.83638 40.836377,-47.90537 -59.318023,-21.06907 61.905453,11.41265 -11.412655,-61.90545 21.06908,59.31802 z"
+       inkscape:randomized="0"
+       inkscape:rounded="0"
+       inkscape:flatsided="false"
+       sodipodi:arg2="-0.26179939"
+       sodipodi:arg1="-0.78539816"
+       sodipodi:r2="9.9970636"
+       sodipodi:r1="71.4076"
+       sodipodi:cy="588.69531"
+       sodipodi:cx="102.4015"
+       sodipodi:sides="6"
+       id="path3881"
+       style="fill:#ffffff;fill-opacity:1;stroke:none;filter:url(#filter3966)"
+       sodipodi:type="star" />
+    <path
+       sodipodi:type="star"
+       style="fill:#ffffff;fill-opacity:1;stroke:none"
+       id="path3879"
+       sodipodi:sides="6"
+       sodipodi:cx="102.4015"
+       sodipodi:cy="588.69531"
+       sodipodi:r1="71.4076"
+       sodipodi:r2="9.9970636"
+       sodipodi:arg1="-0.78539816"
+       sodipodi:arg2="-0.26179939"
+       inkscape:flatsided="false"
+       inkscape:rounded="0"
+       inkscape:randomized="0"
+       d="m 152.8943,538.20251 -40.83638,47.90537 59.31802,21.06908 -61.90545,-11.41266 11.41265,61.90546 -21.069074,-59.31803 -47.905368,40.83638 40.836377,-47.90537 -59.318023,-21.06907 61.905453,11.41265 -11.412655,-61.90545 21.06908,59.31802 z"
+       transform="matrix(0.98545106,0,0,0.98545106,-3.3864181,10.190337)" />
+  </g>
+</svg>
diff --git a/data/config/controllers.xml b/data/config/controllers.xml
new file mode 100644 (file)
index 0000000..0d79417
--- /dev/null
@@ -0,0 +1,414 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<controllers>
+       <joystick>
+               <controller type="guitar" name="GUITAR_GUITARHERO_OEM">
+                       <!-- Licensed by Sony Computer Entertainment Gamepad for PS(R)3 (13 buttons, 4 axes, 1 hats, 0 balls) -->
+                       <!-- Use this device in Rock Band mode instead, it works much better. -->
+                       <description>OEM wireless guitar in Guitar Hero I/II/III mode</description>
+                       <device regex="NO AUTODETECT" />
+                       <mapping>
+                               <button hw="7" map="green" />
+                               <button hw="2" map="red" />
+                               <button hw="3" map="yellow" />
+                               <button hw="1" map="blue" />
+                               <button hw="0" map="orange" />
+                               <button hw="6" map="godmode" />
+                               <button hw="8" map="cancel" />
+                               <button hw="9" map="start" />
+                               <button hw="10" map="up" />
+                               <button hw="11" map="down" />
+                               <button hw="5" map="moreup" /><!-- Red solo button -->
+                               <button hw="4" map="moredown" /><!-- Yellow solo button -->
+                               <axis hw="0" negative="left" /><!-- Blue solo button -->
+                               <axis hw="2" negative="right" /><!-- Orange solo button -->
+                               <axis hw="1" negative="whammy" />
+                               <axis hw="3" /><!-- Mic switch, gives varying negative and positive values depending on position -->
+                               <hat hw="0" up="pick_up" down="pick_down"/><!-- left = Green solo button _not_ pressed, right is unused -->
+                       </mapping>
+               </controller>
+               <controller type="guitar" name="GUITAR_GUITARHERO">
+                       <description>Guitar Hero 3 guitar</description>
+                       <device regex="Guitar Hero3" />
+                       <mapping>
+                               <button hw="0" map="yellow" />
+                               <button hw="1" map="green" />
+                               <button hw="2" map="red" />
+                               <button hw="3" map="blue" />
+                               <button hw="4" map="orange" />
+                               <button hw="5" map="godmode" />
+                               <button hw="8" map="cancel" />
+                               <button hw="9" map="start" />
+                               <button hw="12" map="godmode" /><!-- PS3 GH3 Les Paul has no button 5, use the PS button -->
+                               <axis hw="2" positive="whammy" />
+                               <axis hw="3" /><!-- This is the GH:WT solo frets, values roughly: G: -.8, R: -.3, Y: .1, B: .5, O: 1 - Falls back to 0 when idle. -->
+                               <axis hw="4" negative="left" positive="right" />
+                               <axis hw="5" negative="pick_up" positive="pick_down" />
+                       </mapping>
+               </controller>
+               <controller type="guitar" name="GUITAR_GUITARHERO5">
+                       <description>Guitar Hero 5/Band Hero/Warriors of Rock guitar</description>
+                       <device regex="Entertainment Guitar Hero5|GuitarHero for Playstation" />
+                       <mapping>
+                               <button hw="0" map="yellow" />
+                               <button hw="1" map="green" />
+                               <button hw="2" map="red" />
+                               <button hw="3" map="blue" />
+                               <button hw="4" map="orange" />
+                               <button hw="8" map="cancel" />
+                               <button hw="9" map="start" />
+                               <axis hw="2" positive="whammy" />
+                               <axis hw="4" negative="left" positive="right" />
+                               <axis hw="5" negative="up" positive="down" />
+                       </mapping>
+               </controller>
+               <controller type="guitar" name="GUITAR_GUITARHERO_XPLORER">
+                       <description>Guitar Hero X-plorer guitar</description>
+                       <device regex="Guitar Hero X-plorer" />
+                       <mapping> 
+                               <button hw="0" map="green" />
+                               <button hw="1" map="red" />
+                               <button hw="2" map="blue" />
+                               <button hw="3" map="yellow" />
+                               <button hw="4" map="orange" />
+                               <button hw="6" map="cancel" />
+                               <button hw="7" map="start" />
+                               <axis hw="1" negative="pick_up" positive="pick_down"/>
+                               <axis hw="2" map="whammy" />
+                               <axis hw="3" map="godmode"/>
+                               <axis hw="4" negative="left" positive="right" />
+                               <axis hw="5" negative="up" positive="down" />
+                       </mapping>
+               </controller>
+               <controller type="guitar" name="GUITAR_ROCKBAND_XBOX360">
+                       <description>Rock Band guitar Xbox 360</description>
+                       <device regex="Harmonix Guitar .* Xbox|Harmonix Rock Band Guitar" />
+                       <mapping> 
+                               <button hw="0" map="green" />
+                               <button hw="1" map="red" />
+                               <button hw="2" map="blue" />
+                               <button hw="3" map="yellow" />
+                               <button hw="4" map="orange" />
+                               <button hw="6" map="cancel" />
+                               <button hw="7" map="start" />
+                               <axis hw="3" negative="godmode"/>
+                               <axis hw="4" map="whammy"/>
+                               <hat hw="0" up="pick_up" down="pick_down" left="left" right="right" />
+                       </mapping>
+               </controller>
+               <controller type="guitar" name="GUITAR_ROCKBAND_XBOXADAPTER">
+                       <description>Rock Band guitar Xbox with USB adapter</description>
+                       <device regex="Generic X-Box pad" />
+                       <mapping> 
+                               <button hw="0" map="green" />
+                               <button hw="1" map="red" />
+                               <button hw="2" map="blue" />
+                               <button hw="3" map="yellow" />
+                               <button hw="4" map="orange" />
+                               <button hw="10" map="cancel" />
+                               <button hw="6" map="start" />
+                               <axis hw="4" map="godmode" />
+                               <axis hw="3" map="whammy" />
+                               <hat hw="0" up="pick_up" down="pick_down" left="left" right="right" />
+                       </mapping>
+               </controller>
+               <controller type="guitar" name="GUITAR_ROCKBAND_PS3">
+                       <!-- Licensed by Sony Computer Entertainment America Harmonix Guitar for PlayStation®3 (13 buttons, 4 axes, 1 hats, 0 balls) -->
+                       <description>Rock Band guitar PS3</description>
+                       <device regex="Harmonix Guitar .* PlayStation" />
+                       <mapping>
+                               <button hw="0" map="blue" />
+                               <button hw="1" map="green" />
+                               <button hw="2" map="red" />
+                               <button hw="3" map="yellow" />
+                               <button hw="4" map="orange" />
+                               <button hw="5" map="godmode" />
+                               <button hw="8" map="cancel" />
+                               <button hw="9" map="start" />
+                               <button hw="6" map="godmode" /><!-- This button is a modifier for the solo frets, doesn't exist by itself -->
+                               <button hw="12" /> <!-- PS button -->
+                               <axis hw="2" map="whammy" /><!-- -1 (fully released) to 1 (fully pressed) but resets to 0 after a while when fully released -->
+                               <axis hw="3" /><!-- Mic switch, values roughly -.9, -.4, .1, .4, .9; sends 0 after a short while -->
+                               <!-- My device does not use these events; please report a bug if yours does:
+                               <axis hw="1" negative="pick_up" positive="pick_down"/>
+                               -->
+                               <axis hw="4" negative="left" positive="right" />
+                               <axis hw="5" negative="pick_up" positive="pick_down" />
+                               <hat hw="0" up="pick_up" down="pick_down" left="left" right="right" />
+                       </mapping>
+               </controller>
+               <controller type="guitar" name="GUITAR_HAMA_PS2">
+                       <description>Hama Guitar for PS2 with converter</description>
+                       <device regex="PS  Converter" />
+                       <mapping>
+                               <button hw="0" map="yellow" />
+                               <button hw="1" map="red" />
+                               <button hw="2" map="blue" />
+                               <button hw="3" map="orange" />
+                               <button hw="4" map="godmode" />
+                               <button hw="5" map="green" />
+                               <button hw="8" map="cancel" />
+                               <button hw="9" map="start" />
+                               <axis hw="4" negative="left" positive="right" />
+                               <axis hw="5" negative="up" positive="down" />
+                       </mapping>
+               </controller>
+               <controller type="guitar" name="GUITAR_PS2">
+                       <description>Guitar Hero 2 with PS2/USB adaptor</description>
+                       <device regex="Twin USB Joystick.*" />
+                       <mapping>
+                               <button hw="0" map="yellow" />
+                               <button hw="1" map="red" />
+                               <button hw="2" map="blue" />
+                               <button hw="3" map="orange" />
+                               <button hw="5" map="green" />
+                               <button hw="8" map="godmode" />
+                               <button hw="8" map="cancel" />
+                               <button hw="9" map="start" />
+                               <axis hw="1" negative="up" positive="down" />
+                               <axis hw="1" negative="pick_up" positive="pick_down" />
+                       </mapping>
+               </controller>
+               <!-- Not managed
+               <controller type="guitar" name="GUITAR_PRO_PS3">
+                       <description>Rock Band Pro Guitar for PS3</description>
+                       <device regex="Licensed by Sony Computer Entertainment America Harmonix RB3 Mustang Guitar for PlayStation" />
+                       <mapping>
+                       </mapping>
+               </controller>
+               -->
+               <controller type="drumkit" name="DRUMS_GUITARHERO">
+                       <description>Guitar Hero 4 drum kit</description>
+                       <device regex="Guitar Hero4" />
+                       <mapping>
+                               <button hw="0" map="blue" />
+                               <button hw="1" map="green" />
+                               <button hw="2" map="red" />
+                               <button hw="3" map="yellow" />
+                               <button hw="4" map="kick" />
+                               <button hw="5" map="green" />
+                               <button hw="8" map="cancel" />
+                               <button hw="9" map="start" />
+                               <axis hw="4" negative="left" positive="right" />
+                               <axis hw="5" negative="up" positive="down" />
+                       </mapping>
+               </controller>
+               <controller type="drumkit" name="DRUMS_GUITARHERO5">
+                       <description>Guitar Hero 5/Band Hero drum kit</description>
+                       <device regex="Drum Guitar Hero5" />
+                       <mapping>
+                               <button hw="0" map="blue" />
+                               <button hw="1" map="green" />
+                               <button hw="2" map="red" />
+                               <button hw="3" map="yellow" />
+                               <button hw="4" map="kick" />
+                               <button hw="5" map="green" />
+                               <button hw="8" map="cancel" />
+                               <button hw="9" map="start" />
+                               <axis hw="4" negative="left" positive="right" />
+                               <axis hw="5" negative="up" positive="down" />
+                       </mapping>
+               </controller>
+               <controller type="drumkit" name="DRUMS_ROCKBAND_WII">
+                       <description>RockBand Wii drum kit</description>
+                       <device regex="Harmonix Drum Controller for Nintendo Wii" />
+                       <mapping>
+                               <button hw="0" map="blue" />
+                               <button hw="1" map="green" />
+                               <button hw="2" map="red" />
+                               <button hw="3" map="yellow" />
+                               <button hw="4" map="kick" />
+                               <button hw="8" map="cancel" />
+                               <button hw="9" map="start" />
+                       </mapping>
+               </controller>
+               <controller type="drumkit" name="DRUMS_ROCKBAND_PS3">
+                       <description>RockBand PS3 drum kit</description>
+                       <device regex="Harmonix Drum [Kk]it for PlayStation" />
+                       <mapping>
+                               <button hw="0" map="blue" />
+                               <button hw="1" map="green" />
+                               <button hw="2" map="red" />
+                               <button hw="3" map="yellow" />
+                               <button hw="4" map="kick" />
+                               <button hw="8" map="cancel" />
+                               <button hw="9" map="start" />
+                               <button hw="12" /><!-- PS button -->
+                               <axis hw="4" negative="left" positive="right" />
+                               <axis hw="5" negative="up" positive="down" />
+                       </mapping>
+               </controller>
+               <controller type="drumkit" name="DRUMS_ROCKBAND_XBOX360">
+                       <description>RockBand XBox drum kit</description>
+                       <device regex="Harmonix Drum [Kk]it for Xbox|Harmonix Rock Band Drumkit" />
+                       <mapping>
+                               <button hw="0" map="green" />
+                               <button hw="1" map="red" />
+                               <button hw="2" map="blue" />
+                               <button hw="3" map="yellow" />
+                               <button hw="4" map="kick" />
+                               <button hw="6" map="cancel" />
+                               <button hw="7" map="start" />
+                       </mapping>
+               </controller>
+               <controller type="dancepad" name="DANCEPAD_GENERIC">
+                       <description>Generic dancepad</description>
+                       <device regex="Dance mat|RedOctane USB Pad|Redoctane XBOX DDR|Positive Gaming Impact USB pad|WiseGroup\.,Ltd USB Deluxe Dance Mat" />
+                       <mapping>
+                               <button hw="0" map="left" />
+                               <button hw="1" map="down" />
+                               <button hw="2" map="up" />
+                               <button hw="3" map="right" />
+                               <button hw="4" map="up-left" />
+                               <button hw="5" map="up-right" />
+                               <button hw="6" map="down-left" />
+                               <button hw="7" map="down-right" />
+                               <button hw="8" map="start" />
+                               <button hw="9" map="cancel" />
+                       </mapping>
+               </controller>
+               <controller type="dancepad" name="DANCEPAD_TIGERGAME">
+                       <description>TigerGame dancepad</description>
+                       <device regex="TigerGame" />
+                       <mapping>
+                               <button hw="0" map="start" />
+                               <button hw="1" map="cancel" />
+                               <button hw="8" map="left" />
+                               <button hw="9" map="right" />
+                               <button hw="10" map="down" />
+                               <button hw="11" map="up" />
+                       </mapping>
+               </controller>
+               <controller type="dancepad" name="DANCEPAD_EMS2">
+                       <description>EMS PS2/PC dancepad adapter</description>
+                       <device regex="0b43:0003" />
+                       <mapping>
+                               <button hw="0" map="down-left" />
+                               <button hw="1" map="up-right" />
+                               <button hw="2" map="up-left" />
+                               <button hw="3" map="down-right" />
+                               <button hw="8" map="start" />
+                               <button hw="9" map="cancel" />
+                               <button hw="12" map="up" />
+                               <button hw="13" map="right" />
+                               <button hw="14" map="down" />
+                               <button hw="15" map="left" />
+                       </mapping>
+               </controller>
+               <controller type="dancepad" name="DANCEPAD_2TECH">
+                       <description>2-tech usb dancepad</description>
+                       <device regex="USB Gamepad" />
+                       <mapping>
+                               <button hw="0" map="left" />
+                               <button hw="1" map="down" />
+                               <button hw="2" map="up" />
+                               <button hw="3" map="right" />
+                               <button hw="4" map="up-left" />
+                               <button hw="5" map="up-right" />
+                               <button hw="6" map="down-left" />
+                               <button hw="7" map="down-right" />
+                               <button hw="8" map="cancel" />
+                               <button hw="9" map="start" />
+                       </mapping>
+               </controller>
+               <controller type="dancepad" name="DANCEPAD_THRUST">
+                       <description>Thrustmaster dancepad</description>
+                       <device regex="DDR2SET DDR2SET" />
+                       <mapping>
+                               <button hw="0" map="down" />
+                               <button hw="1" map="right" />
+                               <button hw="2" map="up-right" />
+                               <button hw="3" map="left" />
+                               <button hw="4" map="up" />
+                               <button hw="5" map="up-left" />
+                               <button hw="6" map="down-left" />
+                               <button hw="7" map="down-right" />
+                               <button hw="8" map="start" />
+                               <button hw="9" map="cancel" />
+                       </mapping>
+               </controller>
+               <controller type="keytar" name="KEYTAR_GENERIC">
+                       <description>Generic keytar</description>
+                       <device regex="NO MATCH" />
+                       <mapping>
+                               <button hw="0" map="C" />
+                               <button hw="1" map="D" />
+                               <button hw="2" map="E" />
+                               <button hw="3" map="F" />
+                               <button hw="4" map="G" />
+                               <button hw="5" map="godmode" />
+                               <axis hw="4" negative="left" positive="right" />
+                               <axis hw="5" negative="up" positive="down" />
+                       </mapping>
+               </controller>
+       </joystick>
+       <midi>
+               <controller type="piano" name="MIDI_PIANO">
+                       <description>Standard MIDI piano/keyboard</description>
+                       <major min="1" max="9" />
+               </controller>
+               <controller type="drumkit" name="MIDI_DRUMS">
+                       <description>Standard Midi drums</description>
+                       <!--
+                                PortMidi device name for USB-connected drum controllers Millenium MPS-600 and Alesis DM6 is
+                                "e-drum MIDI 1" (same name even if multiple devices are connected at the same time).
+                                Still, we don't want to filter by device here as filtering by channel should be enough.
+            -->
+                       <!-- Standard MIDI drum channels are 10 and 11. -->
+                       <channel min="10" max="11" />
+                       <mapping>
+                               <!-- Notes below 35 and above 81 are non-standardized but tested to work. -->
+                               <button hw="22" map="yellow-cymbal" name="Closed Hi-Hat Rim" /><!-- Closed Hi-Hat Rim on MPS-600 -->
+                               <button hw="23" map="yellow-cymbal" name="Half-Open Hi-Hat" /><!-- Half-Open Hi-Hat on MPS-600 -->
+                               <button hw="24" map="yellow-cymbal" name="Half-Open Hi-Hat Rim" /><!-- Half-Open Hi-Hat Rim on MPS-600 -->
+                               <button hw="26" map="yellow-cymbal" name="Open Hi-Hat Rim" /><!-- Open Hi-Hat Rim on MPS-600 -->
+                               <button hw="35" map="kick" name="Acoustic Bass Drum" />
+                               <button hw="36" map="kick" name="Bass Drum 1" /><!-- Kick on MPS-600 & DM6 -->
+                               <button hw="37" map="red" name="Side Stick" />
+                               <button hw="38" map="red" name="Acoustic Snare" /><!-- Snare on MPS-600 & DM6 -->
+                               <button hw="39" map="green-tom" name="Hand Clap" /><!-- Tom 4 Rim on MPS-600 -->
+                               <button hw="40" map="red" name="Electric Snare" /><!-- Snare Rim on MPS-600 & DM6 -->
+                               <button hw="41" map="green-tom" name="Low Floor Tom" /><!-- Tom 4 on MPS-600 -->
+                               <button hw="42" map="yellow-cymbal" name="Closed Hi-Hat" /><!-- Closed Hi-Hat on MPS-600 & DM6 -->
+                               <button hw="43" map="green-tom" name="High Floor Tom" /><!-- Tom 3 on MPS-600 & DM6 -->
+                               <button hw="44" map="" name="Pedal Hi-Hat" /><!-- Closing Hi-Hat (pedal press) on MPS-600 & DM6 -->
+                               <button hw="45" map="blue-tom" name="Low Tom" /><!-- Tom 2 on MPS-600 & DM6 -->
+                               <button hw="46" map="yellow-cymbal" name="Open Hi-Hat" /><!-- Open Hi-Hat on MPS-600 & DM6 -->
+                               <button hw="47" map="blue-tom" name="Low-Mid Tom" /><!-- Tom 2 Rim on MPS-600 -->
+                               <button hw="48" map="yellow-tom" name="Hi-Mid Tom" /><!-- Tom 1 on MPS-600 & DM6 -->
+                               <button hw="49" map="green-cymbal" name="Crash Cymbal 1" /><!-- Crash 1 on MPS-600 & DM6 -->
+                               <button hw="50" map="yellow-tom" name="High Tom" /><!-- Tom 1 Rim on MPS-600 -->
+                               <button hw="51" map="blue-cymbal" name="Ride Cymbal 1" /><!-- Ride on MPS-600 & DM6 -->
+                               <button hw="52" map="green-cymbal" name="Chinese Cymbal" /><!-- Crash 2 Rim on MPS-600 -->
+                               <button hw="53" map="" name="Ride Bell" />
+                               <button hw="54" map="" name="Tambourine" />
+                               <button hw="55" map="green-cymbal" name="Splash Cymbal" /><!-- Crash 1 Rim on MPS-600 -->
+                               <button hw="56" map="" name="Cowbell" />
+                               <button hw="57" map="green-cymbal" name="Crash Cymbal 2" /><!-- Crash 2 on MPS-600 -->
+                               <button hw="58" map="green-tom" name="Vibraslap" /><!-- Tom 3 Rim on MPS-600 -->
+                               <button hw="59" map="blue-cymbal" name="Ride Cymbal 2" /><!-- Ride Rim on MPS-600 -->
+                               <button hw="60" map="" name="Hi Bongo" />
+                               <button hw="61" map="" name="Low Bongo" />
+                               <button hw="62" map="" name="Mute Hi Conga" />
+                               <button hw="63" map="" name="Open Hi Conga" />
+                               <button hw="64" map="" name="Low Conga" />
+                               <button hw="65" map="" name="High Timbale" />
+                               <button hw="66" map="" name="Low Timbale" />
+                               <button hw="67" map="" name="High Agogo" />
+                               <button hw="68" map="" name="Low Agogo" />
+                               <button hw="69" map="" name="Cabasa" />
+                               <button hw="70" map="" name="Maracas" />
+                               <button hw="71" map="" name="Short Whistle" />
+                               <button hw="72" map="" name="Long Whistle" />
+                               <button hw="73" map="" name="Short Guiro" />
+                               <button hw="74" map="" name="Long Guiro" />
+                               <button hw="75" map="" name="Claves" />
+                               <button hw="76" map="" name="Hi Wood Block" />
+                               <button hw="77" map="" name="Low Wood Block" />
+                               <button hw="78" map="" name="Mute Cuica" />
+                               <button hw="79" map="" name="Open Cuica" />
+                               <button hw="80" map="" name="Mute Triangle" />
+                               <button hw="81" map="" name="Open Triangle" />
+                       </mapping>
+               </controller>
+       </midi>
+</controllers>
diff --git a/data/config/schema.xml b/data/config/schema.xml
new file mode 100644 (file)
index 0000000..df96741
--- /dev/null
@@ -0,0 +1,293 @@
+<?xml version="1.0"?>
+<!--
+DO NOT EDIT THIS FILE!
+This is a config schema with built-in defaults for Performous.
+
+System-wide settings go to /etc/xdg/performous/config.xml and user settings
+go to ~/.config/performous/config.xml but you should generally let Performous
+modify them instead of touching the XML yourself. Press Ctrl+S in config menu
+to save the current settings to XML.
+-->
+<performous>
+       <!-- Menu definitions.
+       All config entries with the same prefix as the menu entry are displayed in the menu,
+       except if they have attribute hidden="true". The options display in the same order
+       as they are specified here.
+       -->
+       <menu>
+               <entry name="game">
+                       <short>Game</short>
+                       <long>Gameplay related options</long>
+               </entry>
+               <entry name="graphic">
+                       <short>Graphic</short>
+                       <long>Configure rendering and video settings</long>
+               </entry>
+               <entry name="AudioDevices">
+                       <!-- Handled internally by Performous -->
+                       <short>Audio Devices</short>
+                       <long>Setup microphones and playback</long>
+               </entry>
+               <entry name="audio">
+                       <short>Audio</short>
+                       <long>Configure general audio settings</long>
+               </entry>
+               <entry name="Paths">
+                       <short>Paths</short>
+                       <long>Setup song and data paths</long>
+               </entry>
+       </menu>
+
+       <!-- Gameplay preferences -->
+       <entry name="game/karaoke_mode" type="int" value="0">
+               <limits>
+                       <enum>Off</enum>
+                       <enum>On - normal text</enum>
+                       <enum>On - centered text</enum>
+               </limits>
+               <short>Karaoke mode</short>
+               <long>Hide pitch wave, notes and scoring.</long>
+       </entry>
+       <entry name="game/Textstyle" type="int" value="0">
+               <limits>
+                       <enum>Western mode</enum>
+                       <enum>Asian mode</enum>
+               </limits>
+               <short>Lyric highlight style</short>
+               <long>Hide pitch wave, notes and scoring.</long>
+       </entry>
+       <entry name="game/autoplay" type="bool" value="false">
+               <short>Autoplay</short>
+               <long>Keep playing random songs after the playlist is empty.</long>
+       </entry>
+       <entry name="game/pitch" type="bool" value="true">
+               <short>Pitch waves</short>
+               <long>Enable singing pitch display (when not in karaoke mode).</long>
+       </entry>
+       <entry name="game/theme" type="int" value="-1">
+               <limits min="-1" max="-1" step="0" />
+               <!-- Enum options added dynamically by scanning theme folders -->
+               <short>Theme</short>
+               <long>Name of the theme to use.</long>
+       </entry>
+       <entry name="game/keyboard_guitar" type="bool" value="true">
+               <short>Keyboard as guitar</short>
+               <long>Enable keyboard as guitar (Frets on Fire mode).</long>
+       </entry>
+       <entry name="game/keyboard_drumkit" type="bool" value="true">
+               <short>Keyboard as drumkit</short>
+               <long>Enable keyboard as drumkit.</long>
+       </entry>
+       <entry name="game/keyboard_dancepad" type="bool" value="true">
+               <short>Keyboard as dance pad</short>
+               <long>Enable keyboard as dance pad.</long>
+       </entry>
+       <entry name="game/keyboard_keytar" type="bool" value="true">
+               <short>Keyboard as keytar</short>
+               <long>Enable keyboard as keytar.</long>
+       </entry>
+       <entry name="game/instrument0" type="int" value="0">
+               <limits>
+                       <enum>Auto</enum>
+                       <!-- Options added dynamically from controllers.xml -->
+               </limits>
+               <short>Force controller A's type</short>
+               <long>Override autodetection and force the first controller to the given type.</long>
+       </entry>
+       <entry name="game/instrument1" type="int" value="0">
+               <limits>
+                       <enum>Auto</enum>
+                       <!-- Options added dynamically from controllers.xml -->
+               </limits>
+               <short>Force controller B's type</short>
+               <long>Override autodetection and force the second controller to the given type.</long>
+       </entry>
+       <entry name="game/instrument2" type="int" value="0">
+               <limits>
+                       <enum>Auto</enum>
+                       <!-- Options added dynamically from controllers.xml -->
+               </limits>
+               <short>Force controller C's type</short>
+               <long>Override autodetection and force the third controller to the given type.</long>
+       </entry>
+       <entry name="game/instrument3" type="int" value="0">
+               <limits>
+                       <enum>Auto</enum>
+                       <!-- Options added dynamically from controllers.xml -->
+               </limits>
+               <short>Force controller D's type</short>
+               <long>Override autodetection and force the fourth controller to the given type.</long>
+       </entry>
+       <entry name="game/instruments" type="string_list">
+               <!-- Should be SDL_ID:{GUITAR_GUITARHERO|GUITAR_GUITARHERO_XPLORER|GUITAR_ROCKBAND_PS3|GUITAR_ROCKBAND_XB360|DRUMS_GUITARHERO|DRUMS_ROCKBAND_PS3|DRUMS_ROCKBAND_XB360|DRUMS_MIDI|DANCEPAD_GENERIC|DANCEPAD_TIGERGAME|DANCEPAD_2TECH}
+                    example:
+                       <stringvalue>0:GUITAR_GUITARHERO</stringvalue>
+               -->
+               <short>Joystick configuration</short>
+               <long>Force joystick to some kind of instrument.</long>
+       </entry>
+       <entry name="game/midi_input" type="string">
+               <short>Hardware MIDI input device</short>
+               <long>Regex for matching the MIDI devices to use. The default is to use all available devices.</long>
+               <stringvalue></stringvalue>
+       </entry>
+       <entry name="game/fallback_encoding" type="int" value="2">
+               <limits>
+                       <enum>CP1250</enum>
+                       <enum>CP1251</enum>
+                       <enum>CP1252</enum>
+                       <enum>CP1253</enum>
+                       <enum>CP1254</enum>
+                       <enum>CP1255</enum>
+                       <enum>CP1256</enum>
+                       <enum>CP1257</enum>
+                       <enum>CP1258</enum>
+               </limits>
+               <short>Fallback song encoding</short>
+               <long>Pick the text codec used for song files that are not UTF-8.</long>
+       </entry>
+
+       <!-- Graphic preferences -->
+       <entry name="graphic/window_width" type="int" value="800" hidden="true">
+               <ui unit=" pixels" />
+               <limits min="320" max="4096" step="16" />
+               <short>Windowed width</short>
+               <long>The width of the window.</long>
+       </entry>
+       <entry name="graphic/window_height" type="int" value="600" hidden="true">
+               <ui unit=" pixels" />
+               <limits min="240" max="2048" step="16" />
+               <short>Windowed height</short>
+               <long>The height of the window.</long>
+       </entry>
+       <entry name="graphic/fullscreen" type="bool" value="false">
+               <short>Fullscreen mode</short>
+               <long>Enable fullscreen mode on startup.</long>
+       </entry>
+       <entry name="graphic/stereo3d" type="bool" value="false">
+               <short>Stereoscopic 3D</short>
+               <long>Enable 3D rendering of Performous.</long>
+       </entry>
+       <entry name="graphic/stereo3dtype" type="int" value="0">
+               <limits>
+                       <enum>Red/Cyan</enum>
+                       <enum>Green/Magenta</enum>
+                       <enum>Over/Under</enum>
+               </limits>
+               <short>Stereo3D type</short>
+               <long>Some modes may only get activated in fullscreen mode.</long>
+       </entry>
+       <entry name="graphic/stereo3dseparation" type="float" value="50">
+               <ui unit=" %" />
+               <limits min="0" max="100" step="2" />
+               <short>Stereo3D separation</short>
+               <long>The strength of the effect. Experiment with different settings for best results.</long>
+       </entry>
+       <entry name="graphic/video" type="bool" value="true">
+               <short>Video playback</short>
+               <long>Allows completely disabling background videos. It is recommended to leave this enabled as Performous will still smoothly fade out the video if your computer is not fast enough.</long>
+       </entry>
+       <entry name="graphic/webcam" type="bool" value="false">
+               <short>Webcam background</short>
+               <long>Performous can use webcam as a background video. Disable it if Performous crashes while entering a song.</long>
+       </entry>
+       <entry name="graphic/webcamid" type="int" value="-1">
+               <limits min="-1" max="9" step="1" />
+               <short>Webcam id</short>
+               <long>Use -1 to autodetect or a number starting from 0 to choose specific device.</long>
+       </entry>
+       <entry name="graphic/svg_lod" type="float" value="1.0">
+               <ui unit="x" />
+               <limits min="0.5" max="3.0" step="0.1" />
+               <short>SVG quality</short>
+               <long>Larger numbers cause vector graphics to be rendered in higher resolution. Decrease this to make navigating in menus faster.</long>
+       </entry>
+       <entry name="graphic/text_lod" type="float" value="1.0">
+               <ui unit="x" />
+               <limits min="0.5" max="3.0" step="0.1" />
+               <short>Text quality</short>
+               <long>Larger numbers cause text to be rendered in higher resolution. Decrease this to make everything a little faster.</long>
+       </entry>
+       <entry name="graphic/fps" type="bool" value="false">
+               <short>Benchmark mode</short>
+               <long>Framerate limit of 100 FPS is removed and the game instead renders at full speed. FPS values are printed to console. Please note that the display drivers may still limit the rendering speed to the screen refresh rate.</long>
+       </entry>
+
+       <!-- Audio preferences -->
+       <entry name="audio/latency" type="float" value="0.075">
+               <ui unit=" ms" multiplier="1000" />
+               <limits min="0.0" max="0.25" step="0.005" />
+               <short>Suggested latency</short>
+               <long>This is a hint for the audio engine about the desired latency. Set this as low as possible while retaining clear audio playback. Requires restart.</long>
+       </entry>
+       <entry name="audio/video_delay" type="float" value="0.06">
+               <ui unit=" ms" multiplier="1000" />
+               <limits min="-0.5" max="0.5" step="0.01" />
+               <short>Audio/video latency</short>
+               <long>Affects all modes. Use negative value if your display input lag is greater than the sound card output latency, positive values in the opposite case and zero if they are equal. This should be set so that the notes pass the cursor at the same time the audio is heard. Use Ctrl+F1/F2 to adjust this while performing.</long>
+       </entry>
+       <entry name="audio/round-trip" type="float" value="0.09">
+               <ui unit=" ms" multiplier="1000" />
+               <limits min="0.0" max="0.5" step="0.01" />
+               <short>Audio round-trip latency</short>
+               <long>Affects singing only. The time it takes for Performous playback to reach your speakers, fly to the microphone and all the way back until Performous captures and analyzes it. While performing, press Ctrl+S for synth mode and adjust with Ctrl+F3/F4.</long>
+       </entry>
+       <entry name="audio/controller_delay" type="float" value="0.08">
+               <ui unit=" ms" multiplier="1000" />
+               <limits min="0.0" max="0.5" step="0.01" />
+               <short>Audio/controller latency</short>
+               <long>Affects instruments and dancing only. The total of USB (guitar or dance pad) latency combined with audio output latency. Adjust so that you can hit the notes best when playing by ear (not looking on screen). Use Ctrl+F5/F6 to adjust while performing.</long>
+       </entry>
+       <entry name="audio/devices" type="string_list">
+               <stringvalue>dev="USBMIC" mics="blue,red"</stringvalue><!-- SingStar mics -->
+               <stringvalue>dev="Microphone" mics="*"</stringvalue><!-- Rock Band branded Logitech mic -->
+               <stringvalue>mics="blue"</stringvalue><!-- Any other microphone (only if blue is still free) -->
+               <stringvalue>out=2</stringvalue><!-- Any stereo output device -->
+               <short>Audio devices</short>
+               <long>List of audio devices to try.</long>
+       </entry>
+       <entry name="audio/preview_volume" type="int" value="70">
+               <ui unit=" %" />
+               <limits min="0" max="100" step="5" />
+               <short>Menu volume</short>
+               <long>The volume level of menus, song previews and jukebox mode.</long>
+       </entry>
+       <entry name="audio/music_volume" type="int" value="90">
+               <ui unit=" %" />
+               <limits min="0" max="100" step="5" />
+               <short>Music volume</short>
+               <long>The ingame music volume. Values above 90 are not recommended as distortion may occur.</long>
+       </entry>
+       <entry name="audio/fail_volume" type="int" value="90">
+               <ui unit=" %" />
+               <limits min="0" max="100" step="5" />
+               <short>Failure volume</short>
+               <long>The ingame fail sound volume. Values above 90 are not recommended as distortion may occur. 11 is louder than 10, but these go to 100. 89 louder!</long>
+       </entry>
+       <entry name="audio/pass-through" type="bool" value="false">
+               <short>Microphone pass-through</short>
+               <long>Send captured singing voice to speakers.</long>
+       </entry>
+       <entry name="audio/pass-through_ratio" type="float" value="2.0">
+               <ui unit=" x" />
+               <limits min="0.5" max="4.0" step="0.1" />
+               <short>Pass-through volume ratio</short>
+               <long>How much voice is amplified compared to the music.</long>
+       </entry>
+
+       <!-- Paths -->
+       <entry name="paths/songs" type="string_list">
+               <stringvalue>DATADIR/songs/</stringvalue>
+               <stringvalue>/usr/local/share/games/ultrastar/songs/</stringvalue>
+               <stringvalue>/usr/local/share/games/fretsonfire/data/songs/</stringvalue>
+               <stringvalue>/usr/share/games/ultrastar/songs/</stringvalue>
+               <stringvalue>/usr/share/games/fretsonfire/data/songs/</stringvalue>
+               <stringvalue>~/.ultrastar/songs/</stringvalue>
+               <short>Song folders</short>
+               <long>Where to recursively look for songs. DATADIR at the beginning means all Performous data folders.</long>
+       </entry>
+       <entry name="paths/system" type="string_list">
+               <short>Base folders for data</short>
+               <long>System defaults are included automatically. Additional paths can be added here.</long>
+       </entry>
+</performous>
diff --git a/data/database.xml b/data/database.xml
new file mode 100644 (file)
index 0000000..725b6e2
--- /dev/null
@@ -0,0 +1,19 @@
+<performous>
+       <songs> <!-- a list of songs -->
+               <song id="123" artist="ABBA" title="Dancing Queen">
+                       <!-- extra song details -->
+               </song>
+       </songs>
+       <players> <!-- a list of players -->
+               <player id="123" name="Markus">
+                       <picture>markus.jpg</picture> <!-- optional picture shown at players selection -->
+               </player>
+       </players>
+       <hiscores> <!-- a list of highscores -->
+               <hiscore songid="123" playerid="123" track="vocals">600</hiscore>
+       </hiscores>
+</performous>
+<!--
+id of songs: collateByTitle (?)
+id of players: ?
+-->
diff --git a/data/fonts/GoblinOne.otf b/data/fonts/GoblinOne.otf
new file mode 100644 (file)
index 0000000..9194194
Binary files /dev/null and b/data/fonts/GoblinOne.otf differ
diff --git a/data/fonts/NewRocker-Regular.otf b/data/fonts/NewRocker-Regular.otf
new file mode 100644 (file)
index 0000000..900a33a
Binary files /dev/null and b/data/fonts/NewRocker-Regular.otf differ
diff --git a/data/performous.desktop b/data/performous.desktop
new file mode 100755 (executable)
index 0000000..89fcb8b
--- /dev/null
@@ -0,0 +1,16 @@
+[Desktop Entry]
+Name=Performous
+Comment=A karaoke game
+Comment[de]=Ein Karaoke-Spiel
+Comment[es]=Un juego de karaoke
+Comment[fi]=Karaokepeli
+Comment[fr]=Un jeu de Karaoké
+Comment[it]=Un gioco di karaoke
+Comment[ro]=Un joc de tip karaoke
+Comment[se]=Ett karaoke-spel
+Exec=performous
+Icon=performous
+Terminal=false
+Type=Application
+Categories=Game;ArcadeGame;
+Keywords=song;music;dance;karaoke;microphone;sound;singing;
diff --git a/data/shaders/core.frag b/data/shaders/core.frag
new file mode 100644 (file)
index 0000000..32b659b
--- /dev/null
@@ -0,0 +1,92 @@
+#version 120
+#extension GL_ARB_texture_rectangle : require
+
+//DEFINES
+
+uniform mat4 colorMatrix;
+
+#ifdef ENABLE_BOGUS
+in float bogus;  // Workaround for http://www.nvnews.net/vbulletin/showthread.php?p=2401097
+#endif
+
+varying vec3 normal;
+varying vec4 color;
+
+#ifdef ENABLE_LIGHTING
+varying vec3 lightDir;
+#endif
+
+#if defined(ENABLE_TEXTURING) || defined(ENABLE_SPECULAR_MAP) || defined(ENABLE_EMISSION_MAP)
+varying vec2 texCoord;
+#endif
+
+#ifdef ENABLE_TEXTURING
+#if ENABLE_TEXTURING == 1
+uniform sampler2DRect tex;
+#define TEXFUNC texture2DRect(tex, texCoord)
+#elif ENABLE_TEXTURING == 2
+uniform sampler2D tex;
+#define TEXFUNC texture2D(tex, texCoord)
+#else
+#error Unknown texturing mode in ENABLE_TEXTURING
+#endif
+#endif
+
+#ifndef TEXFUNC
+#define TEXFUNC vec4(1,1,1,1)
+#endif
+
+#ifdef ENABLE_SPECULAR_MAP
+uniform sampler2D specularTex;
+#endif
+
+#ifdef ENABLE_EMISSION_MAP
+uniform sampler2D emissionTex;
+#endif
+
+
+void main() {
+       vec4 frag = TEXFUNC;
+
+#ifdef ENABLE_BOGUS
+       frag.a += 1e-14 * bogus;  // Convince the compiler not to optimize away the bogus variable
+#endif
+
+#ifdef ENABLE_VERTEX_COLOR
+       frag *= color;
+#endif
+
+#ifdef ENABLE_LIGHTING
+       vec3 n = normalize(normal);
+       vec3 l = normalize(lightDir);
+
+       // Diffuse
+       float diff = max(dot(n, l), 0.0);
+       float power = 1.0 - 0.02 * length(lightDir);
+       frag = vec4(frag.rgb * power * diff, frag.a);
+       
+#endif
+
+       frag = colorMatrix * frag;  // Colorize
+
+#ifdef ENABLE_LIGHTING
+
+       // Specular
+       vec3 refl = reflect(-l, n);
+       float spec = dot(refl, n);
+       if (power > 0.0) {
+               power *= pow(spec, 100);
+               #ifdef ENABLE_SPECULAR_MAP
+               power *= texture2D(specularTex, texCoord);
+               #endif
+               frag.rgb += vec3(power, power, power);
+       }
+
+       #ifdef ENABLE_EMISSION_MAP
+       frag.xyz += texture2D(emissionTex, texCoord);
+       #endif
+#endif
+
+       gl_FragColor = frag;
+}
+
diff --git a/data/shaders/core.vert b/data/shaders/core.vert
new file mode 100644 (file)
index 0000000..40d20c9
--- /dev/null
@@ -0,0 +1,34 @@
+#version 120
+
+//DEFINES
+
+uniform mat4 projMatrix;
+uniform mat4 mvMatrix;
+uniform mat3 normalMatrix;
+
+attribute vec3 vertPos;
+attribute vec2 vertTexCoord;
+attribute vec3 vertNormal;
+attribute vec4 vertColor;
+
+varying vec3 lightDir;
+varying vec3 vLightDir;
+varying vec2 texCoord;
+varying vec2 vTexCoord;
+varying vec3 normal;
+varying vec3 vNormal;
+varying vec4 color;
+varying vec4 vColor;
+
+void main() {
+       //const vec3 lightPos = vec3(0.0, -2.94, 1.0);
+       const vec3 lightPos = vec3(-10.0, 2.0, 15.0);
+
+       vec4 posEye = mvMatrix * vec4(vertPos, 1.0);  // Vertex position in eye space
+       gl_Position = projMatrix * posEye;  // Vertex position in normalized device coordinates
+       vLightDir = lightDir = lightPos - posEye.xyz / posEye.w;  // Light position relative to vertex
+       vTexCoord = texCoord = vertTexCoord;
+       vNormal = normal = normalize(normalMatrix * vertNormal);
+       vColor = color = vertColor;
+}
+
diff --git a/data/shaders/dancenote.vert b/data/shaders/dancenote.vert
new file mode 100644 (file)
index 0000000..a6b6552
--- /dev/null
@@ -0,0 +1,81 @@
+#version 120
+
+uniform mat4 projMatrix;
+uniform mat4 mvMatrix;
+uniform mat3 normalMatrix;
+uniform int noteType;
+uniform float hitAnim;
+uniform float clock;
+uniform float scale;
+uniform vec2 position;
+
+attribute vec3 vertPos;
+attribute vec2 vertTexCoord;
+attribute vec3 vertNormal;
+attribute vec4 vertColor;
+
+// Per-vextex for fragment shader (if no geometry shader)
+varying vec2 texCoord;
+varying vec3 normal;
+varying vec4 color;
+
+// Per-vertex for geometry shader (if one exists)
+varying vec2 vTexCoord;
+varying vec3 vNormal;
+varying vec4 vColor;
+
+mat4 scaleMat(in float sc) {
+       return mat4(sc,  0,  0,  0,
+                    0, sc,  0,  0,
+                    0,  0, sc,  0,
+                    0,  0,  0,  1);
+}
+
+mat4 rotMat(in float ang) {
+       float ca = cos(ang);
+       float sa = sin(ang);
+       return mat4(ca, -sa, 0, 0,
+                   sa,  ca, 0, 0,
+                    0,   0, 1, 0,
+                    0,   0, 0, 1);
+}
+
+void main() {
+       vTexCoord = texCoord = vertTexCoord;
+       vNormal = normal = normalMatrix * vertNormal;
+       vColor = color = vertColor;
+
+       mat4 trans = scaleMat(scale);
+
+       // Cursor arrows
+       if (noteType == 0) {
+               trans *= scaleMat(1.0 - hitAnim * .5);
+
+       // Regular arrows
+       } else if (noteType == 1) {
+               trans *= scaleMat(1.0 + hitAnim);
+
+       // Holds
+       } else if (noteType == 2) {
+               trans *= scaleMat(1.0 + hitAnim);
+
+       // Mines
+       } else if (noteType == 3) {
+               trans *= scaleMat(1.0 + hitAnim);
+               float r = radians(mod(clock*360.0, 360.0)); // They rotate!
+               trans *= rotMat(r);
+       }
+
+       // Glow color for regular arrows or holds
+       if (noteType == 1 || noteType == 2) {
+               vColor = color = vec4(
+                 min(color.r + hitAnim *.5, 1.0),
+                 min(color.g + hitAnim *.5, 1.0),
+                 min(color.b + hitAnim *.5, 1.0),
+                 max(color.a - hitAnim, 0.0)
+               );
+       }
+
+       gl_Position = projMatrix * mvMatrix * (vec4(position, 0, 0) + trans * vec4(vertPos, 1.0));
+}
+
diff --git a/data/shaders/stereo3d.geom b/data/shaders/stereo3d.geom
new file mode 100644 (file)
index 0000000..12736e3
--- /dev/null
@@ -0,0 +1,43 @@
+#version 330
+#extension GL_ARB_viewport_array : require
+
+uniform float sepFactor;
+uniform float z0;
+
+layout(triangles) in;
+layout(triangle_strip, max_vertices = 6) out;
+
+in vec3 vLightDir[];
+in vec2 vTexCoord[];
+in vec3 vNormal[];
+in vec4 vColor[];
+
+out float bogus;  // Workaround for http://www.nvnews.net/vbulletin/showthread.php?p=2401097
+out vec3 lightDir;
+out vec2 texCoord;
+out vec3 normal;
+out vec4 color;
+
+int i;
+
+void passthru() {
+       gl_Position = gl_in[i].gl_Position;
+       lightDir = vLightDir[i];
+       texCoord = vTexCoord[i];
+       normal = vNormal[i];
+       color = vColor[i];
+}
+
+// Process all the vertices, applying code to them before emitting (do-while to convince Nvidia of the code getting executed)
+#define PROCESS(code) i = 0; do { passthru(); code; EmitVertex(); } while (++i < 3); EndPrimitive();
+
+void main() {
+       bogus = 0.0;
+       if (sepFactor == 0.0) {
+               gl_ViewportIndex = 0; PROCESS(;); // No stereo
+       } else {
+               gl_ViewportIndex = 1; PROCESS(gl_Position.x -= sepFactor * (gl_Position.z - z0));  // Left eye
+               gl_ViewportIndex = 2; PROCESS(gl_Position.x += sepFactor * (gl_Position.z - z0));  // Right eye
+       }
+}
+
diff --git a/data/sounds/drum_bass.ogg b/data/sounds/drum_bass.ogg
new file mode 100644 (file)
index 0000000..0875fb2
Binary files /dev/null and b/data/sounds/drum_bass.ogg differ
diff --git a/data/sounds/drum_cymbal.ogg b/data/sounds/drum_cymbal.ogg
new file mode 100644 (file)
index 0000000..cb0e869
Binary files /dev/null and b/data/sounds/drum_cymbal.ogg differ
diff --git a/data/sounds/drum_hi-hat.ogg b/data/sounds/drum_hi-hat.ogg
new file mode 100644 (file)
index 0000000..f7808a3
Binary files /dev/null and b/data/sounds/drum_hi-hat.ogg differ
diff --git a/data/sounds/drum_snare.ogg b/data/sounds/drum_snare.ogg
new file mode 100644 (file)
index 0000000..462907d
Binary files /dev/null and b/data/sounds/drum_snare.ogg differ
diff --git a/data/sounds/drum_tom1.ogg b/data/sounds/drum_tom1.ogg
new file mode 100644 (file)
index 0000000..90a1a06
Binary files /dev/null and b/data/sounds/drum_tom1.ogg differ
diff --git a/data/sounds/drum_tom2.ogg b/data/sounds/drum_tom2.ogg
new file mode 100644 (file)
index 0000000..8e213d3
Binary files /dev/null and b/data/sounds/drum_tom2.ogg differ
diff --git a/data/sounds/guitar_fail1.ogg b/data/sounds/guitar_fail1.ogg
new file mode 100644 (file)
index 0000000..c5b1c43
Binary files /dev/null and b/data/sounds/guitar_fail1.ogg differ
diff --git a/data/sounds/guitar_fail2.ogg b/data/sounds/guitar_fail2.ogg
new file mode 100644 (file)
index 0000000..ec9048b
Binary files /dev/null and b/data/sounds/guitar_fail2.ogg differ
diff --git a/data/sounds/guitar_fail3.ogg b/data/sounds/guitar_fail3.ogg
new file mode 100644 (file)
index 0000000..ce67d63
Binary files /dev/null and b/data/sounds/guitar_fail3.ogg differ
diff --git a/data/sounds/guitar_fail4.ogg b/data/sounds/guitar_fail4.ogg
new file mode 100644 (file)
index 0000000..4502efe
Binary files /dev/null and b/data/sounds/guitar_fail4.ogg differ
diff --git a/data/sounds/guitar_fail5.ogg b/data/sounds/guitar_fail5.ogg
new file mode 100644 (file)
index 0000000..2e62474
Binary files /dev/null and b/data/sounds/guitar_fail5.ogg differ
diff --git a/data/sounds/guitar_fail6.ogg b/data/sounds/guitar_fail6.ogg
new file mode 100644 (file)
index 0000000..c7c6516
Binary files /dev/null and b/data/sounds/guitar_fail6.ogg differ
diff --git a/data/themes/default/arrow_button_down.svg b/data/themes/default/arrow_button_down.svg
new file mode 100644 (file)
index 0000000..7927d4b
--- /dev/null
@@ -0,0 +1,910 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://creativecommons.org/ns#"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:xlink="http://www.w3.org/1999/xlink"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   sodipodi:docname="arrow_button_up.svg"
+   inkscape:version="0.48.0 r9654"
+   sodipodi:version="0.32"
+   id="svg5683"
+   height="56.5886"
+   width="57.044964"
+   version="1.0">
+  <defs
+     id="defs3">
+    <linearGradient
+       y2="323.17273"
+       x2="681.0014"
+       y1="300.41397"
+       x1="661.46326"
+       gradientTransform="matrix(0.80139,0,0,1.247832,288.7111,-153.4135)"
+       gradientUnits="userSpaceOnUse"
+       id="linearGradient5500"
+       xlink:href="#linearGradient4738"
+       inkscape:collect="always" />
+    <linearGradient
+       y2="390.78342"
+       x2="311.27377"
+       y1="377.9527"
+       x1="302.73621"
+       gradientTransform="matrix(1.9519,0,0,1.84182,206.7081,-481.0457)"
+       gradientUnits="userSpaceOnUse"
+       id="linearGradient5498"
+       xlink:href="#linearGradient4554"
+       inkscape:collect="always" />
+    <linearGradient
+       y2="387.43924"
+       x2="332.02466"
+       y1="369.97995"
+       x1="314.56537"
+       gradientUnits="userSpaceOnUse"
+       id="linearGradient5496"
+       xlink:href="#linearGradient4568"
+       inkscape:collect="always" />
+    <linearGradient
+       y2="550.81836"
+       x2="-487.88327"
+       y1="529.3363"
+       x1="-466.60916"
+       gradientTransform="matrix(0,-0.80139,1.247832,0,224.6646,-148.7015)"
+       gradientUnits="userSpaceOnUse"
+       id="linearGradient5494"
+       xlink:href="#linearGradient4738"
+       inkscape:collect="always" />
+    <linearGradient
+       y2="390.78342"
+       x2="311.27377"
+       y1="377.9527"
+       x1="302.73621"
+       gradientTransform="matrix(1.9519,0,0,1.84182,281.3651,-481.0457)"
+       gradientUnits="userSpaceOnUse"
+       id="linearGradient5492"
+       xlink:href="#linearGradient4554"
+       inkscape:collect="always" />
+    <linearGradient
+       y2="387.43924"
+       x2="332.02466"
+       y1="369.97995"
+       x1="314.56537"
+       gradientUnits="userSpaceOnUse"
+       id="linearGradient5490"
+       xlink:href="#linearGradient4568"
+       inkscape:collect="always" />
+    <linearGradient
+       y2="316.30093"
+       x2="-673.75562"
+       y1="293.93457"
+       x1="-653.01508"
+       gradientTransform="matrix(-0.80139,0,0,1.247832,214.5211,-145.3283)"
+       gradientUnits="userSpaceOnUse"
+       id="linearGradient5488"
+       xlink:href="#linearGradient4738"
+       inkscape:collect="always" />
+    <linearGradient
+       y2="390.78342"
+       x2="311.27377"
+       y1="377.9527"
+       x1="302.73621"
+       gradientTransform="matrix(1.9519,0,0,1.84182,132.051,-481.0457)"
+       gradientUnits="userSpaceOnUse"
+       id="linearGradient5486"
+       xlink:href="#linearGradient4554"
+       inkscape:collect="always" />
+    <linearGradient
+       y2="387.43924"
+       x2="332.02466"
+       y1="369.97995"
+       x1="314.56537"
+       gradientUnits="userSpaceOnUse"
+       id="linearGradient5484"
+       xlink:href="#linearGradient4568"
+       inkscape:collect="always" />
+    <linearGradient
+       y2="614.64392"
+       x2="487.88327"
+       y1="592.7915"
+       x1="467.18936"
+       gradientTransform="matrix(0,0.80139,1.247832,0,219.986,-144.9236)"
+       gradientUnits="userSpaceOnUse"
+       id="linearGradient5482"
+       xlink:href="#linearGradient4738"
+       inkscape:collect="always" />
+    <linearGradient
+       y2="390.78342"
+       x2="311.27377"
+       y1="377.9527"
+       x1="302.73621"
+       gradientTransform="matrix(1.9519,0,0,1.84182,356.022,-481.0457)"
+       gradientUnits="userSpaceOnUse"
+       id="linearGradient5480"
+       xlink:href="#linearGradient4554"
+       inkscape:collect="always" />
+    <linearGradient
+       id="linearGradient4568">
+      <stop
+         id="stop4570"
+         offset="0"
+         style="stop-color:#e12b1c;stop-opacity:1;" />
+      <stop
+         id="stop4572"
+         offset="1.0000000"
+         style="stop-color:#980b00;stop-opacity:1.0000000;" />
+    </linearGradient>
+    <linearGradient
+       y2="387.43924"
+       x2="332.02466"
+       y1="369.97995"
+       x1="314.56537"
+       gradientUnits="userSpaceOnUse"
+       id="linearGradient5478"
+       xlink:href="#linearGradient4568"
+       inkscape:collect="always" />
+    <linearGradient
+       y2="323.17273"
+       x2="681.0014"
+       y1="300.41397"
+       x1="661.46326"
+       gradientTransform="matrix(0.80139,0,0,1.247832,324.2651,-311.3622)"
+       gradientUnits="userSpaceOnUse"
+       id="linearGradient5606"
+       xlink:href="#linearGradient4738"
+       inkscape:collect="always" />
+    <linearGradient
+       y2="390.78342"
+       x2="311.27377"
+       y1="377.9527"
+       x1="302.73621"
+       gradientTransform="matrix(1.9519,0,0,1.84182,242.2621,-638.9944)"
+       gradientUnits="userSpaceOnUse"
+       id="linearGradient5604"
+       xlink:href="#linearGradient4554"
+       inkscape:collect="always" />
+    <linearGradient
+       y2="387.43924"
+       x2="332.02466"
+       y1="369.97995"
+       x1="314.56537"
+       gradientUnits="userSpaceOnUse"
+       id="linearGradient5602"
+       xlink:href="#linearGradient4886"
+       inkscape:collect="always" />
+    <linearGradient
+       y2="550.81836"
+       x2="-487.88327"
+       y1="529.3363"
+       x1="-466.60916"
+       gradientTransform="matrix(0,-0.80139,1.247832,0,260.2186,-306.6502)"
+       gradientUnits="userSpaceOnUse"
+       id="linearGradient5287"
+       xlink:href="#linearGradient4738"
+       inkscape:collect="always" />
+    <linearGradient
+       y2="390.78342"
+       x2="311.27377"
+       y1="377.9527"
+       x1="302.73621"
+       gradientTransform="matrix(1.9519,0,0,1.84182,316.9191,-638.9944)"
+       gradientUnits="userSpaceOnUse"
+       id="linearGradient5290"
+       xlink:href="#linearGradient4554"
+       inkscape:collect="always" />
+    <linearGradient
+       y2="387.43924"
+       x2="332.02466"
+       y1="369.97995"
+       x1="314.56537"
+       gradientUnits="userSpaceOnUse"
+       id="linearGradient5336"
+       xlink:href="#linearGradient4886"
+       inkscape:collect="always" />
+    <linearGradient
+       y2="316.30093"
+       x2="-673.75562"
+       y1="293.93457"
+       x1="-653.01508"
+       gradientTransform="matrix(-0.80139,0,0,1.247832,250.0751,-303.277)"
+       gradientUnits="userSpaceOnUse"
+       id="linearGradient5594"
+       xlink:href="#linearGradient4738"
+       inkscape:collect="always" />
+    <linearGradient
+       y2="390.78342"
+       x2="311.27377"
+       y1="377.9527"
+       x1="302.73621"
+       gradientTransform="matrix(1.9519,0,0,1.84182,167.605,-638.9944)"
+       gradientUnits="userSpaceOnUse"
+       id="linearGradient5592"
+       xlink:href="#linearGradient4554"
+       inkscape:collect="always" />
+    <linearGradient
+       y2="387.43924"
+       x2="332.02466"
+       y1="369.97995"
+       x1="314.56537"
+       gradientUnits="userSpaceOnUse"
+       id="linearGradient5590"
+       xlink:href="#linearGradient4886"
+       inkscape:collect="always" />
+    <linearGradient
+       y2="614.64392"
+       x2="487.88327"
+       y1="592.7915"
+       x1="467.18936"
+       gradientTransform="matrix(0,0.80139,1.247832,0,255.54,-302.8723)"
+       gradientUnits="userSpaceOnUse"
+       id="linearGradient5600"
+       xlink:href="#linearGradient4738"
+       inkscape:collect="always" />
+    <linearGradient
+       y2="390.78342"
+       x2="311.27377"
+       y1="377.9527"
+       x1="302.73621"
+       gradientTransform="matrix(1.9519,0,0,1.84182,391.576,-638.9944)"
+       gradientUnits="userSpaceOnUse"
+       id="linearGradient5598"
+       xlink:href="#linearGradient4554"
+       inkscape:collect="always" />
+    <linearGradient
+       id="linearGradient4886">
+      <stop
+         id="stop4888"
+         offset="0"
+         style="stop-color:#1155ff;stop-opacity:1;" />
+      <stop
+         id="stop4890"
+         offset="1"
+         style="stop-color:#0000a1;stop-opacity:1;" />
+    </linearGradient>
+    <linearGradient
+       y2="323.17273"
+       x2="681.0014"
+       y1="300.41397"
+       x1="661.46326"
+       gradientTransform="matrix(0.80139,0,0,1.247832,291.6739,-84.28068)"
+       gradientUnits="userSpaceOnUse"
+       id="linearGradient5476"
+       xlink:href="#linearGradient4738"
+       inkscape:collect="always" />
+    <linearGradient
+       y2="390.78342"
+       x2="311.27377"
+       y1="377.9527"
+       x1="302.73621"
+       gradientTransform="matrix(1.9519,0,0,1.84182,209.6709,-411.9129)"
+       gradientUnits="userSpaceOnUse"
+       id="linearGradient5474"
+       xlink:href="#linearGradient4554"
+       inkscape:collect="always" />
+    <linearGradient
+       y2="387.43924"
+       x2="332.02466"
+       y1="369.97995"
+       x1="314.56537"
+       gradientUnits="userSpaceOnUse"
+       id="linearGradient5472"
+       xlink:href="#linearGradient4932"
+       inkscape:collect="always" />
+    <linearGradient
+       y2="550.81836"
+       x2="-487.88327"
+       y1="529.3363"
+       x1="-466.60916"
+       gradientTransform="matrix(0,-0.80139,1.247832,0,227.6274,-79.56868)"
+       gradientUnits="userSpaceOnUse"
+       id="linearGradient5470"
+       xlink:href="#linearGradient4738"
+       inkscape:collect="always" />
+    <linearGradient
+       y2="390.78342"
+       x2="311.27377"
+       y1="377.9527"
+       x1="302.73621"
+       gradientTransform="matrix(1.9519,0,0,1.84182,284.3279,-411.9129)"
+       gradientUnits="userSpaceOnUse"
+       id="linearGradient5468"
+       xlink:href="#linearGradient4554"
+       inkscape:collect="always" />
+    <linearGradient
+       y2="387.43924"
+       x2="332.02466"
+       y1="369.97995"
+       x1="314.56537"
+       gradientUnits="userSpaceOnUse"
+       id="linearGradient5466"
+       xlink:href="#linearGradient4932"
+       inkscape:collect="always" />
+    <linearGradient
+       y2="316.30093"
+       x2="-673.75562"
+       y1="293.93457"
+       x1="-653.01508"
+       gradientTransform="matrix(-0.80139,0,0,1.247832,217.4839,-76.19548)"
+       gradientUnits="userSpaceOnUse"
+       id="linearGradient5464"
+       xlink:href="#linearGradient4738"
+       inkscape:collect="always" />
+    <linearGradient
+       y2="390.78342"
+       x2="311.27377"
+       y1="377.9527"
+       x1="302.73621"
+       gradientTransform="matrix(1.9519,0,0,1.84182,135.0138,-411.9129)"
+       gradientUnits="userSpaceOnUse"
+       id="linearGradient5462"
+       xlink:href="#linearGradient4554"
+       inkscape:collect="always" />
+    <linearGradient
+       y2="387.43924"
+       x2="332.02466"
+       y1="369.97995"
+       x1="314.56537"
+       gradientUnits="userSpaceOnUse"
+       id="linearGradient5460"
+       xlink:href="#linearGradient4932"
+       inkscape:collect="always" />
+    <linearGradient
+       y2="614.64392"
+       x2="487.88327"
+       y1="592.7915"
+       x1="467.18936"
+       gradientTransform="matrix(0,0.80139,1.247832,0,222.9488,-75.79078)"
+       gradientUnits="userSpaceOnUse"
+       id="linearGradient5458"
+       xlink:href="#linearGradient4738"
+       inkscape:collect="always" />
+    <linearGradient
+       y2="390.78342"
+       x2="311.27377"
+       y1="377.9527"
+       x1="302.73621"
+       gradientTransform="matrix(1.9519,0,0,1.84182,358.9848,-411.9129)"
+       gradientUnits="userSpaceOnUse"
+       id="linearGradient5456"
+       xlink:href="#linearGradient4554"
+       inkscape:collect="always" />
+    <linearGradient
+       id="linearGradient4932">
+      <stop
+         id="stop4934"
+         offset="0.0000000"
+         style="stop-color:#66e11c;stop-opacity:1.0000000;" />
+      <stop
+         id="stop4936"
+         offset="1.0000000"
+         style="stop-color:#3d9800;stop-opacity:1.0000000;" />
+    </linearGradient>
+    <linearGradient
+       y2="387.43924"
+       x2="332.02466"
+       y1="369.97995"
+       x1="314.56537"
+       gradientUnits="userSpaceOnUse"
+       id="linearGradient5454"
+       xlink:href="#linearGradient4932"
+       inkscape:collect="always" />
+    <linearGradient
+       y2="323.17273"
+       x2="681.0014"
+       y1="300.41397"
+       x1="661.46326"
+       gradientTransform="matrix(0.80139,0,0,1.247832,324.2651,-100.0825)"
+       gradientUnits="userSpaceOnUse"
+       id="linearGradient5633"
+       xlink:href="#linearGradient4738"
+       inkscape:collect="always" />
+    <linearGradient
+       y2="390.78342"
+       x2="311.27377"
+       y1="377.9527"
+       x1="302.73621"
+       gradientTransform="matrix(1.9519,0,0,1.84182,242.2621,-427.7147)"
+       gradientUnits="userSpaceOnUse"
+       id="linearGradient5636"
+       xlink:href="#linearGradient4554"
+       inkscape:collect="always" />
+    <linearGradient
+       y2="387.43924"
+       x2="332.02466"
+       y1="369.97995"
+       x1="314.56537"
+       gradientUnits="userSpaceOnUse"
+       id="linearGradient5644"
+       xlink:href="#linearGradient5028"
+       inkscape:collect="always" />
+    <linearGradient
+       y2="550.81836"
+       x2="-487.88327"
+       y1="529.3363"
+       x1="-466.60916"
+       gradientTransform="matrix(0,-0.80139,1.247832,0,260.2186,-95.37047)"
+       gradientUnits="userSpaceOnUse"
+       id="linearGradient5625"
+       xlink:href="#linearGradient4738"
+       inkscape:collect="always" />
+    <linearGradient
+       y2="390.78342"
+       x2="311.27377"
+       y1="377.9527"
+       x1="302.73621"
+       gradientTransform="matrix(1.9519,0,0,1.84182,316.9191,-427.7147)"
+       gradientUnits="userSpaceOnUse"
+       id="linearGradient5628"
+       xlink:href="#linearGradient4554"
+       inkscape:collect="always" />
+    <linearGradient
+       y2="387.43924"
+       x2="332.02466"
+       y1="369.97995"
+       x1="314.56537"
+       gradientUnits="userSpaceOnUse"
+       id="linearGradient5640"
+       xlink:href="#linearGradient5028"
+       inkscape:collect="always" />
+    <linearGradient
+       y2="316.30093"
+       x2="-673.75562"
+       y1="293.93457"
+       x1="-653.01508"
+       gradientTransform="matrix(-0.80139,0,0,1.247832,250.0751,-91.99727)"
+       gradientUnits="userSpaceOnUse"
+       id="linearGradient5617"
+       xlink:href="#linearGradient4738"
+       inkscape:collect="always" />
+    <linearGradient
+       y2="390.78342"
+       x2="311.27377"
+       y1="377.9527"
+       x1="302.73621"
+       gradientTransform="matrix(1.9519,0,0,1.84182,167.605,-427.7147)"
+       gradientUnits="userSpaceOnUse"
+       id="linearGradient5620"
+       xlink:href="#linearGradient4554"
+       inkscape:collect="always" />
+    <linearGradient
+       y2="387.43924"
+       x2="332.02466"
+       y1="369.97995"
+       x1="314.56537"
+       gradientUnits="userSpaceOnUse"
+       id="linearGradient5646"
+       xlink:href="#linearGradient5028"
+       inkscape:collect="always" />
+    <linearGradient
+       id="linearGradient4738">
+      <stop
+         id="stop4740"
+         offset="0.0000000"
+         style="stop-color:#ffffff;stop-opacity:0.72656250;" />
+      <stop
+         id="stop4742"
+         offset="1.0000000"
+         style="stop-color:#ffffff;stop-opacity:1.0000000;" />
+    </linearGradient>
+    <linearGradient
+       y2="614.64392"
+       x2="487.88327"
+       y1="592.7915"
+       x1="467.18936"
+       gradientTransform="matrix(0,0.80139,1.247832,0,255.54,-91.59257)"
+       gradientUnits="userSpaceOnUse"
+       id="linearGradient5609"
+       xlink:href="#linearGradient4738"
+       inkscape:collect="always" />
+    <linearGradient
+       id="linearGradient4554">
+      <stop
+         id="stop4556"
+         offset="0.0000000"
+         style="stop-color:#ffffff;stop-opacity:1.0000000;" />
+      <stop
+         id="stop4558"
+         offset="1.0000000"
+         style="stop-color:#ffffff;stop-opacity:0.0000000;" />
+    </linearGradient>
+    <linearGradient
+       y2="390.78342"
+       x2="311.27377"
+       y1="377.9527"
+       x1="302.73621"
+       gradientTransform="matrix(1.9519,0,0,1.84182,391.576,-427.7147)"
+       gradientUnits="userSpaceOnUse"
+       id="linearGradient5612"
+       xlink:href="#linearGradient4554"
+       inkscape:collect="always" />
+    <linearGradient
+       id="linearGradient5028">
+      <stop
+         style="stop-color:#fffd26;stop-opacity:1.0000000;"
+         offset="0.0000000"
+         id="stop5030" />
+      <stop
+         style="stop-color:#967f00;stop-opacity:1.0000000;"
+         offset="1.0000000"
+         id="stop5032" />
+    </linearGradient>
+    <linearGradient
+       y2="387.43924"
+       x2="332.02466"
+       y1="369.97995"
+       x1="314.56537"
+       gradientUnits="userSpaceOnUse"
+       id="linearGradient5642"
+       xlink:href="#linearGradient5028"
+       inkscape:collect="always" />
+    <linearGradient
+       y2="614.64392"
+       x2="487.88327"
+       y1="592.7915"
+       x1="467.18936"
+       gradientTransform="matrix(0,0.80139,1.247832,0,-501.9489,-144.8603)"
+       gradientUnits="userSpaceOnUse"
+       id="linearGradient5958"
+       xlink:href="#linearGradient4738"
+       inkscape:collect="always" />
+    <linearGradient
+       y2="390.78342"
+       x2="311.27377"
+       y1="377.9527"
+       x1="302.73621"
+       gradientTransform="matrix(1.9519,0,0,1.84182,-365.9129,-480.9825)"
+       gradientUnits="userSpaceOnUse"
+       id="linearGradient5961"
+       xlink:href="#linearGradient4554"
+       inkscape:collect="always" />
+    <linearGradient
+       y2="316.30093"
+       x2="-673.75562"
+       y1="293.93457"
+       x1="-653.01508"
+       gradientTransform="matrix(-0.80139,0,0,1.247832,-507.4138,-145.265)"
+       gradientUnits="userSpaceOnUse"
+       id="linearGradient5966"
+       xlink:href="#linearGradient4738"
+       inkscape:collect="always" />
+    <linearGradient
+       y2="390.78342"
+       x2="311.27377"
+       y1="377.9527"
+       x1="302.73621"
+       gradientTransform="matrix(1.9519,0,0,1.84182,-589.8839,-480.9825)"
+       gradientUnits="userSpaceOnUse"
+       id="linearGradient5969"
+       xlink:href="#linearGradient4554"
+       inkscape:collect="always" />
+    <linearGradient
+       y2="550.81836"
+       x2="-487.88327"
+       y1="529.3363"
+       x1="-466.60916"
+       gradientTransform="matrix(0,-0.80139,1.247832,0,-497.2703,-148.6382)"
+       gradientUnits="userSpaceOnUse"
+       id="linearGradient5974"
+       xlink:href="#linearGradient4738"
+       inkscape:collect="always" />
+    <linearGradient
+       y2="390.78342"
+       x2="311.27377"
+       y1="377.9527"
+       x1="302.73621"
+       gradientTransform="matrix(1.9519,0,0,1.84182,-440.5698,-480.9825)"
+       gradientUnits="userSpaceOnUse"
+       id="linearGradient5977"
+       xlink:href="#linearGradient4554"
+       inkscape:collect="always" />
+    <linearGradient
+       y2="323.17273"
+       x2="681.0014"
+       y1="300.41397"
+       x1="661.46326"
+       gradientTransform="matrix(0.80139,0,0,1.247832,-433.2238,-153.3502)"
+       gradientUnits="userSpaceOnUse"
+       id="linearGradient5982"
+       xlink:href="#linearGradient4738"
+       inkscape:collect="always" />
+    <linearGradient
+       y2="390.78342"
+       x2="311.27377"
+       y1="377.9527"
+       x1="302.73621"
+       gradientTransform="matrix(1.9519,0,0,1.84182,-515.2268,-480.9825)"
+       gradientUnits="userSpaceOnUse"
+       id="linearGradient5985"
+       xlink:href="#linearGradient4554"
+       inkscape:collect="always" />
+    <linearGradient
+       y2="614.64392"
+       x2="487.88327"
+       y1="592.7915"
+       x1="467.18936"
+       gradientTransform="matrix(0,0.80139,1.247832,0,-501.9489,-214.9808)"
+       gradientUnits="userSpaceOnUse"
+       id="linearGradient5990"
+       xlink:href="#linearGradient4738"
+       inkscape:collect="always" />
+    <linearGradient
+       y2="390.78342"
+       x2="311.27377"
+       y1="377.9527"
+       x1="302.73621"
+       gradientTransform="matrix(1.9519,0,0,1.84182,-365.9129,-551.1029)"
+       gradientUnits="userSpaceOnUse"
+       id="linearGradient5993"
+       xlink:href="#linearGradient4554"
+       inkscape:collect="always" />
+    <linearGradient
+       y2="316.30093"
+       x2="-673.75562"
+       y1="293.93457"
+       x1="-653.01508"
+       gradientTransform="matrix(-0.80139,0,0,1.247832,-507.4138,-215.3855)"
+       gradientUnits="userSpaceOnUse"
+       id="linearGradient5998"
+       xlink:href="#linearGradient4738"
+       inkscape:collect="always" />
+    <linearGradient
+       y2="390.78342"
+       x2="311.27377"
+       y1="377.9527"
+       x1="302.73621"
+       gradientTransform="matrix(1.9519,0,0,1.84182,-589.8839,-551.1029)"
+       gradientUnits="userSpaceOnUse"
+       id="linearGradient6001"
+       xlink:href="#linearGradient4554"
+       inkscape:collect="always" />
+    <linearGradient
+       y2="550.81836"
+       x2="-487.88327"
+       y1="529.3363"
+       x1="-466.60916"
+       gradientTransform="matrix(0,-0.80139,1.247832,0,-497.2703,-218.7587)"
+       gradientUnits="userSpaceOnUse"
+       id="linearGradient6006"
+       xlink:href="#linearGradient4738"
+       inkscape:collect="always" />
+    <linearGradient
+       y2="390.78342"
+       x2="311.27377"
+       y1="377.9527"
+       x1="302.73621"
+       gradientTransform="matrix(1.9519,0,0,1.84182,-440.5698,-551.1029)"
+       gradientUnits="userSpaceOnUse"
+       id="linearGradient6009"
+       xlink:href="#linearGradient4554"
+       inkscape:collect="always" />
+    <linearGradient
+       y2="323.17273"
+       x2="681.0014"
+       y1="300.41397"
+       x1="661.46326"
+       gradientTransform="matrix(0.80139,0,0,1.247832,-433.2238,-223.4707)"
+       gradientUnits="userSpaceOnUse"
+       id="linearGradient6014"
+       xlink:href="#linearGradient4738"
+       inkscape:collect="always" />
+    <linearGradient
+       y2="390.78342"
+       x2="311.27377"
+       y1="377.9527"
+       x1="302.73621"
+       gradientTransform="matrix(1.9519,0,0,1.84182,-515.2268,-551.1029)"
+       gradientUnits="userSpaceOnUse"
+       id="linearGradient6017"
+       xlink:href="#linearGradient4554"
+       inkscape:collect="always" />
+    <linearGradient
+       y2="316.30093"
+       x2="-673.75562"
+       y1="293.93457"
+       x1="-653.01508"
+       gradientTransform="matrix(-0.80139,0,0,1.247832,-507.4138,-356.5448)"
+       gradientUnits="userSpaceOnUse"
+       id="linearGradient6030"
+       xlink:href="#linearGradient4738"
+       inkscape:collect="always" />
+    <linearGradient
+       y2="390.78342"
+       x2="311.27377"
+       y1="377.9527"
+       x1="302.73621"
+       gradientTransform="matrix(1.9519,0,0,1.84182,-589.8839,-692.2622)"
+       gradientUnits="userSpaceOnUse"
+       id="linearGradient6033"
+       xlink:href="#linearGradient4554"
+       inkscape:collect="always" />
+    <linearGradient
+       y2="550.81836"
+       x2="-487.88327"
+       y1="529.3363"
+       x1="-466.60916"
+       gradientTransform="matrix(0,-0.80139,1.247832,0,-497.2703,-359.918)"
+       gradientUnits="userSpaceOnUse"
+       id="linearGradient6038"
+       xlink:href="#linearGradient4738"
+       inkscape:collect="always" />
+    <linearGradient
+       y2="390.78342"
+       x2="311.27377"
+       y1="377.9527"
+       x1="302.73621"
+       gradientTransform="matrix(1.9519,0,0,1.84182,-440.5698,-692.2622)"
+       gradientUnits="userSpaceOnUse"
+       id="linearGradient6041"
+       xlink:href="#linearGradient4554"
+       inkscape:collect="always" />
+    <linearGradient
+       y2="323.17273"
+       x2="681.0014"
+       y1="300.41397"
+       x1="661.46326"
+       gradientTransform="matrix(0,0.80139,-1.247832,0,631.33596,-520.76998)"
+       gradientUnits="userSpaceOnUse"
+       id="linearGradient6046"
+       xlink:href="#linearGradient4738"
+       inkscape:collect="always" />
+    <linearGradient
+       y2="390.78342"
+       x2="311.27377"
+       y1="377.9527"
+       x1="302.73621"
+       gradientTransform="matrix(1.9519,0,0,1.84182,-374.8545,-700.975)"
+       gradientUnits="userSpaceOnUse"
+       id="linearGradient6049"
+       xlink:href="#linearGradient4554"
+       inkscape:collect="always" />
+    <linearGradient
+       y2="614.64392"
+       x2="487.88327"
+       y1="592.7915"
+       x1="467.18936"
+       gradientTransform="matrix(0,0.80139,1.247832,0,-501.9489,-284.1136)"
+       gradientUnits="userSpaceOnUse"
+       id="linearGradient6054"
+       xlink:href="#linearGradient4738"
+       inkscape:collect="always" />
+    <linearGradient
+       y2="390.78342"
+       x2="311.27377"
+       y1="377.9527"
+       x1="302.73621"
+       gradientTransform="matrix(1.9519,0,0,1.84182,-365.9129,-620.2357)"
+       gradientUnits="userSpaceOnUse"
+       id="linearGradient6057"
+       xlink:href="#linearGradient4554"
+       inkscape:collect="always" />
+    <linearGradient
+       y2="316.30093"
+       x2="-673.75562"
+       y1="293.93457"
+       x1="-653.01508"
+       gradientTransform="matrix(-0.80139,0,0,1.247832,-507.4138,-284.5183)"
+       gradientUnits="userSpaceOnUse"
+       id="linearGradient6062"
+       xlink:href="#linearGradient4738"
+       inkscape:collect="always" />
+    <linearGradient
+       y2="390.78342"
+       x2="311.27377"
+       y1="377.9527"
+       x1="302.73621"
+       gradientTransform="matrix(1.9519,0,0,1.84182,-589.8839,-620.2357)"
+       gradientUnits="userSpaceOnUse"
+       id="linearGradient6065"
+       xlink:href="#linearGradient4554"
+       inkscape:collect="always" />
+    <linearGradient
+       y2="550.81836"
+       x2="-487.88327"
+       y1="529.3363"
+       x1="-466.60916"
+       gradientTransform="matrix(0,-0.80139,1.247832,0,-497.27,-287.8915)"
+       gradientUnits="userSpaceOnUse"
+       id="linearGradient6070"
+       xlink:href="#linearGradient4738"
+       inkscape:collect="always" />
+    <linearGradient
+       y2="390.78342"
+       x2="311.27377"
+       y1="377.9527"
+       x1="302.73621"
+       gradientTransform="matrix(1.9519,0,0,1.84182,-440.5695,-620.2357)"
+       gradientUnits="userSpaceOnUse"
+       id="linearGradient6073"
+       xlink:href="#linearGradient4554"
+       inkscape:collect="always" />
+    <linearGradient
+       y2="323.17273"
+       x2="681.0014"
+       y1="300.41397"
+       x1="661.46326"
+       gradientTransform="matrix(0.80139,0,0,1.247832,-433.2238,-292.6035)"
+       gradientUnits="userSpaceOnUse"
+       id="linearGradient6077"
+       xlink:href="#linearGradient4738"
+       inkscape:collect="always" />
+    <linearGradient
+       y2="390.78342"
+       x2="311.27377"
+       y1="377.9527"
+       x1="302.73621"
+       gradientTransform="matrix(1.9519,0,0,1.84182,-515.2268,-620.2357)"
+       gradientUnits="userSpaceOnUse"
+       id="linearGradient6080"
+       xlink:href="#linearGradient4554"
+       inkscape:collect="always" />
+  </defs>
+  <sodipodi:namedview
+     inkscape:window-y="0"
+     inkscape:window-x="0"
+     inkscape:window-height="968"
+     inkscape:window-width="1280"
+     inkscape:document-units="px"
+     inkscape:current-layer="layer1"
+     inkscape:cy="57.545109"
+     inkscape:cx="-46.821767"
+     inkscape:zoom="3.0989011"
+     inkscape:pageshadow="2"
+     inkscape:pageopacity="0.0"
+     borderopacity="1.0"
+     bordercolor="#666666"
+     pagecolor="#ffffff"
+     id="base"
+     borderlayer="true"
+     showborder="true"
+     showgrid="false"
+     inkscape:window-maximized="0" />
+  <metadata
+     id="metadata4">
+    <rdf:RDF>
+      <cc:Work
+         rdf:about="">
+        <dc:format>image/svg+xml</dc:format>
+        <dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+      </cc:Work>
+    </rdf:RDF>
+  </metadata>
+  <g
+     inkscape:groupmode="layer"
+     inkscape:label="Layer 1"
+     id="layer1"
+     transform="translate(-213.3568,12.4428)">
+    <path
+       transform="matrix(1.896061,0,0,1.896061,-374.8545,-700.975)"
+       d="m 339.53775,378.05789 c 0,7.71359 -6.25309,13.96668 -13.96667,13.96668 -7.71359,0 -13.96668,-6.25309 -13.96668,-13.96668 0,-7.71358 6.25309,-13.96668 13.96668,-13.96668 7.71358,0 13.96667,6.2531 13.96667,13.96668 z"
+       sodipodi:ry="13.966679"
+       sodipodi:rx="13.966679"
+       sodipodi:cy="378.05789"
+       sodipodi:cx="325.57108"
+       id="path5170"
+       style="color:black;fill:#000080;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:3.62500000000000000;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible"
+       sodipodi:type="arc" />
+    <path
+       transform="matrix(1.731185,0,0,1.731185,-321.1761,-638.6428)"
+       d="m 339.53775,378.05789 c 0,7.71359 -6.25309,13.96668 -13.96667,13.96668 -7.71359,0 -13.96668,-6.25309 -13.96668,-13.96668 0,-7.71358 6.25309,-13.96668 13.96668,-13.96668 7.71358,0 13.96667,6.2531 13.96667,13.96668 z"
+       sodipodi:ry="13.966679"
+       sodipodi:rx="13.966679"
+       sodipodi:cy="378.05789"
+       sodipodi:cx="325.57108"
+       id="path5172"
+       style="color:black;fill:url(#linearGradient5602);fill-opacity:1;fill-rule:nonzero;stroke:white;stroke-width:0.72204876;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible"
+       sodipodi:type="arc" />
+    <path
+       id="path5174"
+       d="M 242.43189,-8.3201378 C 229.08514,-8.3201378 218.25709,2.507892 218.25711,15.854642 C 218.25711,22.267212 220.87405,27.997552 224.95258,32.326672 C 227.07143,14.826182 241.8421,1.2194221 259.9112,1.2194221 C 260.39841,1.2194221 260.85081,1.318382 261.33325,1.337922 C 256.91182,-4.4127679 250.24118,-8.3201378 242.43189,-8.3201378 z "
+       style="color:black;fill:url(#linearGradient6049);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.61607176;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible" />
+    <path
+       style="color:#000000;fill:url(#linearGradient6046);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.75000167;marker:none;visibility:visible;display:inline;overflow:visible"
+       d="M 257.93856,11.283501 253.80724,7.1521606 242.10689,18.85252 230.51874,7.2643706 226.3568,11.426311 242.07629,27.1458 257.93856,11.283501 z"
+       id="path5176"
+       inkscape:connector-curvature="0" />
+  </g>
+</svg>
diff --git a/data/themes/default/arrow_button_left.svg b/data/themes/default/arrow_button_left.svg
new file mode 100644 (file)
index 0000000..c420c62
--- /dev/null
@@ -0,0 +1,911 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://creativecommons.org/ns#"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:xlink="http://www.w3.org/1999/xlink"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   sodipodi:docname="arrow_button_left.svg"
+   inkscape:version="0.48.0 r9654"
+   sodipodi:version="0.32"
+   id="svg5683"
+   height="56.5886"
+   width="57.044964"
+   version="1.0">
+  <defs
+     id="defs3">
+    <linearGradient
+       y2="323.17273"
+       x2="681.0014"
+       y1="300.41397"
+       x1="661.46326"
+       gradientTransform="matrix(0.80139,0,0,1.247832,288.7111,-153.4135)"
+       gradientUnits="userSpaceOnUse"
+       id="linearGradient5500"
+       xlink:href="#linearGradient4738"
+       inkscape:collect="always" />
+    <linearGradient
+       y2="390.78342"
+       x2="311.27377"
+       y1="377.9527"
+       x1="302.73621"
+       gradientTransform="matrix(1.9519,0,0,1.84182,206.7081,-481.0457)"
+       gradientUnits="userSpaceOnUse"
+       id="linearGradient5498"
+       xlink:href="#linearGradient4554"
+       inkscape:collect="always" />
+    <linearGradient
+       y2="387.43924"
+       x2="332.02466"
+       y1="369.97995"
+       x1="314.56537"
+       gradientUnits="userSpaceOnUse"
+       id="linearGradient5496"
+       xlink:href="#linearGradient4568"
+       inkscape:collect="always" />
+    <linearGradient
+       y2="550.81836"
+       x2="-487.88327"
+       y1="529.3363"
+       x1="-466.60916"
+       gradientTransform="matrix(0,-0.80139,1.247832,0,224.6646,-148.7015)"
+       gradientUnits="userSpaceOnUse"
+       id="linearGradient5494"
+       xlink:href="#linearGradient4738"
+       inkscape:collect="always" />
+    <linearGradient
+       y2="390.78342"
+       x2="311.27377"
+       y1="377.9527"
+       x1="302.73621"
+       gradientTransform="matrix(1.9519,0,0,1.84182,281.3651,-481.0457)"
+       gradientUnits="userSpaceOnUse"
+       id="linearGradient5492"
+       xlink:href="#linearGradient4554"
+       inkscape:collect="always" />
+    <linearGradient
+       y2="387.43924"
+       x2="332.02466"
+       y1="369.97995"
+       x1="314.56537"
+       gradientUnits="userSpaceOnUse"
+       id="linearGradient5490"
+       xlink:href="#linearGradient4568"
+       inkscape:collect="always" />
+    <linearGradient
+       y2="316.30093"
+       x2="-673.75562"
+       y1="293.93457"
+       x1="-653.01508"
+       gradientTransform="matrix(-0.80139,0,0,1.247832,214.5211,-145.3283)"
+       gradientUnits="userSpaceOnUse"
+       id="linearGradient5488"
+       xlink:href="#linearGradient4738"
+       inkscape:collect="always" />
+    <linearGradient
+       y2="390.78342"
+       x2="311.27377"
+       y1="377.9527"
+       x1="302.73621"
+       gradientTransform="matrix(1.9519,0,0,1.84182,132.051,-481.0457)"
+       gradientUnits="userSpaceOnUse"
+       id="linearGradient5486"
+       xlink:href="#linearGradient4554"
+       inkscape:collect="always" />
+    <linearGradient
+       y2="387.43924"
+       x2="332.02466"
+       y1="369.97995"
+       x1="314.56537"
+       gradientUnits="userSpaceOnUse"
+       id="linearGradient5484"
+       xlink:href="#linearGradient4568"
+       inkscape:collect="always" />
+    <linearGradient
+       y2="614.64392"
+       x2="487.88327"
+       y1="592.7915"
+       x1="467.18936"
+       gradientTransform="matrix(0,0.80139,1.247832,0,219.986,-144.9236)"
+       gradientUnits="userSpaceOnUse"
+       id="linearGradient5482"
+       xlink:href="#linearGradient4738"
+       inkscape:collect="always" />
+    <linearGradient
+       y2="390.78342"
+       x2="311.27377"
+       y1="377.9527"
+       x1="302.73621"
+       gradientTransform="matrix(1.9519,0,0,1.84182,356.022,-481.0457)"
+       gradientUnits="userSpaceOnUse"
+       id="linearGradient5480"
+       xlink:href="#linearGradient4554"
+       inkscape:collect="always" />
+    <linearGradient
+       id="linearGradient4568">
+      <stop
+         id="stop4570"
+         offset="0"
+         style="stop-color:#e12b1c;stop-opacity:1;" />
+      <stop
+         id="stop4572"
+         offset="1.0000000"
+         style="stop-color:#980b00;stop-opacity:1.0000000;" />
+    </linearGradient>
+    <linearGradient
+       y2="387.43924"
+       x2="332.02466"
+       y1="369.97995"
+       x1="314.56537"
+       gradientUnits="userSpaceOnUse"
+       id="linearGradient5478"
+       xlink:href="#linearGradient4568"
+       inkscape:collect="always" />
+    <linearGradient
+       y2="323.17273"
+       x2="681.0014"
+       y1="300.41397"
+       x1="661.46326"
+       gradientTransform="matrix(0.80139,0,0,1.247832,324.2651,-311.3622)"
+       gradientUnits="userSpaceOnUse"
+       id="linearGradient5606"
+       xlink:href="#linearGradient4738"
+       inkscape:collect="always" />
+    <linearGradient
+       y2="390.78342"
+       x2="311.27377"
+       y1="377.9527"
+       x1="302.73621"
+       gradientTransform="matrix(1.9519,0,0,1.84182,242.2621,-638.9944)"
+       gradientUnits="userSpaceOnUse"
+       id="linearGradient5604"
+       xlink:href="#linearGradient4554"
+       inkscape:collect="always" />
+    <linearGradient
+       y2="387.43924"
+       x2="332.02466"
+       y1="369.97995"
+       x1="314.56537"
+       gradientUnits="userSpaceOnUse"
+       id="linearGradient5602"
+       xlink:href="#linearGradient4886"
+       inkscape:collect="always" />
+    <linearGradient
+       y2="550.81836"
+       x2="-487.88327"
+       y1="529.3363"
+       x1="-466.60916"
+       gradientTransform="matrix(0,-0.80139,1.247832,0,260.2186,-306.6502)"
+       gradientUnits="userSpaceOnUse"
+       id="linearGradient5287"
+       xlink:href="#linearGradient4738"
+       inkscape:collect="always" />
+    <linearGradient
+       y2="390.78342"
+       x2="311.27377"
+       y1="377.9527"
+       x1="302.73621"
+       gradientTransform="matrix(1.9519,0,0,1.84182,316.9191,-638.9944)"
+       gradientUnits="userSpaceOnUse"
+       id="linearGradient5290"
+       xlink:href="#linearGradient4554"
+       inkscape:collect="always" />
+    <linearGradient
+       y2="387.43924"
+       x2="332.02466"
+       y1="369.97995"
+       x1="314.56537"
+       gradientUnits="userSpaceOnUse"
+       id="linearGradient5336"
+       xlink:href="#linearGradient4886"
+       inkscape:collect="always" />
+    <linearGradient
+       y2="316.30093"
+       x2="-673.75562"
+       y1="293.93457"
+       x1="-653.01508"
+       gradientTransform="matrix(-0.80139,0,0,1.247832,250.0751,-303.277)"
+       gradientUnits="userSpaceOnUse"
+       id="linearGradient5594"
+       xlink:href="#linearGradient4738"
+       inkscape:collect="always" />
+    <linearGradient
+       y2="390.78342"
+       x2="311.27377"
+       y1="377.9527"
+       x1="302.73621"
+       gradientTransform="matrix(1.9519,0,0,1.84182,167.605,-638.9944)"
+       gradientUnits="userSpaceOnUse"
+       id="linearGradient5592"
+       xlink:href="#linearGradient4554"
+       inkscape:collect="always" />
+    <linearGradient
+       y2="387.43924"
+       x2="332.02466"
+       y1="369.97995"
+       x1="314.56537"
+       gradientUnits="userSpaceOnUse"
+       id="linearGradient5590"
+       xlink:href="#linearGradient4886"
+       inkscape:collect="always" />
+    <linearGradient
+       y2="614.64392"
+       x2="487.88327"
+       y1="592.7915"
+       x1="467.18936"
+       gradientTransform="matrix(0,0.80139,1.247832,0,255.54,-302.8723)"
+       gradientUnits="userSpaceOnUse"
+       id="linearGradient5600"
+       xlink:href="#linearGradient4738"
+       inkscape:collect="always" />
+    <linearGradient
+       y2="390.78342"
+       x2="311.27377"
+       y1="377.9527"
+       x1="302.73621"
+       gradientTransform="matrix(1.9519,0,0,1.84182,391.576,-638.9944)"
+       gradientUnits="userSpaceOnUse"
+       id="linearGradient5598"
+       xlink:href="#linearGradient4554"
+       inkscape:collect="always" />
+    <linearGradient
+       id="linearGradient4886">
+      <stop
+         id="stop4888"
+         offset="0"
+         style="stop-color:#16e500;stop-opacity:1;" />
+      <stop
+         id="stop4890"
+         offset="1"
+         style="stop-color:#005900;stop-opacity:1;" />
+    </linearGradient>
+    <linearGradient
+       y2="323.17273"
+       x2="681.0014"
+       y1="300.41397"
+       x1="661.46326"
+       gradientTransform="matrix(0.80139,0,0,1.247832,291.6739,-84.28068)"
+       gradientUnits="userSpaceOnUse"
+       id="linearGradient5476"
+       xlink:href="#linearGradient4738"
+       inkscape:collect="always" />
+    <linearGradient
+       y2="390.78342"
+       x2="311.27377"
+       y1="377.9527"
+       x1="302.73621"
+       gradientTransform="matrix(1.9519,0,0,1.84182,209.6709,-411.9129)"
+       gradientUnits="userSpaceOnUse"
+       id="linearGradient5474"
+       xlink:href="#linearGradient4554"
+       inkscape:collect="always" />
+    <linearGradient
+       y2="387.43924"
+       x2="332.02466"
+       y1="369.97995"
+       x1="314.56537"
+       gradientUnits="userSpaceOnUse"
+       id="linearGradient5472"
+       xlink:href="#linearGradient4932"
+       inkscape:collect="always" />
+    <linearGradient
+       y2="550.81836"
+       x2="-487.88327"
+       y1="529.3363"
+       x1="-466.60916"
+       gradientTransform="matrix(0,-0.80139,1.247832,0,227.6274,-79.56868)"
+       gradientUnits="userSpaceOnUse"
+       id="linearGradient5470"
+       xlink:href="#linearGradient4738"
+       inkscape:collect="always" />
+    <linearGradient
+       y2="390.78342"
+       x2="311.27377"
+       y1="377.9527"
+       x1="302.73621"
+       gradientTransform="matrix(1.9519,0,0,1.84182,284.3279,-411.9129)"
+       gradientUnits="userSpaceOnUse"
+       id="linearGradient5468"
+       xlink:href="#linearGradient4554"
+       inkscape:collect="always" />
+    <linearGradient
+       y2="387.43924"
+       x2="332.02466"
+       y1="369.97995"
+       x1="314.56537"
+       gradientUnits="userSpaceOnUse"
+       id="linearGradient5466"
+       xlink:href="#linearGradient4932"
+       inkscape:collect="always" />
+    <linearGradient
+       y2="316.30093"
+       x2="-673.75562"
+       y1="293.93457"
+       x1="-653.01508"
+       gradientTransform="matrix(-0.80139,0,0,1.247832,217.4839,-76.19548)"
+       gradientUnits="userSpaceOnUse"
+       id="linearGradient5464"
+       xlink:href="#linearGradient4738"
+       inkscape:collect="always" />
+    <linearGradient
+       y2="390.78342"
+       x2="311.27377"
+       y1="377.9527"
+       x1="302.73621"
+       gradientTransform="matrix(1.9519,0,0,1.84182,135.0138,-411.9129)"
+       gradientUnits="userSpaceOnUse"
+       id="linearGradient5462"
+       xlink:href="#linearGradient4554"
+       inkscape:collect="always" />
+    <linearGradient
+       y2="387.43924"
+       x2="332.02466"
+       y1="369.97995"
+       x1="314.56537"
+       gradientUnits="userSpaceOnUse"
+       id="linearGradient5460"
+       xlink:href="#linearGradient4932"
+       inkscape:collect="always" />
+    <linearGradient
+       y2="614.64392"
+       x2="487.88327"
+       y1="592.7915"
+       x1="467.18936"
+       gradientTransform="matrix(0,0.80139,1.247832,0,222.9488,-75.79078)"
+       gradientUnits="userSpaceOnUse"
+       id="linearGradient5458"
+       xlink:href="#linearGradient4738"
+       inkscape:collect="always" />
+    <linearGradient
+       y2="390.78342"
+       x2="311.27377"
+       y1="377.9527"
+       x1="302.73621"
+       gradientTransform="matrix(1.9519,0,0,1.84182,358.9848,-411.9129)"
+       gradientUnits="userSpaceOnUse"
+       id="linearGradient5456"
+       xlink:href="#linearGradient4554"
+       inkscape:collect="always" />
+    <linearGradient
+       id="linearGradient4932">
+      <stop
+         id="stop4934"
+         offset="0.0000000"
+         style="stop-color:#66e11c;stop-opacity:1.0000000;" />
+      <stop
+         id="stop4936"
+         offset="1.0000000"
+         style="stop-color:#3d9800;stop-opacity:1.0000000;" />
+    </linearGradient>
+    <linearGradient
+       y2="387.43924"
+       x2="332.02466"
+       y1="369.97995"
+       x1="314.56537"
+       gradientUnits="userSpaceOnUse"
+       id="linearGradient5454"
+       xlink:href="#linearGradient4932"
+       inkscape:collect="always" />
+    <linearGradient
+       y2="323.17273"
+       x2="681.0014"
+       y1="300.41397"
+       x1="661.46326"
+       gradientTransform="matrix(0.80139,0,0,1.247832,324.2651,-100.0825)"
+       gradientUnits="userSpaceOnUse"
+       id="linearGradient5633"
+       xlink:href="#linearGradient4738"
+       inkscape:collect="always" />
+    <linearGradient
+       y2="390.78342"
+       x2="311.27377"
+       y1="377.9527"
+       x1="302.73621"
+       gradientTransform="matrix(1.9519,0,0,1.84182,242.2621,-427.7147)"
+       gradientUnits="userSpaceOnUse"
+       id="linearGradient5636"
+       xlink:href="#linearGradient4554"
+       inkscape:collect="always" />
+    <linearGradient
+       y2="387.43924"
+       x2="332.02466"
+       y1="369.97995"
+       x1="314.56537"
+       gradientUnits="userSpaceOnUse"
+       id="linearGradient5644"
+       xlink:href="#linearGradient5028"
+       inkscape:collect="always" />
+    <linearGradient
+       y2="550.81836"
+       x2="-487.88327"
+       y1="529.3363"
+       x1="-466.60916"
+       gradientTransform="matrix(0,-0.80139,1.247832,0,260.2186,-95.37047)"
+       gradientUnits="userSpaceOnUse"
+       id="linearGradient5625"
+       xlink:href="#linearGradient4738"
+       inkscape:collect="always" />
+    <linearGradient
+       y2="390.78342"
+       x2="311.27377"
+       y1="377.9527"
+       x1="302.73621"
+       gradientTransform="matrix(1.9519,0,0,1.84182,316.9191,-427.7147)"
+       gradientUnits="userSpaceOnUse"
+       id="linearGradient5628"
+       xlink:href="#linearGradient4554"
+       inkscape:collect="always" />
+    <linearGradient
+       y2="387.43924"
+       x2="332.02466"
+       y1="369.97995"
+       x1="314.56537"
+       gradientUnits="userSpaceOnUse"
+       id="linearGradient5640"
+       xlink:href="#linearGradient5028"
+       inkscape:collect="always" />
+    <linearGradient
+       y2="316.30093"
+       x2="-673.75562"
+       y1="293.93457"
+       x1="-653.01508"
+       gradientTransform="matrix(-0.80139,0,0,1.247832,250.0751,-91.99727)"
+       gradientUnits="userSpaceOnUse"
+       id="linearGradient5617"
+       xlink:href="#linearGradient4738"
+       inkscape:collect="always" />
+    <linearGradient
+       y2="390.78342"
+       x2="311.27377"
+       y1="377.9527"
+       x1="302.73621"
+       gradientTransform="matrix(1.9519,0,0,1.84182,167.605,-427.7147)"
+       gradientUnits="userSpaceOnUse"
+       id="linearGradient5620"
+       xlink:href="#linearGradient4554"
+       inkscape:collect="always" />
+    <linearGradient
+       y2="387.43924"
+       x2="332.02466"
+       y1="369.97995"
+       x1="314.56537"
+       gradientUnits="userSpaceOnUse"
+       id="linearGradient5646"
+       xlink:href="#linearGradient5028"
+       inkscape:collect="always" />
+    <linearGradient
+       id="linearGradient4738">
+      <stop
+         id="stop4740"
+         offset="0.0000000"
+         style="stop-color:#ffffff;stop-opacity:0.72656250;" />
+      <stop
+         id="stop4742"
+         offset="1.0000000"
+         style="stop-color:#ffffff;stop-opacity:1.0000000;" />
+    </linearGradient>
+    <linearGradient
+       y2="614.64392"
+       x2="487.88327"
+       y1="592.7915"
+       x1="467.18936"
+       gradientTransform="matrix(0,0.80139,1.247832,0,255.54,-91.59257)"
+       gradientUnits="userSpaceOnUse"
+       id="linearGradient5609"
+       xlink:href="#linearGradient4738"
+       inkscape:collect="always" />
+    <linearGradient
+       id="linearGradient4554">
+      <stop
+         id="stop4556"
+         offset="0.0000000"
+         style="stop-color:#ffffff;stop-opacity:1.0000000;" />
+      <stop
+         id="stop4558"
+         offset="1.0000000"
+         style="stop-color:#ffffff;stop-opacity:0.0000000;" />
+    </linearGradient>
+    <linearGradient
+       y2="390.78342"
+       x2="311.27377"
+       y1="377.9527"
+       x1="302.73621"
+       gradientTransform="matrix(1.9519,0,0,1.84182,391.576,-427.7147)"
+       gradientUnits="userSpaceOnUse"
+       id="linearGradient5612"
+       xlink:href="#linearGradient4554"
+       inkscape:collect="always" />
+    <linearGradient
+       id="linearGradient5028">
+      <stop
+         style="stop-color:#fffd26;stop-opacity:1.0000000;"
+         offset="0.0000000"
+         id="stop5030" />
+      <stop
+         style="stop-color:#967f00;stop-opacity:1.0000000;"
+         offset="1.0000000"
+         id="stop5032" />
+    </linearGradient>
+    <linearGradient
+       y2="387.43924"
+       x2="332.02466"
+       y1="369.97995"
+       x1="314.56537"
+       gradientUnits="userSpaceOnUse"
+       id="linearGradient5642"
+       xlink:href="#linearGradient5028"
+       inkscape:collect="always" />
+    <linearGradient
+       y2="614.64392"
+       x2="487.88327"
+       y1="592.7915"
+       x1="467.18936"
+       gradientTransform="matrix(0,0.80139,1.247832,0,-501.9489,-144.8603)"
+       gradientUnits="userSpaceOnUse"
+       id="linearGradient5958"
+       xlink:href="#linearGradient4738"
+       inkscape:collect="always" />
+    <linearGradient
+       y2="390.78342"
+       x2="311.27377"
+       y1="377.9527"
+       x1="302.73621"
+       gradientTransform="matrix(1.9519,0,0,1.84182,-365.9129,-480.9825)"
+       gradientUnits="userSpaceOnUse"
+       id="linearGradient5961"
+       xlink:href="#linearGradient4554"
+       inkscape:collect="always" />
+    <linearGradient
+       y2="316.30093"
+       x2="-673.75562"
+       y1="293.93457"
+       x1="-653.01508"
+       gradientTransform="matrix(-0.80139,0,0,1.247832,-507.4138,-145.265)"
+       gradientUnits="userSpaceOnUse"
+       id="linearGradient5966"
+       xlink:href="#linearGradient4738"
+       inkscape:collect="always" />
+    <linearGradient
+       y2="390.78342"
+       x2="311.27377"
+       y1="377.9527"
+       x1="302.73621"
+       gradientTransform="matrix(1.9519,0,0,1.84182,-589.8839,-480.9825)"
+       gradientUnits="userSpaceOnUse"
+       id="linearGradient5969"
+       xlink:href="#linearGradient4554"
+       inkscape:collect="always" />
+    <linearGradient
+       y2="550.81836"
+       x2="-487.88327"
+       y1="529.3363"
+       x1="-466.60916"
+       gradientTransform="matrix(0,-0.80139,1.247832,0,-497.2703,-148.6382)"
+       gradientUnits="userSpaceOnUse"
+       id="linearGradient5974"
+       xlink:href="#linearGradient4738"
+       inkscape:collect="always" />
+    <linearGradient
+       y2="390.78342"
+       x2="311.27377"
+       y1="377.9527"
+       x1="302.73621"
+       gradientTransform="matrix(1.9519,0,0,1.84182,-440.5698,-480.9825)"
+       gradientUnits="userSpaceOnUse"
+       id="linearGradient5977"
+       xlink:href="#linearGradient4554"
+       inkscape:collect="always" />
+    <linearGradient
+       y2="323.17273"
+       x2="681.0014"
+       y1="300.41397"
+       x1="661.46326"
+       gradientTransform="matrix(0.80139,0,0,1.247832,-433.2238,-153.3502)"
+       gradientUnits="userSpaceOnUse"
+       id="linearGradient5982"
+       xlink:href="#linearGradient4738"
+       inkscape:collect="always" />
+    <linearGradient
+       y2="390.78342"
+       x2="311.27377"
+       y1="377.9527"
+       x1="302.73621"
+       gradientTransform="matrix(1.9519,0,0,1.84182,-515.2268,-480.9825)"
+       gradientUnits="userSpaceOnUse"
+       id="linearGradient5985"
+       xlink:href="#linearGradient4554"
+       inkscape:collect="always" />
+    <linearGradient
+       y2="614.64392"
+       x2="487.88327"
+       y1="592.7915"
+       x1="467.18936"
+       gradientTransform="matrix(0,0.80139,1.247832,0,-501.9489,-214.9808)"
+       gradientUnits="userSpaceOnUse"
+       id="linearGradient5990"
+       xlink:href="#linearGradient4738"
+       inkscape:collect="always" />
+    <linearGradient
+       y2="390.78342"
+       x2="311.27377"
+       y1="377.9527"
+       x1="302.73621"
+       gradientTransform="matrix(1.9519,0,0,1.84182,-365.9129,-551.1029)"
+       gradientUnits="userSpaceOnUse"
+       id="linearGradient5993"
+       xlink:href="#linearGradient4554"
+       inkscape:collect="always" />
+    <linearGradient
+       y2="316.30093"
+       x2="-673.75562"
+       y1="293.93457"
+       x1="-653.01508"
+       gradientTransform="matrix(-0.80139,0,0,1.247832,-507.4138,-215.3855)"
+       gradientUnits="userSpaceOnUse"
+       id="linearGradient5998"
+       xlink:href="#linearGradient4738"
+       inkscape:collect="always" />
+    <linearGradient
+       y2="390.78342"
+       x2="311.27377"
+       y1="377.9527"
+       x1="302.73621"
+       gradientTransform="matrix(1.9519,0,0,1.84182,-589.8839,-551.1029)"
+       gradientUnits="userSpaceOnUse"
+       id="linearGradient6001"
+       xlink:href="#linearGradient4554"
+       inkscape:collect="always" />
+    <linearGradient
+       y2="550.81836"
+       x2="-487.88327"
+       y1="529.3363"
+       x1="-466.60916"
+       gradientTransform="matrix(0,-0.80139,1.247832,0,-497.2703,-218.7587)"
+       gradientUnits="userSpaceOnUse"
+       id="linearGradient6006"
+       xlink:href="#linearGradient4738"
+       inkscape:collect="always" />
+    <linearGradient
+       y2="390.78342"
+       x2="311.27377"
+       y1="377.9527"
+       x1="302.73621"
+       gradientTransform="matrix(1.9519,0,0,1.84182,-440.5698,-551.1029)"
+       gradientUnits="userSpaceOnUse"
+       id="linearGradient6009"
+       xlink:href="#linearGradient4554"
+       inkscape:collect="always" />
+    <linearGradient
+       y2="323.17273"
+       x2="681.0014"
+       y1="300.41397"
+       x1="661.46326"
+       gradientTransform="matrix(0.80139,0,0,1.247832,-433.2238,-223.4707)"
+       gradientUnits="userSpaceOnUse"
+       id="linearGradient6014"
+       xlink:href="#linearGradient4738"
+       inkscape:collect="always" />
+    <linearGradient
+       y2="390.78342"
+       x2="311.27377"
+       y1="377.9527"
+       x1="302.73621"
+       gradientTransform="matrix(1.9519,0,0,1.84182,-515.2268,-551.1029)"
+       gradientUnits="userSpaceOnUse"
+       id="linearGradient6017"
+       xlink:href="#linearGradient4554"
+       inkscape:collect="always" />
+    <linearGradient
+       y2="316.30093"
+       x2="-673.75562"
+       y1="293.93457"
+       x1="-653.01508"
+       gradientTransform="matrix(-0.80139,0,0,1.247832,-507.4138,-356.5448)"
+       gradientUnits="userSpaceOnUse"
+       id="linearGradient6030"
+       xlink:href="#linearGradient4738"
+       inkscape:collect="always" />
+    <linearGradient
+       y2="390.78342"
+       x2="311.27377"
+       y1="377.9527"
+       x1="302.73621"
+       gradientTransform="matrix(1.9519,0,0,1.84182,-589.8839,-692.2622)"
+       gradientUnits="userSpaceOnUse"
+       id="linearGradient6033"
+       xlink:href="#linearGradient4554"
+       inkscape:collect="always" />
+    <linearGradient
+       y2="550.81836"
+       x2="-487.88327"
+       y1="529.3363"
+       x1="-466.60916"
+       gradientTransform="matrix(0,-0.80139,1.247832,0,-497.2703,-359.918)"
+       gradientUnits="userSpaceOnUse"
+       id="linearGradient6038"
+       xlink:href="#linearGradient4738"
+       inkscape:collect="always" />
+    <linearGradient
+       y2="390.78342"
+       x2="311.27377"
+       y1="377.9527"
+       x1="302.73621"
+       gradientTransform="matrix(1.9519,0,0,1.84182,-440.5698,-692.2622)"
+       gradientUnits="userSpaceOnUse"
+       id="linearGradient6041"
+       xlink:href="#linearGradient4554"
+       inkscape:collect="always" />
+    <linearGradient
+       y2="323.17273"
+       x2="681.0014"
+       y1="300.41397"
+       x1="661.46326"
+       gradientTransform="matrix(-0.80139,0,0,1.247832,778.27258,-373.3428)"
+       gradientUnits="userSpaceOnUse"
+       id="linearGradient6046"
+       xlink:href="#linearGradient4738"
+       inkscape:collect="always" />
+    <linearGradient
+       y2="390.78342"
+       x2="311.27377"
+       y1="377.9527"
+       x1="302.73621"
+       gradientTransform="matrix(1.9519,0,0,1.84182,-374.8545,-700.975)"
+       gradientUnits="userSpaceOnUse"
+       id="linearGradient6049"
+       xlink:href="#linearGradient4554"
+       inkscape:collect="always" />
+    <linearGradient
+       y2="614.64392"
+       x2="487.88327"
+       y1="592.7915"
+       x1="467.18936"
+       gradientTransform="matrix(0,0.80139,1.247832,0,-501.9489,-284.1136)"
+       gradientUnits="userSpaceOnUse"
+       id="linearGradient6054"
+       xlink:href="#linearGradient4738"
+       inkscape:collect="always" />
+    <linearGradient
+       y2="390.78342"
+       x2="311.27377"
+       y1="377.9527"
+       x1="302.73621"
+       gradientTransform="matrix(1.9519,0,0,1.84182,-365.9129,-620.2357)"
+       gradientUnits="userSpaceOnUse"
+       id="linearGradient6057"
+       xlink:href="#linearGradient4554"
+       inkscape:collect="always" />
+    <linearGradient
+       y2="316.30093"
+       x2="-673.75562"
+       y1="293.93457"
+       x1="-653.01508"
+       gradientTransform="matrix(-0.80139,0,0,1.247832,-507.4138,-284.5183)"
+       gradientUnits="userSpaceOnUse"
+       id="linearGradient6062"
+       xlink:href="#linearGradient4738"
+       inkscape:collect="always" />
+    <linearGradient
+       y2="390.78342"
+       x2="311.27377"
+       y1="377.9527"
+       x1="302.73621"
+       gradientTransform="matrix(1.9519,0,0,1.84182,-589.8839,-620.2357)"
+       gradientUnits="userSpaceOnUse"
+       id="linearGradient6065"
+       xlink:href="#linearGradient4554"
+       inkscape:collect="always" />
+    <linearGradient
+       y2="550.81836"
+       x2="-487.88327"
+       y1="529.3363"
+       x1="-466.60916"
+       gradientTransform="matrix(0,-0.80139,1.247832,0,-497.27,-287.8915)"
+       gradientUnits="userSpaceOnUse"
+       id="linearGradient6070"
+       xlink:href="#linearGradient4738"
+       inkscape:collect="always" />
+    <linearGradient
+       y2="390.78342"
+       x2="311.27377"
+       y1="377.9527"
+       x1="302.73621"
+       gradientTransform="matrix(1.9519,0,0,1.84182,-440.5695,-620.2357)"
+       gradientUnits="userSpaceOnUse"
+       id="linearGradient6073"
+       xlink:href="#linearGradient4554"
+       inkscape:collect="always" />
+    <linearGradient
+       y2="323.17273"
+       x2="681.0014"
+       y1="300.41397"
+       x1="661.46326"
+       gradientTransform="matrix(0.80139,0,0,1.247832,-433.2238,-292.6035)"
+       gradientUnits="userSpaceOnUse"
+       id="linearGradient6077"
+       xlink:href="#linearGradient4738"
+       inkscape:collect="always" />
+    <linearGradient
+       y2="390.78342"
+       x2="311.27377"
+       y1="377.9527"
+       x1="302.73621"
+       gradientTransform="matrix(1.9519,0,0,1.84182,-515.2268,-620.2357)"
+       gradientUnits="userSpaceOnUse"
+       id="linearGradient6080"
+       xlink:href="#linearGradient4554"
+       inkscape:collect="always" />
+  </defs>
+  <sodipodi:namedview
+     inkscape:window-y="19"
+     inkscape:window-x="0"
+     inkscape:window-height="968"
+     inkscape:window-width="1280"
+     inkscape:document-units="px"
+     inkscape:current-layer="layer1"
+     inkscape:cy="57.545109"
+     inkscape:cx="15.458375"
+     inkscape:zoom="3.0989011"
+     inkscape:pageshadow="2"
+     inkscape:pageopacity="0.0"
+     borderopacity="1.0"
+     bordercolor="#666666"
+     pagecolor="#ffffff"
+     id="base"
+     borderlayer="true"
+     showborder="true"
+     showgrid="false"
+     inkscape:window-maximized="0" />
+  <metadata
+     id="metadata4">
+    <rdf:RDF>
+      <cc:Work
+         rdf:about="">
+        <dc:format>image/svg+xml</dc:format>
+        <dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+        <dc:title></dc:title>
+      </cc:Work>
+    </rdf:RDF>
+  </metadata>
+  <g
+     inkscape:groupmode="layer"
+     inkscape:label="Layer 1"
+     id="layer1"
+     transform="translate(-213.3568,12.4428)">
+    <path
+       transform="matrix(1.896061,0,0,1.896061,-374.8545,-700.975)"
+       d="m 339.53775,378.05789 c 0,7.71359 -6.25309,13.96668 -13.96667,13.96668 -7.71359,0 -13.96668,-6.25309 -13.96668,-13.96668 0,-7.71358 6.25309,-13.96668 13.96668,-13.96668 7.71358,0 13.96667,6.2531 13.96667,13.96668 z"
+       sodipodi:ry="13.966679"
+       sodipodi:rx="13.966679"
+       sodipodi:cy="378.05789"
+       sodipodi:cx="325.57108"
+       id="path5170"
+       style="color:black;fill:#006600;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:3.62500000000000000;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible"
+       sodipodi:type="arc" />
+    <path
+       transform="matrix(1.731185,0,0,1.731185,-321.1761,-638.6428)"
+       d="m 339.53775,378.05789 c 0,7.71359 -6.25309,13.96668 -13.96667,13.96668 -7.71359,0 -13.96668,-6.25309 -13.96668,-13.96668 0,-7.71358 6.25309,-13.96668 13.96668,-13.96668 7.71358,0 13.96667,6.2531 13.96667,13.96668 z"
+       sodipodi:ry="13.966679"
+       sodipodi:rx="13.966679"
+       sodipodi:cy="378.05789"
+       sodipodi:cx="325.57108"
+       id="path5172"
+       style="color:black;fill:url(#linearGradient5602);fill-opacity:1;fill-rule:nonzero;stroke:white;stroke-width:0.72204876;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible"
+       sodipodi:type="arc" />
+    <path
+       id="path5174"
+       d="M 242.43189,-8.3201378 C 229.08514,-8.3201378 218.25709,2.507892 218.25711,15.854642 C 218.25711,22.267212 220.87405,27.997552 224.95258,32.326672 C 227.07143,14.826182 241.8421,1.2194221 259.9112,1.2194221 C 260.39841,1.2194221 260.85081,1.318382 261.33325,1.337922 C 256.91182,-4.4127679 250.24118,-8.3201378 242.43189,-8.3201378 z "
+       style="color:black;fill:url(#linearGradient6049);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.61607176;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible" />
+    <path
+       style="color:#000000;fill:url(#linearGradient6046);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.75000167;marker:none;visibility:visible;display:inline;overflow:visible"
+       d="m 246.2191,0.05459208 4.13134,4.13132992 -11.70036,11.70035 11.58815,11.58815 -4.16194,4.16194 -15.71949,-15.71949 15.8623,-15.86227992 z"
+       id="path5176"
+       inkscape:connector-curvature="0" />
+  </g>
+</svg>
diff --git a/data/themes/default/arrow_button_right.svg b/data/themes/default/arrow_button_right.svg
new file mode 100644 (file)
index 0000000..b6cfc6e
--- /dev/null
@@ -0,0 +1,909 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://creativecommons.org/ns#"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:xlink="http://www.w3.org/1999/xlink"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   sodipodi:docname="arrow_button_right.svg"
+   inkscape:version="0.48.0 r9654"
+   sodipodi:version="0.32"
+   id="svg5683"
+   height="56.5886"
+   width="57.044964"
+   version="1.0">
+  <defs
+     id="defs3">
+    <linearGradient
+       y2="323.17273"
+       x2="681.0014"
+       y1="300.41397"
+       x1="661.46326"
+       gradientTransform="matrix(0.80139,0,0,1.247832,288.7111,-153.4135)"
+       gradientUnits="userSpaceOnUse"
+       id="linearGradient5500"
+       xlink:href="#linearGradient4738"
+       inkscape:collect="always" />
+    <linearGradient
+       y2="390.78342"
+       x2="311.27377"
+       y1="377.9527"
+       x1="302.73621"
+       gradientTransform="matrix(1.9519,0,0,1.84182,206.7081,-481.0457)"
+       gradientUnits="userSpaceOnUse"
+       id="linearGradient5498"
+       xlink:href="#linearGradient4554"
+       inkscape:collect="always" />
+    <linearGradient
+       y2="387.43924"
+       x2="332.02466"
+       y1="369.97995"
+       x1="314.56537"
+       gradientUnits="userSpaceOnUse"
+       id="linearGradient5496"
+       xlink:href="#linearGradient4568"
+       inkscape:collect="always" />
+    <linearGradient
+       y2="550.81836"
+       x2="-487.88327"
+       y1="529.3363"
+       x1="-466.60916"
+       gradientTransform="matrix(0,-0.80139,1.247832,0,224.6646,-148.7015)"
+       gradientUnits="userSpaceOnUse"
+       id="linearGradient5494"
+       xlink:href="#linearGradient4738"
+       inkscape:collect="always" />
+    <linearGradient
+       y2="390.78342"
+       x2="311.27377"
+       y1="377.9527"
+       x1="302.73621"
+       gradientTransform="matrix(1.9519,0,0,1.84182,281.3651,-481.0457)"
+       gradientUnits="userSpaceOnUse"
+       id="linearGradient5492"
+       xlink:href="#linearGradient4554"
+       inkscape:collect="always" />
+    <linearGradient
+       y2="387.43924"
+       x2="332.02466"
+       y1="369.97995"
+       x1="314.56537"
+       gradientUnits="userSpaceOnUse"
+       id="linearGradient5490"
+       xlink:href="#linearGradient4568"
+       inkscape:collect="always" />
+    <linearGradient
+       y2="316.30093"
+       x2="-673.75562"
+       y1="293.93457"
+       x1="-653.01508"
+       gradientTransform="matrix(-0.80139,0,0,1.247832,214.5211,-145.3283)"
+       gradientUnits="userSpaceOnUse"
+       id="linearGradient5488"
+       xlink:href="#linearGradient4738"
+       inkscape:collect="always" />
+    <linearGradient
+       y2="390.78342"
+       x2="311.27377"
+       y1="377.9527"
+       x1="302.73621"
+       gradientTransform="matrix(1.9519,0,0,1.84182,132.051,-481.0457)"
+       gradientUnits="userSpaceOnUse"
+       id="linearGradient5486"
+       xlink:href="#linearGradient4554"
+       inkscape:collect="always" />
+    <linearGradient
+       y2="387.43924"
+       x2="332.02466"
+       y1="369.97995"
+       x1="314.56537"
+       gradientUnits="userSpaceOnUse"
+       id="linearGradient5484"
+       xlink:href="#linearGradient4568"
+       inkscape:collect="always" />
+    <linearGradient
+       y2="614.64392"
+       x2="487.88327"
+       y1="592.7915"
+       x1="467.18936"
+       gradientTransform="matrix(0,0.80139,1.247832,0,219.986,-144.9236)"
+       gradientUnits="userSpaceOnUse"
+       id="linearGradient5482"
+       xlink:href="#linearGradient4738"
+       inkscape:collect="always" />
+    <linearGradient
+       y2="390.78342"
+       x2="311.27377"
+       y1="377.9527"
+       x1="302.73621"
+       gradientTransform="matrix(1.9519,0,0,1.84182,356.022,-481.0457)"
+       gradientUnits="userSpaceOnUse"
+       id="linearGradient5480"
+       xlink:href="#linearGradient4554"
+       inkscape:collect="always" />
+    <linearGradient
+       id="linearGradient4568">
+      <stop
+         id="stop4570"
+         offset="0"
+         style="stop-color:#e12b1c;stop-opacity:1;" />
+      <stop
+         id="stop4572"
+         offset="1.0000000"
+         style="stop-color:#980b00;stop-opacity:1.0000000;" />
+    </linearGradient>
+    <linearGradient
+       y2="387.43924"
+       x2="332.02466"
+       y1="369.97995"
+       x1="314.56537"
+       gradientUnits="userSpaceOnUse"
+       id="linearGradient5478"
+       xlink:href="#linearGradient4568"
+       inkscape:collect="always" />
+    <linearGradient
+       y2="323.17273"
+       x2="681.0014"
+       y1="300.41397"
+       x1="661.46326"
+       gradientTransform="matrix(0.80139,0,0,1.247832,324.2651,-311.3622)"
+       gradientUnits="userSpaceOnUse"
+       id="linearGradient5606"
+       xlink:href="#linearGradient4738"
+       inkscape:collect="always" />
+    <linearGradient
+       y2="390.78342"
+       x2="311.27377"
+       y1="377.9527"
+       x1="302.73621"
+       gradientTransform="matrix(1.9519,0,0,1.84182,242.2621,-638.9944)"
+       gradientUnits="userSpaceOnUse"
+       id="linearGradient5604"
+       xlink:href="#linearGradient4554"
+       inkscape:collect="always" />
+    <linearGradient
+       y2="387.43924"
+       x2="332.02466"
+       y1="369.97995"
+       x1="314.56537"
+       gradientUnits="userSpaceOnUse"
+       id="linearGradient5602"
+       xlink:href="#linearGradient4886"
+       inkscape:collect="always" />
+    <linearGradient
+       y2="550.81836"
+       x2="-487.88327"
+       y1="529.3363"
+       x1="-466.60916"
+       gradientTransform="matrix(0,-0.80139,1.247832,0,260.2186,-306.6502)"
+       gradientUnits="userSpaceOnUse"
+       id="linearGradient5287"
+       xlink:href="#linearGradient4738"
+       inkscape:collect="always" />
+    <linearGradient
+       y2="390.78342"
+       x2="311.27377"
+       y1="377.9527"
+       x1="302.73621"
+       gradientTransform="matrix(1.9519,0,0,1.84182,316.9191,-638.9944)"
+       gradientUnits="userSpaceOnUse"
+       id="linearGradient5290"
+       xlink:href="#linearGradient4554"
+       inkscape:collect="always" />
+    <linearGradient
+       y2="387.43924"
+       x2="332.02466"
+       y1="369.97995"
+       x1="314.56537"
+       gradientUnits="userSpaceOnUse"
+       id="linearGradient5336"
+       xlink:href="#linearGradient4886"
+       inkscape:collect="always" />
+    <linearGradient
+       y2="316.30093"
+       x2="-673.75562"
+       y1="293.93457"
+       x1="-653.01508"
+       gradientTransform="matrix(-0.80139,0,0,1.247832,250.0751,-303.277)"
+       gradientUnits="userSpaceOnUse"
+       id="linearGradient5594"
+       xlink:href="#linearGradient4738"
+       inkscape:collect="always" />
+    <linearGradient
+       y2="390.78342"
+       x2="311.27377"
+       y1="377.9527"
+       x1="302.73621"
+       gradientTransform="matrix(1.9519,0,0,1.84182,167.605,-638.9944)"
+       gradientUnits="userSpaceOnUse"
+       id="linearGradient5592"
+       xlink:href="#linearGradient4554"
+       inkscape:collect="always" />
+    <linearGradient
+       y2="387.43924"
+       x2="332.02466"
+       y1="369.97995"
+       x1="314.56537"
+       gradientUnits="userSpaceOnUse"
+       id="linearGradient5590"
+       xlink:href="#linearGradient4886"
+       inkscape:collect="always" />
+    <linearGradient
+       y2="614.64392"
+       x2="487.88327"
+       y1="592.7915"
+       x1="467.18936"
+       gradientTransform="matrix(0,0.80139,1.247832,0,255.54,-302.8723)"
+       gradientUnits="userSpaceOnUse"
+       id="linearGradient5600"
+       xlink:href="#linearGradient4738"
+       inkscape:collect="always" />
+    <linearGradient
+       y2="390.78342"
+       x2="311.27377"
+       y1="377.9527"
+       x1="302.73621"
+       gradientTransform="matrix(1.9519,0,0,1.84182,391.576,-638.9944)"
+       gradientUnits="userSpaceOnUse"
+       id="linearGradient5598"
+       xlink:href="#linearGradient4554"
+       inkscape:collect="always" />
+    <linearGradient
+       id="linearGradient4886">
+      <stop
+         id="stop4888"
+         offset="0"
+         style="stop-color:#ff0000;stop-opacity:1;" />
+      <stop
+         id="stop4890"
+         offset="1"
+         style="stop-color:#850000;stop-opacity:1;" />
+    </linearGradient>
+    <linearGradient
+       y2="323.17273"
+       x2="681.0014"
+       y1="300.41397"
+       x1="661.46326"
+       gradientTransform="matrix(0.80139,0,0,1.247832,291.6739,-84.28068)"
+       gradientUnits="userSpaceOnUse"
+       id="linearGradient5476"
+       xlink:href="#linearGradient4738"
+       inkscape:collect="always" />
+    <linearGradient
+       y2="390.78342"
+       x2="311.27377"
+       y1="377.9527"
+       x1="302.73621"
+       gradientTransform="matrix(1.9519,0,0,1.84182,209.6709,-411.9129)"
+       gradientUnits="userSpaceOnUse"
+       id="linearGradient5474"
+       xlink:href="#linearGradient4554"
+       inkscape:collect="always" />
+    <linearGradient
+       y2="387.43924"
+       x2="332.02466"
+       y1="369.97995"
+       x1="314.56537"
+       gradientUnits="userSpaceOnUse"
+       id="linearGradient5472"
+       xlink:href="#linearGradient4932"
+       inkscape:collect="always" />
+    <linearGradient
+       y2="550.81836"
+       x2="-487.88327"
+       y1="529.3363"
+       x1="-466.60916"
+       gradientTransform="matrix(0,-0.80139,1.247832,0,227.6274,-79.56868)"
+       gradientUnits="userSpaceOnUse"
+       id="linearGradient5470"
+       xlink:href="#linearGradient4738"
+       inkscape:collect="always" />
+    <linearGradient
+       y2="390.78342"
+       x2="311.27377"
+       y1="377.9527"
+       x1="302.73621"
+       gradientTransform="matrix(1.9519,0,0,1.84182,284.3279,-411.9129)"
+       gradientUnits="userSpaceOnUse"
+       id="linearGradient5468"
+       xlink:href="#linearGradient4554"
+       inkscape:collect="always" />
+    <linearGradient
+       y2="387.43924"
+       x2="332.02466"
+       y1="369.97995"
+       x1="314.56537"
+       gradientUnits="userSpaceOnUse"
+       id="linearGradient5466"
+       xlink:href="#linearGradient4932"
+       inkscape:collect="always" />
+    <linearGradient
+       y2="316.30093"
+       x2="-673.75562"
+       y1="293.93457"
+       x1="-653.01508"
+       gradientTransform="matrix(-0.80139,0,0,1.247832,217.4839,-76.19548)"
+       gradientUnits="userSpaceOnUse"
+       id="linearGradient5464"
+       xlink:href="#linearGradient4738"
+       inkscape:collect="always" />
+    <linearGradient
+       y2="390.78342"
+       x2="311.27377"
+       y1="377.9527"
+       x1="302.73621"
+       gradientTransform="matrix(1.9519,0,0,1.84182,135.0138,-411.9129)"
+       gradientUnits="userSpaceOnUse"
+       id="linearGradient5462"
+       xlink:href="#linearGradient4554"
+       inkscape:collect="always" />
+    <linearGradient
+       y2="387.43924"
+       x2="332.02466"
+       y1="369.97995"
+       x1="314.56537"
+       gradientUnits="userSpaceOnUse"
+       id="linearGradient5460"
+       xlink:href="#linearGradient4932"
+       inkscape:collect="always" />
+    <linearGradient
+       y2="614.64392"
+       x2="487.88327"
+       y1="592.7915"
+       x1="467.18936"
+       gradientTransform="matrix(0,0.80139,1.247832,0,222.9488,-75.79078)"
+       gradientUnits="userSpaceOnUse"
+       id="linearGradient5458"
+       xlink:href="#linearGradient4738"
+       inkscape:collect="always" />
+    <linearGradient
+       y2="390.78342"
+       x2="311.27377"
+       y1="377.9527"
+       x1="302.73621"
+       gradientTransform="matrix(1.9519,0,0,1.84182,358.9848,-411.9129)"
+       gradientUnits="userSpaceOnUse"
+       id="linearGradient5456"
+       xlink:href="#linearGradient4554"
+       inkscape:collect="always" />
+    <linearGradient
+       id="linearGradient4932">
+      <stop
+         id="stop4934"
+         offset="0.0000000"
+         style="stop-color:#66e11c;stop-opacity:1.0000000;" />
+      <stop
+         id="stop4936"
+         offset="1.0000000"
+         style="stop-color:#3d9800;stop-opacity:1.0000000;" />
+    </linearGradient>
+    <linearGradient
+       y2="387.43924"
+       x2="332.02466"
+       y1="369.97995"
+       x1="314.56537"
+       gradientUnits="userSpaceOnUse"
+       id="linearGradient5454"
+       xlink:href="#linearGradient4932"
+       inkscape:collect="always" />
+    <linearGradient
+       y2="323.17273"
+       x2="681.0014"
+       y1="300.41397"
+       x1="661.46326"
+       gradientTransform="matrix(0.80139,0,0,1.247832,324.2651,-100.0825)"
+       gradientUnits="userSpaceOnUse"
+       id="linearGradient5633"
+       xlink:href="#linearGradient4738"
+       inkscape:collect="always" />
+    <linearGradient
+       y2="390.78342"
+       x2="311.27377"
+       y1="377.9527"
+       x1="302.73621"
+       gradientTransform="matrix(1.9519,0,0,1.84182,242.2621,-427.7147)"
+       gradientUnits="userSpaceOnUse"
+       id="linearGradient5636"
+       xlink:href="#linearGradient4554"
+       inkscape:collect="always" />
+    <linearGradient
+       y2="387.43924"
+       x2="332.02466"
+       y1="369.97995"
+       x1="314.56537"
+       gradientUnits="userSpaceOnUse"
+       id="linearGradient5644"
+       xlink:href="#linearGradient5028"
+       inkscape:collect="always" />
+    <linearGradient
+       y2="550.81836"
+       x2="-487.88327"
+       y1="529.3363"
+       x1="-466.60916"
+       gradientTransform="matrix(0,-0.80139,1.247832,0,260.2186,-95.37047)"
+       gradientUnits="userSpaceOnUse"
+       id="linearGradient5625"
+       xlink:href="#linearGradient4738"
+       inkscape:collect="always" />
+    <linearGradient
+       y2="390.78342"
+       x2="311.27377"
+       y1="377.9527"
+       x1="302.73621"
+       gradientTransform="matrix(1.9519,0,0,1.84182,316.9191,-427.7147)"
+       gradientUnits="userSpaceOnUse"
+       id="linearGradient5628"
+       xlink:href="#linearGradient4554"
+       inkscape:collect="always" />
+    <linearGradient
+       y2="387.43924"
+       x2="332.02466"
+       y1="369.97995"
+       x1="314.56537"
+       gradientUnits="userSpaceOnUse"
+       id="linearGradient5640"
+       xlink:href="#linearGradient5028"
+       inkscape:collect="always" />
+    <linearGradient
+       y2="316.30093"
+       x2="-673.75562"
+       y1="293.93457"
+       x1="-653.01508"
+       gradientTransform="matrix(-0.80139,0,0,1.247832,250.0751,-91.99727)"
+       gradientUnits="userSpaceOnUse"
+       id="linearGradient5617"
+       xlink:href="#linearGradient4738"
+       inkscape:collect="always" />
+    <linearGradient
+       y2="390.78342"
+       x2="311.27377"
+       y1="377.9527"
+       x1="302.73621"
+       gradientTransform="matrix(1.9519,0,0,1.84182,167.605,-427.7147)"
+       gradientUnits="userSpaceOnUse"
+       id="linearGradient5620"
+       xlink:href="#linearGradient4554"
+       inkscape:collect="always" />
+    <linearGradient
+       y2="387.43924"
+       x2="332.02466"
+       y1="369.97995"
+       x1="314.56537"
+       gradientUnits="userSpaceOnUse"
+       id="linearGradient5646"
+       xlink:href="#linearGradient5028"
+       inkscape:collect="always" />
+    <linearGradient
+       id="linearGradient4738">
+      <stop
+         id="stop4740"
+         offset="0.0000000"
+         style="stop-color:#ffffff;stop-opacity:0.72656250;" />
+      <stop
+         id="stop4742"
+         offset="1.0000000"
+         style="stop-color:#ffffff;stop-opacity:1.0000000;" />
+    </linearGradient>
+    <linearGradient
+       y2="614.64392"
+       x2="487.88327"
+       y1="592.7915"
+       x1="467.18936"
+       gradientTransform="matrix(0,0.80139,1.247832,0,255.54,-91.59257)"
+       gradientUnits="userSpaceOnUse"
+       id="linearGradient5609"
+       xlink:href="#linearGradient4738"
+       inkscape:collect="always" />
+    <linearGradient
+       id="linearGradient4554">
+      <stop
+         id="stop4556"
+         offset="0.0000000"
+         style="stop-color:#ffffff;stop-opacity:1.0000000;" />
+      <stop
+         id="stop4558"
+         offset="1.0000000"
+         style="stop-color:#ffffff;stop-opacity:0.0000000;" />
+    </linearGradient>
+    <linearGradient
+       y2="390.78342"
+       x2="311.27377"
+       y1="377.9527"
+       x1="302.73621"
+       gradientTransform="matrix(1.9519,0,0,1.84182,391.576,-427.7147)"
+       gradientUnits="userSpaceOnUse"
+       id="linearGradient5612"
+       xlink:href="#linearGradient4554"
+       inkscape:collect="always" />
+    <linearGradient
+       id="linearGradient5028">
+      <stop
+         style="stop-color:#fffd26;stop-opacity:1.0000000;"
+         offset="0.0000000"
+         id="stop5030" />
+      <stop
+         style="stop-color:#967f00;stop-opacity:1.0000000;"
+         offset="1.0000000"
+         id="stop5032" />
+    </linearGradient>
+    <linearGradient
+       y2="387.43924"
+       x2="332.02466"
+       y1="369.97995"
+       x1="314.56537"
+       gradientUnits="userSpaceOnUse"
+       id="linearGradient5642"
+       xlink:href="#linearGradient5028"
+       inkscape:collect="always" />
+    <linearGradient
+       y2="614.64392"
+       x2="487.88327"
+       y1="592.7915"
+       x1="467.18936"
+       gradientTransform="matrix(0,0.80139,1.247832,0,-501.9489,-144.8603)"
+       gradientUnits="userSpaceOnUse"
+       id="linearGradient5958"
+       xlink:href="#linearGradient4738"
+       inkscape:collect="always" />
+    <linearGradient
+       y2="390.78342"
+       x2="311.27377"
+       y1="377.9527"
+       x1="302.73621"
+       gradientTransform="matrix(1.9519,0,0,1.84182,-365.9129,-480.9825)"
+       gradientUnits="userSpaceOnUse"
+       id="linearGradient5961"
+       xlink:href="#linearGradient4554"
+       inkscape:collect="always" />
+    <linearGradient
+       y2="316.30093"
+       x2="-673.75562"
+       y1="293.93457"
+       x1="-653.01508"
+       gradientTransform="matrix(-0.80139,0,0,1.247832,-507.4138,-145.265)"
+       gradientUnits="userSpaceOnUse"
+       id="linearGradient5966"
+       xlink:href="#linearGradient4738"
+       inkscape:collect="always" />
+    <linearGradient
+       y2="390.78342"
+       x2="311.27377"
+       y1="377.9527"
+       x1="302.73621"
+       gradientTransform="matrix(1.9519,0,0,1.84182,-589.8839,-480.9825)"
+       gradientUnits="userSpaceOnUse"
+       id="linearGradient5969"
+       xlink:href="#linearGradient4554"
+       inkscape:collect="always" />
+    <linearGradient
+       y2="550.81836"
+       x2="-487.88327"
+       y1="529.3363"
+       x1="-466.60916"
+       gradientTransform="matrix(0,-0.80139,1.247832,0,-497.2703,-148.6382)"
+       gradientUnits="userSpaceOnUse"
+       id="linearGradient5974"
+       xlink:href="#linearGradient4738"
+       inkscape:collect="always" />
+    <linearGradient
+       y2="390.78342"
+       x2="311.27377"
+       y1="377.9527"
+       x1="302.73621"
+       gradientTransform="matrix(1.9519,0,0,1.84182,-440.5698,-480.9825)"
+       gradientUnits="userSpaceOnUse"
+       id="linearGradient5977"
+       xlink:href="#linearGradient4554"
+       inkscape:collect="always" />
+    <linearGradient
+       y2="323.17273"
+       x2="681.0014"
+       y1="300.41397"
+       x1="661.46326"
+       gradientTransform="matrix(0.80139,0,0,1.247832,-433.2238,-153.3502)"
+       gradientUnits="userSpaceOnUse"
+       id="linearGradient5982"
+       xlink:href="#linearGradient4738"
+       inkscape:collect="always" />
+    <linearGradient
+       y2="390.78342"
+       x2="311.27377"
+       y1="377.9527"
+       x1="302.73621"
+       gradientTransform="matrix(1.9519,0,0,1.84182,-515.2268,-480.9825)"
+       gradientUnits="userSpaceOnUse"
+       id="linearGradient5985"
+       xlink:href="#linearGradient4554"
+       inkscape:collect="always" />
+    <linearGradient
+       y2="614.64392"
+       x2="487.88327"
+       y1="592.7915"
+       x1="467.18936"
+       gradientTransform="matrix(0,0.80139,1.247832,0,-501.9489,-214.9808)"
+       gradientUnits="userSpaceOnUse"
+       id="linearGradient5990"
+       xlink:href="#linearGradient4738"
+       inkscape:collect="always" />
+    <linearGradient
+       y2="390.78342"
+       x2="311.27377"
+       y1="377.9527"
+       x1="302.73621"
+       gradientTransform="matrix(1.9519,0,0,1.84182,-365.9129,-551.1029)"
+       gradientUnits="userSpaceOnUse"
+       id="linearGradient5993"
+       xlink:href="#linearGradient4554"
+       inkscape:collect="always" />
+    <linearGradient
+       y2="316.30093"
+       x2="-673.75562"
+       y1="293.93457"
+       x1="-653.01508"
+       gradientTransform="matrix(-0.80139,0,0,1.247832,-507.4138,-215.3855)"
+       gradientUnits="userSpaceOnUse"
+       id="linearGradient5998"
+       xlink:href="#linearGradient4738"
+       inkscape:collect="always" />
+    <linearGradient
+       y2="390.78342"
+       x2="311.27377"
+       y1="377.9527"
+       x1="302.73621"
+       gradientTransform="matrix(1.9519,0,0,1.84182,-589.8839,-551.1029)"
+       gradientUnits="userSpaceOnUse"
+       id="linearGradient6001"
+       xlink:href="#linearGradient4554"
+       inkscape:collect="always" />
+    <linearGradient
+       y2="550.81836"
+       x2="-487.88327"
+       y1="529.3363"
+       x1="-466.60916"
+       gradientTransform="matrix(0,-0.80139,1.247832,0,-497.2703,-218.7587)"
+       gradientUnits="userSpaceOnUse"
+       id="linearGradient6006"
+       xlink:href="#linearGradient4738"
+       inkscape:collect="always" />
+    <linearGradient
+       y2="390.78342"
+       x2="311.27377"
+       y1="377.9527"
+       x1="302.73621"
+       gradientTransform="matrix(1.9519,0,0,1.84182,-440.5698,-551.1029)"
+       gradientUnits="userSpaceOnUse"
+       id="linearGradient6009"
+       xlink:href="#linearGradient4554"
+       inkscape:collect="always" />
+    <linearGradient
+       y2="323.17273"
+       x2="681.0014"
+       y1="300.41397"
+       x1="661.46326"
+       gradientTransform="matrix(0.80139,0,0,1.247832,-433.2238,-223.4707)"
+       gradientUnits="userSpaceOnUse"
+       id="linearGradient6014"
+       xlink:href="#linearGradient4738"
+       inkscape:collect="always" />
+    <linearGradient
+       y2="390.78342"
+       x2="311.27377"
+       y1="377.9527"
+       x1="302.73621"
+       gradientTransform="matrix(1.9519,0,0,1.84182,-515.2268,-551.1029)"
+       gradientUnits="userSpaceOnUse"
+       id="linearGradient6017"
+       xlink:href="#linearGradient4554"
+       inkscape:collect="always" />
+    <linearGradient
+       y2="316.30093"
+       x2="-673.75562"
+       y1="293.93457"
+       x1="-653.01508"
+       gradientTransform="matrix(-0.80139,0,0,1.247832,-507.4138,-356.5448)"
+       gradientUnits="userSpaceOnUse"
+       id="linearGradient6030"
+       xlink:href="#linearGradient4738"
+       inkscape:collect="always" />
+    <linearGradient
+       y2="390.78342"
+       x2="311.27377"
+       y1="377.9527"
+       x1="302.73621"
+       gradientTransform="matrix(1.9519,0,0,1.84182,-589.8839,-692.2622)"
+       gradientUnits="userSpaceOnUse"
+       id="linearGradient6033"
+       xlink:href="#linearGradient4554"
+       inkscape:collect="always" />
+    <linearGradient
+       y2="550.81836"
+       x2="-487.88327"
+       y1="529.3363"
+       x1="-466.60916"
+       gradientTransform="matrix(0,-0.80139,1.247832,0,-497.2703,-359.918)"
+       gradientUnits="userSpaceOnUse"
+       id="linearGradient6038"
+       xlink:href="#linearGradient4738"
+       inkscape:collect="always" />
+    <linearGradient
+       y2="390.78342"
+       x2="311.27377"
+       y1="377.9527"
+       x1="302.73621"
+       gradientTransform="matrix(1.9519,0,0,1.84182,-440.5698,-692.2622)"
+       gradientUnits="userSpaceOnUse"
+       id="linearGradient6041"
+       xlink:href="#linearGradient4554"
+       inkscape:collect="always" />
+    <linearGradient
+       y2="323.17273"
+       x2="681.0014"
+       y1="300.41397"
+       x1="661.46326"
+       gradientTransform="matrix(0.80139,0,0,1.247832,-292.8515,-373.3428)"
+       gradientUnits="userSpaceOnUse"
+       id="linearGradient6046"
+       xlink:href="#linearGradient4738"
+       inkscape:collect="always" />
+    <linearGradient
+       y2="390.78342"
+       x2="311.27377"
+       y1="377.9527"
+       x1="302.73621"
+       gradientTransform="matrix(1.9519,0,0,1.84182,-374.8545,-700.975)"
+       gradientUnits="userSpaceOnUse"
+       id="linearGradient6049"
+       xlink:href="#linearGradient4554"
+       inkscape:collect="always" />
+    <linearGradient
+       y2="614.64392"
+       x2="487.88327"
+       y1="592.7915"
+       x1="467.18936"
+       gradientTransform="matrix(0,0.80139,1.247832,0,-501.9489,-284.1136)"
+       gradientUnits="userSpaceOnUse"
+       id="linearGradient6054"
+       xlink:href="#linearGradient4738"
+       inkscape:collect="always" />
+    <linearGradient
+       y2="390.78342"
+       x2="311.27377"
+       y1="377.9527"
+       x1="302.73621"
+       gradientTransform="matrix(1.9519,0,0,1.84182,-365.9129,-620.2357)"
+       gradientUnits="userSpaceOnUse"
+       id="linearGradient6057"
+       xlink:href="#linearGradient4554"
+       inkscape:collect="always" />
+    <linearGradient
+       y2="316.30093"
+       x2="-673.75562"
+       y1="293.93457"
+       x1="-653.01508"
+       gradientTransform="matrix(-0.80139,0,0,1.247832,-507.4138,-284.5183)"
+       gradientUnits="userSpaceOnUse"
+       id="linearGradient6062"
+       xlink:href="#linearGradient4738"
+       inkscape:collect="always" />
+    <linearGradient
+       y2="390.78342"
+       x2="311.27377"
+       y1="377.9527"
+       x1="302.73621"
+       gradientTransform="matrix(1.9519,0,0,1.84182,-589.8839,-620.2357)"
+       gradientUnits="userSpaceOnUse"
+       id="linearGradient6065"
+       xlink:href="#linearGradient4554"
+       inkscape:collect="always" />
+    <linearGradient
+       y2="550.81836"
+       x2="-487.88327"
+       y1="529.3363"
+       x1="-466.60916"
+       gradientTransform="matrix(0,-0.80139,1.247832,0,-497.27,-287.8915)"
+       gradientUnits="userSpaceOnUse"
+       id="linearGradient6070"
+       xlink:href="#linearGradient4738"
+       inkscape:collect="always" />
+    <linearGradient
+       y2="390.78342"
+       x2="311.27377"
+       y1="377.9527"
+       x1="302.73621"
+       gradientTransform="matrix(1.9519,0,0,1.84182,-440.5695,-620.2357)"
+       gradientUnits="userSpaceOnUse"
+       id="linearGradient6073"
+       xlink:href="#linearGradient4554"
+       inkscape:collect="always" />
+    <linearGradient
+       y2="323.17273"
+       x2="681.0014"
+       y1="300.41397"
+       x1="661.46326"
+       gradientTransform="matrix(0.80139,0,0,1.247832,-433.2238,-292.6035)"
+       gradientUnits="userSpaceOnUse"
+       id="linearGradient6077"
+       xlink:href="#linearGradient4738"
+       inkscape:collect="always" />
+    <linearGradient
+       y2="390.78342"
+       x2="311.27377"
+       y1="377.9527"
+       x1="302.73621"
+       gradientTransform="matrix(1.9519,0,0,1.84182,-515.2268,-620.2357)"
+       gradientUnits="userSpaceOnUse"
+       id="linearGradient6080"
+       xlink:href="#linearGradient4554"
+       inkscape:collect="always" />
+  </defs>
+  <sodipodi:namedview
+     inkscape:window-y="0"
+     inkscape:window-x="0"
+     inkscape:window-height="968"
+     inkscape:window-width="1280"
+     inkscape:document-units="px"
+     inkscape:current-layer="layer1"
+     inkscape:cy="57.545109"
+     inkscape:cx="15.458375"
+     inkscape:zoom="3.0989011"
+     inkscape:pageshadow="2"
+     inkscape:pageopacity="0.0"
+     borderopacity="1.0"
+     bordercolor="#666666"
+     pagecolor="#ffffff"
+     id="base"
+     borderlayer="true"
+     showborder="true"
+     showgrid="false"
+     inkscape:window-maximized="0" />
+  <metadata
+     id="metadata4">
+    <rdf:RDF>
+      <cc:Work
+         rdf:about="">
+        <dc:format>image/svg+xml</dc:format>
+        <dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+      </cc:Work>
+    </rdf:RDF>
+  </metadata>
+  <g
+     inkscape:groupmode="layer"
+     inkscape:label="Layer 1"
+     id="layer1"
+     transform="translate(-213.3568,12.4428)">
+    <path
+       transform="matrix(1.896061,0,0,1.896061,-374.8545,-700.975)"
+       d="m 339.53775,378.05789 c 0,7.71359 -6.25309,13.96668 -13.96667,13.96668 -7.71359,0 -13.96668,-6.25309 -13.96668,-13.96668 0,-7.71358 6.25309,-13.96668 13.96668,-13.96668 7.71358,0 13.96667,6.2531 13.96667,13.96668 z"
+       sodipodi:ry="13.966679"
+       sodipodi:rx="13.966679"
+       sodipodi:cy="378.05789"
+       sodipodi:cx="325.57108"
+       id="path5170"
+       style="color:black;fill:#800000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:3.62500000000000000;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible"
+       sodipodi:type="arc" />
+    <path
+       transform="matrix(1.731185,0,0,1.731185,-321.1761,-638.6428)"
+       d="m 339.53775,378.05789 c 0,7.71359 -6.25309,13.96668 -13.96667,13.96668 -7.71359,0 -13.96668,-6.25309 -13.96668,-13.96668 0,-7.71358 6.25309,-13.96668 13.96668,-13.96668 7.71358,0 13.96667,6.2531 13.96667,13.96668 z"
+       sodipodi:ry="13.966679"
+       sodipodi:rx="13.966679"
+       sodipodi:cy="378.05789"
+       sodipodi:cx="325.57108"
+       id="path5172"
+       style="color:black;fill:url(#linearGradient5602);fill-opacity:1;fill-rule:nonzero;stroke:white;stroke-width:0.72204876;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible"
+       sodipodi:type="arc" />
+    <path
+       id="path5174"
+       d="M 242.43189,-8.3201378 C 229.08514,-8.3201378 218.25709,2.507892 218.25711,15.854642 C 218.25711,22.267212 220.87405,27.997552 224.95258,32.326672 C 227.07143,14.826182 241.8421,1.2194221 259.9112,1.2194221 C 260.39841,1.2194221 260.85081,1.318382 261.33325,1.337922 C 256.91182,-4.4127679 250.24118,-8.3201378 242.43189,-8.3201378 z "
+       style="color:black;fill:url(#linearGradient6049);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.61607176;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible" />
+    <path
+       style="color:black;fill:url(#linearGradient6046);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.75000167;stroke-linecap:round;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible"
+       d="M 239.20198,0.05459208 L 235.07064,4.185922 L 246.771,15.886272 L 235.18285,27.474422 L 239.34479,31.636362 L 255.06428,15.916872 L 239.20198,0.05459208 z "
+       id="path5176" />
+  </g>
+</svg>
diff --git a/data/themes/default/arrow_button_up.svg b/data/themes/default/arrow_button_up.svg
new file mode 100644 (file)
index 0000000..e77e9f8
--- /dev/null
@@ -0,0 +1,910 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://creativecommons.org/ns#"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:xlink="http://www.w3.org/1999/xlink"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   sodipodi:docname="arrow_button_up.svg"
+   inkscape:version="0.48.0 r9654"
+   sodipodi:version="0.32"
+   id="svg5683"
+   height="56.5886"
+   width="57.044964"
+   version="1.0">
+  <defs
+     id="defs3">
+    <linearGradient
+       y2="323.17273"
+       x2="681.0014"
+       y1="300.41397"
+       x1="661.46326"
+       gradientTransform="matrix(0.80139,0,0,1.247832,288.7111,-153.4135)"
+       gradientUnits="userSpaceOnUse"
+       id="linearGradient5500"
+       xlink:href="#linearGradient4738"
+       inkscape:collect="always" />
+    <linearGradient
+       y2="390.78342"
+       x2="311.27377"
+       y1="377.9527"
+       x1="302.73621"
+       gradientTransform="matrix(1.9519,0,0,1.84182,206.7081,-481.0457)"
+       gradientUnits="userSpaceOnUse"
+       id="linearGradient5498"
+       xlink:href="#linearGradient4554"
+       inkscape:collect="always" />
+    <linearGradient
+       y2="387.43924"
+       x2="332.02466"
+       y1="369.97995"
+       x1="314.56537"
+       gradientUnits="userSpaceOnUse"
+       id="linearGradient5496"
+       xlink:href="#linearGradient4568"
+       inkscape:collect="always" />
+    <linearGradient
+       y2="550.81836"
+       x2="-487.88327"
+       y1="529.3363"
+       x1="-466.60916"
+       gradientTransform="matrix(0,-0.80139,1.247832,0,224.6646,-148.7015)"
+       gradientUnits="userSpaceOnUse"
+       id="linearGradient5494"
+       xlink:href="#linearGradient4738"
+       inkscape:collect="always" />
+    <linearGradient
+       y2="390.78342"
+       x2="311.27377"
+       y1="377.9527"
+       x1="302.73621"
+       gradientTransform="matrix(1.9519,0,0,1.84182,281.3651,-481.0457)"
+       gradientUnits="userSpaceOnUse"
+       id="linearGradient5492"
+       xlink:href="#linearGradient4554"
+       inkscape:collect="always" />
+    <linearGradient
+       y2="387.43924"
+       x2="332.02466"
+       y1="369.97995"
+       x1="314.56537"
+       gradientUnits="userSpaceOnUse"
+       id="linearGradient5490"
+       xlink:href="#linearGradient4568"
+       inkscape:collect="always" />
+    <linearGradient
+       y2="316.30093"
+       x2="-673.75562"
+       y1="293.93457"
+       x1="-653.01508"
+       gradientTransform="matrix(-0.80139,0,0,1.247832,214.5211,-145.3283)"
+       gradientUnits="userSpaceOnUse"
+       id="linearGradient5488"
+       xlink:href="#linearGradient4738"
+       inkscape:collect="always" />
+    <linearGradient
+       y2="390.78342"
+       x2="311.27377"
+       y1="377.9527"
+       x1="302.73621"
+       gradientTransform="matrix(1.9519,0,0,1.84182,132.051,-481.0457)"
+       gradientUnits="userSpaceOnUse"
+       id="linearGradient5486"
+       xlink:href="#linearGradient4554"
+       inkscape:collect="always" />
+    <linearGradient
+       y2="387.43924"
+       x2="332.02466"
+       y1="369.97995"
+       x1="314.56537"
+       gradientUnits="userSpaceOnUse"
+       id="linearGradient5484"
+       xlink:href="#linearGradient4568"
+       inkscape:collect="always" />
+    <linearGradient
+       y2="614.64392"
+       x2="487.88327"
+       y1="592.7915"
+       x1="467.18936"
+       gradientTransform="matrix(0,0.80139,1.247832,0,219.986,-144.9236)"
+       gradientUnits="userSpaceOnUse"
+       id="linearGradient5482"
+       xlink:href="#linearGradient4738"
+       inkscape:collect="always" />
+    <linearGradient
+       y2="390.78342"
+       x2="311.27377"
+       y1="377.9527"
+       x1="302.73621"
+       gradientTransform="matrix(1.9519,0,0,1.84182,356.022,-481.0457)"
+       gradientUnits="userSpaceOnUse"
+       id="linearGradient5480"
+       xlink:href="#linearGradient4554"
+       inkscape:collect="always" />
+    <linearGradient
+       id="linearGradient4568">
+      <stop
+         id="stop4570"
+         offset="0"
+         style="stop-color:#e12b1c;stop-opacity:1;" />
+      <stop
+         id="stop4572"
+         offset="1.0000000"
+         style="stop-color:#980b00;stop-opacity:1.0000000;" />
+    </linearGradient>
+    <linearGradient
+       y2="387.43924"
+       x2="332.02466"
+       y1="369.97995"
+       x1="314.56537"
+       gradientUnits="userSpaceOnUse"
+       id="linearGradient5478"
+       xlink:href="#linearGradient4568"
+       inkscape:collect="always" />
+    <linearGradient
+       y2="323.17273"
+       x2="681.0014"
+       y1="300.41397"
+       x1="661.46326"
+       gradientTransform="matrix(0.80139,0,0,1.247832,324.2651,-311.3622)"
+       gradientUnits="userSpaceOnUse"
+       id="linearGradient5606"
+       xlink:href="#linearGradient4738"
+       inkscape:collect="always" />
+    <linearGradient
+       y2="390.78342"
+       x2="311.27377"
+       y1="377.9527"
+       x1="302.73621"
+       gradientTransform="matrix(1.9519,0,0,1.84182,242.2621,-638.9944)"
+       gradientUnits="userSpaceOnUse"
+       id="linearGradient5604"
+       xlink:href="#linearGradient4554"
+       inkscape:collect="always" />
+    <linearGradient
+       y2="387.43924"
+       x2="332.02466"
+       y1="369.97995"
+       x1="314.56537"
+       gradientUnits="userSpaceOnUse"
+       id="linearGradient5602"
+       xlink:href="#linearGradient4886"
+       inkscape:collect="always" />
+    <linearGradient
+       y2="550.81836"
+       x2="-487.88327"
+       y1="529.3363"
+       x1="-466.60916"
+       gradientTransform="matrix(0,-0.80139,1.247832,0,260.2186,-306.6502)"
+       gradientUnits="userSpaceOnUse"
+       id="linearGradient5287"
+       xlink:href="#linearGradient4738"
+       inkscape:collect="always" />
+    <linearGradient
+       y2="390.78342"
+       x2="311.27377"
+       y1="377.9527"
+       x1="302.73621"
+       gradientTransform="matrix(1.9519,0,0,1.84182,316.9191,-638.9944)"
+       gradientUnits="userSpaceOnUse"
+       id="linearGradient5290"
+       xlink:href="#linearGradient4554"
+       inkscape:collect="always" />
+    <linearGradient
+       y2="387.43924"
+       x2="332.02466"
+       y1="369.97995"
+       x1="314.56537"
+       gradientUnits="userSpaceOnUse"
+       id="linearGradient5336"
+       xlink:href="#linearGradient4886"
+       inkscape:collect="always" />
+    <linearGradient
+       y2="316.30093"
+       x2="-673.75562"
+       y1="293.93457"
+       x1="-653.01508"
+       gradientTransform="matrix(-0.80139,0,0,1.247832,250.0751,-303.277)"
+       gradientUnits="userSpaceOnUse"
+       id="linearGradient5594"
+       xlink:href="#linearGradient4738"
+       inkscape:collect="always" />
+    <linearGradient
+       y2="390.78342"
+       x2="311.27377"
+       y1="377.9527"
+       x1="302.73621"
+       gradientTransform="matrix(1.9519,0,0,1.84182,167.605,-638.9944)"
+       gradientUnits="userSpaceOnUse"
+       id="linearGradient5592"
+       xlink:href="#linearGradient4554"
+       inkscape:collect="always" />
+    <linearGradient
+       y2="387.43924"
+       x2="332.02466"
+       y1="369.97995"
+       x1="314.56537"
+       gradientUnits="userSpaceOnUse"
+       id="linearGradient5590"
+       xlink:href="#linearGradient4886"
+       inkscape:collect="always" />
+    <linearGradient
+       y2="614.64392"
+       x2="487.88327"
+       y1="592.7915"
+       x1="467.18936"
+       gradientTransform="matrix(0,0.80139,1.247832,0,255.54,-302.8723)"
+       gradientUnits="userSpaceOnUse"
+       id="linearGradient5600"
+       xlink:href="#linearGradient4738"
+       inkscape:collect="always" />
+    <linearGradient
+       y2="390.78342"
+       x2="311.27377"
+       y1="377.9527"
+       x1="302.73621"
+       gradientTransform="matrix(1.9519,0,0,1.84182,391.576,-638.9944)"
+       gradientUnits="userSpaceOnUse"
+       id="linearGradient5598"
+       xlink:href="#linearGradient4554"
+       inkscape:collect="always" />
+    <linearGradient
+       id="linearGradient4886">
+      <stop
+         id="stop4888"
+         offset="0"
+         style="stop-color:#f6f100;stop-opacity:1;" />
+      <stop
+         id="stop4890"
+         offset="1"
+         style="stop-color:#dca42d;stop-opacity:1;" />
+    </linearGradient>
+    <linearGradient
+       y2="323.17273"
+       x2="681.0014"
+       y1="300.41397"
+       x1="661.46326"
+       gradientTransform="matrix(0.80139,0,0,1.247832,291.6739,-84.28068)"
+       gradientUnits="userSpaceOnUse"
+       id="linearGradient5476"
+       xlink:href="#linearGradient4738"
+       inkscape:collect="always" />
+    <linearGradient
+       y2="390.78342"
+       x2="311.27377"
+       y1="377.9527"
+       x1="302.73621"
+       gradientTransform="matrix(1.9519,0,0,1.84182,209.6709,-411.9129)"
+       gradientUnits="userSpaceOnUse"
+       id="linearGradient5474"
+       xlink:href="#linearGradient4554"
+       inkscape:collect="always" />
+    <linearGradient
+       y2="387.43924"
+       x2="332.02466"
+       y1="369.97995"
+       x1="314.56537"
+       gradientUnits="userSpaceOnUse"
+       id="linearGradient5472"
+       xlink:href="#linearGradient4932"
+       inkscape:collect="always" />
+    <linearGradient
+       y2="550.81836"
+       x2="-487.88327"
+       y1="529.3363"
+       x1="-466.60916"
+       gradientTransform="matrix(0,-0.80139,1.247832,0,227.6274,-79.56868)"
+       gradientUnits="userSpaceOnUse"
+       id="linearGradient5470"
+       xlink:href="#linearGradient4738"
+       inkscape:collect="always" />
+    <linearGradient
+       y2="390.78342"
+       x2="311.27377"
+       y1="377.9527"
+       x1="302.73621"
+       gradientTransform="matrix(1.9519,0,0,1.84182,284.3279,-411.9129)"
+       gradientUnits="userSpaceOnUse"
+       id="linearGradient5468"
+       xlink:href="#linearGradient4554"
+       inkscape:collect="always" />
+    <linearGradient
+       y2="387.43924"
+       x2="332.02466"
+       y1="369.97995"
+       x1="314.56537"
+       gradientUnits="userSpaceOnUse"
+       id="linearGradient5466"
+       xlink:href="#linearGradient4932"
+       inkscape:collect="always" />
+    <linearGradient
+       y2="316.30093"
+       x2="-673.75562"
+       y1="293.93457"
+       x1="-653.01508"
+       gradientTransform="matrix(-0.80139,0,0,1.247832,217.4839,-76.19548)"
+       gradientUnits="userSpaceOnUse"
+       id="linearGradient5464"
+       xlink:href="#linearGradient4738"
+       inkscape:collect="always" />
+    <linearGradient
+       y2="390.78342"
+       x2="311.27377"
+       y1="377.9527"
+       x1="302.73621"
+       gradientTransform="matrix(1.9519,0,0,1.84182,135.0138,-411.9129)"
+       gradientUnits="userSpaceOnUse"
+       id="linearGradient5462"
+       xlink:href="#linearGradient4554"
+       inkscape:collect="always" />
+    <linearGradient
+       y2="387.43924"
+       x2="332.02466"
+       y1="369.97995"
+       x1="314.56537"
+       gradientUnits="userSpaceOnUse"
+       id="linearGradient5460"
+       xlink:href="#linearGradient4932"
+       inkscape:collect="always" />
+    <linearGradient
+       y2="614.64392"
+       x2="487.88327"
+       y1="592.7915"
+       x1="467.18936"
+       gradientTransform="matrix(0,0.80139,1.247832,0,222.9488,-75.79078)"
+       gradientUnits="userSpaceOnUse"
+       id="linearGradient5458"
+       xlink:href="#linearGradient4738"
+       inkscape:collect="always" />
+    <linearGradient
+       y2="390.78342"
+       x2="311.27377"
+       y1="377.9527"
+       x1="302.73621"
+       gradientTransform="matrix(1.9519,0,0,1.84182,358.9848,-411.9129)"
+       gradientUnits="userSpaceOnUse"
+       id="linearGradient5456"
+       xlink:href="#linearGradient4554"
+       inkscape:collect="always" />
+    <linearGradient
+       id="linearGradient4932">
+      <stop
+         id="stop4934"
+         offset="0.0000000"
+         style="stop-color:#66e11c;stop-opacity:1.0000000;" />
+      <stop
+         id="stop4936"
+         offset="1.0000000"
+         style="stop-color:#3d9800;stop-opacity:1.0000000;" />
+    </linearGradient>
+    <linearGradient
+       y2="387.43924"
+       x2="332.02466"
+       y1="369.97995"
+       x1="314.56537"
+       gradientUnits="userSpaceOnUse"
+       id="linearGradient5454"
+       xlink:href="#linearGradient4932"
+       inkscape:collect="always" />
+    <linearGradient
+       y2="323.17273"
+       x2="681.0014"
+       y1="300.41397"
+       x1="661.46326"
+       gradientTransform="matrix(0.80139,0,0,1.247832,324.2651,-100.0825)"
+       gradientUnits="userSpaceOnUse"
+       id="linearGradient5633"
+       xlink:href="#linearGradient4738"
+       inkscape:collect="always" />
+    <linearGradient
+       y2="390.78342"
+       x2="311.27377"
+       y1="377.9527"
+       x1="302.73621"
+       gradientTransform="matrix(1.9519,0,0,1.84182,242.2621,-427.7147)"
+       gradientUnits="userSpaceOnUse"
+       id="linearGradient5636"
+       xlink:href="#linearGradient4554"
+       inkscape:collect="always" />
+    <linearGradient
+       y2="387.43924"
+       x2="332.02466"
+       y1="369.97995"
+       x1="314.56537"
+       gradientUnits="userSpaceOnUse"
+       id="linearGradient5644"
+       xlink:href="#linearGradient5028"
+       inkscape:collect="always" />
+    <linearGradient
+       y2="550.81836"
+       x2="-487.88327"
+       y1="529.3363"
+       x1="-466.60916"
+       gradientTransform="matrix(0,-0.80139,1.247832,0,260.2186,-95.37047)"
+       gradientUnits="userSpaceOnUse"
+       id="linearGradient5625"
+       xlink:href="#linearGradient4738"
+       inkscape:collect="always" />
+    <linearGradient
+       y2="390.78342"
+       x2="311.27377"
+       y1="377.9527"
+       x1="302.73621"
+       gradientTransform="matrix(1.9519,0,0,1.84182,316.9191,-427.7147)"
+       gradientUnits="userSpaceOnUse"
+       id="linearGradient5628"
+       xlink:href="#linearGradient4554"
+       inkscape:collect="always" />
+    <linearGradient
+       y2="387.43924"
+       x2="332.02466"
+       y1="369.97995"
+       x1="314.56537"
+       gradientUnits="userSpaceOnUse"
+       id="linearGradient5640"
+       xlink:href="#linearGradient5028"
+       inkscape:collect="always" />
+    <linearGradient
+       y2="316.30093"
+       x2="-673.75562"
+       y1="293.93457"
+       x1="-653.01508"
+       gradientTransform="matrix(-0.80139,0,0,1.247832,250.0751,-91.99727)"
+       gradientUnits="userSpaceOnUse"
+       id="linearGradient5617"
+       xlink:href="#linearGradient4738"
+       inkscape:collect="always" />
+    <linearGradient
+       y2="390.78342"
+       x2="311.27377"
+       y1="377.9527"
+       x1="302.73621"
+       gradientTransform="matrix(1.9519,0,0,1.84182,167.605,-427.7147)"
+       gradientUnits="userSpaceOnUse"
+       id="linearGradient5620"
+       xlink:href="#linearGradient4554"
+       inkscape:collect="always" />
+    <linearGradient
+       y2="387.43924"
+       x2="332.02466"
+       y1="369.97995"
+       x1="314.56537"
+       gradientUnits="userSpaceOnUse"
+       id="linearGradient5646"
+       xlink:href="#linearGradient5028"
+       inkscape:collect="always" />
+    <linearGradient
+       id="linearGradient4738">
+      <stop
+         id="stop4740"
+         offset="0.0000000"
+         style="stop-color:#ffffff;stop-opacity:0.72656250;" />
+      <stop
+         id="stop4742"
+         offset="1.0000000"
+         style="stop-color:#ffffff;stop-opacity:1.0000000;" />
+    </linearGradient>
+    <linearGradient
+       y2="614.64392"
+       x2="487.88327"
+       y1="592.7915"
+       x1="467.18936"
+       gradientTransform="matrix(0,0.80139,1.247832,0,255.54,-91.59257)"
+       gradientUnits="userSpaceOnUse"
+       id="linearGradient5609"
+       xlink:href="#linearGradient4738"
+       inkscape:collect="always" />
+    <linearGradient
+       id="linearGradient4554">
+      <stop
+         id="stop4556"
+         offset="0.0000000"
+         style="stop-color:#ffffff;stop-opacity:1.0000000;" />
+      <stop
+         id="stop4558"
+         offset="1.0000000"
+         style="stop-color:#ffffff;stop-opacity:0.0000000;" />
+    </linearGradient>
+    <linearGradient
+       y2="390.78342"
+       x2="311.27377"
+       y1="377.9527"
+       x1="302.73621"
+       gradientTransform="matrix(1.9519,0,0,1.84182,391.576,-427.7147)"
+       gradientUnits="userSpaceOnUse"
+       id="linearGradient5612"
+       xlink:href="#linearGradient4554"
+       inkscape:collect="always" />
+    <linearGradient
+       id="linearGradient5028">
+      <stop
+         style="stop-color:#fffd26;stop-opacity:1.0000000;"
+         offset="0.0000000"
+         id="stop5030" />
+      <stop
+         style="stop-color:#967f00;stop-opacity:1.0000000;"
+         offset="1.0000000"
+         id="stop5032" />
+    </linearGradient>
+    <linearGradient
+       y2="387.43924"
+       x2="332.02466"
+       y1="369.97995"
+       x1="314.56537"
+       gradientUnits="userSpaceOnUse"
+       id="linearGradient5642"
+       xlink:href="#linearGradient5028"
+       inkscape:collect="always" />
+    <linearGradient
+       y2="614.64392"
+       x2="487.88327"
+       y1="592.7915"
+       x1="467.18936"
+       gradientTransform="matrix(0,0.80139,1.247832,0,-501.9489,-144.8603)"
+       gradientUnits="userSpaceOnUse"
+       id="linearGradient5958"
+       xlink:href="#linearGradient4738"
+       inkscape:collect="always" />
+    <linearGradient
+       y2="390.78342"
+       x2="311.27377"
+       y1="377.9527"
+       x1="302.73621"
+       gradientTransform="matrix(1.9519,0,0,1.84182,-365.9129,-480.9825)"
+       gradientUnits="userSpaceOnUse"
+       id="linearGradient5961"
+       xlink:href="#linearGradient4554"
+       inkscape:collect="always" />
+    <linearGradient
+       y2="316.30093"
+       x2="-673.75562"
+       y1="293.93457"
+       x1="-653.01508"
+       gradientTransform="matrix(-0.80139,0,0,1.247832,-507.4138,-145.265)"
+       gradientUnits="userSpaceOnUse"
+       id="linearGradient5966"
+       xlink:href="#linearGradient4738"
+       inkscape:collect="always" />
+    <linearGradient
+       y2="390.78342"
+       x2="311.27377"
+       y1="377.9527"
+       x1="302.73621"
+       gradientTransform="matrix(1.9519,0,0,1.84182,-589.8839,-480.9825)"
+       gradientUnits="userSpaceOnUse"
+       id="linearGradient5969"
+       xlink:href="#linearGradient4554"
+       inkscape:collect="always" />
+    <linearGradient
+       y2="550.81836"
+       x2="-487.88327"
+       y1="529.3363"
+       x1="-466.60916"
+       gradientTransform="matrix(0,-0.80139,1.247832,0,-497.2703,-148.6382)"
+       gradientUnits="userSpaceOnUse"
+       id="linearGradient5974"
+       xlink:href="#linearGradient4738"
+       inkscape:collect="always" />
+    <linearGradient
+       y2="390.78342"
+       x2="311.27377"
+       y1="377.9527"
+       x1="302.73621"
+       gradientTransform="matrix(1.9519,0,0,1.84182,-440.5698,-480.9825)"
+       gradientUnits="userSpaceOnUse"
+       id="linearGradient5977"
+       xlink:href="#linearGradient4554"
+       inkscape:collect="always" />
+    <linearGradient
+       y2="323.17273"
+       x2="681.0014"
+       y1="300.41397"
+       x1="661.46326"
+       gradientTransform="matrix(0.80139,0,0,1.247832,-433.2238,-153.3502)"
+       gradientUnits="userSpaceOnUse"
+       id="linearGradient5982"
+       xlink:href="#linearGradient4738"
+       inkscape:collect="always" />
+    <linearGradient
+       y2="390.78342"
+       x2="311.27377"
+       y1="377.9527"
+       x1="302.73621"
+       gradientTransform="matrix(1.9519,0,0,1.84182,-515.2268,-480.9825)"
+       gradientUnits="userSpaceOnUse"
+       id="linearGradient5985"
+       xlink:href="#linearGradient4554"
+       inkscape:collect="always" />
+    <linearGradient
+       y2="614.64392"
+       x2="487.88327"
+       y1="592.7915"
+       x1="467.18936"
+       gradientTransform="matrix(0,0.80139,1.247832,0,-501.9489,-214.9808)"
+       gradientUnits="userSpaceOnUse"
+       id="linearGradient5990"
+       xlink:href="#linearGradient4738"
+       inkscape:collect="always" />
+    <linearGradient
+       y2="390.78342"
+       x2="311.27377"
+       y1="377.9527"
+       x1="302.73621"
+       gradientTransform="matrix(1.9519,0,0,1.84182,-365.9129,-551.1029)"
+       gradientUnits="userSpaceOnUse"
+       id="linearGradient5993"
+       xlink:href="#linearGradient4554"
+       inkscape:collect="always" />
+    <linearGradient
+       y2="316.30093"
+       x2="-673.75562"
+       y1="293.93457"
+       x1="-653.01508"
+       gradientTransform="matrix(-0.80139,0,0,1.247832,-507.4138,-215.3855)"
+       gradientUnits="userSpaceOnUse"
+       id="linearGradient5998"
+       xlink:href="#linearGradient4738"
+       inkscape:collect="always" />
+    <linearGradient
+       y2="390.78342"
+       x2="311.27377"
+       y1="377.9527"
+       x1="302.73621"
+       gradientTransform="matrix(1.9519,0,0,1.84182,-589.8839,-551.1029)"
+       gradientUnits="userSpaceOnUse"
+       id="linearGradient6001"
+       xlink:href="#linearGradient4554"
+       inkscape:collect="always" />
+    <linearGradient
+       y2="550.81836"
+       x2="-487.88327"
+       y1="529.3363"
+       x1="-466.60916"
+       gradientTransform="matrix(0,-0.80139,1.247832,0,-497.2703,-218.7587)"
+       gradientUnits="userSpaceOnUse"
+       id="linearGradient6006"
+       xlink:href="#linearGradient4738"
+       inkscape:collect="always" />
+    <linearGradient
+       y2="390.78342"
+       x2="311.27377"
+       y1="377.9527"
+       x1="302.73621"
+       gradientTransform="matrix(1.9519,0,0,1.84182,-440.5698,-551.1029)"
+       gradientUnits="userSpaceOnUse"
+       id="linearGradient6009"
+       xlink:href="#linearGradient4554"
+       inkscape:collect="always" />
+    <linearGradient
+       y2="323.17273"
+       x2="681.0014"
+       y1="300.41397"
+       x1="661.46326"
+       gradientTransform="matrix(0.80139,0,0,1.247832,-433.2238,-223.4707)"
+       gradientUnits="userSpaceOnUse"
+       id="linearGradient6014"
+       xlink:href="#linearGradient4738"
+       inkscape:collect="always" />
+    <linearGradient
+       y2="390.78342"
+       x2="311.27377"
+       y1="377.9527"
+       x1="302.73621"
+       gradientTransform="matrix(1.9519,0,0,1.84182,-515.2268,-551.1029)"
+       gradientUnits="userSpaceOnUse"
+       id="linearGradient6017"
+       xlink:href="#linearGradient4554"
+       inkscape:collect="always" />
+    <linearGradient
+       y2="316.30093"
+       x2="-673.75562"
+       y1="293.93457"
+       x1="-653.01508"
+       gradientTransform="matrix(-0.80139,0,0,1.247832,-507.4138,-356.5448)"
+       gradientUnits="userSpaceOnUse"
+       id="linearGradient6030"
+       xlink:href="#linearGradient4738"
+       inkscape:collect="always" />
+    <linearGradient
+       y2="390.78342"
+       x2="311.27377"
+       y1="377.9527"
+       x1="302.73621"
+       gradientTransform="matrix(1.9519,0,0,1.84182,-589.8839,-692.2622)"
+       gradientUnits="userSpaceOnUse"
+       id="linearGradient6033"
+       xlink:href="#linearGradient4554"
+       inkscape:collect="always" />
+    <linearGradient
+       y2="550.81836"
+       x2="-487.88327"
+       y1="529.3363"
+       x1="-466.60916"
+       gradientTransform="matrix(0,-0.80139,1.247832,0,-497.2703,-359.918)"
+       gradientUnits="userSpaceOnUse"
+       id="linearGradient6038"
+       xlink:href="#linearGradient4738"
+       inkscape:collect="always" />
+    <linearGradient
+       y2="390.78342"
+       x2="311.27377"
+       y1="377.9527"
+       x1="302.73621"
+       gradientTransform="matrix(1.9519,0,0,1.84182,-440.5698,-692.2622)"
+       gradientUnits="userSpaceOnUse"
+       id="linearGradient6041"
+       xlink:href="#linearGradient4554"
+       inkscape:collect="always" />
+    <linearGradient
+       y2="323.17273"
+       x2="681.0014"
+       y1="300.41397"
+       x1="661.46326"
+       gradientTransform="matrix(0,-0.80139,-1.247832,0,631.33596,552.06794)"
+       gradientUnits="userSpaceOnUse"
+       id="linearGradient6046"
+       xlink:href="#linearGradient4738"
+       inkscape:collect="always" />
+    <linearGradient
+       y2="390.78342"
+       x2="311.27377"
+       y1="377.9527"
+       x1="302.73621"
+       gradientTransform="matrix(1.9519,0,0,1.84182,-374.8545,-700.975)"
+       gradientUnits="userSpaceOnUse"
+       id="linearGradient6049"
+       xlink:href="#linearGradient4554"
+       inkscape:collect="always" />
+    <linearGradient
+       y2="614.64392"
+       x2="487.88327"
+       y1="592.7915"
+       x1="467.18936"
+       gradientTransform="matrix(0,0.80139,1.247832,0,-501.9489,-284.1136)"
+       gradientUnits="userSpaceOnUse"
+       id="linearGradient6054"
+       xlink:href="#linearGradient4738"
+       inkscape:collect="always" />
+    <linearGradient
+       y2="390.78342"
+       x2="311.27377"
+       y1="377.9527"
+       x1="302.73621"
+       gradientTransform="matrix(1.9519,0,0,1.84182,-365.9129,-620.2357)"
+       gradientUnits="userSpaceOnUse"
+       id="linearGradient6057"
+       xlink:href="#linearGradient4554"
+       inkscape:collect="always" />
+    <linearGradient
+       y2="316.30093"
+       x2="-673.75562"
+       y1="293.93457"
+       x1="-653.01508"
+       gradientTransform="matrix(-0.80139,0,0,1.247832,-507.4138,-284.5183)"
+       gradientUnits="userSpaceOnUse"
+       id="linearGradient6062"
+       xlink:href="#linearGradient4738"
+       inkscape:collect="always" />
+    <linearGradient
+       y2="390.78342"
+       x2="311.27377"
+       y1="377.9527"
+       x1="302.73621"
+       gradientTransform="matrix(1.9519,0,0,1.84182,-589.8839,-620.2357)"
+       gradientUnits="userSpaceOnUse"
+       id="linearGradient6065"
+       xlink:href="#linearGradient4554"
+       inkscape:collect="always" />
+    <linearGradient
+       y2="550.81836"
+       x2="-487.88327"
+       y1="529.3363"
+       x1="-466.60916"
+       gradientTransform="matrix(0,-0.80139,1.247832,0,-497.27,-287.8915)"
+       gradientUnits="userSpaceOnUse"
+       id="linearGradient6070"
+       xlink:href="#linearGradient4738"
+       inkscape:collect="always" />
+    <linearGradient
+       y2="390.78342"
+       x2="311.27377"
+       y1="377.9527"
+       x1="302.73621"
+       gradientTransform="matrix(1.9519,0,0,1.84182,-440.5695,-620.2357)"
+       gradientUnits="userSpaceOnUse"
+       id="linearGradient6073"
+       xlink:href="#linearGradient4554"
+       inkscape:collect="always" />
+    <linearGradient
+       y2="323.17273"
+       x2="681.0014"
+       y1="300.41397"
+       x1="661.46326"
+       gradientTransform="matrix(0.80139,0,0,1.247832,-433.2238,-292.6035)"
+       gradientUnits="userSpaceOnUse"
+       id="linearGradient6077"
+       xlink:href="#linearGradient4738"
+       inkscape:collect="always" />
+    <linearGradient
+       y2="390.78342"
+       x2="311.27377"
+       y1="377.9527"
+       x1="302.73621"
+       gradientTransform="matrix(1.9519,0,0,1.84182,-515.2268,-620.2357)"
+       gradientUnits="userSpaceOnUse"
+       id="linearGradient6080"
+       xlink:href="#linearGradient4554"
+       inkscape:collect="always" />
+  </defs>
+  <sodipodi:namedview
+     inkscape:window-y="0"
+     inkscape:window-x="0"
+     inkscape:window-height="968"
+     inkscape:window-width="1280"
+     inkscape:document-units="px"
+     inkscape:current-layer="layer1"
+     inkscape:cy="57.545109"
+     inkscape:cx="15.183899"
+     inkscape:zoom="3.0989011"
+     inkscape:pageshadow="2"
+     inkscape:pageopacity="0.0"
+     borderopacity="1.0"
+     bordercolor="#666666"
+     pagecolor="#ffffff"
+     id="base"
+     borderlayer="true"
+     showborder="true"
+     showgrid="false"
+     inkscape:window-maximized="0" />
+  <metadata
+     id="metadata4">
+    <rdf:RDF>
+      <cc:Work
+         rdf:about="">
+        <dc:format>image/svg+xml</dc:format>
+        <dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+      </cc:Work>
+    </rdf:RDF>
+  </metadata>
+  <g
+     inkscape:groupmode="layer"
+     inkscape:label="Layer 1"
+     id="layer1"
+     transform="translate(-213.3568,12.4428)">
+    <path
+       transform="matrix(1.896061,0,0,1.896061,-374.8545,-700.975)"
+       d="m 339.53775,378.05789 c 0,7.71359 -6.25309,13.96668 -13.96667,13.96668 -7.71359,0 -13.96668,-6.25309 -13.96668,-13.96668 0,-7.71358 6.25309,-13.96668 13.96668,-13.96668 7.71358,0 13.96667,6.2531 13.96667,13.96668 z"
+       sodipodi:ry="13.966679"
+       sodipodi:rx="13.966679"
+       sodipodi:cy="378.05789"
+       sodipodi:cx="325.57108"
+       id="path5170"
+       style="color:black;fill:#aeab00;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:3.62500000000000000;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible"
+       sodipodi:type="arc" />
+    <path
+       transform="matrix(1.731185,0,0,1.731185,-321.1761,-638.6428)"
+       d="m 339.53775,378.05789 c 0,7.71359 -6.25309,13.96668 -13.96667,13.96668 -7.71359,0 -13.96668,-6.25309 -13.96668,-13.96668 0,-7.71358 6.25309,-13.96668 13.96668,-13.96668 7.71358,0 13.96667,6.2531 13.96667,13.96668 z"
+       sodipodi:ry="13.966679"
+       sodipodi:rx="13.966679"
+       sodipodi:cy="378.05789"
+       sodipodi:cx="325.57108"
+       id="path5172"
+       style="color:black;fill:url(#linearGradient5602);fill-opacity:1;fill-rule:nonzero;stroke:white;stroke-width:0.72204876;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible"
+       sodipodi:type="arc" />
+    <path
+       id="path5174"
+       d="M 242.43189,-8.3201378 C 229.08514,-8.3201378 218.25709,2.507892 218.25711,15.854642 C 218.25711,22.267212 220.87405,27.997552 224.95258,32.326672 C 227.07143,14.826182 241.8421,1.2194221 259.9112,1.2194221 C 260.39841,1.2194221 260.85081,1.318382 261.33325,1.337922 C 256.91182,-4.4127679 250.24118,-8.3201378 242.43189,-8.3201378 z "
+       style="color:black;fill:url(#linearGradient6049);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.61607176;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible" />
+    <path
+       style="color:#000000;fill:url(#linearGradient6046);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.75000167;marker:none;visibility:visible;display:inline;overflow:visible"
+       d="M 257.93856,20.01446 253.80724,24.1458 242.10689,12.445441 230.51874,24.03359 226.3568,19.87165 242.07629,4.1521608 257.93856,20.01446 z"
+       id="path5176"
+       inkscape:connector-curvature="0" />
+  </g>
+</svg>
diff --git a/data/themes/default/arrows.svg b/data/themes/default/arrows.svg
new file mode 100644 (file)
index 0000000..92e1f9d
--- /dev/null
@@ -0,0 +1,376 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://creativecommons.org/ns#"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:xlink="http://www.w3.org/1999/xlink"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   width="512"
+   height="64"
+   id="svg2948"
+   version="1.1"
+   inkscape:version="0.48.0 r9654"
+   sodipodi:docname="arrows.svg">
+  <defs
+     id="defs2950">
+    <radialGradient
+       r="26.692099"
+       fy="344.23474"
+       fx="641.50745"
+       cy="344.23474"
+       cx="641.50745"
+       gradientTransform="matrix(1,0,0,1.0006216,-160.27031,676.55878)"
+       gradientUnits="userSpaceOnUse"
+       id="radialGradient4453"
+       xlink:href="#linearGradient4315-9"
+       inkscape:collect="always" />
+    <linearGradient
+       id="linearGradient4315-9">
+      <stop
+         style="stop-color:#b469ff;stop-opacity:1;"
+         offset="0"
+         id="stop4317-0" />
+      <stop
+         style="stop-color:#7000de;stop-opacity:1;"
+         offset="1"
+         id="stop4319-6" />
+    </linearGradient>
+    <linearGradient
+       gradientTransform="translate(-160.27031,676.77274)"
+       y2="344.23474"
+       x2="668.19952"
+       y1="344.23474"
+       x1="614.81531"
+       gradientUnits="userSpaceOnUse"
+       id="linearGradient4455"
+       xlink:href="#linearGradient5091-7"
+       inkscape:collect="always" />
+    <linearGradient
+       id="linearGradient5091-7">
+      <stop
+         style="stop-color:#000000;stop-opacity:1;"
+         offset="0"
+         id="stop5093-9" />
+      <stop
+         style="stop-color:#000000;stop-opacity:0.3764706;"
+         offset="1"
+         id="stop5095-0" />
+    </linearGradient>
+    <radialGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient5072-7"
+       id="radialGradient5094-1"
+       cx="384.26987"
+       cy="471.5892"
+       fx="384.26987"
+       fy="471.5892"
+       r="31.437084"
+       gradientTransform="matrix(0.96131646,0,0,0.96131644,-145.40496,567.0157)"
+       gradientUnits="userSpaceOnUse" />
+    <linearGradient
+       id="linearGradient5088-5">
+      <stop
+         style="stop-color:#6060ff;stop-opacity:1;"
+         offset="0"
+         id="stop5090-9" />
+      <stop
+         style="stop-color:#0000ff;stop-opacity:1;"
+         offset="1"
+         id="stop5092-4" />
+    </linearGradient>
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient5091-9"
+       id="linearGradient5097-9"
+       x1="415.46988"
+       y1="471.5892"
+       x2="353.58255"
+       y2="471.08411"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(0.96131646,0,0,0.96131644,-145.40496,567.01571)" />
+    <linearGradient
+       id="linearGradient5091-9">
+      <stop
+         style="stop-color:#000000;stop-opacity:1;"
+         offset="0"
+         id="stop5093-1" />
+      <stop
+         style="stop-color:#000000;stop-opacity:0.3764706;"
+         offset="1"
+         id="stop5095-7" />
+    </linearGradient>
+    <radialGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient5080-7"
+       id="radialGradient5086-7"
+       cx="320.26987"
+       cy="471.5892"
+       fx="320.26987"
+       fy="471.5892"
+       r="31.437082"
+       gradientTransform="matrix(0.96131325,-3.0089311e-6,3.0089412e-6,0.96131636,-147.88099,567.01669)"
+       gradientUnits="userSpaceOnUse" />
+    <linearGradient
+       id="linearGradient5080-7">
+      <stop
+         style="stop-color:#ffff80;stop-opacity:1;"
+         offset="0"
+         id="stop5082-1" />
+      <stop
+         style="stop-color:#ffff00;stop-opacity:1;"
+         offset="1"
+         id="stop5084-1" />
+    </linearGradient>
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient5091-9"
+       id="linearGradient5089-5"
+       x1="320.26987"
+       y1="440.1521"
+       x2="319.88715"
+       y2="502.14633"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(0.96131651,0,0,0.96131646,-147.88071,567.01571)" />
+    <radialGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient5088-5"
+       id="radialGradient5078-6"
+       cx="256.26987"
+       cy="471.5892"
+       fx="256.26987"
+       fy="471.5892"
+       r="31.437082"
+       gradientTransform="matrix(0.98425198,-1.3778034e-6,1.3456973e-6,0.96131646,-156.23479,567.0161)"
+       gradientUnits="userSpaceOnUse" />
+    <linearGradient
+       id="linearGradient5072-7">
+      <stop
+         style="stop-color:#ff6b20;stop-opacity:1;"
+         offset="0"
+         id="stop5074-3" />
+      <stop
+         style="stop-color:#ff0000;stop-opacity:1;"
+         offset="1"
+         id="stop5076-6" />
+    </linearGradient>
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient5091-9"
+       id="linearGradient5081-5"
+       x1="256.26987"
+       y1="503.77628"
+       x2="256.31409"
+       y2="440.69635"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(0.96131651,0,0,0.96131646,-150.35646,567.01571)" />
+    <radialGradient
+       r="31"
+       fy="471.5892"
+       fx="192.26987"
+       cy="471.5892"
+       cx="192.26987"
+       gradientTransform="matrix(0.96130346,0,0,0.96130343,-152.82969,567.02183)"
+       gradientUnits="userSpaceOnUse"
+       id="radialGradient3690"
+       xlink:href="#linearGradient5064-8"
+       inkscape:collect="always" />
+    <linearGradient
+       id="linearGradient5064-8">
+      <stop
+         style="stop-color:#20ff20;stop-opacity:1;"
+         offset="0"
+         id="stop5066-1" />
+      <stop
+         style="stop-color:#00a000;stop-opacity:1;"
+         offset="1"
+         id="stop5068-2" />
+    </linearGradient>
+    <linearGradient
+       y2="471.5892"
+       x2="223.70737"
+       y1="471.5892"
+       x1="160.83237"
+       gradientTransform="matrix(0.96130346,0,0,0.96130343,-152.82969,567.02185)"
+       gradientUnits="userSpaceOnUse"
+       id="linearGradient3692"
+       xlink:href="#linearGradient5091-9"
+       inkscape:collect="always" />
+    <radialGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient4307"
+       id="radialGradient4313"
+       cx="575.62433"
+       cy="344.82675"
+       fx="575.62433"
+       fy="344.82675"
+       r="26.708689"
+       gradientTransform="matrix(1,0,0,0.9993789,-160.26987,676.98715)"
+       gradientUnits="userSpaceOnUse" />
+    <linearGradient
+       id="linearGradient4307">
+      <stop
+         style="stop-color:#35ffff;stop-opacity:1;"
+         offset="0"
+         id="stop4309" />
+      <stop
+         style="stop-color:#00dbdb;stop-opacity:1;"
+         offset="1"
+         id="stop4311" />
+    </linearGradient>
+    <linearGradient
+       gradientTransform="translate(-160.26987,676.77298)"
+       inkscape:collect="always"
+       xlink:href="#linearGradient5091-9"
+       id="linearGradient4279"
+       x1="548.91565"
+       y1="344.82675"
+       x2="602.33301"
+       y2="344.82675"
+       gradientUnits="userSpaceOnUse" />
+    <radialGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient4299"
+       id="radialGradient4305"
+       cx="512.91541"
+       cy="342.35165"
+       fx="512.91541"
+       fy="342.35165"
+       r="26.708689"
+       gradientTransform="matrix(1,0,0,0.9993789,-160.26987,676.98561)"
+       gradientUnits="userSpaceOnUse" />
+    <linearGradient
+       id="linearGradient4299">
+      <stop
+         style="stop-color:#ff7cff;stop-opacity:1;"
+         offset="0"
+         id="stop4301" />
+      <stop
+         style="stop-color:#e400e4;stop-opacity:1;"
+         offset="1"
+         id="stop4303" />
+    </linearGradient>
+    <linearGradient
+       gradientTransform="translate(-160.26987,676.77298)"
+       inkscape:collect="always"
+       xlink:href="#linearGradient5091-9"
+       id="linearGradient4271"
+       x1="486.20673"
+       y1="342.35165"
+       x2="539.62408"
+       y2="342.35165"
+       gradientUnits="userSpaceOnUse" />
+    <linearGradient
+       id="linearGradient4289">
+      <stop
+         style="stop-color:#ff8f4c;stop-opacity:1;"
+         offset="0"
+         id="stop4291" />
+      <stop
+         style="stop-color:#f25b00;stop-opacity:1;"
+         offset="1"
+         id="stop4293" />
+    </linearGradient>
+    <radialGradient
+       r="26.692099"
+       fy="342.94363"
+       fx="447.03232"
+       cy="342.94363"
+       cx="447.03232"
+       gradientTransform="matrix(1,0,0,1.0006216,-160.26987,676.55982)"
+       gradientUnits="userSpaceOnUse"
+       id="radialGradient3060"
+       xlink:href="#linearGradient4289"
+       inkscape:collect="always" />
+    <linearGradient
+       y2="342.94363"
+       x2="473.22443"
+       y1="342.94363"
+       x1="420.84024"
+       gradientTransform="translate(-160.26987,676.77298)"
+       gradientUnits="userSpaceOnUse"
+       id="linearGradient3062"
+       xlink:href="#linearGradient5091-9"
+       inkscape:collect="always" />
+  </defs>
+  <sodipodi:namedview
+     id="base"
+     pagecolor="#ffffff"
+     bordercolor="#666666"
+     borderopacity="1.0"
+     inkscape:pageopacity="0.0"
+     inkscape:pageshadow="2"
+     inkscape:zoom="0.98994949"
+     inkscape:cx="171.37241"
+     inkscape:cy="112.0218"
+     inkscape:document-units="px"
+     inkscape:current-layer="layer1"
+     showgrid="false"
+     inkscape:window-width="1283"
+     inkscape:window-height="912"
+     inkscape:window-x="16"
+     inkscape:window-y="62"
+     inkscape:window-maximized="0" />
+  <metadata
+     id="metadata2953">
+    <rdf:RDF>
+      <cc:Work
+         rdf:about="">
+        <dc:format>image/svg+xml</dc:format>
+        <dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+        <dc:title />
+      </cc:Work>
+    </rdf:RDF>
+  </metadata>
+  <g
+     inkscape:label="Capa 1"
+     inkscape:groupmode="layer"
+     id="layer1"
+     transform="translate(0,-988.36218)">
+    <path
+       style="opacity:0.9;fill:url(#radialGradient3060);fill-opacity:1;fill-rule:nonzero;stroke:url(#linearGradient3062);stroke-width:2.5;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+       d="m 265.30767,998.24218 c -1.6047,2.26182 -1.44695,4.90442 -1.65632,6.69942 l -2.32405,32.2726 c -0.16032,2.2252 2.47482,3.8354 5.89688,3.6141 3.42206,-0.2212 6.28508,-2.1853 6.44539,-4.4104 l 1.38081,-19.1642 26.40961,26.4096 c 2.22732,2.2273 6.08773,1.9635 8.64187,-0.5907 2.55414,-2.5541 2.81801,-6.4145 0.59069,-8.6418 l -26.3875,-26.3875 20.3005,-1.4113 c 2.22478,-0.1543 4.20544,-3.048 4.43584,-6.4707 0.23041,-3.42272 -1.38934,-6.05122 -3.61411,-5.89692 l -33.26368,2.2534 c -3.08006,0.1207 -4.53845,-0.053 -6.85593,1.7244 z"
+       id="rect2823-7-2-7-7"
+       sodipodi:nodetypes="cccscccscccsccc" />
+    <path
+       style="opacity:0.9;fill:url(#radialGradient4305);fill-opacity:1;fill-rule:nonzero;stroke:url(#linearGradient4271);stroke-width:2.5;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+       d="m 374.11998,997.66988 c -2.26182,-1.6047 -4.90444,-1.447 -6.69936,-1.6563 l -32.27266,-2.3241 c -2.22517,-0.1603 -3.83538,2.4748 -3.61412,5.8969 0.22127,3.42202 2.18532,6.28502 4.41048,6.44532 l 19.16416,1.3809 -26.40962,26.4096 c -2.22731,2.2273 -1.96345,6.0877 0.59069,8.6418 2.55414,2.5542 6.41456,2.818 8.64187,0.5907 l 26.3875,-26.3875 1.41122,20.3005 c 0.15436,2.2248 3.04804,4.2055 6.47075,4.4359 3.4227,0.2304 6.05126,-1.3894 5.89688,-3.6141 l -2.25338,-33.2637 c -0.12073,-3.0801 0.0535,-4.53852 -1.72441,-6.85592 z"
+       id="rect2823-7-2-7-6-1"
+       sodipodi:nodetypes="cccscccscccsccc" />
+    <path
+       style="opacity:0.9;fill:url(#radialGradient4313);fill-opacity:1;fill-rule:nonzero;stroke:url(#linearGradient4279);stroke-width:2.5;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+       d="m 393.88002,1043.0545 c 2.26182,1.6047 4.90444,1.447 6.69936,1.6563 l 32.27266,2.3241 c 2.22517,0.1603 3.83538,-2.4748 3.61412,-5.8969 -0.22127,-3.4221 -2.18532,-6.2851 -4.41048,-6.4454 l -19.16416,-1.3808 26.40962,-26.4096 c 2.22731,-2.2273 1.96345,-6.0877 -0.59069,-8.64192 -2.55414,-2.5541 -6.41456,-2.818 -8.64187,-0.5907 l -26.3875,26.38752 -1.41122,-20.3005 c -0.15437,-2.2247 -3.04804,-4.20542 -6.47075,-4.43582 -3.4227,-0.2304 -6.05126,1.38942 -5.89688,3.61412 l 2.25338,33.2637 c 0.12073,3.08 -0.0535,4.5384 1.72441,6.8559 z"
+       id="rect2823-7-2-7-0-1"
+       sodipodi:nodetypes="cccscccscccsccc" />
+    <path
+       style="opacity:0.9;fill:url(#radialGradient3690);fill-opacity:1;fill-rule:nonzero;stroke:url(#linearGradient3692);stroke-width:2.5;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+       d="m 2.5,1020.739 c 0.43258,2.5453 2.27607,4.1811 3.31984,5.5005 l 19.71521,22.7751 c 1.35929,1.5703 4.15401,0.8956 6.2611,-1.5028 2.10709,-2.3984 2.69887,-5.576 1.33958,-7.1464 l -11.7068,-13.5248 34.77097,0 c 2.9325,0 5.3001,-2.715 5.3001,-6.0778 0,-3.3628 -2.3676,-6.0778 -5.3001,-6.0778 l -34.74185,0 12.43484,-14.2928 c 1.36295,-1.56622 0.76191,-4.77502 -1.33958,-7.17992 -2.1015,-2.4048 -4.89816,-3.0689 -6.26111,-1.5027 L 5.87809,1015.0905 C 3.92996,1017.1976 2.8552,1018.043 2.5,1020.739 z"
+       id="rect2823-7-9"
+       sodipodi:nodetypes="cccscccscccsccc" />
+    <path
+       style="fill:url(#radialGradient5078-6);fill-opacity:1.0;fill-rule:nonzero;stroke:url(#linearGradient5081-5);stroke-width:2.50000000000000000;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+       d="m 95.62323,1049.8622 c -2.54534,-0.4326 -4.18112,-2.2761 -5.50056,-3.3199 l -22.77506,-19.7152 c -1.57037,-1.3593 -0.89566,-4.154 1.50275,-6.2611 2.39841,-2.107 5.57607,-2.6988 7.14643,-1.3395 l 13.52478,11.7068 0,-34.77102 c 0,-2.9325 2.71501,-5.3001 6.0778,-5.3001 3.36279,0 6.07781,2.3676 6.07781,5.3001 l 0,34.74182 14.29285,-12.4348 c 1.5662,-1.363 4.77498,-0.7619 7.17983,1.3396 2.40484,2.1015 3.06894,4.8981 1.50275,6.2611 l -23.38094,20.4141 c -2.10708,1.9481 -2.95246,3.0229 -5.64844,3.3781 z"
+       id="rect2823-7-2-77"
+       sodipodi:nodetypes="cccscccscccsccc" />
+    <path
+       style="fill:url(#radialGradient5086-7);fill-opacity:1;fill-rule:nonzero;stroke:url(#linearGradient5089-5);stroke-width:2.5;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+       d="m 159.62323,990.86218 c -2.54534,0.4326 -4.18112,2.2761 -5.50056,3.3198 l -22.77506,19.71522 c -1.57037,1.3593 -0.89566,4.1541 1.50275,6.2611 2.39841,2.1071 5.57607,2.6989 7.14643,1.3396 l 13.52478,-11.7068 0,34.771 c 0,2.9325 2.71501,5.3001 6.0778,5.3001 3.36279,0 6.07781,-2.3676 6.07781,-5.3001 l 0,-34.7419 14.29285,12.4349 c 1.5662,1.3629 4.77498,0.7619 7.17983,-1.3396 2.40484,-2.1015 3.06894,-4.8982 1.50275,-6.2611 l -23.38094,-20.41412 c -2.10708,-1.9481 -2.95246,-3.0229 -5.64844,-3.3781 z"
+       id="rect2823-7-2-9-6"
+       sodipodi:nodetypes="cccscccscccsccc" />
+    <path
+       style="fill:url(#radialGradient5094-1);fill-opacity:1.0;fill-rule:nonzero;stroke:url(#linearGradient5097-9);stroke-width:2.50000000000000000;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+       d="m 253.5,1019.9854 c -0.43258,-2.5453 -2.27607,-4.1811 -3.31985,-5.5006 l -19.7152,-22.77502 c -1.3593,-1.5704 -4.15402,-0.8957 -6.2611,1.5028 -2.10709,2.3984 -2.69889,5.576 -1.33958,7.14642 l 11.70679,13.5247 -15.1824,0 -19.58857,0 c -2.93248,0 -5.30009,2.7151 -5.30009,6.0778 0,3.3628 2.36761,6.0778 5.30009,6.0778 l 34.74185,0 -12.43484,14.2929 c -1.36295,1.5662 -0.76191,4.775 1.33959,7.1798 2.10149,2.4049 4.89816,3.069 6.2611,1.5028 l 20.41412,-23.381 c 1.94813,-2.107 3.02288,-2.9524 3.37809,-5.6484 z"
+       id="rect2823-7-2-92-7"
+       sodipodi:nodetypes="cccsccccscccsccc" />
+    <path
+       style="opacity:0.9;fill:url(#radialGradient4453);fill-opacity:1;fill-rule:nonzero;stroke:url(#linearGradient4455);stroke-width:2.5;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+       d="m 502.69188,1042.4819 c 1.6047,-2.2618 1.44695,-4.9044 1.65632,-6.6993 l 2.32405,-32.2727 c 0.16032,-2.2252 -2.47482,-3.83542 -5.89688,-3.61412 -3.42206,0.22132 -6.28508,2.18532 -6.44539,4.41052 l -1.38081,19.1641 -26.40961,-26.40962 c -2.22732,-2.2273 -6.08773,-1.9634 -8.64187,0.5907 -2.55414,2.55422 -2.81801,6.41452 -0.59069,8.64192 l 26.3875,26.3875 -20.3005,1.4112 c -2.22478,0.1543 -4.20544,3.048 -4.43584,6.4707 -0.23041,3.4227 1.38934,6.0513 3.61411,5.8969 l 33.26368,-2.2534 c 3.08006,-0.1207 4.53845,0.053 6.85593,-1.7244 z"
+       id="rect2823-7-2-7-3"
+       sodipodi:nodetypes="cccscccscccsccc" />
+  </g>
+</svg>
diff --git a/data/themes/default/arrows_cursor.svg b/data/themes/default/arrows_cursor.svg
new file mode 100644 (file)
index 0000000..1a27cf5
--- /dev/null
@@ -0,0 +1,477 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://creativecommons.org/ns#"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:xlink="http://www.w3.org/1999/xlink"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   width="512"
+   height="64"
+   id="svg2948"
+   version="1.1"
+   inkscape:version="0.48.0 r9654"
+   sodipodi:docname="arrows_cursor.svg">
+  <defs
+     id="defs2950">
+    <inkscape:perspective
+       sodipodi:type="inkscape:persp3d"
+       inkscape:vp_x="0 : 526.18109 : 1"
+       inkscape:vp_y="0 : 1000 : 0"
+       inkscape:vp_z="744.09448 : 526.18109 : 1"
+       inkscape:persp3d-origin="372.04724 : 350.78739 : 1"
+       id="perspective2956" />
+    <inkscape:perspective
+       id="perspective2966"
+       inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
+       inkscape:vp_z="1 : 0.5 : 1"
+       inkscape:vp_y="0 : 1000 : 0"
+       inkscape:vp_x="0 : 0.5 : 1"
+       sodipodi:type="inkscape:persp3d" />
+    <radialGradient
+       r="26.692099"
+       fy="344.23474"
+       fx="641.50745"
+       cy="344.23474"
+       cx="641.50745"
+       gradientTransform="matrix(1,0,0,1.0006216,-160.27031,676.55878)"
+       gradientUnits="userSpaceOnUse"
+       id="radialGradient4453"
+       xlink:href="#linearGradient4315-9"
+       inkscape:collect="always" />
+    <linearGradient
+       id="linearGradient4315-9">
+      <stop
+         style="stop-color:#b469ff;stop-opacity:1;"
+         offset="0"
+         id="stop4317-0" />
+      <stop
+         style="stop-color:#7000de;stop-opacity:1;"
+         offset="1"
+         id="stop4319-6" />
+    </linearGradient>
+    <linearGradient
+       gradientTransform="translate(-160.27031,676.77274)"
+       y2="344.23474"
+       x2="668.19952"
+       y1="344.23474"
+       x1="614.81531"
+       gradientUnits="userSpaceOnUse"
+       id="linearGradient4455"
+       xlink:href="#linearGradient5091-7"
+       inkscape:collect="always" />
+    <linearGradient
+       id="linearGradient5091-7">
+      <stop
+         style="stop-color:#000000;stop-opacity:1;"
+         offset="0"
+         id="stop5093-9" />
+      <stop
+         style="stop-color:#000000;stop-opacity:0.3764706;"
+         offset="1"
+         id="stop5095-0" />
+    </linearGradient>
+    <radialGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient5072-7"
+       id="radialGradient5094-1"
+       cx="384.26987"
+       cy="471.5892"
+       fx="384.26987"
+       fy="471.5892"
+       r="31.437084"
+       gradientTransform="matrix(0.96131646,0,0,0.96131644,-145.40496,567.0157)"
+       gradientUnits="userSpaceOnUse" />
+    <linearGradient
+       id="linearGradient5088-5">
+      <stop
+         style="stop-color:#6060ff;stop-opacity:1;"
+         offset="0"
+         id="stop5090-9" />
+      <stop
+         style="stop-color:#0000ff;stop-opacity:1;"
+         offset="1"
+         id="stop5092-4" />
+    </linearGradient>
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient5091-9"
+       id="linearGradient5097-9"
+       x1="415.46988"
+       y1="471.5892"
+       x2="353.58255"
+       y2="471.08411"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(0.96131646,0,0,0.96131644,-145.40496,567.01571)" />
+    <linearGradient
+       id="linearGradient5091-9">
+      <stop
+         style="stop-color:#000000;stop-opacity:1;"
+         offset="0"
+         id="stop5093-1" />
+      <stop
+         style="stop-color:#000000;stop-opacity:0.3764706;"
+         offset="1"
+         id="stop5095-7" />
+    </linearGradient>
+    <radialGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient5080-7"
+       id="radialGradient5086-7"
+       cx="320.26987"
+       cy="471.5892"
+       fx="320.26987"
+       fy="471.5892"
+       r="31.437082"
+       gradientTransform="matrix(0.96131325,-3.0089311e-6,3.0089412e-6,0.96131636,-147.88099,567.01669)"
+       gradientUnits="userSpaceOnUse" />
+    <linearGradient
+       id="linearGradient5080-7">
+      <stop
+         style="stop-color:#ffff80;stop-opacity:1;"
+         offset="0"
+         id="stop5082-1" />
+      <stop
+         style="stop-color:#ffff00;stop-opacity:1;"
+         offset="1"
+         id="stop5084-1" />
+    </linearGradient>
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient5091-9"
+       id="linearGradient5089-5"
+       x1="320.26987"
+       y1="440.1521"
+       x2="319.88715"
+       y2="502.14633"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(0.96131651,0,0,0.96131646,-147.88071,567.01571)" />
+    <linearGradient
+       id="linearGradient2991">
+      <stop
+         style="stop-color:#000000;stop-opacity:1;"
+         offset="0"
+         id="stop2993" />
+      <stop
+         style="stop-color:#000000;stop-opacity:0.3764706;"
+         offset="1"
+         id="stop2995" />
+    </linearGradient>
+    <radialGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient5088-5"
+       id="radialGradient5078-6"
+       cx="256.26987"
+       cy="471.5892"
+       fx="256.26987"
+       fy="471.5892"
+       r="31.437082"
+       gradientTransform="matrix(0.98425198,-1.3778034e-6,1.3456973e-6,0.96131646,-156.23479,567.0161)"
+       gradientUnits="userSpaceOnUse" />
+    <linearGradient
+       id="linearGradient5072-7">
+      <stop
+         style="stop-color:#ff6020;stop-opacity:1;"
+         offset="0"
+         id="stop5074-3" />
+      <stop
+         style="stop-color:#ff0000;stop-opacity:1;"
+         offset="1"
+         id="stop5076-6" />
+    </linearGradient>
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient5091-9"
+       id="linearGradient5081-5"
+       x1="256.26987"
+       y1="503.77628"
+       x2="256.31409"
+       y2="440.69635"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(0.96131651,0,0,0.96131646,-150.35646,567.01571)" />
+    <linearGradient
+       id="linearGradient3002">
+      <stop
+         style="stop-color:#000000;stop-opacity:1;"
+         offset="0"
+         id="stop3004" />
+      <stop
+         style="stop-color:#000000;stop-opacity:0.3764706;"
+         offset="1"
+         id="stop3006" />
+    </linearGradient>
+    <radialGradient
+       r="31"
+       fy="471.5892"
+       fx="192.26987"
+       cy="471.5892"
+       cx="192.26987"
+       gradientTransform="matrix(0.96130346,0,0,0.96130343,-152.82969,567.02183)"
+       gradientUnits="userSpaceOnUse"
+       id="radialGradient3690"
+       xlink:href="#linearGradient5064-8"
+       inkscape:collect="always" />
+    <linearGradient
+       id="linearGradient5064-8">
+      <stop
+         style="stop-color:#20ff20;stop-opacity:1;"
+         offset="0"
+         id="stop5066-1" />
+      <stop
+         style="stop-color:#00a000;stop-opacity:1;"
+         offset="1"
+         id="stop5068-2" />
+    </linearGradient>
+    <linearGradient
+       y2="471.5892"
+       x2="223.70737"
+       y1="471.5892"
+       x1="160.83237"
+       gradientTransform="matrix(0.96130346,0,0,0.96130343,-152.82969,567.02185)"
+       gradientUnits="userSpaceOnUse"
+       id="linearGradient3692"
+       xlink:href="#linearGradient5091-9"
+       inkscape:collect="always" />
+    <linearGradient
+       id="linearGradient3013">
+      <stop
+         style="stop-color:#000000;stop-opacity:1;"
+         offset="0"
+         id="stop3015" />
+      <stop
+         style="stop-color:#000000;stop-opacity:0.3764706;"
+         offset="1"
+         id="stop3017" />
+    </linearGradient>
+    <radialGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient4307"
+       id="radialGradient4313"
+       cx="575.62433"
+       cy="344.82675"
+       fx="575.62433"
+       fy="344.82675"
+       r="26.708689"
+       gradientTransform="matrix(1,0,0,0.9993789,-160.26987,676.98715)"
+       gradientUnits="userSpaceOnUse" />
+    <linearGradient
+       id="linearGradient4307">
+      <stop
+         style="stop-color:#35ffff;stop-opacity:1;"
+         offset="0"
+         id="stop4309" />
+      <stop
+         style="stop-color:#00dbdb;stop-opacity:1;"
+         offset="1"
+         id="stop4311" />
+    </linearGradient>
+    <linearGradient
+       gradientTransform="translate(-160.26987,676.77298)"
+       inkscape:collect="always"
+       xlink:href="#linearGradient5091-9"
+       id="linearGradient4279"
+       x1="548.91565"
+       y1="344.82675"
+       x2="602.33301"
+       y2="344.82675"
+       gradientUnits="userSpaceOnUse" />
+    <linearGradient
+       id="linearGradient3024">
+      <stop
+         style="stop-color:#000000;stop-opacity:1;"
+         offset="0"
+         id="stop3026" />
+      <stop
+         style="stop-color:#000000;stop-opacity:0.3764706;"
+         offset="1"
+         id="stop3028" />
+    </linearGradient>
+    <radialGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient4299"
+       id="radialGradient4305"
+       cx="512.91541"
+       cy="342.35165"
+       fx="512.91541"
+       fy="342.35165"
+       r="26.708689"
+       gradientTransform="matrix(1,0,0,0.9993789,-160.26987,676.98561)"
+       gradientUnits="userSpaceOnUse" />
+    <linearGradient
+       id="linearGradient4299">
+      <stop
+         style="stop-color:#ff7cff;stop-opacity:1;"
+         offset="0"
+         id="stop4301" />
+      <stop
+         style="stop-color:#e400e4;stop-opacity:1;"
+         offset="1"
+         id="stop4303" />
+    </linearGradient>
+    <linearGradient
+       gradientTransform="translate(-160.26987,676.77298)"
+       inkscape:collect="always"
+       xlink:href="#linearGradient5091-9"
+       id="linearGradient4271"
+       x1="486.20673"
+       y1="342.35165"
+       x2="539.62408"
+       y2="342.35165"
+       gradientUnits="userSpaceOnUse" />
+    <linearGradient
+       id="linearGradient3035">
+      <stop
+         style="stop-color:#000000;stop-opacity:1;"
+         offset="0"
+         id="stop3037" />
+      <stop
+         style="stop-color:#000000;stop-opacity:0.3764706;"
+         offset="1"
+         id="stop3039" />
+    </linearGradient>
+    <radialGradient
+       r="26.692099"
+       fy="342.94363"
+       fx="447.03232"
+       cy="342.94363"
+       cx="447.03232"
+       gradientTransform="matrix(1,0,0,1.0006216,-5e-6,127.78684)"
+       gradientUnits="userSpaceOnUse"
+       id="radialGradient4428"
+       xlink:href="#linearGradient4289"
+       inkscape:collect="always" />
+    <linearGradient
+       id="linearGradient4289">
+      <stop
+         style="stop-color:#ff8f4c;stop-opacity:1;"
+         offset="0"
+         id="stop4291" />
+      <stop
+         style="stop-color:#f25b00;stop-opacity:1;"
+         offset="1"
+         id="stop4293" />
+    </linearGradient>
+    <linearGradient
+       gradientTransform="translate(-5e-6,128)"
+       y2="342.94363"
+       x2="473.22443"
+       y1="342.94363"
+       x1="420.84024"
+       gradientUnits="userSpaceOnUse"
+       id="linearGradient4430"
+       xlink:href="#linearGradient5091-9"
+       inkscape:collect="always" />
+    <linearGradient
+       id="linearGradient3046">
+      <stop
+         style="stop-color:#000000;stop-opacity:1;"
+         offset="0"
+         id="stop3048" />
+      <stop
+         style="stop-color:#000000;stop-opacity:0.3764706;"
+         offset="1"
+         id="stop3050" />
+    </linearGradient>
+    <radialGradient
+       r="26.692099"
+       fy="342.94363"
+       fx="447.03232"
+       cy="342.94363"
+       cx="447.03232"
+       gradientTransform="matrix(1,0,0,1.0006216,-160.26987,676.55982)"
+       gradientUnits="userSpaceOnUse"
+       id="radialGradient3060"
+       xlink:href="#linearGradient4289"
+       inkscape:collect="always" />
+    <linearGradient
+       y2="342.94363"
+       x2="473.22443"
+       y1="342.94363"
+       x1="420.84024"
+       gradientTransform="translate(-160.26987,676.77298)"
+       gradientUnits="userSpaceOnUse"
+       id="linearGradient3062"
+       xlink:href="#linearGradient5091-9"
+       inkscape:collect="always" />
+  </defs>
+  <sodipodi:namedview
+     id="base"
+     pagecolor="#ffffff"
+     bordercolor="#666666"
+     borderopacity="1.0"
+     inkscape:pageopacity="0.0"
+     inkscape:pageshadow="2"
+     inkscape:zoom="0.98994949"
+     inkscape:cx="259.23355"
+     inkscape:cy="152.4279"
+     inkscape:document-units="px"
+     inkscape:current-layer="layer1"
+     showgrid="false"
+     inkscape:window-width="1080"
+     inkscape:window-height="765"
+     inkscape:window-x="58"
+     inkscape:window-y="75"
+     inkscape:window-maximized="0" />
+  <metadata
+     id="metadata2953">
+    <rdf:RDF>
+      <cc:Work
+         rdf:about="">
+        <dc:format>image/svg+xml</dc:format>
+        <dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+        <dc:title />
+      </cc:Work>
+    </rdf:RDF>
+  </metadata>
+  <g
+     inkscape:label="Capa 1"
+     inkscape:groupmode="layer"
+     id="layer1"
+     transform="translate(0,-988.36218)">
+    <path
+       style="opacity:0.9;fill:url(#radialGradient3060);fill-opacity:1;fill-rule:nonzero;stroke:url(#linearGradient3062);stroke-width:2.5;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+       d="m 265.30767,998.24218 c -1.6047,2.26182 -1.44695,4.90442 -1.65632,6.69942 l -2.32405,32.2726 c -0.16032,2.2252 2.47482,3.8354 5.89688,3.6141 3.42206,-0.2212 6.28508,-2.1853 6.44539,-4.4104 l 1.38081,-19.1642 26.40961,26.4096 c 2.22732,2.2273 6.08773,1.9635 8.64187,-0.5907 2.55414,-2.5541 2.81801,-6.4145 0.59069,-8.6418 l -26.3875,-26.3875 20.3005,-1.4113 c 2.22478,-0.1543 4.20544,-3.048 4.43584,-6.4707 0.23041,-3.42272 -1.38934,-6.05122 -3.61411,-5.89692 l -33.26368,2.2534 c -3.08006,0.1207 -4.53845,-0.053 -6.85593,1.7244 z"
+       id="rect2823-7-2-7-7"
+       sodipodi:nodetypes="cccscccscccsccc" />
+    <path
+       style="opacity:0.9;fill:url(#radialGradient4305);fill-opacity:1;fill-rule:nonzero;stroke:url(#linearGradient4271);stroke-width:2.5;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+       d="m 374.11998,997.66988 c -2.26182,-1.6047 -4.90444,-1.447 -6.69936,-1.6563 l -32.27266,-2.3241 c -2.22517,-0.1603 -3.83538,2.4748 -3.61412,5.8969 0.22127,3.42202 2.18532,6.28502 4.41048,6.44532 l 19.16416,1.3809 -26.40962,26.4096 c -2.22731,2.2273 -1.96345,6.0877 0.59069,8.6418 2.55414,2.5542 6.41456,2.818 8.64187,0.5907 l 26.3875,-26.3875 1.41122,20.3005 c 0.15436,2.2248 3.04804,4.2055 6.47075,4.4359 3.4227,0.2304 6.05126,-1.3894 5.89688,-3.6141 l -2.25338,-33.2637 c -0.12073,-3.0801 0.0535,-4.53852 -1.72441,-6.85592 z"
+       id="rect2823-7-2-7-6-1"
+       sodipodi:nodetypes="cccscccscccsccc" />
+    <path
+       style="opacity:0.9;fill:url(#radialGradient4313);fill-opacity:1;fill-rule:nonzero;stroke:url(#linearGradient4279);stroke-width:2.5;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+       d="m 393.88002,1043.0545 c 2.26182,1.6047 4.90444,1.447 6.69936,1.6563 l 32.27266,2.3241 c 2.22517,0.1603 3.83538,-2.4748 3.61412,-5.8969 -0.22127,-3.4221 -2.18532,-6.2851 -4.41048,-6.4454 l -19.16416,-1.3808 26.40962,-26.4096 c 2.22731,-2.2273 1.96345,-6.0877 -0.59069,-8.64192 -2.55414,-2.5541 -6.41456,-2.818 -8.64187,-0.5907 l -26.3875,26.38752 -1.41122,-20.3005 c -0.15437,-2.2247 -3.04804,-4.20542 -6.47075,-4.43582 -3.4227,-0.2304 -6.05126,1.38942 -5.89688,3.61412 l 2.25338,33.2637 c 0.12073,3.08 -0.0535,4.5384 1.72441,6.8559 z"
+       id="rect2823-7-2-7-0-1"
+       sodipodi:nodetypes="cccscccscccsccc" />
+    <path
+       style="fill:url(#radialGradient3690);fill-opacity:1;fill-rule:nonzero;stroke:url(#linearGradient3692);stroke-width:2.5;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+       d="m 2.5,1020.739 c 0.43258,2.5453 2.27607,4.1811 3.31984,5.5005 l 19.71521,22.7751 c 1.35929,1.5703 4.15401,0.8956 6.2611,-1.5028 2.10709,-2.3984 2.69887,-5.576 1.33958,-7.1464 l -11.7068,-13.5248 34.77097,0 c 2.9325,0 5.3001,-2.715 5.3001,-6.0778 0,-3.3628 -2.3676,-6.0778 -5.3001,-6.0778 l -34.74185,0 12.43484,-14.2928 c 1.36295,-1.56622 0.76191,-4.77502 -1.33958,-7.17992 -2.1015,-2.4048 -4.89816,-3.0689 -6.26111,-1.5027 L 5.87809,1015.0905 C 3.92996,1017.1976 2.8552,1018.043 2.5,1020.739 z"
+       id="rect2823-7-9"
+       sodipodi:nodetypes="cccscccscccsccc" />
+    <path
+       style="fill:url(#radialGradient5078-6);fill-opacity:1.0;fill-rule:nonzero;stroke:url(#linearGradient5081-5);stroke-width:2.50000000000000000;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+       d="m 95.62323,1049.8622 c -2.54534,-0.4326 -4.18112,-2.2761 -5.50056,-3.3199 l -22.77506,-19.7152 c -1.57037,-1.3593 -0.89566,-4.154 1.50275,-6.2611 2.39841,-2.107 5.57607,-2.6988 7.14643,-1.3395 l 13.52478,11.7068 0,-34.77102 c 0,-2.9325 2.71501,-5.3001 6.0778,-5.3001 3.36279,0 6.07781,2.3676 6.07781,5.3001 l 0,34.74182 14.29285,-12.4348 c 1.5662,-1.363 4.77498,-0.7619 7.17983,1.3396 2.40484,2.1015 3.06894,4.8981 1.50275,6.2611 l -23.38094,20.4141 c -2.10708,1.9481 -2.95246,3.0229 -5.64844,3.3781 z"
+       id="rect2823-7-2-77"
+       sodipodi:nodetypes="cccscccscccsccc" />
+    <path
+       style="fill:url(#radialGradient5086-7);fill-opacity:1;fill-rule:nonzero;stroke:url(#linearGradient5089-5);stroke-width:2.5;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+       d="m 159.62323,990.86218 c -2.54534,0.4326 -4.18112,2.2761 -5.50056,3.3198 l -22.77506,19.71522 c -1.57037,1.3593 -0.89566,4.1541 1.50275,6.2611 2.39841,2.1071 5.57607,2.6989 7.14643,1.3396 l 13.52478,-11.7068 0,34.771 c 0,2.9325 2.71501,5.3001 6.0778,5.3001 3.36279,0 6.07781,-2.3676 6.07781,-5.3001 l 0,-34.7419 14.29285,12.4349 c 1.5662,1.3629 4.77498,0.7619 7.17983,-1.3396 2.40484,-2.1015 3.06894,-4.8982 1.50275,-6.2611 l -23.38094,-20.41412 c -2.10708,-1.9481 -2.95246,-3.0229 -5.64844,-3.3781 z"
+       id="rect2823-7-2-9-6"
+       sodipodi:nodetypes="cccscccscccsccc" />
+    <path
+       style="fill:url(#radialGradient5094-1);fill-opacity:1.0;fill-rule:nonzero;stroke:url(#linearGradient5097-9);stroke-width:2.50000000000000000;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+       d="m 253.5,1019.9854 c -0.43258,-2.5453 -2.27607,-4.1811 -3.31985,-5.5006 l -19.7152,-22.77502 c -1.3593,-1.5704 -4.15402,-0.8957 -6.2611,1.5028 -2.10709,2.3984 -2.69889,5.576 -1.33958,7.14642 l 11.70679,13.5247 -15.1824,0 -19.58857,0 c -2.93248,0 -5.30009,2.7151 -5.30009,6.0778 0,3.3628 2.36761,6.0778 5.30009,6.0778 l 34.74185,0 -12.43484,14.2929 c -1.36295,1.5662 -0.76191,4.775 1.33959,7.1798 2.10149,2.4049 4.89816,3.069 6.2611,1.5028 l 20.41412,-23.381 c 1.94813,-2.107 3.02288,-2.9524 3.37809,-5.6484 z"
+       id="rect2823-7-2-92-7"
+       sodipodi:nodetypes="cccsccccscccsccc" />
+    <path
+       style="opacity:0.9;fill:url(#radialGradient4453);fill-opacity:1;fill-rule:nonzero;stroke:url(#linearGradient4455);stroke-width:2.5;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+       d="m 502.69188,1042.4819 c 1.6047,-2.2618 1.44695,-4.9044 1.65632,-6.6993 l 2.32405,-32.2727 c 0.16032,-2.2252 -2.47482,-3.83542 -5.89688,-3.61412 -3.42206,0.22132 -6.28508,2.18532 -6.44539,4.41052 l -1.38081,19.1641 -26.40961,-26.40962 c -2.22732,-2.2273 -6.08773,-1.9634 -8.64187,0.5907 -2.55414,2.55422 -2.81801,6.41452 -0.59069,8.64192 l 26.3875,26.3875 -20.3005,1.4112 c -2.22478,0.1543 -4.20544,3.048 -4.43584,6.4707 -0.23041,3.4227 1.38934,6.0513 3.61411,5.8969 l 33.26368,-2.2534 c 3.08006,-0.1207 4.53845,0.053 6.85593,-1.7244 z"
+       id="rect2823-7-2-7-3"
+       sodipodi:nodetypes="cccscccscccsccc" />
+  </g>
+</svg>
diff --git a/data/themes/default/arrows_hold.svg b/data/themes/default/arrows_hold.svg
new file mode 100644 (file)
index 0000000..878bea3
--- /dev/null
@@ -0,0 +1,733 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://creativecommons.org/ns#"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:xlink="http://www.w3.org/1999/xlink"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   width="512"
+   height="192"
+   id="svg3163"
+   version="1.1"
+   inkscape:version="0.48.0 r9654"
+   sodipodi:docname="arrows_hold.svg">
+  <defs
+     id="defs3165">
+    <inkscape:perspective
+       sodipodi:type="inkscape:persp3d"
+       inkscape:vp_x="0 : 526.18109 : 1"
+       inkscape:vp_y="0 : 1000 : 0"
+       inkscape:vp_z="744.09448 : 526.18109 : 1"
+       inkscape:persp3d-origin="372.04724 : 350.78739 : 1"
+       id="perspective3171" />
+    <inkscape:perspective
+       id="perspective3016"
+       inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
+       inkscape:vp_z="1 : 0.5 : 1"
+       inkscape:vp_y="0 : 1000 : 0"
+       inkscape:vp_x="0 : 0.5 : 1"
+       sodipodi:type="inkscape:persp3d" />
+    <radialGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient5072-7"
+       id="radialGradient5094-1"
+       cx="384.26987"
+       cy="471.5892"
+       fx="384.26987"
+       fy="471.5892"
+       r="31.437084"
+       gradientTransform="matrix(0.96131646,0,0,0.96131644,-145.40496,439.0157)"
+       gradientUnits="userSpaceOnUse" />
+    <linearGradient
+       id="linearGradient5088-5">
+      <stop
+         style="stop-color:#6060ff;stop-opacity:1;"
+         offset="0"
+         id="stop5090-9" />
+      <stop
+         style="stop-color:#0000ff;stop-opacity:1;"
+         offset="1"
+         id="stop5092-4" />
+    </linearGradient>
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient5091"
+       id="linearGradient5097-9"
+       x1="415.46988"
+       y1="471.5892"
+       x2="353.58255"
+       y2="471.08411"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(0.96131646,0,0,0.96131644,-145.40496,439.01571)" />
+    <linearGradient
+       id="linearGradient5091">
+      <stop
+         style="stop-color:#000000;stop-opacity:1;"
+         offset="0"
+         id="stop5093" />
+      <stop
+         style="stop-color:#000000;stop-opacity:0.3764706;"
+         offset="1"
+         id="stop5095" />
+    </linearGradient>
+    <radialGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient5080-7"
+       id="radialGradient5086-7"
+       cx="320.26987"
+       cy="471.5892"
+       fx="320.26987"
+       fy="471.5892"
+       r="31.437082"
+       gradientTransform="matrix(0.96131325,-3.0089311e-6,3.0089412e-6,0.96131636,-147.88099,439.01669)"
+       gradientUnits="userSpaceOnUse" />
+    <linearGradient
+       id="linearGradient5080-7">
+      <stop
+         style="stop-color:#ffff80;stop-opacity:1;"
+         offset="0"
+         id="stop5082-1" />
+      <stop
+         style="stop-color:#ffff00;stop-opacity:1;"
+         offset="1"
+         id="stop5084-1" />
+    </linearGradient>
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient5091"
+       id="linearGradient5089-5"
+       x1="320.26987"
+       y1="440.1521"
+       x2="319.88715"
+       y2="502.14633"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(0.96131651,0,0,0.96131646,-147.88071,439.01571)" />
+    <linearGradient
+       id="linearGradient3033">
+      <stop
+         style="stop-color:#000000;stop-opacity:1;"
+         offset="0"
+         id="stop3035" />
+      <stop
+         style="stop-color:#000000;stop-opacity:0.3764706;"
+         offset="1"
+         id="stop3037" />
+    </linearGradient>
+    <radialGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient5088-5"
+       id="radialGradient5078-6"
+       cx="256.26987"
+       cy="471.5892"
+       fx="256.26987"
+       fy="471.5892"
+       r="31.437082"
+       gradientTransform="matrix(0.98425198,-1.3778034e-6,1.3456973e-6,0.96131646,-156.23479,439.0161)"
+       gradientUnits="userSpaceOnUse" />
+    <linearGradient
+       id="linearGradient5072-7">
+      <stop
+         style="stop-color:#ff6020;stop-opacity:1;"
+         offset="0"
+         id="stop5074-3" />
+      <stop
+         style="stop-color:#ff0000;stop-opacity:1;"
+         offset="1"
+         id="stop5076-6" />
+    </linearGradient>
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient5091"
+       id="linearGradient5081-5"
+       x1="256.26987"
+       y1="503.77628"
+       x2="256.31409"
+       y2="440.69635"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(0.96131651,0,0,0.96131646,-150.35646,439.01571)" />
+    <linearGradient
+       id="linearGradient3044">
+      <stop
+         style="stop-color:#000000;stop-opacity:1;"
+         offset="0"
+         id="stop3046" />
+      <stop
+         style="stop-color:#000000;stop-opacity:0.3764706;"
+         offset="1"
+         id="stop3048" />
+    </linearGradient>
+    <radialGradient
+       r="31"
+       fy="471.5892"
+       fx="192.26987"
+       cy="471.5892"
+       cx="192.26987"
+       gradientTransform="matrix(0.96130346,0,0,0.96130343,-152.82969,439.02183)"
+       gradientUnits="userSpaceOnUse"
+       id="radialGradient3690"
+       xlink:href="#linearGradient5064-8"
+       inkscape:collect="always" />
+    <linearGradient
+       id="linearGradient5064-8">
+      <stop
+         style="stop-color:#20ff20;stop-opacity:1;"
+         offset="0"
+         id="stop5066-1" />
+      <stop
+         style="stop-color:#00a000;stop-opacity:1;"
+         offset="1"
+         id="stop5068-2" />
+    </linearGradient>
+    <linearGradient
+       y2="471.5892"
+       x2="223.70737"
+       y1="471.5892"
+       x1="160.83237"
+       gradientTransform="matrix(0.96130346,0,0,0.96130343,-152.82969,439.02185)"
+       gradientUnits="userSpaceOnUse"
+       id="linearGradient3692"
+       xlink:href="#linearGradient5091"
+       inkscape:collect="always" />
+    <linearGradient
+       id="linearGradient3055">
+      <stop
+         style="stop-color:#000000;stop-opacity:1;"
+         offset="0"
+         id="stop3057" />
+      <stop
+         style="stop-color:#000000;stop-opacity:0.3764706;"
+         offset="1"
+         id="stop3059" />
+    </linearGradient>
+    <radialGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient4315"
+       id="radialGradient4321"
+       cx="641.50745"
+       cy="344.23474"
+       fx="641.50745"
+       fy="344.23474"
+       r="26.692099"
+       gradientTransform="matrix(1,0,0,1.0006216,-160.26987,548.559)"
+       gradientUnits="userSpaceOnUse" />
+    <linearGradient
+       id="linearGradient4315">
+      <stop
+         style="stop-color:#b469ff;stop-opacity:1;"
+         offset="0"
+         id="stop4317" />
+      <stop
+         style="stop-color:#7000de;stop-opacity:1;"
+         offset="1"
+         id="stop4319" />
+    </linearGradient>
+    <linearGradient
+       gradientTransform="translate(-160.26987,548.77297)"
+       inkscape:collect="always"
+       xlink:href="#linearGradient5091"
+       id="linearGradient4287"
+       x1="614.81531"
+       y1="344.23474"
+       x2="668.19952"
+       y2="344.23474"
+       gradientUnits="userSpaceOnUse" />
+    <linearGradient
+       id="linearGradient3066">
+      <stop
+         style="stop-color:#000000;stop-opacity:1;"
+         offset="0"
+         id="stop3068" />
+      <stop
+         style="stop-color:#000000;stop-opacity:0.3764706;"
+         offset="1"
+         id="stop3070" />
+    </linearGradient>
+    <radialGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient4307"
+       id="radialGradient4313"
+       cx="575.62433"
+       cy="344.82675"
+       fx="575.62433"
+       fy="344.82675"
+       r="26.708689"
+       gradientTransform="matrix(1,0,0,0.9993789,-160.26987,548.98714)"
+       gradientUnits="userSpaceOnUse" />
+    <linearGradient
+       id="linearGradient4307">
+      <stop
+         style="stop-color:#35ffff;stop-opacity:1;"
+         offset="0"
+         id="stop4309" />
+      <stop
+         style="stop-color:#00dbdb;stop-opacity:1;"
+         offset="1"
+         id="stop4311" />
+    </linearGradient>
+    <linearGradient
+       gradientTransform="translate(-160.26987,548.77297)"
+       inkscape:collect="always"
+       xlink:href="#linearGradient5091"
+       id="linearGradient4279"
+       x1="548.91565"
+       y1="344.82675"
+       x2="602.33301"
+       y2="344.82675"
+       gradientUnits="userSpaceOnUse" />
+    <linearGradient
+       id="linearGradient3077">
+      <stop
+         style="stop-color:#000000;stop-opacity:1;"
+         offset="0"
+         id="stop3079" />
+      <stop
+         style="stop-color:#000000;stop-opacity:0.3764706;"
+         offset="1"
+         id="stop3081" />
+    </linearGradient>
+    <radialGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient4299"
+       id="radialGradient4305"
+       cx="512.91541"
+       cy="342.35165"
+       fx="512.91541"
+       fy="342.35165"
+       r="26.708689"
+       gradientTransform="matrix(1,0,0,0.9993789,-160.26987,548.9856)"
+       gradientUnits="userSpaceOnUse" />
+    <linearGradient
+       id="linearGradient4299">
+      <stop
+         style="stop-color:#ff7cff;stop-opacity:1;"
+         offset="0"
+         id="stop4301" />
+      <stop
+         style="stop-color:#e400e4;stop-opacity:1;"
+         offset="1"
+         id="stop4303" />
+    </linearGradient>
+    <linearGradient
+       gradientTransform="translate(-160.26987,548.77297)"
+       inkscape:collect="always"
+       xlink:href="#linearGradient5091"
+       id="linearGradient4271"
+       x1="486.20673"
+       y1="342.35165"
+       x2="539.62408"
+       y2="342.35165"
+       gradientUnits="userSpaceOnUse" />
+    <linearGradient
+       id="linearGradient3088">
+      <stop
+         style="stop-color:#000000;stop-opacity:1;"
+         offset="0"
+         id="stop3090" />
+      <stop
+         style="stop-color:#000000;stop-opacity:0.3764706;"
+         offset="1"
+         id="stop3092" />
+    </linearGradient>
+    <radialGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient4289"
+       id="radialGradient4297"
+       cx="447.03232"
+       cy="342.94363"
+       fx="447.03232"
+       fy="342.94363"
+       r="26.692099"
+       gradientTransform="matrix(1,0,0,1.0006216,-160.26987,548.55981)"
+       gradientUnits="userSpaceOnUse" />
+    <linearGradient
+       id="linearGradient4289">
+      <stop
+         style="stop-color:#ff8f4c;stop-opacity:1;"
+         offset="0"
+         id="stop4291" />
+      <stop
+         style="stop-color:#f25b00;stop-opacity:1;"
+         offset="1"
+         id="stop4293" />
+    </linearGradient>
+    <linearGradient
+       gradientTransform="translate(-160.26987,548.77297)"
+       inkscape:collect="always"
+       xlink:href="#linearGradient5091"
+       id="linearGradient4263"
+       x1="420.84024"
+       y1="342.94363"
+       x2="473.22443"
+       y2="342.94363"
+       gradientUnits="userSpaceOnUse" />
+    <linearGradient
+       id="linearGradient3099">
+      <stop
+         style="stop-color:#000000;stop-opacity:1;"
+         offset="0"
+         id="stop3101" />
+      <stop
+         style="stop-color:#000000;stop-opacity:0.3764706;"
+         offset="1"
+         id="stop3103" />
+    </linearGradient>
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient5080"
+       id="linearGradient5088"
+       x1="-0.75"
+       y1="110.88067"
+       x2="64.75"
+       y2="110.88067"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(1,0,0,1.0220971,3.5771484e-6,856.26364)" />
+    <linearGradient
+       id="linearGradient5080">
+      <stop
+         style="stop-color:#00ff00;stop-opacity:0;"
+         offset="0"
+         id="stop5082" />
+      <stop
+         id="stop5090"
+         offset="0.5"
+         style="stop-color:#00ff00;stop-opacity:1;" />
+      <stop
+         style="stop-color:#00ff00;stop-opacity:0;"
+         offset="1"
+         id="stop5084" />
+    </linearGradient>
+    <linearGradient
+       gradientTransform="matrix(1,0,0,0.93686547,64.000013,872.53269)"
+       y2="110.88067"
+       x2="64.75"
+       y1="110.88067"
+       x1="-0.75"
+       gradientUnits="userSpaceOnUse"
+       id="linearGradient5110"
+       xlink:href="#linearGradient5080-0"
+       inkscape:collect="always" />
+    <linearGradient
+       id="linearGradient5133">
+      <stop
+         id="stop5135"
+         offset="0"
+         style="stop-color:#ff0000;stop-opacity:0;" />
+      <stop
+         style="stop-color:#ff0000;stop-opacity:1;"
+         offset="0.5"
+         id="stop5137" />
+      <stop
+         id="stop5139"
+         offset="1"
+         style="stop-color:#ff0000;stop-opacity:0;" />
+    </linearGradient>
+    <linearGradient
+       y2="110.88067"
+       x2="64.75"
+       y1="110.88067"
+       x1="-0.75"
+       spreadMethod="pad"
+       gradientTransform="matrix(1,0,0,1.1483661,256.00001,832.16137)"
+       gradientUnits="userSpaceOnUse"
+       id="linearGradient4111"
+       xlink:href="#linearGradient5080-0-0"
+       inkscape:collect="always" />
+    <linearGradient
+       id="linearGradient5080-0-0">
+      <stop
+         style="stop-color:#ff6000;stop-opacity:0;"
+         offset="0"
+         id="stop5082-0-3" />
+      <stop
+         id="stop5090-2-3"
+         offset="0.5"
+         style="stop-color:#ff6000;stop-opacity:1;" />
+      <stop
+         style="stop-color:#ff6000;stop-opacity:0;"
+         offset="1"
+         id="stop5084-9-6" />
+    </linearGradient>
+    <linearGradient
+       gradientTransform="matrix(1,0,0,1.0410374,192,852.64831)"
+       y2="110.88067"
+       x2="64.75"
+       y1="110.88067"
+       x1="-0.75"
+       gradientUnits="userSpaceOnUse"
+       id="linearGradient5110-6"
+       xlink:href="#linearGradient5133"
+       inkscape:collect="always"
+       spreadMethod="pad" />
+    <linearGradient
+       id="linearGradient5080-0">
+      <stop
+         style="stop-color:#0000ff;stop-opacity:0;"
+         offset="0"
+         id="stop5082-0" />
+      <stop
+         id="stop5090-2"
+         offset="0.5"
+         style="stop-color:#0000ff;stop-opacity:1;" />
+      <stop
+         style="stop-color:#0000ff;stop-opacity:0;"
+         offset="1"
+         id="stop5084-9" />
+    </linearGradient>
+    <linearGradient
+       y2="110.88067"
+       x2="64.75"
+       y1="110.88067"
+       x1="-0.75"
+       spreadMethod="pad"
+       gradientTransform="matrix(1,0,0,1.1483661,320.00002,832.16138)"
+       gradientUnits="userSpaceOnUse"
+       id="linearGradient4152"
+       xlink:href="#linearGradient5080-0-0-2"
+       inkscape:collect="always" />
+    <linearGradient
+       id="linearGradient5080-0-0-2">
+      <stop
+         style="stop-color:#ff00ff;stop-opacity:0;"
+         offset="0"
+         id="stop5082-0-3-7" />
+      <stop
+         id="stop5090-2-3-5"
+         offset="0.5"
+         style="stop-color:#ff00ff;stop-opacity:1;" />
+      <stop
+         style="stop-color:#ff00ff;stop-opacity:0;"
+         offset="1"
+         id="stop5084-9-6-7" />
+    </linearGradient>
+    <linearGradient
+       y2="110.88067"
+       x2="64.75"
+       y1="110.88067"
+       x1="-0.75"
+       gradientTransform="matrix(1,0,0,0.90937494,384.00005,877.78016)"
+       gradientUnits="userSpaceOnUse"
+       id="linearGradient4193"
+       xlink:href="#linearGradient5133-4"
+       inkscape:collect="always" />
+    <linearGradient
+       id="linearGradient5133-4">
+      <stop
+         id="stop5135-4"
+         offset="0"
+         style="stop-color:#00ffff;stop-opacity:0;" />
+      <stop
+         style="stop-color:#00ffff;stop-opacity:1;"
+         offset="0.5"
+         id="stop5137-6" />
+      <stop
+         id="stop5139-8"
+         offset="1"
+         style="stop-color:#00ffff;stop-opacity:0;" />
+    </linearGradient>
+    <linearGradient
+       y2="110.88067"
+       x2="64.75"
+       y1="110.88067"
+       x1="-0.75"
+       gradientTransform="matrix(1,0,0,0.91562494,448.00001,876.58716)"
+       gradientUnits="userSpaceOnUse"
+       id="linearGradient4234"
+       xlink:href="#linearGradient5133-4-1"
+       inkscape:collect="always" />
+    <linearGradient
+       id="linearGradient5133-4-1">
+      <stop
+         id="stop5135-4-3"
+         offset="0"
+         style="stop-color:#8000ff;stop-opacity:0;" />
+      <stop
+         style="stop-color:#8000ff;stop-opacity:1;"
+         offset="0.5"
+         id="stop5137-6-3" />
+      <stop
+         id="stop5139-8-9"
+         offset="1"
+         style="stop-color:#8000ff;stop-opacity:0;" />
+    </linearGradient>
+    <linearGradient
+       gradientTransform="matrix(1,0,0,1.0820749,288.26986,297.04201)"
+       y2="110.88067"
+       x2="64.75"
+       y1="110.88067"
+       x1="-0.75"
+       gradientUnits="userSpaceOnUse"
+       id="linearGradient5110-8"
+       xlink:href="#linearGradient5162"
+       inkscape:collect="always" />
+    <linearGradient
+       id="linearGradient5162">
+      <stop
+         id="stop5164"
+         offset="0"
+         style="stop-color:#ffff00;stop-opacity:0;" />
+      <stop
+         style="stop-color:#ffff00;stop-opacity:1;"
+         offset="0.5"
+         id="stop5166" />
+      <stop
+         id="stop5168"
+         offset="1"
+         style="stop-color:#ffff00;stop-opacity:0;" />
+    </linearGradient>
+    <linearGradient
+       y2="110.88067"
+       x2="64.75"
+       y1="110.88067"
+       x1="-0.75"
+       gradientTransform="matrix(1,0,0,1.0820749,127.99999,844.81501)"
+       gradientUnits="userSpaceOnUse"
+       id="linearGradient3161"
+       xlink:href="#linearGradient5162"
+       inkscape:collect="always" />
+  </defs>
+  <sodipodi:namedview
+     id="base"
+     pagecolor="#ffffff"
+     bordercolor="#666666"
+     borderopacity="1.0"
+     inkscape:pageopacity="0.0"
+     inkscape:pageshadow="2"
+     inkscape:zoom="1.979899"
+     inkscape:cx="172.07259"
+     inkscape:cy="116.77159"
+     inkscape:document-units="px"
+     inkscape:current-layer="layer1"
+     showgrid="false"
+     inkscape:window-width="1297"
+     inkscape:window-height="786"
+     inkscape:window-x="68"
+     inkscape:window-y="38"
+     inkscape:window-maximized="0" />
+  <metadata
+     id="metadata3168">
+    <rdf:RDF>
+      <cc:Work
+         rdf:about="">
+        <dc:format>image/svg+xml</dc:format>
+        <dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+        <dc:title />
+      </cc:Work>
+    </rdf:RDF>
+  </metadata>
+  <g
+     inkscape:label="Capa 1"
+     inkscape:groupmode="layer"
+     id="layer1"
+     transform="translate(0,-860.36218)">
+    <rect
+       style="fill:url(#linearGradient3161);fill-opacity:1;fill-rule:nonzero;stroke:none"
+       id="rect2858-7"
+       width="64"
+       height="173.13199"
+       x="128"
+       y="878.23016"
+       ry="19.323547" />
+    <rect
+       style="fill:url(#linearGradient4234);fill-opacity:1;fill-rule:nonzero;stroke:none"
+       id="rect2858-4-1-4"
+       width="64"
+       height="146.5"
+       x="448.00006"
+       y="904.86218"
+       ry="16.351105" />
+    <rect
+       style="fill:url(#linearGradient4193);fill-opacity:1;fill-rule:nonzero;stroke:none"
+       id="rect2858-4-1"
+       width="64"
+       height="145.5"
+       x="384.00006"
+       y="905.86218"
+       ry="16.239492" />
+    <rect
+       style="fill:url(#linearGradient4152);fill-opacity:1;fill-rule:nonzero;stroke:none"
+       id="rect2858-5-1-5"
+       width="64"
+       height="183.73857"
+       x="320"
+       y="867.6236"
+       ry="20.507366" />
+    <rect
+       style="fill:url(#linearGradient5110-6);fill-opacity:1.0;fill-rule:nonzero;stroke:none"
+       id="rect2858-5"
+       width="64"
+       height="166.56598"
+       x="192"
+       y="884.7962"
+       ry="18.590704" />
+    <rect
+       style="fill:url(#linearGradient4111);fill-opacity:1;fill-rule:nonzero;stroke:none"
+       id="rect2858-5-1"
+       width="64"
+       height="183.73857"
+       x="256"
+       y="867.6236"
+       ry="20.507366" />
+    <rect
+       style="fill:url(#linearGradient5110);fill-opacity:1.0;fill-rule:nonzero;stroke:none"
+       id="rect2858-4"
+       width="64"
+       height="149.89848"
+       x="64"
+       y="901.46368"
+       ry="16.730415" />
+    <rect
+       style="fill:url(#linearGradient5088);fill-opacity:1;fill-rule:nonzero;stroke:none"
+       id="rect2858"
+       width="64"
+       height="163.53552"
+       x="0"
+       y="887.82666"
+       ry="18.252472" />
+    <path
+       style="opacity:1;fill:url(#radialGradient4297);fill-opacity:1;fill-rule:nonzero;stroke:url(#linearGradient4263);stroke-width:2.50000000000000000;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+       d="m 265.30767,870.24219 c -1.6047,2.26182 -1.44695,4.90443 -1.65632,6.69936 l -2.32405,32.27266 c -0.16032,2.22516 2.47482,3.83538 5.89688,3.61411 3.42206,-0.22127 6.28508,-2.18531 6.44539,-4.41047 l 1.38081,-19.16417 26.40961,26.40962 c 2.22732,2.22732 6.08773,1.96345 8.64187,-0.59069 2.55414,-2.55414 2.81801,-6.41455 0.59069,-8.64187 l -26.3875,-26.3875 20.3005,-1.41121 c 2.22478,-0.15437 4.20544,-3.04805 4.43584,-6.47076 0.23041,-3.42269 -1.38934,-6.05125 -3.61411,-5.89688 l -33.26368,2.25339 c -3.08006,0.12073 -4.53845,-0.0535 -6.85593,1.72441 z"
+       id="rect2823-7-2-7"
+       sodipodi:nodetypes="cccscccscccsccc" />
+    <path
+       style="opacity:1;fill:url(#radialGradient4305);fill-opacity:1;fill-rule:nonzero;stroke:url(#linearGradient4271);stroke-width:2.50000000000000000;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+       d="m 374.11998,869.66984 c -2.26182,-1.60471 -4.90444,-1.44695 -6.69936,-1.65632 l -32.27266,-2.32406 c -2.22517,-0.16031 -3.83538,2.47483 -3.61412,5.89689 0.22127,3.42205 2.18532,6.28507 4.41048,6.44538 l 19.16416,1.38081 -26.40962,26.40962 c -2.22731,2.22731 -1.96345,6.08772 0.59069,8.64186 2.55414,2.55414 6.41456,2.81801 8.64187,0.5907 l 26.3875,-26.3875 1.41122,20.3005 c 0.15436,2.22477 3.04804,4.20544 6.47075,4.43584 3.4227,0.2304 6.05126,-1.38935 5.89688,-3.61412 l -2.25338,-33.26368 c -0.12073,-3.08006 0.0535,-4.53845 -1.72441,-6.85592 z"
+       id="rect2823-7-2-7-6"
+       sodipodi:nodetypes="cccscccscccsccc" />
+    <path
+       style="opacity:1;fill:url(#radialGradient4313);fill-opacity:1;fill-rule:nonzero;stroke:url(#linearGradient4279);stroke-width:2.50000000000000000;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+       d="m 393.88002,915.05449 c 2.26182,1.60471 4.90444,1.44695 6.69936,1.65632 l 32.27266,2.32406 c 2.22517,0.16031 3.83538,-2.47483 3.61412,-5.89689 -0.22127,-3.42205 -2.18532,-6.28507 -4.41048,-6.44538 l -19.16416,-1.38081 26.40962,-26.40962 c 2.22731,-2.22731 1.96345,-6.08772 -0.59069,-8.64186 -2.55414,-2.55414 -6.41456,-2.81801 -8.64187,-0.5907 l -26.3875,26.3875 -1.41122,-20.3005 c -0.15437,-2.22477 -3.04804,-4.20544 -6.47075,-4.43584 -3.4227,-0.2304 -6.05126,1.38935 -5.89688,3.61412 l 2.25338,33.26368 c 0.12073,3.08006 -0.0535,4.53845 1.72441,6.85592 z"
+       id="rect2823-7-2-7-0"
+       sodipodi:nodetypes="cccscccscccsccc" />
+    <path
+       style="opacity:1;fill:url(#radialGradient4321);fill-opacity:1;fill-rule:nonzero;stroke:url(#linearGradient4287);stroke-width:2.50000000000000000;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+       d="m 502.69233,914.48214 c 1.6047,-2.26182 1.44695,-4.90443 1.65632,-6.69936 l 2.32405,-32.27266 c 0.16032,-2.22516 -2.47482,-3.83538 -5.89688,-3.61411 -3.42206,0.22127 -6.28508,2.18531 -6.44539,4.41047 l -1.38081,19.16417 -26.40961,-26.40962 c -2.22732,-2.22732 -6.08773,-1.96345 -8.64187,0.59069 -2.55414,2.55414 -2.81801,6.41455 -0.59069,8.64187 l 26.3875,26.3875 -20.3005,1.41121 c -2.22478,0.15437 -4.20544,3.04805 -4.43584,6.47076 -0.23041,3.42269 1.38934,6.05125 3.61411,5.89688 l 33.26368,-2.25339 c 3.08006,-0.12073 4.53845,0.0535 6.85593,-1.72441 z"
+       id="rect2823-7-2-7-3"
+       sodipodi:nodetypes="cccscccscccsccc" />
+    <path
+       style="fill:url(#radialGradient3690);fill-opacity:1;fill-rule:nonzero;stroke:url(#linearGradient3692);stroke-width:2.5;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+       d="m 2.5000036,892.73894 c 0.43258,2.54534 2.27607,4.18113 3.31984,5.50055 l 19.7152104,22.77507 c 1.35929,1.57037 4.15401,0.89566 6.2611,-1.50275 2.10709,-2.3984 2.69887,-5.57607 1.33958,-7.14642 l -11.7068,-13.52478 34.770969,0 c 2.9325,0 5.3001,-2.71502 5.3001,-6.07781 0,-3.36279 -2.3676,-6.07781 -5.3001,-6.07781 l -34.741849,0 12.43484,-14.29285 c 1.36295,-1.56619 0.76191,-4.77498 -1.33958,-7.17983 -2.1015,-2.40484 -4.89816,-3.06894 -6.26111,-1.50275 L 5.8780936,887.0905 c -1.94813,2.10708 -3.02289,2.95246 -3.37809,5.64844 z"
+       id="rect2823-7"
+       sodipodi:nodetypes="cccscccscccsccc" />
+    <path
+       style="fill:url(#radialGradient5078-6);fill-opacity:1.0;fill-rule:nonzero;stroke:url(#linearGradient5081-5);stroke-width:2.50000000000000000;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+       d="m 95.623234,921.86217 c -2.54534,-0.43258 -4.18112,-2.27607 -5.50056,-3.31984 L 67.347613,898.82712 c -1.57037,-1.35929 -0.89566,-4.15402 1.502751,-6.2611 2.39841,-2.10708 5.57607,-2.69888 7.14643,-1.33958 l 13.52478,11.7068 0,-34.77097 c 0,-2.93249 2.71501,-5.3001 6.0778,-5.3001 3.36279,0 6.077806,2.36761 6.077806,5.3001 l 0,34.74184 14.29285,-12.43483 c 1.5662,-1.36295 4.77498,-0.76192 7.17983,1.33959 2.40484,2.10148 3.06894,4.89816 1.50275,6.26109 l -23.38094,20.41412 c -2.107076,1.94813 -2.952456,3.02288 -5.648436,3.37809 z"
+       id="rect2823-7-2"
+       sodipodi:nodetypes="cccscccscccsccc" />
+    <path
+       style="fill:url(#radialGradient5086-7);fill-opacity:1;fill-rule:nonzero;stroke:url(#linearGradient5089-5);stroke-width:2.5;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+       d="m 159.62323,862.86217 c -2.54534,0.43258 -4.18112,2.27607 -5.50056,3.31984 l -22.77506,19.7152 c -1.57037,1.3593 -0.89566,4.15403 1.50275,6.26111 2.39841,2.10708 5.57607,2.69887 7.14643,1.33958 l 13.52478,-11.7068 0,34.77097 c 0,2.93249 2.71501,5.3001 6.0778,5.3001 3.36279,0 6.07781,-2.36761 6.07781,-5.3001 l 0,-34.74185 14.29285,12.43483 c 1.5662,1.36296 4.77498,0.76192 7.17983,-1.33958 2.40484,-2.10149 3.06894,-4.89816 1.50275,-6.26109 l -23.38094,-20.41413 c -2.10708,-1.94812 -2.95246,-3.02287 -5.64844,-3.37808 z"
+       id="rect2823-7-2-9"
+       sodipodi:nodetypes="cccscccscccsccc" />
+    <path
+       style="fill:url(#radialGradient5094-1);fill-opacity:1.0;fill-rule:nonzero;stroke:url(#linearGradient5097-9);stroke-width:2.50000000000000000;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+       d="m 253.5,891.98539 c -0.43258,-2.54534 -2.27607,-4.18112 -3.31985,-5.50056 l -19.7152,-22.77506 c -1.3593,-1.57037 -4.15402,-0.89566 -6.2611,1.50275 -2.10709,2.39841 -2.69889,5.57607 -1.33958,7.14643 l 11.70679,13.52478 -15.1824,0 -19.58857,0 c -2.93248,0 -5.30009,2.71501 -5.30009,6.0778 0,3.36279 2.36761,6.0778 5.30009,6.0778 l 34.74185,0 -12.43484,14.29286 c -1.36295,1.56619 -0.76191,4.77498 1.33959,7.17983 2.10149,2.40484 4.89816,3.06894 6.2611,1.50275 l 20.41412,-23.38094 c 1.94813,-2.10708 3.02288,-2.95246 3.37809,-5.64844 z"
+       id="rect2823-7-2-92"
+       sodipodi:nodetypes="cccsccccscccsccc" />
+  </g>
+</svg>
diff --git a/data/themes/default/audiodevices_bg.svg b/data/themes/default/audiodevices_bg.svg
new file mode 100644 (file)
index 0000000..d259852
--- /dev/null
@@ -0,0 +1,176 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Sodipodi ("http://www.sodipodi.com/") -->
+
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://creativecommons.org/ns#"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:xlink="http://www.w3.org/1999/xlink"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   version="1.0"
+   x="0"
+   y="0"
+   width="1000"
+   height="800"
+   id="svg559"
+   sodipodi:version="0.32"
+   inkscape:version="0.48.1 r9760"
+   sodipodi:docname="audiodevices_bg.svg"
+   inkscape:output_extension="org.inkscape.output.svg.inkscape">
+  <metadata
+     id="metadata35">
+    <rdf:RDF>
+      <cc:Work
+         rdf:about="">
+        <dc:format>image/svg+xml</dc:format>
+        <dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+      </cc:Work>
+    </rdf:RDF>
+  </metadata>
+  <sodipodi:namedview
+     inkscape:window-height="856"
+     inkscape:window-width="1242"
+     inkscape:pageshadow="2"
+     inkscape:pageopacity="0.0"
+     guidetolerance="10.0"
+     gridtolerance="10.0"
+     objecttolerance="10.0"
+     borderopacity="1.0"
+     bordercolor="#666666"
+     pagecolor="#ffffff"
+     id="base"
+     inkscape:zoom="1.2304507"
+     inkscape:cx="468.69692"
+     inkscape:cy="408.0027"
+     inkscape:window-x="541"
+     inkscape:window-y="122"
+     inkscape:current-layer="svg559"
+     showgrid="false"
+     showguides="true"
+     inkscape:guide-bbox="true"
+     inkscape:window-maximized="0" />
+  <defs
+     id="defs561">
+    <filter
+       inkscape:collect="always"
+       id="filter3869"
+       x="-0.019231318"
+       width="1.0384626"
+       y="-0.12226724"
+       height="1.2445345">
+      <feGaussianBlur
+         inkscape:collect="always"
+         stdDeviation="3.4581674"
+         id="feGaussianBlur3871" />
+    </filter>
+    <filter
+       inkscape:collect="always"
+       id="filter5083">
+      <feGaussianBlur
+         inkscape:collect="always"
+         stdDeviation="2.8444007"
+         id="feGaussianBlur5085" />
+    </filter>
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient4040"
+       id="linearGradient4038"
+       x1="-568.24231"
+       y1="-820.92566"
+       x2="-733.16718"
+       y2="-401.87253"
+       gradientUnits="userSpaceOnUse" />
+    <linearGradient
+       id="linearGradient4040">
+      <stop
+         style="stop-color:black;stop-opacity:1;"
+         offset="0"
+         id="stop4042" />
+      <stop
+         style="stop-color:black;stop-opacity:0"
+         offset="1"
+         id="stop4044" />
+    </linearGradient>
+    <linearGradient
+       id="linearGradient3629-3">
+      <stop
+         style="stop-color:#00cbff;stop-opacity:0;"
+         offset="0"
+         id="stop3631-1" />
+      <stop
+         style="stop-color:#000000;stop-opacity:1;"
+         offset="1"
+         id="stop3633-4" />
+    </linearGradient>
+    <radialGradient
+       r="500"
+       fy="757.60583"
+       fx="727.25122"
+       cy="757.60583"
+       cx="727.25122"
+       gradientTransform="matrix(0.43355171,-0.84504566,1.805509,0.92631863,-980.88023,538.04792)"
+       gradientUnits="userSpaceOnUse"
+       id="radialGradient3721"
+       xlink:href="#linearGradient3629-3"
+       inkscape:collect="always" />
+  </defs>
+  <rect
+     style="fill:#ffffff;fill-opacity:1"
+     id="rect2851"
+     width="1000"
+     height="800"
+     x="0"
+     y="0" />
+  <rect
+     style="fill:url(#radialGradient3721);fill-opacity:1;stroke:none"
+     id="rect2855"
+     width="1000"
+     height="800"
+     x="0"
+     y="0" />
+  <text
+     xml:space="preserve"
+     style="font-size:24.89476013px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Goblin"
+     x="266.96185"
+     y="759.88806"
+     id="text2508"><tspan
+       sodipodi:role="line"
+       id="tspan2510"
+       x="266.96185"
+       y="759.88806" /></text>
+  <g
+     id="g3955"
+     transform="translate(18.488319,-59.198001)"
+     style="opacity:0.6;filter:url(#filter5083)">
+    <g
+       id="g2900"
+       transform="translate(446.28087,8.6462405)">
+      <g
+         id="g2943"
+         transform="matrix(0.25866863,-0.70093291,0.70093291,0.25866863,-1269.8962,257.2773)"
+         style="fill:#000000;fill-opacity:1">
+        <g
+           id="g2991"
+           style="fill:#000000;fill-opacity:1">
+          <g
+             id="g2911-6"
+             transform="matrix(-1,0,0,-1,-410.27669,1157.9797)"
+             style="fill:#000000;fill-opacity:1">
+            <path
+               style="fill:#000000;fill-opacity:1"
+               d="m -1194.8117,-863.52093 c 19.9136,27.44817 57.5228,35.34606 89.0483,27.10277 22.5638,-5.7965 37.0616,-24.36427 42.8644,-45.73397 l 95.90189,0.01 -0.01,0.093 246.73575,0.03 c 6.22244,21.7225 16.62274,44.36454 41.67591,44.67404 26.75421,5.8851 56.40568,0.92191 76.07369,-19.29084 9.46533,-7.8536 38.47618,-46.686 8.50508,-36.7546 -20.80791,1.9633 -43.2584,13.8753 -63.40389,6.1445 -14.79195,-15.2204 -21.87362,-57.2277 7.41832,-60.1166 18.87837,-4.7561 40.38545,-3.9612 57.65211,-11.8239 -19.91357,-27.4482 -57.50833,-35.3069 -89.03383,-27.0636 -22.55755,5.7949 -37.01919,24.3574 -42.82515,45.7195 l -95.90196,-0.01 -0.004,-0.1321 -246.76042,0.024 c -6.2219,-21.7277 -16.6161,-44.3644 -41.676,-44.674 -26.7542,-5.8851 -56.4201,-0.9611 -76.0881,19.2517 -9.4654,7.8536 -38.437,46.6715 -8.4659,36.7401 20.8079,-1.9633 43.2337,-13.8216 63.3792,-6.0908 14.7919,15.2203 21.8983,57.1739 -7.3936,60.0628 -18.8784,4.7561 -40.4247,3.9758 -57.6914,11.8384 z"
+               id="rect2874-8-7" />
+            <path
+               style="opacity:0.228;fill:url(#linearGradient4038);fill-opacity:1"
+               d="m -611.00177,-318.3564 c 10.90414,18.74819 16.56625,-4.20336 16.26165,-43.18309 -0.18286,-27.76164 -5.34425,-65.31304 -12.14637,-98.85454 l 7.59806,-85.2597 0.0306,0.1315 19.54959,-219.3502 c 7.87435,23.3179 16.39192,44.1417 18.4811,22.2763 4.11855,-15.9727 4.78014,-48.9298 -0.53084,-93.2633 -1.91916,-18.8469 -12.81737,-96.2171 -11.81601,-56.3773 -0.98066,21.1093 1.28922,56.8921 -2.93313,64.5374 -6.34344,-7.0622 -21.17874,-56.5566 -19.84077,-86.4391 -0.12115,-23.1028 1.85216,-41.1704 0.5477,-66.9661 -10.90418,-18.7484 -16.55185,4.2422 -16.24722,43.2221 0.18277,27.7537 5.34528,65.2661 12.14456,98.8004 l -7.59807,85.2597 -0.0452,-0.1721 -19.5332,219.4438 c -7.87602,-23.325 -16.39134,-44.1473 -18.48109,-22.2762 -4.11852,15.9729 -4.79458,48.8907 0.51637,93.2239 1.91916,18.8471 12.8156,96.16325 11.81424,56.3235 0.98069,-21.1091 -1.27295,-56.7988 2.9494,-64.4441 6.34341,7.062 21.16243,56.4632 19.82445,86.34561 0.12116,23.10279 -1.8503,41.22467 -0.54585,67.02048 z"
+               id="rect2874-8-7-4" />
+          </g>
+        </g>
+      </g>
+    </g>
+  </g>
+</svg>
diff --git a/data/themes/default/audiodevices_dev_bg.svg b/data/themes/default/audiodevices_dev_bg.svg
new file mode 100644 (file)
index 0000000..493bccb
--- /dev/null
@@ -0,0 +1,124 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://creativecommons.org/ns#"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:xlink="http://www.w3.org/1999/xlink"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   width="1000"
+   height="35"
+   id="svg2919"
+   version="1.1"
+   inkscape:version="0.48.0 r9654"
+   sodipodi:docname="audiodevices_dev_bg.svg">
+  <defs
+     id="defs2921">
+    <inkscape:perspective
+       sodipodi:type="inkscape:persp3d"
+       inkscape:vp_x="0 : 526.18109 : 1"
+       inkscape:vp_y="0 : 1000 : 0"
+       inkscape:vp_z="744.09448 : 526.18109 : 1"
+       inkscape:persp3d-origin="372.04724 : 350.78739 : 1"
+       id="perspective2927" />
+    <inkscape:perspective
+       id="perspective2908"
+       inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
+       inkscape:vp_z="1 : 0.5 : 1"
+       inkscape:vp_y="0 : 1000 : 0"
+       inkscape:vp_x="0 : 0.5 : 1"
+       sodipodi:type="inkscape:persp3d" />
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient5448"
+       id="linearGradient5460"
+       gradientUnits="userSpaceOnUse"
+       x1="0"
+       y1="768"
+       x2="0"
+       y2="713.1153"
+       gradientTransform="translate(0,-2)" />
+    <linearGradient
+       id="linearGradient5448">
+      <stop
+         style="stop-color:#beb7c8;stop-opacity:0.76862746;"
+         offset="0"
+         id="stop5450" />
+      <stop
+         style="stop-color:#beb7c8;stop-opacity:0;"
+         offset="1"
+         id="stop5452" />
+    </linearGradient>
+    <linearGradient
+       y2="713.1153"
+       x2="0"
+       y1="768"
+       x1="0"
+       gradientTransform="matrix(1.0000001,0,0,0.70000002,0,514.76198)"
+       gradientUnits="userSpaceOnUse"
+       id="linearGradient2917"
+       xlink:href="#linearGradient5448"
+       inkscape:collect="always" />
+    <inkscape:perspective
+       id="perspective2956"
+       inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
+       inkscape:vp_z="1 : 0.5 : 1"
+       inkscape:vp_y="0 : 1000 : 0"
+       inkscape:vp_x="0 : 0.5 : 1"
+       sodipodi:type="inkscape:persp3d" />
+    <inkscape:perspective
+       id="perspective2821"
+       inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
+       inkscape:vp_z="1 : 0.5 : 1"
+       inkscape:vp_y="0 : 1000 : 0"
+       inkscape:vp_x="0 : 0.5 : 1"
+       sodipodi:type="inkscape:persp3d" />
+  </defs>
+  <sodipodi:namedview
+     id="base"
+     pagecolor="#ffffff"
+     bordercolor="#666666"
+     borderopacity="1.0"
+     inkscape:pageopacity="0.0"
+     inkscape:pageshadow="2"
+     inkscape:zoom="2"
+     inkscape:cx="285.7361"
+     inkscape:cy="55.181507"
+     inkscape:document-units="px"
+     inkscape:current-layer="layer1"
+     showgrid="false"
+     inkscape:window-width="1920"
+     inkscape:window-height="1027"
+     inkscape:window-x="0"
+     inkscape:window-y="0"
+     inkscape:window-maximized="1" />
+  <metadata
+     id="metadata2924">
+    <rdf:RDF>
+      <cc:Work
+         rdf:about="">
+        <dc:format>image/svg+xml</dc:format>
+        <dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+        <dc:title />
+      </cc:Work>
+    </rdf:RDF>
+  </metadata>
+  <g
+     inkscape:label="Capa 1"
+     inkscape:groupmode="layer"
+     id="layer1"
+     transform="translate(0,-1017.3622)">
+    <rect
+       style="fill:url(#linearGradient2917);fill-opacity:1;stroke:none"
+       id="rect3982"
+       width="1000"
+       height="35"
+       x="0"
+       y="1017.3622" />
+  </g>
+</svg>
diff --git a/data/themes/default/band_cover.svg b/data/themes/default/band_cover.svg
new file mode 100644 (file)
index 0000000..22ea4fb
--- /dev/null
@@ -0,0 +1,127 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://creativecommons.org/ns#"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:xlink="http://www.w3.org/1999/xlink"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   width="256"
+   height="256"
+   id="svg2"
+   sodipodi:version="0.32"
+   inkscape:version="0.46"
+   sodipodi:docbase="/home/yoda/UltraStar/sf/svn/UltraStar-ng/themes/lima"
+   sodipodi:docname="band_cover.svg"
+   inkscape:output_extension="org.inkscape.output.svg.inkscape"
+   version="1.0">
+  <defs
+     id="defs4">
+    <inkscape:perspective
+       sodipodi:type="inkscape:persp3d"
+       inkscape:vp_x="0 : 128 : 1"
+       inkscape:vp_y="0 : 1000 : 0"
+       inkscape:vp_z="256 : 128 : 1"
+       inkscape:persp3d-origin="128 : 85.333333 : 1"
+       id="perspective17" />
+    <linearGradient
+       id="linearGradient3751"
+       inkscape:collect="always">
+      <stop
+         id="stop3753"
+         offset="0"
+         style="stop-color:black;stop-opacity:1;" />
+      <stop
+         id="stop3755"
+         offset="1"
+         style="stop-color:black;stop-opacity:0;" />
+    </linearGradient>
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient3751"
+       id="linearGradient3484"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(0.336682,0,0,0.336682,-81.3739,-51.8729)"
+       x1="665.12128"
+       y1="684.16162"
+       x2="381.28015"
+       y2="449.80624" />
+  </defs>
+  <sodipodi:namedview
+     id="base"
+     pagecolor="#ffffff"
+     bordercolor="#666666"
+     borderopacity="1.0"
+     inkscape:pageopacity="0.0"
+     inkscape:pageshadow="2"
+     inkscape:zoom="1.1191406"
+     inkscape:cx="-57.186749"
+     inkscape:cy="70.174855"
+     inkscape:document-units="px"
+     inkscape:current-layer="layer1"
+     inkscape:window-width="1144"
+     inkscape:window-height="785"
+     inkscape:window-x="136"
+     inkscape:window-y="25"
+     showguides="true"
+     inkscape:guide-bbox="true"
+     width="256px"
+     height="256px"
+     borderlayer="false"
+     showgrid="false" />
+  <metadata
+     id="metadata7">
+    <rdf:RDF>
+      <cc:Work
+         rdf:about="">
+        <dc:format>image/svg+xml</dc:format>
+        <dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+      </cc:Work>
+    </rdf:RDF>
+  </metadata>
+  <g
+     inkscape:label="Capa 1"
+     inkscape:groupmode="layer"
+     id="layer1">
+    <rect
+       style="opacity:1;color:#000000;fill:#ffffff;fill-opacity:0.31313129000000001;fill-rule:nonzero;stroke:#7f7f7f;stroke-width:10.01399999999999935;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:block;overflow:visible"
+       id="rect1906"
+       width="246.30026"
+       height="246.30028"
+       x="4.8498545"
+       y="4.0691833"
+       inkscape:export-filename="/home/jesusda/docs/curro/yo/ultrastar-ng/base/theme-pod/images/no_cover.png"
+       inkscape:export-xdpi="89.889648"
+       inkscape:export-ydpi="89.889648" />
+    <path
+       style="opacity:1;fill:#171717;fill-opacity:1"
+       d="M 169.41447,135.01629 C 163.31507,134.72906 157.33592,132.58979 152.4885,128.96039 C 150.97451,127.82683 148.77141,125.75385 147.63186,124.3906 C 144.16045,120.23772 142.07803,115.59758 141.33924,110.3691 L 141.26406,109.837 L 140.61465,109.85523 L 139.96526,109.87344 L 139.37286,111.57568 L 138.78047,113.27792 L 138.79345,115.6159 L 138.80642,117.95388 L 139.9138,118.22899 C 141.06641,118.51534 141.47817,118.68747 141.58819,118.92892 C 141.62394,119.00739 141.67395,119.36438 141.69932,119.72223 L 141.74545,120.37287 L 141.56523,120.44139 C 141.46612,120.47908 141.20951,120.50144 140.995,120.49108 L 140.605,120.47226 L 140.51352,120.11093 C 140.43956,119.81887 140.39647,119.74921 140.28869,119.74748 C 140.0645,119.74392 138.09312,119.23776 137.8452,119.12011 C 137.57575,118.99225 137.42535,118.74279 137.42535,118.42371 C 137.42535,118.30039 137.40146,118.18472 137.37227,118.16668 C 137.29692,118.12011 137.03994,118.19554 137.03994,118.26423 C 137.03994,118.29576 136.11023,120.98786 134.97392,124.24667 C 133.22839,129.25263 132.9063,130.23157 132.89761,130.55718 C 132.889,130.87909 132.80578,131.13794 132.39259,132.12808 C 131.77277,133.61334 131.65437,133.81627 131.27932,134.03606 C 130.74629,134.34844 129.96083,134.23726 129.4097,133.77144 C 129.13955,133.54311 128.99117,133.25798 129.04739,133.0752 C 129.10659,132.8827 131.11448,127.97677 131.19773,127.82122 C 131.25217,127.7195 131.28788,127.70977 131.39544,127.76734 C 131.46764,127.80598 131.53394,127.82803 131.54275,127.81633 C 131.55157,127.80463 132.35998,125.48608 133.33921,122.66398 L 135.11963,117.53289 L 134.98778,117.39256 C 134.91527,117.31536 134.85594,117.1912 134.85594,117.11664 C 134.85594,116.96916 135.29077,115.70068 135.38233,115.58104 C 135.4133,115.54057 135.53156,115.48991 135.64511,115.46844 L 135.85159,115.42942 L 136.60816,113.26168 L 137.36473,111.09391 L 137.36293,109.05444 L 137.36112,107.01498 L 136.71876,107.01498 L 136.07641,107.01498 L 136.07001,107.5128 C 136.0601,108.28335 136.03723,108.32817 135.64227,108.35115 C 135.32609,108.36954 135.30721,108.36162 135.25947,108.19056 C 135.19407,107.9563 135.19407,105.30283 135.25947,105.06858 C 135.30721,104.89752 135.32609,104.8896 135.64227,104.90798 C 136.03723,104.93096 136.0601,104.97578 136.07001,105.74633 L 136.07641,106.24416 L 136.71876,106.24416 L 137.36112,106.24416 L 137.36112,103.50668 L 137.36112,100.7692 L 136.95965,100.80871 C 135.40575,100.96163 134.23479,101.00374 131.46754,101.00622 L 128.3682,101.00899 L 128.36819,109.03597 L 128.36819,117.06296 L 128.52205,117.19384 C 128.65892,117.31027 128.68001,117.39388 128.71304,117.95102 C 128.74419,118.47664 128.73495,118.57732 128.65552,118.57732 C 128.57599,118.57732 128.5609,118.74666 128.5609,119.6388 L 128.5609,120.70026 L 128.38425,120.76851 C 128.13371,120.86531 126.90636,120.81199 126.66596,120.69387 L 126.47325,120.59918 L 126.45538,119.67561 C 126.44125,118.94596 126.45681,118.73032 126.52946,118.64862 C 126.58601,118.58504 126.63813,118.32252 126.66478,117.96708 C 126.71699,117.27097 126.74336,117.16414 126.86299,117.16414 C 126.94238,117.16414 126.95502,116.0493 126.95502,109.04386 L 126.95502,100.9236 L 126.48931,100.88725 C 124.37303,100.72208 122.71427,100.58069 122.54651,100.55119 L 122.34542,100.5158 L 122.29684,103.33181 C 122.27012,104.8806 122.25495,107.96887 122.26311,110.19462 C 122.27852,114.39368 122.2553,115.11256 122.10013,115.24134 C 122.04201,115.28957 122.00891,115.44242 122.00891,115.66248 L 122.00891,116.00791 L 121.67167,116.00692 C 121.48619,116.00639 121.29923,115.98357 121.25619,115.95622 C 121.1259,115.87344 121.10239,114.78451 121.07177,107.41733 L 121.04263,100.4005 L 120.89947,100.36993 C 120.82073,100.35311 120.48171,100.30716 120.14609,100.2678 C 119.19819,100.15665 116.44153,99.710872 115.23209,99.473162 L 114.14009,99.258532 L 113.9276,99.459292 C 113.72487,99.650822 113.69088,99.659982 113.18888,99.658792 C 112.1791,99.656352 111.36791,99.267702 111.24975,98.729722 C 111.22634,98.623152 111.17293,98.535932 111.13106,98.535932 C 111.0892,98.535932 110.5206,98.373792 109.86752,98.175622 C 109.21444,97.977442 108.62951,97.800642 108.56768,97.782712 C 108.46117,97.751842 108.45534,98.073432 108.45654,103.90814 L 108.4578,110.06615 L 110.97777,113.6696 C 118.8789,124.96788 120.44439,127.18152 120.54539,127.19847 C 120.65239,127.21641 123.4109,131.09128 123.4691,131.30538 C 123.54777,131.59482 123.1246,131.87441 122.60943,131.87337 C 122.22426,131.8726 121.73011,131.64927 121.45565,131.35193 C 121.13001,130.99914 120.00432,129.35803 119.89712,129.07977 C 119.84267,128.93845 118.39393,126.81387 116.67772,124.35849 C 114.9615,121.9031 112.41658,118.26261 111.02236,116.26851 L 108.48739,112.6429 L 108.45323,115.62616 C 108.42703,117.91508 108.39933,118.64866 108.33421,118.77797 C 108.19939,119.04569 107.85731,119.19102 106.6451,119.49553 C 105.66161,119.74258 105.49848,119.76828 105.41887,119.68868 C 105.33927,119.60907 105.31608,119.64858 105.24454,119.98567 C 105.19916,120.19953 105.12209,120.40763 105.07328,120.44815 C 105.01632,120.49541 104.83332,120.50966 104.56241,120.48791 L 104.14027,120.45402 L 104.18522,121.36244 C 104.20995,121.86206 104.24978,122.52678 104.27375,122.83959 C 104.31711,123.40541 104.3165,123.40872 104.15414,123.47752 C 104.06437,123.51556 103.77903,123.54868 103.52005,123.55111 C 103.14346,123.55465 103.03281,123.53318 102.96749,123.44386 C 102.8644,123.30287 102.7736,121.99774 102.85967,121.89404 C 102.89988,121.84559 102.86742,121.1427 102.76727,119.89321 C 102.68236,118.83384 102.61227,117.88036 102.61153,117.77438 L 102.61017,117.58167 L 102.14431,117.60414 C 101.55601,117.63251 100.61573,117.50707 100.25377,117.35191 L 99.976232,117.23294 L 99.974672,116.82919 L 99.973112,116.42543 L 97.558182,114.69108 C 96.229962,113.73719 94.990842,112.84827 94.804582,112.71571 L 94.465912,112.47468 L 89.43517,118.91441 C 86.66824,122.45626 83.98604,125.88889 83.47468,126.54248 C 82.96334,127.19608 82.42017,127.8669 82.26766,128.0332 C 82.09744,128.2188 81.99036,128.39674 81.99036,128.49398 C 81.99036,128.65652 81.90548,128.78009 80.98793,129.9534 C 80.43871,130.65571 80.12673,130.96963 79.82071,131.12788 C 79.58439,131.25009 79.09425,131.31899 78.84722,131.26473 C 78.58013,131.20606 78.26461,130.9326 78.26516,130.76024 C 78.26542,130.6779 78.84237,129.87655 79.68316,128.79071 C 81.21753,126.80916 81.34182,126.65954 81.41566,126.70518 C 81.4426,126.72184 85.60084,121.44292 90.6562,114.97427 L 99.847762,103.21309 L 99.847762,102.7741 C 99.847762,102.37573 99.863502,102.32275 100.01801,102.20121 C 100.11164,102.12756 100.29953,102.0495 100.43553,102.02775 L 100.68282,101.98821 L 100.6821,94.496972 L 100.68139,87.005712 L 100.34487,86.877242 L 100.00835,86.748772 L 99.991042,85.311562 C 99.979932,84.388552 99.997552,83.845662 100.04031,83.794142 C 100.07693,83.750022 100.27983,83.665392 100.49121,83.606082 L 100.87552,83.498242 L 100.87413,69.899766 L 100.87274,56.301286 L 100.66537,56.204926 C 100.46273,56.110776 100.45489,56.091286 100.32209,55.351726 C 100.24733,54.935466 100.1736,54.582286 100.15821,54.566916 C 100.14283,54.551536 98.445222,57.327716 96.385742,60.736206 C 94.326262,64.144686 92.579732,66.976536 92.504562,67.029176 C 92.270282,67.193286 91.899442,67.151636 91.684952,66.937146 C 91.289302,66.541506 91.103722,66.899176 95.351702,59.870486 L 99.206212,53.492802 L 99.003532,53.261972 C 98.314992,52.477752 98.244342,51.140262 98.831582,50.006222 C 99.340352,49.023702 100.07156,48.376142 101.0941,48.002492 C 101.23885,47.949592 101.64433,47.887402 101.99516,47.864272 L 102.63303,47.822232 L 107.88941,39.124382 C 110.78041,34.340552 113.13267,30.413422 113.11665,30.397402 C 113.10063,30.381382 112.0814,30.114202 110.85169,29.803672 C 102.79299,27.768702 96.020262,25.410462 90.88695,22.852062 C 87.47056,21.149352 85.2961,19.678962 84.03167,18.216452 C 82.92666,16.938322 82.72188,15.745562 83.43961,14.767842 C 84.15145,13.798132 86.08494,13.023082 88.7993,12.619392 C 91.761432,12.178872 96.514892,12.132222 101.32517,12.496462 C 113.70361,13.433792 129.4225,16.955582 140.25171,21.217912 C 147.11074,23.917592 151.43444,26.603072 152.61276,28.895482 C 153.44729,30.519102 152.51162,31.900152 149.98231,32.777942 C 148.78278,33.194232 146.70095,33.593352 145.18175,33.698302 C 144.8373,33.722092 144.55546,33.760742 144.55546,33.784172 C 144.55546,33.807612 144.70722,33.865302 144.8927,33.912362 C 145.4717,34.059292 147.81481,34.845262 148.92346,35.264452 C 156.23761,38.029902 162.13217,42.076122 162.95354,44.895122 C 163.16081,45.606552 163.11586,45.848362 162.44495,47.631182 C 162.10934,48.523042 161.83498,49.277752 161.83526,49.308322 C 161.83559,49.338872 162.81114,49.726142 164.00323,50.168912 L 166.17059,50.973932 L 166.19144,50.747832 C 166.21735,50.467002 166.30266,50.359522 166.49964,50.359522 C 166.65225,50.359522 166.65237,50.358792 166.65237,49.564242 L 166.65237,48.768962 L 166.15455,48.713122 L 165.65673,48.657282 L 165.6375,48.360492 C 165.61288,47.981092 165.59992,47.984572 167.03779,47.984572 C 168.47564,47.984572 168.46269,47.981092 168.43806,48.360492 L 168.41883,48.657282 L 167.88701,48.714502 L 167.35514,48.771722 L 167.37311,49.549032 L 167.39106,50.326332 L 167.58379,50.359322 C 167.76068,50.389602 167.77805,50.415952 167.7955,50.681022 C 167.81417,50.963752 167.82085,50.971762 168.1167,51.066112 L 168.41883,51.162462 L 168.41883,51.868182 L 168.41883,52.573902 L 168.24218,52.658572 L 168.06553,52.743232 L 168.06553,54.122806 C 168.06553,55.377946 168.07569,55.506136 168.17796,55.544136 C 168.23979,55.567116 168.53605,55.744896 168.83636,55.939226 C 170.08728,56.748676 169.96771,56.701326 170.5913,56.634476 C 170.93792,56.597316 171.30419,56.598506 171.57656,56.637676 C 172.06899,56.708476 172.03178,56.724056 173.18913,55.962326 C 173.5164,55.746936 173.84161,55.552466 173.91179,55.530196 C 174.03386,55.491446 174.03941,55.430246 174.03941,54.124546 L 174.03941,52.759412 L 173.83064,52.667522 L 173.62188,52.575632 L 173.60301,51.997522 C 173.57702,51.201852 173.59754,51.144952 173.94446,51.052172 C 174.22817,50.976282 174.23213,50.971482 174.23213,50.701332 C 174.23213,50.446212 174.24643,50.423722 174.4409,50.373442 L 174.64966,50.319432 L 174.6676,49.545582 L 174.68558,48.771722 L 174.15375,48.714502 L 173.62188,48.657282 L 173.60265,48.360832 C 173.58406,48.073772 173.5899,48.063092 173.78732,48.023602 C 174.05224,47.970622 176.01788,47.970622 176.2828,48.023602 C 176.48023,48.063092 176.4861,48.073772 176.46747,48.360832 L 176.44824,48.657282 L 175.91827,48.714312 L 175.38835,48.771342 L 175.38835,49.535332 C 175.38835,50.206882 175.40195,50.303522 175.50075,50.334052 C 175.74757,50.410322 175.80721,50.479452 175.83798,50.725032 L 175.87013,50.981142 L 178.08097,50.156332 C 179.29699,49.702692 180.30036,49.323042 180.31072,49.312682 C 180.32109,49.302322 179.98142,48.370172 179.55592,47.241212 C 178.8444,45.353492 178.78237,45.153952 178.78399,44.757592 C 178.78719,43.964302 179.25492,43.102872 180.23719,42.081072 C 181.75085,40.506522 183.8735,39.044862 186.88647,37.502422 C 190.75346,35.522772 195.73956,33.843442 199.60504,33.218792 C 201.27328,32.949192 201.62307,32.921162 203.29855,32.922752 C 204.7931,32.924172 205.03248,32.939282 205.57572,33.066482 C 206.21808,33.216902 206.88332,33.495912 207.22991,33.760272 C 207.52228,33.983312 207.69955,34.316902 208.11351,35.423292 C 208.41427,36.227022 208.5165,36.427802 208.7349,36.643762 C 208.87864,36.785922 209.03436,36.975782 209.081,37.065682 C 209.20729,37.309272 209.35228,37.921502 209.43759,38.571422 C 209.50521,39.086932 209.85569,40.058702 212.71703,47.665732 C 215.24316,54.381356 215.92079,56.245216 215.92079,56.477656 L 215.92079,56.772436 L 217.0319,56.793796 C 218.25237,56.817256 218.39185,56.856536 218.60876,57.237796 L 218.715,57.424586 L 219.59487,57.424996 L 220.47479,57.425396 L 220.49418,57.089066 C 220.51265,56.768826 220.52625,56.745786 220.77741,56.607556 C 221.03196,56.467476 221.04269,56.448476 221.08254,56.067216 C 221.12841,55.628626 221.18372,55.529486 221.41491,55.471446 L 221.5723,55.431956 L 221.58898,52.207612 L 221.60561,48.983262 L 221.8373,48.928472 C 221.96727,48.897742 222.1647,48.898472 222.28697,48.930152 L 222.50489,48.986612 L 222.52157,52.202802 L 222.53817,55.419006 L 222.72818,55.497696 C 222.9389,55.584976 222.95808,55.628356 223.0174,56.150766 C 223.05335,56.467466 223.07898,56.519216 223.21697,56.553866 C 223.49124,56.622706 223.62903,56.817436 223.62903,57.136336 L 223.62903,57.425396 L 224.91181,57.425396 C 230.64725,57.425396 239.00701,57.970836 242.25722,58.557116 C 243.76977,58.829956 244.76067,59.170136 244.86963,59.453966 C 244.93757,59.631086 244.8287,59.839896 244.60033,59.970406 L 244.3695,60.102326 L 244.60167,60.279426 C 245.10693,60.664806 244.76043,61.057966 243.63827,61.372446 C 241.78653,61.891416 237.66204,62.343266 232.49349,62.593406 C 229.96967,62.715546 226.51601,62.821456 225.06211,62.821286 L 223.95793,62.821156 L 223.93801,63.062036 C 223.92003,63.279146 223.88642,63.319156 223.59749,63.467466 L 223.27694,63.632026 L 223.18645,64.174056 C 223.11773,64.585726 223.09032,65.652706 223.07247,68.610366 L 223.04895,72.504626 L 223.21588,72.614016 C 223.30771,72.674166 223.4376,72.843986 223.50453,72.991386 C 223.62074,73.247386 223.62624,73.497036 223.62757,78.570586 L 223.62903,83.881822 L 223.89647,84.062712 C 224.35874,84.375372 224.42854,84.594962 224.45421,85.817362 C 224.48259,87.169892 224.42477,87.453662 224.04166,87.842302 C 223.8465,88.040292 223.75702,88.185782 223.75605,88.306852 C 223.75399,88.566512 223.5355,89.003252 223.34533,89.127862 L 223.17936,89.236602 L 223.17936,96.541862 L 223.17936,103.84711 L 223.43525,103.92378 C 223.76406,104.02229 223.82168,104.14052 223.82168,104.71607 L 223.82168,105.18772 L 228.90403,112.44458 C 231.69929,116.43585 235.2545,121.51185 236.80448,123.72457 C 238.35441,125.93729 239.67342,127.76126 239.7355,127.77781 C 239.90191,127.82218 242.51416,131.58599 242.51416,131.78141 C 242.51416,132.02595 242.18486,132.19497 241.71122,132.19353 C 241.25268,132.19213 240.89649,132.04461 240.60986,131.73732 C 240.29899,131.40406 239.16703,129.75017 239.07669,129.4973 C 239.03256,129.37365 238.2661,128.23187 237.37355,126.96001 C 236.48096,125.68815 234.98431,123.54911 234.04768,122.20661 C 227.82757,113.29105 228.24688,113.87496 228.13416,113.97201 C 228.03472,114.05765 225.41652,116.20669 225.37667,116.23538 C 225.36635,116.24282 225.54904,116.43248 225.7827,116.65683 C 226.01633,116.88119 226.17654,117.07508 226.13872,117.08769 C 226.09046,117.10377 226.06993,118.94194 226.06993,123.24351 C 226.06993,127.31576 226.09151,129.36307 226.13415,129.33671 C 226.1695,129.31488 226.19841,129.15419 226.19841,128.97963 C 226.19841,128.80506 226.22011,128.66337 226.24659,128.66475 C 226.27307,128.66612 226.54046,128.78897 226.84077,128.93774 C 227.4688,129.24888 227.57922,129.40639 227.69586,130.15776 C 227.75162,130.51676 227.74732,130.60835 227.67145,130.67851 C 227.62088,130.72533 226.30882,131.05802 224.75581,131.41783 C 223.20284,131.77763 221.9203,132.0839 221.90576,132.09841 C 221.89127,132.11293 221.98399,132.24701 222.11186,132.39638 C 222.23972,132.54574 222.3443,132.73291 222.3443,132.81231 C 222.3443,133.04001 222.05614,133.22294 221.69745,133.22294 C 221.27332,133.22294 221.10712,133.14667 220.7074,132.76864 L 220.36243,132.44237 L 219.43413,132.65511 C 218.77383,132.80643 218.51486,132.89129 218.53701,132.94905 C 218.55414,132.9937 218.53746,133.03023 218.49988,133.03023 C 218.46231,133.03023 217.68596,132.50023 216.77471,131.85245 C 212.61002,128.89193 210.44173,127.37519 210.41392,127.40298 C 210.39731,127.41958 210.41747,127.53531 210.4587,127.66017 C 210.5253,127.86205 210.54713,127.87869 210.6562,127.8106 C 210.73512,127.76131 210.79856,127.75635 210.83439,127.79667 C 210.9276,127.90161 213.03022,133.05479 213.03022,133.17828 C 213.03022,133.35962 212.86688,133.62808 212.66711,133.77505 C 211.71038,134.47899 210.67722,134.32249 210.2224,133.40471 C 210.14652,133.25174 209.88014,132.62685 209.63032,132.01605 C 209.26625,131.12603 209.17624,130.83903 209.17684,130.57076 C 209.17741,130.30687 208.99723,129.71377 208.32572,127.76932 L 207.47386,125.30263 L 207.01155,124.95902 C 206.75732,124.77004 206.535,124.61543 206.51754,124.61543 C 206.50005,124.61543 205.77954,125.51937 204.91639,126.62419 C 204.05324,127.729 203.30301,128.66948 203.2492,128.71412 C 203.19539,128.75877 203.13267,128.89519 203.10975,129.01728 C 203.08202,129.16518 202.80827,129.57333 202.2894,130.24027 C 201.46268,131.30297 201.15712,131.5606 200.61456,131.65227 C 200.12913,131.73427 199.49463,131.4134 199.55442,131.11616 C 199.56459,131.06559 200.22331,130.19029 201.0182,129.17106 C 202.00282,127.90862 202.50444,127.31517 202.59198,127.30931 C 202.66268,127.30457 202.59874,127.26739 202.45002,127.2267 C 202.04999,127.11727 202.04108,127.09674 202.11137,126.44455 C 202.23028,125.34081 202.4314,122.62503 202.4314,122.12317 L 202.4314,121.61794 L 200.68096,120.1696 C 199.37194,119.08648 198.9119,118.73955 198.85667,118.79381 C 198.6769,118.9703 190.09846,131.29945 190.01282,131.50446 C 189.89718,131.78117 189.06994,132.98113 188.79657,133.26864 C 188.52787,133.55121 188.24449,133.67259 187.8534,133.67259 C 187.58504,133.67259 187.49228,133.64189 187.35951,133.50914 C 187.26962,133.41925 187.21153,133.30553 187.23035,133.25644 C 187.30927,133.0507 189.43014,130.07763 189.49873,130.07657 C 189.53991,130.07593 189.86977,129.64906 190.23179,129.12795 C 190.59373,128.60684 190.99315,128.03727 191.11939,127.86223 C 191.39262,127.48337 191.33003,127.5144 190.61211,128.11376 C 187.48649,130.72311 183.46659,132.80744 179.40308,133.92565 C 177.0455,134.5744 174.98318,134.89804 172.43356,135.01935 C 170.94388,135.09022 170.98509,135.09026 169.41447,135.01629 z M 224.65678,126.41401 C 224.65678,125.60143 224.6428,124.9366 224.62576,124.9366 C 224.56102,124.9366 220.45839,125.9018 220.43847,125.9217 C 220.41661,125.94359 224.52478,127.87992 224.60859,127.88722 C 224.63511,127.88953 224.65678,127.22659 224.65678,126.41401 z M 204.44457,125.00084 L 205.37647,123.81249 L 205.21747,123.68402 C 205.07041,123.56514 205.05997,123.52006 205.07782,123.08057 L 205.09713,122.60559 L 205.758,122.44824 C 206.5037,122.27066 206.45899,122.3529 206.19589,121.64286 L 206.05843,121.27182 L 205.78995,121.46927 C 205.55001,121.64575 205.5194,121.69848 205.50198,121.96558 C 205.48543,122.22046 205.45409,122.28101 205.28893,122.37712 C 205.04709,122.51788 204.26828,122.64251 203.81026,122.61374 L 203.46416,122.59201 L 203.42925,122.91319 C 203.31698,123.94587 203.21126,125.79405 203.24588,126.11835 L 203.28637,126.49715 L 203.3995,126.34317 C 203.46173,126.25848 203.93197,125.65443 204.44457,125.00084 z M 218.169,120.61493 L 218.169,119.31231 L 218.58677,118.89824 C 218.9562,118.53209 219.06956,118.4617 219.56637,118.28987 L 220.1282,118.09555 L 220.14711,117.80638 L 220.16602,117.5172 L 219.66537,117.15975 C 219.38996,116.96314 218.22779,116.128 217.08271,115.30389 C 215.6338,114.26108 214.97589,113.82295 214.91888,113.86288 C 214.87386,113.89444 214.40823,114.46947 213.88425,115.14073 C 212.16131,117.34798 211.21819,118.56625 211.20876,118.59676 C 211.19078,118.65515 213.43021,121.47753 213.52269,121.51303 C 213.59208,121.53965 216.72223,121.81335 218.05656,121.90945 C 218.16022,121.91692 218.169,121.81578 218.169,120.61493 z M 211.11847,121.35574 C 211.47782,121.38449 211.80574,121.3998 211.84716,121.38977 C 211.91582,121.37315 210.5749,119.58882 210.47278,119.56091 C 210.4361,119.55089 208.86139,121.53685 208.8045,121.66486 C 208.79446,121.68747 209.164,121.6154 209.6257,121.50471 C 210.40841,121.31706 210.50927,121.307 211.11847,121.35574 z M 202.5406,120.04139 C 202.70555,119.85766 202.9516,116.33995 202.93035,114.47027 L 202.91314,112.96038 L 201.18558,115.42841 C 200.23541,116.78582 199.45498,117.92969 199.45126,117.97036 C 199.44749,118.01101 200.10929,118.59923 200.92187,119.2775 C 202.33896,120.46039 202.40014,120.5034 202.4207,120.33091 C 202.43249,120.232 202.48646,120.10172 202.5406,120.04139 z M 205.00267,120.03641 C 205.03511,118.71241 205.02365,118.19188 204.96222,118.1919 C 204.91769,118.1919 204.87691,118.447 204.85197,118.88243 C 204.83015,119.26222 204.79249,119.7281 204.76824,119.91772 C 204.725,120.2561 204.72674,120.26111 204.8625,120.18846 C 204.93854,120.14775 205.00166,120.07933 205.00267,120.03641 z M 208.41046,118.62549 C 208.866,118.29869 209.23183,118.00109 209.22348,117.96414 C 209.20668,117.89033 205.43186,113.05025 205.40894,113.07317 C 205.38838,113.09376 206.17934,115.31855 206.24112,115.41386 C 206.2697,115.45795 206.36008,115.49402 206.44203,115.49402 C 206.65095,115.49402 206.69659,115.56839 206.98965,116.38654 C 207.25258,117.12057 207.25501,117.15937 207.05217,117.38896 C 206.9428,117.51276 206.94924,117.54845 207.22967,118.36855 C 207.38976,118.83667 207.53455,119.21967 207.55152,119.21967 C 207.5684,119.21967 207.95496,118.95229 208.41046,118.62549 z M 213.84324,112.98885 C 215.67838,110.63945 217.83602,107.87531 218.63799,106.84631 L 220.0961,104.97539 L 220.0961,104.55776 C 220.0961,104.08508 220.13703,104.02718 220.55974,103.90237 L 220.83478,103.82116 L 220.8511,96.551302 L 220.86746,89.281432 L 220.61023,89.036752 C 220.38024,88.817982 220.353,88.759642 220.353,88.485642 C 220.353,88.205752 220.32656,88.152772 220.04791,87.873902 C 219.88009,87.705972 219.66663,87.478072 219.57354,87.367442 C 219.43093,87.198002 219.35959,87.166302 219.12067,87.166302 C 218.78667,87.166302 218.68302,87.249172 218.68265,87.516382 C 218.68233,87.774732 218.47875,88.099232 218.23929,88.223072 C 217.96976,88.362432 217.53809,88.348602 217.28192,88.192422 C 216.93534,87.981132 216.86273,87.719072 216.83289,86.572132 L 216.80657,85.560422 L 216.56874,85.560422 C 216.37974,85.560422 216.19964,85.650782 215.69223,86.000252 C 215.34098,86.242142 214.99581,86.454452 214.92516,86.472022 C 214.85446,86.489602 213.39134,87.475772 211.67366,88.663502 C 208.86086,90.608512 208.55351,90.838042 208.57955,90.974312 C 208.60181,91.090542 208.55444,91.166812 208.37539,91.303412 C 208.17995,91.452482 207.94544,91.875242 206.92482,93.918742 L 205.70739,96.356262 L 205.70739,97.023992 C 205.70739,97.776062 205.67674,97.839862 205.25488,97.966272 L 205.00081,98.042382 L 205.00081,102.14327 L 205.00081,106.24416 L 205.47308,106.24416 L 205.9453,106.24416 L 205.98223,105.6821 C 206.03373,104.89778 206.04115,104.88507 206.43377,104.90819 C 206.73351,104.92585 206.76274,104.94222 206.81226,105.12004 C 206.8798,105.36262 206.8802,107.80456 206.81271,108.10698 C 206.76424,108.32431 206.75165,108.33243 206.43575,108.35094 C 206.04443,108.37385 206.04908,108.38168 205.9896,107.59404 L 205.94587,107.01498 L 205.47337,107.01498 L 205.00081,107.01498 L 205.00081,108.7481 L 205.00081,110.48123 L 205.17746,110.52321 C 205.48753,110.59688 205.57892,110.72767 205.57892,111.09795 L 205.57892,111.43535 L 207.93957,114.45684 C 210.13183,117.26281 210.30754,117.47054 210.40343,117.3694 C 210.46019,117.3095 212.0081,115.33825 213.84324,112.98885 z M 220.27194,115.54641 C 220.31571,115.49371 220.46746,115.41584 220.60917,115.37337 L 220.86689,115.29616 L 220.86689,111.05922 C 220.86689,107.71295 220.85,106.82209 220.7866,106.82139 C 220.74246,106.82091 220.6472,106.80464 220.57496,106.78523 C 220.46398,106.75541 220.06658,107.23228 218.0115,109.86149 C 216.67381,111.57284 215.58266,112.99279 215.58671,113.01693 C 215.59072,113.04108 216.61421,113.79492 217.86112,114.69212 L 220.1282,116.32341 L 220.16031,115.98282 C 220.17796,115.7955 220.22821,115.59911 220.27194,115.54641 z M 105.07609,115.90565 C 105.58686,115.69899 106.0425,115.34289 106.58736,114.72456 C 106.97041,114.28985 107.0421,114.17219 107.0421,113.9781 L 107.0421,113.74772 L 106.73699,113.99944 C 106.56918,114.13789 105.91156,114.67941 105.27563,115.20283 C 104.63971,115.72624 104.09171,116.17955 104.05788,116.21018 C 103.97561,116.28463 104.60387,116.09673 105.07609,115.90565 z M 225.84327,114.53857 C 226.79817,113.7481 227.58561,113.06882 227.59314,113.02904 C 227.61015,112.93913 223.35945,106.8716 223.25511,106.83682 C 223.12049,106.79194 223.16421,109.10307 223.33929,111.28662 C 223.42711,112.38183 223.53324,113.75224 223.57518,114.33197 C 223.63891,115.21256 223.67074,115.40254 223.76868,115.48642 C 223.84921,115.55537 223.88594,115.67531 223.88594,115.86946 C 223.88594,116.12818 223.89529,116.14464 223.99652,116.06395 C 224.05733,116.01546 224.88837,115.32904 225.84327,114.53857 z M 100.34487,114.1772 L 100.68139,114.04874 L 100.6821,109.60848 L 100.68282,105.16821 L 100.4773,105.12711 C 100.34665,105.10098 100.24273,105.11561 100.19202,105.16726 C 100.14814,105.21195 98.982452,106.6938 97.601592,108.46027 C 95.341642,111.35131 95.102312,111.67981 95.205052,111.74992 C 95.267822,111.79276 96.359792,112.57674 97.631652,113.49209 L 99.944112,115.15635 L 99.976232,114.73102 L 100.00835,114.30567 L 100.34487,114.1772 z M 105.60962,113.51243 L 107.0294,112.33377 L 106.86326,111.97078 C 106.71564,111.64825 106.69642,111.52188 106.6908,110.83697 L 106.68447,110.06615 L 104.96219,107.60916 C 104.01493,106.2578 103.21377,105.15216 103.18183,105.15216 C 103.04036,105.15216 103.12742,107.68449 103.37951,110.90207 C 103.61357,113.8897 103.64624,114.17808 103.76491,114.3044 C 103.84748,114.3923 103.89458,114.53009 103.89458,114.68382 L 103.89458,114.92523 L 104.04221,114.80816 C 104.1234,114.74377 104.82874,114.16068 105.60962,113.51243 z M 107.0421,102.58846 L 107.0421,97.198422 L 106.31048,96.846612 C 105.48862,96.451432 104.91021,96.079312 104.45056,95.650072 C 104.0945,95.317562 103.91701,95.007292 103.85411,94.607422 C 103.82998,94.454032 103.77375,94.270722 103.72916,94.200062 C 103.52863,93.882282 103.49732,93.528382 103.56989,92.400022 L 103.641,91.294602 L 103.47955,90.973182 C 103.39077,90.796402 103.27628,90.496232 103.22516,90.306142 C 103.14217,89.997582 103.13176,90.605542 103.12798,95.977602 L 103.12375,101.99467 L 103.36463,102.07226 C 103.74973,102.19629 103.76611,102.22664 103.76611,102.81606 L 103.76611,103.35481 L 105.38485,105.66665 C 106.27516,106.93817 107.01226,107.97851 107.02285,107.97851 C 107.03344,107.97851 107.0421,105.55298 107.0421,102.58846 z M 201.9201,103.27725 C 202.07894,103.15984 202.11024,103.09174 202.11024,102.86352 C 202.11024,102.71327 202.13911,102.57246 202.17445,102.55063 C 202.21498,102.52558 202.23871,101.78985 202.23871,100.55555 C 202.23871,99.294792 202.21587,98.600172 202.17445,98.600172 C 202.13911,98.600172 202.11024,98.565612 202.11024,98.523392 C 202.11024,98.481162 202.0365,98.369652 201.94634,98.275592 C 201.85624,98.181532 201.70991,97.890892 201.62117,97.629722 C 201.45483,97.140192 199.60083,93.058722 199.56232,93.097252 C 199.5222,93.137382 200.18391,98.692972 200.27898,99.114052 C 200.33085,99.343692 200.44677,100.16751 200.53665,100.94475 C 200.62654,101.722 200.72732,102.56026 200.76072,102.80757 C 200.79401,103.05487 200.82227,103.29336 200.8234,103.33751 C 200.8249,103.39394 200.95989,103.41781 201.27777,103.41781 C 201.64218,103.41781 201.76692,103.39053 201.9201,103.27725 z M 206.0281,93.462212 C 206.27566,92.968062 206.47823,92.537572 206.47823,92.505552 C 206.47823,92.334192 206.24023,92.422692 205.69978,92.795092 C 205.36833,93.023462 205.08624,93.241762 205.07288,93.280182 C 205.05304,93.337302 205.50996,94.341742 205.56244,94.356312 C 205.57102,94.358692 205.78059,93.956352 206.0281,93.462212 z M 205.62309,91.231322 C 205.61228,91.075492 205.71035,90.988892 206.56843,90.396532 C 207.39847,89.823502 207.55658,89.737752 207.75725,89.751722 C 207.96617,89.766262 208.25555,89.583572 210.73074,87.874702 C 212.23885,86.833482 213.46203,85.970842 213.44891,85.957732 C 213.4358,85.944622 212.90988,85.980222 212.28015,86.036842 C 210.80739,86.169282 208.20178,86.330582 207.52896,86.330952 C 207.02641,86.331232 207.00442,86.337432 206.96616,86.490062 C 206.94422,86.577402 206.87397,86.700252 206.81004,86.763052 C 206.74606,86.825852 206.32598,87.812172 205.87652,88.954862 C 205.22152,90.620122 205.07454,91.050792 205.13584,91.124702 C 205.19403,91.194762 205.19472,91.255782 205.13872,91.378642 C 205.09818,91.467572 205.06502,91.598192 205.06502,91.668872 C 205.06502,91.787272 205.0875,91.781952 205.35007,91.601292 C 205.579,91.443802 205.63277,91.370922 205.62309,91.231322 z M 202.94529,90.866112 C 202.94529,90.740252 203.28325,90.632752 203.81244,90.590282 L 204.26208,90.554202 L 204.99628,88.683602 C 205.40003,87.654782 205.76598,86.726292 205.80942,86.620302 L 205.88842,86.427592 L 202.30422,86.427592 L 198.72006,86.427592 L 198.64637,86.631282 C 198.58519,86.800212 198.5996,86.951922 198.73075,87.520412 C 198.81768,87.897412 198.89825,88.214392 198.90971,88.224812 C 199.06248,88.363572 199.95859,88.965052 200.01325,88.965522 C 200.36515,88.968512 201.74077,89.922072 202.22413,90.498062 C 202.39115,90.697032 202.55663,90.881062 202.59198,90.907012 C 202.70332,90.988822 202.94529,90.960812 202.94529,90.866112 z M 103.4488,88.490412 C 103.68923,87.769022 104.26901,86.547642 104.56965,86.129162 L 104.79365,85.817362 L 104.47259,85.817362 C 104.19434,85.817362 104.15152,85.834502 104.15152,85.945832 C 104.15152,86.016492 104.09371,86.132112 104.02305,86.202772 C 103.95239,86.273442 103.89458,86.382622 103.89458,86.445422 C 103.89458,86.649922 103.71325,86.825242 103.41555,86.908592 L 103.12375,86.990292 L 103.13126,88.379062 C 103.13695,89.431232 103.1527,89.683962 103.19623,89.421822 C 103.22784,89.231502 103.34149,88.812372 103.4488,88.490412 z M 219.36563,85.329282 C 219.44078,85.309102 219.53568,85.219322 219.5765,85.129762 C 219.63541,85.000452 219.63371,84.973432 219.56823,84.998542 C 219.52293,85.015932 219.31963,85.067352 219.1165,85.112812 C 218.76059,85.192442 218.69812,85.233042 218.78995,85.324892 C 218.84206,85.377002 219.1782,85.379562 219.36563,85.329282 z M 104.92444,84.998372 C 104.9256,84.936542 105.23844,82.125432 105.61965,78.751486 L 106.31275,72.617026 L 106.16124,72.167376 C 105.94151,71.515296 105.71349,70.577096 105.62511,69.961436 C 105.49561,69.059376 105.6118,68.593286 106.07601,68.152676 L 106.31287,67.927846 L 106.41481,66.758726 C 106.50655,65.706466 106.53464,65.556726 106.69586,65.260536 C 106.79436,65.079546 106.95168,64.876836 107.04544,64.810066 C 107.19429,64.704076 107.2213,64.629276 107.25828,64.220616 C 107.29099,63.859226 107.34103,63.694016 107.4779,63.495626 C 108.09351,62.603246 110.24726,61.904996 113.50255,61.542406 C 115.56162,61.313056 116.82416,61.254746 119.64826,61.258556 C 121.15859,61.260596 122.39431,61.240266 122.39431,61.213396 C 122.39431,61.186516 122.4636,61.097846 122.54828,61.016336 L 122.70224,60.868156 L 122.55794,60.672356 C 122.04562,59.977176 121.79246,59.266496 121.82863,58.624946 C 121.85251,58.201496 122.14235,57.400076 125.40105,48.747212 C 128.52761,40.445242 128.95538,39.266442 129.0141,38.790752 C 129.12931,37.857412 129.30798,37.385442 129.68043,37.030712 C 129.84029,36.878442 129.99538,36.537402 130.41948,35.405562 C 130.71469,34.617712 131.03875,33.859202 131.13961,33.719942 C 131.24048,33.580702 131.32301,33.456332 131.32301,33.443572 C 131.32301,33.430812 131.07009,33.401052 130.76095,33.377442 C 129.90915,33.312382 126.81167,32.916282 124.89949,32.627892 C 121.98389,32.188182 118.96243,31.633792 115.75686,30.950372 C 115.09158,30.808542 114.53911,30.702202 114.52914,30.714082 C 114.50953,30.737442 104.5126,47.284952 104.28517,47.670502 L 104.14732,47.904172 L 104.4812,48.023792 C 105.61858,48.431282 106.13825,49.760652 105.72119,51.195862 C 105.50762,51.930842 104.74295,52.962462 104.11926,53.357032 C 103.96409,53.455202 103.8238,53.594166 103.80752,53.665816 C 103.79124,53.737476 103.68346,54.323606 103.56802,54.968326 L 103.35814,56.140536 L 103.14459,56.217756 L 102.93105,56.294976 L 102.93105,69.898706 L 102.93105,83.502452 L 103.10769,83.541002 C 103.7549,83.682312 103.89458,83.813262 103.89458,84.278802 C 103.89458,84.536182 103.92182,84.657842 103.98487,84.682032 C 104.03453,84.701092 104.09464,84.805352 104.11845,84.913732 C 104.1608,85.106572 104.16983,85.110772 104.54203,85.110772 C 104.8606,85.110772 104.92268,85.092522 104.92444,84.998372 z M 146.62254,80.010346 C 149.00958,76.408396 152.61977,73.274596 156.74256,71.225726 C 157.3601,70.918856 157.40249,70.885386 157.40249,70.705106 C 157.40249,70.433876 157.60886,70.131816 157.90966,69.962756 C 158.25892,69.766446 160.15152,69.057356 161.09601,68.768906 C 162.8935,68.219966 165.09648,67.766196 167.03779,67.545036 C 168.56905,67.370586 169.04727,67.434166 169.27985,67.843096 C 169.35916,67.982566 169.42973,68.023486 169.59153,68.023796 L 169.8007,68.024206 L 169.78422,63.062036 L 169.76778,58.099866 L 169.2285,57.919086 C 168.93187,57.819666 168.54888,57.721686 168.37738,57.701386 L 168.06553,57.664446 L 168.06553,59.925846 C 168.06553,61.298946 168.0405,62.234026 168.00179,62.306346 C 167.84964,62.590636 166.75614,62.688126 166.28739,62.459186 L 166.04215,62.339386 L 166.01,59.913906 L 165.9779,57.488416 L 165.76913,57.361496 L 165.56037,57.234576 L 165.56037,56.504886 C 165.56037,55.738956 165.59122,55.650896 165.89761,55.542236 C 165.99992,55.505946 166.01,55.378966 166.01,54.129056 L 166.01,52.755742 L 165.76913,52.650772 C 165.63665,52.593032 164.64644,52.219152 163.5687,51.819912 L 161.60918,51.094022 L 161.6312,51.325042 C 161.65667,51.591982 161.37992,52.472852 161.18428,52.747602 C 161.03305,52.959962 160.7512,53.121632 160.5322,53.121632 C 160.38829,53.121632 160.19343,53.616456 157.14866,61.713096 C 155.22926,66.817196 153.84376,70.412226 153.73533,70.569826 C 153.07017,71.536736 150.82733,72.070276 148.15263,71.897856 C 147.60503,71.862556 147.15228,71.836496 147.14652,71.839936 C 147.14076,71.843376 147.11581,72.308686 147.09107,72.873966 L 147.04608,73.901726 L 147.24254,74.146986 C 147.66131,74.669846 147.67426,75.263306 147.29183,76.406906 C 147.04518,77.144496 146.41926,78.505256 146.09099,79.017546 C 145.9248,79.276906 145.88781,79.423246 145.80697,80.141656 C 145.75584,80.595926 145.69839,81.097676 145.6793,81.256652 L 145.6446,81.545712 L 145.85479,81.198696 C 145.9704,81.007846 146.31589,80.473076 146.62254,80.010346 z M 190.06611,72.167056 C 194.07775,71.357816 201.73134,70.838816 208.14834,70.940866 C 213.9326,71.032876 218.41789,71.452316 220.49755,72.095756 L 220.99536,72.249786 L 220.995,68.515056 C 220.99484,66.460956 220.9684,64.679156 220.93629,64.555506 C 220.90422,64.431856 220.85924,64.166896 220.83636,63.966726 C 220.79648,63.617826 220.78454,63.598666 220.54735,63.503766 C 220.26979,63.392726 220.0961,63.186236 220.0961,62.967456 L 220.0961,62.821156 L 218.89166,62.820346 C 217.54976,62.819446 214.68194,62.736606 212.00243,62.621356 L 210.23596,62.545376 L 209.43306,63.008146 C 208.3698,63.620926 206.31583,64.629016 205.00081,65.183446 C 201.26871,66.756986 197.52571,67.826616 194.01657,68.322376 C 192.9698,68.470256 190.04323,68.488636 189.35953,68.351626 C 188.3217,68.143646 187.49037,67.733476 187.16763,67.270186 C 187.07504,67.137296 185.77703,63.776656 184.28322,59.802096 C 182.11659,54.037636 181.54309,52.571882 181.4486,52.557082 C 181.13022,52.507202 181.04346,52.466142 180.86016,52.278672 C 180.7478,52.163772 180.58832,51.873552 180.49131,51.607512 L 180.32036,51.138782 L 179.82959,51.321512 C 179.55965,51.422022 178.71735,51.735302 177.95777,52.017702 C 177.19818,52.300102 176.45387,52.580432 176.30369,52.640662 L 176.03071,52.750172 L 176.03071,54.119936 C 176.03071,55.431916 176.0361,55.491396 176.15879,55.530336 C 176.44472,55.621086 176.48035,55.727276 176.48035,56.488616 C 176.48035,57.248546 176.44909,57.337216 176.14311,57.445726 C 176.03877,57.482746 176.03071,57.658346 176.03071,59.894956 L 176.03071,62.304306 L 175.87718,62.404896 C 175.64845,62.554776 175.08982,62.623996 174.66152,62.555526 C 173.98373,62.447196 174.03941,62.675666 174.03941,60.002486 L 174.03941,57.664366 L 173.69521,57.699896 C 173.50592,57.719426 173.10847,57.818106 172.81197,57.919186 L 172.27294,58.102946 L 172.2565,63.054746 L 172.24006,68.006556 L 172.66192,68.040416 C 173.05681,68.072116 173.10706,68.060286 173.44656,67.855846 C 174.0739,67.478096 174.33465,67.447046 175.53067,67.607666 C 176.76373,67.773266 177.16021,67.878866 177.38217,68.100846 C 177.49032,68.209006 177.59401,68.373366 177.61255,68.466066 C 177.64446,68.625546 177.69175,68.644546 178.49255,68.819216 C 181.48046,69.470956 184.64365,70.717086 187.20383,72.250986 L 187.93872,72.691296 L 188.45641,72.539316 C 188.74114,72.455726 189.46549,72.288216 190.06611,72.167056 z M 226.19841,123.55555 L 226.19841,122.5599 L 226.41612,122.5599 C 226.53589,122.5599 226.69339,122.61049 226.76619,122.67232 C 227.02982,122.89622 227.27316,124.02004 227.11262,124.27231 C 227.07439,124.3324 226.38765,124.55119 226.23732,124.55119 C 226.2159,124.55119 226.19841,124.10315 226.19841,123.55555 z"
+       id="path2384"
+       sodipodi:nodetypes="csscccccccccsccccccsssssssssssssscccsscccccccccssssccccccccccccssccccccsssccccccsscccscccscccssssscccsssssscccssssscccsssssscccccccccccssssssssscccscccccccscccccssssscccsscccssssssssssssssssscccscccccscccccccscccccccsssssscccccsscccccccsscccccscccssssssssssssssccccccccssccccccccccsscccsscccsscccccccccscccsssccccccccsssssssssssssssssssssssscccsssssssssssscccssssssssssscccssssssssssssccsssccccccccccsscccccccccccccccssssssccsssscccccsssccssssccssssssssccccccccccssssssscccsssssccccccccccssssccccccccccscccccsssscccccscccssccsssssssccccccssscccccccccccssscccccccssscccsccccccsccsssssssssssssccssssccsssssssssssssccccccccccssssscccccssscccsccsssscccccscccssssssscccssssssssssscccssscccccccssssccssssssccccccccscccccccsccccccsssssscccssscccccscccsssccccccssssssscccscccssscccsccccccccssssscccccccsssc" />
+    <path
+       style="opacity:1;fill:#000000;stroke:none;stroke-opacity:1"
+       d="M 29.392548,172.30403 C 29.413158,172.259 29.393148,172.22657 29.348058,172.23197 C 29.302978,172.23725 28.986438,172.22663 28.644678,172.20826 C 28.302918,172.18996 27.940038,172.18718 27.838278,172.20202 C 27.736498,172.21691 27.530668,172.19938 27.380868,172.16302 C 27.142638,172.10534 27.127088,172.11441 27.256808,172.23591 C 27.459358,172.42554 27.352658,172.42327 26.578558,172.2214 C 25.695228,171.99111 24.341588,171.46425 23.723018,171.11 C 23.026358,170.711 20.671508,168.83958 20.236468,168.33913 C 20.038098,168.11098 19.844538,167.90511 19.806308,167.88163 C 19.540958,167.71878 16.969278,164.27866 15.590168,162.24178 C 14.446448,160.55255 13.640618,159.21826 12.216858,156.65632 C 11.778008,155.86661 11.334758,155.17173 11.231908,155.11211 C 11.072198,155.01957 11.016758,155.04814 10.852338,155.30785 C 10.746418,155.47509 10.666718,155.66893 10.675218,155.73855 C 10.699118,155.93426 10.505798,155.91273 10.215298,155.68728 C 9.9335976,155.4687 9.3891576,154.51725 9.3448476,154.16613 C 9.3216576,153.98221 9.3626376,153.95661 9.6547476,153.9726 C 9.8398776,153.98274 10.097648,154.00796 10.227558,154.02865 C 10.414288,154.05842 10.458608,154.02563 10.439268,153.87223 C 10.425788,153.7655 10.449578,153.62982 10.492118,153.57069 C 10.537738,153.50731 10.286498,152.84471 9.8798276,151.95584 C 8.5063776,148.95373 7.1336776,145.18637 6.1711376,141.77742 C 5.6962776,140.0956 5.2182576,136.31548 5.3149076,135.00638 C 5.7013276,129.77242 8.1543876,124.79628 12.086668,121.26967 C 12.536928,120.86585 14.304718,119.51023 14.396098,119.4987 C 14.426838,119.49482 14.794698,119.28638 15.213508,119.03548 C 16.053178,118.53248 17.844668,117.73142 19.053178,117.31857 C 21.475148,116.4912 24.646498,115.85918 31.036568,114.9304 C 35.218968,114.32248 36.094778,114.1682 37.023858,113.87572 C 38.874758,113.29301 40.151808,112.58995 41.528858,111.39553 C 42.572218,110.49054 42.911848,110.09338 45.128888,107.18547 C 48.529128,102.72566 50.611428,100.55463 53.992208,97.944362 C 54.806788,97.315442 56.808778,96.119462 57.954018,95.577602 C 59.679478,94.761202 60.975158,94.386962 62.916998,94.144132 C 65.741828,93.790872 67.015168,94.072802 68.017088,95.273342 C 68.177298,95.465292 68.373538,95.614092 68.453208,95.604062 C 68.532898,95.593992 68.684818,95.678982 68.790828,95.792902 L 68.983568,96.000032 L 69.278168,95.564582 C 69.451478,95.308502 69.634308,95.144262 69.722108,95.165852 C 69.908058,95.211532 70.082348,95.717212 69.972078,95.891052 C 69.919018,95.974662 69.932158,96.028262 70.009488,96.043642 C 70.157638,96.073092 70.466178,97.005512 70.369158,97.130562 C 70.330118,97.180882 70.108308,97.153592 69.876268,97.069942 C 69.349668,96.880112 69.186728,96.897842 69.217468,97.141602 C 69.230728,97.246592 69.147588,97.413192 69.032748,97.511842 C 68.917908,97.610502 68.788418,97.898322 68.745038,98.151432 C 68.621868,98.869882 68.153978,99.809337 67.639388,100.3714 C 67.380958,100.65366 66.582348,101.36711 65.864718,101.95687 C 63.594478,103.82252 61.992518,105.3949 61.221328,106.51452 C 60.451958,107.63148 60.363778,107.78502 60.119138,108.4332 C 59.902538,109.00706 59.886558,109.17391 59.979258,109.89092 C 60.067488,110.57301 60.139478,110.78274 60.436298,111.22191 C 61.019568,112.08487 61.486878,112.36501 62.546518,112.48693 C 62.992988,112.5383 63.084168,112.5181 63.347058,112.30966 C 63.519148,112.17323 63.852118,112.03136 63.975508,111.93065 C 64.752798,111.38731 65.872358,110.64256 66.866088,110.05438 C 67.756058,109.38619 68.775338,108.75654 69.822098,108.15153 C 71.385898,107.0664 73.199748,105.75022 74.871218,104.61988 C 76.683798,103.42581 78.110688,102.44906 79.838298,101.30511 C 80.962718,100.52587 82.426918,99.627187 83.656828,98.783592 C 84.841138,97.948602 86.279165,97.004302 87.575351,96.187582 C 88.917361,95.124622 90.400581,94.130752 91.886072,93.229972 C 92.583272,92.754192 93.362348,92.218012 94.110061,91.702122 C 95.652661,90.654392 95.446621,90.772582 96.337251,90.204712 C 97.696301,89.181292 99.494021,88.093502 101.01457,87.089302 C 102.59663,85.905642 105.01996,84.261722 106.41682,83.409412 C 106.55922,83.333692 107.69419,82.588642 108.93895,81.753782 C 110.42142,80.759502 111.23377,80.255222 111.35944,80.167362 C 112.9617,78.998272 115.29401,77.498164 116.99124,76.512044 C 118.72273,75.198054 120.90735,73.793624 122.84301,72.529714 C 123.83216,71.781044 124.99253,71.036574 126.05922,70.314514 C 127.72854,69.196374 129.10452,68.239764 129.11693,68.188684 C 129.47828,67.953794 129.63911,67.930454 129.87946,67.574684 C 130.19292,67.157324 130.40393,66.315754 130.39458,65.520214 C 130.39116,65.227794 130.23482,64.450304 130.03151,63.714514 C 129.38886,61.388604 129.62634,61.020624 132.52309,59.853714 L 133.37171,59.511874 L 133.22478,59.260914 C 132.85006,58.620824 132.23309,58.248614 131.44902,58.189574 C 131.07162,58.161134 130.38392,57.685544 130.16234,57.299714 C 130.06442,57.129124 129.95309,56.742444 129.91497,56.440394 C 129.85585,55.971824 129.88645,55.825334 130.12339,55.442464 C 130.2761,55.195674 130.47669,54.945494 130.56911,54.886514 C 130.66154,54.827544 130.88032,54.529794 131.0553,54.224844 C 131.27777,53.837154 131.48902,53.614654 131.75763,53.485044 C 132.26014,53.242594 133.00646,53.222894 133.41283,53.441354 C 133.59118,53.537244 133.86289,53.626044 134.01663,53.638704 C 134.17032,53.651384 134.40938,53.670564 134.54782,53.681374 C 134.91261,53.709844 135.45919,54.095114 135.75785,54.534254 C 135.96768,54.842754 136.01719,55.020544 136.01773,55.466794 C 136.0184,56.024004 135.9202,56.245104 135.27532,57.138394 C 134.97523,57.554074 134.85173,58.053834 134.91779,58.585094 L 134.95715,58.901694 L 135.3697,58.706644 C 135.59662,58.599374 136.70567,58.138984 137.83427,57.683544 C 138.96284,57.228124 139.90166,56.835604 139.92054,56.811264 C 139.96016,56.760214 139.75665,56.529304 139.34126,56.153974 C 139.01119,55.855704 138.76885,55.766624 137.91978,55.631464 C 137.24277,55.523694 136.87806,55.248334 136.51747,54.572784 C 136.07482,53.743494 136.27322,52.994654 137.13156,52.254974 C 137.36133,52.033064 137.39145,51.781224 137.51381,51.472634 C 137.6659,51.057144 138.0395,50.823534 138.68023,50.743334 C 139.07281,50.694194 139.3341,50.729414 139.65339,50.874524 C 139.89342,50.983614 140.21759,51.058214 140.37373,51.040274 C 141.10522,50.956254 141.95347,51.578534 142.21445,52.390594 C 142.40841,52.994204 142.31996,53.392624 141.83562,54.096774 C 141.39472,54.737804 141.38356,54.775644 141.43132,55.466434 L 141.48046,56.176834 L 141.76481,56.090654 C 141.92122,56.043244 142.64379,55.764274 143.37052,55.470714 C 144.09723,55.177154 145.10122,54.771844 145.6016,54.570044 C 146.10196,54.368234 146.53226,54.176154 146.55782,54.143224 C 146.6424,54.034244 146.08311,53.312214 145.81122,53.179354 C 145.66435,53.107584 145.27123,53.013754 144.93762,52.970884 C 144.25083,52.882594 143.91517,52.681794 143.54112,52.135414 C 143.27838,51.751654 143.20452,51.235934 143.22568,51.044984 C 143.26069,50.728844 143.3242,50.425834 143.35778,50.198814 C 143.37216,50.101614 143.43868,49.941884 143.71233,49.724584 C 143.99934,49.496654 144.13148,49.315264 144.11547,49.171114 C 144.08467,48.893474 144.42947,48.453974 144.90768,48.161354 C 145.36662,47.880534 145.8322,47.885294 146.40477,48.176684 C 146.62513,48.288824 146.91434,48.366834 147.04748,48.350054 C 147.61054,48.279004 148.10641,48.546834 148.63852,49.209424 C 148.87548,49.504514 148.92942,49.666914 148.95599,50.165154 C 148.98464,50.702284 148.94879,50.820454 148.61507,51.288704 C 148.40993,51.576474 148.19683,51.975394 148.14148,52.175134 C 148.02376,52.600024 148.12027,53.610174 148.26727,53.491554 C 148.32026,53.448774 149.38764,53.012004 150.63923,52.520924 C 153.51049,51.394374 153.35698,51.463694 153.33667,51.302714 C 153.28636,50.903794 152.00212,50.193714 151.45564,50.262644 C 151.14939,50.301284 150.2806,49.634014 150.03289,49.169914 C 149.87256,48.869544 149.8337,48.692384 149.88326,48.487914 C 149.9201,48.335964 149.91591,48.126044 149.87397,48.021404 C 149.78209,47.792224 150.14081,47.197214 150.53391,46.926714 C 150.68904,46.819934 150.79612,46.656224 150.78233,46.546914 C 150.74089,46.218454 151.16581,45.694664 151.66897,45.453984 C 152.22054,45.190134 152.81937,45.216304 153.1725,45.519674 C 153.31856,45.645174 153.51001,45.683254 153.8067,45.645824 C 154.66577,45.537444 155.64466,46.401624 155.75118,47.362454 C 155.8074,47.869594 155.73624,48.089494 155.32002,48.695084 C 154.94682,49.238094 154.79156,49.789314 154.85971,50.329374 L 154.92232,50.825864 L 155.44144,50.660074 C 156.63435,50.279094 158.3741,50.393664 159.38093,50.919494 C 160.03093,51.258964 160.9119,51.984594 160.87186,52.147524 C 160.84823,52.243754 160.87332,52.270234 160.93838,52.217714 C 161.08682,52.097914 161.89048,53.384854 162.1172,54.105404 C 162.53863,55.444864 162.45083,56.862904 161.8736,58.038724 C 161.14719,59.518464 159.34163,60.791184 157.67865,60.995694 C 156.63684,61.123814 156.14508,61.065884 154.98231,60.678094 C 153.71422,60.255184 153.60317,60.240684 153.17883,60.442674 C 152.36191,60.831534 150.64627,62.470714 149.88162,63.592944 C 149.35043,64.372524 147.3959,66.926584 146.88975,67.502484 C 146.19161,68.296864 145.61084,68.875714 144.56364,69.820944 C 143.22842,71.026154 142.70357,71.424954 142.40276,71.462904 C 142.27215,71.479384 141.72071,71.295464 141.17733,71.054234 C 139.50698,70.312654 138.22538,70.187904 136.77276,70.625474 C 136.0853,70.832574 134.39182,71.756094 133.87907,72.203504 C 132.05213,73.039294 131.02389,74.253024 129.468,75.496714 C 128.26735,76.404584 127.80845,76.742174 126.57043,77.628354 C 126.20721,77.888364 125.52992,78.390214 125.0653,78.743572 C 123.75808,79.729232 122.42289,80.676832 121.11284,81.658742 C 118.19679,83.327732 116.04977,85.351942 113.65123,87.130282 C 111.66273,88.217732 110.65906,89.304252 109.54941,90.146082 C 106.5028,91.785742 105.28376,93.327662 102.71091,95.195592 C 100.81023,96.253122 99.821881,97.326582 97.869921,98.733412 C 96.579331,99.584857 96.600451,99.625477 95.909241,100.19084 C 95.689661,100.35626 95.214121,100.71443 94.852441,100.98671 C 93.430598,102.05716 93.062358,102.24811 92.421812,102.70884 C 91.517012,103.41232 89.939851,104.6976 88.666591,105.54003 C 88.094231,105.94737 87.053125,106.69048 86.662935,106.97943 C 79.445418,111.72786 72.264208,117.65966 64.416138,123.16622 C 63.363488,123.70091 62.314038,124.56498 61.670948,125.59674 C 60.265078,127.84896 61.157748,130.42335 63.817528,131.78726 C 64.560238,132.16809 65.651638,132.30034 66.845468,132.15416 C 68.097098,132.00088 68.641528,131.82186 70.401038,130.9849 C 71.995968,130.22625 72.710838,130.04485 73.494908,130.19986 C 74.101458,130.31979 74.964418,130.90126 75.334948,131.43967 C 75.619768,131.85354 75.820198,132.799 75.763338,133.46039 C 75.677538,134.45814 74.930648,136.30916 74.170098,137.40885 C 73.515348,138.35558 71.982368,139.92296 70.410558,141.25273 C 67.286068,143.89606 61.630008,146.40606 55.409508,147.9097 C 52.721068,148.55957 52.032238,148.80464 50.735898,149.57243 C 49.562178,150.26763 48.611798,151.14608 47.505868,152.55807 C 46.606818,153.70593 45.687858,155.34594 45.149088,156.76417 C 45.047498,157.03156 44.932118,157.26984 44.892718,157.29367 C 44.853278,157.31751 44.826198,157.37814 44.832558,157.42842 C 44.843728,157.51704 44.535788,158.2618 43.561518,160.50246 C 43.303968,161.09482 43.098148,161.61837 43.104138,161.66594 C 43.110138,161.71352 43.079328,161.75691 43.035638,161.76245 C 42.991958,161.76797 42.888988,161.93138 42.806788,162.12565 C 42.458778,162.94818 41.487828,164.65661 40.796388,165.66304 C 39.968358,166.8683 39.137528,167.78358 37.891748,168.86297 C 35.673698,170.78472 33.867118,171.63956 31.033288,172.10833 C 30.110258,172.261 29.371908,172.34907 29.392548,172.30403 z M 131.84053,53.765784 C 131.91727,53.701274 131.93446,53.654204 131.87878,53.661224 C 131.82309,53.668264 131.71476,53.726794 131.63804,53.791304 C 131.56131,53.855834 131.5441,53.902864 131.5998,53.895844 C 131.65548,53.888814 131.76383,53.830294 131.84053,53.765784 z"
+       id="path2398"
+       sodipodi:nodetypes="csssssssssssssssssssssssssssssssssssscccssssssssssssssssccccccccccccsccccccsscccssssssssssssscccsssssccssssscccssssssssssssssssssssssssssssssscccssssssssssssssccscccccccscccccsssssssssssssssssssssccsssc" />
+    <path
+       style="opacity:1;fill:#000000"
+       d="M 109.70227,165.77288 C 109.59907,165.33986 109.8398,165.01229 110.23968,165.04158 C 110.36674,165.05089 110.5064,165.02864 110.55,164.99216 C 110.62598,164.9286 110.7617,164.50023 110.74423,164.37912 C 110.73964,164.34716 110.3775,163.85748 109.9395,163.29093 C 108.95086,162.01216 108.07427,160.80165 107.18992,159.49395 C 105.79425,157.43012 104.05383,154.60437 103.42533,153.38169 C 101.87062,150.35728 101.0282,147.11246 100.98534,143.98362 C 100.96858,142.76009 101.17265,140.35333 101.37151,139.42879 C 102.00426,136.48749 103.43362,134.1992 106.14497,131.78691 C 107.78082,130.33152 110.63967,128.33482 112.39262,127.4234 C 115.63153,125.73941 119.61977,124.25277 126.22783,122.26625 C 129.96393,121.1431 131.04119,120.77773 132.46546,120.15062 C 136.1834,118.51364 138.99367,115.98317 141.66634,111.86576 C 143.15213,109.57679 146.51458,104.58135 146.93782,104.03411 C 150.63806,99.249908 154.18006,96.365698 157.62865,95.328678 C 158.31638,95.121878 159.63643,94.872438 160.29529,94.824798 C 161.52855,94.735578 162.67802,94.984938 163.50119,95.520248 C 163.80971,95.720848 163.91471,95.819268 164.17693,96.153708 C 164.47649,96.535638 164.48724,96.544568 164.48147,96.406808 C 164.47814,96.328298 164.46495,96.250648 164.45209,96.234308 C 164.37585,96.137508 164.54363,96.171548 164.88571,96.322338 L 165.27722,96.494868 L 165.39421,96.348958 C 165.67621,95.997268 165.93468,95.948238 166.22992,96.190418 C 166.39629,96.326858 166.4526,96.485298 166.51838,97.001878 C 166.58339,97.512718 166.53898,97.690598 166.29545,97.894338 C 166.07543,98.078408 165.89099,98.085058 165.68935,97.916158 C 165.40867,97.681128 165.21205,97.750168 164.92856,98.183248 C 164.85068,98.302208 164.78109,98.404768 164.77387,98.411208 C 164.76666,98.417608 164.74604,98.333788 164.72807,98.224878 L 164.69538,98.026888 L 164.61146,98.289818 C 164.41437,98.907268 164.18805,99.189958 162.95005,100.36507 C 161.86573,101.3943 160.95969,102.33255 160.27523,103.13498 C 160.00164,103.45572 159.6338,103.88164 159.4578,104.08147 C 159.07409,104.51711 158.90535,104.77568 158.70063,105.24175 C 158.40397,105.91709 158.24864,106.62036 158.16696,107.65813 C 158.03238,109.36812 158.33129,111.06494 159.02297,112.51766 C 159.193,112.87474 159.30696,113.03966 159.75644,113.57904 C 160.3699,114.31516 160.57332,114.47744 161.304,114.81325 C 161.84602,115.06238 162.35354,115.18723 162.96099,115.22094 C 163.52751,115.25234 164.47929,115.1455 164.61045,115.03579 C 164.66515,114.99002 166.69219,113.38252 169.11497,111.46355 C 180.64258,102.33309 188.23471,96.291718 199.65658,87.160318 C 201.71469,85.514954 206.44962,81.707876 209.72941,79.061376 C 211.87185,77.332636 216.42009,73.620756 220.97218,69.886052 L 223.17373,68.079872 L 223.19907,67.712872 C 223.23277,67.224722 223.22559,66.722342 223.17732,66.202942 C 223.11808,65.564932 223.16145,65.149872 223.31599,64.877552 C 223.61625,64.348372 224.05472,64.023642 224.93714,63.676962 C 225.58305,63.423182 226.77762,62.853162 226.78265,62.796292 C 226.79121,62.700502 226.5611,62.221952 226.47312,62.152352 C 226.41864,62.109282 226.26489,62.092802 226.10349,62.112752 C 225.86163,62.142612 225.80963,62.129182 225.68736,62.005122 C 225.53302,61.848512 225.35262,61.423602 225.18913,60.831702 C 225.06085,60.367052 225.07777,60.338822 225.73609,59.918222 C 226.2468,59.591922 226.49252,59.485872 226.89402,59.418372 C 227.22974,59.361912 227.42628,59.406052 227.62262,59.581982 C 227.82014,59.758912 228.14456,60.338412 228.21262,60.635862 C 228.2784,60.923422 228.18499,61.258092 227.99453,61.417472 C 227.83392,61.551802 227.83562,61.559642 228.10805,61.958992 C 228.25423,62.173252 228.25815,62.175202 228.41203,62.111432 C 229.05004,61.846942 230.90986,61.023122 230.90934,61.005192 C 230.90894,60.992932 230.86205,60.868592 230.80503,60.728952 C 230.67753,60.416632 230.53997,60.325642 230.28256,60.383112 C 230.18224,60.405522 230.05585,60.413782 230.00164,60.401512 C 229.76859,60.348852 229.5505,59.923232 229.33064,59.091712 L 229.21843,58.667342 L 229.67048,58.331042 C 230.44233,57.756852 231.16283,57.536082 231.58601,57.744142 C 231.80143,57.850082 231.83297,57.883092 232.04225,58.221852 C 232.29359,58.628632 232.38666,58.880432 232.37556,59.123302 C 232.36569,59.337092 232.19901,59.677602 232.07569,59.735792 C 231.95884,59.790922 231.97478,59.850432 232.1947,60.181762 L 232.35773,60.427462 L 233.61219,59.903482 C 234.30213,59.615302 234.8724,59.366372 234.87946,59.350302 C 234.90931,59.282692 234.68828,58.808462 234.59559,58.741152 C 234.54014,58.700852 234.42159,58.684222 234.33217,58.704152 C 234.07195,58.762172 233.90252,58.726712 233.78841,58.590342 C 233.65576,58.431822 233.41925,57.829362 233.30795,57.366382 L 233.22245,57.010922 L 233.49658,56.789032 C 234.12336,56.281782 234.49279,56.097332 235.05712,56.010032 C 235.32603,55.968422 235.42674,55.980982 235.59964,56.077532 C 235.78566,56.181402 235.83935,56.240092 236.03268,56.550862 C 236.33333,57.034152 236.42021,57.405842 236.30662,57.722772 C 236.24372,57.898472 236.18174,57.988352 236.08833,58.039262 C 235.94418,58.117892 235.94705,58.128582 236.23144,58.566132 L 236.36972,58.778872 L 237.72255,58.233312 C 238.46657,57.933282 239.0746,57.675882 239.07362,57.661342 C 239.0665,57.554262 238.81326,57.054882 238.73972,57.002942 C 238.68943,56.967372 238.52182,56.955412 238.36722,56.976382 C 238.1264,57.009022 238.06768,56.995822 237.95729,56.884212 C 237.80752,56.732862 237.62555,56.296362 237.46945,55.714412 C 237.33679,55.219952 237.346,55.203832 238.00275,54.781102 C 238.73789,54.307912 239.36427,54.148402 239.73814,54.339192 C 239.8902,54.416792 239.95499,54.488242 240.15747,54.801382 C 240.46916,55.283612 240.5514,55.577162 240.46792,55.909202 C 240.41645,56.113782 240.36858,56.194022 240.24898,56.276292 C 240.07668,56.394802 240.07616,56.392492 240.38837,56.861932 L 240.55682,57.115132 L 241.86393,56.609882 C 242.58287,56.331992 243.17659,56.093582 243.18332,56.080072 C 243.20056,56.045712 242.91193,55.366352 242.8457,55.285432 C 242.81585,55.248882 242.72068,55.225022 242.63427,55.232392 C 242.19325,55.270052 242.09894,55.254952 241.99437,55.129942 C 241.8717,54.983342 241.67066,54.477412 241.51488,53.923112 L 241.40436,53.529982 L 241.87765,53.175422 C 242.38522,52.795162 242.75517,52.626062 243.2679,52.539852 C 243.57672,52.487912 243.74935,52.528192 243.94556,52.697992 C 244.12923,52.856902 244.4775,53.445402 244.53275,53.690322 C 244.61858,54.070172 244.49846,54.483032 244.26992,54.593652 C 244.14602,54.653612 244.13622,54.620472 244.4485,55.199272 C 244.54784,55.383462 244.637,55.533992 244.64647,55.533842 C 244.65601,55.533662 245.00382,55.374622 245.41936,55.180432 C 245.83497,54.986222 246.42262,54.721472 246.72536,54.592082 C 247.02803,54.462712 247.2746,54.349212 247.27317,54.339892 C 247.25847,54.244262 247.01869,53.756132 246.9443,53.670492 C 246.8669,53.581452 246.79387,53.566452 246.57154,53.594002 C 246.11145,53.651012 246.00231,53.516382 245.69101,52.507542 C 245.4929,51.865552 245.49617,51.853442 245.94999,51.548592 C 246.10413,51.445022 246.31093,51.305762 246.40955,51.239132 C 246.78702,50.983982 247.50732,50.815412 247.79857,50.914052 C 248.00223,50.983022 248.2258,51.227442 248.45226,51.628722 C 248.7499,52.155882 248.74082,52.633102 248.42822,52.894592 L 248.26454,53.031532 L 248.5209,53.430172 C 248.66192,53.649412 248.78739,53.829202 248.7998,53.829672 C 248.81221,53.830102 249.0243,53.782612 249.27113,53.724082 C 250.02507,53.545322 250.49692,53.513352 251.0056,53.606552 C 252.40794,53.863492 253.52315,54.613812 254.15346,55.724472 C 254.26462,55.920442 254.41035,56.212362 254.47723,56.373182 C 254.62432,56.727032 254.82582,57.547782 254.87566,57.996012 C 254.97193,58.862202 254.7285,59.776612 254.19219,60.563172 C 253.66156,61.341342 252.79762,62.226802 252.29455,62.507932 C 251.24276,63.095752 249.81312,63.406202 248.85473,63.254892 C 248.56787,63.209572 248.0454,63.031872 247.48525,62.789092 C 246.7844,62.485342 246.23601,62.539302 245.63157,62.971512 C 245.23288,63.256562 245.06698,63.455392 243.13845,65.958572 C 241.13689,68.556522 239.88942,70.140332 238.88296,71.361222 C 238.18603,72.206682 238.11647,72.277862 237.36448,72.914832 C 236.7976,73.394976 236.53157,73.596076 236.41661,73.631266 C 236.29878,73.667306 236.12387,73.632396 235.75091,73.498446 C 235.0082,73.231706 233.96784,72.939582 233.44603,72.851252 C 232.87673,72.754882 232.40684,72.747102 231.72527,72.822832 C 230.71332,72.935252 230.53076,72.991182 229.85239,73.396656 C 229.51523,73.598156 229.06676,73.857076 228.85586,73.972006 C 228.45645,74.189586 226.70845,75.659826 195.38985,102.12088 C 192.71234,104.3831 186.4843,109.64041 181.54972,113.8038 C 176.61516,117.96718 171.44622,122.33522 170.06316,123.51057 C 168.68013,124.68589 166.70935,126.34999 165.68373,127.20851 L 163.81888,128.7695 L 163.85638,128.90545 C 163.877,128.98023 163.86929,129.14186 163.83926,129.26463 C 163.54406,130.47107 164.373,132.53311 165.75999,134.04257 C 167.39439,135.82124 169.32031,136.74035 171.36338,136.71673 C 171.89166,136.71062 172.54908,136.51959 173.94752,135.96587 C 174.73678,135.65334 176.30976,134.90504 177.02511,134.50179 C 177.90375,134.00649 178.45603,133.86075 179.20774,133.92588 C 180.0736,134.00089 180.66593,134.33163 181.20589,135.04157 C 181.71,135.7044 181.85592,136.29309 181.7665,137.30346 C 181.73548,137.65494 181.65651,138.11482 181.59119,138.32538 C 181.32725,139.1762 180.23083,140.87825 179.12476,142.15431 C 178.59678,142.76343 176.77603,144.28595 176.03289,144.73975 C 174.52046,145.6633 173.55495,146.11025 169.3804,147.8193 C 169.12474,147.92397 168.4166,148.13749 167.80675,148.29378 C 166.11515,148.72732 165.16194,149.06264 163.94975,149.65056 C 161.99581,150.59825 160.3919,151.88328 159.03392,153.58904 C 158.09658,154.76644 157.38522,156.00188 156.69083,157.6584 C 156.46171,158.205 156.15836,158.86703 156.01673,159.12955 C 155.67984,159.754 155.31877,160.48364 154.35339,162.49077 C 152.80894,165.70186 152.01394,167.19097 150.92796,168.90698 C 148.93254,172.06004 146.70575,174.55274 144.12641,176.52066 C 142.36135,177.86732 141.12213,178.65666 139.75632,179.30426 C 137.21476,180.50928 135.05432,180.89234 131.83442,180.70892 C 130.45684,180.63044 130.38317,180.61771 129.20803,180.2552 C 126.54371,179.43319 125.17312,178.81357 123.42272,177.63963 C 121.24664,176.18021 118.9218,174.02916 116.86988,171.57659 C 116.2434,170.82781 114.90269,169.24865 113.89054,168.06734 L 112.05021,165.91954 L 111.68462,165.9813 L 111.31904,166.04306 L 111.28143,166.31121 C 111.23996,166.60672 111.14081,166.7231 110.88121,166.78099 C 110.58507,166.84704 110.39698,166.74434 110.05217,166.32825 C 109.83129,166.06171 109.73446,165.90802 109.70227,165.77288 z"
+       id="path3250"
+       sodipodi:nodetypes="csssssssssssssssssssscccsssssscccssssssssssssscccssssssssssssssssssscccsssscccsssscccssssscccsssssssssscccsssscccsssssssssssssssscccssssssssssssssssssssssscccssssssssssssssssssssssssscccccssc" />
+    <rect
+       style="opacity:1;color:#000000;fill:#0000ff;fill-opacity:0.22608696;fill-rule:nonzero;stroke:none;stroke-width:10.60000038000000089;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:block;overflow:visible"
+       id="rect1913"
+       width="291.42856"
+       height="45.714287"
+       x="-16.285721"
+       y="181.50516" />
+    <path
+       style="font-size:39.83382034000000260px;font-family:Goblin;stroke:none;stroke-opacity:1;fill:#000000;fill-opacity:1"
+       d="M 58.72672,219.00823 L 44.00299,198.17717 L 44.00299,218.61923 L 40.30747,218.61923 L 40.30747,190.12482 L 41.86348,190.12482 L 56.19821,209.82778 L 56.19821,190.12482 L 59.89373,190.12482 L 59.89373,219.00823 L 58.72672,219.00823 M 64.3867,204.1289 C 64.3867,200.0055 65.41756,196.55635 67.47927,193.78144 C 69.55394,191.00659 72.34827,189.61915 75.86227,189.61912 C 79.8171,189.61915 82.84483,190.89637 84.94547,193.45079 C 87.05902,196.00526 88.11581,199.56463 88.11583,204.1289 C 88.11581,208.8099 87.05902,212.47949 84.94547,215.13766 C 82.83187,217.78288 79.80414,219.10548 75.86227,219.10548 C 72.27047,219.10548 69.45669,217.70508 67.42092,214.90426 C 65.39811,212.10345 64.3867,208.51167 64.3867,204.1289 M 68.47123,204.1289 C 68.47122,207.39653 69.11307,210.12603 70.39679,212.3174 C 71.69345,214.50878 73.51528,215.60447 75.86227,215.60447 C 78.52043,215.60447 80.54324,214.59955 81.9307,212.5897 C 83.33109,210.57986 84.03129,207.7596 84.03131,204.1289 C 84.03129,196.78975 81.30828,193.12017 75.86227,193.12014 C 73.45044,193.12017 71.61565,194.10564 70.35789,196.07656 C 69.10011,198.04752 68.47122,200.73163 68.47123,204.1289 M 122.75647,191.17513 L 121.45332,194.5011 C 120.20849,193.59345 118.25052,193.13962 115.57938,193.13959 C 113.07679,193.13962 111.06695,194.21585 109.54985,196.36831 C 108.0457,198.52081 107.29363,201.29569 107.29364,204.69296 C 107.29363,207.93465 108.06515,210.5669 109.6082,212.5897 C 111.1642,214.59955 113.16756,215.60447 115.61828,215.60447 C 118.28942,215.60447 120.34464,214.6579 121.78397,212.76475 L 123.92348,215.74062 C 121.66725,217.98386 118.7627,219.10548 115.20983,219.10548 C 111.48837,219.10548 108.55789,217.76343 106.41838,215.07931 C 104.27887,212.3952 103.20911,208.85529 103.20912,204.45955 C 103.20911,200.20648 104.35019,196.67305 106.63233,193.85925 C 108.91447,191.04549 111.8644,189.6386 115.48213,189.63857 C 118.58117,189.6386 121.00594,190.15079 122.75647,191.17513 M 127.01605,204.1289 C 127.01604,200.0055 128.0469,196.55635 130.10861,193.78144 C 132.18328,191.00659 134.97761,189.61915 138.49161,189.61912 C 142.44645,189.61915 145.47418,190.89637 147.57481,193.45079 C 149.68836,196.00526 150.74515,199.56463 150.74518,204.1289 C 150.74515,208.8099 149.68836,212.47949 147.57481,215.13766 C 145.46121,217.78288 142.43348,219.10548 138.49161,219.10548 C 134.89981,219.10548 132.08603,217.70508 130.05026,214.90426 C 128.02745,212.10345 127.01604,208.51167 127.01605,204.1289 M 131.10057,204.1289 C 131.10056,207.39653 131.74242,210.12603 133.02613,212.3174 C 134.32279,214.50878 136.14462,215.60447 138.49161,215.60447 C 141.14977,215.60447 143.17258,214.59955 144.56004,212.5897 C 145.96043,210.57986 146.66063,207.7596 146.66065,204.1289 C 146.66063,196.78975 143.93762,193.12017 138.49161,193.12014 C 136.07979,193.12017 134.24499,194.10564 132.98723,196.07656 C 131.72945,198.04752 131.10056,200.73163 131.10057,204.1289 M 165.13826,219.00823 L 163.1738,219.00823 L 152.55404,190.12482 L 156.87197,190.12482 L 164.20466,211.11149 L 171.26505,190.12482 L 175.44682,190.12482 L 165.13826,219.00823 M 182.52665,193.62584 L 182.52665,201.54204 L 191.94051,201.54204 L 191.94051,204.84856 L 182.52665,204.84856 L 182.52665,215.11821 L 195.44153,215.11821 L 195.44153,218.61923 L 178.63663,218.61923 L 178.63663,190.12482 L 195.65548,190.12482 L 195.65548,193.62584 L 182.52665,193.62584 M 215.76689,218.61923 L 208.1619,206.38511 C 207.29312,206.38513 205.91864,206.32029 204.03848,206.19061 L 204.03848,218.61923 L 200.14846,218.61923 L 200.14846,190.12482 C 200.29109,190.12485 201.29601,190.07947 203.16322,189.98867 C 205.04339,189.88497 206.41138,189.8331 207.26719,189.83307 C 214.11362,189.8331 217.53683,192.55611 217.53685,198.00212 C 217.53683,199.79155 216.98575,201.4059 215.88359,202.84519 C 214.7814,204.27155 213.47176,205.15977 211.95467,205.50986 L 220.22097,218.61923 L 215.76689,218.61923 M 204.03848,193.62584 L 204.03848,202.8841 C 204.97207,203.01378 205.87974,203.07861 206.76149,203.0786 C 209.09549,203.07861 210.79413,202.70258 211.85742,201.95049 C 212.92068,201.19844 213.45231,199.85638 213.45233,197.92432 C 213.45231,196.32943 212.88178,195.18188 211.74072,194.48165 C 210.59963,193.78147 208.79726,193.43137 206.33359,193.43134 C 205.94458,193.43137 205.17954,193.4962 204.03848,193.62584"
+       id="text1909" />
+  </g>
+</svg>
diff --git a/data/themes/default/bassneck.svg b/data/themes/default/bassneck.svg
new file mode 100644 (file)
index 0000000..7df67da
--- /dev/null
@@ -0,0 +1,269 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://creativecommons.org/ns#"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:xlink="http://www.w3.org/1999/xlink"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   version="1.0"
+   width="250"
+   height="520"
+   id="svg2"
+   sodipodi:version="0.32"
+   inkscape:version="0.47 r22583"
+   sodipodi:docname="bassneck.svg"
+   inkscape:output_extension="org.inkscape.output.svg.inkscape"
+   sodipodi:modified="true">
+  <metadata
+     id="metadata3009">
+    <rdf:RDF>
+      <cc:Work
+         rdf:about="">
+        <dc:format>image/svg+xml</dc:format>
+        <dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+      </cc:Work>
+    </rdf:RDF>
+  </metadata>
+  <sodipodi:namedview
+     inkscape:window-height="871"
+     inkscape:window-width="1375"
+     inkscape:pageshadow="2"
+     inkscape:pageopacity="0.0"
+     borderopacity="1.0"
+     bordercolor="#666666"
+     pagecolor="#ffffff"
+     id="base"
+     inkscape:zoom="1.244236"
+     inkscape:cx="-20.470797"
+     inkscape:cy="292.14824"
+     inkscape:window-x="0"
+     inkscape:window-y="0"
+     inkscape:current-layer="g4297"
+     showgrid="true"
+     showguides="false"
+     inkscape:window-maximized="0">
+    <inkscape:grid
+       type="xygrid"
+       id="grid3223"
+       visible="true"
+       enabled="true" />
+  </sodipodi:namedview>
+  <defs
+     id="defs4">
+    <inkscape:perspective
+       sodipodi:type="inkscape:persp3d"
+       inkscape:vp_x="0 : 260 : 1"
+       inkscape:vp_y="0 : 1000 : 0"
+       inkscape:vp_z="250 : 260 : 1"
+       inkscape:persp3d-origin="125 : 173.33333 : 1"
+       id="perspective41" />
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient4109"
+       id="linearGradient4303"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(1.173252,0,0,1.1426938,-40.651789,-74.675511)"
+       x1="64.430161"
+       y1="268.30783"
+       x2="146.39825"
+       y2="301.49274" />
+    <linearGradient
+       id="linearGradient4109">
+      <stop
+         style="stop-color:#ad6c12;stop-opacity:0.58823532;"
+         offset="0"
+         id="stop4111" />
+      <stop
+         id="stop4117"
+         offset="0.5"
+         style="stop-color:#b36e05;stop-opacity:1;" />
+      <stop
+         style="stop-color:#b66406;stop-opacity:0.58823532;"
+         offset="1"
+         id="stop4113" />
+    </linearGradient>
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient4109"
+       id="linearGradient4301"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(1.0948624,0,0,1.2672683,6.8733359,2.5614661)"
+       x1="92.684113"
+       y1="164.62471"
+       x2="227.01991"
+       y2="194.92398" />
+    <linearGradient
+       id="linearGradient4387">
+      <stop
+         style="stop-color:#53300d;stop-opacity:0;"
+         offset="0"
+         id="stop4389" />
+      <stop
+         id="stop10266"
+         offset="0.04048297"
+         style="stop-color:#59330d;stop-opacity:0.93333333;" />
+      <stop
+         id="stop4395"
+         offset="0.5"
+         style="stop-color:#a65b10;stop-opacity:0.93333334;" />
+      <stop
+         style="stop-color:#4e2804;stop-opacity:0.93333333;"
+         offset="0.96050948"
+         id="stop10268" />
+      <stop
+         style="stop-color:#462403;stop-opacity:0;"
+         offset="1"
+         id="stop4391" />
+    </linearGradient>
+    <linearGradient
+       id="linearGradient3207">
+      <stop
+         style="stop-color:#999999;stop-opacity:1;"
+         offset="0"
+         id="stop3209" />
+      <stop
+         style="stop-color:#5f5f5f;stop-opacity:1;"
+         offset="1"
+         id="stop3211" />
+    </linearGradient>
+    <linearGradient
+       id="linearGradient2417">
+      <stop
+         style="stop-color:#f2f2f2;stop-opacity:1;"
+         offset="0"
+         id="stop2419" />
+      <stop
+         style="stop-color:#999999;stop-opacity:0.73282444;"
+         offset="1"
+         id="stop2421" />
+    </linearGradient>
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient4387"
+       id="linearGradient4393"
+       x1="3.4098361"
+       y1="259.35468"
+       x2="249.85738"
+       y2="259.35468"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(0.9893675,0,0,0.9937313,0,2.2711467)" />
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient3207"
+       id="linearGradient10308"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(1.7058765,0,0,1.0054914,478.96768,-1.4243308)"
+       spreadMethod="repeat"
+       x1="-265.2009"
+       y1="-3.3672962"
+       x2="-267.33176"
+       y2="2.4799759" />
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient2417"
+       id="linearGradient10369"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(0.8756074,0,0,1.2260835,248.64415,3.5311546)"
+       spreadMethod="reflect"
+       x1="-142.75803"
+       y1="0.78900218"
+       x2="-142.75803"
+       y2="4.6783328" />
+  </defs>
+  <rect
+     y="0"
+     x="0"
+     height="520"
+     width="250"
+     id="rect2405"
+     style="opacity:1;fill:url(#linearGradient4393);fill-opacity:1;stroke:none;stroke-width:4;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" />
+  <g
+     id="g4297">
+    <path
+       sodipodi:nodetypes="cscssc"
+       id="path3261"
+       d="M 81.432615,523.32667 C -18.442228,249.08013 45.037557,325.48219 83.125406,205.12676 C 121.21329,84.771376 59.426308,16.350148 59.426308,16.350148 C 59.426308,16.350148 127.98446,33.661541 127.98446,167.2066 C 127.98446,300.75162 79.739823,297.4542 95.821367,384.01118 C 111.9029,470.56812 153.37636,523.32667 153.37636,523.32667"
+       style="fill:url(#linearGradient4303);fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+       inkscape:transform-center-x="25.312288"
+       inkscape:transform-center-y="-253.48831" />
+    <path
+       style="fill:url(#linearGradient4301);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+       d="M 156.94058,-2.7426601 C 197.09035,63.403575 223.53139,132.71627 211.6837,209.35672 C 190.42957,346.84571 243.03378,478.1378 243.03378,478.1378 C 209.22758,435.88668 204.37385,417.26638 192.48364,377.57343 C 145.93498,222.18048 183.42574,222.06796 157.13587,128.90521 C 138.95232,64.468613 110.71652,46.267978 92.17322,3.3547926e-14"
+       id="use3265"
+       sodipodi:nodetypes="cscssc"
+       inkscape:transform-center-x="-46.636479"
+       inkscape:transform-center-y="240.44022" />
+  </g>
+  <g
+     id="g3393"
+     transform="translate(1.3558093,0.6218326)">
+    <rect
+       y="-0.62183261"
+       x="-1.3558093"
+       height="9.8890123"
+       width="250"
+       id="rect2415"
+       style="fill:url(#linearGradient10369);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:6;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+    <use
+       height="520"
+       width="250"
+       transform="translate(3.0940247e-8,255.33617)"
+       id="use3197"
+       xlink:href="#rect2415"
+       y="0"
+       x="0" />
+    <use
+       height="520"
+       width="250"
+       transform="translate(3.0940247e-8,515.13684)"
+       id="use3203"
+       xlink:href="#rect2415"
+       y="0"
+       x="0" />
+    <use
+       height="520"
+       width="250"
+       transform="matrix(0.8333333,0,0,1,53.926741,0)"
+       id="use3215"
+       xlink:href="#rect3205"
+       y="0"
+       x="0" />
+    <use
+       height="520"
+       width="250"
+       transform="matrix(0.6666667,0,0,1,109.29626,0)"
+       id="use3217"
+       xlink:href="#rect3205"
+       y="0"
+       x="0" />
+    <use
+       height="520"
+       width="250"
+       transform="matrix(0.5,0,0,1,163.22302,0)"
+       id="use3219"
+       xlink:href="#rect3205"
+       y="0"
+       x="0" />
+    <use
+       height="520"
+       width="250"
+       transform="matrix(0.3333333,0,0,1,216.42835,0)"
+       id="use3221"
+       xlink:href="#rect3205"
+       y="0"
+       x="0" />
+    <rect
+       y="-4.8101187"
+       x="20.56773"
+       height="528.36328"
+       width="12"
+       id="rect3205"
+       style="fill:url(#linearGradient10308);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:6;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+  </g>
+</svg>
diff --git a/data/themes/default/button.svg b/data/themes/default/button.svg
new file mode 100644 (file)
index 0000000..3ffb606
--- /dev/null
@@ -0,0 +1,124 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://creativecommons.org/ns#"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:xlink="http://www.w3.org/1999/xlink"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   width="64"
+   height="64"
+   id="svg2463"
+   sodipodi:version="0.32"
+   inkscape:version="0.46"
+   version="1.0"
+   sodipodi:docname="button.svg"
+   inkscape:output_extension="org.inkscape.output.svg.inkscape">
+  <defs
+     id="defs2465">
+    <linearGradient
+       id="linearGradient3262">
+      <stop
+         style="stop-color:#f5f5f5;stop-opacity:0.22680412;"
+         offset="0"
+         id="stop3264" />
+      <stop
+         style="stop-color:#f5f5f5;stop-opacity:0.96078432;"
+         offset="1"
+         id="stop3266" />
+    </linearGradient>
+    <linearGradient
+       id="linearGradient3751"
+       inkscape:collect="always">
+      <stop
+         id="stop3753"
+         offset="0"
+         style="stop-color:black;stop-opacity:1;" />
+      <stop
+         id="stop3755"
+         offset="1"
+         style="stop-color:black;stop-opacity:0;" />
+    </linearGradient>
+    <inkscape:perspective
+       sodipodi:type="inkscape:persp3d"
+       inkscape:vp_x="0 : 526.18109 : 1"
+       inkscape:vp_y="0 : 1000 : 0"
+       inkscape:vp_z="744.09448 : 526.18109 : 1"
+       inkscape:persp3d-origin="372.04724 : 350.78739 : 1"
+       id="perspective2471" />
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient3751"
+       id="linearGradient3272"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(0.3868046,0,0,0.3868046,40.335717,481.59837)"
+       x1="665.12128"
+       y1="684.16162"
+       x2="381.28015"
+       y2="449.80624" />
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient3751"
+       id="linearGradient2406"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(0.3868046,0,0,0.3868046,43.114888,485.8841)"
+       x1="665.12128"
+       y1="684.16162"
+       x2="381.28015"
+       y2="449.80624" />
+  </defs>
+  <sodipodi:namedview
+     id="base"
+     pagecolor="#f5f5f5"
+     bordercolor="#666666"
+     borderopacity="1.0"
+     gridtolerance="10000"
+     guidetolerance="10"
+     objecttolerance="10"
+     inkscape:pageopacity="0"
+     inkscape:pageshadow="2"
+     inkscape:zoom="5.6"
+     inkscape:cx="27.116923"
+     inkscape:cy="40.003406"
+     inkscape:document-units="px"
+     inkscape:current-layer="layer1"
+     showgrid="false"
+     inkscape:window-width="1021"
+     inkscape:window-height="720"
+     inkscape:window-x="87"
+     inkscape:window-y="34" />
+  <metadata
+     id="metadata2468">
+    <rdf:RDF>
+      <cc:Work
+         rdf:about="">
+        <dc:format>image/svg+xml</dc:format>
+        <dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+      </cc:Work>
+    </rdf:RDF>
+  </metadata>
+  <g
+     inkscape:label="Layer 1"
+     inkscape:groupmode="layer"
+     id="layer1"
+     transform="translate(-110.35967,-771.51188)">
+    <path
+       sodipodi:type="arc"
+       style="fill:#f5f5f5;fill-opacity:0.96078430999999997;stroke:#000000;stroke-width:17.75125346;stroke-miterlimit:3.29999995;stroke-dasharray:none;stroke-opacity:1"
+       id="path2481"
+       sodipodi:cx="360"
+       sodipodi:cy="838.07648"
+       sodipodi:rx="165.71428"
+       sodipodi:ry="165.71428"
+       d="M 525.71428,838.07648 A 165.71428,165.71428 0 1 1 194.28572,838.07648 A 165.71428,165.71428 0 1 1 525.71428,838.07648 z"
+       transform="matrix(0.1690021,0,0,0.1690022,81.519358,662.1236)" />
+    <path
+       style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:0.06804083px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+       d="M 145.82521,786.11711 L 144.45057,786.11711 L 144.17565,786.80444 L 144.45057,787.56047 L 144.31311,788.38526 L 143.62581,787.97287 L 143.07595,786.94189 L 141.90751,786.66697 L 141.42639,786.18585 L 140.39542,785.70472 L 139.22698,783.78023 L 139.29572,782.88672 L 142.18244,780.6873 L 143.55706,781.30589 L 143.76326,781.78703 L 143.76326,782.33687 L 144.10692,782.81799 L 144.79423,783.02419 L 145.27535,782.61179 L 145.34408,782.13067 L 145.13789,781.71829 L 144.7255,781.51209 L 144.45057,781.16843 L 145.06916,780.89351 L 144.9317,780.20618 L 144.9317,779.7938 L 144.51932,779.3814 L 144.31311,778.76281 L 143.48834,778.55663 L 142.80102,778.41916 L 141.35765,779.45014 L 137.71489,780.89351 L 136.8901,781.71829 L 136.27151,782.19941 L 136.13404,783.29911 L 136.40899,783.84896 L 137.09631,785.70472 L 137.98981,787.42302 L 138.95205,788.66018 L 137.43996,791.13453 L 135.72166,794.84603 L 134.69068,796.49558 L 132.97241,798.62627 L 132.90367,799.58851 L 132.01017,800.4133 L 133.38479,801.65047 L 133.04114,803.09384 L 133.1786,806.32421 L 133.79717,810.03572 L 134.41577,813.33485 L 135.10307,814.43455 L 136.06533,816.42776 L 137.57742,818.69592 L 137.98981,820.13927 L 138.4022,821.17025 L 137.16502,822.88855 L 134.96561,823.78205 L 134.75943,824.46937 L 138.95205,824.33192 L 138.33347,825.43162 L 139.08951,826.11894 L 141.08274,826.32513 L 142.66356,824.9505 L 143.21342,823.02602 L 144.10692,821.37645 L 145.20662,820.41421 L 145.55028,819.3145 L 144.38186,819.24576 L 145.13789,818.48971 L 143.62581,818.97084 L 144.7255,817.87112 L 143.90073,817.66494 L 143.28213,816.90889 L 142.25117,814.77821 L 139.84556,812.785 L 139.36445,812.64753 L 139.84556,812.23514 L 139.77683,811.06671 L 140.25796,810.03572 L 139.84556,810.10446 L 140.60161,808.79856 L 140.60161,807.49266 L 141.08274,806.80534 L 141.08274,805.91182 L 142.1137,804.53718 L 142.18244,803.36875 L 141.97624,802.40652 L 142.45737,801.3068 L 143.0072,800.4133 L 143.0072,799.86344 L 143.62581,799.7947 L 144.17565,799.24485 L 144.65677,797.87022 L 145.75648,796.63305 L 147.06237,796.15193 L 147.88715,796.83925 L 149.88037,797.45783 L 151.4612,798.28261 L 152.21723,799.24485 L 153.52314,799.38231 L 157.64704,801.16934 L 159.77771,801.92538 L 161.49601,803.23129 L 161.90839,803.09384 L 161.90839,802.68144 L 160.94616,801.92538 L 162.8019,802.40652 L 163.0081,802.06285 L 162.59571,801.65047 L 163.28303,801.65047 L 163.35176,801.23808 L 162.11459,800.96314 L 163.07683,800.68821 L 163.07683,800.2071 L 162.73317,800.13837 L 161.70219,800.2071 L 160.87743,799.86344 L 160.32757,799.58851 L 161.15235,798.90119 L 161.35855,798.42008 L 161.22108,798.07642 L 160.46504,798.21388 L 158.8842,799.03866 L 158.67802,799.45105 L 158.12816,799.31359 L 156.13494,798.21388 L 156.0662,797.45783 L 154.89777,796.83925 L 152.90456,795.80826 L 152.42345,796.15193 L 152.49216,795.6708 L 151.39247,794.63983 L 150.43021,794.36491 L 149.53671,793.33393 L 149.26179,792.99027 L 150.1553,793.60886 L 150.01784,792.92154 L 150.70515,793.26519 L 150.49895,792.23422 L 151.4612,793.12772 L 151.04882,792.50914 L 152.01105,792.92154 L 151.18628,791.75311 L 151.80485,791.95929 L 151.52993,790.8596 L 152.01105,791.27198 L 151.32373,790.24102 L 152.01105,790.44721 L 151.39247,789.62243 L 152.21723,789.55369 L 151.32373,789.00384 L 151.87358,788.72892 L 151.25501,788.66018 L 152.07977,787.90413 L 151.32373,787.97287 L 151.39247,787.49175 L 151.4612,786.11711 L 151.04882,787.07936 L 150.56768,785.70472 L 150.63642,786.80444 L 150.36149,786.87316 L 149.67417,786.87316 L 148.91813,785.77346 L 148.16207,785.77346 L 147.26856,785.0174 L 146.85617,785.42979 L 145.82521,786.11711 z"
+       id="path1939" />
+  </g>
+</svg>
diff --git a/data/themes/default/dance_cover.svg b/data/themes/default/dance_cover.svg
new file mode 100644 (file)
index 0000000..f785af4
--- /dev/null
@@ -0,0 +1,168 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://creativecommons.org/ns#"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:xlink="http://www.w3.org/1999/xlink"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   width="256"
+   height="256"
+   id="svg2"
+   sodipodi:version="0.32"
+   inkscape:version="0.47 r22583"
+   sodipodi:docname="dance_cover.svg"
+   inkscape:output_extension="org.inkscape.output.svg.inkscape"
+   version="1.0">
+  <defs
+     id="defs4">
+    <inkscape:perspective
+       sodipodi:type="inkscape:persp3d"
+       inkscape:vp_x="0 : 128 : 1"
+       inkscape:vp_y="0 : 1000 : 0"
+       inkscape:vp_z="256 : 128 : 1"
+       inkscape:persp3d-origin="128 : 85.333333 : 1"
+       id="perspective17" />
+    <linearGradient
+       id="linearGradient3751"
+       inkscape:collect="always">
+      <stop
+         id="stop3753"
+         offset="0"
+         style="stop-color:black;stop-opacity:1;" />
+      <stop
+         id="stop3755"
+         offset="1"
+         style="stop-color:black;stop-opacity:0;" />
+    </linearGradient>
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient3751"
+       id="linearGradient3484"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(0.336682,0,0,0.336682,-81.3739,-51.8729)"
+       x1="665.12128"
+       y1="684.16162"
+       x2="381.28015"
+       y2="449.80624" />
+    <inkscape:perspective
+       sodipodi:type="inkscape:persp3d"
+       inkscape:vp_x="0 : 0.5 : 1"
+       inkscape:vp_y="0 : 1000 : 0"
+       inkscape:vp_z="1 : 0.5 : 1"
+       inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
+       id="perspective3827" />
+    <inkscape:perspective
+       sodipodi:type="inkscape:persp3d"
+       inkscape:vp_x="0 : 0.5 : 1"
+       inkscape:vp_y="0 : 1000 : 0"
+       inkscape:vp_z="1 : 0.5 : 1"
+       inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
+       id="perspective2830" />
+    <linearGradient
+       y2="449.80624"
+       x2="381.28015"
+       y1="684.16162"
+       x1="665.12128"
+       gradientTransform="matrix(0.336682,0,0,0.336682,-81.3739,-51.8729)"
+       gradientUnits="userSpaceOnUse"
+       id="linearGradient3484-3"
+       xlink:href="#linearGradient3751-8"
+       inkscape:collect="always" />
+    <linearGradient
+       inkscape:collect="always"
+       id="linearGradient3751-8">
+      <stop
+         style="stop-color:black;stop-opacity:1;"
+         offset="0"
+         id="stop3753-9" />
+      <stop
+         style="stop-color:black;stop-opacity:0;"
+         offset="1"
+         id="stop3755-7" />
+    </linearGradient>
+    <inkscape:perspective
+       id="perspective17-2"
+       inkscape:persp3d-origin="128 : 85.333333 : 1"
+       inkscape:vp_z="256 : 128 : 1"
+       inkscape:vp_y="0 : 1000 : 0"
+       inkscape:vp_x="0 : 128 : 1"
+       sodipodi:type="inkscape:persp3d" />
+    <inkscape:path-effect
+       vertical="false"
+       scale_y_rel="false"
+       prop_scale="1"
+       bendpath="m 266.25,32.092577 41.87495,0"
+       is_visible="true"
+       id="path-effect2844"
+       effect="bend_path" />
+  </defs>
+  <sodipodi:namedview
+     id="base"
+     pagecolor="#ffffff"
+     bordercolor="#666666"
+     borderopacity="1.0"
+     inkscape:pageopacity="0.0"
+     inkscape:pageshadow="2"
+     inkscape:zoom="1.1191406"
+     inkscape:cx="-124.08132"
+     inkscape:cy="70.174855"
+     inkscape:document-units="px"
+     inkscape:current-layer="layer1"
+     inkscape:window-width="1144"
+     inkscape:window-height="785"
+     inkscape:window-x="136"
+     inkscape:window-y="25"
+     showguides="true"
+     inkscape:guide-bbox="true"
+     width="256px"
+     height="256px"
+     borderlayer="false"
+     showgrid="false"
+     inkscape:window-maximized="0" />
+  <metadata
+     id="metadata7">
+    <rdf:RDF>
+      <cc:Work
+         rdf:about="">
+        <dc:format>image/svg+xml</dc:format>
+        <dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+      </cc:Work>
+    </rdf:RDF>
+  </metadata>
+  <g
+     inkscape:label="Capa 1"
+     inkscape:groupmode="layer"
+     id="layer1">
+    <rect
+       style="opacity:1;color:#000000;fill:#ffffff;fill-opacity:0.31313129000000001;fill-rule:nonzero;stroke:#7f7f7f;stroke-width:10.01399999999999935;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:block;overflow:visible"
+       id="rect1906"
+       width="246.30026"
+       height="246.30028"
+       x="4.8498545"
+       y="4.0691833"
+       inkscape:export-filename="/home/jesusda/docs/curro/yo/ultrastar-ng/base/theme-pod/images/no_cover.png"
+       inkscape:export-xdpi="89.889648"
+       inkscape:export-ydpi="89.889648" />
+    <rect
+       style="opacity:1;color:#000000;fill:#0000ff;fill-opacity:0.22608696;fill-rule:nonzero;stroke:none;stroke-width:10.60000038000000089;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:block;overflow:visible"
+       id="rect1913"
+       width="291.42856"
+       height="45.714287"
+       x="-16.285721"
+       y="181.50516" />
+    <path
+       style="font-size:39.83382034000000260px;font-family:Goblin;stroke:none;stroke-opacity:1;fill:#000000;fill-opacity:1"
+       d="M 58.72672,219.00823 L 44.00299,198.17717 L 44.00299,218.61923 L 40.30747,218.61923 L 40.30747,190.12482 L 41.86348,190.12482 L 56.19821,209.82778 L 56.19821,190.12482 L 59.89373,190.12482 L 59.89373,219.00823 L 58.72672,219.00823 M 64.3867,204.1289 C 64.3867,200.0055 65.41756,196.55635 67.47927,193.78144 C 69.55394,191.00659 72.34827,189.61915 75.86227,189.61912 C 79.8171,189.61915 82.84483,190.89637 84.94547,193.45079 C 87.05902,196.00526 88.11581,199.56463 88.11583,204.1289 C 88.11581,208.8099 87.05902,212.47949 84.94547,215.13766 C 82.83187,217.78288 79.80414,219.10548 75.86227,219.10548 C 72.27047,219.10548 69.45669,217.70508 67.42092,214.90426 C 65.39811,212.10345 64.3867,208.51167 64.3867,204.1289 M 68.47123,204.1289 C 68.47122,207.39653 69.11307,210.12603 70.39679,212.3174 C 71.69345,214.50878 73.51528,215.60447 75.86227,215.60447 C 78.52043,215.60447 80.54324,214.59955 81.9307,212.5897 C 83.33109,210.57986 84.03129,207.7596 84.03131,204.1289 C 84.03129,196.78975 81.30828,193.12017 75.86227,193.12014 C 73.45044,193.12017 71.61565,194.10564 70.35789,196.07656 C 69.10011,198.04752 68.47122,200.73163 68.47123,204.1289 M 122.75647,191.17513 L 121.45332,194.5011 C 120.20849,193.59345 118.25052,193.13962 115.57938,193.13959 C 113.07679,193.13962 111.06695,194.21585 109.54985,196.36831 C 108.0457,198.52081 107.29363,201.29569 107.29364,204.69296 C 107.29363,207.93465 108.06515,210.5669 109.6082,212.5897 C 111.1642,214.59955 113.16756,215.60447 115.61828,215.60447 C 118.28942,215.60447 120.34464,214.6579 121.78397,212.76475 L 123.92348,215.74062 C 121.66725,217.98386 118.7627,219.10548 115.20983,219.10548 C 111.48837,219.10548 108.55789,217.76343 106.41838,215.07931 C 104.27887,212.3952 103.20911,208.85529 103.20912,204.45955 C 103.20911,200.20648 104.35019,196.67305 106.63233,193.85925 C 108.91447,191.04549 111.8644,189.6386 115.48213,189.63857 C 118.58117,189.6386 121.00594,190.15079 122.75647,191.17513 M 127.01605,204.1289 C 127.01604,200.0055 128.0469,196.55635 130.10861,193.78144 C 132.18328,191.00659 134.97761,189.61915 138.49161,189.61912 C 142.44645,189.61915 145.47418,190.89637 147.57481,193.45079 C 149.68836,196.00526 150.74515,199.56463 150.74518,204.1289 C 150.74515,208.8099 149.68836,212.47949 147.57481,215.13766 C 145.46121,217.78288 142.43348,219.10548 138.49161,219.10548 C 134.89981,219.10548 132.08603,217.70508 130.05026,214.90426 C 128.02745,212.10345 127.01604,208.51167 127.01605,204.1289 M 131.10057,204.1289 C 131.10056,207.39653 131.74242,210.12603 133.02613,212.3174 C 134.32279,214.50878 136.14462,215.60447 138.49161,215.60447 C 141.14977,215.60447 143.17258,214.59955 144.56004,212.5897 C 145.96043,210.57986 146.66063,207.7596 146.66065,204.1289 C 146.66063,196.78975 143.93762,193.12017 138.49161,193.12014 C 136.07979,193.12017 134.24499,194.10564 132.98723,196.07656 C 131.72945,198.04752 131.10056,200.73163 131.10057,204.1289 M 165.13826,219.00823 L 163.1738,219.00823 L 152.55404,190.12482 L 156.87197,190.12482 L 164.20466,211.11149 L 171.26505,190.12482 L 175.44682,190.12482 L 165.13826,219.00823 M 182.52665,193.62584 L 182.52665,201.54204 L 191.94051,201.54204 L 191.94051,204.84856 L 182.52665,204.84856 L 182.52665,215.11821 L 195.44153,215.11821 L 195.44153,218.61923 L 178.63663,218.61923 L 178.63663,190.12482 L 195.65548,190.12482 L 195.65548,193.62584 L 182.52665,193.62584 M 215.76689,218.61923 L 208.1619,206.38511 C 207.29312,206.38513 205.91864,206.32029 204.03848,206.19061 L 204.03848,218.61923 L 200.14846,218.61923 L 200.14846,190.12482 C 200.29109,190.12485 201.29601,190.07947 203.16322,189.98867 C 205.04339,189.88497 206.41138,189.8331 207.26719,189.83307 C 214.11362,189.8331 217.53683,192.55611 217.53685,198.00212 C 217.53683,199.79155 216.98575,201.4059 215.88359,202.84519 C 214.7814,204.27155 213.47176,205.15977 211.95467,205.50986 L 220.22097,218.61923 L 215.76689,218.61923 M 204.03848,193.62584 L 204.03848,202.8841 C 204.97207,203.01378 205.87974,203.07861 206.76149,203.0786 C 209.09549,203.07861 210.79413,202.70258 211.85742,201.95049 C 212.92068,201.19844 213.45231,199.85638 213.45233,197.92432 C 213.45231,196.32943 212.88178,195.18188 211.74072,194.48165 C 210.59963,193.78147 208.79726,193.43137 206.33359,193.43134 C 205.94458,193.43137 205.17954,193.4962 204.03848,193.62584"
+       id="text1909" />
+    <path
+       style="fill:#000000;fill-opacity:1;stroke:#000000;stroke-width:1.40280461;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+       d="m 150.06592,185.68938 c -4.60748,-1.65764 -3.02251,-6.45629 -3.46934,-9.9616 0.45138,-2.29816 -0.81974,-4.1423 -1.53758,-6.17672 -0.65093,-2.92866 0.32225,-5.94531 1.98756,-8.44695 -0.11225,-6.62708 -1.73113,-13.11696 -2.83659,-19.60947 -0.5634,-4.70997 2.74548,-9.2889 0.84779,-13.89767 -1.46904,-4.34277 -1.42389,-8.84118 -1.35356,-13.34214 0.37405,-6.06667 -2.28758,-11.83498 -2.51296,-17.880806 -4.94948,-2.011 -4.58183,6.589956 -7.48859,8.935276 -1.93755,5.80211 -6.56939,10.34955 -9.15248,15.84237 -1.0796,3.21557 -2.14731,6.42925 -4.67981,8.95528 -3.94492,4.98803 -3.09551,11.88695 -7.37915,16.75106 -2.41299,4.83031 -6.25228,9.45184 -7.5511,14.55623 -0.73919,2.521 2.72056,4.45511 0.86328,6.86187 -1.94891,3.73982 -0.89276,7.99719 -1.86996,11.94519 -3.22233,0.0253 -2.29359,3.45536 -4.651424,4.49153 -2.00584,0.95556 -4.893543,1.2878 -6.860664,0.36653 -2.263319,-1.64154 -0.516986,-5.22107 0.562164,-7.31035 1.620486,-2.48333 2.66659,-5.11934 2.58929,-8.0539 0.40643,-2.34692 1.97441,-4.41653 1.86946,-6.91004 -0.45913,-2.76019 1.32116,-4.91181 1.97487,-7.33345 1.549324,-7.25078 4.847674,-14.12259 6.138794,-21.46583 2.43722,-4.95745 6.05943,-9.61678 7.24202,-14.97415 0.45945,-6.60418 3.08522,-12.82904 6.29493,-18.66454 0.87782,-4.050706 4.05654,-7.133006 5.26261,-11.051936 -0.51996,-3.457574 -0.87916,-6.917758 -0.33294,-10.392816 -2.09213,-5.931618 -6.12352,-11.12084 -7.41466,-17.313859 -0.81618,2.200211 -0.37618,6.158337 -0.7221,9.029368 -1.40657,5.679449 -3.33103,11.356489 -4.41847,17.037433 1.73574,2.838374 1.44674,6.119564 0.10495,9.049664 0.76578,1.62228 -1.08639,4.784376 -1.41843,1.68275 0.72076,-4.18196 -2.52721,-1.52836 -0.6401,0.99062 1.21022,2.057156 5.21453,4.987306 -0.0547,2.250046 -2.36934,-1.2345 -2.93795,-4.337476 -3.60066,-6.600426 0.92607,-3.14323 1.96527,-6.20945 1.68891,-9.520656 0.30158,-5.78565 -0.099,-11.657333 1.8842,-17.236965 0.60466,-6.866955 -0.15179,-13.899436 0.53127,-20.747169 0.24997,-2.980567 2.73471,-5.51103 6.03977,-5.224186 3.76945,0.02245 3.87528,-3.891744 1.37737,-2.151116 1.41312,-1.464416 5.70233,-9.908458 2.61089,-8.193922 -1.55725,-0.387174 0.51082,-3.256386 -2.2359,-4.668954 3.16893,1.053085 0.58407,-2.546707 2.06122,-3.635003 -1.88616,-3.120623 8.8269,2.457658 2.72294,-1.410043 -3.88665,-3.653436 2.98605,0.890388 5.40311,0.02806 -2.20254,-1.645687 -7.12086,-5.979903 -5.03163,-6.228088 -1.95596,-2.285617 1.58737,0.270742 0.62683,-2.5728 2.54629,1.637663 7.38032,5.973928 3.33334,0.65368 -2.52936,-3.540819 -1.35286,-2.770764 1.19933,-2.679441 1.32023,4.29303 5.25372,4.047596 1.67564,0.02833 2.42561,1.300905 5.9377,7.964395 3.95706,1.703622 2.30498,1.454259 3.19267,0.849482 4.37004,2.040856 0.43799,-2.598892 1.27142,3.452105 3.98394,0.173947 2.72604,-0.726455 3.59564,2.25773 5.07677,3.75542 2.87292,1.633735 5.46317,5.700213 1.94662,7.955782 -1.88108,1.835655 -0.0429,5.567535 0.74049,6.659254 -3.8222,-0.03198 0.47953,5.790806 0.44466,8.856186 -0.7948,4.045464 -3.30782,-6.334336 -4.72652,-3.861697 0.42033,2.593926 0.11386,5.178229 -1.37465,2.187169 -2.3909,3.391841 -2.04657,-2.896426 -2.67343,1.402495 1.05017,1.718212 -4.8369,1.246589 -0.53545,2.761898 2.92199,0.462309 7.7406,0.374633 7.85851,4.017885 0.30429,2.95627 -0.25587,5.779022 -1.56298,8.48663 -0.42541,4.157276 -0.31364,8.502407 0.45089,12.54074 3.84267,3.702645 5.8369,8.565052 8.25658,13.090578 1.4979,3.599908 0.55921,7.697308 1.48971,11.272268 1.56301,1.41868 1.40284,4.30409 0.75659,5.998196 -2.33258,2.50641 -0.48893,6.32063 -1.53683,9.3508 -1.18186,7.62161 -1.69711,15.37388 -1.00333,23.04293 1.51761,6.29688 -1.55448,12.56394 -1.57841,18.89311 0.25727,3.12682 -2.11686,6.45739 0.0197,9.2685 -2.87217,3.12469 -0.27636,7.4449 -0.25728,11.05758 0.23791,4.35542 4.34126,8.46847 2.3075,12.82654 -1.75303,1.40965 -3.75749,1.95065 -6.08938,0.72096 z M 119.9718,41.851919 c 0.0452,-1.192188 -1.08308,1.300484 0,0 z"
+       id="path2875" />
+  </g>
+</svg>
diff --git a/data/themes/default/dancebeat.svg b/data/themes/default/dancebeat.svg
new file mode 100644 (file)
index 0000000..69689a5
--- /dev/null
@@ -0,0 +1,248 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://creativecommons.org/ns#"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:xlink="http://www.w3.org/1999/xlink"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   version="1.0"
+   width="250"
+   height="520"
+   id="svg2"
+   sodipodi:version="0.32"
+   inkscape:version="0.47pre4 r22446"
+   sodipodi:docname="dancebeat.svg"
+   inkscape:output_extension="org.inkscape.output.svg.inkscape"
+   sodipodi:modified="true">
+  <metadata
+     id="metadata3009">
+    <rdf:RDF>
+      <cc:Work
+         rdf:about="">
+        <dc:format>image/svg+xml</dc:format>
+        <dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+      </cc:Work>
+    </rdf:RDF>
+  </metadata>
+  <sodipodi:namedview
+     inkscape:window-height="1124"
+     inkscape:window-width="1914"
+     inkscape:pageshadow="2"
+     inkscape:pageopacity="0.0"
+     borderopacity="1.0"
+     bordercolor="#666666"
+     pagecolor="#ffffff"
+     id="base"
+     inkscape:zoom="1.6493699"
+     inkscape:cx="17.383146"
+     inkscape:cy="260.2425"
+     inkscape:window-x="0"
+     inkscape:window-y="25"
+     inkscape:current-layer="svg2"
+     showgrid="true"
+     showguides="false"
+     inkscape:snap-global="true"
+     inkscape:snap-bbox="true"
+     inkscape:window-maximized="0">
+    <inkscape:grid
+       type="xygrid"
+       id="grid3223"
+       visible="true"
+       enabled="true"
+       empspacing="5"
+       snapvisiblegridlinesonly="true" />
+  </sodipodi:namedview>
+  <defs
+     id="defs4">
+    <linearGradient
+       id="linearGradient3725">
+      <stop
+         style="stop-color:#ffffff;stop-opacity:0.81884056;"
+         offset="0"
+         id="stop3727" />
+      <stop
+         id="stop3749"
+         offset="0.24528302"
+         style="stop-color:#ffffff;stop-opacity:0;" />
+      <stop
+         style="stop-color:#ffffff;stop-opacity:0;"
+         offset="1"
+         id="stop3729" />
+    </linearGradient>
+    <linearGradient
+       id="linearGradient3713">
+      <stop
+         id="stop3715"
+         offset="0"
+         style="stop-color:#3b41cc;stop-opacity:0.31884059;" />
+      <stop
+         style="stop-color:#3b41cc;stop-opacity:0;"
+         offset="0.58999997"
+         id="stop3747" />
+      <stop
+         id="stop3717"
+         offset="1"
+         style="stop-color:#3b41cc;stop-opacity:0;" />
+    </linearGradient>
+    <inkscape:perspective
+       sodipodi:type="inkscape:persp3d"
+       inkscape:vp_x="0 : 260 : 1"
+       inkscape:vp_y="0 : 1000 : 0"
+       inkscape:vp_z="250 : 260 : 1"
+       inkscape:persp3d-origin="125 : 173.33333 : 1"
+       id="perspective42" />
+    <linearGradient
+       id="linearGradient4387">
+      <stop
+         style="stop-color:#530d0d;stop-opacity:0;"
+         offset="0"
+         id="stop4389" />
+      <stop
+         id="stop10272"
+         offset="0.03502782"
+         style="stop-color:#5b0d0d;stop-opacity:0.93333333;" />
+      <stop
+         id="stop4395"
+         offset="0.5"
+         style="stop-color:#a61010;stop-opacity:0.93333334;" />
+      <stop
+         style="stop-color:#5a0d0d;stop-opacity:0.93333333;"
+         offset="0.96107578"
+         id="stop10270" />
+      <stop
+         style="stop-color:#530d0d;stop-opacity:0;"
+         offset="1"
+         id="stop4391" />
+    </linearGradient>
+    <linearGradient
+       id="linearGradient4109">
+      <stop
+         style="stop-color:#ffffff;stop-opacity:0.442029;"
+         offset="0"
+         id="stop4111" />
+      <stop
+         id="stop4117"
+         offset="0.25"
+         style="stop-color:#ffffff;stop-opacity:0;" />
+      <stop
+         style="stop-color:#ffffff;stop-opacity:0;"
+         offset="1"
+         id="stop4113" />
+    </linearGradient>
+    <linearGradient
+       id="linearGradient3207">
+      <stop
+         style="stop-color:#999999;stop-opacity:1;"
+         offset="0"
+         id="stop3209" />
+      <stop
+         style="stop-color:#5f5f5f;stop-opacity:1;"
+         offset="1"
+         id="stop3211" />
+    </linearGradient>
+    <linearGradient
+       id="linearGradient2417">
+      <stop
+         style="stop-color:#f2f2f2;stop-opacity:1;"
+         offset="0"
+         id="stop2419" />
+      <stop
+         style="stop-color:#999999;stop-opacity:0.73282444;"
+         offset="1"
+         id="stop2421" />
+    </linearGradient>
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient2417"
+       id="linearGradient3337"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(0.8922696,0,0,1.2260835,253.8584,-0.7360251)"
+       spreadMethod="reflect"
+       x1="-142.75803"
+       y1="0.78900218"
+       x2="-142.75803"
+       y2="4.6783328" />
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient3713"
+       id="linearGradient2937"
+       x1="115"
+       y1="520"
+       x2="115"
+       y2="0"
+       gradientUnits="userSpaceOnUse" />
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient3725"
+       id="linearGradient3731"
+       gradientUnits="userSpaceOnUse"
+       x1="0"
+       y1="520"
+       x2="0"
+       y2="390" />
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient4109"
+       id="linearGradient3737"
+       gradientUnits="userSpaceOnUse"
+       x1="0"
+       y1="520"
+       x2="0"
+       y2="390"
+       gradientTransform="translate(0,-130)" />
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient4109"
+       id="linearGradient3741"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="translate(0,-260)"
+       x1="0"
+       y1="520"
+       x2="0"
+       y2="390" />
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient4109"
+       id="linearGradient3745"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="translate(0,-390)"
+       x1="0"
+       y1="520"
+       x2="0"
+       y2="390" />
+  </defs>
+  <rect
+     y="390"
+     x="0"
+     height="130"
+     width="250"
+     id="rect3723"
+     style="fill:url(#linearGradient3731);fill-opacity:1.0" />
+  <rect
+     style="fill:url(#linearGradient3737);fill-opacity:1"
+     id="rect3735"
+     width="250"
+     height="130"
+     x="0"
+     y="260" />
+  <rect
+     y="130"
+     x="0"
+     height="130"
+     width="250"
+     id="rect3739"
+     style="fill:url(#linearGradient3741);fill-opacity:1" />
+  <rect
+     style="fill:url(#linearGradient3745);fill-opacity:1"
+     id="rect3743"
+     width="250"
+     height="130"
+     x="0"
+     y="0" />
+</svg>
diff --git a/data/themes/default/device_selector.svg b/data/themes/default/device_selector.svg
new file mode 100644 (file)
index 0000000..0ed0a8a
--- /dev/null
@@ -0,0 +1,69 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://creativecommons.org/ns#"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:xlink="http://www.w3.org/1999/xlink"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   xml:space="preserve"
+   version="1.0"
+   id="layer1"
+   width="256"
+   height="256"
+   viewBox="0 0 38.4 38.4"
+   inkscape:version="0.48.0 r9654"
+   sodipodi:docname="device_selector.svg"><defs
+   id="defs19"><linearGradient
+     id="linearGradient3762"><stop
+       style="stop-color:#00266f;stop-opacity:1;"
+       offset="0"
+       id="stop3764" /><stop
+       style="stop-color:#49338a;stop-opacity:1;"
+       offset="1"
+       id="stop3766" /></linearGradient><linearGradient
+     inkscape:collect="always"
+     xlink:href="#linearGradient3762"
+     id="linearGradient3768"
+     x1="33.130413"
+     y1="32.795361"
+     x2="6.3005142"
+     y2="6.3778343"
+     gradientUnits="userSpaceOnUse" /><filter
+     inkscape:collect="always"
+     id="filter3754"><feGaussianBlur
+       inkscape:collect="always"
+       stdDeviation="0.15"
+       id="feGaussianBlur3756" /></filter></defs><sodipodi:namedview
+   pagecolor="#ffffff"
+   bordercolor="#666666"
+   borderopacity="1"
+   objecttolerance="10"
+   gridtolerance="10"
+   guidetolerance="10"
+   inkscape:pageopacity="0"
+   inkscape:pageshadow="2"
+   inkscape:window-width="1057"
+   inkscape:window-height="784"
+   id="namedview17"
+   showgrid="false"
+   inkscape:zoom="2.328"
+   inkscape:cx="47.60517"
+   inkscape:cy="129.72509"
+   inkscape:window-x="165"
+   inkscape:window-y="112"
+   inkscape:window-maximized="0"
+   inkscape:current-layer="layer1" /><metadata
+   id="metadata1"><rdf:RDF><cc:Work
+       rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
+         rdf:resource="http://purl.org/dc/dcmitype/StillImage" /></cc:Work></rdf:RDF></metadata>
+<rect
+   style="fill:none;fill-opacity:1;fill-rule:evenodd;stroke:url(#linearGradient3768);stroke-width:2.39999999999999991;stroke-miterlimit:4;stroke-dasharray:none;opacity:1;stroke-linecap:butt;filter:url(#filter3754)"
+   id="rect2992"
+   width="30"
+   height="30"
+   x="4.1999998"
+   y="4.1999998"
+   ry="6.210372" /></svg>
\ No newline at end of file
diff --git a/data/themes/default/dialog_txt.svg b/data/themes/default/dialog_txt.svg
new file mode 100644 (file)
index 0000000..13ff6aa
--- /dev/null
@@ -0,0 +1,74 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Sodipodi ("http://www.sodipodi.com/") -->
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://creativecommons.org/ns#"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   version="1.0"
+   x="0"
+   y="0"
+   width="1000"
+   height="800"
+   id="svg559"
+   sodipodi:version="0.32"
+   inkscape:version="0.46"
+   sodipodi:docname="dialog_txt.svg"
+   sodipodi:docbase="/home/pim/tmp/UltraStar-ng/themes/lima"
+   inkscape:output_extension="org.inkscape.output.svg.inkscape"
+   sodipodi:modified="true">
+  <metadata
+     id="metadata35">
+    <rdf:RDF>
+      <cc:Work
+         rdf:about="">
+        <dc:format>image/svg+xml</dc:format>
+        <dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+      </cc:Work>
+    </rdf:RDF>
+  </metadata>
+  <sodipodi:namedview
+     inkscape:window-height="1125"
+     inkscape:window-width="1920"
+     inkscape:pageshadow="2"
+     inkscape:pageopacity="0.0"
+     guidetolerance="10.0"
+     gridtolerance="10.0"
+     objecttolerance="10.0"
+     borderopacity="1.0"
+     bordercolor="#666666"
+     pagecolor="#ffffff"
+     id="base"
+     inkscape:zoom="0.88479263"
+     inkscape:cx="400.80078"
+     inkscape:cy="473.88589"
+     inkscape:window-x="0"
+     inkscape:window-y="25"
+     inkscape:current-layer="svg559"
+     showgrid="false" />
+  <defs
+     id="defs561">
+    <inkscape:perspective
+       sodipodi:type="inkscape:persp3d"
+       inkscape:vp_x="0 : 300 : 1"
+       inkscape:vp_y="0 : 1000 : 0"
+       inkscape:vp_z="800 : 300 : 1"
+       inkscape:persp3d-origin="400 : 200 : 1"
+       id="perspective8" />
+  </defs>
+  <text
+     x="515.28125"
+     y="402.58807"
+     style="font-size:22px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:center;line-height:125%;writing-mode:lr-tb;text-anchor:middle;opacity:1;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1.58534133000000010;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;display:inline;font-family:Goblin;-inkscape-font-specification:Goblin"
+     id="text10203"
+     xml:space="preserve"
+     sodipodi:linespacing="125%"><tspan
+       x="515.28125"
+       y="402.58807"
+       id="tspan10205"
+       style="font-size:22px;text-align:center;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1.58534133000000010;-inkscape-font-specification:Goblin;font-family:Goblin;font-weight:normal;font-style:normal;font-stretch:normal;font-variant:normal">Dialog text</tspan></text>
+</svg>
diff --git a/data/themes/default/drumneck.svg b/data/themes/default/drumneck.svg
new file mode 100644 (file)
index 0000000..fcfba4a
--- /dev/null
@@ -0,0 +1,338 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://creativecommons.org/ns#"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:xlink="http://www.w3.org/1999/xlink"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   version="1.0"
+   width="200"
+   height="520"
+   id="svg2"
+   sodipodi:version="0.32"
+   inkscape:version="0.46"
+   sodipodi:docname="drumneck.svg"
+   sodipodi:docbase="/home/skyostil/proj/keyboardhero/trunk/data"
+   inkscape:output_extension="org.inkscape.output.svg.inkscape"
+   sodipodi:modified="true">
+  <metadata
+     id="metadata3009">
+    <rdf:RDF>
+      <cc:Work
+         rdf:about="">
+        <dc:format>image/svg+xml</dc:format>
+        <dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+      </cc:Work>
+    </rdf:RDF>
+  </metadata>
+  <sodipodi:namedview
+     inkscape:window-height="1127"
+     inkscape:window-width="1920"
+     inkscape:pageshadow="2"
+     inkscape:pageopacity="0.0"
+     borderopacity="1.0"
+     bordercolor="#666666"
+     pagecolor="#ffffff"
+     id="base"
+     inkscape:zoom="0.5025987"
+     inkscape:cx="-789.66498"
+     inkscape:cy="345.04969"
+     inkscape:window-x="0"
+     inkscape:window-y="25"
+     inkscape:current-layer="svg2"
+     showgrid="true"
+     showguides="false">
+    <inkscape:grid
+       type="xygrid"
+       id="grid3223"
+       visible="true"
+       enabled="true" />
+  </sodipodi:namedview>
+  <defs
+     id="defs4">
+    <inkscape:perspective
+       sodipodi:type="inkscape:persp3d"
+       inkscape:vp_x="0 : 526.18109 : 1"
+       inkscape:vp_y="0 : 1000 : 0"
+       inkscape:vp_z="744.09448 : 526.18109 : 1"
+       inkscape:persp3d-origin="372.04724 : 350.78739 : 1"
+       id="perspective25" />
+    <linearGradient
+       id="linearGradient3591">
+      <stop
+         style="stop-color:#000000;stop-opacity:0;"
+         offset="0"
+         id="stop3593" />
+      <stop
+         id="stop3599"
+         offset="0.1021521"
+         style="stop-color:#2a0000;stop-opacity:1;" />
+      <stop
+         style="stop-color:#440000;stop-opacity:1;"
+         offset="0.8938309"
+         id="stop3601" />
+      <stop
+         style="stop-color:#000000;stop-opacity:0;"
+         offset="1"
+         id="stop3595" />
+    </linearGradient>
+    <linearGradient
+       id="linearGradient3016">
+      <stop
+         style="stop-color:#4b0000;stop-opacity:1;"
+         offset="0"
+         id="stop3018" />
+      <stop
+         id="stop3024"
+         offset="0.5"
+         style="stop-color:#840000;stop-opacity:1;" />
+      <stop
+         style="stop-color:#4b0000;stop-opacity:1;"
+         offset="1"
+         id="stop3020" />
+    </linearGradient>
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient3016"
+       id="linearGradient3022"
+       x1="-196.5988"
+       y1="-0.14184041"
+       x2="198.1898"
+       y2="-0.14184041"
+       gradientUnits="userSpaceOnUse" />
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient3016"
+       id="linearGradient3030"
+       gradientUnits="userSpaceOnUse"
+       x1="-196.5988"
+       y1="-0.14184041"
+       x2="198.1898"
+       y2="-0.14184041" />
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient3016"
+       id="linearGradient3034"
+       gradientUnits="userSpaceOnUse"
+       x1="-196.5988"
+       y1="-0.14184041"
+       x2="198.1898"
+       y2="-0.14184041"
+       gradientTransform="translate(-10.04059,46.9656)" />
+    <inkscape:perspective
+       id="perspective2548"
+       inkscape:persp3d-origin="200 : 133.33333 : 1"
+       inkscape:vp_z="400 : 200 : 1"
+       inkscape:vp_y="0 : 1000 : 0"
+       inkscape:vp_x="0 : 200 : 1"
+       sodipodi:type="inkscape:persp3d" />
+  </defs>
+  <rect
+     y="-2.2854736"
+     x="0"
+     height="523.28027"
+     width="252.68669"
+     id="rect2405"
+     style="fill:#000000;fill-opacity:0.83902438;stroke:none;stroke-width:4;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" />
+  <g
+     transform="matrix(0.5969127,-0.1578621,0.1174074,0.7318426,-44.719635,266.31726)"
+     id="g2818">
+    <g
+       transform="matrix(0.651999,0,0,0.651999,-51.23088,-96.82474)"
+       id="g2820">
+      <g
+         transform="translate(87.13029,195.4545)"
+         style="font-size:12px;fill:#000000;fill-opacity:1;stroke:#000000;stroke-opacity:0.99122799"
+         id="g2822">
+        <path
+           d="M 294.895,259.711 C 285.199,267.084 283.042,269.56 277.684,277.719 C 275.745,280.868 272.124,288.227 271.134,293.164 C 270.145,298.1 269.404,305.262 269.407,309.055 C 269.419,321.908 273.51,329.971 277.978,329.69 C 281.97,329.232 287.05,325.069 294.748,315.614"
+           style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1pt;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:0.99122799"
+           id="path2824" />
+        <path
+           d="M 294.895,259.711 C 285.199,267.084 283.042,269.56 277.684,277.719 C 275.745,280.868 272.124,288.227 271.134,293.164 C 270.145,298.1 269.404,305.262 269.407,309.055 C 269.419,321.908 273.51,329.971 277.978,329.69 C 281.97,329.232 287.05,325.069 294.748,315.614"
+           transform="matrix(-1,0,0,1,596.772,0.208099)"
+           style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1pt;stroke-linecap:butt;stroke-linejoin:bevel;stroke-opacity:0.99122799"
+           id="path2826" />
+        <path
+           d="M 211.888,203.561 C 225.348,201.202 238.391,199.676 251.851,198.15 C 269.474,193.709 278.355,213.83 273.498,228.955 C 267.393,242.415 258.79,254.21 248.938,265.588 C 241.306,274.191 232.214,275.583 223.544,272.664 C 216.546,270.724 210.083,266.421 203.145,256.43 C 200.093,247.826 197.457,243.385 193.571,232.701 C 190.519,222.849 195.266,208.101 211.888,203.561 z"
+           transform="translate(0.588722,-3.051758e-5)"
+           style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1pt;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:0.99122799"
+           id="path2828" />
+        <path
+           d="M 211.888,203.561 C 225.348,201.202 238.391,199.676 251.851,198.15 C 269.474,193.709 278.355,213.83 273.498,228.955 C 267.393,242.415 258.79,254.21 248.938,265.588 C 241.306,274.191 232.214,275.583 223.544,272.664 C 216.546,270.724 210.083,266.421 203.145,256.43 C 200.093,247.826 197.457,243.385 193.571,232.701 C 190.519,222.849 195.266,208.101 211.888,203.561 z"
+           transform="matrix(-1,0,0,1,596.4468,-3.051758e-5)"
+           style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1pt;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:0.99122799"
+           id="path2830" />
+      </g>
+      <g
+         transform="translate(87.13029,195.4545)"
+         style="font-size:12px;stroke:#000000;stroke-opacity:0.99122799"
+         id="g2832">
+        <g
+           style="fill:none;fill-opacity:1;stroke:#000000;stroke-opacity:0.99122799"
+           id="g2834">
+          <g
+             style="font-size:12px;fill:none;fill-opacity:1;stroke:#000000;stroke-opacity:0.99122799"
+             id="g2836">
+            <path
+               d="M 212.232,318.53 C 217.922,331.874 219.682,336.945 223.785,350.248 C 227.281,362.537 228.566,370.042 230.726,387.506"
+               style="fill:none;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:6.25;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:0.99122799"
+               id="path2838" />
+            <path
+               d="M 212.232,318.53 C 217.922,331.874 219.682,336.945 223.785,350.248 C 227.281,362.537 228.566,370.042 230.726,387.506"
+               transform="matrix(-1,0,0,1,596.3183,-0.735886)"
+               style="fill:none;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:6.25;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:0.99122799"
+               id="path2840" />
+            <g
+               style="fill:none;fill-opacity:1;stroke:#000000;stroke-opacity:0.99122799"
+               id="g2842">
+              <path
+                 d="M 236.516,349.732 C 251.234,358.759 276.677,360.151 299.472,359.741 C 324.866,359.612 346.605,357.778 360.881,349.144"
+                 style="fill:none;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:5;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:0.99122799"
+                 id="path2844" />
+              <path
+                 d="M 241.667,373.282 C 257.905,383.486 277.001,386.99 298.993,386.16 C 321.835,385.604 339.344,383.682 354.994,372.988"
+                 style="fill:none;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:5;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:0.99122799"
+                 id="path2846" />
+              <g
+                 style="fill:none;fill-opacity:1;stroke:#000000;stroke-opacity:0.99122799"
+                 id="g2848">
+                <path
+                   d="M 229.893,385.644 C 247.26,406.592 271.501,410.229 299.066,410.959 C 328.585,412.036 358.232,400.314 365.885,385.645"
+                   style="fill:none;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:6.25;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:0.99122799"
+                   id="path2850" />
+                <g
+                   style="fill:none;fill-opacity:1;stroke:#000000;stroke-opacity:0.99122799"
+                   id="g2852">
+                  <path
+                     d="M 241.444,354.256 L 241.028,395.468"
+                     style="fill:none;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:5;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:0.99122799"
+                     id="path2854" />
+                  <path
+                     d="M 254.973,358.627 L 254.765,402.753"
+                     style="fill:none;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:5;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:0.99122799"
+                     id="path2856" />
+                  <path
+                     d="M 269.959,360.5 L 269.543,406.708"
+                     style="fill:none;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:5;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:0.99122799"
+                     id="path2858" />
+                  <path
+                     d="M 283.489,361.541 L 283.28,408.373"
+                     style="fill:none;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:5;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:0.99122799"
+                     id="path2860" />
+                  <path
+                     d="M 298.683,361.957 L 298.683,408.789"
+                     style="fill:none;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:5;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:0.99122799"
+                     id="path2862" />
+                  <path
+                     d="M 313.253,361.749 L 313.461,408.581"
+                     style="fill:none;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:5;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:0.99122799"
+                     id="path2864" />
+                  <path
+                     d="M 326.782,360.5 L 327.198,406.5"
+                     transform="translate(-0.41626,-3.051758e-5)"
+                     style="fill:none;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:5;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:0.99122799"
+                     id="path2866" />
+                  <path
+                     d="M 341.56,358.003 L 341.768,402.129"
+                     style="fill:none;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:5;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:0.99122799"
+                     id="path2868" />
+                  <path
+                     d="M 355.297,352.591 L 355.714,394.219"
+                     style="fill:none;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:5;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:0.99122799"
+                     id="path2870" />
+                </g>
+              </g>
+            </g>
+          </g>
+          <g
+             style="font-size:12px;fill:none;fill-opacity:1;stroke:#000000;stroke-opacity:0.99122799"
+             id="g2872">
+            <path
+               d="M 171.498,235.561 C 152.362,216.958 138.988,184.673 137.132,149.809 C 135.117,111.389 155.35,73.2389 185.669,51.4898 C 219.638,27.5804 276.435,20.9678 311.751,22.7523 C 335.672,22.7689 388.957,35.1725 407.766,49.18 C 440.76,73.1701 458.454,107.22 459.68,146.03 C 461.493,185.013 445.074,214.705 424.969,233.236"
+               style="fill:none;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:12.5;stroke-linecap:round;stroke-linejoin:round;stroke-dasharray:none;stroke-opacity:0.99122799"
+               id="path2874" />
+            <path
+               d="M 172.662,126.267 C 164.91,133.049 165.888,143.244 167.284,158.459 C 168.386,170.019 175.762,181.398 176.15,191.959 C 178.862,214.244 172.274,236.529 169.173,254.745 C 167.041,275.673 173.05,293.695 180.801,300.671 C 188.552,307.551 198.557,310.4 209.069,313.607 C 218.62,316.105 223.573,320.449 230.797,325.835 C 239.403,334.972 241.456,342.529 241.262,351.831"
+               style="fill:none;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:12.5;stroke-linecap:butt;stroke-linejoin:round;stroke-dasharray:none;stroke-opacity:0.99122799"
+               id="path2876" />
+            <path
+               d="M 172.662,126.267 C 164.91,133.049 165.888,143.244 167.284,158.459 C 168.386,170.019 175.762,181.398 176.15,191.959 C 178.862,214.244 172.274,236.529 169.173,254.745 C 167.041,275.673 173.05,293.695 180.801,300.671 C 188.552,307.551 202.738,311.246 209.069,313.607 C 216.446,316.188 223.989,320.865 230.797,326.251 C 238.987,334.139 241.456,342.529 241.262,351.831"
+               transform="matrix(-1,0,0,1,597.7228,-0.58139)"
+               style="fill:none;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:12.5;stroke-linecap:butt;stroke-linejoin:round;stroke-dasharray:none;stroke-opacity:0.99122799"
+               id="path2878" />
+            <path
+               d="M 194.821,310.959 C 201.759,327.749 209.113,344.123 209.807,361.329 C 206.616,375.205 207.587,391.579 211.056,404.623 C 215.497,422.523 232.842,443.753 250.188,450.83 C 267.949,457.282 279.05,458.948 298.892,458.948"
+               style="fill:none;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:12.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:0.99122799"
+               id="path2880" />
+            <path
+               d="M 194.821,310.959 C 201.759,327.749 209.113,344.123 209.807,361.329 C 206.616,375.205 207.587,391.579 211.056,404.623 C 215.497,422.523 233.05,443.129 250.396,450.206 C 267.741,457.283 278.841,458.948 298.684,458.948"
+               transform="matrix(-1,0,0,1,596.7438,-3.051758e-5)"
+               style="fill:none;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:12.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:0.99122799"
+               id="path2882" />
+          </g>
+        </g>
+        <g
+           style="stroke:#000000;stroke-opacity:0.99122799"
+           id="g2884">
+          <path
+             d="M 391.308,389.636 L 459.58,421.274 C 467.905,424.743 474.565,423.633 480.81,421.69 C 490.662,418.776 498.432,420.442 506.619,423.772 C 516.471,428.767 516.75,435.844 510.367,442.921 C 504.539,449.72 498.71,453.189 491.634,459.988 C 490.107,470.95 491.078,481.08 486.221,491.21 C 480.116,500.09 473.594,498.564 463.326,489.128 C 452.919,481.079 456.665,472.199 441.679,459.155 L 378.403,426.269 L 378.403,426.269"
+             style="fill:none;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:12.5;stroke-linecap:butt;stroke-linejoin:round;stroke-dasharray:none;stroke-opacity:0.99122799"
+             id="path2886" />
+          <path
+             d="M 204.812,389.22 C 182.055,401.292 161.38,412.531 135.293,422.522 C 114.062,427.795 114.895,414.752 89.0851,423.355 C 81.7307,429.183 81.8695,437.508 87.8363,443.752 C 94.7745,450.552 99.6313,454.854 105.737,460.821 C 107.68,469.424 107.957,476.778 109.067,487.046 C 113.23,499.674 122.388,498.98 130.297,492.875 C 133.766,488.573 138.068,484.688 140.704,479.97 C 144.312,473.726 148.336,466.649 153.193,460.821 L 216.052,427.518"
+             style="fill:none;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:12.5;stroke-linecap:butt;stroke-linejoin:round;stroke-dasharray:none;stroke-opacity:0.99122799"
+             id="path2888" />
+          <path
+             d="M 401.299,321.365 C 427.109,308.599 448.339,298.33 471.651,286.813 C 485.943,274.88 482.336,263.362 493.715,254.759 C 504.954,244.074 512.447,246.711 516.61,252.678 C 520.634,262.807 522.577,272.937 522.022,283.483 C 532.706,293.335 538.396,299.024 544.502,308.045 C 545.334,319.423 535.343,324.14 523.271,324.279 C 507.452,327.193 504.954,317.202 487.054,324.279 L 392.557,368.821 L 392.557,368.821"
+             style="fill:none;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:12.5;stroke-linecap:square;stroke-linejoin:round;stroke-dasharray:none;stroke-opacity:0.99122799"
+             id="path2890" />
+          <path
+             d="M 197.22,322.353 C 171.12,309.597 149.436,300.079 123.63,285.852 C 109.599,274.666 114.113,262.008 97.1383,251.706 C 89.6812,247.978 84.2847,246.31 78.2994,256.416 C 74.4727,265.444 74.7671,275.059 74.1784,284.381 C 67.5063,291.543 59.9511,295.763 54.4564,304.692 C 46.5087,317.448 58.5773,321.667 65.0532,323.237 C 83.4995,327.848 90.1715,319.508 107.146,322.942 C 140.213,338.347 173.573,354.34 205.462,370.039"
+             style="fill:none;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:12.5;stroke-linecap:butt;stroke-linejoin:round;stroke-dasharray:none;stroke-opacity:0.99122799"
+             id="path2892" />
+        </g>
+      </g>
+    </g>
+  </g>
+  <path
+     sodipodi:nodetypes="cc"
+     id="path2417"
+     d="M 4.1840998e-08,-3.6832e-07 L 250,-3.6832e-07"
+     style="fill:none;fill-rule:evenodd;stroke:#ffffff;stroke-width:10;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:0.49268293" />
+  <path
+     style="fill:none;fill-rule:evenodd;stroke:#ffffff;stroke-width:10;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:0.49268293"
+     d="M 4.1840998e-08,260 L 250,260"
+     id="path3191"
+     sodipodi:nodetypes="cc" />
+  <path
+     style="fill:none;fill-rule:evenodd;stroke:#ffffff;stroke-width:3;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:0.49268293"
+     d="M 25,519.99999 L 25,-3.6832e-07"
+     id="path3193"
+     sodipodi:nodetypes="cc" />
+  <path
+     sodipodi:nodetypes="cc"
+     id="path3195"
+     d="M 74.999999,519.99999 L 74.999999,-3.6832e-07"
+     style="fill:none;fill-rule:evenodd;stroke:#ffffff;stroke-width:3;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:0.49268293" />
+  <path
+     style="fill:none;fill-rule:evenodd;stroke:#ffffff;stroke-width:3;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:0.49268293"
+     d="M 125,519.99999 L 125,-3.6832e-07"
+     id="path3197"
+     sodipodi:nodetypes="cc" />
+  <path
+     sodipodi:nodetypes="cc"
+     id="path3199"
+     d="M 175,519.99999 L 175,-3.6832e-07"
+     style="fill:none;fill-rule:evenodd;stroke:#ffffff;stroke-width:3;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:0.49268293" />
+  <path
+     sodipodi:nodetypes="cc"
+     id="path3229"
+     d="M 4.1840998e-08,519.99999 L 250,519.99999"
+     style="fill:none;fill-rule:evenodd;stroke:#ffffff;stroke-width:10;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:0.49268293" />
+</svg>
diff --git a/data/themes/default/flame.svg b/data/themes/default/flame.svg
new file mode 100644 (file)
index 0000000..b0a7e68
--- /dev/null
@@ -0,0 +1,161 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://creativecommons.org/ns#"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:xlink="http://www.w3.org/1999/xlink"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   width="128"
+   height="128"
+   id="svg1901"
+   sodipodi:version="0.32"
+   inkscape:version="0.47pre4 r22446"
+   sodipodi:docname="flame.svg"
+   version="1.1">
+  <defs
+     id="defs1903">
+    <linearGradient
+       id="linearGradient3605">
+      <stop
+         style="stop-color:#ff0000;stop-opacity:0.88235295;"
+         offset="0"
+         id="stop3607" />
+      <stop
+         id="stop3613"
+         offset="0.5"
+         style="stop-color:#ffff00;stop-opacity:0.78431374;" />
+      <stop
+         style="stop-color:#ffff00;stop-opacity:0.3764706;"
+         offset="1"
+         id="stop3609" />
+    </linearGradient>
+    <inkscape:perspective
+       sodipodi:type="inkscape:persp3d"
+       inkscape:vp_x="0 : 526.18109 : 1"
+       inkscape:vp_y="0 : 1000 : 0"
+       inkscape:vp_z="744.09448 : 526.18109 : 1"
+       inkscape:persp3d-origin="372.04724 : 350.78739 : 1"
+       id="perspective7" />
+    <inkscape:perspective
+       id="perspective2821"
+       inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
+       inkscape:vp_z="1 : 0.5 : 1"
+       inkscape:vp_y="0 : 1000 : 0"
+       inkscape:vp_x="0 : 0.5 : 1"
+       sodipodi:type="inkscape:persp3d" />
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient3605"
+       id="linearGradient3611"
+       x1="164.57143"
+       y1="451.79074"
+       x2="164.57143"
+       y2="323.79074"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(0.85622228,0,0,0.89173546,15.722622,45.629923)" />
+    <inkscape:perspective
+       id="perspective3623"
+       inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
+       inkscape:vp_z="1 : 0.5 : 1"
+       inkscape:vp_y="0 : 1000 : 0"
+       inkscape:vp_x="0 : 0.5 : 1"
+       sodipodi:type="inkscape:persp3d" />
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient3605-4"
+       id="linearGradient3611-4"
+       x1="164.57143"
+       y1="451.79074"
+       x2="164.57143"
+       y2="323.79074"
+       gradientUnits="userSpaceOnUse" />
+    <linearGradient
+       id="linearGradient3605-4">
+      <stop
+         style="stop-color:#ff0000;stop-opacity:0.88235295;"
+         offset="0"
+         id="stop3607-1" />
+      <stop
+         id="stop3613-9"
+         offset="0.5"
+         style="stop-color:#ffff00;stop-opacity:0.78431374;" />
+      <stop
+         style="stop-color:#ffff00;stop-opacity:0.3764706;"
+         offset="1"
+         id="stop3609-4" />
+    </linearGradient>
+    <linearGradient
+       gradientTransform="matrix(-1,0,0,1,329.14286,-1.0238602e-5)"
+       y2="323.79074"
+       x2="164.57143"
+       y1="451.79074"
+       x1="164.57143"
+       gradientUnits="userSpaceOnUse"
+       id="linearGradient3633"
+       xlink:href="#linearGradient3605-4"
+       inkscape:collect="always" />
+    <filter
+       inkscape:collect="always"
+       id="filter4650"
+       x="-0.28828125"
+       width="1.5765625"
+       y="-0.5765625"
+       height="2.153125">
+      <feGaussianBlur
+         inkscape:collect="always"
+         stdDeviation="14.014386"
+         id="feGaussianBlur4652" />
+    </filter>
+  </defs>
+  <sodipodi:namedview
+     id="base"
+     pagecolor="#ffffff"
+     bordercolor="#666666"
+     borderopacity="1.0"
+     inkscape:pageopacity="0"
+     inkscape:pageshadow="2"
+     inkscape:zoom="3.959798"
+     inkscape:cx="19.163728"
+     inkscape:cy="62.215768"
+     inkscape:document-units="px"
+     inkscape:current-layer="layer1"
+     inkscape:window-width="1680"
+     inkscape:window-height="1026"
+     inkscape:window-x="0"
+     inkscape:window-y="24"
+     showgrid="false"
+     inkscape:window-maximized="1" />
+  <metadata
+     id="metadata1906">
+    <rdf:RDF>
+      <cc:Work
+         rdf:about="">
+        <dc:format>image/svg+xml</dc:format>
+        <dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+        <dc:title />
+      </cc:Work>
+    </rdf:RDF>
+  </metadata>
+  <g
+     inkscape:label="Taso 1"
+     inkscape:groupmode="layer"
+     id="layer1"
+     transform="translate(-100.57143,-323.79074)">
+    <path
+       sodipodi:type="arc"
+       style="opacity:0.73809521;color:#000000;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:7;marker:none;visibility:visible;display:inline;overflow:visible;filter:url(#filter4650);enable-background:accumulate"
+       id="path4102"
+       sodipodi:cx="60.861691"
+       sodipodi:cy="97.31662"
+       sodipodi:rx="58.336308"
+       sodipodi:ry="29.168154"
+       d="m 119.198,97.31662 a 58.336308,29.168154 0 1 1 -116.672617,0 58.336308,29.168154 0 1 1 116.672617,0 z"
+       transform="matrix(0.83918321,0,0,0.83918321,114.39962,325.29876)" />
+  </g>
+</svg>
diff --git a/data/themes/default/flame_godmode.svg b/data/themes/default/flame_godmode.svg
new file mode 100644 (file)
index 0000000..ca50d88
--- /dev/null
@@ -0,0 +1,225 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://creativecommons.org/ns#"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:xlink="http://www.w3.org/1999/xlink"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   width="128"
+   height="128"
+   id="svg1901"
+   sodipodi:version="0.32"
+   inkscape:version="0.47pre4 r22446"
+   sodipodi:docname="flame_godmode.svg"
+   version="1.1">
+  <defs
+     id="defs1903">
+    <linearGradient
+       id="linearGradient3605">
+      <stop
+         style="stop-color:#ff0000;stop-opacity:0.88235295;"
+         offset="0"
+         id="stop3607" />
+      <stop
+         id="stop3613"
+         offset="0.5"
+         style="stop-color:#ffff00;stop-opacity:0.78431374;" />
+      <stop
+         style="stop-color:#ffff00;stop-opacity:0.3764706;"
+         offset="1"
+         id="stop3609" />
+    </linearGradient>
+    <inkscape:perspective
+       sodipodi:type="inkscape:persp3d"
+       inkscape:vp_x="0 : 526.18109 : 1"
+       inkscape:vp_y="0 : 1000 : 0"
+       inkscape:vp_z="744.09448 : 526.18109 : 1"
+       inkscape:persp3d-origin="372.04724 : 350.78739 : 1"
+       id="perspective7" />
+    <inkscape:perspective
+       id="perspective2821"
+       inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
+       inkscape:vp_z="1 : 0.5 : 1"
+       inkscape:vp_y="0 : 1000 : 0"
+       inkscape:vp_x="0 : 0.5 : 1"
+       sodipodi:type="inkscape:persp3d" />
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient3605"
+       id="linearGradient3611"
+       x1="164.57143"
+       y1="451.79074"
+       x2="164.57143"
+       y2="323.79074"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(0.85622228,0,0,0.89173546,15.722622,45.629923)" />
+    <inkscape:perspective
+       id="perspective3623"
+       inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
+       inkscape:vp_z="1 : 0.5 : 1"
+       inkscape:vp_y="0 : 1000 : 0"
+       inkscape:vp_x="0 : 0.5 : 1"
+       sodipodi:type="inkscape:persp3d" />
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient3605-4"
+       id="linearGradient3611-4"
+       x1="164.57143"
+       y1="451.79074"
+       x2="164.57143"
+       y2="323.79074"
+       gradientUnits="userSpaceOnUse" />
+    <linearGradient
+       id="linearGradient3605-4">
+      <stop
+         style="stop-color:#ff0000;stop-opacity:0.88235295;"
+         offset="0"
+         id="stop3607-1" />
+      <stop
+         id="stop3613-9"
+         offset="0.5"
+         style="stop-color:#ffff00;stop-opacity:0.78431374;" />
+      <stop
+         style="stop-color:#ffff00;stop-opacity:0.3764706;"
+         offset="1"
+         id="stop3609-4" />
+    </linearGradient>
+    <linearGradient
+       gradientTransform="matrix(-1,0,0,1,329.14286,-1.0238602e-5)"
+       y2="323.79074"
+       x2="164.57143"
+       y1="451.79074"
+       x1="164.57143"
+       gradientUnits="userSpaceOnUse"
+       id="linearGradient3633"
+       xlink:href="#linearGradient3605-4"
+       inkscape:collect="always" />
+    <filter
+       inkscape:collect="always"
+       id="filter4650"
+       x="-0.28828125"
+       width="1.5765625"
+       y="-0.5765625"
+       height="2.153125">
+      <feGaussianBlur
+         inkscape:collect="always"
+         stdDeviation="14.014386"
+         id="feGaussianBlur4652" />
+    </filter>
+  </defs>
+  <sodipodi:namedview
+     id="base"
+     pagecolor="#000000"
+     bordercolor="#666666"
+     borderopacity="1.0"
+     inkscape:pageopacity="1"
+     inkscape:pageshadow="2"
+     inkscape:zoom="3.959798"
+     inkscape:cx="74.469579"
+     inkscape:cy="61.205615"
+     inkscape:document-units="px"
+     inkscape:current-layer="layer1"
+     inkscape:window-width="1680"
+     inkscape:window-height="1026"
+     inkscape:window-x="0"
+     inkscape:window-y="24"
+     showgrid="false"
+     inkscape:window-maximized="1" />
+  <metadata
+     id="metadata1906">
+    <rdf:RDF>
+      <cc:Work
+         rdf:about="">
+        <dc:format>image/svg+xml</dc:format>
+        <dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+        <dc:title></dc:title>
+      </cc:Work>
+    </rdf:RDF>
+  </metadata>
+  <g
+     inkscape:label="Taso 1"
+     inkscape:groupmode="layer"
+     id="layer1"
+     transform="translate(-100.57143,-323.79074)">
+    <path
+       sodipodi:type="arc"
+       style="opacity:0.73809521;color:#000000;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:7;marker:none;visibility:visible;display:inline;overflow:visible;filter:url(#filter4650);enable-background:accumulate"
+       id="path4102"
+       sodipodi:cx="60.861691"
+       sodipodi:cy="97.31662"
+       sodipodi:rx="58.336308"
+       sodipodi:ry="29.168154"
+       d="m 119.198,97.31662 c 0,16.10913 -26.118056,29.16815 -58.336309,29.16815 -32.218253,0 -58.336308,-13.05902 -58.336308,-29.16815 0,-16.109127 26.118055,-29.168154 58.336308,-29.168154 32.218253,0 58.336309,13.059027 58.336309,29.168154 z"
+       transform="matrix(0.83918321,0,0,0.83918321,114.39962,325.29876)" />
+    <path
+       transform="translate(113.95595,353.3377)"
+       d="M 40.19067,66.417802 18.687822,48.553072 -2.815025,66.417803 15.049705,44.914955 -2.8150251,23.412108 18.687822,41.276838 40.19067,23.412108 22.32594,44.914955 40.19067,66.417802 z"
+       inkscape:randomized="0"
+       inkscape:rounded="0"
+       inkscape:flatsided="false"
+       sodipodi:arg2="1.5707963"
+       sodipodi:arg1="0.78539816"
+       sodipodi:r2="3.6381173"
+       sodipodi:r1="30.409618"
+       sodipodi:cy="44.914955"
+       sodipodi:cx="18.687822"
+       sodipodi:sides="4"
+       id="path2851"
+       style="color:#000000;fill:#ffffff;stroke:none;stroke-width:1px;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+       sodipodi:type="star" />
+    <path
+       transform="translate(170.27196,366.97476)"
+       d="M 40.19067,66.417802 18.687822,48.553072 -2.815025,66.417803 15.049705,44.914955 -2.8150251,23.412108 18.687822,41.276838 40.19067,23.412108 22.32594,44.914955 40.19067,66.417802 z"
+       inkscape:randomized="0"
+       inkscape:rounded="0"
+       inkscape:flatsided="false"
+       sodipodi:arg2="1.5707963"
+       sodipodi:arg1="0.78539816"
+       sodipodi:r2="3.6381173"
+       sodipodi:r1="30.409618"
+       sodipodi:cy="44.914955"
+       sodipodi:cx="18.687822"
+       sodipodi:sides="4"
+       id="path2853"
+       style="color:#000000;fill:#ffffff;stroke:none;stroke-width:1px;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+       sodipodi:type="star" />
+    <path
+       transform="matrix(0.48324621,0,0,0.48324621,160.9886,353.81924)"
+       d="M 40.19067,66.417802 18.687822,48.553072 -2.815025,66.417803 15.049705,44.914955 -2.8150251,23.412108 18.687822,41.276838 40.19067,23.412108 22.32594,44.914955 40.19067,66.417802 z"
+       inkscape:randomized="0"
+       inkscape:rounded="0"
+       inkscape:flatsided="false"
+       sodipodi:arg2="1.5707963"
+       sodipodi:arg1="0.78539816"
+       sodipodi:r2="3.6381173"
+       sodipodi:r1="30.409618"
+       sodipodi:cy="44.914955"
+       sodipodi:cx="18.687822"
+       sodipodi:sides="4"
+       id="path2855"
+       style="color:#000000;fill:#ffffff;stroke:none;stroke-width:1px;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+       sodipodi:type="star" />
+    <path
+       transform="matrix(0.62417906,0,0,0.62417906,132.34344,391.17835)"
+       d="M 40.19067,66.417802 18.687822,48.553072 -2.815025,66.417803 15.049705,44.914955 -2.8150251,23.412108 18.687822,41.276838 40.19067,23.412108 22.32594,44.914955 40.19067,66.417802 z"
+       inkscape:randomized="0"
+       inkscape:rounded="0"
+       inkscape:flatsided="false"
+       sodipodi:arg2="1.5707963"
+       sodipodi:arg1="0.78539816"
+       sodipodi:r2="3.6381173"
+       sodipodi:r1="30.409618"
+       sodipodi:cy="44.914955"
+       sodipodi:cx="18.687822"
+       sodipodi:sides="4"
+       id="path2857"
+       style="color:#000000;fill:#ffffff;stroke:none;stroke-width:1px;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+       sodipodi:type="star" />
+  </g>
+</svg>
diff --git a/data/themes/default/fret.obj b/data/themes/default/fret.obj
new file mode 100644 (file)
index 0000000..001706e
--- /dev/null
@@ -0,0 +1,515 @@
+# Fret object
+
+v  0.0000007153 -0.0000004768 0.1034815758
+v  0.0000007153 0.1913409233 0.1948112249
+v  -0.0732226372 0.1767761707 0.1948112249
+v  -0.1352984905 0.1352984905 0.1948112249
+v  -0.1767761707 0.0732226372 0.1948112249
+v  -0.1913411617 -0.0000004768 0.1948112100
+v  -0.1767761707 -0.0732238293 0.1948112100
+v  -0.1352984905 -0.1352996826 0.1948112100
+v  -0.0732226372 -0.1767773628 0.1948112100
+v  0.0000007153 -0.1913423538 0.1948112100
+v  0.0732238293 -0.1767773628 0.1948112100
+v  0.1352996826 -0.1352996826 0.1948112100
+v  0.1767773628 -0.0732238293 0.1948112100
+v  0.1913423538 -0.0000004768 0.1948112100
+v  0.1767771244 0.0732231140 0.1948112249
+v  0.1352994442 0.1352984905 0.1948112249
+v  0.0732238293 0.1767761707 0.1948112249
+v  0.0000007153 0.4169557095 0.0748493001
+v  -0.1595616341 0.3852167130 0.0748493001
+v  -0.2948319912 0.2948322296 0.0748493001
+v  -0.3852165937 0.1595618725 0.0748492777
+v  -0.4169555902 -0.0000004768 0.0748492777
+v  -0.3852168322 -0.1595625877 0.0748492777
+v  -0.2948321104 -0.2948329449 0.0748492628
+v  -0.1595616341 -0.3852181435 0.0748492628
+v  0.0000007153 -0.4169569016 0.0748492628
+v  0.1595630646 -0.3852181435 0.0748492628
+v  0.2948334217 -0.2948329449 0.0748492628
+v  0.3852181435 -0.1595625877 0.0748492777
+v  0.4169569016 -0.0000002384 0.0748492777
+v  0.3852179050 0.1595621109 0.0748492777
+v  0.2948329449 0.2948324680 0.0748493001
+v  0.1595623493 0.3852169514 0.0748493001
+v  0.0000007153 0.5018217564 0.0753878132
+v  -0.1920385361 0.4636228085 0.0753878132
+v  -0.3548412323 0.3548414707 0.0753877982
+v  -0.4636226892 0.1920385361 0.0753878206
+v  -0.5018217564 -0.0000004768 0.0753878132
+v  -0.4636226892 -0.1920394897 0.0753877982
+v  -0.3548414707 -0.3548424244 0.0753878206
+v  -0.1920385361 -0.4636240005 0.0753878132
+v  0.0000007153 -0.5018227100 0.0753878132
+v  0.1920397282 -0.4636240005 0.0753878132
+v  0.3548426628 -0.3548424244 0.0753878206
+v  0.4636240005 -0.1920394897 0.0753877982
+v  0.5018229485 -0.0000002384 0.0753878132
+v  0.4636237621 0.1920390129 0.0753878206
+v  0.3548421860 0.3548417091 0.0753877982
+v  0.1920392513 0.4636230469 0.0753878132
+v  0.0000007153 0.4999995232 -0.0000000219
+v  -0.1913411617 0.4619390965 -0.0000000219
+v  -0.3535528183 0.3535528183 -0.0000000219
+v  -0.4619390965 0.1913414001 -0.0000000219
+v  -0.4999994040 -0.0000004768 -0.0000000219
+v  -0.4619392157 -0.1913421154 -0.0000000219
+v  -0.3535528183 -0.3535537720 -0.0000000219
+v  -0.1913411617 -0.4619402885 -0.0000000219
+v  0.0000007153 -0.5000004768 -0.0000000219
+v  0.1913425922 -0.4619402885 -0.0000000219
+v  0.3535540104 -0.3535537720 -0.0000000219
+v  0.4619402885 -0.1913421154 -0.0000000219
+v  0.5000007153 -0.0000002384 -0.0000000219
+v  0.4619402885 0.1913416386 -0.0000000219
+v  0.3535537720 0.3535532951 -0.0000000219
+v  0.1913418770 0.4619393349 -0.0000000219
+v  0.0000007153 0.3260121346 0.1965681016
+v  -0.1247589588 0.3011956215 0.1965681165
+v  -0.2305250168 0.2305250168 0.1965681165
+v  -0.3011956215 0.1247589588 0.1965681165
+v  -0.3260117769 -0.0000004768 0.1965681016
+v  -0.3011956215 -0.1247601509 0.1965681016
+v  -0.2305250168 -0.2305259705 0.1965681016
+v  -0.1247589588 -0.3011968136 0.1965681016
+v  0.0000007153 -0.3260130882 0.1965681016
+v  0.1247603893 -0.3011968136 0.1965681016
+v  0.2305262089 -0.2305259705 0.1965681016
+v  0.3011968136 -0.1247601509 0.1965681016
+v  0.3260130882 -0.0000002384 0.1965681016
+v  0.3011968136 0.1247591972 0.1965681165
+v  0.2305259705 0.2305252552 0.1965681165
+v  0.1247599125 0.3011956215 0.1965681165
+v  0.0000007153 0.1181845665 0.1019219384
+v  -0.0452268124 0.1091883183 0.1019219384
+v  -0.0835688114 0.0835690498 0.1019219384
+v  -0.1091883183 0.0452270508 0.1019219384
+v  -0.1181845665 -0.0000004768 0.1019219384
+v  -0.1091883183 -0.0452280045 0.1019219384
+v  -0.0835690498 -0.0835697651 0.1019219384
+v  -0.0452268124 -0.1091892719 0.1019219384
+v  0.0000007153 -0.1181857586 0.1019219384
+v  0.0452282429 -0.1091892719 0.1019219384
+v  0.0835702419 -0.0835697651 0.1019219384
+v  0.1091895103 -0.0452280045 0.1019219384
+v  0.1181857586 -0.0000004768 0.1019219384
+v  0.1091895103 0.0452270508 0.1019219384
+v  0.0835702419 0.0835690498 0.1019219384
+v  0.0452280045 0.1091883183 0.1019219384
+# 97 vertices
+
+vt  0.0000000000 1.0000000000 0.0000000000
+vt  0.0625000000 1.0000000000 0.0000000000
+vt  0.1250000000 1.0000000000 0.0000000000
+vt  0.1875000000 1.0000000000 0.0000000000
+vt  0.2500000000 1.0000000000 0.0000000000
+vt  0.3125000000 1.0000000000 0.0000000000
+vt  0.3750000000 1.0000000000 0.0000000000
+vt  0.4374999702 1.0000000000 0.0000000000
+vt  0.4999999702 1.0000000000 0.0000000000
+vt  0.5624999404 1.0000000000 0.0000000000
+vt  0.6249999404 1.0000000000 0.0000000000
+vt  0.6874999404 1.0000000000 0.0000000000
+vt  0.7500000000 1.0000000000 0.0000000000
+vt  0.8125000000 1.0000000000 0.0000000000
+vt  0.8750000000 1.0000000000 0.0000000000
+vt  0.9375000596 1.0000000000 0.0000000000
+vt  0.0000000000 0.8750000000 0.0000000000
+vt  0.0625000000 0.8750000000 0.0000000000
+vt  0.1250000000 0.8750000000 0.0000000000
+vt  0.1875000000 0.8750000000 0.0000000000
+vt  0.2500000000 0.8750000000 0.0000000000
+vt  0.3125000000 0.8750000000 0.0000000000
+vt  0.3750000000 0.8750000000 0.0000000000
+vt  0.4374999702 0.8750000000 0.0000000000
+vt  0.4999999702 0.8750000000 0.0000000000
+vt  0.5624999404 0.8750000000 0.0000000000
+vt  0.6249999404 0.8750000000 0.0000000000
+vt  0.6874999404 0.8750000000 0.0000000000
+vt  0.7500000000 0.8750000000 0.0000000000
+vt  0.8125000000 0.8750000000 0.0000000000
+vt  0.8750000000 0.8750000000 0.0000000000
+vt  0.9375000596 0.8750000000 0.0000000000
+vt  1.0000001192 0.8750000000 0.0000000000
+vt  0.0000000000 0.7500000000 0.0000000000
+vt  0.0625000000 0.7500000000 0.0000000000
+vt  0.1250000000 0.7500000000 0.0000000000
+vt  0.1875000000 0.7500000000 0.0000000000
+vt  0.2500000000 0.7500000000 0.0000000000
+vt  0.3125000000 0.7500000000 0.0000000000
+vt  0.3750000000 0.7500000000 0.0000000000
+vt  0.4374999702 0.7500000000 0.0000000000
+vt  0.4999999702 0.7500000000 0.0000000000
+vt  0.5624999404 0.7500000000 0.0000000000
+vt  0.6249999404 0.7500000000 0.0000000000
+vt  0.6874999404 0.7500000000 0.0000000000
+vt  0.7500000000 0.7500000000 0.0000000000
+vt  0.8125000000 0.7500000000 0.0000000000
+vt  0.8750000000 0.7500000000 0.0000000000
+vt  0.9375000596 0.7500000000 0.0000000000
+vt  1.0000001192 0.7500000000 0.0000000000
+vt  0.0000000000 0.6250000000 0.0000000000
+vt  0.0625000000 0.6250000000 0.0000000000
+vt  0.1250000000 0.6250000000 0.0000000000
+vt  0.1875000000 0.6250000000 0.0000000000
+vt  0.2500000000 0.6250000000 0.0000000000
+vt  0.3125000000 0.6250000000 0.0000000000
+vt  0.3750000000 0.6250000000 0.0000000000
+vt  0.4374999702 0.6250000000 0.0000000000
+vt  0.4999999702 0.6250000000 0.0000000000
+vt  0.5624999404 0.6250000000 0.0000000000
+vt  0.6249999404 0.6250000000 0.0000000000
+vt  0.6874999404 0.6250000000 0.0000000000
+vt  0.7500000000 0.6250000000 0.0000000000
+vt  0.8125000000 0.6250000000 0.0000000000
+vt  0.8750000000 0.6250000000 0.0000000000
+vt  0.9375000596 0.6250000000 0.0000000000
+vt  1.0000001192 0.6250000000 0.0000000000
+vt  0.0000000000 0.5000000000 0.0000000000
+vt  0.0625000000 0.5000000000 0.0000000000
+vt  0.1250000000 0.5000000000 0.0000000000
+vt  0.1875000000 0.5000000000 0.0000000000
+vt  0.2500000000 0.5000000000 0.0000000000
+vt  0.3125000000 0.5000000000 0.0000000000
+vt  0.3750000000 0.5000000000 0.0000000000
+vt  0.4374999702 0.5000000000 0.0000000000
+vt  0.4999999702 0.5000000000 0.0000000000
+vt  0.5624999404 0.5000000000 0.0000000000
+vt  0.6249999404 0.5000000000 0.0000000000
+vt  0.6874999404 0.5000000000 0.0000000000
+vt  0.7500000000 0.5000000000 0.0000000000
+vt  0.8125000000 0.5000000000 0.0000000000
+vt  0.8750000000 0.5000000000 0.0000000000
+vt  0.9375000596 0.5000000000 0.0000000000
+vt  1.0000001192 0.5000000000 0.0000000000
+vt  0.0000000000 0.8003866673 0.0000000000
+vt  1.0000001192 0.8003866673 0.0000000000
+vt  0.0625000000 0.8003866673 0.0000000000
+vt  0.1250000000 0.8003866673 0.0000000000
+vt  0.1875000000 0.8003866673 0.0000000000
+vt  0.2500000000 0.8003866673 0.0000000000
+vt  0.3125000000 0.8003866673 0.0000000000
+vt  0.3750000000 0.8003866673 0.0000000000
+vt  0.4374999702 0.8003866673 0.0000000000
+vt  0.4999999404 0.8003866673 0.0000000000
+vt  0.5624999404 0.8003866673 0.0000000000
+vt  0.6249999404 0.8003866673 0.0000000000
+vt  0.6874999404 0.8003866673 0.0000000000
+vt  0.7500000000 0.8003866673 0.0000000000
+vt  0.8125000000 0.8003866673 0.0000000000
+vt  0.8750000000 0.8003866673 0.0000000000
+vt  0.9375000000 0.8003866673 0.0000000000
+vt  0.0000000000 0.9227918386 0.0000000000
+vt  0.9761041403 0.9227918386 0.0000000000
+vt  0.0386040956 0.9227918386 0.0000000000
+vt  0.0625000000 0.9227918386 0.0000000000
+vt  0.1011040956 0.9227918386 0.0000000000
+vt  0.1250000000 0.9227918386 0.0000000000
+vt  0.1636040956 0.9227918386 0.0000000000
+vt  0.1875000000 0.9227918386 0.0000000000
+vt  0.2261041105 0.9227918386 0.0000000000
+vt  0.2500000000 0.9227918386 0.0000000000
+vt  0.2886041105 0.9227918386 0.0000000000
+vt  0.3125000000 0.9227918386 0.0000000000
+vt  0.3511041105 0.9227918386 0.0000000000
+vt  0.3750000000 0.9227918386 0.0000000000
+vt  0.4136040807 0.9227918386 0.0000000000
+vt  0.4375000000 0.9227918386 0.0000000000
+vt  0.4761040807 0.9227918386 0.0000000000
+vt  0.4999999702 0.9227918386 0.0000000000
+vt  0.5386040211 0.9227918386 0.0000000000
+vt  0.5624999404 0.9227918386 0.0000000000
+vt  0.6011040807 0.9227918386 0.0000000000
+vt  0.6250000000 0.9227918386 0.0000000000
+vt  0.6636040211 0.9227918386 0.0000000000
+vt  0.6874999404 0.9227918386 0.0000000000
+vt  0.7261040807 0.9227918386 0.0000000000
+vt  0.7500000000 0.9227918386 0.0000000000
+vt  0.7886041403 0.9227918386 0.0000000000
+vt  0.8125000000 0.9227918386 0.0000000000
+vt  0.8511041403 0.9227918386 0.0000000000
+vt  0.8750000596 0.9227918386 0.0000000000
+vt  0.9136041403 0.9227918386 0.0000000000
+vt  0.9375000596 0.9227918386 0.0000000000
+# 133 texture vertices
+
+vn  -0.0000000000 0.0000000000 0.0049999999
+vn  -0.0000028757 -0.0017635220 0.0046786731
+vn  0.0007066720 -0.0020869889 0.0044883285
+vn  0.0014515370 -0.0016576933 0.0044883285
+vn  0.0019754181 -0.0009760293 0.0044883280
+vn  0.0021985578 -0.0001457730 0.0044883285
+vn  0.0020869875 0.0007066733 0.0044883289
+vn  0.0016576921 0.0014515356 0.0044883294
+vn  0.0009760302 0.0019754157 0.0044883289
+vn  0.0001457728 0.0021985557 0.0044883294
+vn  -0.0007066744 0.0020869870 0.0044883289
+vn  -0.0014515381 0.0016576906 0.0044883294
+vn  -0.0019754176 0.0009760263 0.0044883289
+vn  -0.0021985576 0.0001457721 0.0044883285
+vn  -0.0020869880 -0.0007066759 0.0044883280
+vn  -0.0016576921 -0.0014515409 0.0044883275
+vn  -0.0009586700 -0.0023090527 0.0043300376
+vn  -0.0001465860 0.0022108043 0.0044822828
+vn  -0.0009814642 0.0019864195 0.0044822833
+vn  -0.0016669232 0.0014596214 0.0044822842
+vn  -0.0020986111 0.0007106090 0.0044822837
+vn  -0.0022108022 -0.0001465845 0.0044822837
+vn  -0.0019864189 -0.0009814636 0.0044822837
+vn  -0.0014596224 -0.0016669215 0.0044822842
+vn  -0.0007106106 -0.0020986074 0.0044822851
+vn  0.0001465854 -0.0022107996 0.0044822847
+vn  0.0009814652 -0.0019864158 0.0044822851
+vn  0.0016669242 -0.0014596203 0.0044822842
+vn  0.0020986102 -0.0007106088 0.0044822837
+vn  0.0022108031 0.0001465878 0.0044822828
+vn  0.0019864168 0.0009814652 0.0044822842
+vn  0.0014596184 0.0016669260 0.0044822842
+vn  0.0007106091 0.0020986123 0.0044822828
+vn  -0.0002369510 0.0035277342 0.0035353845
+vn  -0.0015689185 0.0031685242 0.0035353852
+vn  -0.0026620319 0.0023269332 0.0035353878
+vn  -0.0033498774 0.0011310925 0.0035353852
+vn  -0.0035277323 -0.0002369506 0.0035353862
+vn  -0.0031685228 -0.0015689180 0.0035353866
+vn  -0.0023269376 -0.0026620333 0.0035353838
+vn  -0.0011310905 -0.0033498767 0.0035353869
+vn  0.0002369506 -0.0035277312 0.0035353878
+vn  0.0015689199 -0.0031685233 0.0035353857
+vn  0.0026620345 -0.0023269334 0.0035353857
+vn  0.0033498770 -0.0011310903 0.0035353866
+vn  0.0035277291 0.0002369521 0.0035353894
+vn  0.0031685173 0.0015689186 0.0035353911
+vn  0.0023269299 0.0026620331 0.0035353892
+vn  0.0011310893 0.0033498772 0.0035353869
+vn  0.0003306963 0.0049875951 -0.0001205623
+vn  -0.0016031442 0.0047344896 -0.0001205678
+vn  -0.0032929236 0.0037606009 -0.0001205578
+vn  -0.0044813841 0.0022141954 -0.0001205606
+vn  -0.0049875947 0.0003306992 -0.0001205657
+vn  -0.0047344891 -0.0016031456 -0.0001205591
+vn  -0.0037606030 -0.0032929210 -0.0001205673
+vn  -0.0022141968 -0.0044813831 -0.0001205682
+vn  -0.0003306971 -0.0049875951 -0.0001205590
+vn  0.0016031456 -0.0047344891 -0.0001205619
+vn  0.0032929259 -0.0037605988 -0.0001205654
+vn  0.0044813845 -0.0022141943 -0.0001205644
+vn  0.0049875951 -0.0003306971 -0.0001205590
+vn  0.0047344887 0.0016031479 -0.0001205495
+vn  0.0037605981 0.0032929268 -0.0001205502
+vn  0.0022141906 0.0044813864 -0.0001205544
+vn  0.0001504593 0.0021956100 0.0044896165
+vn  -0.0007012178 0.0020860573 0.0044896165
+vn  -0.0014461377 0.0016589203 0.0044896179
+vn  -0.0019708998 0.0009792279 0.0044896174
+vn  -0.0021956093 0.0001504589 0.0044896170
+vn  -0.0020860566 -0.0007012160 0.0044896174
+vn  -0.0016589210 -0.0014461380 0.0044896174
+vn  -0.0009792309 -0.0019708970 0.0044896184
+vn  -0.0001504590 -0.0021956067 0.0044896184
+vn  0.0007012172 -0.0020860541 0.0044896184
+vn  0.0014461398 -0.0016589186 0.0044896179
+vn  0.0019708981 -0.0009792292 0.0044896184
+vn  0.0021956095 -0.0001504569 0.0044896170
+vn  0.0020860555 0.0007012184 0.0044896174
+vn  0.0016589173 0.0014461395 0.0044896184
+vn  0.0009792269 0.0019709002 0.0044896174
+vn  -0.0000000008 -0.0028467039 0.0041105081
+vn  0.0011438610 -0.0023107007 0.0042839516
+vn  0.0019410575 -0.0016970717 0.0042839516
+vn  0.0024427446 -0.0008250771 0.0042839521
+vn  0.0025725444 0.0001725262 0.0042839525
+vn  0.0023106989 0.0011438609 0.0042839530
+vn  0.0016970710 0.0019410556 0.0042839530
+vn  0.0008250794 0.0024427420 0.0042839530
+vn  -0.0001725269 0.0025725428 0.0042839535
+vn  -0.0011438631 0.0023106975 0.0042839530
+vn  -0.0019410589 0.0016970657 0.0042839535
+vn  -0.0024427441 0.0008250753 0.0042839525
+vn  -0.0025725455 -0.0001725254 0.0042839516
+vn  -0.0023106996 -0.0011438649 0.0042839516
+vn  -0.0016970672 -0.0019410617 0.0042839516
+vn  -0.0008189199 -0.0019770572 0.0045189173
+# 97 vertex normals
+
+g Fret
+f 1/1/1 82/102/82 83/104/83
+f 1/2/1 83/105/83 84/106/84
+f 1/3/1 84/107/84 85/108/85
+f 1/4/1 85/109/85 86/110/86
+f 1/5/1 86/111/86 87/112/87
+f 1/6/1 87/113/87 88/114/88
+f 1/7/1 88/115/88 89/116/89
+f 1/8/1 89/117/89 90/118/90
+f 1/9/1 90/119/90 91/120/91
+f 1/10/1 91/121/91 92/122/92
+f 1/11/1 92/123/92 93/124/93
+f 1/12/1 93/125/93 94/126/94
+f 1/13/1 94/127/94 95/128/95
+f 1/14/1 95/129/95 96/130/96
+f 1/15/1 96/131/96 97/132/97
+f 1/16/1 97/133/97 82/103/82
+f 66/85/66 67/87/67 3/18/3
+f 3/18/3 2/17/2 66/85/66
+f 67/87/67 68/88/68 4/19/4
+f 4/19/4 3/18/3 67/87/67
+f 68/88/68 69/89/69 5/20/5
+f 5/20/5 4/19/4 68/88/68
+f 69/89/69 70/90/70 6/21/6
+f 6/21/6 5/20/5 69/89/69
+f 70/90/70 71/91/71 7/22/7
+f 7/22/7 6/21/6 70/90/70
+f 71/91/71 72/92/72 8/23/8
+f 8/23/8 7/22/7 71/91/71
+f 72/92/72 73/93/73 9/24/9
+f 9/24/9 8/23/8 72/92/72
+f 73/93/73 74/94/74 10/25/10
+f 10/25/10 9/24/9 73/93/73
+f 74/94/74 75/95/75 11/26/11
+f 11/26/11 10/25/10 74/94/74
+f 75/95/75 76/96/76 12/27/12
+f 12/27/12 11/26/11 75/95/75
+f 76/96/76 77/97/77 13/28/13
+f 13/28/13 12/27/12 76/96/76
+f 77/97/77 78/98/78 14/29/14
+f 14/29/14 13/28/13 77/97/77
+f 78/98/78 79/99/79 15/30/15
+f 15/30/15 14/29/14 78/98/78
+f 79/99/79 80/100/80 16/31/16
+f 16/31/16 15/30/15 79/99/79
+f 80/100/80 81/101/81 17/32/17
+f 17/32/17 16/31/16 80/100/80
+f 81/101/81 66/86/66 2/33/2
+f 2/33/2 17/32/17 81/101/81
+f 35/52/35 19/35/19 18/34/18
+f 18/34/18 34/51/34 35/52/35
+f 36/53/36 20/36/20 19/35/19
+f 19/35/19 35/52/35 36/53/36
+f 37/54/37 21/37/21 20/36/20
+f 20/36/20 36/53/36 37/54/37
+f 38/55/38 22/38/22 21/37/21
+f 21/37/21 37/54/37 38/55/38
+f 39/56/39 23/39/23 22/38/22
+f 22/38/22 38/55/38 39/56/39
+f 40/57/40 24/40/24 23/39/23
+f 23/39/23 39/56/39 40/57/40
+f 41/58/41 25/41/25 24/40/24
+f 24/40/24 40/57/40 41/58/41
+f 42/59/42 26/42/26 25/41/25
+f 25/41/25 41/58/41 42/59/42
+f 43/60/43 27/43/27 26/42/26
+f 26/42/26 42/59/42 43/60/43
+f 44/61/44 28/44/28 27/43/27
+f 27/43/27 43/60/43 44/61/44
+f 45/62/45 29/45/29 28/44/28
+f 28/44/28 44/61/44 45/62/45
+f 46/63/46 30/46/30 29/45/29
+f 29/45/29 45/62/45 46/63/46
+f 47/64/47 31/47/31 30/46/30
+f 30/46/30 46/63/46 47/64/47
+f 48/65/48 32/48/32 31/47/31
+f 31/47/31 47/64/47 48/65/48
+f 49/66/49 33/49/33 32/48/32
+f 32/48/32 48/65/48 49/66/49
+f 34/67/34 18/50/18 33/49/33
+f 33/49/33 49/66/49 34/67/34
+f 51/69/51 35/52/35 34/51/34
+f 34/51/34 50/68/50 51/69/51
+f 52/70/52 36/53/36 35/52/35
+f 35/52/35 51/69/51 52/70/52
+f 53/71/53 37/54/37 36/53/36
+f 36/53/36 52/70/52 53/71/53
+f 54/72/54 38/55/38 37/54/37
+f 37/54/37 53/71/53 54/72/54
+f 55/73/55 39/56/39 38/55/38
+f 38/55/38 54/72/54 55/73/55
+f 56/74/56 40/57/40 39/56/39
+f 39/56/39 55/73/55 56/74/56
+f 57/75/57 41/58/41 40/57/40
+f 40/57/40 56/74/56 57/75/57
+f 58/76/58 42/59/42 41/58/41
+f 41/58/41 57/75/57 58/76/58
+f 59/77/59 43/60/43 42/59/42
+f 42/59/42 58/76/58 59/77/59
+f 60/78/60 44/61/44 43/60/43
+f 43/60/43 59/77/59 60/78/60
+f 61/79/61 45/62/45 44/61/44
+f 44/61/44 60/78/60 61/79/61
+f 62/80/62 46/63/46 45/62/45
+f 45/62/45 61/79/61 62/80/62
+f 63/81/63 47/64/47 46/63/46
+f 46/63/46 62/80/62 63/81/63
+f 64/82/64 48/65/48 47/64/47
+f 47/64/47 63/81/63 64/82/64
+f 65/83/65 49/66/49 48/65/48
+f 48/65/48 64/82/64 65/83/65
+f 50/84/50 34/67/34 49/66/49
+f 49/66/49 65/83/65 50/84/50
+f 18/34/18 19/35/19 67/87/67
+f 67/87/67 66/85/66 18/34/18
+f 19/35/19 20/36/20 68/88/68
+f 68/88/68 67/87/67 19/35/19
+f 20/36/20 21/37/21 69/89/69
+f 69/89/69 68/88/68 20/36/20
+f 21/37/21 22/38/22 70/90/70
+f 70/90/70 69/89/69 21/37/21
+f 22/38/22 23/39/23 71/91/71
+f 71/91/71 70/90/70 22/38/22
+f 23/39/23 24/40/24 72/92/72
+f 72/92/72 71/91/71 23/39/23
+f 24/40/24 25/41/25 73/93/73
+f 73/93/73 72/92/72 24/40/24
+f 25/41/25 26/42/26 74/94/74
+f 74/94/74 73/93/73 25/41/25
+f 26/42/26 27/43/27 75/95/75
+f 75/95/75 74/94/74 26/42/26
+f 27/43/27 28/44/28 76/96/76
+f 76/96/76 75/95/75 27/43/27
+f 28/44/28 29/45/29 77/97/77
+f 77/97/77 76/96/76 28/44/28
+f 29/45/29 30/46/30 78/98/78
+f 78/98/78 77/97/77 29/45/29
+f 30/46/30 31/47/31 79/99/79
+f 79/99/79 78/98/78 30/46/30
+f 31/47/31 32/48/32 80/100/80
+f 80/100/80 79/99/79 31/47/31
+f 32/48/32 33/49/33 81/101/81
+f 81/101/81 80/100/80 32/48/32
+f 33/49/33 18/50/18 66/86/66
+f 66/86/66 81/101/81 33/49/33
+f 3/18/3 83/104/83 82/102/82
+f 82/102/82 2/17/2 3/18/3
+f 83/105/83 3/18/3 4/19/4
+f 4/19/4 84/106/84 83/105/83
+f 84/107/84 4/19/4 5/20/5
+f 5/20/5 85/108/85 84/107/84
+f 85/109/85 5/20/5 6/21/6
+f 6/21/6 86/110/86 85/109/85
+f 86/111/86 6/21/6 7/22/7
+f 7/22/7 87/112/87 86/111/86
+f 87/113/87 7/22/7 8/23/8
+f 8/23/8 88/114/88 87/113/87
+f 88/115/88 8/23/8 9/24/9
+f 9/24/9 89/116/89 88/115/88
+f 89/117/89 9/24/9 10/25/10
+f 10/25/10 90/118/90 89/117/89
+f 90/119/90 10/25/10 11/26/11
+f 11/26/11 91/120/91 90/119/90
+f 91/121/91 11/26/11 12/27/12
+f 12/27/12 92/122/92 91/121/91
+f 92/123/92 12/27/12 13/28/13
+f 13/28/13 93/124/93 92/123/92
+f 93/125/93 13/28/13 14/29/14
+f 14/29/14 94/126/94 93/125/93
+f 94/127/94 14/29/14 15/30/15
+f 15/30/15 95/128/95 94/127/94
+f 95/129/95 15/30/15 16/31/16
+f 16/31/16 96/130/96 95/129/95
+f 96/131/96 16/31/16 17/32/17
+f 17/32/17 97/132/97 96/131/96
+f 82/103/82 97/133/97 17/32/17
+f 17/32/17 2/33/2 82/103/82
+# 176 faces
+
+g
diff --git a/data/themes/default/fret_tap.obj b/data/themes/default/fret_tap.obj
new file mode 100644 (file)
index 0000000..668f822
--- /dev/null
@@ -0,0 +1,194 @@
+# Fret_tap object
+
+v  -0.0000000066 -0.1499983668 0.1526451111
+v  -0.1060660183 -0.1060643867 0.1526451111
+v  -0.1499999911 0.0000016412 0.1526451111
+v  -0.1060659960 0.1060676649 0.1526451260
+v  0.0000000018 0.1500016153 0.1526451260
+v  0.1060659960 0.1060676649 0.1526451260
+v  0.1499999911 0.0000016734 0.1526451111
+v  0.1060660630 -0.1060643345 0.1526451111
+v  -0.0000000046 -0.1060643941 0.2587111294
+v  -0.0749999955 -0.0749983713 0.2587111294
+v  -0.1060660183 0.0000016281 0.2587111294
+v  -0.0749999806 0.0750016347 0.2587111294
+v  0.0000000013 0.1060676426 0.2587111294
+v  0.0749999881 0.0750016347 0.2587111294
+v  0.1060660183 0.0000016508 0.2587111294
+v  0.0750000328 -0.0749983415 0.2587111294
+v  0.0000000000 0.0000016149 0.3026450872
+v  0.0000000000 0.0000016323 0.1034809500
+v  0.0000000000 0.1181867570 0.1019213125
+v  -0.0452275090 0.1091904789 0.1019213125
+v  -0.0835694894 0.0835712776 0.1019213051
+v  -0.1091888398 0.0452292934 0.1019213051
+v  -0.1181851178 0.0000016325 0.1019213125
+v  -0.1091888398 -0.0452257246 0.1019213051
+v  -0.0835696384 -0.0835676938 0.1019213125
+v  -0.0452275090 -0.1091872007 0.1019213051
+v  0.0000000000 -0.1181834787 0.1019213051
+v  0.0452275090 -0.1091872007 0.1019213051
+v  0.0835696384 -0.0835676938 0.1019213125
+v  0.1091888398 -0.0452257246 0.1019213051
+v  0.1181851178 0.0000016325 0.1019213125
+v  0.1091888398 0.0452292934 0.1019213051
+v  0.0835694894 0.0835712776 0.1019213051
+v  0.0452273563 0.1091904789 0.1019213125
+# 34 vertices
+
+vt  0.0000000000 0.5000000000 0.0000000000
+vt  0.1250000000 0.5000000000 0.0000000000
+vt  0.2500000000 0.5000000000 0.0000000000
+vt  0.3750000000 0.5000000000 0.0000000000
+vt  0.5000000000 0.5000000000 0.0000000000
+vt  0.6250000000 0.5000000000 0.0000000000
+vt  0.7500000000 0.5000000000 0.0000000000
+vt  0.8749999404 0.5000000000 0.0000000000
+vt  0.9999999404 0.5000000000 0.0000000000
+vt  0.0000000000 0.2500000000 0.0000000000
+vt  0.1250000000 0.2500000000 0.0000000000
+vt  0.2500000000 0.2500000000 0.0000000000
+vt  0.3750000000 0.2500000000 0.0000000000
+vt  0.5000000000 0.2500000000 0.0000000000
+vt  0.6250000000 0.2500000000 0.0000000000
+vt  0.7500000000 0.2500000000 0.0000000000
+vt  0.8749999404 0.2500000000 0.0000000000
+vt  0.9999999404 0.2500000000 0.0000000000
+vt  0.0000000000 0.0000000000 0.0000000000
+vt  0.1250000000 0.0000000000 0.0000000000
+vt  0.2500000000 0.0000000000 0.0000000000
+vt  0.3750000000 0.0000000000 0.0000000000
+vt  0.5000000000 0.0000000000 0.0000000000
+vt  0.6250000000 0.0000000000 0.0000000000
+vt  0.7500000000 0.0000000000 0.0000000000
+vt  0.8749999404 0.0000000000 0.0000000000
+vt  0.0000000000 1.0000000000 0.0000000000
+vt  0.0625000000 1.0000000000 0.0000000000
+vt  0.1250000000 1.0000000000 0.0000000000
+vt  0.1875000000 1.0000000000 0.0000000000
+vt  0.2500000000 1.0000000000 0.0000000000
+vt  0.3125000000 1.0000000000 0.0000000000
+vt  0.3750000000 1.0000000000 0.0000000000
+vt  0.4374999702 1.0000000000 0.0000000000
+vt  0.4999999702 1.0000000000 0.0000000000
+vt  0.5624999404 1.0000000000 0.0000000000
+vt  0.6249999404 1.0000000000 0.0000000000
+vt  0.6874999404 1.0000000000 0.0000000000
+vt  0.7500000000 1.0000000000 0.0000000000
+vt  0.8125000000 1.0000000000 0.0000000000
+vt  0.8750000000 1.0000000000 0.0000000000
+vt  0.9375000596 1.0000000000 0.0000000000
+vt  0.0000000000 0.9227918386 0.0000000000
+vt  0.9761041403 0.9227918386 0.0000000000
+vt  0.0386040956 0.9227918386 0.0000000000
+vt  0.0625000000 0.9227918386 0.0000000000
+vt  0.1011040956 0.9227918386 0.0000000000
+vt  0.1250000000 0.9227918386 0.0000000000
+vt  0.1636040956 0.9227918386 0.0000000000
+vt  0.1875000000 0.9227918386 0.0000000000
+vt  0.2261041105 0.9227918386 0.0000000000
+vt  0.2500000000 0.9227918386 0.0000000000
+vt  0.2886041105 0.9227918386 0.0000000000
+vt  0.3125000000 0.9227918386 0.0000000000
+vt  0.3511041105 0.9227918386 0.0000000000
+vt  0.3750000000 0.9227918386 0.0000000000
+vt  0.4136040807 0.9227918386 0.0000000000
+vt  0.4375000000 0.9227918386 0.0000000000
+vt  0.4761040807 0.9227918386 0.0000000000
+vt  0.4999999702 0.9227918386 0.0000000000
+vt  0.5386040211 0.9227918386 0.0000000000
+vt  0.5624999404 0.9227918386 0.0000000000
+vt  0.6011040807 0.9227918386 0.0000000000
+vt  0.6250000000 0.9227918386 0.0000000000
+vt  0.6636040211 0.9227918386 0.0000000000
+vt  0.6874999404 0.9227918386 0.0000000000
+vt  0.7261040807 0.9227918386 0.0000000000
+vt  0.7500000000 0.9227918386 0.0000000000
+vt  0.7886041403 0.9227918386 0.0000000000
+vt  0.8125000000 0.9227918386 0.0000000000
+vt  0.8511041403 0.9227918386 0.0000000000
+vt  0.8750000596 0.9227918386 0.0000000000
+vt  0.9136041403 0.9227918386 0.0000000000
+vt  0.9375000596 0.9227918386 0.0000000000
+# 74 texture vertices
+
+vn  -0.0006326789 -0.0045822668 0.0018980372
+vn  -0.0036875238 -0.0027927805 0.0018980370
+vn  -0.0045822668 0.0006326793 0.0018980372
+vn  -0.0027927801 0.0036875235 0.0018980375
+vn  0.0006326789 0.0045822668 0.0018980376
+vn  0.0036875233 0.0027927808 0.0018980375
+vn  0.0045822673 -0.0006326777 0.0018980372
+vn  0.0027927812 -0.0036875231 0.0018980368
+vn  0.0004025514 -0.0037669437 0.0032631406
+vn  -0.0023789846 -0.0029482779 0.0032631408
+vn  -0.0037669435 -0.0004025510 0.0032631408
+vn  -0.0029482776 0.0023789846 0.0032631413
+vn  -0.0004025509 0.0037669432 0.0032631410
+vn  0.0023789844 0.0029482779 0.0032631410
+vn  0.0037669435 0.0004025517 0.0032631408
+vn  0.0029482783 -0.0023789839 0.0032631406
+vn  0.0000000000 -0.0000000002 0.0049999999
+vn  -0.0000000000 0.0000000001 0.0049999999
+vn  0.0000000000 0.0000659771 0.0049995645
+vn  -0.0000252484 0.0000609549 0.0049995645
+vn  -0.0000466531 0.0000466528 0.0049995645
+vn  -0.0000609551 0.0000252485 0.0049995645
+vn  -0.0000659771 0.0000000000 0.0049995645
+vn  -0.0000609552 -0.0000252483 0.0049995645
+vn  -0.0000466531 -0.0000466526 0.0049995645
+vn  -0.0000252482 -0.0000609550 0.0049995645
+vn  -0.0000000000 -0.0000659772 0.0049995645
+vn  0.0000252482 -0.0000609550 0.0049995645
+vn  0.0000466531 -0.0000466526 0.0049995645
+vn  0.0000609552 -0.0000252483 0.0049995645
+vn  0.0000659771 0.0000000000 0.0049995645
+vn  0.0000609551 0.0000252485 0.0049995645
+vn  0.0000466530 0.0000466528 0.0049995645
+vn  0.0000252484 0.0000609549 0.0049995645
+# 34 vertex normals
+
+g Fret_tap
+f 10/11/10 2/2/2 1/1/1
+f 1/1/1 9/10/9 10/11/10
+f 11/12/11 3/3/3 2/2/2
+f 2/2/2 10/11/10 11/12/11
+f 12/13/12 4/4/4 3/3/3
+f 3/3/3 11/12/11 12/13/12
+f 13/14/13 5/5/5 4/4/4
+f 4/4/4 12/13/12 13/14/13
+f 14/15/14 6/6/6 5/5/5
+f 5/5/5 13/14/13 14/15/14
+f 15/16/15 7/7/7 6/6/6
+f 6/6/6 14/15/14 15/16/15
+f 16/17/16 8/8/8 7/7/7
+f 7/7/7 15/16/15 16/17/16
+f 9/18/9 1/9/1 8/8/8
+f 8/8/8 16/17/16 9/18/9
+f 17/19/17 10/11/10 9/10/9
+f 17/20/17 11/12/11 10/11/10
+f 17/21/17 12/13/12 11/12/11
+f 17/22/17 13/14/13 12/13/12
+f 17/23/17 14/15/14 13/14/13
+f 17/24/17 15/16/15 14/15/14
+f 17/25/17 16/17/16 15/16/15
+f 17/26/17 9/18/9 16/17/16
+f 18/27/18 19/43/19 20/45/20
+f 18/28/18 20/46/20 21/47/21
+f 18/29/18 21/48/21 22/49/22
+f 18/30/18 22/50/22 23/51/23
+f 18/31/18 23/52/23 24/53/24
+f 18/32/18 24/54/24 25/55/25
+f 18/33/18 25/56/25 26/57/26
+f 18/34/18 26/58/26 27/59/27
+f 18/35/18 27/60/27 28/61/28
+f 18/36/18 28/62/28 29/63/29
+f 18/37/18 29/64/29 30/65/30
+f 18/38/18 30/66/30 31/67/31
+f 18/39/18 31/68/31 32/69/32
+f 18/40/18 32/70/32 33/71/33
+f 18/41/18 33/72/33 34/73/34
+f 18/42/18 34/74/34 19/44/19
+# 40 faces
+
+g
diff --git a/data/themes/default/guitarneck.svg b/data/themes/default/guitarneck.svg
new file mode 100644 (file)
index 0000000..4f0b867
--- /dev/null
@@ -0,0 +1,281 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://creativecommons.org/ns#"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:xlink="http://www.w3.org/1999/xlink"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   version="1.0"
+   width="250"
+   height="520"
+   id="svg2"
+   sodipodi:version="0.32"
+   inkscape:version="0.47 r22583"
+   sodipodi:docname="guitarneck.svg"
+   inkscape:output_extension="org.inkscape.output.svg.inkscape"
+   sodipodi:modified="true">
+  <metadata
+     id="metadata3009">
+    <rdf:RDF>
+      <cc:Work
+         rdf:about="">
+        <dc:format>image/svg+xml</dc:format>
+        <dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+      </cc:Work>
+    </rdf:RDF>
+  </metadata>
+  <sodipodi:namedview
+     inkscape:window-height="854"
+     inkscape:window-width="1440"
+     inkscape:pageshadow="2"
+     inkscape:pageopacity="0.0"
+     borderopacity="1.0"
+     bordercolor="#666666"
+     pagecolor="#ffffff"
+     id="base"
+     inkscape:zoom="1.2557891"
+     inkscape:cx="-64.662274"
+     inkscape:cy="332.00336"
+     inkscape:window-x="0"
+     inkscape:window-y="0"
+     inkscape:current-layer="g4297"
+     showgrid="true"
+     showguides="false"
+     inkscape:snap-global="true"
+     inkscape:snap-bbox="true"
+     inkscape:window-maximized="1">
+    <inkscape:grid
+       type="xygrid"
+       id="grid3223"
+       visible="true"
+       enabled="true" />
+  </sodipodi:namedview>
+  <defs
+     id="defs4">
+    <inkscape:perspective
+       sodipodi:type="inkscape:persp3d"
+       inkscape:vp_x="0 : 260 : 1"
+       inkscape:vp_y="0 : 1000 : 0"
+       inkscape:vp_z="250 : 260 : 1"
+       inkscape:persp3d-origin="125 : 173.33333 : 1"
+       id="perspective42" />
+    <linearGradient
+       id="linearGradient4387">
+      <stop
+         style="stop-color:#672500;stop-opacity:0;"
+         offset="0"
+         id="stop4389" />
+      <stop
+         id="stop10272"
+         offset="0.03502782"
+         style="stop-color:#4c0d00;stop-opacity:0.93333334;" />
+      <stop
+         id="stop4395"
+         offset="0.5"
+         style="stop-color:#b21000;stop-opacity:0.93333334;" />
+      <stop
+         style="stop-color:#490b00;stop-opacity:0.93333334;"
+         offset="0.96107578"
+         id="stop10270" />
+      <stop
+         style="stop-color:#530d0d;stop-opacity:0;"
+         offset="1"
+         id="stop4391" />
+    </linearGradient>
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient4387"
+       id="linearGradient4393"
+       x1="3.9839032"
+       y1="259.35468"
+       x2="249.84105"
+       y2="259.35468"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(0.9893674,0,0,0.9937313,0,3.2659465)" />
+    <linearGradient
+       id="linearGradient4109">
+      <stop
+         style="stop-color:#ff0000;stop-opacity:0.50196081;"
+         offset="0"
+         id="stop4111" />
+      <stop
+         id="stop4117"
+         offset="0.5"
+         style="stop-color:#fd6405;stop-opacity:0.78481013;" />
+      <stop
+         style="stop-color:#ff0018;stop-opacity:0.31012657;"
+         offset="1"
+         id="stop4113" />
+    </linearGradient>
+    <linearGradient
+       id="linearGradient3207">
+      <stop
+         style="stop-color:#999999;stop-opacity:1;"
+         offset="0"
+         id="stop3209" />
+      <stop
+         style="stop-color:#5f5f5f;stop-opacity:1;"
+         offset="1"
+         id="stop3211" />
+    </linearGradient>
+    <linearGradient
+       id="linearGradient2417">
+      <stop
+         style="stop-color:#f2f2f2;stop-opacity:1;"
+         offset="0"
+         id="stop2419" />
+      <stop
+         style="stop-color:#999999;stop-opacity:0.73282444;"
+         offset="1"
+         id="stop2421" />
+    </linearGradient>
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient2417"
+       id="linearGradient3337"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(0.8922696,0,0,1.2260835,253.8584,-0.7360251)"
+       spreadMethod="reflect"
+       x1="-142.75803"
+       y1="0.78900218"
+       x2="-142.75803"
+       y2="4.6783328" />
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient4109"
+       id="linearGradient4301"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(1,0,0,1.0877042,14.263989,1.809904)"
+       x1="92.684113"
+       y1="164.62471"
+       x2="227.01991"
+       y2="194.92398" />
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient4109"
+       id="linearGradient4303"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(1.0775945,0,0,1.0893886,-24.832299,-46.77942)"
+       x1="64.430161"
+       y1="268.30783"
+       x2="146.39825"
+       y2="301.49274" />
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient3207"
+       id="linearGradient2516"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(1.2794074,0,0,1.0054914,364.3677,-1.4243308)"
+       spreadMethod="repeat"
+       x1="-265.2009"
+       y1="-3.3672962"
+       x2="-265.91348"
+       y2="-0.3399277" />
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient2417"
+       id="linearGradient10373"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(0.8756075,0,0,1.2260835,249.99996,-0.7360251)"
+       spreadMethod="reflect"
+       x1="-142.75803"
+       y1="0.78900218"
+       x2="-142.75803"
+       y2="4.6783328" />
+  </defs>
+  <rect
+     y="0.99479985"
+     x="0"
+     height="520"
+     width="250"
+     id="rect2405"
+     style="opacity:1;fill:url(#linearGradient4393);fill-opacity:1;stroke:none;stroke-width:4;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" />
+  <g
+     id="g4297">
+    <path
+       style="fill:url(#linearGradient4301);fill-opacity:1;fill-rule:evenodd;stroke:none"
+       d="M 151.32893,-2.7426601 C 188,54.03106 212.1501,113.52257 201.32893,179.30355 181.91633,297.3112 229.96274,410 229.96274,410 199.08562,373.7356 194.65243,357.75369 183.79243,323.68497 141.27689,190.31026 175.51933,190.21369 151.5073,110.25152 134.89923,54.94519 109.10987,39.323472 92.17322,-0.38861802"
+       id="use3265"
+       sodipodi:nodetypes="cscssc"
+       inkscape:transform-center-x="-42.595745"
+       inkscape:transform-center-y="206.37132" />
+    <path
+       sodipodi:nodetypes="cscssc"
+       id="path3261"
+       d="M 87.298327,523.32667 C -4.4335267,261.8734 53.870629,334.71139 88.853102,219.97041 123.8356,105.22945 67.086237,40 67.086237,40 c 0,0 62.968473,16.503833 62.968473,143.81917 0,127.31531 -44.311158,124.17171 -29.54077,206.69091 14.77038,82.51916 52.86242,132.81659 52.86242,132.81659"
+       style="fill:url(#linearGradient4303);fill-rule:evenodd;stroke:none"
+       inkscape:transform-center-x="23.248528"
+       inkscape:transform-center-y="-241.66338" />
+  </g>
+  <g
+     id="g3393">
+    <rect
+       y="-4.8890123"
+       x="0"
+       height="9.8890123"
+       width="250"
+       id="rect2415"
+       style="fill:url(#linearGradient10373);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:6;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+    <use
+       height="520"
+       width="250"
+       transform="translate(3.6930847e-8,259.60335)"
+       id="use3197"
+       xlink:href="#rect2415"
+       y="0"
+       x="0" />
+    <use
+       height="520"
+       width="250"
+       transform="translate(3.6930847e-8,519.40402)"
+       id="use3203"
+       xlink:href="#rect2415"
+       y="0"
+       x="0" />
+    <use
+       height="520"
+       width="250"
+       transform="matrix(0.8333333,0,0,1,53.926741,0)"
+       id="use3215"
+       xlink:href="#rect3205"
+       y="0"
+       x="0" />
+    <use
+       height="520"
+       width="250"
+       transform="matrix(0.6666667,0,0,1,109.29626,0)"
+       id="use3217"
+       xlink:href="#rect3205"
+       y="0"
+       x="0" />
+    <use
+       height="520"
+       width="250"
+       transform="matrix(0.5,0,0,1,163.22302,0)"
+       id="use3219"
+       xlink:href="#rect3205"
+       y="0"
+       x="0" />
+    <use
+       height="520"
+       width="250"
+       transform="matrix(0.3333333,0,0,1,216.42835,0)"
+       id="use3221"
+       xlink:href="#rect3205"
+       y="0"
+       x="0" />
+    <rect
+       y="-4.8101187"
+       x="20.56773"
+       height="528.36328"
+       width="9"
+       id="rect3205"
+       style="fill:url(#linearGradient2516);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:6;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+  </g>
+</svg>
diff --git a/data/themes/default/icon.bmp b/data/themes/default/icon.bmp
new file mode 100644 (file)
index 0000000..0ad4fce
Binary files /dev/null and b/data/themes/default/icon.bmp differ
diff --git a/data/themes/default/icon.png b/data/themes/default/icon.png
new file mode 100644 (file)
index 0000000..cf18c84
Binary files /dev/null and b/data/themes/default/icon.png differ
diff --git a/data/themes/default/icon.svg b/data/themes/default/icon.svg
new file mode 100644 (file)
index 0000000..bd762f7
--- /dev/null
@@ -0,0 +1,186 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://creativecommons.org/ns#"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:xlink="http://www.w3.org/1999/xlink"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   width="64"
+   height="64"
+   id="svg3048"
+   version="1.1"
+   inkscape:version="0.48.1 r9760"
+   sodipodi:docname="icon.svg"
+   inkscape:export-filename="./icon.png"
+   inkscape:export-xdpi="90"
+   inkscape:export-ydpi="90">
+  <defs
+     id="defs3050">
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient4351"
+       id="linearGradient3047"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(1.4301676,0,0,1.4301681,-13.203293,980.42008)"
+       x1="30.445436"
+       y1="49.898205"
+       x2="30.47093"
+       y2="40.705814" />
+    <linearGradient
+       inkscape:collect="always"
+       id="linearGradient4351">
+      <stop
+         style="stop-color:#ffffff;stop-opacity:1;"
+         offset="0"
+         id="stop4353" />
+      <stop
+         style="stop-color:#ffffff;stop-opacity:0;"
+         offset="1"
+         id="stop4355" />
+    </linearGradient>
+    <radialGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient3629-3"
+       id="radialGradient3049"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(0.07511259,-0.14640373,0.31280336,0.16048423,-266.7139,1057.1493)"
+       cx="727.25122"
+       cy="757.60583"
+       fx="727.25122"
+       fy="757.60583"
+       r="500" />
+    <linearGradient
+       id="linearGradient3629-3">
+      <stop
+         style="stop-color:#00cbff;stop-opacity:0;"
+         offset="0"
+         id="stop3631-1" />
+      <stop
+         style="stop-color:#0000ce;stop-opacity:1;"
+         offset="1"
+         id="stop3633-4" />
+    </linearGradient>
+    <filter
+       color-interpolation-filters="sRGB"
+       inkscape:collect="always"
+       id="filter4102">
+      <feGaussianBlur
+         inkscape:collect="always"
+         stdDeviation="10.689196"
+         id="feGaussianBlur4104" />
+    </filter>
+    <radialGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient3629-3-2"
+       id="radialGradient3049-9"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(0.07511259,-0.14640373,0.31280336,0.16048423,-266.7139,1057.1493)"
+       cx="727.25122"
+       cy="757.60583"
+       fx="727.25122"
+       fy="757.60583"
+       r="500" />
+    <linearGradient
+       id="linearGradient3629-3-2">
+      <stop
+         style="stop-color:#00cbff;stop-opacity:0;"
+         offset="0"
+         id="stop3631-1-6" />
+      <stop
+         style="stop-color:#0000ce;stop-opacity:1;"
+         offset="1"
+         id="stop3633-4-6" />
+    </linearGradient>
+  </defs>
+  <sodipodi:namedview
+     id="base"
+     pagecolor="#ffffff"
+     bordercolor="#666666"
+     borderopacity="1.0"
+     inkscape:pageopacity="0.0"
+     inkscape:pageshadow="2"
+     inkscape:zoom="5.6"
+     inkscape:cx="7.5884659"
+     inkscape:cy="34.870974"
+     inkscape:document-units="px"
+     inkscape:current-layer="layer1"
+     showgrid="false"
+     inkscape:window-width="1280"
+     inkscape:window-height="739"
+     inkscape:window-x="0"
+     inkscape:window-y="26"
+     inkscape:window-maximized="1" />
+  <metadata
+     id="metadata3053">
+    <rdf:RDF>
+      <cc:Work
+         rdf:about="">
+        <dc:format>image/svg+xml</dc:format>
+        <dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+        <dc:title />
+      </cc:Work>
+    </rdf:RDF>
+  </metadata>
+  <g
+     inkscape:label="Capa 1"
+     inkscape:groupmode="layer"
+     id="layer1"
+     transform="translate(0,-988.36218)">
+    <path
+       inkscape:connector-curvature="0"
+       style="fill:#ffffff;fill-opacity:1;stroke:none"
+       d="M 14.301675,988.36218 C 6.378546,988.36218 0,994.74078 0,1002.6639 l 0,35.3966 c 0,7.9231 6.378546,14.3017 14.301675,14.3017 l 35.396648,0 c 7.92312,0 14.30168,-6.3786 14.30168,-14.3017 l 0,-35.3966 c 0,-7.92312 -6.37856,-14.30172 -14.30168,-14.30172 l -35.396648,0 z"
+       id="rect2855-8" />
+    <path
+       style="fill:url(#radialGradient3049);fill-opacity:1;stroke:none"
+       d="m 14.302022,988.36218 c -7.923129,0 -14.301676,6.3786 -14.301676,14.30172 l 0,35.3966 c 0,7.9232 6.378547,14.3017 14.301676,14.3017 l 35.396647,0 c 7.923134,0 14.301674,-6.3785 14.301674,-14.3017 l 0,-35.3966 c 0,-7.92312 -6.37854,-14.30172 -14.301674,-14.30172 l -35.396647,0 z"
+       id="rect2855"
+       inkscape:connector-curvature="0" />
+    <path
+       style="opacity:0.3;fill:#ffffff;fill-opacity:1;stroke:none"
+       d="m 14.301689,988.36218 c -7.923129,0 -14.301676,6.3786 -14.301676,14.30172 l 0,12.0802 c 15.525165,13.2075 48.417309,11.8647 64,0 l 0,-12.0802 c 0,-7.92312 -6.37855,-14.30172 -14.301677,-14.30172 z"
+       id="rect2855-83"
+       inkscape:connector-curvature="0"
+       sodipodi:nodetypes="ssccsss" />
+    <path
+       transform="matrix(0.17178694,0,0,0.17320543,-154.13045,1042.417)"
+       id="path1939-0"
+       d="m 1077.7371,-298.93512 c -14.23,4.82045 -25.272,17.07679 -40.5625,19.34375 -16.5396,6.42255 -33.9604,17.15883 -39.93749,34.84375 -3.86066,17.63507 7.05159,33.79585 13.44299,49.33403 2.7177,5.64987 5.7418,11.14072 9.182,16.35347 -16.9148,28.10647 -26.15445,60.97532 -49.84374,84.593754 -3.28446,4.2066 -4.0471,9.91279 -6.4375,14.312499 -11.90138,8.64494 -9.39804,29.48494 3.78125,35.5 -2.72141,10.24779 -1.31106,21.30932 -0.96875,31.84375 2.27202,23.897498 6.36544,37.255804 10.24938,60.900044 10.29506,4.495497 61.15696,6.42352 86.74486,7.518841 4.5352,-12.415552 8.2368,-21.837815 5.9433,-4.793887 -4.8546,5.451249 3.1073,-10.22909 3.125,-15.78125 -0.232,-6.91335 4.6326,-12.62164 3.9687,-19.6875 -0.1981,-6.0760976 4.5862,-10.8420476 4.7188,-17.0624976 0.8877,-6.01123 7.438,-8.8790404 8.625,-14.9062504 3.355,-8.92733 1.8213,-18.80448 1.8125,-27.9375 2.5027,-7.35007 9.0666,-11.79115 14.1562,-17.0625 5.7728,-7.3577 6.6055,-17.60552 13.8125,-23.968749 10.9809,8.551139 27.9266,6.467869 36.9375,17.843749 6.1472,10.97305 20.2319,10.05515 30.5938,13.65625 17.6551,7.4915 35.0859,15.63863 53.125,22 8.8467,6.21187 17.8572,16.61076 29.9062,13.75 7.8178,-32.066599 11.212,-99.257783 -14.7812,-85.937503 -8.3682,1.38541 -15.4892,7.083084 -23.2813,9.375004 -3.5422,-0.56964 -4.2323,-3.7164 -4.8125,-6.468754 -5.7202,-10.58512 -18.964,-12.19175 -28.117,-18.48735 -3.2994,-1.63505 -7.1201,-3.14924 -9.9142,-5.26265 4.3321,-6.25041 2.5588,-14.59267 0.062,-20.9375 1.7038,-6.32883 -0.2261,-13.88561 4.6562,-19.09375 2.4662,-6.0895 -2.3302,-11.72068 -2.6875,-17.5 3.6575,-7.75845 -0.2648,-17.53211 -7.5312,-21.625 -0.02,-10.68903 -2.7035,-21.0945 -5.5625,-31.34375 -7.0238,-1.9202 -12.8088,3.28339 -17.9375,7.15625 -5.0543,-1.03242 -10.1395,0.97113 -14.4688,3.1875 -7.8617,-0.92057 -12.4799,-9.36199 -20.7187,-8.5 -2.5583,0.18376 -4.8286,0.86061 -2.6875,-2.46875 2.2773,-7.12236 0.2685,-14.82375 -2.1875,-21.40625 0.347,-13.82765 -6.6884,-27.53577 -17.0938,-36.28125 -7.6106,-4.2492 -16.7613,-4.89974 -25.3125,-5 z m -4.625,63.5625 c 2.3451,6.8718 8.3358,11.94203 14.8125,14.75 -3.0028,1.86643 -5.5166,6.64448 -9.1875,3.15625 -5.2429,-2.51528 -11.7944,-6.36906 -13.6875,-11.8125 2.7029,-1.55258 5.7886,-5.62007 8.0625,-6.09375 z"
+       style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;filter:url(#filter4102)"
+       inkscape:connector-curvature="0"
+       sodipodi:nodetypes="cccccccccccccccccccccccccccccccccccccccccccccc" />
+    <path
+       style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:0.11655536px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+       d="m 31.299203,993.35908 -2.455689,1.7878 -6.250837,2.4581 -1.384115,1.4301 -1.071573,0.8045 -0.223242,1.87712 0.446485,0.9832 1.205521,3.1732 1.51806,2.9497 1.652008,2.1006 -2.589634,4.2458 -2.946823,6.3464 -1.785953,2.8603 -2.902176,3.6201 -0.133958,1.6536 -1.518061,1.4302 2.32174,2.1006 -0.580436,2.5028 0.223246,5.4972 1.071569,6.391 0.892977,4.6481 9.286967,0 -0.625087,-0.1788 0.803678,-0.7151 -0.13396,-2.0112 0.848328,-1.743 -0.71438,0.089 1.294816,-2.2346 0,-2.2347 0.848329,-1.162 0,-1.5195 1.741305,-2.3687 0.13396,-2.0112 -0.357192,-1.6536 0.80368,-1.8771 0.937624,-1.5196 0,-0.9385 1.071573,-0.1341 0.937627,-0.9386 0.848328,-2.3687 1.875251,-2.1006 2.232441,-0.8491 1.384116,1.2067 3.437962,1.0279 2.72358,1.4302 1.294815,1.6536 2.232443,0.2235 7.054517,3.0838 3.61656,1.2961 2.94682,2.2346 0.62509,-0.1788 0,-0.8491 -1.56271,-1.2067 1.56271,0.4022 0,-3.3519 -0.26789,0 -1.38412,-0.5811 -0.93763,-0.4916 1.38412,-1.162 0.35719,-0.8491 -0.22325,-0.5811 -1.29481,0.2235 -2.72358,1.4302 -0.35719,0.7151 -0.93763,-0.2235 -3.39331,-1.9218 -0.13396,-1.2961 -2.0092,-1.0279 -3.393312,-1.7877 -0.848328,0.581 0.13396,-0.8045 -1.875252,-1.7877 -1.652009,-0.4469 -1.518061,-1.7877 -0.491136,-0.581 1.51806,1.0726 -0.223245,-1.2067 1.205518,0.6257 -0.35719,-1.7877 1.65201,1.5195 -0.714382,-1.0279 1.652004,0.6704 -1.428762,-1.9665 1.071575,0.3575 -0.491139,-1.9217 0.848326,0.715 -1.205518,-1.743 1.205518,0.3576 -1.071569,-1.4302 1.428762,-0.1341 -1.562711,-0.9385 0.937626,-0.447 -1.026922,-0.1341 1.384115,-1.2961 -1.294819,0.1341 0.13396,-0.8491 0.13396,-2.324 -0.714384,1.6089 -0.84833,-2.324 0.133961,1.8771 -0.491139,0.1341 -1.16087,0 -1.294818,-1.9218 -1.294815,0 -1.518062,-1.2961 -0.714381,0.7151 -1.785954,1.2067 -2.321739,0 -0.491136,1.162 0.491136,1.2961 -0.267893,1.3854 -1.16087,-0.6703 -0.937627,-1.7878 -2.009198,-0.4469 -0.803681,-0.8491 -1.785953,-0.8045 -2.009197,-3.3073 0.133959,-1.5195 4.956023,-3.79892 2.321741,1.0726 0.357188,0.8045 0,0.98322 0.625088,0.8045 1.160867,0.3575 0.80368,-0.7151 0.133958,-0.80442 -0.357189,-0.7151 -0.714385,-0.3575 -0.446486,-0.581 1.026923,-0.4916 -0.223243,-1.1621 0,-0.715 -0.714434,-0.7151 -0.357189,-1.0726 -1.384113,-0.3129 -1.205517,-0.2682 z"
+       id="path1939-09"
+       inkscape:connector-curvature="0" />
+    <path
+       style="fill:none;stroke:#ffffff;stroke-width:0.27772158;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+       d="m 31.212342,994.95748 c -4.607603,-1.7048 -6.516821,4.531 -5.565548,8.25652 1.113206,4.3598 1.455542,9.7055 -0.54919,13.6376 -1.436505,2.8175 -8.07984,3.8724 -7.996017,7.8324"
+       id="path3759-3"
+       sodipodi:nodetypes="cssc"
+       inkscape:connector-curvature="0" />
+    <path
+       style="opacity:0.8;fill:url(#linearGradient3047);fill-opacity:1;stroke:none"
+       d="m 3.46e-4,1038.0605 c 0,7.9232 6.378547,14.3017 14.301676,14.3017 l 35.396647,0 c 7.923134,0 14.301674,-6.3785 14.301674,-14.3017 -59.814553,0.1908 -2.06552,-0.035 -63.999997,0 z"
+       id="rect2855-9"
+       inkscape:connector-curvature="0"
+       sodipodi:nodetypes="csscc" />
+    <path
+       style="fill:none;stroke:#000000;stroke-width:1;stroke-miterlimit:4;stroke-opacity:0.17699116;stroke-dasharray:none"
+       d="m 14.578146,988.86204 c -7.7993597,0 -14.07826626,6.27896 -14.07826626,14.07836 l 0,34.8436 c 0,7.7994 6.27890656,14.0783 14.07826626,14.0783 l 34.843709,0 c 7.799365,0 14.078265,-6.2789 14.078265,-14.0783 l 0,-34.8436 c 0,-7.79939 -6.2789,-14.07835 -14.078265,-14.07835 l -34.843709,0 z"
+       id="rect2855-4"
+       inkscape:connector-curvature="0" />
+    <path
+       style="fill:none;stroke:#ffffff;stroke-width:0.99999189000000011;stroke-miterlimit:4;stroke-opacity:0.40789473;stroke-dasharray:none"
+       d="m 15.131283,989.86217 c -7.5517331,0 -13.631287,6.07961 -13.631287,13.63133 l 0,33.7373 c 0,7.5519 6.0795539,13.6314 13.631287,13.6314 l 33.737435,0 c 7.551739,0 13.631286,-6.0795 13.631286,-13.6314 l 0,-33.7373 c 0,-7.55171 -6.079547,-13.63132 -13.631286,-13.63132 l -33.737435,0 z"
+       id="rect2855-4-8"
+       inkscape:connector-curvature="0" />
+  </g>
+</svg>
diff --git a/data/themes/default/icon_pdev.svg b/data/themes/default/icon_pdev.svg
new file mode 100644 (file)
index 0000000..d17ca3c
--- /dev/null
@@ -0,0 +1,85 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://creativecommons.org/ns#"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   xml:space="preserve"
+   version="1.0"
+   id="layer1"
+   width="128"
+   height="128"
+   viewBox="0 0 19.2 19.2"
+   inkscape:version="0.48.0 r9654"
+   sodipodi:docname="icon_pdev.svg"><defs
+   id="defs19" /><sodipodi:namedview
+   pagecolor="#ffffff"
+   bordercolor="#666666"
+   borderopacity="1"
+   objecttolerance="10"
+   gridtolerance="10"
+   guidetolerance="10"
+   inkscape:pageopacity="0"
+   inkscape:pageshadow="2"
+   inkscape:window-width="1057"
+   inkscape:window-height="784"
+   id="namedview17"
+   showgrid="false"
+   inkscape:zoom="1.164"
+   inkscape:cx="253.43643"
+   inkscape:cy="146.90722"
+   inkscape:window-x="390"
+   inkscape:window-y="166"
+   inkscape:window-maximized="0"
+   inkscape:current-layer="layer1" /><metadata
+   id="metadata1"><rdf:RDF><cc:Work
+       rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
+         rdf:resource="http://purl.org/dc/dcmitype/StillImage" /></cc:Work></rdf:RDF></metadata><polygon
+   id="polygon1_extrashade"
+   points="40.389,62.75 40.389,14.769 40.389,14.769 23.235,29.606 7,29.606 7,48.699 22.989,48.699 "
+   style="stroke:#999999;stroke-width:5;stroke-linejoin:round"
+   transform="matrix(0.25667351,0,0,0.25667351,-0.23340565,-0.08139115)" /><g
+   id="g1shade"
+   transform="matrix(0.25667351,0,0,0.25667351,0.02326765,-0.08139115)"><polygon
+   id="polygon1s2"
+   points="39.389,62.75 39.389,13.769 39.389,13.769 22.235,28.606 6,28.606 6,47.699 21.989,47.699 "
+   style="stroke:#999999;stroke-width:5;stroke-linejoin:round" /><path
+   id="path1s"
+   d="m 48.128,49.03 c 1.929,-3.096 3.062,-6.739 3.062,-10.653 0,-3.978 -1.164,-7.674 -3.147,-10.8"
+   style="fill:none;stroke:#999999;stroke-width:5;stroke-linecap:round"
+   inkscape:connector-curvature="0" />
+<path
+   id="path2s"
+   d="m 55.082,20.537 c 3.695,4.986 5.884,11.157 5.884,17.84 0,6.621 -2.151,12.738 -5.788,17.699"
+   style="fill:none;stroke:#999999;stroke-width:5;stroke-linecap:round"
+   inkscape:connector-curvature="0" />
+<path
+   id="path9"
+   d="m 61.71,62.611 c 5.267,-6.666 8.418,-15.08 8.418,-24.233 0,-9.217 -3.192,-17.682 -8.519,-24.368"
+   style="fill:none;stroke:#999999;stroke-width:5;stroke-linecap:round"
+   inkscape:connector-curvature="0" />
+</g><g
+   id="g1"
+   transform="matrix(0.25667351,0,0,0.25667351,-0.23340565,-0.08139115)"><polygon
+   id="polygon1"
+   points="39.389,13.769 22.235,28.606 6,28.606 6,47.699 21.989,47.699 39.389,62.75 39.389,13.769 "
+   style="fill:#666666;stroke:#666666;stroke-width:5;stroke-linejoin:round" /><path
+   id="path1"
+   d="m 48.128,49.03 c 1.929,-3.096 3.062,-6.739 3.062,-10.653 0,-3.978 -1.164,-7.674 -3.147,-10.8"
+   style="fill:none;stroke:#666666;stroke-width:5;stroke-linecap:round"
+   inkscape:connector-curvature="0" />
+<path
+   id="path2"
+   d="m 55.082,20.537 c 3.695,4.986 5.884,11.157 5.884,17.84 0,6.621 -2.151,12.738 -5.788,17.699"
+   style="fill:none;stroke:#666666;stroke-width:5;stroke-linecap:round"
+   inkscape:connector-curvature="0" />
+<path
+   id="path15"
+   d="m 61.71,62.611 c 5.267,-6.666 8.418,-15.08 8.418,-24.233 0,-9.217 -3.192,-17.682 -8.519,-24.368"
+   style="fill:none;stroke:#666666;stroke-width:5;stroke-linecap:round"
+   inkscape:connector-curvature="0" />
+</g>
+</svg>
\ No newline at end of file
diff --git a/data/themes/default/instrument_cover.svg b/data/themes/default/instrument_cover.svg
new file mode 100644 (file)
index 0000000..2fc0778
--- /dev/null
@@ -0,0 +1,117 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://creativecommons.org/ns#"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:xlink="http://www.w3.org/1999/xlink"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   width="256"
+   height="256"
+   id="svg2"
+   sodipodi:version="0.32"
+   inkscape:version="0.46"
+   sodipodi:docbase="/home/yoda/UltraStar/sf/svn/UltraStar-ng/themes/lima"
+   sodipodi:docname="instrument_cover.svg"
+   inkscape:output_extension="org.inkscape.output.svg.inkscape"
+   version="1.0">
+  <defs
+     id="defs4">
+    <inkscape:perspective
+       sodipodi:type="inkscape:persp3d"
+       inkscape:vp_x="0 : 128 : 1"
+       inkscape:vp_y="0 : 1000 : 0"
+       inkscape:vp_z="256 : 128 : 1"
+       inkscape:persp3d-origin="128 : 85.333333 : 1"
+       id="perspective17" />
+    <linearGradient
+       id="linearGradient3751"
+       inkscape:collect="always">
+      <stop
+         id="stop3753"
+         offset="0"
+         style="stop-color:black;stop-opacity:1;" />
+      <stop
+         id="stop3755"
+         offset="1"
+         style="stop-color:black;stop-opacity:0;" />
+    </linearGradient>
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient3751"
+       id="linearGradient3484"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(0.336682,0,0,0.336682,-81.3739,-51.8729)"
+       x1="665.12128"
+       y1="684.16162"
+       x2="381.28015"
+       y2="449.80624" />
+  </defs>
+  <sodipodi:namedview
+     id="base"
+     pagecolor="#ffffff"
+     bordercolor="#666666"
+     borderopacity="1.0"
+     inkscape:pageopacity="0.0"
+     inkscape:pageshadow="2"
+     inkscape:zoom="1.1191406"
+     inkscape:cx="14.555935"
+     inkscape:cy="70.174855"
+     inkscape:document-units="px"
+     inkscape:current-layer="layer1"
+     inkscape:window-width="1144"
+     inkscape:window-height="785"
+     inkscape:window-x="136"
+     inkscape:window-y="25"
+     showguides="true"
+     inkscape:guide-bbox="true"
+     width="256px"
+     height="256px"
+     borderlayer="false"
+     showgrid="false" />
+  <metadata
+     id="metadata7">
+    <rdf:RDF>
+      <cc:Work
+         rdf:about="">
+        <dc:format>image/svg+xml</dc:format>
+        <dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+      </cc:Work>
+    </rdf:RDF>
+  </metadata>
+  <g
+     inkscape:label="Capa 1"
+     inkscape:groupmode="layer"
+     id="layer1">
+    <rect
+       style="opacity:1;color:#000000;fill:#ffffff;fill-opacity:0.31313129000000001;fill-rule:nonzero;stroke:#7f7f7f;stroke-width:10.01399999999999935;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:block;overflow:visible"
+       id="rect1906"
+       width="246.30026"
+       height="246.30028"
+       x="4.8498545"
+       y="4.0691833"
+       inkscape:export-filename="/home/jesusda/docs/curro/yo/ultrastar-ng/base/theme-pod/images/no_cover.png"
+       inkscape:export-xdpi="89.889648"
+       inkscape:export-ydpi="89.889648" />
+    <path
+       style="opacity:1;fill:#000000"
+       d="M 58.770328,163.09224 C 58.667128,162.65922 58.907858,162.33165 59.307738,162.36094 C 59.434798,162.37025 59.574458,162.348 59.618058,162.31152 C 59.694038,162.24796 59.829758,161.81959 59.812288,161.69848 C 59.807698,161.66652 59.445558,161.17684 59.007558,160.61029 C 58.018918,159.33152 57.142328,158.12101 56.257978,156.81331 C 54.862308,154.74948 53.121888,151.92373 52.493388,150.70105 C 50.938678,147.67664 50.096268,144.43182 50.053408,141.30298 C 50.036648,140.07945 50.240718,137.67269 50.439578,136.74815 C 51.072318,133.80685 52.501678,131.51856 55.213028,129.10627 C 56.848878,127.65088 59.707728,125.65418 61.460679,124.74276 C 64.699589,123.05877 68.687829,121.57213 75.295889,119.58561 C 79.031989,118.46246 80.109249,118.09709 81.533518,117.46998 C 85.251458,115.833 88.061728,113.30253 90.734398,109.18512 C 92.220188,106.89615 95.58264,101.90071 96.00588,101.35347 C 99.706114,96.569272 103.24812,93.685062 106.69671,92.648042 C 107.38444,92.441242 108.70449,92.191802 109.36335,92.144162 C 110.59661,92.054942 111.74608,92.304302 112.56925,92.839612 C 112.87777,93.040212 112.98277,93.138632 113.24499,93.473072 C 113.54455,93.855002 113.5553,93.863932 113.54953,93.726172 C 113.5462,93.647662 113.53301,93.570012 113.52015,93.553672 C 113.44391,93.456872 113.61169,93.490912 113.95377,93.641702 L 114.34528,93.814232 L 114.46227,93.668322 C 114.74427,93.316632 115.00274,93.267602 115.29798,93.509782 C 115.46435,93.646222 115.52066,93.804662 115.58644,94.321242 C 115.65145,94.832082 115.60704,95.009962 115.36351,95.213702 C 115.14349,95.397772 114.95905,95.404422 114.75741,95.235522 C 114.47673,95.000492 114.28011,95.069532 113.99662,95.502612 C 113.91874,95.621572 113.84915,95.724132 113.84193,95.730572 C 113.83472,95.736972 113.8141,95.653152 113.79613,95.544242 L 113.76344,95.346252 L 113.67952,95.609182 C 113.48243,96.226632 113.25611,96.509322 112.01811,97.684432 C 110.93379,98.713662 110.02775,99.651912 109.34329,100.45434 C 109.0697,100.77508 108.70186,101.201 108.52586,101.40083 C 108.14215,101.83647 107.97341,102.09504 107.76869,102.56111 C 107.47203,103.23645 107.3167,103.93972 107.23502,104.97749 C 107.10044,106.68748 107.39935,108.3843 108.09103,109.83702 C 108.26106,110.1941 108.37502,110.35902 108.8245,110.8984 C 109.43796,111.63452 109.64138,111.7968 110.37206,112.13261 C 110.91408,112.38174 111.4216,112.50659 112.02905,112.5403 C 112.59557,112.5717 113.54735,112.46486 113.67851,112.35515 C 113.73321,112.30938 115.76025,110.70188 118.18303,108.78291 C 129.71064,99.652452 137.30277,93.611082 148.72464,84.479686 C 150.78275,82.834326 155.51767,79.027246 158.79746,76.380746 C 160.9399,74.652006 165.48814,70.940126 170.04023,67.205426 L 172.24178,65.399246 L 172.26712,65.032246 C 172.30082,64.544096 172.29364,64.041716 172.24537,63.522316 C 172.18613,62.884306 172.2295,62.469246 172.38404,62.196926 C 172.6843,61.667746 173.12277,61.343016 174.00519,60.996336 C 174.6511,60.742556 175.84567,60.172536 175.8507,60.115666 C 175.85926,60.019876 175.62915,59.541326 175.54117,59.471726 C 175.48669,59.428656 175.33294,59.412176 175.17154,59.432126 C 174.92968,59.461986 174.87768,59.448556 174.75541,59.324496 C 174.60107,59.167886 174.42067,58.742976 174.25718,58.151076 C 174.1289,57.686426 174.14582,57.658196 174.80414,57.237596 C 175.31485,56.911296 175.56057,56.805246 175.96207,56.737746 C 176.29779,56.681286 176.49433,56.725426 176.69067,56.901356 C 176.88819,57.078286 177.21261,57.657786 177.28067,57.955236 C 177.34645,58.242796 177.25304,58.577466 177.06258,58.736846 C 176.90197,58.871176 176.90367,58.879016 177.1761,59.278366 C 177.32228,59.492626 177.3262,59.494576 177.48008,59.430806 C 178.11809,59.166316 179.97791,58.342496 179.97739,58.324566 C 179.97699,58.312306 179.9301,58.187966 179.87308,58.048326 C 179.74558,57.736006 179.60802,57.645016 179.35061,57.702486 C 179.25029,57.724896 179.1239,57.733156 179.06969,57.720886 C 178.83664,57.668226 178.61855,57.242606 178.39869,56.411086 L 178.28648,55.986716 L 178.73853,55.650416 C 179.51038,55.076226 180.23088,54.855456 180.65406,55.063516 C 180.86948,55.169456 180.90102,55.202466 181.1103,55.541226 C 181.36164,55.948006 181.45471,56.199806 181.44361,56.442676 C 181.43374,56.656466 181.26706,56.996976 181.14374,57.055166 C 181.02689,57.110296 181.04283,57.169806 181.26275,57.501136 L 181.42578,57.746836 L 182.68024,57.222856 C 183.37018,56.934676 183.94045,56.685746 183.94751,56.669676 C 183.97736,56.602066 183.75633,56.127836 183.66364,56.060526 C 183.60819,56.020226 183.48964,56.003596 183.40022,56.023526 C 183.14,56.081546 182.97057,56.046086 182.85646,55.909716 C 182.72381,55.751196 182.4873,55.148736 182.376,54.685756 L 182.2905,54.330296 L 182.56463,54.108406 C 183.19141,53.601156 183.56084,53.416706 184.12517,53.329406 C 184.39408,53.287796 184.49479,53.300356 184.66769,53.396906 C 184.85371,53.500776 184.9074,53.559466 185.10073,53.870236 C 185.40138,54.353526 185.48826,54.725216 185.37467,55.042146 C 185.31177,55.217846 185.24979,55.307726 185.15638,55.358636 C 185.01223,55.437266 185.0151,55.447956 185.29949,55.885506 L 185.43777,56.098246 L 186.7906,55.552686 C 187.53462,55.252656 188.14265,54.995256 188.14167,54.980716 C 188.13455,54.873636 187.88131,54.374256 187.80777,54.322316 C 187.75748,54.286746 187.58987,54.274786 187.43527,54.295756 C 187.19445,54.328396 187.13573,54.315196 187.02534,54.203586 C 186.87557,54.052236 186.6936,53.615736 186.5375,53.033786 C 186.40484,52.539326 186.41405,52.523206 187.0708,52.100476 C 187.80594,51.627286 188.43232,51.467776 188.80619,51.658566 C 188.95825,51.736166 189.02304,51.807616 189.22552,52.120756 C 189.53721,52.602986 189.61945,52.896536 189.53597,53.228576 C 189.4845,53.433156 189.43663,53.513396 189.31703,53.595666 C 189.14473,53.714176 189.14421,53.711866 189.45642,54.181306 L 189.62487,54.434506 L 190.93198,53.929256 C 191.65092,53.651366 192.24464,53.412956 192.25137,53.399446 C 192.26861,53.365086 191.97998,52.685726 191.91375,52.604806 C 191.8839,52.568256 191.78873,52.544396 191.70232,52.551766 C 191.2613,52.589426 191.16699,52.574326 191.06242,52.449316 C 190.93975,52.302716 190.73871,51.796786 190.58293,51.242486 L 190.47241,50.849356 L 190.9457,50.494796 C 191.45327,50.114536 191.82322,49.945436 192.33595,49.859226 C 192.64477,49.807286 192.8174,49.847566 193.01361,50.017366 C 193.19728,50.176276 193.54555,50.764776 193.6008,51.009696 C 193.68663,51.389546 193.56651,51.802406 193.33797,51.913026 C 193.21407,51.972986 193.20427,51.939846 193.51655,52.518646 C 193.61589,52.702836 193.70505,52.853366 193.71452,52.853216 C 193.72406,52.853036 194.07187,52.693996 194.48741,52.499806 C 194.90302,52.305596 195.49067,52.040846 195.79341,51.911456 C 196.09608,51.782086 196.34265,51.668586 196.34122,51.659266 C 196.32652,51.563636 196.08674,51.075506 196.01235,50.989866 C 195.93495,50.900826 195.86192,50.885826 195.63959,50.913376 C 195.1795,50.970386 195.07036,50.835756 194.75906,49.826916 C 194.56095,49.184926 194.56422,49.172816 195.01804,48.867966 C 195.17218,48.764396 195.37898,48.625136 195.4776,48.558506 C 195.85507,48.303356 196.57537,48.134786 196.86662,48.233426 C 197.07028,48.302396 197.29385,48.546816 197.52031,48.948096 C 197.81795,49.475256 197.80887,49.952476 197.49627,50.213966 L 197.33259,50.350906 L 197.58895,50.749546 C 197.72997,50.968786 197.85544,51.148576 197.86785,51.149046 C 197.88026,51.149476 198.09235,51.101986 198.33918,51.043456 C 199.09312,50.864696 199.56497,50.832726 200.07365,50.925926 C 201.47599,51.182866 202.5912,51.933186 203.22151,53.043846 C 203.33267,53.239816 203.4784,53.531736 203.54528,53.692556 C 203.69237,54.046406 203.89387,54.867156 203.94371,55.315386 C 204.03998,56.181576 203.79655,57.095986 203.26024,57.882546 C 202.72961,58.660716 201.86567,59.546176 201.3626,59.827306 C 200.31081,60.415126 198.88117,60.725576 197.92278,60.574266 C 197.63592,60.528946 197.11345,60.351246 196.5533,60.108466 C 195.85245,59.804716 195.30406,59.858676 194.69962,60.290886 C 194.30093,60.575936 194.13503,60.774766 192.2065,63.277946 C 190.20494,65.875896 188.95747,67.459706 187.95101,68.680596 C 187.25408,69.526056 187.18452,69.597236 186.43253,70.234206 C 185.86565,70.714346 185.59962,70.915446 185.48466,70.950636 C 185.36683,70.986676 185.19192,70.951766 184.81896,70.817816 C 184.07625,70.551076 183.03589,70.258956 182.51408,70.170626 C 181.94478,70.074256 181.47489,70.066476 180.79332,70.142206 C 179.78137,70.254626 179.59881,70.310556 178.92044,70.716026 C 178.58328,70.917526 178.13481,71.176446 177.92391,71.291376 C 177.5245,71.508956 175.7765,72.979196 144.45791,99.440242 C 141.7804,101.70246 135.55236,106.95977 130.61778,111.12316 C 125.68322,115.28654 120.51428,119.65458 119.13122,120.82993 C 117.74819,122.00525 115.77741,123.66935 114.75179,124.52787 L 112.88694,126.08886 L 112.92444,126.22481 C 112.94506,126.29959 112.93735,126.46122 112.90732,126.58399 C 112.61212,127.79043 113.44106,129.85247 114.82805,131.36193 C 116.46245,133.1406 118.38837,134.05971 120.43144,134.03609 C 120.95972,134.02998 121.61714,133.83895 123.01558,133.28523 C 123.80484,132.9727 125.37782,132.2244 126.09317,131.82115 C 126.97181,131.32585 127.52409,131.18011 128.2758,131.24524 C 129.14166,131.32025 129.73399,131.65099 130.27395,132.36093 C 130.77806,133.02376 130.92398,133.61245 130.83456,134.62282 C 130.80354,134.9743 130.72457,135.43418 130.65925,135.64474 C 130.39531,136.49556 129.29889,138.19761 128.19282,139.47367 C 127.66484,140.08279 125.84409,141.60531 125.10095,142.05911 C 123.58852,142.98266 122.62301,143.42961 118.44846,145.13866 C 118.1928,145.24333 117.48466,145.45685 116.87481,145.61314 C 115.18321,146.04668 114.23,146.382 113.01781,146.96992 C 111.06387,147.91761 109.45996,149.20264 108.10198,150.9084 C 107.16464,152.0858 106.45328,153.32124 105.75889,154.97776 C 105.52977,155.52436 105.22642,156.18639 105.08479,156.44891 C 104.7479,157.07336 104.38683,157.803 103.42145,159.81013 C 101.877,163.02122 101.082,164.51033 99.996014,166.22634 C 98.0006,169.3794 95.77381,171.8721 93.194468,173.84002 C 91.429408,175.18668 90.190188,175.97602 88.824378,176.62362 C 86.282818,177.82864 84.122378,178.2117 80.902478,178.02828 C 79.524899,177.9498 79.451229,177.93707 78.276089,177.57456 C 75.611769,176.75255 74.241179,176.13293 72.490779,174.95899 C 70.314699,173.49957 67.989859,171.34852 65.937939,168.89595 C 65.311459,168.14717 63.970749,166.56801 62.958599,165.3867 L 61.118269,163.2389 L 60.752679,163.30066 L 60.387098,163.36242 L 60.349488,163.63057 C 60.308018,163.92608 60.208868,164.04246 59.949268,164.10035 C 59.653128,164.1664 59.465038,164.0637 59.120228,163.64761 C 58.899348,163.38107 58.802518,163.22738 58.770328,163.09224 z"
+       id="path3250"
+       sodipodi:nodetypes="csssssssssssssssssssscccsssssscccssssssssssssscccssssssssssssssssssscccsssscccsssscccssssscccsssssssssscccsssscccsssssssssssssssscccssssssssssssssssssssssscccssssssssssssssssssssssssscccccssc" />
+    <rect
+       style="opacity:1;color:#000000;fill:#0000ff;fill-opacity:0.22608696;fill-rule:nonzero;stroke:none;stroke-width:10.60000038000000089;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:block;overflow:visible"
+       id="rect1913"
+       width="291.42856"
+       height="45.714287"
+       x="-16.285721"
+       y="181.50516" />
+    <path
+       style="font-size:39.83382034000000260px;font-family:Goblin;stroke:none;stroke-opacity:1;fill:#000000;fill-opacity:1"
+       d="M 58.72672,219.00823 L 44.00299,198.17717 L 44.00299,218.61923 L 40.30747,218.61923 L 40.30747,190.12482 L 41.86348,190.12482 L 56.19821,209.82778 L 56.19821,190.12482 L 59.89373,190.12482 L 59.89373,219.00823 L 58.72672,219.00823 M 64.3867,204.1289 C 64.3867,200.0055 65.41756,196.55635 67.47927,193.78144 C 69.55394,191.00659 72.34827,189.61915 75.86227,189.61912 C 79.8171,189.61915 82.84483,190.89637 84.94547,193.45079 C 87.05902,196.00526 88.11581,199.56463 88.11583,204.1289 C 88.11581,208.8099 87.05902,212.47949 84.94547,215.13766 C 82.83187,217.78288 79.80414,219.10548 75.86227,219.10548 C 72.27047,219.10548 69.45669,217.70508 67.42092,214.90426 C 65.39811,212.10345 64.3867,208.51167 64.3867,204.1289 M 68.47123,204.1289 C 68.47122,207.39653 69.11307,210.12603 70.39679,212.3174 C 71.69345,214.50878 73.51528,215.60447 75.86227,215.60447 C 78.52043,215.60447 80.54324,214.59955 81.9307,212.5897 C 83.33109,210.57986 84.03129,207.7596 84.03131,204.1289 C 84.03129,196.78975 81.30828,193.12017 75.86227,193.12014 C 73.45044,193.12017 71.61565,194.10564 70.35789,196.07656 C 69.10011,198.04752 68.47122,200.73163 68.47123,204.1289 M 122.75647,191.17513 L 121.45332,194.5011 C 120.20849,193.59345 118.25052,193.13962 115.57938,193.13959 C 113.07679,193.13962 111.06695,194.21585 109.54985,196.36831 C 108.0457,198.52081 107.29363,201.29569 107.29364,204.69296 C 107.29363,207.93465 108.06515,210.5669 109.6082,212.5897 C 111.1642,214.59955 113.16756,215.60447 115.61828,215.60447 C 118.28942,215.60447 120.34464,214.6579 121.78397,212.76475 L 123.92348,215.74062 C 121.66725,217.98386 118.7627,219.10548 115.20983,219.10548 C 111.48837,219.10548 108.55789,217.76343 106.41838,215.07931 C 104.27887,212.3952 103.20911,208.85529 103.20912,204.45955 C 103.20911,200.20648 104.35019,196.67305 106.63233,193.85925 C 108.91447,191.04549 111.8644,189.6386 115.48213,189.63857 C 118.58117,189.6386 121.00594,190.15079 122.75647,191.17513 M 127.01605,204.1289 C 127.01604,200.0055 128.0469,196.55635 130.10861,193.78144 C 132.18328,191.00659 134.97761,189.61915 138.49161,189.61912 C 142.44645,189.61915 145.47418,190.89637 147.57481,193.45079 C 149.68836,196.00526 150.74515,199.56463 150.74518,204.1289 C 150.74515,208.8099 149.68836,212.47949 147.57481,215.13766 C 145.46121,217.78288 142.43348,219.10548 138.49161,219.10548 C 134.89981,219.10548 132.08603,217.70508 130.05026,214.90426 C 128.02745,212.10345 127.01604,208.51167 127.01605,204.1289 M 131.10057,204.1289 C 131.10056,207.39653 131.74242,210.12603 133.02613,212.3174 C 134.32279,214.50878 136.14462,215.60447 138.49161,215.60447 C 141.14977,215.60447 143.17258,214.59955 144.56004,212.5897 C 145.96043,210.57986 146.66063,207.7596 146.66065,204.1289 C 146.66063,196.78975 143.93762,193.12017 138.49161,193.12014 C 136.07979,193.12017 134.24499,194.10564 132.98723,196.07656 C 131.72945,198.04752 131.10056,200.73163 131.10057,204.1289 M 165.13826,219.00823 L 163.1738,219.00823 L 152.55404,190.12482 L 156.87197,190.12482 L 164.20466,211.11149 L 171.26505,190.12482 L 175.44682,190.12482 L 165.13826,219.00823 M 182.52665,193.62584 L 182.52665,201.54204 L 191.94051,201.54204 L 191.94051,204.84856 L 182.52665,204.84856 L 182.52665,215.11821 L 195.44153,215.11821 L 195.44153,218.61923 L 178.63663,218.61923 L 178.63663,190.12482 L 195.65548,190.12482 L 195.65548,193.62584 L 182.52665,193.62584 M 215.76689,218.61923 L 208.1619,206.38511 C 207.29312,206.38513 205.91864,206.32029 204.03848,206.19061 L 204.03848,218.61923 L 200.14846,218.61923 L 200.14846,190.12482 C 200.29109,190.12485 201.29601,190.07947 203.16322,189.98867 C 205.04339,189.88497 206.41138,189.8331 207.26719,189.83307 C 214.11362,189.8331 217.53683,192.55611 217.53685,198.00212 C 217.53683,199.79155 216.98575,201.4059 215.88359,202.84519 C 214.7814,204.27155 213.47176,205.15977 211.95467,205.50986 L 220.22097,218.61923 L 215.76689,218.61923 M 204.03848,193.62584 L 204.03848,202.8841 C 204.97207,203.01378 205.87974,203.07861 206.76149,203.0786 C 209.09549,203.07861 210.79413,202.70258 211.85742,201.95049 C 212.92068,201.19844 213.45231,199.85638 213.45233,197.92432 C 213.45231,196.32943 212.88178,195.18188 211.74072,194.48165 C 210.59963,193.78147 208.79726,193.43137 206.33359,193.43134 C 205.94458,193.43137 205.17954,193.4962 204.03848,193.62584"
+       id="text1909" />
+  </g>
+</svg>
diff --git a/data/themes/default/instrumenthelp.svg b/data/themes/default/instrumenthelp.svg
new file mode 100644 (file)
index 0000000..0835d2f
--- /dev/null
@@ -0,0 +1,474 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://creativecommons.org/ns#"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   width="1000"
+   height="700"
+   id="svg5215"
+   sodipodi:version="0.32"
+   inkscape:version="0.48.4 r9939"
+   inkscape:output_extension="org.inkscape.output.svg.inkscape"
+   sodipodi:docname="instrumenthelp.svg"
+   version="1.0">
+  <metadata
+     id="metadata5462">
+    <rdf:RDF>
+      <cc:Work
+         rdf:about="">
+        <dc:format>image/svg+xml</dc:format>
+        <dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+      </cc:Work>
+    </rdf:RDF>
+  </metadata>
+  <defs
+     id="defs5460">
+    <inkscape:perspective
+       sodipodi:type="inkscape:persp3d"
+       inkscape:vp_x="0 : 765.35431 : 1"
+       inkscape:vp_y="0 : 1000 : 0"
+       inkscape:vp_z="1530.7086 : 765.35431 : 1"
+       inkscape:persp3d-origin="765.35431 : 510.23621 : 1"
+       id="perspective5464" />
+    <inkscape:perspective
+       id="perspective3703"
+       inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
+       inkscape:vp_z="1 : 0.5 : 1"
+       inkscape:vp_y="0 : 1000 : 0"
+       inkscape:vp_x="0 : 0.5 : 1"
+       sodipodi:type="inkscape:persp3d" />
+    <inkscape:perspective
+       id="perspective3725"
+       inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
+       inkscape:vp_z="1 : 0.5 : 1"
+       inkscape:vp_y="0 : 1000 : 0"
+       inkscape:vp_x="0 : 0.5 : 1"
+       sodipodi:type="inkscape:persp3d" />
+  </defs>
+  <sodipodi:namedview
+     inkscape:window-height="791"
+     inkscape:window-width="1370"
+     inkscape:pageshadow="2"
+     inkscape:pageopacity="0.0"
+     guidetolerance="10.0"
+     gridtolerance="10.0"
+     objecttolerance="10.0"
+     borderopacity="1.0"
+     bordercolor="#666666"
+     pagecolor="#ffffff"
+     id="base"
+     showgrid="false"
+     showguides="true"
+     inkscape:guide-bbox="true"
+     inkscape:zoom="2"
+     inkscape:cx="503.82147"
+     inkscape:cy="476.32724"
+     inkscape:window-x="58"
+     inkscape:window-y="27"
+     inkscape:current-layer="svg5215"
+     inkscape:window-maximized="0" />
+  <text
+     transform="scale(0.89213371,1.1209082)"
+     id="text2954"
+     y="434.98087"
+     x="553.4765"
+     style="font-size:48.68118668px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;text-align:center;text-anchor:middle;fill:#ffffff;fill-opacity:1;stroke:#000000;stroke-width:1.01400006;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;font-family:Goblin;-inkscape-font-specification:Goblin Bold"
+     xml:space="preserve"><tspan
+       style="text-align:center;text-anchor:middle;stroke:#000000;stroke-width:1.01400006;stroke-miterlimit:4;stroke-dasharray:none"
+       y="434.98087"
+       x="553.4765"
+       sodipodi:role="line"
+       id="tspan2905"><tspan
+   style="text-align:center;text-anchor:middle;fill:#ff6600;stroke:#000000;stroke-width:1.01400006"
+   id="tspan2873">PRESS</tspan> A BUTTON</tspan><tspan
+       style="text-align:center;text-anchor:middle;stroke:#000000;stroke-width:1.01400006;stroke-miterlimit:4;stroke-dasharray:none"
+       y="434.98087"
+       x="553.4765"
+       sodipodi:role="line"
+       id="tspan2970"><tspan
+         style="text-align:center;text-anchor:middle;fill:#ffff00;stroke:#000000;stroke-width:1.01400006"
+         id="tspan2911" /></tspan></text>
+  <!-- EMR_SETMAPMODE -->
+  <!-- EMR_SETWINDOWEXTEX -->
+  <!-- EMR_SETVIEWPORTEXTEX -->
+  <!-- EMR_SETBKMODE -->
+  <!-- EMR_STRETCHDIBITS -->
+  <!-- EMR_SETBKCOLOR -->
+  <path
+     style="fill:#c00000;fill-opacity:1;fill-rule:nonzero;stroke:none"
+     id="path5221"
+     d="" />
+  <!-- EMR_SETBKCOLOR -->
+  <path
+     style="fill:#c00000;fill-opacity:1;fill-rule:nonzero;stroke:none"
+     id="path5239"
+     d="" />
+  <!-- EMR_SETBKCOLOR -->
+  <path
+     style="fill:#c00000;fill-opacity:1;fill-rule:nonzero;stroke:none"
+     id="path5339"
+     d="" />
+  <!-- EMR_SETBKCOLOR -->
+  <g
+     id="g6678"
+     transform="matrix(-0.5733385,-0.09492075,0.06423444,-0.8472365,906.86031,1416.0712)"
+     style="opacity:0.9">
+    <g
+       id="g2919"
+       transform="translate(-520.43821,59.690285)">
+      <path
+         style="fill:#5f4343;fill-opacity:1;stroke:none"
+         d="m 1520.754,975.60048 c -91.3221,35.38732 -287.6594,165.49742 -363,228.28132 -1.1415,1.1415 -2.2813,2.296 -2.2813,3.4375 1.1416,2.283 1.125,6.8438 1.125,6.8438 0,0 2.2813,2.2812 2.2813,2.2812 57.0762,50.2271 179.2161,126.7028 242,166.6562 2.283,1.1416 5.7317,3.4264 9.1562,-2.2812 110.728,-148.3983 245.4062,-343.5938 245.4062,-343.5938 10e-5,10e-5 1.158,-1.1397 -1.125,-2.2812 -55.9346,-31.9627 -129,-59.34382 -129,-59.34382 0,0 -2.2794,0 -4.5624,0 z m 2.1874,1.0313 c 0.8918,0.056 1.3438,0.5 1.3438,0.5 0,0 65.2787,26.16232 128.0625,58.12502 2.2831,1.1414 1.125,2.2813 1.125,2.2813 0,-10e-5 -240.0129,334.1692 -243.4375,337.5937 -3.4245,4.5662 -4.5772,2.2813 -5.7187,2.2813 -71.9161,-44.5196 -243.1545,-166.138 -245.4375,-169.5626 -1.1416,-1.1414 0,-3.4062 0,-3.4062 93.3121,-67.8759 237.2795,-171.6109 361.9687,-227.31252 0.8561,-0.4281 1.5587,-0.5334 2.0937,-0.5 z"
+         id="path5217" />
+      <path
+         transform="matrix(-1.7225489,0.19298701,-0.13059748,-1.1656764,1755.7005,1552.9114)"
+         id="path2917"
+         d="M 85.297081,500.8407 C 72.406572,489.9957 55.509153,475.29159 45.767424,466.44204 38.460906,459.80468 26.420394,448.27881 25.88033,447.40497 c -0.296189,-0.47925 15.394509,-26.28264 96.1936,-158.19065 43.14146,-70.43028 64.35284,-104.7607 65.60429,-106.17989 0.50762,-0.57566 1.23583,-0.97101 1.61825,-0.87855 2.3117,0.55891 55.12816,67.08109 97.78919,123.1652 27.00989,35.50843 33.11909,44.00628 32.61418,45.36606 -0.45506,1.2255 -7.48232,7.2277 -34.97522,29.8734 -62.39911,51.39771 -112.6815,87.81472 -154.9143,112.19668 -8.62325,4.97839 -32.299417,17.28648 -33.149573,17.23285 -0.290513,-0.0183 -5.404164,-4.13555 -11.363666,-9.14937 z"
+         style="fill:#f9f9f9" />
+    </g>
+    <path
+       id="path5223"
+       d="m 726.50097,1255.8195 c -2.28304,3.4246 -12.55678,9.1322 -12.55678,9.1322 0,0 -1.14152,2.2831 -3.42457,1.1415 -2.28304,-1.1415 -17.12287,-12.5567 -17.12287,-12.5567 0,0 -3.42457,14.8398 -3.42457,14.8398 0,0 20.54744,15.9813 20.54744,15.9813 0,0 2.28305,0 4.56609,-1.1415 3.4246,-2.283 20.54748,-14.8398 20.54748,-14.8398 0,0 2.28304,-1.1415 0,-3.4246 -2.28305,-3.4246 -6.84917,-11.4152 -7.9907,-11.4152 -1.14152,0 2.28305,-1.1416 -1.14152,2.283"
+       style="fill:#5f4343;fill-opacity:1;stroke:none" />
+    <path
+       id="path5225"
+       d="m 736.77471,1221.5738 c 0,0 -3.42457,15.9813 -3.42457,15.9813 0,0 19.40592,13.6983 19.40592,13.6983 0,0 2.28304,1.1415 4.56609,0 1.14152,-1.1415 18.26439,-13.6983 18.26439,-13.6983 1.14153,-1.1415 0,-2.283 0,-3.4246 -1.14152,-1.1415 -5.70761,-10.2737 -6.84913,-11.4152 0,1.1415 -12.55678,12.5568 -15.98135,11.4152 -3.42457,-2.283 -15.98135,-12.5567 -15.98135,-12.5567"
+       style="fill:#5f4343;fill-opacity:1;stroke:none" />
+    <path
+       id="path5227"
+       d="m 760.74672,1206.7339 c 0,0 -3.42457,9.1323 -3.42457,9.1323 0,0 11.41526,6.8491 11.41526,6.8491 0,0 6.84913,12.5568 6.84913,11.4152 -1.14152,-1.1415 1.14153,2.2831 3.42457,1.1416 2.28308,-1.1416 17.12287,-12.5568 18.26443,-14.8399 1.14152,-1.1415 -5.70765,-12.5567 -6.84917,-13.6983 1.14152,2.2831 -10.27374,12.5568 -13.6983,11.4153 -3.42457,-2.283 -15.98135,-11.4153 -15.98135,-11.4153"
+       style="fill:#5f4343;fill-opacity:1;stroke:none" />
+    <path
+       id="path5229"
+       d="m 782.43571,1191.8941 c 0,0 -2.28308,7.9907 -2.28308,7.9907 0,0 10.27374,6.8491 10.27374,6.8491 0,0 6.84917,12.5568 6.84917,12.5568 0,0 1.14152,1.1415 3.42457,-1.1415 2.28304,-1.1415 15.98135,-11.4153 15.98135,-11.4153 1.14152,0 1.14152,-2.283 0,-3.4245 0,-2.2831 -3.42457,-7.9907 -4.56613,-10.2738 1.14156,2.2831 -11.41522,10.2738 -13.69827,9.1322 -1.14152,-1.1415 -15.98135,-10.2737 -15.98135,-10.2737"
+       style="fill:#5f4343;fill-opacity:1;stroke:none" />
+    <path
+       id="path5231"
+       d="m 802.98315,1177.0543 c 0,0 -2.28304,7.9907 -2.28304,7.9907 0,0 11.41522,7.9906 11.41522,7.9906 0,0 4.56613,10.2738 4.56613,10.2738 0,0 2.28304,1.1415 4.56609,0 1.14152,-1.1416 13.6983,-9.1322 14.83982,-11.4153 1.14153,-1.1415 -3.42457,-10.2737 -4.56609,-13.6983 0,2.2831 -10.27373,11.4153 -13.6983,9.1322 -3.42457,-2.283 -14.83983,-10.2737 -14.83983,-10.2737"
+       style="fill:#5f4343;fill-opacity:1;stroke:none" />
+    <path
+       id="path5233"
+       d="m 833.80433,1156.5068 c 0,0 -4.56609,13.6984 -4.56609,13.6984 0,0 18.26439,10.2737 18.26439,10.2737 0,0 3.42457,1.1415 5.70762,0 1.14152,-1.1416 11.41525,-9.1322 11.41525,-9.1322 0,0 0,-1.1415 0,-2.2831 1.14153,1.1416 1.14153,0 2.28305,0 1.14152,0 13.6983,-9.1322 13.6983,-9.1322 0,0 0,-1.1415 0,-2.283 0,1.1415 1.14153,1.1415 2.28305,0 0,0 11.41526,-7.9907 11.41526,-7.9907 0,0 1.14152,-1.1415 0,-2.2831 2.28304,1.1416 2.28304,1.1416 2.28304,0 1.14153,0 11.41523,-7.9906 12.55675,-7.9906 0,-1.1415 0,-2.2831 0,-3.4246 -1.14152,0 -3.42457,-6.8492 -4.56609,-9.1322 1.14152,2.283 -5.70761,7.9907 -7.99066,5.7076 -3.4246,-1.1415 -14.83982,-7.9907 -14.83982,-7.9907 0,0 -1.14153,5.7077 -1.14153,5.7077 0,0 10.27371,5.7076 10.27371,5.7076 0,0 1.14152,2.2831 0,2.2831 -1.14153,1.1415 -5.70762,6.8491 -9.13218,5.7076 -2.28305,-1.1416 -14.83983,-9.1322 -14.83983,-9.1322 0,0 -1.14152,5.7076 -1.14152,5.7076 0,0 10.2737,5.7076 10.2737,5.7076 0,0 1.14156,2.2831 0,3.4246 -1.14152,1.1415 -6.84914,4.5661 -6.84914,4.5661 0,0 -2.28304,1.1415 -4.56609,0 -1.14152,-1.1415 -13.6983,-7.9907 -13.6983,-9.1322 0,-1.1415 -2.28305,6.8492 -2.28305,6.8492 0,0 11.41523,5.7076 11.41523,5.7076 0,0 1.14156,1.1415 0,2.283 -1.14152,1.1415 -7.99066,5.7076 -7.99066,5.7076 0,0 -2.28304,1.1416 -4.56609,0 -2.28304,-2.283 -13.6983,-9.1322 -13.6983,-9.1322"
+       style="fill:#5f4343;fill-opacity:1;stroke:none" />
+    <path
+       id="path5235"
+       d="m 904.57886,1109.7043 c 0,0 -4.56609,11.4153 -4.56609,11.4153 0,0 17.12287,7.9906 18.2644,9.1322 0,0 2.28304,0 3.42456,0 1.14153,-1.1416 7.99069,-5.7077 7.99069,-5.7077 0,0 0,-2.283 0,-2.283 1.14153,0 1.14153,0 1.14153,0 0,0 10.2737,-6.8492 10.2737,-6.8492 0,0 0,-1.1415 0,-1.1415 1.14156,0 1.14156,0 2.28308,0 0,-1.1415 9.13218,-6.8491 9.13218,-6.8491 0,0 0,-1.1415 0,-1.1415 -1.14152,-1.1416 1.14152,1.1415 1.14152,0 1.14153,0 7.99069,-5.7077 9.13222,-5.7077 0,-1.1415 -2.28305,-10.2737 -2.28305,-10.2737 0,-1.1415 -4.56612,3.4246 -4.56612,3.4246 0,0 -1.14152,0 -3.42457,0 -2.28305,-1.1416 -11.41526,-6.8492 -11.41526,-6.8492 0,0 -2.28304,3.4246 -2.28304,3.4246 0,0 11.41525,5.7076 11.41525,5.7076 0,0 1.14153,1.1415 0,2.2831 -1.14152,1.1415 -4.56609,3.4245 -4.56609,3.4245 0,0 -2.28304,0 -3.42456,0 -1.14156,-1.1415 -12.55679,-7.9906 -12.55679,-7.9906 0,0 -2.28304,3.4245 -2.28304,3.4245 0,0 11.41523,6.8492 11.41523,6.8492 0,0 1.14152,1.1415 0,2.2831 -1.14153,1.1415 -4.56609,3.4245 -4.56609,3.4245 0,0 -1.14153,1.1415 -3.42457,0 -1.14153,-1.1415 -13.69831,-7.9907 -13.69831,-7.9907 0,0 -1.14152,4.5662 -1.14152,4.5662 0,0 10.27374,4.566 10.27374,4.566 0,0 2.28304,1.1416 0,2.2831 -1.14156,2.283 -4.56613,4.5661 -4.56613,4.5661 0,0 -1.14152,1.1415 -3.42456,0 -1.14153,-1.1415 -13.69831,-7.9907 -13.69831,-7.9907"
+       style="fill:#5f4343;fill-opacity:1;stroke:none" />
+    <path
+       id="path5237"
+       d="m 954.80596,1077.7416 c 0,0 -3.42457,6.8492 -3.42457,6.8492 0,0 9.13221,4.5661 9.13221,4.5661 0,0 0,1.1415 0,1.1415 0,0 1.14152,2.283 1.14152,2.283 0,0 5.70762,2.2831 4.56609,2.2831 0,-1.1415 2.28305,1.1415 4.5661,0 1.14152,-1.1415 4.56612,-4.5661 4.56612,-4.5661 0,0 0,0 0,-1.1415 1.14152,0 2.28304,0 2.28304,0 1.14153,0 6.84914,-4.5661 6.84914,-4.5661 0,0 0,-1.1416 0,-2.2831 1.14152,1.1415 2.28304,1.1415 2.28304,0 0,0 5.70765,-4.5661 5.70765,-4.5661 0,-1.1415 0,-9.1322 0,-9.1322 0,0 -3.4246,3.4246 -3.4246,3.4246 0,0 -2.28305,0 -3.42457,0 -1.14152,-1.1415 -11.41522,-6.8492 -11.41522,-6.8492 0,0 -1.14156,3.4246 -1.14156,3.4246 0,0 9.13221,4.5661 9.13221,4.5661 0,0 1.14153,1.1416 0,2.2831 0,0 -3.42456,2.283 -3.42456,2.283 0,0 0,0 -2.28305,0 -2.28304,-1.1415 -11.41526,-6.8491 -11.41526,-6.8491 0,0 -2.28304,3.4246 -2.28304,3.4246 0,0 10.2737,4.566 10.2737,4.566 0,0 2.28308,1.1416 1.14156,2.2831 -1.14156,1.1415 -3.4246,2.283 -3.4246,2.283 0,0 -2.28305,1.1416 -3.42457,0 -2.28305,0 -12.55678,-5.7076 -12.55678,-5.7076"
+       style="fill:#5f4343;fill-opacity:1;stroke:none" />
+    <path
+       id="path5241"
+       d="m 989.0625,1102.8438 c 0,1.1414 -12.5625,12.5624 -12.5625,12.5624 2e-5,1e-4 -2.29594,1.1416 -3.4375,0 -2.28306,-2.2829 -13.6875,-8 -13.6875,-8 10e-6,1e-4 -2.28125,4.5938 -2.28125,4.5938 10e-6,0 11.40625,5.6875 11.40625,5.6875 -10e-6,10e-5 1.14152,1.1396 0,2.2813 -10e-6,1.1414 -3.40625,3.4374 -3.40625,3.4374 -2e-5,1e-4 -1.16918,1.1416 -4.59375,0 -2.28305,-1.1414 -13.6875,-6.8437 -13.6875,-6.8437 -10e-6,0 -1.125,3.4063 -1.125,3.4063 0,-1e-4 11.40625,5.7187 11.40625,5.7187 10e-6,0 1.125,1.1545 1.125,3.4375 -1.14153,1.1416 -5.6875,3.4062 -5.6875,3.4062 2e-5,1e-4 0.002,2.2832 -2.28125,0 -2.28305,-1.1414 -14.84375,-8 -14.84375,-8 2e-5,1e-4 -2.28125,4.5938 -2.28125,4.5938 -10e-6,0 11.40625,6.8438 11.40625,6.8438 2e-5,0 2.29778,1.1396 1.15625,2.2812 -2.28304,2.2829 -4.59375,4.5625 -4.59375,4.5625 -2e-5,0 -1.1232,1.1416 -3.40625,0 -3.42459,-1.1415 -14.84375,-8 -14.84375,-8 0,0 -2.28125,4.5625 -2.28125,4.5625 3e-5,0 12.5625,5.7188 12.5625,5.7188 -10e-6,0 1.14153,2.2959 0,3.4374 -1.14153,1.1415 -5.71875,4.5626 -5.71875,4.5626 2e-5,0 -2.26473,1.1414 -3.40625,0 -1.14154,-1.1415 -14.84375,-9.1563 -14.84375,-9.1563 -10e-6,0 -2.28125,5.7187 -2.28125,5.7187 -3e-5,0 12.53125,6.8438 12.53125,6.8438 -10e-6,0 1.14152,1.1398 0,2.2812 -1.14153,1.1415 -4.5625,4.5626 -4.5625,4.5626 0,0 -2.2629,2.2829 -5.6875,0 -4.5661,-1.1415 -14.84375,-7.9688 -14.84375,-7.9688 -2e-5,-10e-5 -2.28125,5.6875 -2.28125,5.6875 -10e-6,0 12.5625,6.875 12.5625,6.875 0,0 1.14152,2.2648 0,3.4063 -1.14152,1.1415 -4.59375,4.5624 -4.59375,4.5624 10e-6,0 -2.26293,2.283 -5.6875,0 -3.42462,-1.1416 -16,-9.125 -16,-9.125 2e-5,0 -1.125,6.8438 -1.125,6.8438 -2e-5,-10e-5 11.40625,6.8438 11.40625,6.8438 -2e-5,0 2.28305,1.1544 0,3.4374 -1.14154,1.1416 -5.71875,4.5626 -5.71875,4.5626 10e-6,0 -3.41915,2.2831 -6.84375,0 -3.42455,-1.1415 -13.6875,-9.125 -13.6875,-9.125 -10e-6,0 -2.28125,6.8437 -2.28125,6.8437 -10e-6,0 11.40625,8 11.40625,8 -3e-5,0 2.29778,1.1398 1.15625,2.2813 -1.14151,2.283 -8,6.8437 -8,6.8437 10e-6,0 -2.29415,2.283 -5.71875,0 -3.42456,-2.2831 -14.84375,-9.125 -14.84375,-9.125 3e-5,0 -2.28125,6.8437 -2.28125,6.8437 10e-6,1e-4 12.5625,8 12.5625,8 2e-5,1e-4 1.14152,1.1232 0,3.4063 -2.28303,1.1414 -7.96875,6.8437 -7.96875,6.8437 3e-5,1e-4 -2.29418,2.2831 -5.71875,0 -2.28302,-1.1414 -15.96875,-10.25 -15.96875,-10.25 -10e-6,1e-4 -2.3125,6.8438 -2.3125,6.8438 -3e-5,0 11.4375,7.9688 11.4375,7.9688 10e-6,-1e-4 2.26652,2.2959 1.125,3.4374 -2.28306,2.2831 -9.125,8 -9.125,8 -2e-5,1e-4 -3.42098,2.2831 -4.5625,0 -2.28306,-1.1415 -18.28125,-11.4374 -18.28125,-11.4374 0,-1e-4 -2.28125,8 -2.28125,8 -2e-5,-1e-4 12.5625,8 12.5625,8 -10e-6,-1e-4 2.28304,2.2794 0,4.5624 -2.28309,2.2831 -10.28125,9.125 -10.28125,9.125 0,1e-4 -3.40446,1.1416 -5.6875,0 -2.28305,-2.283 -16,-12.5624 -16,-12.5624 0,-1e-4 -3.40625,10.2812 -3.40625,10.2812 2e-5,0 12.5625,8 12.5625,8 -2e-5,0 2.26832,2.2794 -1.15625,4.5625 -2.28305,2.283 -9.125,8 -9.125,8 -2e-5,0 -3.41918,2.2665 -6.84375,1.125 -2.28308,-2.2831 -16,-13.6875 -16,-13.6875 10e-6,0 -3.40625,11.4062 -3.40625,11.4062 0,0 10.25,8 10.25,8 2e-5,0 4.58082,2.263 1.15625,5.6876 -3.42463,3.4246 -12.5625,9.1562 -12.5625,9.1562 2e-5,10e-5 -2.27763,2.2683 -6.84375,-1.1562 -4.56606,-3.4246 -14.84375,-12.5626 -14.84375,-12.5626 -2e-5,0 -3.40625,14.8438 -3.40625,14.8438 -3e-5,0 -1.15805,1.1398 1.125,2.2812 1.14154,1.1415 20.5625,16 20.5625,16 10e-6,1e-4 3.40446,1.1268 5.6875,-1.1562 -1.14154,3.4245 0.0147,3.421 1.15625,4.5625 1.14155,1.1416 21.6875,17.125 21.6875,17.125 2e-5,0 3.42098,0 4.5625,-2.2813 2.28303,-1.1415 -1.15804,3.4357 1.125,5.7188 3.42459,2.283 22.84375,17.125 22.84375,17.125 10e-6,0 2.27762,2.2701 6.84375,-3.4375 -2.28309,5.7077 -0.002,6.8419 2.28125,9.125 2.28306,1.1416 21.6875,16 21.6875,16 2e-5,0 4.59013,2.2867 9.15625,-4.5625 -4.56609,9.1322 -1.14152,9.1084 0,10.25 1.14155,0 22.82722,16 23.96875,16 -10e-6,1.1414 2.27945,2.2831 4.5625,0 2.28306,-2.2831 29.6875,-33.125 29.6875,-33.125 0,0 -0.0147,-3.4044 -1.15625,-5.6875 2.28306,1.1417 3.42098,1.1416 4.5625,0 1.14153,-2.2829 14.84375,-19.4063 14.84375,-19.4063 0,1e-4 1.14152,-3.4209 0,-4.5624 2.28304,-1e-4 3.43571,2.2683 5.71875,-1.1563 2.28305,-3.4246 21.6875,-26.25 21.6875,-26.25 -10e-6,0 1.14153,-3.4209 0,-4.5625 2.28304,1.1417 3.42097,-1.1562 4.5625,-1.1562 -10e-6,-1.1415 74.1875,-93.5938 74.1875,-93.5938 0,0 1.1415,-1.1545 0,-3.4375 1.1415,1.1415 2.2959,0.016 3.4375,-1.125 1.1415,-1.1416 10.2813,-13.6875 10.2813,-13.6875 0,0 1.125,-1.171 1.125,-2.3125 1.1415,0 1.1396,0.016 2.2812,-1.125 1.1414,-1.1415 5.7188,-6.8437 5.7188,-6.8437 0,0 1.1414,-1.1546 0,-3.4376 2.283,0 2.2646,0.017 3.4062,-1.125 1.1414,-1.1415 4.5625,-5.7187 4.5625,-5.7187 0,0 2.283,-1.1544 0,-3.4375 2.283,1.1416 3.4522,-1.1398 4.5937,-2.2812 0,0 6.8438,-9.125 6.8438,-9.125 0,0 1.125,-1.1379 1.125,-4.5626 -1.1416,-2.2831 -1.125,-5.7168 -1.125,-8 -1.1415,3.4247 -6.8438,10.2813 -6.8438,10.2813 0,0 -0.013,1.1415 -3.4374,0 -2.2831,0 -13.7023,-3.4209 -14.8438,-4.5625 -10e-5,-1.1415 4.5625,-5.7188 4.5625,-5.7188 0,1e-4 0,-6.8418 0,-9.125 -1.1416,2.2832 -18.25,20.5626 -18.25,20.5626 0,0 -1.138,1.1414 -4.5625,0 -2.2831,-1.1415 -13.7188,-3.4376 -13.7188,-3.4376 10e-5,0 -1.1416,-1.125 0,-1.125 10e-5,-1.1416 16,-17.125 16,-17.125 0,0 -1.1562,-5.7168 -1.1562,-8 0,2.2832 -14.8438,14.8438 -14.8438,14.8438 10e-5,-10e-5 -1.1232,2.2665 -3.4062,1.125 -2.2831,-1.1415 -12.5625,-4.5625 -12.5625,-4.5625 10e-6,0 -1.14152,-1.1397 0,-2.2813 1.14154,-2.2829 12.5625,-11.4062 12.5625,-11.4062 0,0 -1.1396,-5.7023 -2.2812,-6.8438 0,2.2832 -6.875,7.9688 -6.875,7.9688 -10e-5,0 -1.1232,0 -3.4063,0 -2.28303,-1.1415 -12.5625,-5.6875 -12.5625,-5.6875 -10e-6,0 -2.28304,-1.1398 0,-2.2813 1.14151,-1.1414 4.5625,-3.4374 4.5625,-3.4374 10e-6,-1e-4 -1.125,-5.717 -1.125,-8 z m -8.84375,15.4687 c 0.99827,0.019 1.96875,0.5313 1.96875,0.5313 -2e-5,-2e-4 7.9982,3.4044 10.28125,5.6874 2.28303,1.1418 2.28125,2.2813 2.28125,2.2813 10e-6,10e-5 -2.27945,2.2959 -4.5625,3.4375 -1.14154,1.1415 -3.40625,0 -3.40625,0 -3e-5,0 -10.27946,-4.5772 -12.5625,-5.7188 -1.14156,2e-4 0,-2.2812 0,-2.2812 0,0 3.42097,-1.1231 4.5625,-3.4062 0.28538,-0.2855 0.62544,-0.4465 1,-0.5 0.14046,-0.02 0.29489,-0.034 0.4375,-0.031 z m -10.5625,9.1563 c 0.14262,-0.012 0.29537,-0.01 0.4375,0 0.94755,0.056 1.84375,0.5 1.84375,0.5 0,-2e-4 10.26472,4.5772 11.40625,5.7187 1.14149,1.1416 1.15625,2.2813 1.15625,2.2813 10e-6,0 -3.45223,2.2795 -4.59375,4.5624 -1.14149,1.1416 -3.40625,0 -3.40625,0 2e-5,0 -11.42098,-5.7187 -12.5625,-5.7187 -2.28305,-1.1416 0,-3.4063 0,-3.4063 0,0 2.27945,-2.2959 4.5625,-3.4374 0.32105,-0.3211 0.72839,-0.4645 1.15625,-0.5 z m -11.40625,9.125 c 0.14262,-0.012 0.29537,-0.01 0.4375,0 0.94756,0.056 1.8125,0.5 1.8125,0.5 -10e-6,-2e-4 10.29598,4.5772 11.4375,5.7187 2.28308,1.1416 1.125,2.2813 1.125,2.2813 -2e-5,0 -3.42098,3.421 -4.5625,4.5624 -1.14153,2.2832 -3.40625,0 -3.40625,0 -2e-5,0 -12.57723,-5.7187 -13.71875,-5.7187 -1.14155,-1.1416 0,-2.2813 0,-2.2813 -2e-5,2e-4 3.43571,-3.4208 5.71875,-4.5624 0.32107,-0.3211 0.72839,-0.4645 1.15625,-0.5 z m 34.96875,0 c 0.19612,-0.012 0.37856,-0.01 0.5625,0 1.22625,0.056 2.125,0.5 2.125,0.5 -10e-6,-2e-4 7.98165,3.421 11.40625,4.5624 3.4246,1.1417 1.1562,3.4376 1.1563,3.4376 0,0 -2.2793,2.2959 -4.5626,3.4374 -1.1413,1.1416 -3.4375,0 -3.4374,0 0,0 -9.12322,-3.4522 -11.4063,-4.5937 -3.42457,-1.1416 -1.15625,-3.4063 -1.15625,-3.4063 2e-5,0 2.29597,-1.1543 3.4375,-3.4374 0.64211,-0.3211 1.28665,-0.4645 1.875,-0.5 z m -8.71875,9.625 c 10e-6,-2e-4 10.24821,3.4356 12.53125,5.7187 2.28302,1.1415 1.15625,2.2813 1.15625,2.2813 10e-6,0 -1.15446,2.2959 -3.4375,3.4374 -2.28304,2.2831 -4.5625,1.125 -4.5625,1.125 10e-6,0 -11.40445,-4.546 -13.6875,-5.6874 -2.28302,-1.1416 0,-2.2813 0,-2.2813 2e-5,0 2.27946,-2.2959 4.5625,-3.4375 1.14152,-1.1415 3.4375,-1.1562 3.4375,-1.1562 z m -38.8125,0.6562 c 0.14262,-0.012 0.29537,-0.01 0.4375,0 0.94755,0.056 1.84375,0.5 1.84375,0.5 -3e-5,0 10.24821,4.5773 12.53125,5.7188 2.28304,1.1414 1.15625,2.2812 1.15625,2.2812 3e-5,-10e-5 -3.42094,4.546 -4.5625,5.6875 -2.28303,1.1416 -4.5625,0 -4.5625,0 2e-5,0 -11.43571,-5.7023 -13.71875,-6.8437 -1.1415,0 0,-2.2813 0,-2.2813 3e-5,0 4.57723,-3.4209 5.71875,-4.5625 0.32106,-0.3211 0.72839,-0.4644 1.15625,-0.5 z m 97.25,4.5625 c 0.1843,-0.012 0.3702,-0.01 0.5625,0 1.282,0.056 2.625,0.5 2.625,0.5 -10e-5,0 10.2795,3.4375 12.5625,3.4375 1.1416,-10e-5 1.125,2.2812 1.125,2.2812 0,0 -1.1232,2.2794 -3.4063,4.5626 -1.1414,1.1414 -3.4374,0 -3.4374,0 0,0 -10.2629,-3.4211 -13.6876,-4.5626 -2.283,0 -1.1562,-2.2812 -1.1562,-2.2812 0,-10e-5 2.2959,-1.1545 3.4375,-3.4375 0.3211,-0.3211 0.8222,-0.4644 1.375,-0.5 z m -31.9063,1.375 c 0.5708,0 0.8438,0.2813 0.8438,0.2813 0,0 10.2795,3.4209 12.5625,4.5624 2.283,0 2.2813,2.2813 2.2813,2.2813 -2e-4,0 -2.2794,2.2648 -4.5626,3.4063 -2.283,2.2829 -4.5625,0 -4.5624,0 0,0 -11.4208,-3.4063 -12.5626,-3.4063 -2.283,-1.1415 -1.1249,-2.2813 -1.125,-2.2813 10e-5,0 2.2795,-2.296 4.5626,-3.4374 1.1415,-1.1416 1.9918,-1.4063 2.5624,-1.4063 z m -40.0937,3.8125 c 1.04538,-0.067 2.125,1.0312 2.125,1.0312 -2e-5,0 11.43571,4.5626 13.71875,4.5626 2.28302,1.1414 0,3.4062 0,3.4062 -3e-5,0 -2.3107,3.4521 -4.59375,4.5938 -1.14154,1.1413 -3.40625,0 -3.40625,0 -2e-5,-2e-4 -11.40445,-4.5773 -13.6875,-5.7188 -2.28306,-1.1416 0,-2.2812 0,-2.2812 -2e-5,0 2.27946,-3.4211 4.5625,-4.5626 0.35674,-0.7133 0.80608,-1.0005 1.28125,-1.0312 z m -38.15625,0.5 c 0.97939,0.019 1.46875,0.5312 1.46875,0.5312 -2e-5,0 11.4357,4.5461 13.71875,5.6876 2.28301,1.1414 1.125,3.4374 1.125,3.4374 10e-6,0 -3.40446,3.4211 -5.6875,4.5626 -1.14154,2.2829 -4.59375,0 -4.59375,0 3e-5,0 -11.40442,-4.5772 -13.6875,-5.7188 -2.28302,-1.1415 0,-3.4062 0,-3.4062 2e-5,0 3.4357,-2.2796 5.71875,-4.5626 0.57077,-0.2853 1.07193,-0.4464 1.5,-0.5 0.16053,-0.02 0.29759,-0.034 0.4375,-0.031 z m 102.24995,4.5625 c 0.9983,0.019 1.9688,0.5313 1.9688,0.5313 0,0 10.2795,2.2647 12.5625,3.4062 2.2831,1.1416 1.125,3.4375 1.125,3.4375 0,0 -1.1398,1.1545 -2.2813,3.4375 -1.1414,1.1415 -4.5624,1.125 -4.5624,1.125 0,-10e-5 -11.4045,-4.5625 -13.6876,-4.5625 -2.2829,-1.1415 0,-2.2813 0,-2.2813 0,0 2.2648,-3.421 3.4063,-4.5624 0.2854,-0.2855 0.6567,-0.4465 1.0313,-0.5 0.1404,-0.02 0.2948,-0.034 0.4374,-0.031 z m -35.18745,1.1563 c 0.15448,-0.012 0.30375,-0.01 0.43745,0 0.8919,0.056 1.3125,0.5 1.3126,0.5 -10e-5,0 9.1379,2.2958 12.5624,3.4374 3.4246,1.1416 2.2813,3.4376 2.2813,3.4376 0,-2e-4 -2.2794,1.1232 -4.5625,3.4062 -1.1415,2.283 -4.5625,1.1562 -4.5625,1.1562 0,0 -10.27946,-3.4374 -12.5625,-3.4374 -3.42456,-1.1416 0,-3.4063 0,-3.4063 10e-6,0 1.15446,-2.3108 3.4375,-4.5937 0.64212,-0.3211 1.19282,-0.4645 1.65625,-0.5 z m -39.625,4.7812 c 0.85614,0 1.4375,0.3125 1.4375,0.3125 3e-5,0 10.27942,4.546 12.5625,5.6875 3.42456,1.1414 1.125,3.4375 1.125,3.4375 -2e-5,0 -2.27946,2.2794 -4.5625,4.5625 -2.28303,1.1415 -4.5625,0 -4.5625,0 2e-5,0 -12.54598,-5.7188 -13.6875,-5.7188 -2.28303,-1.1415 0,-3.4062 0,-3.4062 2e-5,0 2.27946,-1.1544 4.5625,-3.4375 1.14155,-1.1415 2.26886,-1.4375 3.125,-1.4375 z m -41.1875,0.9375 c 0.19905,-0.012 0.37856,-0.01 0.5625,0 1.22624,0.056 2.09375,0.5 2.09375,0.5 10e-6,0 11.42097,5.7021 12.5625,6.8437 2.28302,1.1416 1.15625,3.4376 1.15625,3.4376 2e-5,0 -4.57722,3.4043 -5.71875,5.6874 -2.28306,1.1416 -4.5625,0 -4.5625,0 2e-5,0 -11.40445,-5.6857 -13.6875,-7.9687 -2.28309,-1.1415 0,-2.2813 0,-2.2813 -10e-6,0 4.54598,-3.4356 5.6875,-5.7187 0.64211,-0.3211 1.30911,-0.4644 1.90625,-0.5 z M 1026,1172.1875 c 0.9988,0 1.875,0.3125 1.875,0.3125 0,0 10.2483,2.2646 12.5312,3.4062 3.4248,1.1416 2.3126,3.4376 2.3126,3.4376 0,0 -6.8733,6.842 -9.1563,9.125 -2.2831,3.4245 -4.5625,1.1562 -4.5625,1.1562 0,0 -10.2629,-3.4523 -13.6875,-4.5938 -2.2831,0 -1.1562,-2.2812 -1.1563,-2.2812 10e-5,10e-5 6.8732,-6.8419 9.1563,-9.125 0.5708,-1.1415 1.6887,-1.4375 2.6875,-1.4375 z m -36.65625,1.1563 c 0.57077,0 0.84375,0.2812 0.84375,0.2812 10e-6,-10e-5 12.5774,4.5773 13.7187,5.7188 2.2832,0 1.1251,2.2812 1.125,2.2812 0,0 -2.2795,3.421 -4.5624,4.5625 -1.14164,2.283 -4.56255,0 -4.56255,0 -10e-6,0 -10.29418,-3.4375 -13.71875,-3.4375 -2.28306,-1.1414 0,-3.4062 0,-3.4062 -2e-5,0 2.31071,-2.2794 4.59375,-4.5626 1.14151,-1.1414 1.99173,-1.4375 2.5625,-1.4374 z m -43.4375,6.625 c 0.18425,-0.012 0.3702,-0.01 0.5625,0 1.28198,0.056 2.625,0.5 2.625,0.5 10e-6,0 11.40445,4.5772 13.6875,5.7187 2.28306,1.1415 0,3.4375 0,3.4375 2e-5,0 -3.42098,3.4044 -4.5625,5.6875 -2.28305,1.1415 -4.5625,0 -4.5625,0 0,0 -12.56071,-5.7021 -14.84375,-6.8437 -2.28302,-1.1416 0,-3.4376 0,-3.4376 3e-5,0 3.43571,-2.2795 5.71875,-4.5624 0.32106,-0.3211 0.82224,-0.4645 1.375,-0.5 z m -41.53125,0.625 c 1.41631,-0.068 2.5,1.0312 2.5,1.0312 -3e-5,0 11.40446,5.7023 13.6875,6.8438 2.28308,1.1415 0,3.4374 0,3.4374 3e-5,2e-4 -2.29418,3.4046 -5.71875,5.6876 -2.28305,2.283 -5.6875,0 -5.6875,0 -10e-6,0 -10.27945,-5.7023 -12.5625,-6.8438 -3.4246,-2.2831 -1.15625,-3.4375 -1.15625,-3.4375 2e-5,0 3.41918,-3.4044 6.84375,-5.6875 0.71344,-0.7135 1.44997,-1.0006 2.09375,-1.0312 z m 72.1875,5.7187 c 1.75353,-0.067 3.34375,1 3.34375,1 3e-5,0 10.27945,2.296 12.5625,3.4375 2.28303,2.283 1.15625,4.5625 1.15625,4.5625 2e-5,0 -2.27942,2.2794 -4.5625,4.5625 -2.28305,1.1415 -5.71875,0 -5.71875,0 -3e-5,0 -10.27946,-3.421 -12.5625,-4.5625 -3.42455,-1.1415 -1.125,-3.4063 -1.125,-3.4063 3e-5,2e-4 3.42094,-2.3106 4.5625,-4.5937 0.71345,-0.7134 1.54669,-0.9693 2.34375,-1 z m 34.1875,2.1563 c 1.1415,0 14.8273,2.2924 15.9688,8 2.2829,6.849 -60.49105,82.1674 -71.9063,87.875 -3.42458,2.283 -5.71875,0 -5.71875,0 10e-6,0 -11.41919,-4.5607 -14.84375,-6.8438 -4.56612,-1.1415 -1.125,-4.5625 -1.125,-4.5625 -10e-6,0 71.9209,-79.8898 73.0625,-81.0313 1.1415,-1.1413 2.2794,-3.4374 4.5625,-3.4374 z m -79.1875,4.0624 c 0.19612,-0.012 0.37856,-0.01 0.5625,0 1.22625,0.056 2.125,0.5 2.125,0.5 -2e-5,0 11.41918,4.5772 14.84375,5.7188 2.28306,2.283 1.15625,3.4062 1.15625,3.4062 -10e-6,0 -4.56071,4.5919 -6.84375,6.875 -1.14154,1.1417 -4.59375,0 -4.59375,0 3e-5,2e-4 -13.67098,-6.875 -14.8125,-6.875 -2.28307,-1.1414 0,-3.4062 0,-3.4062 -2e-5,0 3.40446,-3.4356 5.6875,-5.7188 0.6421,-0.3209 1.28664,-0.4644 1.875,-0.5 z m -43.6875,1.7813 c 1.38259,-0.067 3,1 3,1 10e-6,0 10.27945,4.5608 12.5625,6.8437 3.42459,1.1417 2.28125,3.4376 2.28125,3.4376 -2e-5,-2e-4 -4.56071,4.5606 -6.84375,6.8437 -2.28308,2.2829 -5.71875,0 -5.71875,0 3e-5,-10e-5 -11.41918,-6.8585 -14.84375,-8 -2.28306,-1.1415 0,-3.4063 0,-3.4063 2e-5,2e-4 5.71695,-3.4357 8,-5.7187 0.35673,-0.7135 0.93405,-0.9693 1.5625,-1 z m 75.84375,4.5625 c 1.41631,-0.067 2.5,1 2.5,1 2e-5,0 11.41918,3.421 14.84375,4.5625 2.28305,1.1415 1.125,3.4375 1.125,3.4375 -2e-5,0 -4.54598,4.5773 -5.6875,5.7188 -2.28302,1.1413 -5.71875,0 -5.71875,0 2e-5,-2e-4 -10.2629,-3.4211 -13.6875,-4.5626 -3.42456,-1.1413 -1.15625,-3.4374 -1.15625,-3.4374 -3e-5,-2e-4 4.57723,-3.4358 5.71875,-5.7188 0.71346,-0.7135 1.41872,-0.9693 2.0625,-1 z m -46.78125,6.8438 c 1.41631,-0.068 2.46875,1 2.46875,1 -10e-6,0 12.5607,5.7187 14.84375,5.7187 2.28302,1.1414 0,4.5625 0,4.5625 -2e-5,0 -4.54598,4.5772 -5.6875,5.7188 -2.28304,2.2828 -5.71875,1.125 -5.71875,1.125 0,-2e-4 -11.41915,-5.6858 -14.84375,-7.9688 -3.42456,-1.1416 0,-3.4375 0,-3.4375 10e-6,-10e-5 4.5607,-3.4356 6.84375,-5.7187 0.71345,-0.7136 1.44997,-0.9694 2.09375,-1 z M 870.75,1208 c 1.38259,-0.067 3,1.0312 3,1.0312 0,2e-4 12.56071,6.8273 14.84375,7.9688 1.1415,1.1415 0,3.4375 0,3.4375 -2e-5,-10e-5 -5.71695,5.7022 -8,6.8437 -2.28306,2.2832 -4.5625,1.1563 -4.5625,1.1563 2e-5,0 -13.70223,-8.0148 -14.84375,-9.1563 -2.28307,-1.1413 0,-3.4062 0,-3.4062 10e-6,0 5.71696,-4.5608 8,-6.8438 0.35673,-0.7133 0.93405,-1.0005 1.5625,-1.0312 z m 79.8125,5.0625 c 0.99827,0.019 1.96875,0.5313 1.96875,0.5313 2e-5,-2e-4 13.6857,4.546 15.96875,5.6874 2.28304,1.1417 0,3.4376 0,3.4376 -10e-6,-2e-4 -3.43571,3.4357 -5.71875,5.7187 -2.28303,2.283 -4.5625,1.125 -4.5625,1.125 3e-5,-10e-5 -13.68571,-5.7023 -15.96875,-6.8437 -2.28308,-1.1417 0,-2.2813 0,-2.2813 0,-10e-5 4.56071,-4.5607 6.84375,-6.8437 0.28538,-0.2855 0.65669,-0.4465 1.03125,-0.5 0.14046,-0.02 0.29489,-0.034 0.4375,-0.031 z m -49.34375,7.5 c 1.75353,-0.067 3.375,1 3.375,1 0,-10e-5 11.40445,5.7335 13.6875,6.875 2.28305,2.283 0,4.5625 0,4.5625 10e-6,0 -4.57722,4.5607 -5.71875,6.8438 -2.28307,1.1413 -5.6875,0 -5.6875,0 -3e-5,-2e-4 -13.71696,-6.8586 -16,-8 -2.28304,-2.2833 1.15625,-3.4063 1.15625,-3.4063 -10e-6,0 4.5607,-4.592 6.84375,-6.875 0.71344,-0.7135 1.54669,-0.9693 2.34375,-1 z m -48.125,2.9687 c 0.41302,0.011 0.82193,0.099 1.25,0.3126 3.42459,2.2829 14.84375,9.1562 14.84375,9.1562 0,0 2.29777,1.1231 1.15625,3.4062 -2.28306,2.2832 -8,6.8438 -8,6.8438 -10e-6,0 -1.15262,3.4393 -5.71875,1.1562 -3.42458,-1.1414 -15.96875,-9.125 -15.96875,-9.125 2e-5,2e-4 -1.14152,-1.1545 0,-3.4374 2.28307,-1.1418 9.125,-6.8438 9.125,-6.8438 -2e-5,0 1.52274,-1.5158 3.3125,-1.4688 z m 82.46875,4.5313 c 0.70453,-0.033 1.41155,0.09 2.125,0.375 7.99066,3.4246 17.11028,5.6856 15.96875,7.9687 -1.14152,2.2832 -6.84016,11.4081 -11.40625,9.125 -1.14156,2e-4 -19.40804,-5.7004 -17.125,-9.125 0.99888,-0.9986 5.50577,-8.1096 10.4375,-8.3437 z m -52.625,8.4687 c 1.75353,-0.067 3.375,1.0313 3.375,1.0313 2e-5,0 11.41919,5.7022 14.84375,6.8437 2.28304,1.1417 0,4.5626 0,4.5626 -10e-6,-2e-4 -4.56071,5.7022 -6.84375,6.8437 -2.2831,2.2831 -5.71875,1.1563 -5.71875,1.1563 -2e-5,-2e-4 -13.6857,-6.8585 -15.96875,-8 -2.28303,-1.1417 0,-4.5626 0,-4.5626 10e-6,2e-4 5.68571,-4.5606 7.96875,-6.8437 0.71345,-0.7134 1.54669,-1.0006 2.34375,-1.0313 z m -51,4.5938 c 1.38259,-0.067 3,1 3,1 -10e-6,0 13.71695,6.842 16,9.125 1.14153,1.1415 -1.15625,3.4375 -1.15625,3.4375 -3e-5,0 -6.84195,6.8273 -9.125,7.9687 -2.28302,2.2833 -5.71875,0 -5.71875,0 -10e-6,2e-4 -11.41918,-6.8419 -14.84375,-9.125 -3.42456,-2.2829 0,-4.5624 0,-4.5624 0,-2e-4 7.99817,-5.7023 10.28125,-6.8438 0.35672,-0.7134 0.93405,-0.9693 1.5625,-1 z m 87.90625,3 c 0.99883,0 1.84375,0.2812 1.84375,0.2812 10e-6,2e-4 13.71696,5.7023 16,6.8438 1.1415,1.1415 1.125,4.5625 1.125,4.5625 3e-5,0 -5.68571,5.7023 -7.96875,6.8437 -1.1415,2.2833 -5.71875,0 -5.71875,0 2e-5,2e-4 -13.68567,-5.7022 -15.96875,-6.8437 -2.28305,-1.1415 0,-2.2813 0,-2.2813 -10e-6,2e-4 5.68571,-5.7169 7.96875,-8 0.57077,-1.1414 1.71992,-1.4062 2.71875,-1.4062 z m -55.8125,9.5312 c 1.78725,-0.067 2.875,1.0313 2.875,1.0313 -2e-5,0 13.6857,6.8273 15.96875,7.9687 2.28305,1.1418 0,4.5938 0,4.5938 10e-6,10e-5 -5.68567,5.6857 -7.96875,7.9688 -2.28307,2.283 -5.71875,1.1562 -5.71875,1.1562 0,10e-5 -13.68571,-7.9835 -15.96875,-9.125 -3.42459,-2.283 0,-4.5938 0,-4.5938 -2e-5,2e-4 5.68567,-4.5441 7.96875,-7.9687 1.07018,-0.7135 2.03136,-1.0006 2.84375,-1.0313 z m -53.28125,4.5626 c 1.41633,-0.068 2.5,1.0312 2.5,1.0312 -10e-6,0 13.71692,7.9835 16,9.125 1.14154,2.283 0,4.5625 0,4.5625 2e-5,0 -9.15446,7.9835 -11.4375,9.125 -2.28307,2.283 -4.5625,0 -4.5625,0 -10e-6,0 -14.82723,-9.1085 -15.96875,-10.25 -2.28305,-1.1416 0,-3.4375 0,-3.4375 3e-5,0 9.12321,-6.842 11.40625,-9.125 0.71346,-0.7135 1.41872,-1.0006 2.0625,-1.0312 z m 90.21875,3.9374 c 0.24068,-0.012 0.48465,-0.01 0.71875,0 1.56068,0.056 2.90625,0.5 2.90625,0.5 0,2e-4 12.52945,5.7335 14.8125,6.875 3.42456,1.1416 2.28125,3.4063 2.28125,3.4063 10e-6,0 -4.56071,4.5754 -6.84375,8 -3.42457,3.4245 -7.96875,1.125 -7.96875,1.125 -3e-5,0 -12.5754,-5.7022 -16,-6.8437 -2.28304,-1.1416 0,-4.5626 0,-4.5626 10e-6,0 5.71695,-5.7168 8,-8 0.6421,-0.3209 1.37171,-0.4644 2.09375,-0.5 z m -56.84375,10.9063 c 1.75354,-0.067 3.375,1.0313 3.375,1.0313 10e-6,0 13.70223,6.8419 14.84375,9.125 2.28303,1.1414 1.125,3.4374 1.125,3.4374 -3e-5,0 -9.10848,7.9835 -10.25,9.125 -2.28307,2.2831 -4.5625,0 -4.5625,0 -2e-5,0 -15.99821,-7.9834 -18.28125,-9.125 -2.28308,-2.283 1.15625,-3.4374 1.15625,-3.4374 -2e-5,0 6.82543,-6.842 10.25,-9.125 0.71345,-0.7136 1.54669,-1.0006 2.34375,-1.0313 z m -56.8125,5.0625 c 0.99827,0.019 1.96875,0.5312 1.96875,0.5312 0,0 13.71695,9.1398 16,10.2813 3.42459,2.2831 0,4.5625 0,4.5625 3e-5,10e-5 -19.41918,18.263 -22.84375,21.6875 -3.42462,3.4246 -6.84375,0 -6.84375,0 -10e-6,0 -14.85847,-9.1545 -16,-11.4375 -2.28301,-1.1415 0,-3.4062 0,-3.4062 3e-5,0 25.13973,-20.546 26.28125,-21.6876 0.28538,-0.2853 0.62544,-0.4464 1,-0.5 0.14046,-0.02 0.29489,-0.034 0.4375,-0.031 z m 95.875,2.5312 c 1.14152,0 2,0.2813 2,0.2813 3e-5,0 11.38793,5.7022 14.8125,6.8437 4.5661,2.2832 2.28125,4.5626 2.28125,4.5626 -2e-5,0 -6.84192,7.9982 -9.125,10.2812 -1.14149,2.2832 -5.6875,0 -5.6875,0 0,10e-5 -13.70043,-6.8584 -17.125,-8 -3.42458,-1.1415 0,-4.5625 0,-4.5625 -10e-6,0 6.84196,-5.717 9.125,-8 1.14152,-1.1415 2.57723,-1.4062 3.71875,-1.4063 z m 43.375,3.4063 c 1.14153,0 2,0.2813 2,0.2813 0,0 11.40263,5.7169 15.96875,8 3.42459,2.2829 1.15625,4.5624 1.15625,4.5624 0,0 -13.71695,17.1398 -16,18.2813 -2.28306,2.2831 -6.84375,1.125 -6.84375,1.125 0,0 -11.40263,-4.5606 -15.96875,-6.8437 -4.56612,-1.1416 0,-5.7188 0,-5.7188 -3e-5,10e-5 13.6857,-15.967 15.96875,-18.25 1.14152,-1.1415 2.57722,-1.4375 3.71875,-1.4375 z m -104.75,9.5625 c 1.78726,-0.068 2.875,1 2.875,1 -10e-6,0 14.8107,9.1398 17.09375,10.2812 2.28305,2.2831 0,3.4376 0,3.4376 10e-6,-2e-4 -27.37317,25.0918 -29.65625,27.375 -3.4246,2.2828 -6.84375,1.1562 -6.84375,1.1562 3e-5,0 -14.84195,-9.1544 -17.125,-11.4375 -2.28303,-2.283 1.125,-5.6875 1.125,-5.6875 0,0 26.26293,-21.7004 29.6875,-25.125 1.07019,-0.7135 2.03136,-0.9693 2.84375,-1 z m 40.84375,8.25 c 1.24158,0.023 1.96875,0.75 1.96875,0.75 10e-6,10e-5 13.70043,6.8419 17.125,9.125 3.42459,2.283 1.125,3.4375 1.125,3.4375 10e-6,0 -37.65442,38.8108 -39.9375,41.0937 -3.42458,2.2832 -8,0 -8,0 -10e-6,2e-4 -11.41918,-6.8418 -14.84375,-9.125 -4.56609,-2.2828 -1.125,-5.7187 -1.125,-5.7187 2e-5,-10e-5 37.65445,-34.263 39.9375,-37.6875 1.49827,-1.4982 2.78433,-1.8926 3.75,-1.875 z m 34.5,13.4375 c 1.78725,-0.067 2.84375,1 2.84375,1 10e-6,0 13.70044,5.717 17.125,8 3.42459,1.1415 1.15625,4.5625 1.15625,4.5625 10e-6,0 -6.84192,7.9817 -9.125,11.4062 -2.28305,2.2832 -6.875,-1.125 -6.875,-1.125 -2e-5,2e-4 -13.66918,-5.717 -17.09375,-8 -3.42453,-2.2829 0,-3.4062 0,-3.4062 3e-5,0 5.7004,-8.0129 9.125,-11.4375 1.07017,-0.7134 2.03136,-0.9693 2.84375,-1 z m -20.125,23.0937 c 0.92554,0.023 1.28125,0.75 1.28125,0.75 2e-5,2e-4 14.85665,6.8421 18.28125,9.125 4.56609,3.4248 1.125,6.8438 1.125,6.8438 -10e-6,0 -19.40442,19.4191 -21.6875,22.8438 -2.28302,3.4245 -7.96875,1.125 -7.96875,1.125 2e-5,-2e-4 -12.55891,-7.9671 -17.125,-10.25 -4.56608,-2.2832 0,-5.7188 0,-5.7188 10e-6,0 20.52945,-19.4192 22.8125,-22.8438 1.49826,-1.4981 2.56138,-1.8925 3.28125,-1.875 z"
+       style="fill:#5f4343;fill-opacity:1;stroke:none" />
+    <path
+       id="path5329"
+       d="m 996.43321,1078.2021 c 0,0 1.75429,1.8291 1.75429,1.8291 10e-6,1e-4 12.5625,6.8438 12.5625,6.8438 0,0 -0.015,1.1398 -1.1562,2.2812 -1.1416,1e-4 -2.2813,2.2813 -2.2813,2.2813 0,0 -1.1396,1.1415 -2.2813,0 -1.1415,-1.1415 -13.68745,-8 -13.68745,-8 0,0 -1.15625,3.4375 -1.15625,3.4375 10e-6,0 10.2813,5.7188 10.2813,5.7188 0,-1e-4 2.2664,1.1397 1.125,2.2812 -1.1416,1.1415 -3.4063,2.2812 -3.4063,2.2812 10e-6,1e-4 -1.15446,2.2831 -3.4375,0 -2.28304,-1.1414 -12.5625,-5.7187 -12.5625,-5.7187 -2e-5,0 -4.5625,4.5625 -4.5625,4.5625 0,0 11.4375,6.8438 11.4375,6.8438 0,-1e-4 1.125,2.2812 1.125,2.2812 10e-6,0 4.5625,2.2812 4.5625,2.2812 10e-6,1e-4 2.29598,0.017 3.4375,-1.125 10e-6,1.1416 1.13969,2.2813 2.2813,2.2813 2.283,1.1416 8,3.421 8,4.5625 2.2831,2.283 5.6874,3.4375 5.6874,3.4375 10e-5,0 2.2961,1.1415 3.4376,0 0,0 -0.017,1.1398 1.125,2.2813 2.283,1.1415 16,7.9687 16,7.9687 0,10e-5 1.1397,0 2.2812,0 1.1416,-1.1414 4.5625,-5.6875 4.5625,-5.6875 0,0 0,-0.015 0,-1.1562 1.1415,-1e-4 1.1398,0.017 2.2813,-1.125 1.1415,-1e-4 2.2812,-2.2813 2.2812,-2.2813 -10e-5,1.1415 -1.1416,2.2646 0,3.4063 1.1414,1.1414 13.6875,6.8437 13.6875,6.8437 4.5592,-0.3379 0.4467,6.3072 1.5882,5.1657 -10e-5,-10e-5 1.8643,-4.0244 3.0055,-5.1657 2.283,-2.283 3.4063,-1.125 3.4063,-1.125 0,0 10.2795,3.4375 12.5625,3.4375 2.2831,1.1416 0,3.4062 0,3.4062 0,1e-4 0,1.1397 -2.2812,2.2813 -1.1416,2.283 -2.2813,1.1563 -2.2813,1.1563 -1.1415,0 -14.8437,-4.5626 -14.8437,-4.5626 0,0 -3.4376,4.5461 -3.4376,5.6876 1.1415,-1e-4 12.5773,4.5624 13.7188,4.5624 0,2.2832 0,4.5626 0,4.5626 0,-1e-4 4.5625,1.1562 4.5625,1.1562 0,0 1.1397,1.1416 2.2813,0 0,-1.1415 3.4062,-5.7188 3.4062,-5.7188 -10e-5,1e-4 1.1416,-1.1397 0,-2.2812 1.1415,1.1415 2.296,-1.125 3.4375,-1.125 0,-1.1417 3.4375,-4.5625 3.4375,-4.5625 0,0 0,-1.1545 0,-3.4375 1.1415,0 1.1398,1.1415 2.2812,0 0,-1.1416 3.4063,-5.7188 3.4063,-5.7188 0,1e-4 0,0 0,-2.2812 0,-2.283 0,-6.8438 0,-6.8438 0,1e-4 -2.2813,3.4376 -2.2813,3.4376 1e-4,-1e-4 -1.1232,1.1416 -3.4062,0 -1.1415,-1e-4 -9.6865,-1.4962 -11.5258,-2.6746 -1.8392,-1.1784 4.9339,-5.5365 4.9339,-5.5365 -1.5289,-2.2482 -12.18,13.0253 -12.18,13.0253 0,0 3.2725,-2.7532 6.0024,-5.7913 2.0445,-2.2754 11.6133,3.2583 11.6133,3.2583 -1e-4,0 1.1414,1.1398 0,2.2812 -1.1417,1.1416 -1.125,3.4063 -1.125,3.4063 0,10e-5 -1.1545,1.1415 -3.4376,0 -3.4246,10e-5 -12.5624,-3.4063 -12.5624,-3.4063 0,1e-4 -2.2813,-1.1562 -2.2813,-1.1562 0,0 0,-9.125 0,-9.125 0,0 -2.2648,4.5625 -3.4063,4.5625 -2.2831,10e-5 -14.8585,-3.421 -16,-4.5625 -1.1415,0 3.4376,-4.5625 3.4376,-4.5625 0,10e-5 15.0012,5.1873 16.1427,5.1873 1.1415,10e-5 -15.0158,-6.2196 -15.0158,-6.2196 0,10e-5 3.4355,-8.0927 3.4355,-8.0927 0,10e-5 -3.4374,3.4063 -3.4374,3.4063 0,-1e-4 0,1.1414 -2.2813,0 -1.1416,-1.1417 -11.4063,-4.5626 -11.4063,-4.5626 0,1e-4 -1.1562,-1.125 -1.1562,-1.125 0,1e-4 1.1562,-1.1562 1.1562,-1.1562 0,0 -1.1562,-5.6875 -1.1562,-5.6875 0,10e-5 -3.4062,3.4063 -3.4062,3.4063 0,-1e-4 -1.1398,1.1414 -2.2813,0 0,-1.1417 -12.5625,-6.8438 -12.5625,-6.8438 0,0 -1.1562,-4.5625 -1.1562,-4.5625 0,0 -3.4063,2.2813 -3.4063,2.2813 0,-1e-4 -1.1544,1.1414 -3.4375,0 -1.1415,-1.1417 -15.44179,-6.3917 -15.44179,-6.3917 z m 22.28559,10.9541 c 0,2e-4 8.0146,4.5773 9.1562,5.7188 2.283,1.1415 2.2812,2.2812 2.2812,2.2812 0,2e-4 -2.2959,1.1398 -3.4374,2.2813 -1.1417,2.2831 -3.4063,1.125 -3.4063,1.125 0,0 -6.8565,-4.546 -10.2813,-5.6875 -2.2829,-1.1415 -1.1562,-2.2812 -1.1562,-2.2812 0,-2e-4 2.296,-1.1398 3.4375,-2.2813 1.1415,-1.1414 3.4062,-1.1563 3.4063,-1.1563 z m -10.9063,6.3438 c 0.1516,-0.012 0.3037,-0.01 0.4375,0 0.8918,0.056 1.3437,0.5 1.3438,0.5 0,0 9.1397,4.5773 10.2812,5.7188 2.2831,1.1414 1.125,2.2812 1.125,2.2812 0,0 -1.1233,1.1232 -3.4062,3.4062 -1.1415,1.1417 -3.4375,0 -3.4376,0 10e-5,2e-4 -10.2647,-4.5459 -11.4062,-5.6874 -2.283,-2.2832 0,-2.2813 0,-2.2813 0,10e-5 1.1544,-2.296 3.4375,-3.4375 0.6421,-0.3211 1.1703,-0.4644 1.625,-0.5 z m 28.8125,3.9375 c 0.2319,-0.018 0.375,0 0.375,0 0,10e-5 7.9981,3.421 10.2812,4.5625 1.1416,1.1415 1.125,3.4062 1.125,3.4062 0,2e-4 -1.1397,0.015 -2.2812,1.1563 -2.2832,2.2831 -4.5625,1.1563 -4.5625,1.1563 0,-2e-4 -9.1232,-3.4522 -11.4063,-4.5938 -2.2829,-1.1415 0,-2.2812 0,-2.2812 0,-2e-4 2.2648,-1.1398 3.4063,-2.2813 0.8561,-0.8562 2.3669,-1.0715 3.0625,-1.125 z m -9.9062,7.4687 c 0.1396,-0.012 0.2953,-0.01 0.4374,0 0.9477,0.056 1.8438,0.5 1.8438,0.5 0,2e-4 9.1398,3.4522 10.2812,4.5938 2.2832,1.1415 1.125,2.2812 1.125,2.2812 2e-4,2e-4 -2.2646,1.1397 -3.4062,2.2813 -1.1415,2.283 -3.4375,0 -3.4375,0 0,0 -7.9816,-3.421 -11.4063,-4.5625 -2.283,-1.1416 10e-5,-2.2812 0,-2.2812 0,-2e-4 2.2961,-1.1711 3.4376,-2.3126 0.3209,-0.3209 0.7059,-0.4644 1.125,-0.5 z"
+       style="fill:#5f4343;fill-opacity:1;stroke:none"
+       sodipodi:nodetypes="cccccscccscccccccccccccccccccscssccccccccccccscccccscccsccscscccccsccsccccccccccccccccccccccsccscccssscscccccscscsccsccccccssc" />
+    <path
+       id="path5341"
+       d="m 1032.4375,1053.7812 c 0,0 0,2.2813 0,2.2813 0,0 9.125,4.5625 9.125,4.5625 0,0 1.1563,1.1397 1.1563,2.2812 -1.1415,0 -2.3126,1.125 -2.3126,1.125 1e-4,0 0,0 -2.2812,0 -2.2831,-1.1415 -11.4062,-5.6874 -11.4062,-5.6874 -1e-4,0 -1.125,2.2812 -1.125,2.2812 0,0 9.125,4.5625 9.125,4.5625 0,0 2.2664,1.1397 1.125,2.2813 -1.1416,1.1415 -2.2813,2.2812 -2.2813,2.2812 0,0 -1.1232,1.1415 -3.4063,0 -1.1415,-1.1416 -11.4374,-5.7188 -11.4374,-5.7188 0,0 0,2.2813 0,2.2813 0,0 9.1562,4.5937 9.1562,4.5937 0,1e-4 2.2665,1.1398 1.125,2.2813 -1.1415,1.1416 -2.2812,2.2813 -2.2812,2.2813 -1e-4,-1e-4 -2.2648,0 -3.4063,0 -2.2831,-1.1416 -11.4375,-6.8438 -11.4375,-6.8438 0,0 -3.4062,6.8438 -3.4062,6.8438 0,-1e-4 7.9669,4.546 10.25,5.6874 1.1415,1.1415 4.5937,3.4376 4.5937,3.4376 0,-1e-4 1.125,-1.1563 1.125,-1.1563 0,0 1.1398,-1.1415 2.2813,0 1.1415,1.1416 11.4062,5.7187 11.4062,5.7187 0,1e-4 1.1415,1.1398 0,2.2813 2.283,1.1415 3.4375,1.1563 3.4375,1.1563 0,-1e-4 1.1398,1.1268 2.2813,-1.1563 0,2.2831 0.015,2.2813 1.1562,2.2813 1.1415,1.1414 10.2648,4.5772 11.4062,5.7187 0,10e-5 3.4063,2.2813 3.4063,2.2813 0,-1e-4 0.8733,0.8455 1.8437,-0.4063 -0.2316,0.8449 0.4376,1.5313 0.4376,1.5313 0,-1e-4 14.8437,8 14.8437,8 0,-1e-4 2.4929,-0.8258 3.2187,-1.7813 -0.5808,1.7789 1.3438,1.7813 1.3438,1.7813 -10e-5,-1e-4 10.2812,3.4374 10.2812,3.4374 1e-4,1e-4 2.2813,-0.016 2.2813,1.125 0,2.2832 0,3.4376 0,3.4376 0,-1e-4 2.2813,1.125 2.2813,1.125 -1e-4,-1e-4 1.1397,1.1581 2.2812,-1.125 1.1415,-1.1416 8,-10.2813 8,-10.2813 0,10e-5 1.1562,-1.1398 1.1562,-2.2813 1e-4,1.1416 1.1397,-0.015 2.2813,-1.1562 10e-5,0 2.2813,-3.4062 2.2813,-3.4062 -1e-4,-1e-4 0,-1.1398 0,-2.2813 1.1414,1.1416 2.2812,0 2.2812,0 1.1415,-1.1414 2.2812,-2.296 2.2812,-3.4375 1e-4,-2.283 0,-8 0,-8 1e-4,0 -2.2812,1.1562 -2.2812,1.1562 0,1e-4 0,1.1415 -2.2812,0 -1.1416,1e-4 -29.6876,-9.125 -29.6876,-9.125 0,1e-4 0,-1.1562 0,-1.1562 0,-1.1415 0,-1.125 0,-1.125 0,0 0,-4.5625 0,-4.5625 0,0 -2.2812,1.125 -2.2812,1.125 0,0 -1.1398,1.1563 -2.2812,1.1563 -1.1416,-1.1416 -27.4063,-11.4376 -27.4063,-11.4376 0,0 -1.1416,-1.125 0,-1.125 0,-1.1415 -1.125,0 -1.125,0 0,0 -1.1563,-5.7187 -1.1563,-5.7187 0,0 -2.2812,1.1563 -2.2812,1.1563 -10e-5,0 0,1.1414 -2.2812,0 -1.1415,0 -11.4063,-4.5626 -11.4063,-4.5626 z m 14.5,10.875 c 0.1431,-0.01 0.2767,0.011 0.4063,0.031 1.5143,0.2436 3.0593,0.9756 4.4374,1.75 2.2956,1.2899 8.1091,1.352 7.3438,3.75 -0.4274,1.3393 -3.1814,3.4295 -4.875,2.6875 -2.9708,-1.3016 -5.9217,-3.1706 -9.125,-3.9375 -3.7088,-0.888 -0.3336,-4.153 1.8125,-4.2813 z m -6.75,4.5938 c 0.1067,-0.012 0.2115,-0.01 0.3125,0 2.1854,0.1729 4.5292,1.6622 6.6875,2.7188 1.7885,0.8756 7.0484,1.8489 4.5,4.7812 -2.6942,3.1001 -4.9473,1.0023 -7.4375,-0.25 -2.4903,-1.2523 -7.6472,-1.121 -7.75,-3.4062 -0.061,-1.3642 2.0875,-3.6678 3.6875,-3.8438 z m 24.5313,3.4062 c 3.135,-0.181 5.7528,2.9029 8.8437,3.2813 4.7632,0.5831 1.709,5.6486 -1.0313,5.5 -3.1145,-0.1689 -5.9514,-2.7015 -9.0937,-3.0313 -4.9831,-0.5228 -2.0245,-4.8267 0.8437,-5.7187 0,0 0.4376,-0.031 0.4376,-0.031 z m -31.1876,2.5626 c 0.4059,0.018 0.8322,0.1295 1.1876,0.25 2.8864,0.9782 5.5539,2.8687 8.5,3.7187 4.39,1.2666 0.668,6.2885 -1.7188,5.9063 -3.4682,-0.5554 -6.7382,-3.3346 -10.25,-4.5313 -3.9168,-1.3348 -0.5444,-3.9827 1.1875,-5.0937 0.3026,-0.1942 0.6879,-0.2685 1.0937,-0.25 z m 25,3.375 c 2.7119,-0.1165 5.3251,2.3977 8.1563,2.9062 2.5246,0.4534 5.1522,1.4808 2.8437,4.1562 -2.44,2.828 -5.4778,2.2403 -8.2812,0.5 -2.3712,-1.4719 -7.2155,-1.838 -7.4062,-4.2812 -0.1156,-1.4802 3.0044,-3.2089 4.6874,-3.2812 z M 1081.125,1080 c 1.6161,-0.071 3.4869,0.8546 5.0625,1.75 2.3345,1.3267 7.6074,1.2983 7.4063,3.625 -0.1199,1.3867 -2.2066,3.3749 -4.0938,3.0312 -3.366,-0.6128 -6.5292,-2.4262 -9.9062,-3.0312 -3.6566,-0.6551 -1.6553,-3.9335 0.031,-4.9375 0.4656,-0.2772 0.9613,-0.4138 1.5,-0.4375 z m -30.125,4.0625 c 3.52,-0.2033 6.5985,2.7821 10.0312,3.4687 4.4432,0.8887 2.5162,6.3853 -1.0312,5.5626 -3.5586,-0.8255 -6.8109,-3.3234 -10.5,-3.7813 -4.359,-0.5411 -1.4036,-4.5171 1.0625,-5.2187 0,0 0.4375,-0.031 0.4375,-0.031 z m 24.375,2.3125 c 3.484,0.2314 7.1443,2.2076 10.7188,2.7812 4.2477,0.6818 1.5611,5.693 -1.2188,5.0626 -3.3481,-0.7593 -6.7659,-2.5707 -10.25,-2.6876 -4.6488,-0.1558 -1.3613,-5.2964 0.75,-5.1562 z m 26.25,1.5312 c 0.159,0.01 0.3016,0.047 0.4375,0.094 3.4825,1.1963 8.7418,1.8557 10.4063,4.4062 1.5228,2.3337 -4.192,4.401 -6.9063,3.1563 -2.7477,-1.26 -6.3887,-0.5186 -8.7187,-2.25 -2.275,-1.6904 2.3962,-5.5491 4.7812,-5.4063 z m -31.3438,4.5938 c 0.3405,-0.035 0.6569,6e-4 0.9688,0.094 3.1728,0.9482 6.2433,2.7944 9.5,3.1874 2.8926,0.3491 1.6663,1.7373 0.3438,3.375 -1.7361,2.1499 -4.2301,1.3607 -6.6563,0.625 -2.937,-0.8903 -7.3865,-1.2683 -8.7187,-3.125 -0.6351,-0.885 2.1796,-3.914 4.5624,-4.1562 z m 23.1563,2.0312 c 0,0 0.2264,0.049 0.3125,0.094 0.1066,0.056 0.3125,0.25 0.3125,0.25 2.6649,2.0969 6.6322,1.4252 9.9687,1.9375 3.7146,0.5703 2.9883,4.3818 0.2813,6.0625 -2.4697,1.5334 -3.7411,5.5719 -6.4687,6 -3.4422,0.5403 -7.0547,-2.0774 -10.5938,-2.8125 -4.2034,-0.8731 -2.2665,-3.8985 0.062,-5.5937 2.2838,-1.6622 3.9073,-4.3793 6.125,-5.9376 z"
+       style="fill:#5f4343;fill-opacity:1;stroke:none" />
+  </g>
+  <path
+     style="fill:#c00000;fill-opacity:1;fill-rule:nonzero;stroke:none"
+     id="path5365"
+     d="" />
+  <!-- EMR_SETBKCOLOR -->
+  <path
+     style="fill:#e00a0e;fill-opacity:1;fill-rule:nonzero;stroke:#ffffff;stroke-width:0.03543307px;stroke-linejoin:round;stroke-dasharray:none;stroke-opacity:1"
+     id="path5379"
+     d="" />
+  <path
+     style="fill:none;stroke:#ffffff;stroke-width:0.03543307px;stroke-linejoin:round;stroke-dasharray:none;stroke-opacity:1"
+     d=""
+     id="path5393" />
+  <!-- EMR_SETBKCOLOR -->
+  <path
+     style="fill:none;stroke:#ffffff;stroke-width:1.41732287px;stroke-linejoin:round;stroke-dasharray:none;stroke-opacity:1"
+     d=""
+     id="path5397" />
+  <!-- EMR_SETBKCOLOR -->
+  <!-- EMR_SETBKCOLOR -->
+  <!-- EMR_SETBKCOLOR -->
+  <!-- EMR_SETBKCOLOR -->
+  <path
+     style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:#ffffff;stroke-width:0.88582677px;stroke-linejoin:round;stroke-dasharray:none;stroke-opacity:1"
+     id="path5413"
+     d="" />
+  <path
+     style="fill:none;stroke:#ffffff;stroke-width:0.88582677px;stroke-linejoin:round;stroke-dasharray:none;stroke-opacity:1"
+     d=""
+     id="path5423" />
+  <!-- EMR_SETBKCOLOR -->
+  <path
+     style="fill:none;stroke:none"
+     d=""
+     id="path5433" />
+  <!-- EMR_SETBKCOLOR -->
+  <path
+     style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:#ffffff;stroke-width:0.10629921px;stroke-linejoin:round;stroke-dasharray:none;stroke-opacity:1"
+     id="path5439"
+     d="" />
+  <path
+     style="fill:none;stroke:#ffffff;stroke-width:0.10629921px;stroke-linejoin:round;stroke-dasharray:none;stroke-opacity:1"
+     d=""
+     id="path5445" />
+  <!-- EMR_SETBKCOLOR -->
+  <path
+     style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:#ffffff;stroke-width:0.10629921px;stroke-linejoin:round;stroke-dasharray:none;stroke-opacity:1"
+     id="path5451"
+     d="" />
+  <path
+     style="fill:none;stroke:#ffffff;stroke-width:0.10629921px;stroke-linejoin:round;stroke-dasharray:none;stroke-opacity:1"
+     d=""
+     id="path5457" />
+  <path
+     style="fill:#82dd82;fill-opacity:1;fill-rule:evenodd;stroke:none"
+     d="m 562.95051,311.07906 -8.20912,-13.48641 c 0,0 -7.02559,4.4238 -9.38186,7.0364 -0.68696,0.76169 -1.7591,2.93182 -1.7591,2.93182 l 7.62276,10.84778 c 0,0 2.35405,0.55873 3.5182,-0.29319 1.98869,-1.45531 8.20912,-7.0364 8.20912,-7.0364 z"
+     id="path2421"
+     sodipodi:nodetypes="ccsccsc" />
+  <path
+     id="path3193"
+     d="m 548.12942,320.89154 -8.72397,-11.08723 c 0,0 -4.2646,2.2353 -5.63607,3.72826 -1.54143,1.67797 -3.63889,6.66655 -3.63889,6.66655 l 7.66457,7.02896 c 0,0 2.86994,0.36904 3.96645,-0.094 2.46448,-1.04073 6.36791,-6.24254 6.36791,-6.24254 z"
+     style="fill:#dd8282;fill-opacity:1;fill-rule:evenodd;stroke:none"
+     inkscape:transform-center-y="6.743208"
+     sodipodi:nodetypes="ccsccsc" />
+  <path
+     sodipodi:nodetypes="ccsccsc"
+     id="path3195"
+     d="m 534.80495,332.18823 -8.50231,-11.14094 c 0,0 -2.92103,0.31923 -5.2773,2.93183 -0.68696,0.7617 -3.5182,3.81138 -3.5182,3.81138 l 7.62277,9.38185 c 0,0 3.23359,1.1451 4.39774,0.29318 1.98869,-1.45531 5.2773,-5.2773 5.2773,-5.2773 z"
+     style="fill:#f2fa66;fill-opacity:1;fill-rule:evenodd;stroke:none" />
+  <path
+     style="fill:#6766fa;fill-opacity:1;fill-rule:evenodd;stroke:none"
+     d="m 522.09443,342.55737 -7.36808,-11.24867 c 0,0 -4.15725,0.48942 -6.22792,2.98144 -0.60369,0.72655 -3.30497,4.84879 -3.30497,4.84879 l 6.69879,10.34711 c 0,0 4.64517,-1.70427 5.6682,-2.51686 1.74764,-1.38816 4.53398,-4.41181 4.53398,-4.41181 z"
+     id="path3197"
+     sodipodi:nodetypes="ccsccsc" />
+  <path
+     sodipodi:nodetypes="csscssc"
+     id="path3199"
+     d="m 502.98724,356.81075 c 0,0 -6.15329,-7.8654 -6.71213,-8.39073 -2.12774,-2.00018 -3.15592,-1.10569 -7.22338,2.25021 -2.15469,1.77774 -1.04936,3.01483 -1.04936,3.01483 0,0 6.29388,9.74911 7.53386,9.96574 1.10444,0.19295 5.51695,-3.97211 6.2754,-4.67985 1.29566,-1.20904 1.17561,-2.1602 1.17561,-2.1602 z"
+     style="fill:#faab66;fill-opacity:1;fill-rule:evenodd;stroke:none" />
+  <path
+     sodipodi:nodetypes="ccsccss"
+     id="path3201"
+     d="m 554.45074,277.9667 c 0.30244,-1.5732 -10.73457,-16.03165 -10.73457,-16.03165 0,0 -6.34815,5.12268 -8.47722,8.14802 -0.62072,0.88203 -1.58948,3.395 -1.58948,3.395 l 8.96086,12.14692 c 0,0 4.20018,-1.2188 5.25207,-2.20531 1.79694,-1.68523 6.20869,-3.4782 6.58834,-5.45298 z"
+     style="fill:#82dd82;fill-opacity:1;fill-rule:evenodd;stroke:none" />
+  <path
+     sodipodi:nodetypes="ccsccsc"
+     inkscape:transform-center-y="7.7231055"
+     style="fill:#dd8282;fill-opacity:1;fill-rule:evenodd;stroke:none"
+     d="m 537.95297,289.50333 -8.69279,-13.06165 c 0,0 -4.61199,2.34582 -6.13186,3.9831 -1.7082,1.84017 -4.16076,7.4296 -4.16076,7.4296 l 7.76566,8.38254 c 0,0 3.01497,0.55791 4.19552,0.0821 2.65334,-1.06932 7.02423,-6.81574 7.02423,-6.81574 z"
+     id="path3203"
+     inkscape:transform-center-x="0.41226172" />
+  <path
+     style="fill:#f2fa66;fill-opacity:1;fill-rule:evenodd;stroke:none"
+     d="m 524.85399,302.95511 -9.4194,-12.79725 c 0,0 -3.23609,0.36669 -5.84652,3.3677 -0.76106,0.87493 -3.89769,4.378 -3.89769,4.378 l 8.44498,10.77665 c 0,0 3.58239,1.31534 4.8721,0.33677 2.2032,-1.67167 5.84653,-6.06187 5.84653,-6.06187 z"
+     id="path3205"
+     sodipodi:nodetypes="ccsccsc" />
+  <path
+     sodipodi:nodetypes="ccsccsc"
+     id="path3207"
+     d="m 511.52154,313.52352 -7.7296,-12.27501 c 0,0 -4.36123,0.53408 -6.53349,3.25348 -0.63332,0.79283 -3.46713,5.29118 -3.46713,5.29118 l 7.02747,11.29117 c 0,0 4.87308,-1.85976 5.94631,-2.7465 1.83339,-1.51481 4.75644,-4.81432 4.75644,-4.81432 z"
+     style="fill:#6766fa;fill-opacity:1;fill-rule:evenodd;stroke:none" />
+  <path
+     style="fill:#faab66;fill-opacity:1;fill-rule:evenodd;stroke:none"
+     d="m 499.46263,323.17222 c 0,0 -6.82155,-8.16565 -7.44109,-8.71104 -2.35882,-2.07652 -3.49865,-1.1479 -8.00785,2.33611 -2.38869,1.84561 -1.16333,3.12992 -1.16333,3.12992 0,0 6.97742,10.12127 8.35206,10.34616 1.22438,0.20031 6.1161,-4.12373 6.95693,-4.85849 1.43636,-1.25519 1.30328,-2.24266 1.30328,-2.24266 z"
+     id="path3209"
+     sodipodi:nodetypes="csscssc" />
+  <path
+     style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none"
+     d="m 399.72127,346.37536 c 0.30246,-1.5732 -9.69801,-6.49532 -9.69801,-6.49532 0,0 -13.17637,16.5185 -13.17637,16.5185 l 4.60732,3.23252 c 0,0 4.20018,3.54936 5.25207,2.56285 1.79694,-1.68523 12.63534,-13.84377 13.01499,-15.81855 z"
+     id="path3223"
+     sodipodi:nodetypes="ccccss" />
+  <path
+     sodipodi:nodetypes="ccccss"
+     id="path3225"
+     d="m 408.42921,360.39904 c 0.26409,-1.25413 -8.26055,-6.62911 -8.26055,-6.62911 -2.73905,1.7119 -12.71136,13.35206 -11.09039,12.33895 l 4.64484,4.02807 c 0,0 3.25278,3.03679 4.17125,2.25037 1.569,-1.34343 10.20336,-10.41403 10.53485,-11.98828 z"
+     style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none" />
+  <text
+     xml:space="preserve"
+     style="font-size:5.19999981px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;fill:#ffffff;fill-opacity:1;stroke:none;font-family:Goblin;-inkscape-font-specification:Goblin"
+     x="16.636446"
+     y="-520.85742"
+     id="text3227"
+     transform="matrix(-0.6328411,0.7742817,-0.7742817,-0.6328411,0,0)"
+     inkscape:transform-center-x="160.30374"
+     inkscape:transform-center-y="104.4831"><tspan
+       sodipodi:role="line"
+       id="tspan3229"
+       x="16.636446"
+       y="-520.85742">PICK</tspan></text>
+  <text
+     inkscape:transform-center-y="100.81871"
+     inkscape:transform-center-x="143.0233"
+     transform="matrix(-0.6612382,0.7410299,-0.8090256,-0.6056635,0,0)"
+     id="text3231"
+     y="-533.45447"
+     x="43.743084"
+     style="font-size:4.69999981px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;fill:#ffffff;fill-opacity:1;stroke:none;font-family:Goblin;-inkscape-font-specification:Goblin"
+     xml:space="preserve"><tspan
+       y="-533.45447"
+       x="43.743084"
+       id="tspan3233"
+       sodipodi:role="line"
+       style="font-size:4.69999981px">PICK</tspan></text>
+  <text
+     xml:space="preserve"
+     style="font-size:22px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:center;text-anchor:start;opacity:0.95;fill:#ffffff;fill-opacity:0.95;fill-rule:nonzero;stroke:#000000;stroke-width:0.89999998;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;font-family:Goblin;-inkscape-font-specification:Goblin"
+     x="548.48071"
+     y="373.84677"
+     id="text3235"><tspan
+       sodipodi:role="line"
+       x="548.48071"
+       y="373.84677"
+       id="tspan3239"
+       style="font-size:22px;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:0.89999998;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none">Guitar</tspan></text>
+  <path
+     style="fill:none;stroke:#000000;stroke-width:1.98199999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+     d="m 553.04176,309.95795 8.49977,38.14534"
+     id="path3259" />
+  <text
+     xml:space="preserve"
+     style="font-size:48.68118668px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;text-align:center;text-anchor:middle;fill:#ffffff;fill-opacity:1;stroke:#000000;stroke-width:1.01400006;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;font-family:Goblin;-inkscape-font-specification:Goblin Bold"
+     x="551.75928"
+     y="155.65428"
+     id="text3263"
+     transform="scale(0.89213371,1.1209082)"><tspan
+       sodipodi:role="line"
+       id="tspan3265"
+       x="551.75928"
+       y="155.65428"
+       style="text-align:center;text-anchor:middle;stroke-width:1.01400006;stroke-miterlimit:4;stroke-dasharray:none">PICK UP YOUR</tspan><tspan
+       sodipodi:role="line"
+       x="551.75928"
+       y="216.50577"
+       id="tspan3267"
+       style="text-align:center;text-anchor:middle;stroke-width:1.01400006;stroke-miterlimit:4;stroke-dasharray:none">INSTRUMENTS</tspan></text>
+  <text
+     xml:space="preserve"
+     style="font-size:40px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;font-family:Goblin"
+     x="370.25256"
+     y="559.18805"
+     id="text2867"><tspan
+       sodipodi:role="line"
+       id="tspan2869"
+       x="370.25256"
+       y="559.18805" /></text>
+  <path
+     style="fill:#ff40a9;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:3;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+     d="m 360.74551,386.80657 c -1.19397,-0.89713 -2.54012,-1.74835 -2.99146,-1.8916 -1.08508,-0.34439 -1.03628,-1.15017 0.15341,-2.53328 l 0.97403,-1.13238 2.64981,1.36391 c 2.83946,1.46152 4.51349,2.77696 4.51349,3.54665 0,0.66336 -1.78807,2.27784 -2.52275,2.27784 -0.33313,0 -1.58256,-0.73401 -2.77653,-1.63114 z"
+     id="path2875" />
+  <path
+     style="fill:#ff40a9;fill-opacity:1;fill-rule:nonzero;stroke:none"
+     d="m 370.62087,395.43097 c -3.22309,-2.56854 -3.81154,-3.60509 -2.86593,-5.04826 0.35169,-0.53675 0.81425,-0.97591 1.02792,-0.97591 0.21367,0 1.38962,0.81543 2.61322,1.81207 1.2236,0.99664 2.67521,2.04957 3.2258,2.33984 0.55059,0.29028 1.12724,0.72182 1.28145,0.95898 0.54105,0.83211 -1.17766,3.17217 -2.32987,3.17217 -0.0649,0 -1.3936,-1.0165 -2.95259,-2.25889 l 0,0 z"
+     id="path3649" />
+  <path
+     style="fill:#ff40a9;fill-opacity:1;fill-rule:nonzero;stroke:none"
+     d="m 380.38571,404.40249 c -3.20987,-2.76047 -3.42843,-3.08387 -2.94444,-4.35688 0.51822,-1.36302 1.52694,-2.12334 2.26217,-1.70511 0.9779,0.55627 6.06626,5.48681 6.06626,5.87812 0,0.61088 -1.68951,2.54236 -2.20437,2.52008 -0.26819,-0.0116 -1.69902,-1.0629 -3.17962,-2.33621 z"
+     id="path3651" />
+  <path
+     style="fill:#ff40a9;fill-opacity:1;fill-rule:nonzero;stroke:none"
+     d="m 378.48847,410.78489 c -2.10831,-1.23484 -5.55751,-4.64178 -5.55751,-5.48942 0,-0.80629 1.13781,-2.26304 1.76757,-2.26304 0.13905,0 1.07806,0.69888 2.0867,1.55307 1.00863,0.85419 2.41773,1.87055 3.13133,2.25858 1.55065,0.84318 1.6684,1.93823 0.36561,3.40003 -0.80453,0.90273 -1.04959,0.97661 -1.7937,0.54078 l 0,0 z"
+     id="path3653" />
+  <path
+     style="fill:#ff40a9;fill-opacity:1;fill-rule:nonzero;stroke:none"
+     d="m 372.51681,412.71693 c -1.02503,-0.78856 -2.40471,-1.8514 -3.06595,-2.36186 -1.04524,-0.80689 -1.13995,-1.04452 -0.72521,-1.81948 0.9497,-1.77453 1.90248,-1.56269 5.22082,1.16084 1.71931,1.41112 3.12602,2.69654 3.12602,2.85648 0,0.50756 -1.49118,1.66292 -2.10338,1.6297 -0.32374,-0.0176 -1.42727,-0.67712 -2.4523,-1.46568 z"
+     id="path3655" />
+  <path
+     style="fill:#ff40a9;fill-opacity:1;fill-rule:nonzero;stroke:none"
+     d="m 367.3399,400.29561 c -0.68335,-0.57774 -1.94134,-1.50522 -2.79553,-2.06107 -0.95393,-0.62075 -1.55308,-1.33544 -1.55308,-1.85257 0,-1.04923 1.91518,-3.02338 2.65692,-2.73874 0.30213,0.11593 1.78479,1.19549 3.29481,2.399 2.92038,2.32761 3.37578,3.39234 1.9881,4.64817 -1.05341,0.95332 -2.13763,0.83413 -3.59122,-0.39479 z"
+     id="path3657" />
+  <path
+     style="fill:#ff40a9;fill-opacity:1;fill-rule:nonzero;stroke:none"
+     d="m 361.99013,403.57514 c -1.49942,-1.29601 -2.72621,-2.59019 -2.72621,-2.87598 0,-0.28579 0.41933,-0.999 0.93184,-1.58492 l 0.93185,-1.0653 1.24245,0.83189 c 3.28091,2.19676 4.98041,3.66556 5.08966,4.39878 0.13461,0.90344 -1.29776,2.65189 -2.17251,2.65189 -0.31398,0 -1.79767,-1.06036 -3.29708,-2.35636 z"
+     id="path3659" />
+  <path
+     style="fill:#ff40a9;fill-opacity:1;fill-rule:nonzero;stroke:none"
+     d="m 359.02616,392.79149 c -5.76907,-3.32651 -6.087,-3.59781 -5.71355,-4.87564 0.57014,-1.9509 1.14184,-2.01574 3.6465,-0.41353 1.30097,0.83222 2.91087,1.70328 3.57756,1.93569 1.42124,0.49544 1.62273,1.82003 0.4874,3.20406 -0.70702,0.86189 -0.75595,0.86555 -1.99791,0.14942 l 0,0 z"
+     id="path3661" />
+  <path
+     style="fill:#ff40a9;fill-opacity:1;fill-rule:nonzero;stroke:none"
+     d="m 353.67286,396.39555 c -1.13892,-0.88756 -2.51443,-1.95668 -3.05669,-2.37582 -1.14288,-0.8834 -0.94747,-2.29548 0.41885,-3.02671 0.69226,-0.37049 1.3598,-0.0858 4.11348,1.75422 1.80791,1.20806 3.28711,2.48402 3.28711,2.83546 0,0.99051 -1.21099,2.48288 -1.99071,2.45325 -0.3857,-0.0147 -1.63312,-0.75284 -2.77204,-1.6404 z"
+     id="path3663" />
+  <path
+     style="fill:#ff40a9;fill-opacity:1;fill-rule:nonzero;stroke:none"
+     d="m 360.12694,366.73155 c -0.9816,-0.52048 -2.1175,-1.40631 -3.47163,-2.70734 -1.38142,-1.32726 -1.53551,-1.79814 -0.9278,-2.83513 0.44544,-0.76007 0.80927,-1.86128 0.81159,-2.45641 0.003,-0.71239 1.00881,-0.8234 1.75842,-0.19403 0.12095,0.10155 0.54937,0.30354 0.95203,0.44887 0.86793,0.31326 2.64584,1.35 4.72801,2.75703 l 1.50664,1.01812 -0.85332,0.89702 c -0.46933,0.49335 -1.33562,1.47356 -1.92508,2.17823 -1.22451,1.46382 -1.39325,1.52229 -2.57886,0.89364 z"
+     id="path3687" />
+  <path
+     style="fill:#ff40a9;fill-opacity:1;fill-rule:nonzero;stroke:none"
+     d="m 355.4425,370.31734 c -1.36907,-0.95524 -2.75279,-1.86401 -3.07493,-2.01948 -0.32213,-0.15547 -0.70921,-0.41947 -0.86018,-0.58667 -0.2708,-0.29993 -0.26334,-0.32367 0.55691,-1.77235 0.93375,-1.64914 1.25184,-1.86666 2.05215,-1.40335 0.24612,0.14249 1.13936,0.55408 1.98496,0.91465 1.90586,0.81266 4.07231,1.99429 4.68885,2.55742 0.56732,0.51816 0.51857,0.89655 -0.24207,1.87901 -0.60528,0.78178 -2.19575,2.20245 -2.44277,2.18197 -0.0955,-0.008 -1.29384,-0.79596 -2.66292,-1.7512 z"
+     id="path3689" />
+  <path
+     style="fill:#ff40a9;fill-opacity:1;fill-rule:nonzero;stroke:none"
+     d="m 366.7167,360.77495 c -0.855,-0.67758 -4.36154,-2.85332 -5.63683,-3.49754 -1.25696,-0.63497 -1.46425,-0.85418 -1.46425,-1.54846 0,-0.74305 1.08272,-2.73437 1.69122,-3.11044 0.26952,-0.16657 0.52806,-0.42268 0.57454,-0.56912 0.0465,-0.14645 0.20971,-0.37957 0.36272,-0.51805 0.26547,-0.24024 0.32735,-0.22328 1.3507,0.37007 1.34197,0.77809 6.97402,4.51025 7.0904,4.69856 0.11054,0.17885 -1.43763,3.30003 -1.87841,3.78695 -0.45545,0.50313 -1.01027,0.87754 -1.28019,0.86391 -0.12302,-0.006 -0.48747,-0.22035 -0.8099,-0.47588 l 0,0 z"
+     id="path3691" />
+  <path
+     style="fill:#ff40a9;fill-opacity:1;fill-rule:nonzero;stroke:none"
+     d="m 373.81885,376.09213 c -0.52347,-0.37473 -2.36842,-1.63241 -4.0999,-2.79486 -1.73148,-1.16244 -3.17144,-2.13438 -3.19991,-2.15986 -0.10299,-0.0922 1.21689,-2.41943 1.54918,-2.73161 l 0.34076,-0.32012 1.83388,0.92535 c 2.15593,1.08785 5.34347,3.06246 6.3675,3.94454 0.71332,0.61444 0.71946,0.62707 0.50562,1.04058 -0.36546,0.70672 -1.9907,2.78733 -2.17325,2.78217 -0.0947,-0.003 -0.60041,-0.31146 -1.12388,-0.68619 z"
+     id="path3693" />
+  <path
+     style="fill:none;stroke:#000000;stroke-width:1.98199999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+     d="m 306.06196,335.46267 c 1.80316,6.1993 66.96622,37.16213 66.96622,37.16213"
+     id="path3253-1"
+     inkscape:connector-curvature="0"
+     sodipodi:nodetypes="cc" />
+  <text
+     xml:space="preserve"
+     style="font-size:22px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;opacity:0.95;fill:#ffffff;fill-opacity:0.95;fill-rule:nonzero;stroke:#000000;stroke-width:0.89999998;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;font-family:Goblin;-inkscape-font-specification:Goblin"
+     x="233.86311"
+     y="327.96237"
+     id="text3241-7"><tspan
+       sodipodi:role="line"
+       x="233.86311"
+       y="327.96237"
+       id="tspan3245-0"
+       style="font-size:22px;fill-rule:nonzero;stroke-width:0.89999998;stroke-miterlimit:4;stroke-dasharray:none">Dance</tspan></text>
+  <text
+     xml:space="preserve"
+     style="font-size:48.68118668px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;text-align:center;text-anchor:middle;fill:#ffffff;fill-opacity:1;stroke:#000000;stroke-width:1.01400006;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;font-family:Goblin;-inkscape-font-specification:Goblin Bold"
+     x="552.28552"
+     y="495.83029"
+     id="text2891"
+     transform="scale(0.89213371,1.1209082)"><tspan
+       id="tspan2897"
+       sodipodi:role="line"
+       x="552.28552"
+       y="495.83029"
+       style="text-align:center;text-anchor:middle;stroke-width:1.01400006;stroke-miterlimit:4;stroke-dasharray:none">TO JOIN THE GAME</tspan></text>
+  <text
+     id="text3063"
+     y="277.46237"
+     x="252.86311"
+     style="font-size:22px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;opacity:0.95;fill:#ffffff;fill-opacity:0.95;fill-rule:nonzero;stroke:#000000;stroke-width:0.89999998;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;font-family:Goblin;-inkscape-font-specification:Goblin"
+     xml:space="preserve"><tspan
+       style="font-size:22px;fill-rule:nonzero;stroke-width:0.89999998;stroke-miterlimit:4;stroke-dasharray:none"
+       id="tspan3065"
+       y="277.46237"
+       x="252.86311"
+       sodipodi:role="line">Drums</tspan></text>
+  <path
+     id="path3067"
+     d="m 355.56196,282.46267 c 17.30316,4.1993 65.46622,-4.33787 65.46622,-4.33787"
+     style="fill:none;stroke:#000000;stroke-width:1.98199999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+     inkscape:connector-curvature="0"
+     sodipodi:nodetypes="cc" />
+  <text
+     xml:space="preserve"
+     style="font-size:12px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
+     x="497"
+     y="419.5"
+     id="text3079"
+     sodipodi:linespacing="125%"><tspan
+       sodipodi:role="line"
+       id="tspan3081"
+       x="497"
+       y="419.5" /></text>
+</svg>
diff --git a/data/themes/default/instrumentmenu_back_highlight.svg b/data/themes/default/instrumentmenu_back_highlight.svg
new file mode 100644 (file)
index 0000000..4c70e6f
--- /dev/null
@@ -0,0 +1,272 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Sodipodi ("http://www.sodipodi.com/") -->
+
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://creativecommons.org/ns#"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:xlink="http://www.w3.org/1999/xlink"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   version="1.0"
+   x="0"
+   y="0"
+   width="400"
+   height="80"
+   id="svg559"
+   sodipodi:version="0.32"
+   inkscape:version="0.47pre4 r22446"
+   sodipodi:docname="menu_back_highlight.svg"
+   inkscape:output_extension="org.inkscape.output.svg.inkscape">
+  <metadata
+     id="metadata35">
+    <rdf:RDF>
+      <cc:Work
+         rdf:about="">
+        <dc:format>image/svg+xml</dc:format>
+        <dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+        <dc:title />
+      </cc:Work>
+    </rdf:RDF>
+  </metadata>
+  <sodipodi:namedview
+     inkscape:window-height="726"
+     inkscape:window-width="1280"
+     inkscape:pageshadow="2"
+     inkscape:pageopacity="0.0"
+     guidetolerance="10.0"
+     gridtolerance="10.0"
+     objecttolerance="10.0"
+     borderopacity="1.0"
+     bordercolor="#666666"
+     pagecolor="#ffffff"
+     id="base"
+     inkscape:zoom="1.2304507"
+     inkscape:cx="114.89549"
+     inkscape:cy="35.400925"
+     inkscape:window-x="0"
+     inkscape:window-y="25"
+     inkscape:current-layer="svg559"
+     showgrid="false"
+     showguides="true"
+     inkscape:guide-bbox="true"
+     inkscape:window-maximized="1" />
+  <defs
+     id="defs561">
+    <linearGradient
+       id="linearGradient4557">
+      <stop
+         style="stop-color:#ffffff;stop-opacity:1;"
+         offset="0"
+         id="stop4559" />
+      <stop
+         style="stop-color:#0300da;stop-opacity:1;"
+         offset="1"
+         id="stop4561" />
+    </linearGradient>
+    <linearGradient
+       id="linearGradient3945">
+      <stop
+         style="stop-color:#ffffff;stop-opacity:1;"
+         offset="0"
+         id="stop3947" />
+      <stop
+         style="stop-color:#ffffff;stop-opacity:0;"
+         offset="1"
+         id="stop3949" />
+    </linearGradient>
+    <inkscape:perspective
+       sodipodi:type="inkscape:persp3d"
+       inkscape:vp_x="0 : 400 : 1"
+       inkscape:vp_y="0 : 1000 : 0"
+       inkscape:vp_z="1000 : 400 : 1"
+       inkscape:persp3d-origin="500 : 266.66667 : 1"
+       id="perspective62" />
+    <linearGradient
+       id="linearGradient6053">
+      <stop
+         style="stop-color:#000000;stop-opacity:1;"
+         offset="0"
+         id="stop6055" />
+      <stop
+         style="stop-color:#5f5f5f;stop-opacity:1;"
+         offset="1"
+         id="stop6057" />
+    </linearGradient>
+    <linearGradient
+       id="linearGradient6499"
+       inkscape:collect="always">
+      <stop
+         id="stop6501"
+         offset="0"
+         style="stop-color:white;stop-opacity:1;" />
+      <stop
+         id="stop6503"
+         offset="1"
+         style="stop-color:white;stop-opacity:0;" />
+    </linearGradient>
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient6499"
+       id="linearGradient3245"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(0.8327515,0,0,-0.6476426,-48.09403,12.672202)"
+       x1="311.95688"
+       y1="-116.67703"
+       x2="311.95688"
+       y2="-276.41519" />
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient6499"
+       id="linearGradient4108"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(1.3544445,0,0,1.7332213,31.621862,51.58815)"
+       x1="44.868057"
+       y1="260.4765"
+       x2="358.07056"
+       y2="260.4765" />
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient6499"
+       id="linearGradient4121"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(1.2483528,0,0,1.0242885,40.754503,133.62899)"
+       x1="44.868057"
+       y1="260.4765"
+       x2="358.07056"
+       y2="260.4765" />
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient6499"
+       id="linearGradient4127"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(1.2483528,0,0,1.0242885,40.754503,340.11416)"
+       x1="44.868057"
+       y1="260.4765"
+       x2="358.07056"
+       y2="260.4765" />
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient6499"
+       id="linearGradient4133"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(1.2483528,0,0,1.0242885,39.887975,233.1463)"
+       x1="44.868057"
+       y1="260.4765"
+       x2="358.07056"
+       y2="260.4765" />
+    <inkscape:perspective
+       id="perspective2871"
+       inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
+       inkscape:vp_z="1 : 0.5 : 1"
+       inkscape:vp_y="0 : 1000 : 0"
+       inkscape:vp_x="0 : 0.5 : 1"
+       sodipodi:type="inkscape:persp3d" />
+    <linearGradient
+       id="linearGradient3751">
+      <stop
+         id="stop3753"
+         offset="0"
+         style="stop-color:black;stop-opacity:1;" />
+      <stop
+         id="stop3755"
+         offset="1"
+         style="stop-color:black;stop-opacity:0;" />
+    </linearGradient>
+    <inkscape:perspective
+       id="perspective2871-4"
+       inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
+       inkscape:vp_z="1 : 0.5 : 1"
+       inkscape:vp_y="0 : 1000 : 0"
+       inkscape:vp_x="0 : 0.5 : 1"
+       sodipodi:type="inkscape:persp3d" />
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient6499-1"
+       id="linearGradient4108-1"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(1.3544445,0,0,1.7332213,31.621862,-148.41185)"
+       x1="44.868057"
+       y1="260.4765"
+       x2="358.07056"
+       y2="260.4765" />
+    <linearGradient
+       id="linearGradient6499-1">
+      <stop
+         id="stop6501-3"
+         offset="0"
+         style="stop-color:#000000;stop-opacity:1;" />
+      <stop
+         id="stop6503-0"
+         offset="1"
+         style="stop-color:white;stop-opacity:0;" />
+    </linearGradient>
+    <inkscape:perspective
+       id="perspective2849"
+       inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
+       inkscape:vp_z="1 : 0.5 : 1"
+       inkscape:vp_y="0 : 1000 : 0"
+       inkscape:vp_x="0 : 0.5 : 1"
+       sodipodi:type="inkscape:persp3d" />
+    <inkscape:perspective
+       id="perspective2854"
+       inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
+       inkscape:vp_z="1 : 0.5 : 1"
+       inkscape:vp_y="0 : 1000 : 0"
+       inkscape:vp_x="0 : 0.5 : 1"
+       sodipodi:type="inkscape:persp3d" />
+    <linearGradient
+       y2="260.4765"
+       x2="358.07056"
+       y1="260.4765"
+       x1="44.868057"
+       gradientTransform="matrix(1.3544445,0,0,1.8513768,-45.940851,-180.28458)"
+       gradientUnits="userSpaceOnUse"
+       id="linearGradient2880"
+       xlink:href="#linearGradient6499-1-4"
+       inkscape:collect="always" />
+    <linearGradient
+       id="linearGradient6499-1-4">
+      <stop
+         id="stop6501-3-4"
+         offset="0"
+         style="stop-color:#a5dbea;stop-opacity:1;" />
+      <stop
+         id="stop6503-0-4"
+         offset="1"
+         style="stop-color:white;stop-opacity:0;" />
+    </linearGradient>
+    <linearGradient
+       y2="260.4765"
+       x2="358.07056"
+       y1="260.4765"
+       x1="44.868057"
+       gradientTransform="matrix(1.5954958,0,0,1.7716569,-170.6897,-421.47588)"
+       gradientUnits="userSpaceOnUse"
+       id="linearGradient2863"
+       xlink:href="#linearGradient6499-1-4"
+       inkscape:collect="always" />
+  </defs>
+  <text
+     xml:space="preserve"
+     style="font-size:24.89476013px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;font-family:Goblin"
+     x="266.96185"
+     y="39.888062"
+     id="text2508"><tspan
+       sodipodi:role="line"
+       id="tspan2510"
+       x="266.96185"
+       y="39.888062" /></text>
+  <rect
+     y="1.2243493"
+     x="1.2243469"
+     height="77.551308"
+     width="397.5513"
+     id="rect6405"
+     style="fill:url(#linearGradient2863);fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:2.44869375;stroke-opacity:1;marker:none;visibility:visible;display:inline;overflow:visible"
+     rx="17.669563"
+     ry="14.354104" />
+</svg>
diff --git a/data/themes/default/instrumentmenu_bg.svg b/data/themes/default/instrumentmenu_bg.svg
new file mode 100644 (file)
index 0000000..3c1650f
--- /dev/null
@@ -0,0 +1,134 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://creativecommons.org/ns#"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:xlink="http://www.w3.org/1999/xlink"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   width="658.31732"
+   height="378.5"
+   id="svg2"
+   sodipodi:version="0.32"
+   inkscape:version="0.48.3.1 r9886"
+   version="1.0"
+   sodipodi:docname="instrumentmenu_bg.svg"
+   inkscape:output_extension="org.inkscape.output.svg.inkscape">
+  <defs
+     id="defs4">
+    <linearGradient
+       id="linearGradient3897">
+      <stop
+         id="stop3899"
+         offset="0"
+         style="stop-color:#ffffff;stop-opacity:0.88554215;" />
+      <stop
+         style="stop-color:#b0b0b0;stop-opacity:0.78313255;"
+         offset="0.30000001"
+         id="stop3903" />
+      <stop
+         id="stop3901"
+         offset="1"
+         style="stop-color:#0e0f11;stop-opacity:0.83734941;" />
+    </linearGradient>
+    <linearGradient
+       id="linearGradient3879">
+      <stop
+         style="stop-color:#000000;stop-opacity:1;"
+         offset="0"
+         id="stop3881" />
+      <stop
+         style="stop-color:#000000;stop-opacity:0;"
+         offset="1"
+         id="stop3883" />
+    </linearGradient>
+    <inkscape:perspective
+       sodipodi:type="inkscape:persp3d"
+       inkscape:vp_x="0 : 526.18109 : 1"
+       inkscape:vp_y="0 : 1000 : 0"
+       inkscape:vp_z="744.09448 : 526.18109 : 1"
+       inkscape:persp3d-origin="372.04724 : 350.78739 : 1"
+       id="perspective10" />
+    <inkscape:perspective
+       id="perspective2963"
+       inkscape:persp3d-origin="88 : 58.666667 : 1"
+       inkscape:vp_z="176 : 88 : 1"
+       inkscape:vp_y="0 : 1000 : 0"
+       inkscape:vp_x="0 : 88 : 1"
+       sodipodi:type="inkscape:persp3d" />
+    <radialGradient
+       r="500"
+       fy="757.60583"
+       fx="727.25122"
+       cy="757.60583"
+       cx="727.25122"
+       gradientTransform="matrix(0.43355171,-0.84504566,1.805509,0.92631863,-980.8803,536.04792)"
+       gradientUnits="userSpaceOnUse"
+       id="radialGradient3750"
+       xlink:href="#linearGradient3629-3"
+       inkscape:collect="always" />
+    <linearGradient
+       id="linearGradient3629-3">
+      <stop
+         style="stop-color:#00cbff;stop-opacity:0.8012048;"
+         offset="0"
+         id="stop3631-1" />
+      <stop
+         style="stop-color:#000000;stop-opacity:0.88554215;"
+         offset="1"
+         id="stop3633-4" />
+    </linearGradient>
+  </defs>
+  <sodipodi:namedview
+     id="base"
+     pagecolor="#ffffff"
+     bordercolor="#666666"
+     borderopacity="1.0"
+     inkscape:pageopacity="0.0"
+     inkscape:pageshadow="2"
+     inkscape:zoom="0.49497475"
+     inkscape:cx="-77.406281"
+     inkscape:cy="220.56135"
+     inkscape:document-units="px"
+     inkscape:current-layer="layer1"
+     showgrid="false"
+     inkscape:window-width="1920"
+     inkscape:window-height="1053"
+     inkscape:window-x="0"
+     inkscape:window-y="-1"
+     inkscape:window-maximized="1"
+     fit-margin-top="0"
+     fit-margin-left="0"
+     fit-margin-right="0"
+     fit-margin-bottom="0" />
+  <metadata
+     id="metadata7">
+    <rdf:RDF>
+      <cc:Work
+         rdf:about="">
+        <dc:format>image/svg+xml</dc:format>
+        <dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+      </cc:Work>
+    </rdf:RDF>
+  </metadata>
+  <g
+     inkscape:label="Calque 1"
+     inkscape:groupmode="layer"
+     id="layer1"
+     transform="translate(369.06735,69.25)">
+    <rect
+       style="opacity:0.79237288;fill:#000000;fill-opacity:1;stroke:none"
+       id="rect2383"
+       width="658.31732"
+       height="378.5"
+       x="-369.06735"
+       y="-69.25"
+       rx="31.697433"
+       ry="31.697433" />
+  </g>
+</svg>
diff --git a/data/themes/default/instrumentmenu_comment.svg b/data/themes/default/instrumentmenu_comment.svg
new file mode 100644 (file)
index 0000000..bbc7948
--- /dev/null
@@ -0,0 +1,76 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Sodipodi ("http://www.sodipodi.com/") -->
+
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://creativecommons.org/ns#"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   version="1.0"
+   x="0"
+   y="0"
+   width="140"
+   height="40"
+   id="svg559"
+   sodipodi:version="0.32"
+   inkscape:version="0.47 r22583"
+   sodipodi:docname="instrumentmenu_comment.svg"
+   inkscape:output_extension="org.inkscape.output.svg.inkscape">
+  <defs
+     id="defs2522">
+    <inkscape:perspective
+       sodipodi:type="inkscape:persp3d"
+       inkscape:vp_x="0 : 300 : 1"
+       inkscape:vp_y="0 : 1000 : 0"
+       inkscape:vp_z="800 : 300 : 1"
+       inkscape:persp3d-origin="400 : 200 : 1"
+       id="perspective8" />
+  </defs>
+  <metadata
+     id="metadata35">
+    <rdf:RDF>
+      <cc:Work
+         rdf:about="">
+        <dc:format>image/svg+xml</dc:format>
+        <dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+        <dc:title />
+      </cc:Work>
+    </rdf:RDF>
+  </metadata>
+  <sodipodi:namedview
+     inkscape:window-height="852"
+     inkscape:window-width="1440"
+     inkscape:pageshadow="2"
+     inkscape:pageopacity="0.0"
+     guidetolerance="10.0"
+     gridtolerance="10.0"
+     objecttolerance="10.0"
+     borderopacity="1.0"
+     bordercolor="#666666"
+     pagecolor="#ffffff"
+     id="base"
+     inkscape:zoom="3.5638182"
+     inkscape:cx="63.312761"
+     inkscape:cy="28.101518"
+     inkscape:window-x="0"
+     inkscape:window-y="0"
+     inkscape:current-layer="svg559"
+     showgrid="false"
+     inkscape:window-maximized="1" />
+  <text
+     x="12.682061"
+     y="30.636002"
+     style="font-size:28.45248412999999843px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;text-align:start;line-height:125%;writing-mode:lr-tb;text-anchor:start;fill:#808080;fill-opacity:1;stroke:#000000;stroke-width:0.96595233999999996;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;display:inline;font-family:Goblin"
+     id="text10203"
+     xml:space="preserve"
+     sodipodi:linespacing="125%"
+     transform="scale(1.0377692,0.9636054)"><tspan
+       x="12.682061"
+       y="30.636002"
+       id="tspan10205"
+       style="font-size:28.45248412999999843px;text-align:start;text-anchor:start;fill:#808080;fill-opacity:1;stroke-width:0.96595233999999996">Cmmnt</tspan></text>
+</svg>
diff --git a/data/themes/default/instrumentmenu_option.svg b/data/themes/default/instrumentmenu_option.svg
new file mode 100644 (file)
index 0000000..12035b9
--- /dev/null
@@ -0,0 +1,76 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Sodipodi ("http://www.sodipodi.com/") -->
+
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://creativecommons.org/ns#"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   version="1.0"
+   x="0"
+   y="0"
+   width="140"
+   height="40"
+   id="svg559"
+   sodipodi:version="0.32"
+   inkscape:version="0.48.3.1 r9886"
+   sodipodi:docname="instrumentmenu_option.svg"
+   inkscape:output_extension="org.inkscape.output.svg.inkscape">
+  <defs
+     id="defs2522">
+    <inkscape:perspective
+       sodipodi:type="inkscape:persp3d"
+       inkscape:vp_x="0 : 300 : 1"
+       inkscape:vp_y="0 : 1000 : 0"
+       inkscape:vp_z="800 : 300 : 1"
+       inkscape:persp3d-origin="400 : 200 : 1"
+       id="perspective8" />
+  </defs>
+  <metadata
+     id="metadata35">
+    <rdf:RDF>
+      <cc:Work
+         rdf:about="">
+        <dc:format>image/svg+xml</dc:format>
+        <dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+        <dc:title />
+      </cc:Work>
+    </rdf:RDF>
+  </metadata>
+  <sodipodi:namedview
+     inkscape:window-height="1053"
+     inkscape:window-width="1920"
+     inkscape:pageshadow="2"
+     inkscape:pageopacity="0.0"
+     guidetolerance="10.0"
+     gridtolerance="10.0"
+     objecttolerance="10.0"
+     borderopacity="1.0"
+     bordercolor="#666666"
+     pagecolor="#ffffff"
+     id="base"
+     inkscape:zoom="3.5638182"
+     inkscape:cx="14.909619"
+     inkscape:cy="28.662714"
+     inkscape:window-x="0"
+     inkscape:window-y="-1"
+     inkscape:current-layer="svg559"
+     showgrid="false"
+     inkscape:window-maximized="1" />
+  <text
+     x="0.42621329"
+     y="30.720901"
+     style="font-size:31.99999989px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;text-align:start;line-height:125%;writing-mode:lr-tb;text-anchor:start;fill:#add3f1;fill-opacity:1;stroke:#000000;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;display:inline;font-family:Goblin"
+     id="text10203"
+     xml:space="preserve"
+     sodipodi:linespacing="125%"
+     transform="scale(1.0082228,0.99184427)"><tspan
+       x="0.42621329"
+       y="30.720901"
+       id="tspan10205"
+       style="font-size:31.99999989px;text-align:start;text-anchor:start;fill:#add3f1;fill-opacity:1;stroke-width:1;stroke:#000000;stroke-opacity:1;stroke-miterlimit:4;stroke-dasharray:none">option</tspan></text>
+</svg>
diff --git a/data/themes/default/instrumentmenu_option_selected.svg b/data/themes/default/instrumentmenu_option_selected.svg
new file mode 100644 (file)
index 0000000..8cbb31b
--- /dev/null
@@ -0,0 +1,76 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Sodipodi ("http://www.sodipodi.com/") -->
+
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://creativecommons.org/ns#"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   version="1.0"
+   x="0"
+   y="0"
+   width="140"
+   height="40"
+   id="svg559"
+   sodipodi:version="0.32"
+   inkscape:version="0.48.3.1 r9886"
+   sodipodi:docname="instrumentmenu_option_selected.svg"
+   inkscape:output_extension="org.inkscape.output.svg.inkscape">
+  <defs
+     id="defs2522">
+    <inkscape:perspective
+       sodipodi:type="inkscape:persp3d"
+       inkscape:vp_x="0 : 300 : 1"
+       inkscape:vp_y="0 : 1000 : 0"
+       inkscape:vp_z="800 : 300 : 1"
+       inkscape:persp3d-origin="400 : 200 : 1"
+       id="perspective8" />
+  </defs>
+  <metadata
+     id="metadata35">
+    <rdf:RDF>
+      <cc:Work
+         rdf:about="">
+        <dc:format>image/svg+xml</dc:format>
+        <dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+        <dc:title />
+      </cc:Work>
+    </rdf:RDF>
+  </metadata>
+  <sodipodi:namedview
+     inkscape:window-height="1053"
+     inkscape:window-width="1920"
+     inkscape:pageshadow="2"
+     inkscape:pageopacity="0.0"
+     guidetolerance="10.0"
+     gridtolerance="10.0"
+     objecttolerance="10.0"
+     borderopacity="1.0"
+     bordercolor="#666666"
+     pagecolor="#ffffff"
+     id="base"
+     inkscape:zoom="3.5638182"
+     inkscape:cx="14.909619"
+     inkscape:cy="28.662714"
+     inkscape:window-x="0"
+     inkscape:window-y="-1"
+     inkscape:current-layer="svg559"
+     showgrid="false"
+     inkscape:window-maximized="1" />
+  <text
+     x="0.42621329"
+     y="30.720901"
+     style="font-size:31.99999989px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;text-align:start;line-height:125%;writing-mode:lr-tb;text-anchor:start;fill:#ffffff;fill-opacity:1;stroke:#000000;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;display:inline;font-family:Goblin"
+     id="text10203"
+     xml:space="preserve"
+     sodipodi:linespacing="125%"
+     transform="scale(1.0082228,0.99184427)"><tspan
+       x="0.42621329"
+       y="30.720901"
+       id="tspan10205"
+       style="font-size:31.99999989px;text-align:start;text-anchor:start;fill:#ffffff;fill-opacity:1;stroke-width:1;stroke:#000000;stroke-opacity:1;stroke-miterlimit:4;stroke-dasharray:none">option</tspan></text>
+</svg>
diff --git a/data/themes/default/instruments.svg b/data/themes/default/instruments.svg
new file mode 100644 (file)
index 0000000..68d5ea0
--- /dev/null
@@ -0,0 +1,211 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://creativecommons.org/ns#"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:xlink="http://www.w3.org/1999/xlink"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   width="512"
+   height="64"
+   id="svg2"
+   sodipodi:version="0.32"
+   inkscape:version="0.48.4 r9939"
+   sodipodi:docname="instruments.svg"
+   inkscape:output_extension="org.inkscape.output.svg.inkscape"
+   version="1.0">
+  <defs
+     id="defs4">
+    <inkscape:path-effect
+       effect="bend_path"
+       id="path-effect2844"
+       is_visible="true"
+       bendpath="m 266.25,32.092577 41.87495,0"
+       prop_scale="1"
+       scale_y_rel="false"
+       vertical="false" />
+    <inkscape:perspective
+       sodipodi:type="inkscape:persp3d"
+       inkscape:vp_x="0 : 128 : 1"
+       inkscape:vp_y="0 : 1000 : 0"
+       inkscape:vp_z="256 : 128 : 1"
+       inkscape:persp3d-origin="128 : 85.333333 : 1"
+       id="perspective17" />
+    <linearGradient
+       id="linearGradient3751"
+       inkscape:collect="always">
+      <stop
+         id="stop3753"
+         offset="0"
+         style="stop-color:black;stop-opacity:1;" />
+      <stop
+         id="stop3755"
+         offset="1"
+         style="stop-color:black;stop-opacity:0;" />
+    </linearGradient>
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient3751"
+       id="linearGradient3484"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(0.336682,0,0,0.336682,-81.3739,-51.8729)"
+       x1="665.12128"
+       y1="684.16162"
+       x2="381.28015"
+       y2="449.80624" />
+    <inkscape:perspective
+       id="perspective2830"
+       inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
+       inkscape:vp_z="1 : 0.5 : 1"
+       inkscape:vp_y="0 : 1000 : 0"
+       inkscape:vp_x="0 : 0.5 : 1"
+       sodipodi:type="inkscape:persp3d" />
+    <inkscape:perspective
+       id="perspective3827"
+       inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
+       inkscape:vp_z="1 : 0.5 : 1"
+       inkscape:vp_y="0 : 1000 : 0"
+       inkscape:vp_x="0 : 0.5 : 1"
+       sodipodi:type="inkscape:persp3d" />
+    <filter
+       id="filter3945"
+       inkscape:label="Drop Shadow"
+       color-interpolation-filters="sRGB">
+      <feFlood
+         id="feFlood3947"
+         flood-opacity="0.80000000000000004"
+         flood-color="rgb(0,8,255)"
+         result="flood" />
+      <feComposite
+         id="feComposite3949"
+         in2="SourceGraphic"
+         in="flood"
+         operator="in"
+         result="composite1" />
+      <feGaussianBlur
+         id="feGaussianBlur3951"
+         stdDeviation="5"
+         result="blur" />
+      <feOffset
+         id="feOffset3953"
+         dx="0"
+         dy="0"
+         result="offset" />
+      <feComposite
+         id="feComposite3955"
+         in2="offset"
+         in="SourceGraphic"
+         operator="over"
+         result="composite2" />
+    </filter>
+  </defs>
+  <sodipodi:namedview
+     id="base"
+     pagecolor="#ffffff"
+     bordercolor="#666666"
+     borderopacity="1.0"
+     inkscape:pageopacity="0.0"
+     inkscape:pageshadow="2"
+     inkscape:zoom="2.2382812"
+     inkscape:cx="158.5638"
+     inkscape:cy="3.5322802"
+     inkscape:document-units="px"
+     inkscape:current-layer="layer1"
+     inkscape:window-width="1636"
+     inkscape:window-height="816"
+     inkscape:window-x="127"
+     inkscape:window-y="25"
+     showguides="true"
+     inkscape:guide-bbox="true"
+     width="256px"
+     height="256px"
+     borderlayer="false"
+     showgrid="true"
+     inkscape:window-maximized="0"
+     fit-margin-left="20"
+     fit-margin-right="20"
+     fit-margin-top="0"
+     fit-margin-bottom="0">
+    <inkscape:grid
+       type="xygrid"
+       id="grid3957"
+       empspacing="64"
+       visible="true"
+       enabled="true"
+       snapvisiblegridlinesonly="true" />
+  </sodipodi:namedview>
+  <metadata
+     id="metadata7">
+    <rdf:RDF>
+      <cc:Work
+         rdf:about="">
+        <dc:format>image/svg+xml</dc:format>
+        <dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+      </cc:Work>
+    </rdf:RDF>
+  </metadata>
+  <g
+     inkscape:label="Capa 1"
+     inkscape:groupmode="layer"
+     id="layer1"
+     transform="translate(13.268664,-5.200002)">
+    <path
+       style="fill:#ffffff;fill-opacity:1;stroke:#000000;stroke-width:0.5;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;filter:url(#filter3945)"
+       d="m 226.89253,55.978173 c -2.25125,-0.112256 -4.45812,-0.948323 -6.24728,-2.366752 -0.5588,-0.443016 -1.37196,-1.253176 -1.79256,-1.785958 -1.28127,-1.623021 -2.04989,-3.436475 -2.32256,-5.479857 l -0.0278,-0.207947 -0.23969,0.0071 -0.2397,0.0071 -0.21864,0.665268 -0.21865,0.665268 0.005,0.913719 0.005,0.913727 0.40873,0.10752 c 0.42541,0.111911 0.5774,0.179185 0.618,0.273547 0.0132,0.03066 0.0316,0.170187 0.041,0.31004 l 0.017,0.254274 -0.0665,0.02679 c -0.0366,0.01473 -0.1313,0.02347 -0.21047,0.01942 l -0.14395,-0.0074 -0.0337,-0.141218 c -0.0273,-0.114136 -0.0432,-0.141362 -0.083,-0.142044 -0.0827,-0.0014 -0.81037,-0.199208 -0.90187,-0.245182 -0.0995,-0.04997 -0.15496,-0.147463 -0.15496,-0.272167 0,-0.0482 -0.009,-0.0934 -0.0196,-0.100453 -0.0278,-0.0182 -0.12266,0.01129 -0.12266,0.03812 0,0.01233 -0.34314,1.064442 -0.76255,2.338049 -0.64426,1.956413 -0.76314,2.339006 -0.76635,2.466255 -0.003,0.12581 -0.0339,0.226978 -0.18641,0.613937 -0.22877,0.580465 -0.27247,0.659773 -0.4109,0.745673 -0.19674,0.122081 -0.48664,0.07864 -0.69006,-0.103413 -0.0997,-0.08924 -0.15448,-0.200673 -0.13373,-0.272107 0.0218,-0.07524 0.76296,-1.99256 0.79369,-2.053346 0.0201,-0.03975 0.0332,-0.04356 0.0729,-0.02106 0.0266,0.0151 0.0511,0.02371 0.0544,0.01914 0.003,-0.0046 0.30164,-0.9107 0.66307,-2.013628 l 0.65714,-2.00532 -0.0486,-0.05485 c -0.0268,-0.03017 -0.0486,-0.07869 -0.0486,-0.107829 0,-0.05764 0.16049,-0.553384 0.19428,-0.600144 0.0114,-0.01581 0.0551,-0.03561 0.097,-0.04401 l 0.0762,-0.01524 0.27925,-0.847195 0.27924,-0.847205 -6.6e-4,-0.797063 -6.7e-4,-0.797056 -0.23709,0 -0.23709,0 -0.002,0.194558 c -0.004,0.301145 -0.0121,0.318658 -0.15787,0.327647 -0.11671,0.0072 -0.12367,0.0041 -0.1413,-0.06276 -0.0241,-0.09156 -0.0241,-1.128577 0,-1.220128 0.0176,-0.06686 0.0246,-0.06995 0.1413,-0.06277 0.14577,0.009 0.15422,0.0265 0.15787,0.327646 l 0.002,0.194558 0.23709,0 0.23709,0 0,-1.069851 0,-1.069862 -0.14818,0.01544 c -0.57354,0.05976 -1.00574,0.07622 -2.0271,0.07719 l -1.14395,0.0011 -1e-5,3.137088 0,3.137089 0.0568,0.05115 c 0.0505,0.04551 0.0583,0.07818 0.0705,0.295917 0.0115,0.205429 0.008,0.244776 -0.0212,0.244776 -0.0294,0 -0.0349,0.06618 -0.0349,0.414842 l 0,0.414841 -0.0652,0.02667 c -0.0924,0.03783 -0.5455,0.01699 -0.63422,-0.02918 l -0.0711,-0.037 -0.007,-0.360948 c -0.005,-0.285159 5.1e-4,-0.369437 0.0274,-0.401366 0.0208,-0.02486 0.0401,-0.127448 0.05,-0.266361 0.0193,-0.272054 0.029,-0.313801 0.0731,-0.313801 0.0293,0 0.0339,-0.435702 0.0339,-3.173555 l 0,-3.173537 -0.1719,-0.01421 c -0.7811,-0.06456 -1.39334,-0.119814 -1.45526,-0.131339 l -0.0742,-0.01383 -0.018,1.100547 c -0.01,0.605292 -0.0155,1.812245 -0.0125,2.682105 0.006,1.641067 -0.003,1.922017 -0.0601,1.972347 -0.0214,0.01885 -0.0336,0.07859 -0.0336,0.164596 l 0,0.134997 -0.12447,-3.89e-4 c -0.0685,-2.07e-4 -0.13747,-0.0091 -0.15335,-0.01982 -0.0481,-0.03235 -0.0568,-0.457925 -0.068,-3.337151 l -0.0108,-2.742304 -0.0529,-0.01194 c -0.029,-0.0066 -0.15419,-0.02454 -0.27807,-0.03992 -0.34987,-0.04344 -1.36734,-0.217662 -1.81372,-0.310558 l -0.40307,-0.08388 -0.0784,0.07845 c -0.0749,0.07486 -0.0873,0.07844 -0.27267,0.07797 -0.3727,-9.5e-4 -0.6721,-0.152846 -0.71572,-0.363096 -0.009,-0.04165 -0.0283,-0.07574 -0.0438,-0.07574 -0.0155,0 -0.22533,-0.06337 -0.46637,-0.14081 -0.24105,-0.07746 -0.45693,-0.146557 -0.47976,-0.153563 -0.0393,-0.01206 -0.0415,0.113619 -0.041,2.393926 l 4.7e-4,2.40666 0.93011,1.408293 c 2.91626,4.415576 3.49407,5.280698 3.53135,5.287324 0.0395,0.007 1.05764,1.521385 1.07913,1.605059 0.029,0.113118 -0.12715,0.222388 -0.3173,0.221975 -0.14217,-2.94e-4 -0.32456,-0.08758 -0.42585,-0.20378 -0.1202,-0.137878 -0.53568,-0.779259 -0.57526,-0.888003 -0.0201,-0.05523 -0.55481,-0.885559 -1.18825,-1.845166 -0.63345,-0.959606 -1.57276,-2.382375 -2.08736,-3.16171 l -0.93565,-1.416945 -0.0126,1.165905 c -0.01,0.894551 -0.0199,1.181246 -0.0439,1.231783 -0.0498,0.104629 -0.17602,0.16143 -0.62344,0.28044 -0.363,0.09655 -0.4232,0.106596 -0.4526,0.07549 -0.0294,-0.03112 -0.0379,-0.01568 -0.0644,0.116068 -0.0167,0.08358 -0.0452,0.164906 -0.0632,0.180747 -0.021,0.01847 -0.0886,0.02403 -0.18855,0.01554 l -0.15581,-0.01324 0.0166,0.355022 c 0.01,0.195264 0.0238,0.455042 0.0327,0.577298 0.016,0.221138 0.0158,0.222431 -0.0442,0.249313 -0.0332,0.01487 -0.13845,0.02781 -0.23403,0.02876 -0.13901,0.0014 -0.17984,-0.007 -0.20395,-0.04192 -0.038,-0.0551 -0.0716,-0.565168 -0.0398,-0.60569 0.0149,-0.01894 0.003,-0.293639 -0.0341,-0.781966 -0.0313,-0.414023 -0.0572,-0.78666 -0.0575,-0.828079 l -5.1e-4,-0.07531 -0.17194,0.0088 c -0.21713,0.01109 -0.56417,-0.03793 -0.69778,-0.09857 l -0.10245,-0.0465 -5.7e-4,-0.157789 -5.6e-4,-0.157798 -0.89135,-0.677812 c -0.49024,-0.372802 -0.94758,-0.720205 -1.01633,-0.772011 l -0.125,-0.0942 -1.85682,2.516759 c -1.02125,1.384222 -2.01125,2.725757 -2.19998,2.981188 -0.18874,0.255438 -0.38922,0.517607 -0.4455,0.582603 -0.0628,0.07254 -0.10236,0.14208 -0.10236,0.180082 0,0.06352 -0.0313,0.111815 -0.37,0.570361 -0.2027,0.27448 -0.31785,0.397165 -0.43081,0.459013 -0.0873,0.04776 -0.26813,0.07468 -0.3593,0.05348 -0.0986,-0.02293 -0.21505,-0.129804 -0.21484,-0.197164 1e-4,-0.03218 0.21305,-0.345359 0.52338,-0.769725 0.56633,-0.774427 0.6122,-0.832901 0.63945,-0.81506 0.01,0.0065 1.54472,-2.056591 3.41064,-4.584651 l 3.39255,-4.596478 0,-0.171566 c 0,-0.155693 0.006,-0.176398 0.0628,-0.223898 0.0346,-0.02878 0.10391,-0.05929 0.1541,-0.06779 l 0.0913,-0.01545 -2.7e-4,-2.927709 -2.6e-4,-2.927718 -0.12421,-0.05021 -0.1242,-0.05021 -0.007,-0.561691 c -0.004,-0.360723 0.002,-0.572898 0.0182,-0.593034 0.0135,-0.01724 0.0884,-0.05031 0.16644,-0.07349 l 0.14183,-0.04214 -5.1e-4,-5.314536 -5.2e-4,-5.314526 -0.0765,-0.03766 c -0.0748,-0.0368 -0.0776,-0.04441 -0.1267,-0.333447 -0.0276,-0.162681 -0.0548,-0.30071 -0.0605,-0.306717 -0.006,-0.006 -0.63225,1.078969 -1.3924,2.411069 -0.76014,1.332097 -1.40478,2.43883 -1.43251,2.459407 -0.0865,0.06413 -0.22335,0.04785 -0.30252,-0.03597 -0.14603,-0.154624 -0.21452,-0.01484 1.35338,-2.761776 l 1.42268,-2.492517 -0.0748,-0.09021 c -0.25414,-0.306487 -0.28021,-0.829203 -0.0635,-1.272407 0.18779,-0.383985 0.45767,-0.637063 0.83508,-0.783093 0.0534,-0.02067 0.2031,-0.04498 0.33259,-0.05402 l 0.23543,-0.01643 1.94009,-3.399276 c 1.06706,-1.869605 1.93526,-3.404399 1.92935,-3.41066 -0.006,-0.0063 -0.38211,-0.110679 -0.83599,-0.23204 -2.97441,-0.795303 -5.47418,-1.716945 -7.36887,-2.716814 -1.26096,-0.665449 -2.06354,-1.240104 -2.53024,-1.811678 -0.40786,-0.4995171 -0.48344,-0.9656681 -0.21854,-1.3477781 0.26275,-0.3789816 0.97639,-0.6818844 1.97825,-0.8396545 1.09329,-0.1721616 2.84778,-0.1903931 4.62323,-0.048043 4.5688,0.3663255 10.37056,1.7427037 14.36756,3.4084986 2.53163,1.055084 4.12747,2.104617 4.56238,3.000531 0.30803,0.634541 -0.0373,1.17428 -0.97087,1.517335 -0.44275,0.162694 -1.21113,0.318677 -1.77186,0.359693 -0.12713,0.0093 -0.23116,0.0244 -0.23116,0.03356 0,0.0092 0.056,0.03171 0.12447,0.0501 0.21371,0.05742 1.07854,0.364594 1.48772,0.528421 2.69962,1.080787 4.87527,2.662121 5.17843,3.763838 0.0765,0.278039 0.06,0.372542 -0.18771,1.069301 -0.12388,0.348555 -0.22515,0.643509 -0.22504,0.655456 1.2e-4,0.01194 0.3602,0.163291 0.80018,0.336334 l 0.79996,0.314616 0.008,-0.08836 c 0.01,-0.109752 0.041,-0.151759 0.11375,-0.151759 0.0563,0 0.0564,-2.86e-4 0.0564,-0.310808 l 0,-0.31081 -0.18374,-0.02182 -0.18374,-0.02182 -0.007,-0.11599 c -0.009,-0.148277 -0.0139,-0.146917 0.51684,-0.146917 0.53069,0 0.52591,-0.0014 0.51682,0.146917 l -0.007,0.11599 -0.1963,0.02236 -0.19631,0.02236 0.007,0.303788 0.007,0.303783 0.0711,0.01289 c 0.0652,0.01183 0.0717,0.02213 0.0781,0.125726 0.007,0.110496 0.01,0.113627 0.11856,0.1505 l 0.11151,0.03766 0,0.275807 0,0.275809 -0.0651,0.03309 -0.0651,0.03309 0,0.539163 c 0,0.490531 0.004,0.54063 0.0415,0.555481 0.0228,0.009 0.13216,0.07846 0.243,0.154408 0.46172,0.316348 0.41758,0.297843 0.64774,0.271716 0.12794,-0.01452 0.26313,-0.01406 0.36366,0.0013 0.18175,0.02767 0.16802,0.03376 0.5952,-0.263939 0.12078,-0.08418 0.24082,-0.16018 0.26671,-0.168885 0.0451,-0.01514 0.0471,-0.03906 0.0471,-0.549353 l 0,-0.533518 -0.0771,-0.03591 -0.0771,-0.03591 -0.007,-0.225935 c -0.01,-0.310962 -0.002,-0.3332 0.12603,-0.36946 0.10471,-0.02966 0.10618,-0.03154 0.10618,-0.137113 0,-0.09971 0.005,-0.108497 0.0771,-0.128147 l 0.0771,-0.02111 0.007,-0.302435 0.007,-0.302439 -0.1963,-0.02236 -0.19631,-0.02236 -0.007,-0.115857 c -0.007,-0.112189 -0.005,-0.116362 0.0681,-0.131797 0.0978,-0.02071 0.8233,-0.02071 0.92107,0 0.0728,0.01544 0.0751,0.01961 0.0681,0.131797 l -0.007,0.115857 -0.19562,0.02229 -0.19559,0.02229 0,0.298581 c 0,0.262454 0.005,0.300222 0.0415,0.312154 0.0911,0.02981 0.11311,0.05682 0.12446,0.152802 l 0.0118,0.100092 0.81601,-0.32235 c 0.44883,-0.177291 0.81916,-0.325664 0.82299,-0.329713 0.004,-0.004 -0.12154,-0.36835 -0.27859,-0.809568 -0.26261,-0.737755 -0.28551,-0.81574 -0.28493,-0.970643 9.7e-4,-0.310032 0.17383,-0.646694 0.53638,-1.046033 0.55868,-0.615363 1.34215,-1.186604 2.45421,-1.789417 1.42729,-0.773683 3.26763,-1.429996 4.69437,-1.67412 0.61572,-0.105365 0.74483,-0.116319 1.36324,-0.115698 0.55163,5.55e-4 0.63998,0.0065 0.84048,0.05617 0.2371,0.05879 0.48263,0.167829 0.61056,0.271146 0.10792,0.08717 0.17335,0.217541 0.32614,0.649939 0.111,0.314111 0.14873,0.39258 0.22934,0.476981 0.053,0.05556 0.11053,0.129759 0.12775,0.164894 0.0466,0.0952 0.10013,0.334469 0.13161,0.588469 0.025,0.201471 0.15433,0.581256 1.21042,3.55422 0.93238,2.624586 1.18249,3.353016 1.18249,3.443857 l 0,0.115206 0.41011,0.0083 c 0.45047,0.0092 0.50195,0.02452 0.58201,0.173523 l 0.0392,0.073 0.32476,1.59e-4 0.32477,1.57e-4 0.007,-0.131444 c 0.007,-0.125156 0.0118,-0.134159 0.10452,-0.188183 0.094,-0.05474 0.0979,-0.06217 0.11262,-0.211174 0.0169,-0.171409 0.0374,-0.210155 0.12268,-0.232838 l 0.0581,-0.01543 0.006,-1.260132 0.006,-1.260133 0.0855,-0.02141 c 0.0479,-0.01201 0.12082,-0.01172 0.16596,6.56e-4 l 0.0804,0.02207 0.006,1.256943 0.006,1.256952 0.0702,0.03075 c 0.0777,0.03411 0.0848,0.05107 0.10674,0.255233 0.0133,0.123772 0.0228,0.143998 0.0737,0.157539 0.10122,0.0269 0.15207,0.103007 0.15207,0.227639 l 0,0.11297 0.47347,0 c 2.11693,0 5.20246,0.213168 6.4021,0.442295 0.55827,0.10663 0.92401,0.239582 0.96422,0.350508 0.0251,0.06923 -0.0151,0.150828 -0.0994,0.201831 l -0.0852,0.05156 0.0857,0.06921 c 0.18648,0.150611 0.0586,0.304267 -0.35558,0.427169 -0.68347,0.202832 -2.20579,0.379418 -4.11349,0.477181 -0.93151,0.04773 -2.20625,0.08912 -2.74287,0.08906 l -0.40755,-5.2e-5 -0.008,0.09414 c -0.007,0.08485 -0.019,0.100487 -0.12569,0.158453 l -0.11832,0.06431 -0.0334,0.211839 c -0.0254,0.160885 -0.0355,0.577883 -0.0421,1.73379 l -0.009,1.521946 0.0616,0.04275 c 0.0339,0.0235 0.0819,0.08988 0.10653,0.147479 0.0429,0.100049 0.045,0.197621 0.0455,2.18045 l 5.4e-4,2.075725 0.0987,0.0707 c 0.17061,0.122194 0.19637,0.208007 0.20585,0.685749 0.0105,0.52859 -0.0109,0.639491 -0.15227,0.791379 -0.0721,0.07738 -0.10505,0.134237 -0.10542,0.181556 -7.6e-4,0.101481 -0.0814,0.272167 -0.15159,0.320868 l -0.0612,0.0425 0,2.855027 0,2.855017 0.0945,0.02997 c 0.12137,0.03849 0.14265,0.0847 0.14265,0.309644 l 0,0.184326 1.87586,2.836106 c 1.03171,1.559861 2.34391,3.543656 2.91601,4.408426 0.57207,0.864769 1.0589,1.577607 1.08182,1.584078 0.0614,0.01734 1.02558,1.488307 1.02558,1.564682 0,0.09557 -0.12154,0.16162 -0.29636,0.16106 -0.16924,-5.44e-4 -0.30071,-0.0582 -0.4065,-0.178296 -0.11474,-0.130243 -0.53254,-0.776609 -0.56588,-0.875441 -0.0162,-0.04832 -0.29919,-0.494546 -0.62862,-0.991612 -0.32945,-0.497067 -0.88186,-1.333047 -1.22757,-1.85772 -2.2958,-3.484354 -2.14104,-3.25616 -2.18264,-3.218226 -0.0367,0.03347 -1.00307,0.873353 -1.01777,0.884569 -0.004,0.0029 0.0636,0.07703 0.14987,0.164708 0.0862,0.08769 0.14535,0.163456 0.13139,0.168383 -0.0178,0.0063 -0.0254,0.724674 -0.0254,2.405805 0,1.591514 0.008,2.391641 0.0237,2.381331 0.0131,-0.0085 0.0237,-0.07133 0.0237,-0.139552 0,-0.06822 0.008,-0.123599 0.0178,-0.123056 0.01,5.35e-4 0.10847,0.04854 0.21932,0.106691 0.2318,0.121599 0.27255,0.183153 0.3156,0.476801 0.0206,0.140303 0.019,0.176096 -0.009,0.203522 -0.0186,0.0183 -0.50293,0.148315 -1.07615,0.288938 -0.57319,0.140612 -1.04656,0.260313 -1.05193,0.26598 -0.006,0.0057 0.0288,0.05808 0.0761,0.116458 0.0472,0.05837 0.0858,0.131519 0.0858,0.16255 0,0.08899 -0.10635,0.160482 -0.23874,0.160482 -0.15654,0 -0.21789,-0.02981 -0.36542,-0.177555 l -0.12732,-0.127508 -0.34264,0.08314 c -0.24372,0.05914 -0.3393,0.09231 -0.33112,0.114878 0.007,0.01745 1.7e-4,0.03173 -0.0137,0.03173 -0.0138,0 -0.30041,-0.207136 -0.63674,-0.460297 -1.53716,-1.157028 -2.33747,-1.749795 -2.34774,-1.738933 -0.006,0.0065 9.6e-4,0.05172 0.0165,0.100513 0.0246,0.0789 0.0327,0.0854 0.0729,0.05879 0.0291,-0.01927 0.0526,-0.02121 0.0657,-0.0054 0.0344,0.041 0.81046,2.054961 0.81046,2.103229 0,0.07087 -0.0603,0.175786 -0.13402,0.233225 -0.35312,0.275117 -0.73446,0.213951 -0.90233,-0.144737 -0.028,-0.05979 -0.12633,-0.304001 -0.21853,-0.542712 -0.13438,-0.347836 -0.16759,-0.459995 -0.16738,-0.56484 2.1e-4,-0.103137 -0.0663,-0.334929 -0.31415,-1.094853 l -0.31441,-0.964033 -0.17064,-0.134288 c -0.0939,-0.07386 -0.17588,-0.134281 -0.18233,-0.134281 -0.007,0 -0.27239,0.353278 -0.59098,0.785063 -0.31858,0.431777 -0.59548,0.799334 -0.61534,0.816778 -0.0199,0.01745 -0.043,0.07077 -0.0515,0.118484 -0.0103,0.0578 -0.11129,0.217315 -0.30279,0.477964 -0.30515,0.415326 -0.41793,0.516012 -0.61819,0.551831 -0.17915,0.03205 -0.41335,-0.09335 -0.39129,-0.209516 0.004,-0.01976 0.24688,-0.361845 0.54029,-0.760183 0.36341,-0.493383 0.54855,-0.725312 0.58086,-0.727608 0.0261,-0.0018 0.003,-0.01638 -0.0524,-0.03228 -0.14765,-0.04276 -0.15094,-0.05079 -0.12498,-0.305675 0.0439,-0.431361 0.11812,-1.492742 0.11812,-1.688879 l 0,-0.197447 -0.64609,-0.566039 c -0.48314,-0.423306 -0.65295,-0.558888 -0.67333,-0.537684 -0.0664,0.06897 -3.2326,4.887427 -3.26422,4.967547 -0.0427,0.108148 -0.34801,0.577117 -0.44891,0.689475 -0.0992,0.110436 -0.20376,0.157876 -0.34811,0.157876 -0.0991,0 -0.13329,-0.012 -0.18229,-0.06388 -0.0331,-0.03513 -0.0546,-0.07958 -0.0477,-0.09876 0.0291,-0.0804 0.81193,-1.242334 0.83724,-1.242747 0.0152,-2.51e-4 0.13696,-0.167081 0.27058,-0.370739 0.13357,-0.20366 0.281,-0.426255 0.3276,-0.494669 0.10085,-0.148058 0.0777,-0.135936 -0.18723,0.09831 -1.15366,1.019779 -2.63738,1.834375 -4.13719,2.271396 -0.87017,0.253541 -1.63136,0.380023 -2.57242,0.427436 -0.54983,0.02769 -0.53461,0.02771 -1.11432,-0.0012 z m 20.38962,-3.361927 c 0,-0.317572 -0.005,-0.577394 -0.0114,-0.577394 -0.0239,0 -1.53816,0.377211 -1.54551,0.384993 -0.008,0.0086 1.50823,0.765307 1.53916,0.768162 0.01,8.98e-4 0.0178,-0.258191 0.0178,-0.575761 z m -7.46021,-0.552288 0.34395,-0.464431 -0.0587,-0.05021 c -0.0543,-0.04646 -0.0581,-0.06408 -0.0515,-0.235839 l 0.007,-0.185627 0.24391,-0.06149 c 0.27525,-0.06941 0.25874,-0.03727 0.16163,-0.314759 l -0.0507,-0.145013 -0.0991,0.07717 c -0.0886,0.06897 -0.0999,0.08957 -0.10628,0.193963 -0.006,0.09962 -0.0177,0.12328 -0.0786,0.160842 -0.0893,0.05501 -0.37671,0.103714 -0.54576,0.09247 l -0.12774,-0.0085 -0.0129,0.125524 c -0.0414,0.403592 -0.0804,1.125894 -0.0677,1.252634 l 0.0149,0.148048 0.0418,-0.06018 c 0.023,-0.0331 0.19653,-0.269173 0.38573,-0.524603 z m 5.06562,-1.714097 0,-0.509083 0.15418,-0.161827 c 0.13637,-0.143097 0.17821,-0.170608 0.36157,-0.237761 l 0.20737,-0.07594 0.007,-0.113015 0.007,-0.113015 -0.18479,-0.139698 c -0.10165,-0.07684 -0.5306,-0.403229 -0.95325,-0.725303 -0.53478,-0.407553 -0.7776,-0.578783 -0.79865,-0.563176 -0.0166,0.01234 -0.18848,0.237072 -0.38188,0.499412 -0.63593,0.86263 -0.98402,1.33875 -0.9875,1.350672 -0.007,0.02282 0.81991,1.125859 0.85406,1.139731 0.0256,0.0104 1.18092,0.117372 1.67341,0.154935 0.0383,0.0029 0.0415,-0.03661 0.0415,-0.505928 z m -2.60232,0.289525 c 0.13263,0.01123 0.25367,0.01722 0.26896,0.01329 0.0254,-0.0065 -0.46959,-0.70384 -0.50728,-0.714744 -0.0136,-0.0039 -0.59475,0.772225 -0.61576,0.822255 -0.004,0.0088 0.13269,-0.01933 0.30311,-0.06259 0.2889,-0.07333 0.32612,-0.07726 0.55097,-0.05822 z m -3.16605,-0.513673 c 0.0609,-0.0718 0.1517,-1.446587 0.14386,-2.177291 l -0.007,-0.590092 -0.63763,0.96455 c -0.3507,0.530495 -0.63874,0.977542 -0.64013,0.993441 -9.6e-4,0.01588 0.24288,0.245768 0.5428,0.510853 0.52304,0.46229 0.54562,0.479104 0.55321,0.411692 0.005,-0.03866 0.0243,-0.08958 0.0442,-0.113153 z m 0.90874,-0.002 c 0.012,-0.517443 0.008,-0.720869 -0.0149,-0.72086 -0.0164,0 -0.0315,0.09969 -0.0406,0.269872 -0.008,0.148428 -0.0219,0.330503 -0.0309,0.40461 -0.016,0.132244 -0.0154,0.134202 0.0348,0.105801 0.0281,-0.01591 0.0513,-0.04264 0.0517,-0.05942 z m 1.2578,-0.551408 c 0.16813,-0.127723 0.30316,-0.244024 0.30008,-0.258467 -0.006,-0.02885 -1.39947,-1.920437 -1.40793,-1.911482 -0.008,0.008 0.28435,0.877537 0.30716,0.914788 0.0106,0.01723 0.0439,0.03133 0.0742,0.03133 0.0772,0 0.094,0.02906 0.20213,0.34881 0.097,0.286876 0.0979,0.302042 0.0231,0.391764 -0.0404,0.04839 -0.038,0.06233 0.0655,0.382844 0.0591,0.182953 0.11252,0.332633 0.11879,0.332633 0.006,0 0.14891,-0.1045 0.31703,-0.232215 z m 2.00521,-2.202896 c 0.67733,-0.918189 1.47371,-1.99847 1.76971,-2.400621 l 0.53818,-0.731187 0,-0.163216 c 0,-0.184732 0.0151,-0.207361 0.17112,-0.256137 l 0.10153,-0.03174 0.006,-2.841189 0.006,-2.841196 -0.0949,-0.09563 c -0.0849,-0.08549 -0.0949,-0.108295 -0.0949,-0.215383 0,-0.109383 -0.01,-0.130088 -0.11261,-0.239074 -0.062,-0.06563 -0.14073,-0.1547 -0.17508,-0.197931 -0.0527,-0.06622 -0.079,-0.07861 -0.16716,-0.07861 -0.12327,0 -0.16152,0.03238 -0.16167,0.136816 -1.1e-4,0.100964 -0.0752,0.227791 -0.16364,0.276188 -0.0995,0.05446 -0.25881,0.04905 -0.35335,-0.01198 -0.12792,-0.08258 -0.15472,-0.18499 -0.16575,-0.633236 l -0.01,-0.395396 -0.0878,0 c -0.0698,0 -0.13623,0.03532 -0.32351,0.171895 -0.12965,0.09453 -0.25705,0.17751 -0.28313,0.184376 -0.0261,0.0069 -0.56612,0.392283 -1.20011,0.856472 -1.03818,0.760139 -1.15163,0.849844 -1.14201,0.903107 0.009,0.04542 -0.01,0.07523 -0.0753,0.128612 -0.0722,0.05826 -0.15868,0.223485 -0.5354,1.022119 l -0.44934,0.952626 0,0.260961 c 0,0.293924 -0.0113,0.318857 -0.16701,0.368264 l -0.0938,0.02974 0,1.602695 0,1.602703 0.17432,0 0.1743,0 0.0136,-0.219661 c 0.019,-0.30653 0.0217,-0.311498 0.16666,-0.302458 0.11063,0.0069 0.12142,0.01329 0.13969,0.08279 0.025,0.0948 0.0251,1.049156 1.9e-4,1.167346 -0.0179,0.08494 -0.0226,0.08811 -0.13914,0.09535 -0.14443,0.009 -0.14272,0.01202 -0.16467,-0.295814 l -0.0161,-0.226306 -0.1744,0 -0.17443,0 0,0.677337 0,0.677338 0.0653,0.01641 c 0.11445,0.02879 0.14816,0.0799 0.14816,0.224615 l 0,0.131863 0.87132,1.180849 c 0.80914,1.096629 0.874,1.17781 0.90939,1.138281 0.0209,-0.0234 0.59228,-0.793811 1.26962,-1.71199 z m 2.3728,0.999531 c 0.0161,-0.02059 0.0722,-0.05103 0.12447,-0.06763 l 0.0951,-0.03017 0,-1.655871 c 0,-1.307788 -0.006,-1.65595 -0.0296,-1.656226 -0.0163,-1.81e-4 -0.0515,-0.0065 -0.0781,-0.01413 -0.0409,-0.01165 -0.18763,0.174716 -0.94615,1.20226 -0.49373,0.668823 -0.89647,1.223768 -0.89498,1.233206 0.002,0.0094 0.37924,0.304053 0.83947,0.654692 l 0.83677,0.637541 0.0118,-0.133117 c 0.007,-0.0732 0.0251,-0.149956 0.0412,-0.170558 z m -42.51814,0.140448 c 0.18852,-0.08077 0.35671,-0.219929 0.5578,-0.461592 0.14139,-0.169884 0.16784,-0.215874 0.16784,-0.291725 l 0,-0.09004 -0.11261,0.09838 c -0.0619,0.05411 -0.30466,0.265741 -0.53938,0.470305 -0.23471,0.204557 -0.43698,0.381714 -0.44945,0.393687 -0.0304,0.0291 0.20152,-0.04433 0.3758,-0.119018 z m 44.57447,-0.534275 c 0.35246,-0.308926 0.6431,-0.574407 0.64588,-0.589954 0.007,-0.03514 -1.56264,-2.406435 -1.60115,-2.420031 -0.0497,-0.01754 -0.0335,0.88569 0.031,1.739063 0.0324,0.428031 0.0716,0.963609 0.0871,1.190182 0.0235,0.344151 0.0353,0.418395 0.0714,0.451178 0.0297,0.02694 0.0432,0.07382 0.0432,0.149697 0,0.10111 0.004,0.107545 0.0408,0.07601 0.0225,-0.01895 0.32918,-0.287221 0.68162,-0.596149 z m -46.32074,-0.141233 0.12421,-0.0502 2.6e-4,-1.735336 2.7e-4,-1.735335 -0.0758,-0.01606 c -0.0482,-0.01022 -0.0866,-0.0045 -0.1053,0.01569 -0.0162,0.01747 -0.44644,0.596597 -0.95611,1.28697 -0.83414,1.129871 -0.92247,1.25825 -0.88455,1.285649 0.0232,0.01675 0.4262,0.323136 0.89564,0.680875 l 0.85351,0.650421 0.0118,-0.166226 0.0118,-0.166236 0.1242,-0.05021 z m 1.9432,-0.259804 0.52403,-0.460635 -0.0613,-0.141863 c -0.0545,-0.126051 -0.0616,-0.17544 -0.0636,-0.44312 l -0.002,-0.30125 -0.63569,-0.960235 c -0.34963,-0.528132 -0.64533,-0.960237 -0.65712,-0.960237 -0.0522,0 -0.0201,0.989681 0.0729,2.247171 0.0864,1.167613 0.0984,1.280317 0.14224,1.32969 0.0305,0.03435 0.0478,0.0882 0.0478,0.148282 l 0,0.09435 0.0545,-0.04575 c 0.03,-0.02517 0.2903,-0.25305 0.57852,-0.5064 z m 0.52871,-4.269279 0,-2.106525 -0.27003,-0.13749 c -0.30335,-0.15445 -0.51683,-0.299877 -0.68648,-0.46763 -0.13142,-0.129949 -0.19693,-0.251212 -0.22015,-0.407491 -0.009,-0.05994 -0.0297,-0.131588 -0.0461,-0.159204 -0.074,-0.124196 -0.0856,-0.262504 -0.0588,-0.703486 l 0.0262,-0.432017 -0.0596,-0.12562 c -0.0328,-0.06909 -0.075,-0.186397 -0.0939,-0.260684 -0.0307,-0.120598 -0.0345,0.11701 -0.0358,2.216503 l -0.002,2.351575 0.0889,0.03032 c 0.14214,0.04848 0.14818,0.06034 0.14818,0.290698 l 0,0.210552 0.59747,0.903505 c 0.32861,0.496936 0.60067,0.903513 0.60458,0.903513 0.004,0 0.007,-0.947934 0.007,-2.106523 z m 35.01893,0.269189 c 0.0586,-0.04589 0.0702,-0.0725 0.0702,-0.161688 0,-0.05873 0.0107,-0.113756 0.0237,-0.122289 0.015,-0.0098 0.0237,-0.297323 0.0237,-0.779715 0,-0.492726 -0.009,-0.764195 -0.0237,-0.764195 -0.0131,0 -0.0237,-0.0135 -0.0237,-0.03 0,-0.0165 -0.0272,-0.06009 -0.0605,-0.09685 -0.0333,-0.03676 -0.0873,-0.150344 -0.12002,-0.252411 -0.0614,-0.191323 -0.74569,-1.786434 -0.75992,-1.771371 -0.0148,0.01568 0.22943,2.186903 0.26452,2.351473 0.0191,0.08975 0.0619,0.411709 0.0951,0.715468 0.0331,0.30376 0.0703,0.631364 0.0827,0.728022 0.0123,0.09665 0.0227,0.189856 0.0232,0.20711 5.6e-4,0.02205 0.0504,0.03139 0.16771,0.03139 0.13451,0 0.18056,-0.01066 0.23708,-0.05494 z m 1.51625,-3.835889 c 0.0914,-0.193126 0.16613,-0.361371 0.16613,-0.37388 0,-0.06697 -0.0878,-0.03239 -0.28732,0.113153 -0.12234,0.08926 -0.22645,0.174569 -0.23138,0.189588 -0.008,0.02232 0.16132,0.414876 0.18069,0.42057 0.003,9.23e-4 0.0805,-0.156314 0.17188,-0.349431 z m -0.1495,-0.871878 c -0.004,-0.0609 0.0322,-0.09474 0.34892,-0.32625 0.30637,-0.22395 0.36473,-0.257458 0.4388,-0.251997 0.0771,0.0057 0.18391,-0.06572 1.0975,-0.733577 0.55663,-0.406929 1.00809,-0.744059 1.00325,-0.749183 -0.005,-0.0051 -0.19894,0.0088 -0.43138,0.03092 -0.54359,0.05175 -1.50531,0.114792 -1.75364,0.114938 -0.18548,1.13e-4 -0.19361,0.0025 -0.20772,0.06219 -0.008,0.03414 -0.034,0.08215 -0.0576,0.10669 -0.0236,0.02455 -0.17866,0.410011 -0.34456,0.8566 -0.24176,0.65081 -0.29602,0.819123 -0.27339,0.848007 0.0215,0.02738 0.0217,0.05124 9.6e-4,0.09925 -0.015,0.03476 -0.0272,0.08581 -0.0272,0.113429 0,0.04628 0.009,0.0442 0.10521,-0.02641 0.0845,-0.06155 0.10434,-0.09003 0.10077,-0.144598 z m -0.98835,-0.142726 c 0,-0.04919 0.12474,-0.09121 0.32005,-0.107804 l 0.16597,-0.0141 0.27099,-0.731067 c 0.14902,-0.402082 0.28409,-0.764946 0.30012,-0.806373 l 0.0291,-0.07531 -1.32289,0 -1.3229,0 -0.0272,0.0796 c -0.0226,0.06602 -0.0173,0.125316 0.0311,0.347489 0.0321,0.147342 0.0618,0.271218 0.066,0.275298 0.0564,0.05423 0.38712,0.289292 0.4073,0.289482 0.12989,0.0012 0.63761,0.373836 0.81602,0.598942 0.0617,0.07776 0.12273,0.14968 0.13577,0.159827 0.0411,0.03197 0.13041,0.02102 0.13041,-0.01599 z m -36.7236,-0.928464 c 0.0888,-0.281932 0.30275,-0.759276 0.41371,-0.922819 l 0.0826,-0.121858 -0.11851,0 c -0.1027,0 -0.1185,0.0067 -0.1185,0.05021 0,0.02761 -0.0213,0.07279 -0.0474,0.10041 -0.026,0.02763 -0.0475,0.07029 -0.0475,0.09484 0,0.07992 -0.0669,0.148437 -0.17681,0.181012 l -0.10771,0.03193 0.003,0.542754 c 0.002,0.41121 0.008,0.509981 0.024,0.407534 0.0116,-0.07438 0.0536,-0.238184 0.0932,-0.364011 z m 42.78425,-1.235431 c 0.0278,-0.0079 0.0627,-0.04297 0.0778,-0.07797 0.0217,-0.05054 0.0211,-0.0611 -0.003,-0.05129 -0.0167,0.0068 -0.0918,0.02689 -0.16675,0.04466 -0.13136,0.03112 -0.15441,0.04698 -0.12051,0.08288 0.0192,0.02037 0.1433,0.02137 0.21248,0.0017 z M 203.08964,36.43027 c 4.2e-4,-0.02416 0.11589,-1.122796 0.2566,-2.441392 l 0.25581,-2.397455 -0.0559,-0.175734 c -0.0811,-0.254843 -0.16527,-0.621511 -0.19789,-0.862119 -0.0478,-0.352538 -0.005,-0.534698 0.16643,-0.706894 l 0.0874,-0.08787 0.0376,-0.456917 c 0.0338,-0.411243 0.0442,-0.469761 0.10373,-0.585518 0.0363,-0.07073 0.0945,-0.149956 0.12904,-0.176053 0.055,-0.04142 0.0649,-0.07066 0.0785,-0.230369 0.0121,-0.141233 0.0306,-0.205798 0.0811,-0.283338 0.22721,-0.348759 1.02216,-0.621642 2.22366,-0.76335 0.75999,-0.08964 1.22599,-0.112419 2.26836,-0.110936 0.55745,8.02e-4 1.01354,-0.0071 1.01354,-0.01765 0,-0.0105 0.0256,-0.04516 0.0568,-0.07701 l 0.0568,-0.05791 -0.0532,-0.07652 c -0.1891,-0.271683 -0.28254,-0.549432 -0.26918,-0.80016 0.009,-0.165494 0.11579,-0.478702 1.31856,-3.860395 1.15398,-3.244558 1.31188,-3.705255 1.33355,-3.891163 0.0426,-0.364766 0.10847,-0.54922 0.24593,-0.687855 0.059,-0.05951 0.11625,-0.192795 0.27278,-0.635139 0.10897,-0.307906 0.22858,-0.604344 0.26581,-0.65877 0.0372,-0.05442 0.0676,-0.103023 0.0676,-0.10801 0,-0.005 -0.0933,-0.01662 -0.20745,-0.02585 -0.3144,-0.02543 -1.45766,-0.18023 -2.16343,-0.292937 -1.07613,-0.171847 -2.19134,-0.388513 -3.37451,-0.655605 -0.24555,-0.05543 -0.44946,-0.09699 -0.45313,-0.09235 -0.008,0.0091 -3.69705,6.476193 -3.781,6.626873 l -0.0508,0.09132 0.12323,0.04675 c 0.4198,0.159254 0.61161,0.678796 0.45768,1.239701 -0.0788,0.287244 -0.36108,0.69042 -0.59127,0.844625 -0.0573,0.03836 -0.10906,0.09268 -0.11506,0.120678 -0.006,0.02801 -0.0458,0.257076 -0.0884,0.509044 l -0.0774,0.458121 -0.0788,0.03018 -0.0788,0.03018 0,5.316577 0,5.316589 0.0652,0.01507 c 0.23888,0.05522 0.29044,0.106397 0.29044,0.288342 0,0.100591 0.0101,0.148135 0.0333,0.15759 0.0184,0.0074 0.0406,0.04819 0.0493,0.09055 0.0157,0.07537 0.0189,0.077 0.15635,0.077 0.11759,0 0.14049,-0.0071 0.14115,-0.04393 z m 15.39052,-1.949408 c 0.88104,-1.407705 2.21354,-2.632447 3.73524,-3.433186 0.22793,-0.119926 0.24358,-0.133013 0.24358,-0.203469 0,-0.106002 0.0762,-0.224045 0.18719,-0.29012 0.12891,-0.07672 0.82746,-0.353848 1.17606,-0.466579 0.66345,-0.214537 1.47656,-0.391876 2.19309,-0.47831 0.56517,-0.06818 0.74169,-0.04333 0.82753,0.116491 0.0293,0.05451 0.0554,0.07049 0.11503,0.07062 l 0.0772,1.54e-4 -0.006,-1.939304 -0.006,-1.939306 -0.19905,-0.07065 c -0.10948,-0.03886 -0.25084,-0.07715 -0.31413,-0.08508 l -0.11511,-0.01444 0,0.8838 c 0,0.536629 -0.01,0.902072 -0.0235,0.930334 -0.0561,0.111109 -0.45975,0.149214 -0.63276,0.05973 l -0.0905,-0.04682 -0.0119,-0.947917 -0.0118,-0.947928 -0.0771,-0.0496 -0.0771,-0.0496 0,-0.285175 c 0,-0.299339 0.0113,-0.333755 0.12446,-0.37622 0.0378,-0.01418 0.0415,-0.06381 0.0415,-0.552298 l 0,-0.536713 -0.0889,-0.04103 c -0.0489,-0.02257 -0.41438,-0.168685 -0.81218,-0.324715 l -0.72324,-0.28369 0.008,0.09029 c 0.01,0.104325 -0.0927,0.448585 -0.16495,0.555962 -0.0558,0.08299 -0.15985,0.146178 -0.24069,0.146178 -0.0531,0 -0.12503,0.193386 -1.24883,3.357695 -0.70846,1.994777 -1.21984,3.399783 -1.25985,3.461371 -0.24551,0.377883 -1.07333,0.5864 -2.06054,0.519022 -0.20212,-0.0138 -0.36923,-0.02398 -0.37134,-0.02264 -0.002,0.0013 -0.0113,0.183196 -0.0205,0.404118 l -0.0166,0.401668 0.0726,0.09585 c 0.15455,0.20434 0.15934,0.436278 0.0182,0.883222 -0.091,0.288256 -0.32206,0.820072 -0.44323,1.02028 -0.0613,0.101359 -0.075,0.158558 -0.10484,0.439325 -0.0188,0.177536 -0.0401,0.37363 -0.0471,0.435763 l -0.0128,0.112962 0.0776,-0.135617 c 0.0427,-0.07459 0.17018,-0.283581 0.28337,-0.464431 z m 16.03477,-3.065293 c 1.48068,-0.316269 4.30558,-0.5191 6.67406,-0.479217 2.13493,0.03596 3.79042,0.199881 4.55801,0.451351 l 0.18374,0.0602 -1.3e-4,-1.459605 c -6e-5,-0.802776 -0.01,-1.499136 -0.0216,-1.547465 -0.0118,-0.04832 -0.0284,-0.15187 -0.0369,-0.230101 -0.0147,-0.136359 -0.0191,-0.143847 -0.10668,-0.180935 -0.10245,-0.04339 -0.16655,-0.124092 -0.16655,-0.209594 l 0,-0.05718 -0.44455,-3.18e-4 c -0.49529,-3.46e-4 -1.55378,-0.03272 -2.54277,-0.07776 l -0.65201,-0.02969 -0.29634,0.180858 c -0.39244,0.239487 -1.15055,0.633459 -1.63592,0.850146 -1.37749,0.614964 -2.75901,1.032997 -4.05422,1.226752 -0.38635,0.05779 -1.46653,0.06497 -1.71888,0.01143 -0.38306,-0.08128 -0.68991,-0.241584 -0.80902,-0.422648 -0.0342,-0.05194 -0.51326,-1.365338 -1.06462,-2.91866 -0.79969,-2.252858 -1.01137,-2.8257 -1.04624,-2.831486 -0.11751,-0.01949 -0.14953,-0.03554 -0.21719,-0.108806 -0.0415,-0.04491 -0.10033,-0.158329 -0.13615,-0.262302 l -0.0631,-0.183188 -0.18115,0.07141 c -0.0996,0.03928 -0.41051,0.161717 -0.69088,0.272083 -0.28035,0.110367 -0.55507,0.219925 -0.6105,0.243464 l -0.10076,0.0428 0,0.535329 c 0,0.512745 0.002,0.535991 0.0473,0.55121 0.10553,0.03547 0.11869,0.07697 0.11869,0.374512 0,0.296995 -0.0115,0.331649 -0.12447,0.374056 -0.0385,0.01447 -0.0415,0.0831 -0.0415,0.957201 l 0,0.94162 -0.0567,0.03931 c -0.0845,0.05858 -0.29061,0.08562 -0.44868,0.05887 -0.25018,-0.04234 -0.22963,0.04695 -0.22963,-0.99778 l 0,-0.91378 -0.12703,0.01389 c -0.0699,0.0076 -0.21656,0.0462 -0.326,0.0857 l -0.19896,0.07182 -0.006,1.93525 -0.006,1.93526 0.15571,0.01322 c 0.14575,0.01239 0.1643,0.0078 0.28961,-0.07213 0.23155,-0.147627 0.32779,-0.159765 0.76923,-0.09699 0.45512,0.06472 0.60147,0.105993 0.68338,0.192746 0.0399,0.04227 0.0782,0.106502 0.085,0.142735 0.0118,0.06233 0.0292,0.06975 0.32482,0.138015 1.10281,0.254714 2.27032,0.741722 3.21526,1.3412 l 0.27126,0.172075 0.19107,-0.05939 c 0.10509,-0.03267 0.37244,-0.09814 0.59413,-0.145487 z m 13.33623,20.083539 0,-0.389115 0.0803,0 c 0.0442,0 0.10234,0.01977 0.1292,0.04394 0.0973,0.0875 0.18712,0.526708 0.12788,0.625299 -0.0141,0.02348 -0.26759,0.108995 -0.32309,0.108995 -0.008,0 -0.0143,-0.175104 -0.0143,-0.389117 z"
+       id="path2384"
+       sodipodi:nodetypes="csscccccccccsccccccsssssssssssssscccsscccccccccssssccccccccccccssccccccsssccccccsscccscccscccssssscccsssssscccssssscccsssssscccccccccccssssssssscccscccccccscccccssssscccsscccssssssssssssssssscccscccccscccccccscccccccsssssscccccsscccccccsscccccscccssssssssssssssccccccccssccccccccccsscccsscccsscccccccccscccsssccccccccsssssssssssssssssssssssscccsssssssssssscccssssssssssscccssssssssssssccsssccccccccccsscccccccccccccccssssssccsssscccccsssccssssccssssssssccccccccccssssssscccsssssccccccccccssssccccccccccscccccsssscccccscccssccsssssssccccccssscccccccccccssscccccccssscccsccccccsccsssssssssssssccssssccsssssssssssssccccccccccssssscccccssscccsccsssscccccscccssssssscccssssssssssscccssscccccccssssccssssssccccccccscccccccsccccccsssssscccssscccccscccsssccccccssssssscccscccssscccsccccccccssssscccccccsssc"
+       inkscape:connector-curvature="0"
+       transform="matrix(0.7640902,0,0,0.7640902,39.769403,12.749128)" />
+    <path
+       style="fill:#ffffff;fill-opacity:1;stroke:#000000;stroke-width:0.5;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;filter:url(#filter3945)"
+       d="m 141.65398,62.591019 c 0.006,-0.02035 -0.005,-0.03292 -0.023,-0.02791 -0.0186,0.005 -0.15273,0.01956 -0.29788,0.03239 -0.14518,0.01286 -0.2983,0.03356 -0.3403,0.046 -0.042,0.01248 -0.12982,0.01745 -0.19516,0.01106 -0.10386,-0.01011 -0.10988,-0.0053 -0.0478,0.03842 0.0967,0.06825 0.0516,0.07373 -0.28676,0.03477 -0.38615,-0.04443 -0.98831,-0.186325 -1.27027,-0.299332 -0.31757,-0.127294 -1.42237,-0.779386 -1.63574,-0.965512 -0.0973,-0.08484 -0.19122,-0.160532 -0.20872,-0.168192 -0.12163,-0.0531 -1.41182,-1.357831 -2.11523,-2.139028 -0.58336,-0.647853 -1.00299,-1.165468 -1.75669,-2.166793 -0.23233,-0.30866 -0.46081,-0.576808 -0.50773,-0.595898 -0.0728,-0.02964 -0.0946,-0.01416 -0.14825,0.105969 -0.0346,0.07736 -0.0566,0.164438 -0.0488,0.193477 0.0219,0.08161 -0.0609,0.08414 -0.19693,0.006 -0.13185,-0.07576 -0.41837,-0.446687 -0.4581,-0.59302 -0.0208,-0.07665 -0.005,-0.09 0.11904,-0.100835 0.0786,-0.0068 0.1888,-0.01172 0.24481,-0.01077 0.0805,0.0014 0.0972,-0.01523 0.0799,-0.07916 -0.0121,-0.04449 -0.0102,-0.10349 0.004,-0.13115 0.0155,-0.02965 -0.13019,-0.295688 -0.35488,-0.648365 -0.75888,-1.19116 -1.5633,-2.707125 -2.17335,-4.095741 -0.30098,-0.685075 -0.72904,-2.260447 -0.76678,-2.821841 -0.15084,-2.244521 0.58489,-4.504332 2.03103,-6.238272 0.16559,-0.19855 0.82948,-0.880535 0.86731,-0.890943 0.0127,-0.0034 0.15528,-0.114158 0.31681,-0.245904 0.32378,-0.264139 1.0309,-0.712198 1.51554,-0.96034 0.97131,-0.497276 2.27021,-0.956889 4.90805,-1.73666 1.72652,-0.510388 2.08644,-0.628713 2.46053,-0.808905 0.74524,-0.35899 1.2414,-0.734421 1.75026,-1.324416 0.38556,-0.447024 0.50491,-0.636068 1.26513,-2.003926 1.16593,-2.097862 1.91352,-3.144869 3.18211,-4.456642 0.30567,-0.316061 1.07784,-0.944428 1.52809,-1.243495 0.67838,-0.450593 1.2021,-0.687604 2.00607,-0.907844 1.16952,-0.320387 1.72318,-0.277583 2.21745,0.171442 0.0791,0.07179 0.17068,0.123097 0.20365,0.114034 0.033,-0.0092 0.10212,0.01782 0.15363,0.05977 l 0.0937,0.07627 0.0981,-0.202576 c 0.0577,-0.119134 0.1249,-0.199867 0.16322,-0.196003 0.0811,0.0082 0.18488,0.212248 0.14883,0.292678 -0.0174,0.03868 -0.009,0.06063 0.0249,0.0625 0.0642,0.0035 0.25016,0.380644 0.21676,0.439568 -0.0135,0.0237 -0.10858,0.02551 -0.21139,0.004 -0.23337,-0.04879 -0.30098,-0.03142 -0.27342,0.07017 0.0119,0.04376 -0.0132,0.119476 -0.0556,0.168271 -0.0425,0.0488 -0.0798,0.178758 -0.083,0.288794 -0.009,0.312331 -0.14976,0.739254 -0.33297,1.008836 -0.0921,0.135382 -0.38589,0.486353 -0.65303,0.779943 -0.84512,0.928753 -1.42613,1.692717 -1.68407,2.214403 -0.25736,0.520447 -0.28533,0.590927 -0.3496,0.880769 -0.0569,0.256607 -0.0536,0.32838 0.0284,0.627072 0.078,0.284141 0.12099,0.368805 0.27241,0.537269 0.2976,0.331025 0.51137,0.421711 0.96533,0.409505 0.19128,-0.0051 0.22851,-0.01922 0.32681,-0.123539 0.0644,-0.06829 0.19622,-0.148586 0.24219,-0.198773 0.29507,-0.277491 0.72234,-0.66111 1.10595,-0.970695 0.33509,-0.337274 0.72699,-0.665996 1.13195,-0.985923 0.59413,-0.554879 1.27981,-1.222905 1.9166,-1.803468 0.69247,-0.616128 1.23538,-1.116752 1.89503,-1.706481 0.42724,-0.398552 0.99057,-0.868297 1.45843,-1.300525 0.44915,-0.425827 0.9987,-0.913353 1.49612,-1.338174 0.50197,-0.53209 1.0676,-1.043378 1.63975,-1.515298 0.26538,-0.243989 0.56161,-0.518548 0.84587,-0.782605 0.58742,-0.537728 0.50766,-0.475138 0.84904,-0.76988 0.51151,-0.516334 1.20408,-1.086463 1.78482,-1.604386 0.59591,-0.597798 1.51886,-1.441692 2.05657,-1.887694 0.0555,-0.04073 0.48925,-0.425406 0.96388,-0.854824 0.56529,-0.511418 0.87748,-0.774448 0.92517,-0.819318 0.60532,-0.592834 1.4985,-1.370202 2.1548,-1.891117 0.6511,-0.662126 1.48777,-1.389978 2.22792,-2.043168 0.37208,-0.377416 0.81657,-0.763381 1.22291,-1.134183 0.63663,-0.575259 1.15928,-1.064262 1.16145,-1.086688 0.13824,-0.12149 0.20463,-0.141102 0.28462,-0.30659 0.10711,-0.196035 0.14562,-0.565917 0.094,-0.902967 -0.0189,-0.12389 -0.13147,-0.444409 -0.26126,-0.744396 -0.41032,-0.9482946 -0.33226,-1.1187913 0.81882,-1.788817 l 0.3372,-0.1962829 -0.077,-0.097636 c -0.19637,-0.248993 -0.47873,-0.3697205 -0.81278,-0.3474581 -0.16079,0.010705 -0.47918,-0.1496269 -0.59569,-0.2999947 -0.0515,-0.066486 -0.1216,-0.2238681 -0.15578,-0.3497511 -0.0529,-0.1952859 -0.0489,-0.2593006 0.028,-0.4360823 0.0496,-0.1139505 0.11913,-0.2322259 0.15456,-0.262834 0.0353,-0.030603 0.1098,-0.1701676 0.16526,-0.3101411 0.0706,-0.177955 0.14626,-0.2851288 0.25171,-0.3563435 0.19728,-0.1332148 0.51068,-0.1866145 0.69506,-0.1184261 0.0809,0.029929 0.20078,0.051219 0.26637,0.047314 0.0655,-0.0039 0.16745,-0.010181 0.22644,-0.013947 0.15548,-0.00993 0.40895,0.1205855 0.56117,0.2889255 0.10693,0.1182597 0.13846,0.1907223 0.16545,0.3800703 0.0337,0.2364305 0.006,0.3361874 -0.21276,0.7542017 -0.10157,0.1945154 -0.12366,0.4140575 -0.064,0.6355289 l 0.0355,0.1319862 0.16222,-0.1076744 c 0.0891,-0.059218 0.5291,-0.3215264 0.97753,-0.5829153 0.44841,-0.261377 0.82062,-0.4846113 0.8271,-0.4960819 0.0137,-0.024055 -0.086,-0.1097677 -0.28356,-0.2439828 -0.15703,-0.1066613 -0.2645,-0.1298412 -0.6305,-0.1359611 -0.29182,-0.00488 -0.46207,-0.09973 -0.65456,-0.3646597 -0.23628,-0.325224 -0.19755,-0.6549934 0.11993,-1.020698 0.0836,-0.10804 0.0812,-0.2167355 0.11422,-0.3550797 0.0393,-0.1855029 0.18269,-0.3071893 0.44796,-0.3798923 0.16253,-0.044546 0.27477,-0.045365 0.41805,-0.00306 0.10773,0.031809 0.24885,0.043905 0.31358,0.02687 0.30329,-0.079799 0.69816,0.1330951 0.85683,0.4619707 0.11792,0.2444563 0.10454,0.4188765 -0.0574,0.7469332 -0.14744,0.2986513 -0.14986,0.3153808 -0.0884,0.6056588 l 0.0634,0.298517 0.11471,-0.053734 c 0.0631,-0.029559 0.35092,-0.1915536 0.63966,-0.3599905 0.28873,-0.1684369 0.68762,-0.4010318 0.88645,-0.516869 0.19882,-0.1158401 0.36867,-0.2233236 0.37748,-0.23884 0.0291,-0.051353 -0.24991,-0.3240195 -0.37247,-0.3639939 -0.0662,-0.021595 -0.23755,-0.037692 -0.38074,-0.035752 -0.29479,0.00398 -0.4483,-0.060982 -0.63873,-0.2702834 -0.13375,-0.1470069 -0.19578,-0.3614131 -0.19832,-0.4437237 -0.004,-0.136278 0.005,-0.2687033 0.005,-0.3670724 2.5e-4,-0.04212 0.0187,-0.1139193 0.12103,-0.2226509 0.10732,-0.1140497 0.15214,-0.1990039 0.13676,-0.2592116 -0.0296,-0.1159668 0.0893,-0.3232906 0.27342,-0.4763325 0.17661,-0.1468699 0.37313,-0.1729465 0.63195,-0.083839 0.0996,0.034291 0.22619,0.049946 0.2813,0.034788 0.23308,-0.064131 0.45815,0.019608 0.72216,0.2686868 0.11758,0.1109322 0.15004,0.1765961 0.1911,0.3864384 0.0443,0.2262193 0.0362,0.2785322 -0.0764,0.4973884 -0.0692,0.134504 -0.13514,0.3166586 -0.14649,0.4047652 -0.0241,0.18742 0.077,0.610286 0.13193,0.5510748 0.0198,-0.021354 0.4435,-0.2711234 0.94164,-0.5550606 1.14275,-0.6513611 1.0822,-0.6126785 1.06399,-0.6797688 -0.0451,-0.1662584 -0.62901,-0.3901041 -0.85523,-0.3278735 -0.12677,0.03488 -0.53298,-0.1958685 -0.66519,-0.3778777 -0.0856,-0.117794 -0.11259,-0.1906347 -0.10395,-0.2803986 0.007,-0.066707 -0.008,-0.1555404 -0.0319,-0.1974175 -0.0525,-0.091716 0.0631,-0.3658746 0.21257,-0.504394 0.059,-0.054676 0.0944,-0.1306144 0.082,-0.1761709 -0.0372,-0.1368914 0.11056,-0.3848227 0.30822,-0.5173272 0.21667,-0.1452597 0.47066,-0.1702907 0.6377,-0.062856 0.0691,0.044446 0.15206,0.049051 0.27488,0.015264 0.35561,-0.097835 0.82001,0.2098346 0.92251,0.6111652 0.0541,0.2118278 0.0373,0.3094447 -0.10185,0.5915631 -0.12478,0.2529669 -0.15717,0.496264 -0.0961,0.7213428 l 0.0561,0.2069251 0.20889,-0.1016875 c 0.47999,-0.2336693 1.2202,-0.2900373 1.67612,-0.1276439 0.29431,0.1048407 0.70917,0.3596203 0.70205,0.4311814 -0.004,0.042265 0.008,0.051989 0.0322,0.025774 0.0555,-0.0598 0.4713,0.4378564 0.61005,0.7299637 0.25792,0.5430128 0.30592,1.1501024 0.13308,1.6839333 -0.21749,0.6718121 -0.90227,1.3208932 -1.59098,1.5080394 -0.43148,0.1172429 -0.64223,0.1223328 -1.15559,0.027934 -0.55989,-0.1029499 -0.60756,-0.1024027 -0.77432,0.00892 -0.32103,0.2143256 -0.94595,1.0134971 -1.201,1.5358978 -0.17717,0.3628965 -0.84795,1.5647444 -1.02678,1.8396904 -0.24665,0.379252 -0.45677,0.659952 -0.84152,1.124288 -0.49059,0.592048 -0.6879,0.792964 -0.81243,0.82722 -0.0541,0.01488 -0.29754,-0.02989 -0.54104,-0.09948 -0.74853,-0.213915 -1.29621,-0.189514 -1.8823,0.08384 -0.27735,0.129376 -0.93583,0.623499 -1.12513,0.844313 -0.72001,0.464947 -1.08067,1.042084 -1.66196,1.663778 -0.45166,0.45774 -0.62486,0.6287 -1.09359,1.079491 -0.13751,0.132262 -0.39292,0.386111 -0.56758,0.564108 -0.49195,0.497185 -0.99796,0.979906 -1.4913,1.475669 -1.12913,0.884263 -1.9128,1.872872 -2.81723,2.772314 -0.773,0.581494 -1.13095,1.103163 -1.54822,1.527386 -1.1859,0.879696 -1.60734,1.607627 -2.57985,2.555607 -0.7378,0.5635 -1.09006,1.078701 -1.82852,1.793529 -0.49296,0.439223 -0.48162,0.455186 -0.73909,0.736828 -0.0827,0.08345 -0.26161,0.264151 -0.39775,0.40153 -0.53519,0.540084 -0.67894,0.643342 -0.92134,0.877524 -0.33922,0.353147 -0.92695,0.993773 -1.41319,1.428124 -0.21683,0.20741 -0.61113,0.585598 -0.75828,0.731772 -2.75768,2.450707 -5.42912,5.401425 -8.40714,8.211918 -0.41167,0.290447 -0.80224,0.720469 -1.01148,1.197138 -0.45757,1.040643 0.073,2.079294 1.2759,2.497613 0.33587,0.116798 0.80384,0.107054 1.2983,-0.02702 0.51839,-0.140581 0.73715,-0.249408 1.42864,-0.710783 0.62681,-0.418206 0.91729,-0.538329 1.25706,-0.519867 0.26286,0.0143 0.66147,0.208986 0.84993,0.41512 0.14486,0.158447 0.28602,0.54759 0.3017,0.831696 0.0236,0.428612 -0.18026,1.259223 -0.43492,1.771818 -0.21923,0.441276 -0.77145,1.198962 -1.35429,1.858146 -1.15859,1.310334 -3.39226,2.716863 -5.92419,3.730369 -1.09425,0.438034 -1.36992,0.583609 -1.87032,0.987682 -0.45307,0.365855 -0.80102,0.796004 -1.18255,1.461966 -0.31016,0.541396 -0.59923,1.292836 -0.74132,1.927229 -0.0269,0.119603 -0.0611,0.227684 -0.0763,0.240182 -0.0152,0.01251 -0.0229,0.03985 -0.0173,0.06081 0.01,0.03694 -0.0752,0.37158 -0.35152,1.381274 -0.073,0.266931 -0.12843,0.501532 -0.12306,0.521361 0.006,0.01985 -0.005,0.04011 -0.023,0.0451 -0.0181,0.005 -0.0517,0.08055 -0.0747,0.167941 -0.0974,0.370073 -0.40425,1.153693 -0.63539,1.622532 -0.27679,0.561463 -0.57213,1.000026 -1.03256,1.53328 -0.81975,0.949416 -1.53,1.421218 -2.69641,1.791159 -0.37992,0.120495 -0.68587,0.202425 -0.67986,0.182077 z M 177.73229,6.1030012 c 0.0284,-0.032009 0.0329,-0.053021 0.01,-0.046683 -0.023,0.00636 -0.0651,0.037726 -0.0937,0.069731 -0.0284,0.032016 -0.033,0.053015 -0.01,0.046672 0.023,-0.00635 0.0652,-0.037717 0.0937,-0.06972 z"
+       id="path2398"
+       sodipodi:nodetypes="csssssssssssssssssssssssssssssssssssscccssssssssssssssssccccccccccccsccccccsscccssssssssssssscccsssssccssssscccssssssssssssssssssssssssssssssscccssssssssssssssccscccccccscccccsssssssssssssssssssssccsssc"
+       inkscape:connector-curvature="0"
+       transform="matrix(0.7640902,0,0,0.7640902,25.127162,12.749114)" />
+    <path
+       style="fill:#ffffff;fill-opacity:1;stroke:#000000;stroke-width:0.5;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;filter:url(#filter3945)"
+       d="m 70.011956,57.308898 c -0.06361,-0.182304 0.02362,-0.335041 0.194719,-0.340992 0.05437,-0.002 0.112637,-0.018 0.129477,-0.0358 0.02935,-0.03101 0.06738,-0.222408 0.05443,-0.273919 -0.0033,-0.0136 -0.17953,-0.208345 -0.391366,-0.432766 -0.478145,-0.506566 -0.905605,-0.988835 -1.340803,-1.512752 -0.686815,-0.826842 -1.554819,-1.96687 -1.877504,-2.46594 -0.79825,-1.234507 -1.304177,-2.597391 -1.465371,-3.947349 -0.06304,-0.527901 -0.0864,-1.577337 -0.04423,-1.986082 0.134187,-1.300354 0.636393,-2.355604 1.677171,-3.524078 0.627936,-0.704963 1.750331,-1.70072 2.452842,-2.176076 1.298025,-0.878324 2.923183,-1.706221 5.63767,-2.871986 1.534725,-0.659112 1.975347,-0.867096 2.551322,-1.204332 1.503536,-0.880276 2.580906,-2.104416 3.527333,-4.007858 0.526136,-1.05817 1.725259,-3.373091 1.879926,-3.629239 1.352177,-2.239361 2.724018,-3.650385 4.140627,-4.258902 0.282506,-0.121351 0.831499,-0.29054 1.109022,-0.341774 0.519471,-0.09592 1.018844,-0.04164 1.392765,0.151361 0.140142,0.07232 0.189216,0.109968 0.315821,0.242281 0.144624,0.151094 0.149596,0.154452 0.140851,0.0952 -0.005,-0.03377 -0.01415,-0.06672 -0.02036,-0.07316 -0.03678,-0.03829 0.03599,-0.03138 0.188106,0.01786 l 0.17409,0.05632 0.04299,-0.06849 c 0.103642,-0.165082 0.211127,-0.19829 0.347534,-0.107377 0.07686,0.05121 0.108008,0.117054 0.159544,0.337204 0.05095,0.217707 0.04022,0.296635 -0.05385,0.395999 -0.085,0.08977 -0.162986,0.101224 -0.256306,0.03762 -0.129897,-0.0885 -0.210212,-0.04951 -0.310766,0.1508 -0.02763,0.05502 -0.05248,0.102578 -0.05525,0.105695 -0.0029,0.0031 -0.01535,-0.03216 -0.02796,-0.07838 l -0.02293,-0.08403 -0.02362,0.117515 c -0.05545,0.275966 -0.138606,0.408643 -0.610458,0.973993 -0.413279,0.495167 -0.755033,0.942729 -1.008925,1.321296 -0.101488,0.151315 -0.238177,0.352464 -0.303761,0.446999 -0.142983,0.206087 -0.202799,0.325663 -0.268406,0.536572 -0.09507,0.305613 -0.128872,0.616717 -0.116115,1.068931 0.02103,0.745138 0.225467,1.464421 0.585498,2.059955 0.0885,0.146383 0.144418,0.212341 0.359883,0.424496 0.294073,0.289536 0.387847,0.350193 0.713386,0.461304 0.241488,0.08244 0.462648,0.11277 0.722064,0.09908 0.241935,-0.01279 0.641106,-0.103226 0.691772,-0.156734 0.02114,-0.02233 0.808186,-0.811209 1.749007,-1.753092 4.476435,-4.481481 7.423355,-7.445107 11.854865,-11.922076 0.79851,-0.806695 2.63461,-2.67198 3.90597,-3.968092 0.83052,-0.846644 2.59171,-2.66211 4.35348,-4.487615 l 0.85207,-0.8828584 -0.006,-0.159756 c -0.008,-0.2124949 -0.0339,-0.4292362 -0.0782,-0.6514218 -0.0543,-0.2729232 -0.0549,-0.4542862 -0.002,-0.5791435 0.10329,-0.2426245 0.2746,-0.4033352 0.63336,-0.5941832 0.26259,-0.1397045 0.74366,-0.4415779 0.74321,-0.4663854 -7.6e-4,-0.041787 -0.1203,-0.2378625 -0.16084,-0.2638428 -0.0251,-0.016077 -0.0911,-0.016045 -0.15873,8.45e-5 -0.1013,0.024153 -0.12398,0.020768 -0.18156,-0.027148 -0.0726,-0.060491 -0.16869,-0.2356996 -0.26514,-0.4838507 -0.0758,-0.1948055 -0.0699,-0.2077894 0.19044,-0.4201538 0.20189,-0.1647517 0.30137,-0.222005 0.46873,-0.2698496 0.13994,-0.040012 0.2254,-0.030085 0.31677,0.036802 0.092,0.06726 0.25616,0.3025681 0.29863,0.4279295 0.041,0.1211922 0.0167,0.2701459 -0.0569,0.3478737 -0.0621,0.065515 -0.061,0.068824 0.0729,0.2287072 0.0718,0.08578 0.0736,0.08644 0.13601,0.051728 0.25876,-0.1439641 1.01067,-0.5864515 1.00962,-0.5941749 -7.2e-4,-0.00527 -0.0264,-0.056824 -0.0569,-0.1145091 -0.0684,-0.1290199 -0.13096,-0.1619374 -0.23761,-0.1251303 -0.0416,0.014351 -0.0948,0.023799 -0.11841,0.021019 -0.10135,-0.011912 -0.21337,-0.1856755 -0.34471,-0.5347434 l -0.0671,-0.1781479 0.17655,-0.1663426 c 0.30142,-0.2840099 0.59718,-0.4129216 0.78637,-0.3427059 0.0962,0.035754 0.11118,0.048551 0.21552,0.1851924 0.12528,0.1640753 0.1763,0.2685475 0.18269,0.3740055 0.006,0.092837 -0.0496,0.2477228 -0.0993,0.2786032 -0.047,0.029257 -0.0376,0.054229 0.0709,0.1871647 l 0.0804,0.098581 0.50859,-0.2847655 c 0.27973,-0.1566165 0.51044,-0.2907068 0.5127,-0.2979785 0.01,-0.030602 -0.10593,-0.2252324 -0.14836,-0.2500044 -0.0254,-0.014835 -0.0765,-0.016504 -0.11351,-0.00374 -0.10783,0.037175 -0.18136,0.029736 -0.23603,-0.023881 -0.0636,-0.062325 -0.19151,-0.3116419 -0.25992,-0.5065157 l -0.0525,-0.1496141 0.10622,-0.1086293 c 0.2429,-0.2483375 0.39131,-0.3452236 0.6269,-0.4091988 0.11224,-0.030488 0.15557,-0.029745 0.23337,0.00394 0.0836,0.036229 0.1092,0.05909 0.2055,0.1843771 0.1497,0.1948415 0.20359,0.3514055 0.16985,0.4936336 -0.0187,0.078845 -0.0408,0.1205649 -0.0782,0.1469072 -0.0576,0.04068 -0.0559,0.045167 0.0848,0.2210005 l 0.0685,0.085491 0.54937,-0.2986667 c 0.30215,-0.1642521 0.54851,-0.3037584 0.54741,-0.3099957 -0.008,-0.045938 -0.13824,-0.249936 -0.17184,-0.2689576 -0.0229,-0.01303 -0.0947,-0.010402 -0.15934,0.00584 -0.10075,0.025305 -0.12628,0.022334 -0.17825,-0.020754 -0.0704,-0.058432 -0.16769,-0.2385756 -0.26055,-0.4827716 -0.0789,-0.2074824 -0.0758,-0.214876 0.18374,-0.4280862 0.29045,-0.2386615 0.54908,-0.336724 0.71651,-0.2716768 0.0681,0.026458 0.0989,0.054317 0.19914,0.1802026 0.15436,0.1938694 0.20269,0.3168844 0.18243,0.4642417 -0.0125,0.090792 -0.0291,0.1276888 -0.0763,0.1688023 -0.0677,0.059222 -0.0681,0.058248 0.0859,0.2465661 l 0.0831,0.1015704 0.5318,-0.2791221 c 0.29251,-0.1535192 0.53367,-0.2841547 0.53591,-0.2903046 0.006,-0.015648 -0.14783,-0.29577 -0.17964,-0.3276544 -0.0144,-0.014405 -0.0559,-0.020286 -0.0921,-0.013082 -0.18552,0.03679 -0.22624,0.034652 -0.27634,-0.0145 -0.0587,-0.057637 -0.16724,-0.2668952 -0.2587,-0.4991592 l -0.0649,-0.1647272 0.18473,-0.1752214 c 0.19809,-0.1879189 0.34741,-0.2781958 0.56113,-0.3392998 0.12875,-0.036809 0.20387,-0.027435 0.29493,0.036806 0.0852,0.06012 0.25997,0.2982072 0.29462,0.4014652 0.0538,0.160139 0.0216,0.3441215 -0.0703,0.4025496 -0.0499,0.031673 -0.0555,0.017808 0.10348,0.2533782 0.0506,0.074967 0.0953,0.1358619 0.0994,0.1353568 0.004,-5.218e-4 0.14441,-0.085422 0.31195,-0.1886621 0.16755,-0.10325 0.40492,-0.2449841 0.52754,-0.3149762 0.12257,-0.06998 0.22205,-0.1304931 0.22102,-0.1344535 -0.0106,-0.040636 -0.13469,-0.2404023 -0.1702,-0.2739454 -0.0369,-0.034874 -0.0686,-0.037958 -0.16175,-0.01571 -0.19271,0.046036 -0.2452,-0.00707 -0.42346,-0.4284912 -0.11345,-0.2681841 -0.11261,-0.2735687 0.0661,-0.4264064 0.0607,-0.051921 0.14213,-0.1217152 0.18096,-0.1550934 0.14858,-0.127809 0.44665,-0.2341539 0.5748,-0.2050811 0.0895,0.020327 0.19569,0.1155397 0.31018,0.2783942 0.15044,0.2139374 0.16841,0.4205638 0.0476,0.5480945 l -0.0633,0.066785 0.12706,0.1603236 c 0.0699,0.088173 0.13136,0.1600219 0.13665,0.1596491 0.006,-3.929e-4 0.0931,-0.030778 0.19527,-0.067552 0.31188,-0.1123134 0.51073,-0.1480784 0.73094,-0.1314715 0.60707,0.045788 1.11479,0.3181169 1.43314,0.7687053 0.0561,0.079507 0.13135,0.198864 0.16709,0.265242 0.0786,0.1460542 0.20167,0.4913223 0.24333,0.6826807 0.0804,0.3697982 0.0189,0.776234 -0.17282,1.141051 -0.18971,0.3609277 -0.516,0.7837197 -0.71672,0.9285972 -0.41963,0.3029223 -1.01237,0.5035726 -1.42614,0.4827765 -0.12385,-0.00624 -0.35377,-0.058717 -0.60268,-0.137562 -0.3114,-0.098646 -0.54174,-0.049819 -0.77857,0.1650545 -0.15624,0.141716 -0.21758,0.2353476 -0.92188,1.4066711 -0.73097,1.2156706 -1.18817,1.9580586 -1.55963,2.532419 -0.25721,0.397738 -0.2835,0.431733 -0.57363,0.741946 -0.2187,0.233838 -0.32245,0.333109 -0.36964,0.353662 -0.0484,0.02106 -0.12422,0.0141 -0.28866,-0.02643 -0.32751,-0.08071 -0.78252,-0.158535 -1.00807,-0.172427 -0.24609,-0.01515 -0.44591,0.0033 -0.73179,0.06777 -0.42447,0.09564 -0.4994,0.128309 -0.76887,0.335071 -0.13393,0.102751 -0.31248,0.235494 -0.39676,0.294964 -0.1596,0.112595 -0.83448,0.829196 -12.92057,13.719798 -1.03327,1.102049 -3.43694,3.663428 -5.341495,5.691963 -1.904551,2.028528 -3.899248,4.15639 -4.432671,4.728587 -0.53341,0.572195 -1.293995,1.382923 -1.690156,1.801587 l -0.720329,0.761253 0.02213,0.05699 c 0.01217,0.03136 0.01628,0.101549 0.0092,0.155995 -0.07018,0.535029 0.37597,1.387468 1.033769,1.975173 0.775133,0.692519 1.634739,1.000072 2.500991,0.894825 0.223987,-0.02722 0.494346,-0.140344 1.06271,-0.444655 0.320775,-0.171767 0.954341,-0.568275 1.239594,-0.775792 0.350364,-0.254893 0.578159,-0.343558 0.900254,-0.350383 0.371006,-0.0079 0.637575,0.107484 0.899259,0.389127 0.244298,0.262961 0.333147,0.51054 0.341362,0.951276 0.003,0.153316 -0.0095,0.355698 -0.02772,0.449715 -0.07316,0.379918 -0.460827,1.16637 -0.87206,1.7692 -0.196299,0.287754 -0.899664,1.030334 -1.194403,1.260984 -0.59985,0.469427 -0.989304,0.70746 -2.683388,1.640129 -0.10375,0.05713 -0.394614,0.182323 -0.646365,0.27823 -0.698309,0.266017 -1.087643,0.455253 -1.575375,0.765679 -0.786181,0.500393 -1.408347,1.130261 -1.906878,1.930483 -0.344112,0.552349 -0.589634,1.119268 -0.808708,1.867347 -0.07228,0.246831 -0.170808,0.547004 -0.218934,0.667034 -0.114479,0.285496 -0.234413,0.617565 -0.552505,1.529739 -0.508894,1.459344 -0.778331,2.139758 -1.160924,2.931761 -0.702994,1.455246 -1.534391,2.635911 -2.539438,3.606231 -0.687763,0.663992 -1.177762,1.062714 -1.727983,1.406074 -1.023877,0.638915 -1.923527,0.904933 -3.298833,0.975469 -0.5884,0.03017 -0.620257,0.02809 -1.1357,-0.07387 -1.168295,-0.231243 -1.778464,-0.435219 -2.575209,-0.861043 -0.990499,-0.529378 -2.075761,-1.350681 -3.058939,-2.314975 -0.300174,-0.294392 -0.941512,-0.914371 -1.42519,-1.377722 l -0.879427,-0.84244 -0.152379,0.0437 -0.15237,0.04369 -0.0037,0.117609 c -0.0041,0.129617 -0.04089,0.18452 -0.148439,0.221608 -0.122697,0.04232 -0.207244,0.0067 -0.372634,-0.157059 -0.105951,-0.104889 -0.154079,-0.166792 -0.173923,-0.223693 z"
+       id="path3250"
+       sodipodi:nodetypes="csssssssssssssssssssscccsssssscccssssssssssssscccssssssssssssssssssscccsssscccsssscccssssscccsssssssssscccsssscccsssssssssssssssscccssssssssssssssssssssssscccssssssssssssssssssssssssscccccssc"
+       inkscape:connector-curvature="0"
+       transform="matrix(0.7640902,0,0,0.7640902,9.8210596,12.749115)" />
+    <path
+       style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:0.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;filter:url(#filter3945)"
+       d="m 28.831462,11.132354 -1.768065,0 -0.353608,0.882352 0.353608,0.97059 -0.176804,1.058822 -0.884019,-0.529411 -0.707217,-1.323529 -1.502858,-0.352943 -0.618815,-0.617646 -1.326044,-0.617648 -1.502846,-2.4705879 0.08841,-1.1470588 3.712923,-2.8235293 1.768039,0.7941165 0.265213,0.6176482 0,0.7058828 0.442016,0.617646 0.884027,0.2647062 0.618821,-0.5294123 0.08841,-0.6176472 L 27.947423,5.4852939 27.417018,5.22059 27.063396,4.7794122 27.859021,4.4264713 27.682217,3.544118 l 0,-0.5294136 L 27.151812,2.485293 26.886593,1.6911778 25.82577,1.4264715 24.941736,1.25 23.08527,2.5735299 l -4.685339,1.8529414 -1.060836,1.0588226 -0.795618,0.6176483 -0.176818,1.4117635 0.353621,0.7058844 0.884026,2.3823509 1.149226,2.205881 1.237641,1.588237 -1.944851,3.176471 -2.210075,4.764706 -1.326043,2.117644 -2.210065,2.735293 -0.0884,1.235296 -1.149237,1.058826 1.768052,1.588235 -0.44201,1.852938 0.176804,4.147063 0.795618,4.764703 0.795632,4.235295 0.884017,1.411764 1.237649,2.558828 1.944865,2.911764 0.530405,1.852932 0.530424,1.323535 -1.59126,2.205883 -2.828886,1.147054 -0.265208,0.882359 5.392571,-0.176468 -0.795618,1.411757 0.972422,0.882352 2.563683,0.264711 2.033272,-1.76471 0.707229,-2.470579 1.149226,-2.117654 1.414439,-1.235289 0.442015,-1.411767 -1.502834,-0.08823 0.972417,-0.970593 -1.94485,0.617648 1.414445,-1.411764 -1.060837,-0.264704 -0.795632,-0.970586 -1.326043,-2.735297 -3.094088,-2.558825 -0.618821,-0.176471 0.618821,-0.529412 -0.08841,-1.499999 0.618822,-1.323531 -0.530419,0.08824 0.972428,-1.676469 0,-1.676474 0.618814,-0.882352 0,-1.147056 1.326042,-1.764709 0.08842,-1.499995 -0.265221,-1.235296 0.618828,-1.411766 0.707217,-1.147056 0,-0.705882 0.795631,-0.08824 0.707216,-0.705881 0.618828,-1.764708 1.414437,-1.588234 1.679658,-0.617648 1.060823,0.882352 2.56369,0.794121 2.033258,1.058822 0.972423,1.235295 1.679651,0.176469 5.304177,2.294118 2.740477,0.970589 2.210075,1.676471 0.530425,-0.176475 0,-0.529409 -1.237643,-0.970587 2.386868,0.617645 0.265219,-0.441179 -0.530425,-0.529408 0.884032,0 0.0884,-0.529412 -1.591249,-0.35294 1.237628,-0.352944 0,-0.617647 -0.44201,-0.08824 -1.326043,0.08824 -1.060823,-0.441174 -0.707231,-0.352945 1.060839,-0.88235 0.265206,-0.617649 -0.176805,-0.441176 -0.972422,0.176474 -2.033284,1.05882 -0.265193,0.529413 -0.707224,-0.176469 -2.563689,-1.411764 -0.0884,-0.970588 -1.502846,-0.794121 -2.563683,-1.323529 -0.618813,0.441177 0.0884,-0.617646 -1.414445,-1.323531 -1.23764,-0.352941 -1.149238,-1.323528 -0.353602,-0.441179 1.149231,0.794119 -0.176804,-0.882354 0.88402,0.441175 -0.265206,-1.323527 1.23764,1.147061 -0.53041,-0.794119 1.237627,0.52941 -1.060823,-1.499998 0.795618,0.264705 -0.353608,-1.411765 0.618813,0.529411 -0.884021,-1.32353 0.884021,0.264707 -0.795618,-1.058822 1.060825,-0.08824 -1.149228,-0.705882 0.707217,-0.352938 -0.795618,-0.08824 1.060824,-0.970587 -0.972423,0.08824 0.08841,-0.617648 0.08841,-1.764705 -0.53041,1.235294 -0.618828,-1.764707 0.08841,1.411765 -0.353608,0.08824 -0.884033,0 -0.97243,-1.411765 -0.972428,0 -1.149239,-0.970587 -0.530419,0.52941 -1.32603,0.882355 z"
+       id="path1939"
+       inkscape:connector-curvature="0"
+       transform="matrix(0.7640902,0,0,0.7640902,-3.2196331,12.749116)" />
+    <path
+       style="fill:#ffffff;fill-opacity:1;stroke:#000000;stroke-width:0.49999997000000002;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;filter:url(#filter3945)"
+       d="m 365.69974,62.509154 c -1.61846,-0.582376 -1.06171,-2.268311 -1.21867,-3.499849 0.15856,-0.807419 -0.28795,-1.45533 -0.5401,-2.170084 -0.22866,-1.028943 0.11319,-2.088791 0.69816,-2.967703 -0.0395,-2.328322 -0.60809,-4.608435 -0.9964,-6.889479 -0.1979,-1.654772 0.96441,-3.263507 0.2978,-4.882724 -0.51603,-1.525766 -0.50017,-3.106202 -0.47546,-4.687539 0.13139,-2.131436 -0.80356,-4.158033 -0.88273,-6.282147 -1.7386,-0.706529 -1.60946,2.315273 -2.63051,3.139266 -0.6806,2.038484 -2.30763,3.636149 -3.21498,5.565972 -0.37924,1.129734 -0.75429,2.258808 -1.64388,3.14629 -1.38572,1.752472 -1.08736,4.176292 -2.59207,5.885214 -0.84761,1.697052 -2.19622,3.32076 -2.65247,5.114101 -0.25965,0.885722 0.95566,1.565231 0.30325,2.410816 -0.6846,1.313919 -0.3136,2.809685 -0.65687,4.19675 -1.13189,0.0087 -0.80566,1.213982 -1.6339,1.578024 -0.70458,0.335722 -1.71895,0.452447 -2.40993,0.128775 -0.79504,-0.576726 -0.1816,-1.834344 0.19746,-2.568376 0.56924,-0.872482 0.9367,-1.798596 0.90954,-2.829613 0.14277,-0.824553 0.69356,-1.551674 0.65669,-2.427733 -0.16129,-0.969749 0.46408,-1.725679 0.69371,-2.576483 0.54423,-2.547446 1.70284,-4.961753 2.15637,-7.541677 0.85612,-1.741729 2.12849,-3.378705 2.5439,-5.26093 0.16139,-2.32027 1.08374,-4.507277 2.21121,-6.557486 0.30835,-1.423159 1.42494,-2.506076 1.84859,-3.882926 -0.18264,-1.21476 -0.30882,-2.430441 -0.11694,-3.651352 -0.73491,-2.083975 -2.15101,-3.907133 -2.60454,-6.082943 -0.28671,0.773006 -0.13215,2.163626 -0.25366,3.172322 -0.49409,1.995387 -1.17008,3.989918 -1.55207,5.985832 0.60971,0.997212 0.50819,2.150012 0.0369,3.179453 0.269,0.569963 -0.38162,1.680912 -0.49824,0.591207 0.25318,-1.469262 -0.88774,-0.536969 -0.22485,0.348043 0.42511,0.72275 1.8317,1.752203 -0.0192,0.790516 -0.83227,-0.43372 -1.03201,-1.523902 -1.26479,-2.318954 0.3253,-1.104328 0.69034,-2.181597 0.59326,-3.344936 0.10593,-2.032689 -0.0348,-4.095621 0.66185,-6.055933 0.21241,-2.412589 -0.0533,-4.883338 0.18663,-7.289181 0.0878,-1.047183 0.96062,-1.936213 2.12159,-1.835439 1.32409,0.0077 1.36126,-1.367298 0.48382,-0.755757 0.49638,-0.514496 2.00306,-3.4811785 0.91713,-2.8788043 -0.54702,-0.1360312 0.17943,-1.1440836 -0.78541,-1.6403603 1.11316,0.3699805 0.20517,-0.8947475 0.72405,-1.2771041 -0.66255,-1.0963816 3.10062,0.8634603 0.95648,-0.4953924 -1.36526,-1.283582 1.04892,0.3128236 1.89795,0.00962 -0.77368,-0.578186 -2.50134,-2.1009448 -1.76746,-2.1881406 -0.68706,-0.8030169 0.55759,0.095134 0.22019,-0.9039153 0.89444,0.5753709 2.59248,2.0988412 1.1709,0.2296639 -0.88848,-1.24401017 -0.47522,-0.9734679 0.42128,-0.941382 0.46376,1.5082868 1.84548,1.4220628 0.58861,0.00991 0.85205,0.4570506 2.08573,2.7981631 1.38999,0.5985389 0.80967,0.5109306 1.12149,0.2984482 1.53506,0.7170228 0.15385,-0.9130828 0.44661,1.2128379 1.39944,0.061116 0.95757,-0.2552343 1.26303,0.7932157 1.78331,1.3194062 1.00917,0.5739861 1.91905,2.0026793 0.68379,2.795136 -0.66076,0.6449226 -0.015,1.9560656 0.26011,2.339624 -1.34262,-0.011247 0.16844,2.0345032 0.1562,3.1114742 -0.2792,1.421305 -1.16194,-2.225471 -1.66029,-1.356746 0.14765,0.911332 0.04,1.819284 -0.48287,0.768432 -0.83985,1.191669 -0.7189,-1.017622 -0.93909,0.492739 0.36889,0.603671 -1.69906,0.437967 -0.18809,0.970354 1.0264,0.162419 2.71904,0.13162 2.76045,1.411618 0.10689,1.038639 -0.0899,2.030364 -0.54902,2.981644 -0.14943,1.460586 -0.11017,2.98718 0.15838,4.405984 1.34982,1.300869 2.05033,3.009195 2.90028,4.599162 0.52617,1.264777 0.19644,2.704329 0.52329,3.960332 0.54904,0.498437 0.49278,1.512178 0.26577,2.107374 -0.81936,0.880592 -0.17175,2.220658 -0.53983,3.285261 -0.41516,2.677731 -0.59616,5.401362 -0.35245,8.095754 0.53309,2.212307 -0.54605,4.414142 -0.55445,6.637799 0.0904,1.098554 -0.74358,2.268696 0.007,3.256338 -1.0089,1.097804 -0.0971,2.615652 -0.0904,3.884898 0.0835,1.530215 1.52495,2.975272 0.81056,4.50641 -0.61579,0.495258 -1.3199,0.685324 -2.13902,0.253295 z M 355.12861,11.974158 c 0.0158,-0.418853 -0.38046,0.456907 0,0 z"
+       id="path2875"
+       inkscape:connector-curvature="0"
+       transform="matrix(0.7640902,0,0,0.7640902,67.428843,12.749115)" />
+    <g
+       id="g3164"
+       transform="matrix(0,-0.32710617,0.32710617,0,256.81897,151.42198)"
+       style="filter:url(#filter3945)">
+      <path
+         style="fill:#fdfdfd"
+         d="m 279.06793,56.225278 0,-43.942726 70.12137,0 70.12137,0 0,43.942726 0,43.942722 -70.12137,0 -70.12137,0 0,-43.942722 z"
+         id="path3170"
+         inkscape:connector-curvature="0" />
+      <path
+         style="fill:#9e9e9e"
+         d="m 279.06793,56.225278 0,-43.942726 70.12137,0 70.12137,0 0,43.942726 0,43.942722 -70.12137,0 -70.12137,0 0,-43.942722 z m 19.57698,24.951521 0.0599,-18.173122 -2.04664,-0.0036 c -1.12565,-0.0019 -2.17763,-0.08677 -2.33774,-0.188435 -0.22869,-0.145228 -0.30386,-5.493481 -0.35061,-24.947943 l -0.0595,-24.763088 -7.01214,0 -7.01214,0 -0.06,42.890905 c -0.033,23.589998 -0.01,43.023592 0.0521,43.185766 0.0882,0.231926 2.09645,0.281813 9.40949,0.233738 l 9.29738,-0.06112 0.0599,-18.173122 z m 20.10146,0 0.0599,-18.173122 -2.0604,0 c -1.28152,0 -2.20994,-0.110448 -2.45599,-0.292172 -0.36663,-0.270786 -0.39984,-2.097155 -0.45372,-24.951521 l -0.0581,-24.659349 -4.49946,-0.06348 -4.49945,-0.06348 0,24.77304 c 0,24.253159 -0.009,24.77812 -0.45211,25.015004 -0.24866,0.133079 -1.40566,0.241961 -2.57112,0.241961 l -2.119,0 0,18.075731 c 0,9.941653 0.0713,18.14703 0.15844,18.234172 0.0871,0.08714 4.37331,0.13097 9.52482,0.09739 l 9.36637,-0.06105 0.0599,-18.173122 z m 19.86691,-25.013433 0.0591,-43.186559 -6.95433,0.06191 -6.95432,0.06191 -0.0595,24.648739 c -0.0403,16.687292 -0.13809,24.727664 -0.3028,24.893087 -0.1338,0.134392 -1.21143,0.296938 -2.39473,0.361216 l -2.15146,0.116869 -0.0599,17.855232 c -0.0439,13.084208 0.0112,17.940889 0.20615,18.175807 0.21874,0.263563 1.89217,0.309705 9.40942,0.259456 l 9.14337,-0.06112 0.059,-43.186555 z m 20.0424,24.954999 0,-18.231557 -2.33737,-0.116869 -2.33738,-0.116869 -0.11687,-24.776217 -0.11687,-24.776218 -6.9537,-0.06191 -6.95371,-0.06191 0,43.089165 c 0,23.699041 0.0713,43.160478 0.15847,43.247636 0.0872,0.08716 4.32074,0.130985 9.40795,0.09739 l 9.24948,-0.06108 0,-18.231556 z M 378.37939,99.1489 c 0.19203,-0.231389 0.24752,-5.176596 0.20392,-18.173122 l -0.0599,-17.855232 -2.20786,-0.06781 c -1.21433,-0.0373 -2.34503,-0.181652 -2.51269,-0.320791 -0.24709,-0.20507 -0.30482,-4.939873 -0.30482,-25.000578 l 0,-24.747599 -4.43996,0 -4.43995,0 -0.0595,24.834652 -0.0595,24.834652 -2.39581,0.06661 -2.39581,0.06661 0,18.184423 c 0,10.001432 0.0701,18.254545 0.15582,18.340247 0.0857,0.08571 4.22752,0.155826 9.20403,0.155826 7.34383,0 9.09789,-0.05988 9.31203,-0.31789 z m 20.30534,-17.972101 0.0599,-18.173122 -2.0604,0 c -1.28151,0 -2.20994,-0.110448 -2.45599,-0.292172 -0.36663,-0.270786 -0.39984,-2.097155 -0.45371,-24.951521 l -0.0581,-24.659349 -4.61632,-0.06338 -4.61633,-0.06338 0,24.734412 c 0,18.926225 -0.0659,24.800276 -0.28048,25.014897 -0.17794,0.177942 -1.0752,0.280485 -2.45425,0.280485 l -2.17376,0 0,18.075731 c 0,9.941653 0.0713,18.14703 0.15844,18.234172 0.0871,0.08714 4.37331,0.13097 9.52482,0.09739 l 9.36638,-0.06105 0.0599,-18.173122 z m 19.80786,-24.951521 0,-43.124643 -6.89527,0 -6.89527,0 -0.0581,24.659349 c -0.0539,22.854366 -0.0871,24.680735 -0.45372,24.951521 -0.24176,0.178555 -1.15082,0.292172 -2.33769,0.292172 l -1.9421,0 0,18.075731 c 0,9.941653 0.0713,18.147058 0.1585,18.234233 0.0872,0.08717 4.26817,0.131 9.29109,0.09739 l 9.13258,-0.06111 0,-43.124643 z"
+         id="path3168"
+         inkscape:connector-curvature="0" />
+      <path
+         style="fill:#0a0a0a"
+         d="m 279.06793,56.225278 0,-43.942726 70.12137,0 70.12137,0 0,43.942726 0,43.942722 -70.12137,0 -70.12137,0 0,-43.942722 z m 139.77526,-0.0024 0,-43.472892 -7.24587,0 c -3.98523,0 -7.27097,0.02629 -7.30164,0.05843 -0.0307,0.03214 -0.10956,11.207733 -0.17531,24.834653 l -0.11953,24.776217 -2.33738,0.116869 c -1.28556,0.06428 -3.44179,0.06428 -4.79163,0 l -2.45425,-0.116869 -0.11953,-24.776217 c -0.0657,-13.62692 -0.14463,-24.804606 -0.17531,-24.839301 -0.0307,-0.0347 -2.29088,-0.0347 -5.02269,0 l -4.96693,0.06308 -0.0595,24.819151 -0.0595,24.819153 -2.39476,0.111413 c -2.89228,0.134561 -2.36469,0.134561 -5.25698,0 l -2.39475,-0.111413 -0.0595,-24.819153 -0.0595,-24.819151 -4.79163,0 -4.79163,0 -0.0595,24.70177 -0.0595,24.701767 -2.27788,0.118237 c -2.90255,0.150658 -2.58515,0.152981 -5.31648,-0.03889 l -2.33738,-0.164191 -0.0595,-24.715986 -0.0595,-24.715985 -14.84129,0 c -8.16271,0 -14.86638,0.02549 -14.89705,0.05664 -0.0307,0.03115 -0.10956,11.205935 -0.17531,24.832855 l -0.11953,24.776217 -2.33738,0.116869 c -1.28556,0.06428 -3.44179,0.06428 -4.79163,0 l -2.45425,-0.116869 -0.11953,-24.776217 c -0.0657,-13.62692 -0.14464,-24.804648 -0.17531,-24.839395 -0.0307,-0.03475 -2.23829,-0.03475 -4.90583,0 l -4.85006,0.06318 -0.0595,24.648739 c -0.0327,13.556808 -0.14818,24.737411 -0.25656,24.845783 -0.10837,0.108375 -2.28111,0.197044 -4.82831,0.197044 -3.54098,0 -4.67656,-0.0714 -4.82366,-0.303303 -0.10582,-0.166817 -0.19401,-11.373715 -0.19598,-24.904218 l -0.004,-24.600914 -7.36274,0 -7.36274,0 0,43.472237 0,43.472235 69.65389,7.01e-4 69.65389,7.02e-4 0,-43.47289 z"
+         id="path3166"
+         inkscape:connector-curvature="0" />
+    </g>
+  </g>
+</svg>
diff --git a/data/themes/default/intro_bg.svg b/data/themes/default/intro_bg.svg
new file mode 100644 (file)
index 0000000..6f16c68
--- /dev/null
@@ -0,0 +1,595 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Sodipodi ("http://www.sodipodi.com/") -->
+
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://creativecommons.org/ns#"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:xlink="http://www.w3.org/1999/xlink"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   version="1.0"
+   x="0"
+   y="0"
+   width="1000"
+   height="800"
+   id="svg559"
+   sodipodi:version="0.32"
+   inkscape:version="0.48.1 r9760"
+   sodipodi:docname="intro_bg.svg"
+   inkscape:output_extension="org.inkscape.output.svg.inkscape">
+  <metadata
+     id="metadata35">
+    <rdf:RDF>
+      <cc:Work
+         rdf:about="">
+        <dc:format>image/svg+xml</dc:format>
+        <dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+        <dc:title />
+      </cc:Work>
+    </rdf:RDF>
+  </metadata>
+  <sodipodi:namedview
+     inkscape:window-height="725"
+     inkscape:window-width="1280"
+     inkscape:pageshadow="2"
+     inkscape:pageopacity="0.0"
+     guidetolerance="10.0"
+     gridtolerance="10.0"
+     objecttolerance="10.0"
+     borderopacity="1.0"
+     bordercolor="#666666"
+     pagecolor="#ffffff"
+     id="base"
+     inkscape:zoom="0.5"
+     inkscape:cx="619.55102"
+     inkscape:cy="354.60886"
+     inkscape:window-x="0"
+     inkscape:window-y="25"
+     inkscape:current-layer="svg559"
+     showgrid="false"
+     showguides="true"
+     inkscape:guide-bbox="true"
+     inkscape:window-maximized="1"
+     inkscape:snap-grids="true" />
+  <defs
+     id="defs561">
+    <linearGradient
+       id="linearGradient5448">
+      <stop
+         style="stop-color:#beb7c8;stop-opacity:1;"
+         offset="0"
+         id="stop5450" />
+      <stop
+         style="stop-color:#beb7c8;stop-opacity:0;"
+         offset="1"
+         id="stop5452" />
+    </linearGradient>
+    <linearGradient
+       id="linearGradient4557">
+      <stop
+         style="stop-color:#ffffff;stop-opacity:1;"
+         offset="0"
+         id="stop4559" />
+      <stop
+         style="stop-color:#0300da;stop-opacity:1;"
+         offset="1"
+         id="stop4561" />
+    </linearGradient>
+    <linearGradient
+       id="linearGradient3751"
+       inkscape:collect="always">
+      <stop
+         id="stop3753"
+         offset="0"
+         style="stop-color:black;stop-opacity:1;" />
+      <stop
+         id="stop3755"
+         offset="1"
+         style="stop-color:black;stop-opacity:0;" />
+    </linearGradient>
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient3751"
+       id="linearGradient2518"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(0.9434139,0,0,0.9434139,62.279262,39.359798)"
+       x1="665.12128"
+       y1="684.16162"
+       x2="381.28015"
+       y2="449.80624" />
+    <linearGradient
+       id="linearGradient3945">
+      <stop
+         style="stop-color:#ffffff;stop-opacity:1;"
+         offset="0"
+         id="stop3947" />
+      <stop
+         style="stop-color:#ffffff;stop-opacity:0;"
+         offset="1"
+         id="stop3949" />
+    </linearGradient>
+    <inkscape:perspective
+       sodipodi:type="inkscape:persp3d"
+       inkscape:vp_x="0 : 400 : 1"
+       inkscape:vp_y="0 : 1000 : 0"
+       inkscape:vp_z="1000 : 400 : 1"
+       inkscape:persp3d-origin="500 : 266.66667 : 1"
+       id="perspective62" />
+    <linearGradient
+       id="linearGradient6053">
+      <stop
+         style="stop-color:#000000;stop-opacity:1;"
+         offset="0"
+         id="stop6055" />
+      <stop
+         style="stop-color:#5f5f5f;stop-opacity:1;"
+         offset="1"
+         id="stop6057" />
+    </linearGradient>
+    <linearGradient
+       id="linearGradient6499"
+       inkscape:collect="always">
+      <stop
+         id="stop6501"
+         offset="0"
+         style="stop-color:white;stop-opacity:1;" />
+      <stop
+         id="stop6503"
+         offset="1"
+         style="stop-color:white;stop-opacity:0;" />
+    </linearGradient>
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient6499"
+       id="linearGradient3245"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(0.8327515,0,0,-0.6476426,-48.09403,12.672202)"
+       x1="311.95688"
+       y1="-116.67703"
+       x2="311.95688"
+       y2="-276.41519" />
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient6499"
+       id="linearGradient4108"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(1.3544445,0,0,1.7332213,31.621862,51.58815)"
+       x1="44.868057"
+       y1="260.4765"
+       x2="358.07056"
+       y2="260.4765" />
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient6499"
+       id="linearGradient4121"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(1.2483528,0,0,1.0242885,40.754503,133.62899)"
+       x1="44.868057"
+       y1="260.4765"
+       x2="358.07056"
+       y2="260.4765" />
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient6499"
+       id="linearGradient4127"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(1.2483528,0,0,1.0242885,40.754503,340.11416)"
+       x1="44.868057"
+       y1="260.4765"
+       x2="358.07056"
+       y2="260.4765" />
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient6499"
+       id="linearGradient4133"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(1.2483528,0,0,1.0242885,39.887975,233.1463)"
+       x1="44.868057"
+       y1="260.4765"
+       x2="358.07056"
+       y2="260.4765" />
+    <inkscape:perspective
+       id="perspective2886"
+       inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
+       inkscape:vp_z="1 : 0.5 : 1"
+       inkscape:vp_y="0 : 1000 : 0"
+       inkscape:vp_x="0 : 0.5 : 1"
+       sodipodi:type="inkscape:persp3d" />
+    <filter
+       color-interpolation-filters="sRGB"
+       inkscape:collect="always"
+       id="filter3869-9"
+       x="-0.019231318"
+       width="1.0384626"
+       y="-0.12226724"
+       height="1.2445345">
+      <feGaussianBlur
+         inkscape:collect="always"
+         stdDeviation="3.4581674"
+         id="feGaussianBlur3871-2" />
+    </filter>
+    <inkscape:perspective
+       id="perspective2849"
+       inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
+       inkscape:vp_z="1 : 0.5 : 1"
+       inkscape:vp_y="0 : 1000 : 0"
+       inkscape:vp_x="0 : 0.5 : 1"
+       sodipodi:type="inkscape:persp3d" />
+    <inkscape:perspective
+       id="perspective3625"
+       inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
+       inkscape:vp_z="1 : 0.5 : 1"
+       inkscape:vp_y="0 : 1000 : 0"
+       inkscape:vp_x="0 : 0.5 : 1"
+       sodipodi:type="inkscape:persp3d" />
+    <inkscape:perspective
+       id="perspective3647"
+       inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
+       inkscape:vp_z="1 : 0.5 : 1"
+       inkscape:vp_y="0 : 1000 : 0"
+       inkscape:vp_x="0 : 0.5 : 1"
+       sodipodi:type="inkscape:persp3d" />
+    <inkscape:perspective
+       id="perspective3669"
+       inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
+       inkscape:vp_z="1 : 0.5 : 1"
+       inkscape:vp_y="0 : 1000 : 0"
+       inkscape:vp_x="0 : 0.5 : 1"
+       sodipodi:type="inkscape:persp3d" />
+    <inkscape:perspective
+       id="perspective3691"
+       inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
+       inkscape:vp_z="1 : 0.5 : 1"
+       inkscape:vp_y="0 : 1000 : 0"
+       inkscape:vp_x="0 : 0.5 : 1"
+       sodipodi:type="inkscape:persp3d" />
+    <inkscape:perspective
+       id="perspective3713"
+       inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
+       inkscape:vp_z="1 : 0.5 : 1"
+       inkscape:vp_y="0 : 1000 : 0"
+       inkscape:vp_x="0 : 0.5 : 1"
+       sodipodi:type="inkscape:persp3d" />
+    <inkscape:perspective
+       id="perspective3713-1"
+       inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
+       inkscape:vp_z="1 : 0.5 : 1"
+       inkscape:vp_y="0 : 1000 : 0"
+       inkscape:vp_x="0 : 0.5 : 1"
+       sodipodi:type="inkscape:persp3d" />
+    <inkscape:perspective
+       id="perspective3713-8"
+       inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
+       inkscape:vp_z="1 : 0.5 : 1"
+       inkscape:vp_y="0 : 1000 : 0"
+       inkscape:vp_x="0 : 0.5 : 1"
+       sodipodi:type="inkscape:persp3d" />
+    <inkscape:perspective
+       id="perspective3713-15"
+       inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
+       inkscape:vp_z="1 : 0.5 : 1"
+       inkscape:vp_y="0 : 1000 : 0"
+       inkscape:vp_x="0 : 0.5 : 1"
+       sodipodi:type="inkscape:persp3d" />
+    <inkscape:perspective
+       id="perspective3713-9"
+       inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
+       inkscape:vp_z="1 : 0.5 : 1"
+       inkscape:vp_y="0 : 1000 : 0"
+       inkscape:vp_x="0 : 0.5 : 1"
+       sodipodi:type="inkscape:persp3d" />
+    <inkscape:perspective
+       id="perspective3713-5"
+       inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
+       inkscape:vp_z="1 : 0.5 : 1"
+       inkscape:vp_y="0 : 1000 : 0"
+       inkscape:vp_x="0 : 0.5 : 1"
+       sodipodi:type="inkscape:persp3d" />
+    <inkscape:perspective
+       id="perspective3713-99"
+       inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
+       inkscape:vp_z="1 : 0.5 : 1"
+       inkscape:vp_y="0 : 1000 : 0"
+       inkscape:vp_x="0 : 0.5 : 1"
+       sodipodi:type="inkscape:persp3d" />
+    <inkscape:perspective
+       id="perspective3713-93"
+       inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
+       inkscape:vp_z="1 : 0.5 : 1"
+       inkscape:vp_y="0 : 1000 : 0"
+       inkscape:vp_x="0 : 0.5 : 1"
+       sodipodi:type="inkscape:persp3d" />
+    <inkscape:perspective
+       id="perspective3713-7"
+       inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
+       inkscape:vp_z="1 : 0.5 : 1"
+       inkscape:vp_y="0 : 1000 : 0"
+       inkscape:vp_x="0 : 0.5 : 1"
+       sodipodi:type="inkscape:persp3d" />
+    <inkscape:perspective
+       id="perspective3816"
+       inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
+       inkscape:vp_z="1 : 0.5 : 1"
+       inkscape:vp_y="0 : 1000 : 0"
+       inkscape:vp_x="0 : 0.5 : 1"
+       sodipodi:type="inkscape:persp3d" />
+    <inkscape:perspective
+       id="perspective3816-4"
+       inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
+       inkscape:vp_z="1 : 0.5 : 1"
+       inkscape:vp_y="0 : 1000 : 0"
+       inkscape:vp_x="0 : 0.5 : 1"
+       sodipodi:type="inkscape:persp3d" />
+    <inkscape:perspective
+       id="perspective3816-1"
+       inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
+       inkscape:vp_z="1 : 0.5 : 1"
+       inkscape:vp_y="0 : 1000 : 0"
+       inkscape:vp_x="0 : 0.5 : 1"
+       sodipodi:type="inkscape:persp3d" />
+    <inkscape:perspective
+       id="perspective3816-3"
+       inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
+       inkscape:vp_z="1 : 0.5 : 1"
+       inkscape:vp_y="0 : 1000 : 0"
+       inkscape:vp_x="0 : 0.5 : 1"
+       sodipodi:type="inkscape:persp3d" />
+    <inkscape:perspective
+       id="perspective3816-8"
+       inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
+       inkscape:vp_z="1 : 0.5 : 1"
+       inkscape:vp_y="0 : 1000 : 0"
+       inkscape:vp_x="0 : 0.5 : 1"
+       sodipodi:type="inkscape:persp3d" />
+    <inkscape:perspective
+       id="perspective3816-6"
+       inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
+       inkscape:vp_z="1 : 0.5 : 1"
+       inkscape:vp_y="0 : 1000 : 0"
+       inkscape:vp_x="0 : 0.5 : 1"
+       sodipodi:type="inkscape:persp3d" />
+    <inkscape:perspective
+       id="perspective3816-17"
+       inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
+       inkscape:vp_z="1 : 0.5 : 1"
+       inkscape:vp_y="0 : 1000 : 0"
+       inkscape:vp_x="0 : 0.5 : 1"
+       sodipodi:type="inkscape:persp3d" />
+    <inkscape:perspective
+       id="perspective3816-85"
+       inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
+       inkscape:vp_z="1 : 0.5 : 1"
+       inkscape:vp_y="0 : 1000 : 0"
+       inkscape:vp_x="0 : 0.5 : 1"
+       sodipodi:type="inkscape:persp3d" />
+    <inkscape:perspective
+       id="perspective3816-66"
+       inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
+       inkscape:vp_z="1 : 0.5 : 1"
+       inkscape:vp_y="0 : 1000 : 0"
+       inkscape:vp_x="0 : 0.5 : 1"
+       sodipodi:type="inkscape:persp3d" />
+    <inkscape:perspective
+       id="perspective3816-49"
+       inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
+       inkscape:vp_z="1 : 0.5 : 1"
+       inkscape:vp_y="0 : 1000 : 0"
+       inkscape:vp_x="0 : 0.5 : 1"
+       sodipodi:type="inkscape:persp3d" />
+    <inkscape:perspective
+       id="perspective3816-852"
+       inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
+       inkscape:vp_z="1 : 0.5 : 1"
+       inkscape:vp_y="0 : 1000 : 0"
+       inkscape:vp_x="0 : 0.5 : 1"
+       sodipodi:type="inkscape:persp3d" />
+    <inkscape:perspective
+       id="perspective3816-7"
+       inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
+       inkscape:vp_z="1 : 0.5 : 1"
+       inkscape:vp_y="0 : 1000 : 0"
+       inkscape:vp_x="0 : 0.5 : 1"
+       sodipodi:type="inkscape:persp3d" />
+    <inkscape:perspective
+       id="perspective3816-46"
+       inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
+       inkscape:vp_z="1 : 0.5 : 1"
+       inkscape:vp_y="0 : 1000 : 0"
+       inkscape:vp_x="0 : 0.5 : 1"
+       sodipodi:type="inkscape:persp3d" />
+    <inkscape:perspective
+       id="perspective3816-63"
+       inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
+       inkscape:vp_z="1 : 0.5 : 1"
+       inkscape:vp_y="0 : 1000 : 0"
+       inkscape:vp_x="0 : 0.5 : 1"
+       sodipodi:type="inkscape:persp3d" />
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient5448"
+       id="linearGradient5454"
+       x1="0"
+       y1="768"
+       x2="0"
+       y2="713.1153"
+       gradientUnits="userSpaceOnUse" />
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient5448"
+       id="linearGradient5460"
+       gradientUnits="userSpaceOnUse"
+       x1="0"
+       y1="768"
+       x2="0"
+       y2="713.1153"
+       gradientTransform="translate(0,-2)" />
+    <inkscape:perspective
+       id="perspective3645"
+       inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
+       inkscape:vp_z="1 : 0.5 : 1"
+       inkscape:vp_y="0 : 1000 : 0"
+       inkscape:vp_x="0 : 0.5 : 1"
+       sodipodi:type="inkscape:persp3d" />
+    <radialGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient3629"
+       id="radialGradient3635"
+       cx="727.25122"
+       cy="757.60583"
+       fx="727.25122"
+       fy="757.60583"
+       r="500"
+       gradientTransform="matrix(0.43355171,-0.84504566,1.805509,0.92631863,-955.91397,614.06396)"
+       gradientUnits="userSpaceOnUse" />
+    <linearGradient
+       id="linearGradient3629">
+      <stop
+         style="stop-color:#00cbff;stop-opacity:0;"
+         offset="0"
+         id="stop3631" />
+      <stop
+         style="stop-color:#000000;stop-opacity:1;"
+         offset="1"
+         id="stop3633" />
+    </linearGradient>
+    <radialGradient
+       r="500"
+       fy="757.60583"
+       fx="727.25122"
+       cy="757.60583"
+       cx="727.25122"
+       gradientTransform="matrix(0.43355171,-0.84504566,1.805509,0.92631863,-980.8803,538.04792)"
+       gradientUnits="userSpaceOnUse"
+       id="radialGradient3654"
+       xlink:href="#linearGradient3629"
+       inkscape:collect="always" />
+    <inkscape:perspective
+       id="perspective3703"
+       inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
+       inkscape:vp_z="1 : 0.5 : 1"
+       inkscape:vp_y="0 : 1000 : 0"
+       inkscape:vp_x="0 : 0.5 : 1"
+       sodipodi:type="inkscape:persp3d" />
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient5448-8"
+       id="linearGradient5460-9"
+       gradientUnits="userSpaceOnUse"
+       x1="0"
+       y1="768"
+       x2="0"
+       y2="713.1153"
+       gradientTransform="translate(0,-2)" />
+    <linearGradient
+       id="linearGradient5448-8">
+      <stop
+         style="stop-color:#beb7c8;stop-opacity:1;"
+         offset="0"
+         id="stop5450-7" />
+      <stop
+         style="stop-color:#beb7c8;stop-opacity:0;"
+         offset="1"
+         id="stop5452-5" />
+    </linearGradient>
+    <inkscape:perspective
+       id="perspective3741"
+       inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
+       inkscape:vp_z="1 : 0.5 : 1"
+       inkscape:vp_y="0 : 1000 : 0"
+       inkscape:vp_x="0 : 0.5 : 1"
+       sodipodi:type="inkscape:persp3d" />
+    <radialGradient
+       r="500"
+       fy="757.60583"
+       fx="727.25122"
+       cy="757.60583"
+       cx="727.25122"
+       gradientTransform="matrix(0.43355171,-0.84504566,1.805509,0.92631863,-980.8803,538.04792)"
+       gradientUnits="userSpaceOnUse"
+       id="radialGradient3654-9"
+       xlink:href="#linearGradient3629-3"
+       inkscape:collect="always" />
+    <linearGradient
+       id="linearGradient3629-3">
+      <stop
+         style="stop-color:#00cbff;stop-opacity:0;"
+         offset="0"
+         id="stop3631-1" />
+      <stop
+         style="stop-color:#000000;stop-opacity:1;"
+         offset="1"
+         id="stop3633-4" />
+    </linearGradient>
+    <radialGradient
+       r="500"
+       fy="757.60583"
+       fx="727.25122"
+       cy="757.60583"
+       cx="727.25122"
+       gradientTransform="matrix(0.43355171,-0.84504566,1.805509,0.92631863,-980.8803,538.04792)"
+       gradientUnits="userSpaceOnUse"
+       id="radialGradient3750"
+       xlink:href="#linearGradient3629-3"
+       inkscape:collect="always" />
+    <inkscape:perspective
+       id="perspective2902"
+       inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
+       inkscape:vp_z="1 : 0.5 : 1"
+       inkscape:vp_y="0 : 1000 : 0"
+       inkscape:vp_x="0 : 0.5 : 1"
+       sodipodi:type="inkscape:persp3d" />
+    <radialGradient
+       r="500"
+       fy="757.60583"
+       fx="727.25122"
+       cy="757.60583"
+       cx="727.25122"
+       gradientTransform="matrix(0.43355171,-0.84504566,1.805509,0.92631863,-980.8803,538.04792)"
+       gradientUnits="userSpaceOnUse"
+       id="radialGradient3750-6"
+       xlink:href="#linearGradient3629-3-3"
+       inkscape:collect="always" />
+    <linearGradient
+       id="linearGradient3629-3-3">
+      <stop
+         style="stop-color:#00cbff;stop-opacity:0;"
+         offset="0"
+         id="stop3631-1-8" />
+      <stop
+         style="stop-color:#000000;stop-opacity:1;"
+         offset="1"
+         id="stop3633-4-5" />
+    </linearGradient>
+  </defs>
+  <rect
+     style="fill:#ffffff;fill-opacity:1;stroke:none"
+     id="rect2855-6"
+     width="1000"
+     height="800"
+     x="0"
+     y="0" />
+  <rect
+     style="fill:url(#radialGradient3750);fill-opacity:1;stroke:none"
+     id="rect2855"
+     width="1000"
+     height="800"
+     x="0"
+     y="0" />
+  <text
+     xml:space="preserve"
+     style="font-size:24.89476013px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Goblin"
+     x="266.96185"
+     y="759.88806"
+     id="text2508"><tspan
+       sodipodi:role="line"
+       id="tspan2510"
+       x="266.96185"
+       y="759.88806" /></text>
+  <g
+     id="g3952"
+     transform="translate(-2.6135359,3.2274215)" />
+</svg>
diff --git a/data/themes/default/intro_configure.svg b/data/themes/default/intro_configure.svg
new file mode 100644 (file)
index 0000000..3e46ac7
--- /dev/null
@@ -0,0 +1,119 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://creativecommons.org/ns#"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:xlink="http://www.w3.org/1999/xlink"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   width="1000"
+   height="800"
+   id="svg4003"
+   version="1.1"
+   inkscape:version="0.46+devel"
+   sodipodi:docname="intro_configure.svg">
+  <defs
+     id="defs4005">
+    <inkscape:perspective
+       sodipodi:type="inkscape:persp3d"
+       inkscape:vp_x="0 : 526.18109 : 1"
+       inkscape:vp_y="0 : 1000 : 0"
+       inkscape:vp_z="744.09448 : 526.18109 : 1"
+       inkscape:persp3d-origin="372.04724 : 350.78739 : 1"
+       id="perspective4011" />
+    <inkscape:perspective
+       id="perspective3998"
+       inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
+       inkscape:vp_z="1 : 0.5 : 1"
+       inkscape:vp_y="0 : 1000 : 0"
+       inkscape:vp_x="0 : 0.5 : 1"
+       sodipodi:type="inkscape:persp3d" />
+    <inkscape:perspective
+       id="perspective4615"
+       inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
+       inkscape:vp_z="1 : 0.5 : 1"
+       inkscape:vp_y="0 : 1000 : 0"
+       inkscape:vp_x="0 : 0.5 : 1"
+       sodipodi:type="inkscape:persp3d" />
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient4040"
+       id="linearGradient4038"
+       x1="-568.24231"
+       y1="-820.92566"
+       x2="-733.16718"
+       y2="-401.87253"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(-0.25866863,0.70093291,-0.70093291,-0.25866863,-99.586642,1046.1972)" />
+    <linearGradient
+       id="linearGradient4040">
+      <stop
+         style="stop-color:black;stop-opacity:1;"
+         offset="0"
+         id="stop4042" />
+      <stop
+         style="stop-color:black;stop-opacity:0"
+         offset="1"
+         id="stop4044" />
+    </linearGradient>
+    <filter
+       inkscape:collect="always"
+       id="filter4644">
+      <feGaussianBlur
+         inkscape:collect="always"
+         stdDeviation="9.018696"
+         id="feGaussianBlur4646" />
+    </filter>
+  </defs>
+  <sodipodi:namedview
+     id="base"
+     pagecolor="#ffffff"
+     bordercolor="#666666"
+     borderopacity="1.0"
+     inkscape:pageopacity="0.0"
+     inkscape:pageshadow="2"
+     inkscape:zoom="0.98994949"
+     inkscape:cx="618.06315"
+     inkscape:cy="414.34766"
+     inkscape:document-units="px"
+     inkscape:current-layer="layer1"
+     showgrid="false"
+     inkscape:window-width="1280"
+     inkscape:window-height="949"
+     inkscape:window-x="0"
+     inkscape:window-y="25"
+     inkscape:window-maximized="1" />
+  <metadata
+     id="metadata4008">
+    <rdf:RDF>
+      <cc:Work
+         rdf:about="">
+        <dc:format>image/svg+xml</dc:format>
+        <dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+      </cc:Work>
+    </rdf:RDF>
+  </metadata>
+  <g
+     inkscape:label="Capa 1"
+     inkscape:groupmode="layer"
+     id="layer1"
+     transform="translate(0,-252.36218)">
+    <path
+       style="fill:#ffffff;fill-opacity:1;stroke:none;display:inline;filter:url(#filter4644)"
+       d="m 811.6875,413.46875 c -27.46192,5.21328 -46.93761,30.03842 -53.9375,55.96875 -6.90588,21.48846 -0.51485,46.31451 15.375,62.21875 -26.28064,72.26371 -51.96523,144.76771 -78.28125,217.03125 -23.89245,0.46637 -48.16793,16.40974 -53.59375,40.40625 -8.65459,25.06212 -6.82152,55.09685 9.90625,76.4375 5.58302,9.72592 17.36083,19.11089 29.0625,14.3125 14.14317,-5.58565 18.24671,-22.69973 17.875,-36.53125 0.35737,-6.44523 -1.19385,-16.83366 6.78125,-19.125 6.1441,-1.37648 14.18585,4.31547 11,10.9375 -3.88135,14.9025 -11.71097,32.05728 -3.3125,46.84375 6.26579,11.03387 22.80504,11.59401 31.5,3.25 27.79889,-16.23545 45.98191,-51.31248 36.125,-83.21875 -3.01361,-10.41319 -8.23834,-19.9738 -15.09375,-28.28125 27.4422,-72.9855 54.17157,-146.59024 82.0625,-219.1875 32.53432,-1.5794 58.65719,-33.16283 56.8125,-65.21875 0.77137,-25.31142 -10.15322,-52.41394 -32.3125,-65.78125 -12.41175,-4.35717 -24.46734,6.80539 -27.75,18.25 -4.6139,11.9195 -2.38946,25.31375 -6.375,37.25 -4.62679,1.06131 -11.27926,0.5028 -14.25,-3 2.37096,-11.49823 3.92988,-23.2497 5.96875,-34.8125 1.20905,-8.89865 0.87375,-20.14033 -7.875,-25.09375 -2.86795,-1.84539 -6.24444,-2.8619 -9.6875,-2.65625 z"
+       id="path3967" />
+    <path
+       style="fill:#000000;fill-opacity:1;display:inline"
+       d="m 814.7439,432.08013 c -24.39035,6.85812 -39.65456,31.17671 -42.03123,55.40625 -1.77359,17.31508 7.49105,32.27997 20.96877,41.87501 l -24.81381,67.21818 -0.0626,-0.0311 -63.84383,172.93744 c -16.83556,-1.25741 -35.39634,0.17572 -42.09375,17.65625 -11.04554,17.23061 -15.23658,39.29813 -6.15629,58.31249 3.05646,8.66604 22.77117,39.04543 23.56251,15.46875 4.00621,-15.09279 1.46393,-33.91034 12.09371,-46.03126 14.49469,-6.43113 45.7708,-0.52893 40.21882,20.75002 -1.54954,14.46272 -7.66992,29.33213 -6.62503,43.46872 24.39036,-6.85808 39.62337,-31.17668 42.00002,-55.40622 1.7731,-17.31029 -7.4972,-32.24847 -20.96878,-41.84376 l 24.81384,-67.21825 0.0936,0.0314 63.81235,-172.96868 c 16.83907,1.25914 35.39453,-0.1711 42.09375,-17.65632 11.04553,-17.23061 15.26778,-39.2981 6.18745,-58.31247 -3.05644,-8.66609 -22.77114,-39.01421 -23.56248,-15.43754 -4.00621,15.09279 -1.49519,33.87914 -12.12497,46.00007 -14.49461,6.43112 -45.73947,0.56015 -40.1875,-20.71878 1.54955,-14.46274 7.66984,-29.36342 6.62503,-43.50002 z"
+       id="rect2874-8-7" />
+    <path
+       style="opacity:0.228;fill:url(#linearGradient4038);fill-opacity:1;display:inline"
+       d="m 281.60683,700.27474 c -15.96178,2.7935 -1.33889,12.69911 26.06207,22.56844 19.50635,7.05289 47.16245,13.14847 72.43229,17.05677 l 57.79595,27.37974 -0.10009,-0.0126 148.69291,70.44196 c -18.38113,-0.51221 -35.18045,0.0716 -20.39468,7.19184 10.13045,7.01846 33.06004,16.00716 65.50863,23.7522 13.70684,3.5299 70.75718,15.90419 42.57314,6.30079 -14.54254,-6.14767 -40.21103,-13.81252 -44.47768,-18.74971 6.59098,-2.61955 45.12066,-0.21545 65.72019,8.45204 16.22485,5.89105 28.3786,11.94777 46.79707,17.70597 15.96194,-2.7935 1.30795,-12.6991 -26.09314,-22.56845 -19.50076,-7.05091 -47.12982,-13.13561 -72.39387,-17.04405 l -57.79595,-27.37974 0.13232,0.0128 -148.76275,-70.45469 c 18.38654,0.51289 35.18422,-0.0697 20.3946,-7.19185 -10.1306,-7.01849 -33.02889,-16.00717 -65.47727,-23.75216 -13.70698,-3.52995 -70.71898,-15.89154 -42.53496,-6.28813 14.54238,6.14766 40.14141,13.79982 44.40807,18.737 -6.59083,2.61959 -45.05097,0.22818 -65.65044,-8.43929 -16.22485,-5.89104 -28.41712,-11.96047 -46.83567,-17.7187 z"
+       id="rect2874-8-7-4" />
+  </g>
+</svg>
diff --git a/data/themes/default/intro_practice.svg b/data/themes/default/intro_practice.svg
new file mode 100644 (file)
index 0000000..add4b50
--- /dev/null
@@ -0,0 +1,308 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Sodipodi ("http://www.sodipodi.com/") -->
+
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://creativecommons.org/ns#"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:xlink="http://www.w3.org/1999/xlink"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   version="1.0"
+   x="0"
+   y="0"
+   width="1000"
+   height="800"
+   id="svg559"
+   sodipodi:version="0.32"
+   inkscape:version="0.47pre4 r22446"
+   sodipodi:docname="intro_practice.svg"
+   inkscape:output_extension="org.inkscape.output.svg.inkscape">
+  <metadata
+     id="metadata35">
+    <rdf:RDF>
+      <cc:Work
+         rdf:about="">
+        <dc:format>image/svg+xml</dc:format>
+        <dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+        <dc:title />
+      </cc:Work>
+    </rdf:RDF>
+  </metadata>
+  <sodipodi:namedview
+     inkscape:window-height="726"
+     inkscape:window-width="1280"
+     inkscape:pageshadow="2"
+     inkscape:pageopacity="0.0"
+     guidetolerance="10.0"
+     gridtolerance="10.0"
+     objecttolerance="10.0"
+     borderopacity="1.0"
+     bordercolor="#666666"
+     pagecolor="#ffffff"
+     id="base"
+     inkscape:zoom="0.61522534"
+     inkscape:cx="615.71024"
+     inkscape:cy="405.75084"
+     inkscape:window-x="0"
+     inkscape:window-y="25"
+     inkscape:current-layer="svg559"
+     showgrid="false"
+     showguides="true"
+     inkscape:guide-bbox="true"
+     inkscape:window-maximized="1" />
+  <defs
+     id="defs561">
+    <linearGradient
+       inkscape:collect="always"
+       id="linearGradient3694">
+      <stop
+         style="stop-color:black;stop-opacity:0.227"
+         offset="0"
+         id="stop3696" />
+      <stop
+         style="stop-color:black;stop-opacity:0;"
+         offset="1"
+         id="stop3698" />
+    </linearGradient>
+    <linearGradient
+       id="linearGradient4557">
+      <stop
+         style="stop-color:#ffffff;stop-opacity:1;"
+         offset="0"
+         id="stop4559" />
+      <stop
+         style="stop-color:#0300da;stop-opacity:1;"
+         offset="1"
+         id="stop4561" />
+    </linearGradient>
+    <linearGradient
+       id="linearGradient3945">
+      <stop
+         style="stop-color:#ffffff;stop-opacity:1;"
+         offset="0"
+         id="stop3947" />
+      <stop
+         style="stop-color:#ffffff;stop-opacity:0;"
+         offset="1"
+         id="stop3949" />
+    </linearGradient>
+    <inkscape:perspective
+       sodipodi:type="inkscape:persp3d"
+       inkscape:vp_x="0 : 400 : 1"
+       inkscape:vp_y="0 : 1000 : 0"
+       inkscape:vp_z="1000 : 400 : 1"
+       inkscape:persp3d-origin="500 : 266.66667 : 1"
+       id="perspective62" />
+    <linearGradient
+       id="linearGradient6053">
+      <stop
+         style="stop-color:#000000;stop-opacity:1;"
+         offset="0"
+         id="stop6055" />
+      <stop
+         style="stop-color:#5f5f5f;stop-opacity:1;"
+         offset="1"
+         id="stop6057" />
+    </linearGradient>
+    <linearGradient
+       id="linearGradient6499"
+       inkscape:collect="always">
+      <stop
+         id="stop6501"
+         offset="0"
+         style="stop-color:white;stop-opacity:1;" />
+      <stop
+         id="stop6503"
+         offset="1"
+         style="stop-color:white;stop-opacity:0;" />
+    </linearGradient>
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient6499"
+       id="linearGradient3245"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(0.8327515,0,0,-0.6476426,-48.09403,12.672202)"
+       x1="311.95688"
+       y1="-116.67703"
+       x2="311.95688"
+       y2="-276.41519" />
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient6499"
+       id="linearGradient4108"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(1.3544445,0,0,1.7332213,31.621862,51.58815)"
+       x1="44.868057"
+       y1="260.4765"
+       x2="358.07056"
+       y2="260.4765" />
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient6499"
+       id="linearGradient4121"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(1.2483528,0,0,1.0242885,40.754503,133.62899)"
+       x1="44.868057"
+       y1="260.4765"
+       x2="358.07056"
+       y2="260.4765" />
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient6499"
+       id="linearGradient4127"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(1.2483528,0,0,1.0242885,40.754503,340.11416)"
+       x1="44.868057"
+       y1="260.4765"
+       x2="358.07056"
+       y2="260.4765" />
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient6499"
+       id="linearGradient4133"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(1.2483528,0,0,1.0242885,39.887975,233.1463)"
+       x1="44.868057"
+       y1="260.4765"
+       x2="358.07056"
+       y2="260.4765" />
+    <inkscape:perspective
+       id="perspective2871"
+       inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
+       inkscape:vp_z="1 : 0.5 : 1"
+       inkscape:vp_y="0 : 1000 : 0"
+       inkscape:vp_x="0 : 0.5 : 1"
+       sodipodi:type="inkscape:persp3d" />
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient3751"
+       id="linearGradient2518"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(0.9434139,0,0,0.9434139,62.279262,39.359798)"
+       x1="665.12128"
+       y1="684.16162"
+       x2="381.28015"
+       y2="449.80624" />
+    <linearGradient
+       id="linearGradient3751"
+       inkscape:collect="always">
+      <stop
+         id="stop3753"
+         offset="0"
+         style="stop-color:black;stop-opacity:1;" />
+      <stop
+         id="stop3755"
+         offset="1"
+         style="stop-color:black;stop-opacity:0;" />
+    </linearGradient>
+    <inkscape:perspective
+       id="perspective2871-4"
+       inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
+       inkscape:vp_z="1 : 0.5 : 1"
+       inkscape:vp_y="0 : 1000 : 0"
+       inkscape:vp_x="0 : 0.5 : 1"
+       sodipodi:type="inkscape:persp3d" />
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient6499-1"
+       id="linearGradient4108-1"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(1.3544445,0,0,1.7332213,31.621862,-148.41185)"
+       x1="44.868057"
+       y1="260.4765"
+       x2="358.07056"
+       y2="260.4765" />
+    <linearGradient
+       id="linearGradient6499-1"
+       inkscape:collect="always">
+      <stop
+         id="stop6501-3"
+         offset="0"
+         style="stop-color:white;stop-opacity:1;" />
+      <stop
+         id="stop6503-0"
+         offset="1"
+         style="stop-color:white;stop-opacity:0;" />
+    </linearGradient>
+    <inkscape:perspective
+       id="perspective2894"
+       inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
+       inkscape:vp_z="1 : 0.5 : 1"
+       inkscape:vp_y="0 : 1000 : 0"
+       inkscape:vp_x="0 : 0.5 : 1"
+       sodipodi:type="inkscape:persp3d" />
+    <inkscape:perspective
+       id="perspective2900"
+       inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
+       inkscape:vp_z="1 : 0.5 : 1"
+       inkscape:vp_y="0 : 1000 : 0"
+       inkscape:vp_x="0 : 0.5 : 1"
+       sodipodi:type="inkscape:persp3d" />
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient3694"
+       id="linearGradient3692"
+       x1="-340.13901"
+       y1="580.56818"
+       x2="-587.59583"
+       y2="385.5177"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="translate(1001.4773,-3.3905771)" />
+    <inkscape:perspective
+       id="perspective4733"
+       inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
+       inkscape:vp_z="1 : 0.5 : 1"
+       inkscape:vp_y="0 : 1000 : 0"
+       inkscape:vp_x="0 : 0.5 : 1"
+       sodipodi:type="inkscape:persp3d" />
+    <inkscape:perspective
+       id="perspective4755"
+       inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
+       inkscape:vp_z="1 : 0.5 : 1"
+       inkscape:vp_y="0 : 1000 : 0"
+       inkscape:vp_x="0 : 0.5 : 1"
+       sodipodi:type="inkscape:persp3d" />
+    <filter
+       inkscape:collect="always"
+       id="filter5279">
+      <feGaussianBlur
+         inkscape:collect="always"
+         stdDeviation="9.1336879"
+         id="feGaussianBlur5281" />
+    </filter>
+  </defs>
+  <text
+     xml:space="preserve"
+     style="font-size:24.89476013px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Goblin"
+     x="266.96185"
+     y="759.88806"
+     id="text2508"><tspan
+       sodipodi:role="line"
+       id="tspan2510"
+       x="266.96185"
+       y="759.88806" /></text>
+  <path
+     style="fill:#ffffff;fill-opacity:1;filter:url(#filter5279)"
+     d="m 727.875,183.625 c -54.95141,0.10239 -108.24656,41.45339 -117.4375,96.3125 -7.18751,34.46439 1.06933,74.66203 29.125,97.71875 30.89444,22.7893 81.93759,12.49974 98.61823,-22.93373 14.37819,-30.04999 10.10074,-71.19785 -16.98347,-92.81884 -10.04267,-7.52903 -22.44565,-11.79194 -35.04101,-12.15368 17.69111,-12.77806 43.12833,-17.16843 62.6875,-6.40625 19.28249,12.40743 26.07937,36.25157 30.2523,57.53233 4.48332,27.1286 6.13127,55.01012 3.6227,82.46767 -4.74574,44.68635 -25.036,87.96711 -57.34375,119.15625 -33.53869,34.54528 -77.40287,56.79957 -121.34375,75.625 -11.23396,6.71688 -16.21668,24.32533 -6.09375,34.15625 9.32663,10.21101 25.578,9.01264 37.03884,3.29819 69.94174,-24.1193 137.78775,-61.10272 186.1071,-118.09283 26.51479,-30.77346 44.20182,-68.80511 51.76031,-108.67411 2.18112,16.71195 14.82435,31.27634 31.28125,35.28125 16.4564,4.95509 35.7916,-0.58354 45.625,-14.8125 16.45944,-21.3702 8.44275,-58.05287 -17.46875,-67.90625 -16.4904,-7.48772 -37.54311,-3.0365 -48.65625,11.46875 -3.13644,3.75974 -5.66889,7.93583 -7.53125,12.46875 3.21694,-39.5474 -2.55464,-80.8248 -21.65625,-115.84375 -19.09902,-33.78711 -53.53548,-58.6884 -92.4113,-63.51014 -11.26208,-1.85956 -22.72889,-2.57781 -34.1512,-2.33361 z m 187,37 c -30.09653,-0.77919 -51.82806,35.96111 -38.57033,62.52391 10.36983,26.30104 50.17864,34.80357 69.44533,13.41359 21.02478,-19.99669 15.03046,-61.36333 -12.59375,-72.1875 -5.63765,-2.62212 -11.99793,-4.03541 -18.28125,-3.75 z"
+     id="path2885-8" />
+  <path
+     style="fill:#000000;fill-opacity:1"
+     d="m 729.24652,202.27502 c -24.86194,0.81505 -49.26109,8.55033 -68.65124,25.43509 -33.84869,27.20416 -45.31559,80.90572 -24.37531,120.11021 12.6486,25.44898 45.9923,30.70952 68.65124,17.78104 21.70115,-12.30047 26.26462,-41.57536 20.48939,-64.64756 -5.42006,-25.10698 -34.31987,-39.60578 -56.05143,-29.43879 -9.43877,4.41596 -8.62695,3.35172 -20.13612,12.83532 -1.62864,-17.11896 8.23708,-32.05555 13.30633,-37.44613 19.27587,-20.49767 47.99987,-30.24403 75.01,-25.90612 29.7625,4.20493 48.55508,33.48396 55.46265,61.93918 9.41352,38.70202 11.15741,79.75225 4.9457,119.16817 -10.65921,64.75378 -54.64129,117.90361 -106.68612,151.66858 -23.56149,16.4422 -50.02019,27.00568 -75.59877,39.21245 -13.30203,6.51851 -0.67282,12.80562 7.77183,8.00736 63.47604,-21.20757 125.74376,-53.00609 173.33552,-102.91797 38.21438,-39.44239 62.32847,-94.42174 61.46817,-151.07981 0,-9.45372 -0.43538,-18.99189 -1.53083,-28.37899 -4.02654,-44.97399 -28.88948,-90.38854 -70.65306,-106.68612 -17.7612,-6.73739 -37.4209,-10.28987 -56.75795,-9.65591 z m 184.64,37.09285 c -6.18299,0.28246 -12.21842,2.88239 -16.48571,7.65409 -5.17362,5.33804 -7.47599,13.22873 -6.8298,20.72489 0.48425,9.59273 6.80369,18.45696 15.30817,21.90246 8.58092,3.35825 19.019,2.00507 25.90612,-4.59245 5.38466,-4.83818 8.39584,-12.25578 8.24286,-19.66511 0.0457,-5.66577 -1.48752,-11.39715 -4.82796,-15.89694 -4.33664,-6.10149 -11.34368,-9.96642 -18.60531,-10.12694 -0.88187,-0.0563 -1.82507,-0.0403 -2.70837,0 z m 0,117.16634 c -6.18144,0.27232 -12.3099,2.88445 -16.48571,7.77184 -5.03654,5.41748 -7.49698,13.22312 -6.8298,20.7249 0.47983,9.59774 6.79871,18.33779 15.30817,21.78469 8.58092,3.35803 19.019,2.00507 25.90612,-4.59245 5.39077,-4.84198 8.39581,-12.24996 8.24286,-19.66511 0.009,-3.5795 -0.58712,-7.09786 -2.00184,-10.36245 -3.82409,-8.66819 -12.29913,-15.27689 -21.54919,-15.54367 -0.87904,-0.0541 -1.70755,-0.15665 -2.59061,-0.11775 z"
+     id="path2885" />
+  <g
+     transform="matrix(5.0734563,0,0,5.3232265,-1583.057,-2586.3935)"
+     style="fill:#000000;fill-opacity:1"
+     id="g2887" />
+  <g
+     transform="matrix(5.0734563,0,0,5.3232265,-1583.057,-2586.3935)"
+     style="fill:#000000;fill-opacity:1"
+     id="g2891" />
+  <path
+     style="fill:url(#linearGradient3692);fill-opacity:1"
+     d="m 367.45933,453.36003 c -24.13417,0.31885 -41.62643,3.34489 -45.94006,9.95021 -9.55792,10.64226 26.92567,31.65031 82.87189,46.9871 35.37217,9.95564 73.41303,12.01356 84.52805,6.95594 10.71799,-4.81194 -10.85831,-16.26428 -37.23486,-25.29012 -27.83824,-9.82185 -69.68411,-15.49377 -82.33751,-11.51645 -5.49573,1.72752 -5.63418,1.31119 -8.67537,5.02118 -16.91428,-6.69694 -20.38554,-12.54013 -20.12958,-14.64893 0.97337,-8.01868 20.99477,-11.83146 51.87825,-10.13447 33.51712,1.64497 78.45313,13.09892 110.76856,24.2306 43.97081,15.14023 82.36874,31.19908 111.35175,46.61858 47.1599,25.33168 50.63566,46.12389 28.73979,59.33274 -8.88014,6.43219 -25.90664,10.56462 -40.58571,15.33991 -7.48161,2.55004 10.76141,5.00956 14.92166,3.13248 44.53966,-8.2964 78.41426,-20.73598 81.43935,-40.26151 2.99601,-15.42986 -21.98133,-36.93778 -73.432,-59.10241 -8.44128,-3.69829 -17.39335,-7.42962 -26.87063,-11.10186 -44.18411,-17.59382 -109.59798,-35.35998 -165.9138,-41.7356 -23.77705,-2.63566 -46.60878,-4.02539 -65.37978,-3.77739 z m 217.76046,14.51072 c -5.93077,0.1105 -9.64471,1.12759 -9.65132,2.99428 -0.40725,2.08824 4.33604,5.17508 11.67561,8.10758 9.04964,3.75267 23.28402,7.22036 34.86502,8.56824 11.57952,1.31375 20.80933,0.78438 21.80548,-1.79657 1.06463,-1.89269 -2.54743,-4.79446 -9.31626,-7.69299 -5.0133,-2.21645 -11.6641,-4.45856 -19.02243,-6.21888 -9.7847,-2.3869 -20.24276,-3.89886 -27.64773,-3.96166 -0.93209,-0.022 -1.86113,-0.0158 -2.70837,0 z m 104.6186,45.83546 c -5.93828,0.10653 -9.73434,1.1284 -9.54617,3.04035 -0.19924,2.11931 4.31004,5.17288 11.67561,8.10758 9.04971,3.75463 23.17265,7.17374 34.75987,8.52217 11.57933,1.31366 20.80933,0.78438 21.80548,-1.79657 1.06734,-1.89418 -2.54225,-4.79218 -9.31625,-7.69299 -3.18816,-1.4003 -6.92484,-2.77668 -11.25454,-4.05379 -11.56399,-3.391 -25.93997,-5.97632 -35.42823,-6.08068 -0.92743,-0.0212 -1.84747,-0.0613 -2.69584,-0.0461 z"
+     id="path2885-9" />
+</svg>
diff --git a/data/themes/default/intro_quit.svg b/data/themes/default/intro_quit.svg
new file mode 100644 (file)
index 0000000..18b4e96
--- /dev/null
@@ -0,0 +1,361 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Sodipodi ("http://www.sodipodi.com/") -->
+
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://creativecommons.org/ns#"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:xlink="http://www.w3.org/1999/xlink"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   version="1.0"
+   x="0"
+   y="0"
+   width="1000"
+   height="800"
+   id="svg559"
+   sodipodi:version="0.32"
+   inkscape:version="0.47pre4 r22446"
+   sodipodi:docname="intro_quit.svg"
+   inkscape:output_extension="org.inkscape.output.svg.inkscape">
+  <metadata
+     id="metadata35">
+    <rdf:RDF>
+      <cc:Work
+         rdf:about="">
+        <dc:format>image/svg+xml</dc:format>
+        <dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+        <dc:title />
+      </cc:Work>
+    </rdf:RDF>
+  </metadata>
+  <sodipodi:namedview
+     inkscape:window-height="726"
+     inkscape:window-width="1280"
+     inkscape:pageshadow="2"
+     inkscape:pageopacity="0.0"
+     guidetolerance="10.0"
+     gridtolerance="10.0"
+     objecttolerance="10.0"
+     borderopacity="1.0"
+     bordercolor="#666666"
+     pagecolor="#ffffff"
+     id="base"
+     inkscape:zoom="0.61522533"
+     inkscape:cx="513.67642"
+     inkscape:cy="463.84008"
+     inkscape:window-x="0"
+     inkscape:window-y="25"
+     inkscape:current-layer="svg559"
+     showgrid="false"
+     showguides="true"
+     inkscape:guide-bbox="true"
+     inkscape:window-maximized="1" />
+  <defs
+     id="defs561">
+    <linearGradient
+       id="linearGradient4557">
+      <stop
+         style="stop-color:#ffffff;stop-opacity:1;"
+         offset="0"
+         id="stop4559" />
+      <stop
+         style="stop-color:#0300da;stop-opacity:1;"
+         offset="1"
+         id="stop4561" />
+    </linearGradient>
+    <linearGradient
+       id="linearGradient3945">
+      <stop
+         style="stop-color:#ffffff;stop-opacity:1;"
+         offset="0"
+         id="stop3947" />
+      <stop
+         style="stop-color:#ffffff;stop-opacity:0;"
+         offset="1"
+         id="stop3949" />
+    </linearGradient>
+    <inkscape:perspective
+       sodipodi:type="inkscape:persp3d"
+       inkscape:vp_x="0 : 400 : 1"
+       inkscape:vp_y="0 : 1000 : 0"
+       inkscape:vp_z="1000 : 400 : 1"
+       inkscape:persp3d-origin="500 : 266.66667 : 1"
+       id="perspective62" />
+    <linearGradient
+       id="linearGradient6053">
+      <stop
+         style="stop-color:#000000;stop-opacity:1;"
+         offset="0"
+         id="stop6055" />
+      <stop
+         style="stop-color:#5f5f5f;stop-opacity:1;"
+         offset="1"
+         id="stop6057" />
+    </linearGradient>
+    <linearGradient
+       id="linearGradient6499"
+       inkscape:collect="always">
+      <stop
+         id="stop6501"
+         offset="0"
+         style="stop-color:white;stop-opacity:1;" />
+      <stop
+         id="stop6503"
+         offset="1"
+         style="stop-color:white;stop-opacity:0;" />
+    </linearGradient>
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient6499"
+       id="linearGradient3245"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(0.8327515,0,0,-0.6476426,-48.09403,12.672202)"
+       x1="311.95688"
+       y1="-116.67703"
+       x2="311.95688"
+       y2="-276.41519" />
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient6499"
+       id="linearGradient4108"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(1.3544445,0,0,1.7332213,31.621862,51.58815)"
+       x1="44.868057"
+       y1="260.4765"
+       x2="358.07056"
+       y2="260.4765" />
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient6499"
+       id="linearGradient4121"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(1.2483528,0,0,1.0242885,40.754503,133.62899)"
+       x1="44.868057"
+       y1="260.4765"
+       x2="358.07056"
+       y2="260.4765" />
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient6499"
+       id="linearGradient4127"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(1.2483528,0,0,1.0242885,40.754503,340.11416)"
+       x1="44.868057"
+       y1="260.4765"
+       x2="358.07056"
+       y2="260.4765" />
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient6499"
+       id="linearGradient4133"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(1.2483528,0,0,1.0242885,39.887975,233.1463)"
+       x1="44.868057"
+       y1="260.4765"
+       x2="358.07056"
+       y2="260.4765" />
+    <inkscape:perspective
+       id="perspective2871"
+       inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
+       inkscape:vp_z="1 : 0.5 : 1"
+       inkscape:vp_y="0 : 1000 : 0"
+       inkscape:vp_x="0 : 0.5 : 1"
+       sodipodi:type="inkscape:persp3d" />
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient3751"
+       id="linearGradient2518"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(0.9434139,0,0,0.9434139,62.279262,39.359798)"
+       x1="665.12128"
+       y1="684.16162"
+       x2="381.28015"
+       y2="449.80624" />
+    <linearGradient
+       id="linearGradient3751"
+       inkscape:collect="always">
+      <stop
+         id="stop3753"
+         offset="0"
+         style="stop-color:black;stop-opacity:1;" />
+      <stop
+         id="stop3755"
+         offset="1"
+         style="stop-color:black;stop-opacity:0;" />
+    </linearGradient>
+    <inkscape:perspective
+       id="perspective2871-4"
+       inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
+       inkscape:vp_z="1 : 0.5 : 1"
+       inkscape:vp_y="0 : 1000 : 0"
+       inkscape:vp_x="0 : 0.5 : 1"
+       sodipodi:type="inkscape:persp3d" />
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient6499-1"
+       id="linearGradient4108-1"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(1.3544445,0,0,1.7332213,31.621862,-148.41185)"
+       x1="44.868057"
+       y1="260.4765"
+       x2="358.07056"
+       y2="260.4765" />
+    <linearGradient
+       id="linearGradient6499-1"
+       inkscape:collect="always">
+      <stop
+         id="stop6501-3"
+         offset="0"
+         style="stop-color:white;stop-opacity:1;" />
+      <stop
+         id="stop6503-0"
+         offset="1"
+         style="stop-color:white;stop-opacity:0;" />
+    </linearGradient>
+    <inkscape:perspective
+       id="perspective3657"
+       inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
+       inkscape:vp_z="1 : 0.5 : 1"
+       inkscape:vp_y="0 : 1000 : 0"
+       inkscape:vp_x="0 : 0.5 : 1"
+       sodipodi:type="inkscape:persp3d" />
+    <inkscape:perspective
+       id="perspective3680"
+       inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
+       inkscape:vp_z="1 : 0.5 : 1"
+       inkscape:vp_y="0 : 1000 : 0"
+       inkscape:vp_x="0 : 0.5 : 1"
+       sodipodi:type="inkscape:persp3d" />
+    <inkscape:perspective
+       id="perspective3739"
+       inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
+       inkscape:vp_z="1 : 0.5 : 1"
+       inkscape:vp_y="0 : 1000 : 0"
+       inkscape:vp_x="0 : 0.5 : 1"
+       sodipodi:type="inkscape:persp3d" />
+    <inkscape:perspective
+       id="perspective3824"
+       inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
+       inkscape:vp_z="1 : 0.5 : 1"
+       inkscape:vp_y="0 : 1000 : 0"
+       inkscape:vp_x="0 : 0.5 : 1"
+       sodipodi:type="inkscape:persp3d" />
+    <inkscape:perspective
+       id="perspective3852"
+       inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
+       inkscape:vp_z="1 : 0.5 : 1"
+       inkscape:vp_y="0 : 1000 : 0"
+       inkscape:vp_x="0 : 0.5 : 1"
+       sodipodi:type="inkscape:persp3d" />
+    <inkscape:perspective
+       id="perspective3940"
+       inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
+       inkscape:vp_z="1 : 0.5 : 1"
+       inkscape:vp_y="0 : 1000 : 0"
+       inkscape:vp_x="0 : 0.5 : 1"
+       sodipodi:type="inkscape:persp3d" />
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient3751"
+       id="linearGradient3960"
+       x1="-278.00076"
+       y1="581.71515"
+       x2="-581.52838"
+       y2="292.07993"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="translate(838.63304,-6.8960763)" />
+    <inkscape:perspective
+       id="perspective5309"
+       inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
+       inkscape:vp_z="1 : 0.5 : 1"
+       inkscape:vp_y="0 : 1000 : 0"
+       inkscape:vp_x="0 : 0.5 : 1"
+       sodipodi:type="inkscape:persp3d" />
+    <inkscape:perspective
+       id="perspective5331"
+       inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
+       inkscape:vp_z="1 : 0.5 : 1"
+       inkscape:vp_y="0 : 1000 : 0"
+       inkscape:vp_x="0 : 0.5 : 1"
+       sodipodi:type="inkscape:persp3d" />
+    <filter
+       inkscape:collect="always"
+       id="filter5858"
+       x="-0.10974643"
+       width="1.2194929"
+       y="-0.045678593"
+       height="1.0913572">
+      <feGaussianBlur
+         inkscape:collect="always"
+         stdDeviation="9.5901209"
+         id="feGaussianBlur5860" />
+    </filter>
+    <filter
+       inkscape:collect="always"
+       id="filter5862">
+      <feGaussianBlur
+         inkscape:collect="always"
+         stdDeviation="9.5901209"
+         id="feGaussianBlur5864" />
+    </filter>
+    <filter
+       inkscape:collect="always"
+       id="filter5894">
+      <feGaussianBlur
+         inkscape:collect="always"
+         stdDeviation="9.5529999"
+         id="feGaussianBlur5896" />
+    </filter>
+    <filter
+       inkscape:collect="always"
+       id="filter5898">
+      <feGaussianBlur
+         inkscape:collect="always"
+         stdDeviation="9.5529999"
+         id="feGaussianBlur5900" />
+    </filter>
+  </defs>
+  <text
+     xml:space="preserve"
+     style="font-size:24.89476013px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Goblin"
+     x="266.96185"
+     y="759.88806"
+     id="text2508"><tspan
+       sodipodi:role="line"
+       id="tspan2510"
+       x="266.96185"
+       y="759.88806" /></text>
+  <g
+     id="g3726"
+     transform="translate(119.53198,32.181688)">
+    <path
+       style="fill:#ffffff;fill-opacity:1;filter:url(#filter5898)"
+       d="m 545.21875,82.15625 c -8.11065,2.593197 -7.26147,12.596658 -6.28125,19.3125 -0.72614,100.68434 -0.0968,201.37534 -0.3125,302.0625 0,52.88542 0,105.77083 0,158.65625 81.87811,22.84479 163.72871,45.78951 245.6875,68.34375 0,-160.66667 0,-321.33333 0,-482 -27.99953,-0.27289 -57.3672,0.50146 -84.53125,-0.34375 6.56063,-10.30581 -0.45922,-26.61008 -13.17755,-27.12784 C 639.97424,107.11942 592.98164,94.273234 545.90625,81.8125 l -0.6875,0.34375 z"
+       id="rect2874-7-7-0" />
+    <path
+       style="fill:#ffffff;fill-opacity:1;filter:url(#filter5894)"
+       d="m 508.5,132.1875 c 0,164.21875 0,328.4375 0,492.65625 11.20155,-10.13695 28.96477,0.18691 40,-10.4375 2.94568,-6.65631 1.33518,-15.10244 1.71876,-22.4681 -0.0789,-139.16269 -0.006,-278.33446 -0.0313,-417.50065 69.32292,0 138.64583,0 207.96875,0 0,150.13542 0,300.27083 0,450.40625 11.20155,-10.13695 28.96477,0.18691 40,-10.4375 2.94568,-6.65631 1.33518,-15.10244 1.71876,-22.4681 -0.0779,-153.91269 -0.007,-307.83447 -0.0313,-461.75065 -97.11458,0 -194.22917,0 -291.34375,0 l 0,1 0,1 z"
+       id="rect2874-3" />
+    <path
+       style="fill:#000000;fill-opacity:1"
+       d="m 557.74927,103.97456 0,35.0625 125.625,0 -125.625,-35.0625 z m 209.66954,63.50576 0.018,-0.006 0.0349,0 -0.0529,0.006 z m 0.018,-0.006 -209.6875,0 0,381.875 209.6875,58.5 0,-440.375 z"
+       id="rect2874-7-7"
+       sodipodi:nodetypes="ccccccccccccc" />
+    <path
+       id="rect2874"
+       d="m 523.61644,145.1279 0,461.625 13.69375,0 0,-445.375 235.97508,0 0,445.375 13.66608,0 0,-461.625 -263.33491,0 z"
+       style="fill:#000000;fill-opacity:1" />
+    <path
+       style="opacity:0.228;fill:url(#linearGradient3960);fill-opacity:1"
+       d="m 106.07575,355.85045 181.25931,70.58159 -181.84379,0 416.96879,179.43749 13.71875,0 -402.31254,-173.09374 168.15629,0 255.86646,115.19639 204.38353,56.02235 -394.43749,-171.21874 2,0 402.31249,173.09374 13.65625,0 -416.96874,-179.43749 -16,0 -246.75931,-70.58159 z"
+       id="rect2874-0-5"
+       sodipodi:nodetypes="cccccccccccccccc" />
+  </g>
+  <g
+     id="g3726-0"
+     transform="translate(516.65949,37.209684)" />
+</svg>
diff --git a/data/themes/default/intro_sing.svg b/data/themes/default/intro_sing.svg
new file mode 100644 (file)
index 0000000..26089d5
--- /dev/null
@@ -0,0 +1,309 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Sodipodi ("http://www.sodipodi.com/") -->
+
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://creativecommons.org/ns#"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:xlink="http://www.w3.org/1999/xlink"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   version="1.0"
+   x="0"
+   y="0"
+   width="1000"
+   height="800"
+   id="svg559"
+   sodipodi:version="0.32"
+   inkscape:version="0.47pre4 r22446"
+   sodipodi:docname="intro_sing.svg"
+   inkscape:output_extension="org.inkscape.output.svg.inkscape">
+  <metadata
+     id="metadata35">
+    <rdf:RDF>
+      <cc:Work
+         rdf:about="">
+        <dc:format>image/svg+xml</dc:format>
+        <dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+        <dc:title />
+      </cc:Work>
+    </rdf:RDF>
+  </metadata>
+  <sodipodi:namedview
+     inkscape:window-height="726"
+     inkscape:window-width="1280"
+     inkscape:pageshadow="2"
+     inkscape:pageopacity="0.0"
+     guidetolerance="10.0"
+     gridtolerance="10.0"
+     objecttolerance="10.0"
+     borderopacity="1.0"
+     bordercolor="#666666"
+     pagecolor="#ffffff"
+     id="base"
+     inkscape:zoom="0.43503001"
+     inkscape:cx="134.29335"
+     inkscape:cy="407.61507"
+     inkscape:window-x="0"
+     inkscape:window-y="25"
+     inkscape:current-layer="g3955"
+     showgrid="false"
+     showguides="true"
+     inkscape:guide-bbox="true"
+     inkscape:window-maximized="1" />
+  <defs
+     id="defs561">
+    <linearGradient
+       id="linearGradient4557">
+      <stop
+         style="stop-color:#ffffff;stop-opacity:1;"
+         offset="0"
+         id="stop4559" />
+      <stop
+         style="stop-color:#0300da;stop-opacity:1;"
+         offset="1"
+         id="stop4561" />
+    </linearGradient>
+    <linearGradient
+       id="linearGradient3945">
+      <stop
+         style="stop-color:#ffffff;stop-opacity:1;"
+         offset="0"
+         id="stop3947" />
+      <stop
+         style="stop-color:#ffffff;stop-opacity:0;"
+         offset="1"
+         id="stop3949" />
+    </linearGradient>
+    <inkscape:perspective
+       sodipodi:type="inkscape:persp3d"
+       inkscape:vp_x="0 : 400 : 1"
+       inkscape:vp_y="0 : 1000 : 0"
+       inkscape:vp_z="1000 : 400 : 1"
+       inkscape:persp3d-origin="500 : 266.66667 : 1"
+       id="perspective62" />
+    <linearGradient
+       id="linearGradient6053">
+      <stop
+         style="stop-color:#000000;stop-opacity:1;"
+         offset="0"
+         id="stop6055" />
+      <stop
+         style="stop-color:#5f5f5f;stop-opacity:1;"
+         offset="1"
+         id="stop6057" />
+    </linearGradient>
+    <linearGradient
+       id="linearGradient6499"
+       inkscape:collect="always">
+      <stop
+         id="stop6501"
+         offset="0"
+         style="stop-color:white;stop-opacity:1;" />
+      <stop
+         id="stop6503"
+         offset="1"
+         style="stop-color:white;stop-opacity:0;" />
+    </linearGradient>
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient6499"
+       id="linearGradient3245"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(0.8327515,0,0,-0.6476426,-48.09403,12.672202)"
+       x1="311.95688"
+       y1="-116.67703"
+       x2="311.95688"
+       y2="-276.41519" />
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient6499"
+       id="linearGradient4108"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(1.3544445,0,0,1.7332213,31.621862,51.58815)"
+       x1="44.868057"
+       y1="260.4765"
+       x2="358.07056"
+       y2="260.4765" />
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient6499"
+       id="linearGradient4121"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(1.2483528,0,0,1.0242885,40.754503,133.62899)"
+       x1="44.868057"
+       y1="260.4765"
+       x2="358.07056"
+       y2="260.4765" />
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient6499"
+       id="linearGradient4127"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(1.2483528,0,0,1.0242885,40.754503,340.11416)"
+       x1="44.868057"
+       y1="260.4765"
+       x2="358.07056"
+       y2="260.4765" />
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient6499"
+       id="linearGradient4133"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(1.2483528,0,0,1.0242885,39.887975,233.1463)"
+       x1="44.868057"
+       y1="260.4765"
+       x2="358.07056"
+       y2="260.4765" />
+    <inkscape:perspective
+       id="perspective2871"
+       inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
+       inkscape:vp_z="1 : 0.5 : 1"
+       inkscape:vp_y="0 : 1000 : 0"
+       inkscape:vp_x="0 : 0.5 : 1"
+       sodipodi:type="inkscape:persp3d" />
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient3751"
+       id="linearGradient2518"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(0.9434139,0,0,0.9434139,62.279262,39.359798)"
+       x1="665.12128"
+       y1="684.16162"
+       x2="381.28015"
+       y2="449.80624" />
+    <linearGradient
+       id="linearGradient3751">
+      <stop
+         id="stop3753"
+         offset="0"
+         style="stop-color:black;stop-opacity:1;" />
+      <stop
+         id="stop3755"
+         offset="1"
+         style="stop-color:black;stop-opacity:0;" />
+    </linearGradient>
+    <inkscape:perspective
+       id="perspective2871-4"
+       inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
+       inkscape:vp_z="1 : 0.5 : 1"
+       inkscape:vp_y="0 : 1000 : 0"
+       inkscape:vp_x="0 : 0.5 : 1"
+       sodipodi:type="inkscape:persp3d" />
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient6499-1"
+       id="linearGradient4108-1"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(1.3544445,0,0,1.7332213,31.621862,-148.41185)"
+       x1="44.868057"
+       y1="260.4765"
+       x2="358.07056"
+       y2="260.4765" />
+    <linearGradient
+       id="linearGradient6499-1">
+      <stop
+         id="stop6501-3"
+         offset="0"
+         style="stop-color:#000000;stop-opacity:1;" />
+      <stop
+         id="stop6503-0"
+         offset="1"
+         style="stop-color:white;stop-opacity:0;" />
+    </linearGradient>
+    <inkscape:perspective
+       id="perspective2849"
+       inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
+       inkscape:vp_z="1 : 0.5 : 1"
+       inkscape:vp_y="0 : 1000 : 0"
+       inkscape:vp_x="0 : 0.5 : 1"
+       sodipodi:type="inkscape:persp3d" />
+    <inkscape:perspective
+       id="perspective2854"
+       inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
+       inkscape:vp_z="1 : 0.5 : 1"
+       inkscape:vp_y="0 : 1000 : 0"
+       inkscape:vp_x="0 : 0.5 : 1"
+       sodipodi:type="inkscape:persp3d" />
+    <linearGradient
+       y2="260.4765"
+       x2="358.07056"
+       y1="260.4765"
+       x1="44.868057"
+       gradientTransform="matrix(1.3544445,0,0,1.8513768,-45.940851,-180.28458)"
+       gradientUnits="userSpaceOnUse"
+       id="linearGradient2880"
+       xlink:href="#linearGradient6499-1-4"
+       inkscape:collect="always" />
+    <linearGradient
+       id="linearGradient6499-1-4">
+      <stop
+         id="stop6501-3-4"
+         offset="0"
+         style="stop-color:#ffffff;stop-opacity:1;" />
+      <stop
+         id="stop6503-0-4"
+         offset="1"
+         style="stop-color:white;stop-opacity:0;" />
+    </linearGradient>
+    <linearGradient
+       y2="260.4765"
+       x2="358.07056"
+       y1="260.4765"
+       x1="44.868057"
+       gradientTransform="matrix(1.3544445,0,0,1.8513768,-45.940837,-180.2845)"
+       gradientUnits="userSpaceOnUse"
+       id="linearGradient2863"
+       xlink:href="#linearGradient6499-1-4"
+       inkscape:collect="always" />
+    <inkscape:perspective
+       id="perspective4038"
+       inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
+       inkscape:vp_z="1 : 0.5 : 1"
+       inkscape:vp_y="0 : 1000 : 0"
+       inkscape:vp_x="0 : 0.5 : 1"
+       sodipodi:type="inkscape:persp3d" />
+    <filter
+       inkscape:collect="always"
+       id="filter4102">
+      <feGaussianBlur
+         inkscape:collect="always"
+         stdDeviation="10.689196"
+         id="feGaussianBlur4104" />
+    </filter>
+  </defs>
+  <text
+     xml:space="preserve"
+     style="font-size:24.89476013px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Goblin"
+     x="266.96185"
+     y="759.88806"
+     id="text2508"><tspan
+       sodipodi:role="line"
+       id="tspan2510"
+       x="266.96185"
+       y="759.88806" /></text>
+  <g
+     id="g3955"
+     transform="translate(-24.96631,-76.016045)">
+    <path
+       style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.67309087999999995px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;filter:url(#filter4102)"
+       d="M 761.625,229.65625 C 747.39502,234.4767 736.35298,246.73304 721.0625,249 c -16.53957,6.42255 -33.9604,17.15883 -39.9375,34.84375 -3.86066,17.63507 7.05157,33.79585 13.44299,49.33403 2.71774,5.64987 5.74176,11.14072 9.18201,16.35347 -16.91479,28.10647 -26.15446,60.97532 -49.84375,84.59375 -3.28446,4.2066 -4.0471,9.91279 -6.4375,14.3125 -11.90138,8.64494 -9.39804,29.48494 3.78125,35.5 -2.72141,10.24779 -1.31106,21.30932 -0.96875,31.84375 2.27202,23.8975 7.39731,47.57451 11.28125,71.21875 4.97381,20.41324 16.81036,38.03645 27.3131,55.93202 4.48373,7.81451 9.85903,15.88888 11.1869,24.81798 -2.73561,7.05561 -11.83548,7.18003 -17.8125,10.0625 -13.11105,5.4779 -20.96481,23.52862 -11.90625,35.71875 8.26796,10.29454 22.63166,7.05398 33.84375,6.34375 5.2536,13.03691 20.58152,18.31912 33.84375,18.71875 11.36573,1.56086 22.75328,-3.18566 30.125,-11.75 9.88814,-7.66249 14.76083,-19.86674 16.75,-31.90625 2.99585,-9.27484 10.9675,-15.48299 17.34375,-22.34375 4.6177,-7.30332 6.21465,-16.08603 9.8125,-23.84375 1.25519,-4.57951 -1.48771,-8.88193 -3.96875,-12.1875 -2.31983,-8.33336 -11.11403,-12.67019 -18.34375,-15.9375 -3.49267,-0.12192 -6.83388,-1.61823 -6.875,-5.46875 -6.04457,-14.60448 -15.68837,-27.98608 -29.65625,-35.75 -3.76008,-5.49339 3.10736,-10.22909 3.125,-15.78125 -0.23194,-6.91335 4.63268,-12.62164 3.96875,-19.6875 -0.19814,-6.0761 4.58616,-10.84205 4.71875,-17.0625 0.88773,-6.01123 7.438,-8.87904 8.625,-14.90625 3.35505,-8.92733 1.82137,-18.80448 1.8125,-27.9375 2.5027,-7.35007 9.06665,-11.79115 14.15625,-17.0625 5.77283,-7.3577 6.60551,-17.60552 13.8125,-23.96875 10.98089,8.55114 27.92664,6.46787 36.9375,17.84375 6.14715,10.97305 20.23191,10.05515 30.59375,13.65625 17.6551,7.4915 35.08597,15.63863 53.125,22 8.84674,6.21187 17.85724,16.61076 29.90625,13.75 6.41713,-0.85646 10.79198,-6.15862 15.6875,-9.5 9.44961,-4.63876 12.90439,-15.83731 16,-25.0625 0.33879,-7.95067 -3.0522,-15.55504 -6.15625,-22.5625 -3.13159,-5.00263 -9.47891,-6.96099 -13.96875,-9.6875 -0.35907,-12.61942 -13.8318,-24.15218 -26.34375,-19.125 -8.36812,1.38541 -15.48913,7.08308 -23.28125,9.375 -3.54222,-0.56964 -4.23235,-3.7164 -4.8125,-6.46875 -5.72019,-10.58512 -18.96404,-12.19175 -28.11704,-18.48735 -3.29936,-1.63505 -7.12007,-3.14924 -9.91421,-5.26265 4.33219,-6.25041 2.55889,-14.59267 0.0625,-20.9375 1.70387,-6.32883 -0.22601,-13.88561 4.65625,-19.09375 2.46623,-6.0895 -2.33021,-11.72068 -2.6875,-17.5 3.65753,-7.75845 -0.26479,-17.53211 -7.53125,-21.625 -0.0204,-10.68903 -2.70341,-21.0945 -5.5625,-31.34375 -7.0238,-1.9202 -12.80876,3.28339 -17.9375,7.15625 -5.05428,-1.03242 -10.13943,0.97113 -14.46875,3.1875 -7.86171,-0.92057 -12.47989,-9.36199 -20.71875,-8.5 -2.55825,0.18376 -4.82854,0.86061 -2.6875,-2.46875 2.27733,-7.12236 0.26858,-14.82375 -2.1875,-21.40625 0.34703,-13.82765 -6.6884,-27.53577 -17.09375,-36.28125 -7.61061,-4.2492 -16.76131,-4.89974 -25.3125,-5 z M 757,293.21875 c 2.34511,6.8718 8.33581,11.94203 14.8125,14.75 -3.00278,1.86643 -5.51663,6.64448 -9.1875,3.15625 -5.2429,-2.51528 -11.79439,-6.36906 -13.6875,-11.8125 2.70289,-1.55258 5.78855,-5.62007 8.0625,-6.09375 z"
+       id="path1939-0" />
+    <path
+       id="path1939"
+       d="m 794.42889,322.92369 -13.59856,0 -2.71967,6.79924 2.71967,7.47917 -1.35984,8.15909 -6.79918,-4.07955 -5.43934,-10.19886 -11.55882,-2.71971 -4.75942,-4.75946 -10.19888,-4.75948 -11.55869,-19.03788 0.67991,-8.83902 28.55686,-21.75758 13.59837,6.11931 2.03984,4.75948 0,5.4394 3.39959,4.75946 6.79928,2.03978 4.75943,-4.07955 0.67992,-4.75947 -2.03975,-4.07954 -4.07951,-2.03977 -2.71977,-3.39963 6.11936,-2.71969 -1.35984,-6.79925 0,-4.07956 -4.07951,-4.07954 -2.03985,-6.11931 -8.15902,-2.03977 -6.79928,-1.35986 -14.27847,10.19887 -36.03596,14.27842 -8.15911,8.15909 -6.11927,4.75947 -1.35994,10.87879 2.71977,5.4394 6.79928,18.35795 8.83894,16.99811 9.51895,12.23864 -14.9583,24.47729 -16.99814,36.71591 -10.19887,16.31818 -16.99806,21.07767 -0.67992,9.51895 -8.83903,8.15908 13.59847,12.23866 -3.3996,14.27839 1.35984,31.95646 6.11926,36.71592 6.11936,32.63638 6.79918,10.87879 9.51906,19.7178 14.9583,22.43751 4.0795,14.27837 4.0796,10.19888 -12.23871,16.99811 -21.75758,8.83902 -2.03976,6.7993 41.4754,-1.35985 -6.11926,10.87876 7.47911,6.79923 19.71782,2.03981 15.63831,-13.59852 5.43944,-19.03784 8.83893,-16.31821 10.8788,-9.51893 3.39959,-10.87882 -11.55861,-0.67991 7.4791,-7.47918 -14.9583,4.75948 10.87879,-10.8788 -8.15911,-2.03977 -6.11937,-7.47917 -10.19886,-21.07766 -23.79734,-19.71781 -4.75943,-1.35984 4.75943,-4.07955 -0.67992,-11.55872 4.75952,-10.19886 -4.0796,0.67992 7.47919,-12.91856 0,-12.91857 4.75944,-6.79924 0,-8.83902 10.19886,-13.5985 0.68002,-11.5587 -2.03985,-9.51895 4.75952,-10.87879 5.43935,-8.83902 0,-5.43939 6.11936,-0.67992 5.43935,-5.4394 4.75952,-13.59848 10.87878,-12.23865 12.91856,-4.75947 8.15901,6.79924 19.71792,6.11933 15.63821,8.15908 7.47911,9.51895 12.91854,1.35985 40.79558,17.67803 21.07757,7.47918 16.99814,12.91856 4.07961,-1.35986 0,-4.07954 -9.51896,-7.47916 18.35789,4.75946 2.03986,-3.39963 -4.0796,-4.07952 6.79928,0 0.67991,-4.07956 -12.23863,-2.7197 9.51886,-2.7197 0,-4.75947 -3.39959,-0.67991 -10.19887,0.67991 -8.15902,-3.39962 -5.43944,-2.71969 8.15911,-6.79925 2.03976,-4.75947 -1.35984,-3.39963 -7.4791,1.35986 -15.63841,8.15908 -2.03966,4.07955 -5.43944,-1.35984 -19.71783,-10.87879 -0.67991,-7.47917 -11.55871,-6.11933 -19.71782,-10.19887 -4.75944,3.39963 0.67993,-4.75947 -10.87879,-10.19887 -9.51896,-2.7197 -8.83903,-10.19886 -2.71966,-3.39963 8.83902,6.11933 -1.35983,-6.79926 6.79918,3.39963 -2.03976,-10.19887 9.51895,8.83903 -4.0795,-6.11932 9.51885,4.07953 -8.15902,-11.5587 6.11927,2.03977 -2.71967,-10.87879 4.75942,4.07954 -6.79918,-10.19887 6.79918,2.03977 -6.11926,-8.15908 8.15902,-0.67993 -8.83894,-5.4394 5.43935,-2.71968 -6.11926,-0.67994 8.15902,-7.47916 -7.47911,0.67992 0.67992,-4.75947 0.67991,-13.59848 -4.0795,9.51894 -4.75952,-13.5985 0.67991,10.8788 -2.71967,0.67992 -6.79928,0 -7.47919,-10.87879 -7.47911,0 -8.83904,-7.47917 -4.0796,4.07954 -10.19877,6.79926 z"
+       style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:0.67309088px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
+    <path
+       style="opacity:0.22790701;fill:url(#linearGradient2518);fill-opacity:1;fill-rule:evenodd;stroke:none"
+       d="m 435.88424,549.14748 -13.60762,0 3.65489,2.67368 9.73545,2.94103 6.29079,3.2084 -10.62954,-1.60421 -15.00754,-4.01048 -14.11696,-1.06948 -9.22613,-1.87156 -14.66914,-1.87157 -29.42027,-7.48627 -7.60882,-3.47577 8.17166,-8.55573 19.34621,2.4063 6.50466,1.87156 5.10103,2.13893 7.86535,1.87158 8.71676,0.80209 0.93671,-1.6042 -3.78299,-1.87156 -5.867,-1.60421 -5.99511,-0.80209 -5.90973,-1.33684 3.5729,-1.06946 -7.73713,-2.67367 -3.82574,-1.60421 -7.90807,-1.6042 -7.77986,-2.4063 -10.07745,-0.8021 -8.07911,-0.53473 -4.7234,4.01051 -22.66986,5.6147 -0.51293,3.20839 -1.65994,1.87157 8.8414,4.27787 7.82259,2.13894 24.01998,7.2189 24.78574,6.68417 21.00277,4.8126 7.98646,9.62519 17.42278,14.43782 5.09755,6.41679 2.75723,8.28838 8.24657,3.74313 -1.19343,3.20841 25.085,4.81261 9.9885,5.61469 31.32954,12.56625 40.55567,14.4378 36.72993,12.83361 17.00589,4.27786 28.01675,7.75364 36.0102,8.82311 17.4726,5.61468 13.64685,4.01051 3.69394,6.68416 -13.4829,3.47577 4.33537,2.67369 40.22783,-0.53473 4.07876,4.27785 13.86045,2.67367 21.64389,0.8021 2.896,-5.34734 -12.41061,-7.48625 -6.45833,-6.41682 1.95919,-3.74312 -6.80031,-4.27787 -12.20401,-0.26737 0.4702,-2.94105 -10.50491,1.87158 0.68387,-4.27787 -10.07745,-0.8021 -13.13732,-2.94103 -29.97245,-8.28838 -42.30467,-7.75363 -6.03793,-0.53473 0.9369,-1.60421 -11.52022,-4.54523 -4.80188,-4.0105 -3.44459,0.26737 -4.63084,-5.07997 -12.11514,-5.07998 -1.61371,-2.67367 -8.28921,-3.47576 -2.54703,-5.34733 -10.15934,-4.54523 -10.96803,-3.74315 -5.43953,-4.27786 -2.8462,-3.47577 -5.10113,-2.13893 5.48586,-0.26737 0.34189,-2.13893 -7.98996,-5.34733 -0.59143,-4.81261 8.46374,-1.87157 14.54084,2.67366 25.46982,2.40631 23.30025,3.20839 16.41106,3.74315 14.20244,0.53473 57.40127,6.95153 28.10571,2.94104 29.12451,5.07998 2.80712,-0.53475 -3.82582,-1.60419 -16.53937,-2.94104 22.83373,1.87156 -1.14709,-1.33682 -7.90798,-1.6042 6.80371,0 -3.14534,-1.60421 -14.79745,-1.06946 6.97476,-1.06947 -4.46349,-1.87158 -4.03942,-0.26736 -9.5681,0.26736 -11.35267,-1.33682 -7.99364,-1.06948 1.78825,-2.67366 -2.42231,-1.87156 -4.54895,-1.33685 -6.20889,0.53474 -7.99714,3.20839 1.78466,1.60421 -6.71823,-0.53473 -29.93321,-4.27787 -7.69429,-2.94103 -17.30515,-2.40631 -29.29554,-4.0105 -1.57446,1.33684 -3.7831,-1.87157 -20.45056,-4.01051 -12.07579,-1.06945 -18.4095,-4.01052 -5.90964,-1.33682 14.58357,2.4063 -7.73703,-2.67368 9.99188,1.33684 -11.60569,-4.01049 17.81459,3.47576 -9.82095,-2.4063 13.35111,1.60419 -19.00432,-4.54522 8.03628,0.8021 -12.92363,-4.27788 8.58845,1.60421 -16.36832,-4.01051 8.71667,0.80211 -13.77506,-3.20841 7.52693,-0.26737 -13.94592,-2.13893 2.8924,-1.06946 -6.76096,-0.26737 1.15048,-2.94104 -6.84644,0.26736 -3.7831,-1.87155 -12.07229,-5.34735 4.84462,3.74314 -17.51533,-5.34733 10.88247,4.27787 -2.08392,0.26737 -6.80371,0 -17.68636,-4.27787 -7.4842,0 -15.85879,-2.94103 -0.25661,1.60418 -3.82922,2.67367 z"
+       id="path2864" />
+    <path
+       sodipodi:nodetypes="cssc"
+       id="path3759"
+       d="m 763.90087,255.09122 c -26.62135,-9.8399 -37.65223,26.15318 -32.15617,47.65699 6.43181,25.16505 8.4097,56.02071 -3.17298,78.7166 -8.29967,16.26295 -46.68286,22.35178 -46.1986,45.20859"
+       style="fill:none;stroke:#ffffff;stroke-width:1.60380363;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
+  </g>
+</svg>
diff --git a/data/themes/default/logo.svg b/data/themes/default/logo.svg
new file mode 100644 (file)
index 0000000..b5a8317
--- /dev/null
@@ -0,0 +1,90 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://creativecommons.org/ns#"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   width="360"
+   height="85"
+   id="svg1901"
+   sodipodi:version="0.32"
+   inkscape:version="0.48.1 r9760"
+   sodipodi:docname="Uusi asiakirja 1"
+   version="1.1">
+  <defs
+     id="defs1903">
+    <filter
+       color-interpolation-filters="sRGB"
+       inkscape:collect="always"
+       id="filter3869-9"
+       x="-0.019231318"
+       width="1.0384626"
+       y="-0.12226724"
+       height="1.2445345">
+      <feGaussianBlur
+         inkscape:collect="always"
+         stdDeviation="3.4581674"
+         id="feGaussianBlur3871-2" />
+    </filter>
+  </defs>
+  <sodipodi:namedview
+     id="base"
+     pagecolor="#ffffff"
+     bordercolor="#666666"
+     borderopacity="1.0"
+     inkscape:pageopacity="0.0"
+     inkscape:pageshadow="2"
+     inkscape:zoom="0.35"
+     inkscape:cx="321.42857"
+     inkscape:cy="-83.214282"
+     inkscape:document-units="px"
+     inkscape:current-layer="layer1"
+     inkscape:window-width="877"
+     inkscape:window-height="722"
+     inkscape:window-x="177"
+     inkscape:window-y="25"
+     showgrid="false"
+     fit-margin-top="0"
+     fit-margin-left="0"
+     fit-margin-right="0"
+     fit-margin-bottom="0"
+     inkscape:window-maximized="0" />
+  <metadata
+     id="metadata1906">
+    <rdf:RDF>
+      <cc:Work
+         rdf:about="">
+        <dc:format>image/svg+xml</dc:format>
+        <dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+        <dc:title></dc:title>
+      </cc:Work>
+    </rdf:RDF>
+  </metadata>
+  <g
+     inkscape:label="Taso 1"
+     inkscape:groupmode="layer"
+     id="layer1"
+     transform="translate(-28.571429,-364.1479)">
+    <g
+       transform="matrix(0.98065768,0,0,0.97754687,-1.9638217,255.66295)"
+       id="g3873">
+      <path
+         inkscape:connector-curvature="0"
+         id="text3236"
+         d="m 74.487864,100.57517 c -5.2e-5,2.78873 -0.646212,5.29401 -1.938481,7.51586 -1.269697,2.19925 -3.10615,4.04703 -5.509366,5.54338 -2.380632,1.45105 -5.044624,2.52798 -7.991981,3.2308 -2.924759,0.70286 -6.155557,1.05428 -9.692404,1.05426 l -4.897214,0 -3.02675,13.09325 c -0.09071,0.38543 -0.170061,0.74819 -0.238059,1.08827 -0.04536,0.34009 -0.06804,0.60082 -0.06802,0.78219 -1.9e-5,1.02026 0.419418,1.76844 1.258312,2.24456 0.838854,0.47612 2.482593,0.83888 4.931223,1.08827 l -0.578144,2.48261 -26.220501,0 0.578143,-2.48261 c 0.566808,-0.0227 1.405682,-0.10202 2.516624,-0.23806 1.133612,-0.1587 1.972486,-0.32875 2.516624,-0.51013 0.884215,-0.29473 1.553047,-0.73684 2.006498,-1.32633 0.476112,-0.58947 0.804859,-1.28097 0.986244,-2.07451 l 7.787931,-33.736365 c 0.113347,-0.476078 0.1927,-0.872842 0.238059,-1.190295 0.04533,-0.317371 0.068,-0.555429 0.06802,-0.714178 -1.5e-5,-0.952192 -0.487468,-1.689041 -1.462362,-2.210548 -0.952249,-0.54409 -2.516635,-0.974863 -4.693164,-1.29232 l 0.578143,-2.482616 26.152485,0 c 5.622686,4.9e-5 9.805719,0.827586 12.549111,2.482616 2.765969,1.655121 4.148977,4.205751 4.149029,7.651896 m -14.215525,5.67941 c 0.498752,-1.70039 0.748147,-3.55951 0.748186,-5.57738 -3.9e-5,-2.44857 -0.657535,-4.273688 -1.972489,-5.475361 -1.315028,-1.224259 -3.457558,-1.83641 -6.427594,-1.836455 l -2.482616,0 -4.965231,21.527336 2.210548,0 c 2.44858,2e-5 4.545765,-0.36273 6.29156,-1.08827 1.768406,-0.74816 3.196758,-1.77975 4.285063,-3.09477 1.042888,-1.26961 1.813745,-2.75465 2.312573,-4.4551 m 29.92742,33.56632 c -2.72069,0 -5.112614,-0.37409 -7.175779,-1.12228 -2.040515,-0.72551 -3.729599,-1.74576 -5.067257,-3.06076 -1.314997,-1.31498 -2.301241,-2.84536 -2.958733,-4.59113 -0.657499,-1.74576 -0.986247,-3.6729 -0.986245,-5.78144 -2e-6,-2.67531 0.498788,-5.27129 1.496371,-7.78793 0.997576,-2.5166 2.482609,-4.78382 4.455105,-6.80168 1.859117,-1.92712 4.217033,-3.49151 7.073754,-4.69317 2.85669,-1.2016 6.008135,-1.80241 9.454344,-1.80245 4.058311,4e-5 7.141741,0.6462 9.250291,1.93849 2.13116,1.29235 3.19676,3.23083 3.1968,5.81544 -4e-5,2.4713 -0.91827,4.60249 -2.75469,6.39358 -1.83649,1.76846 -4.33044,3.08345 -7.481853,3.94498 -2.493976,0.7482 -4.625169,1.281 -6.393585,1.5984 -1.745785,0.31742 -3.888314,0.61216 -6.427594,0.88422 0.04533,0.99759 0.181364,2.11987 0.408101,3.36683 0.226708,1.24699 0.566792,2.31258 1.020253,3.19679 0.544119,1.02026 1.314976,1.83646 2.312574,2.44861 0.997561,0.58948 2.267208,0.88422 3.808944,0.88422 2.675306,0 4.942532,-0.51012 6.80169,-1.53038 1.88177,-1.04292 3.67287,-2.68666 5.37333,-4.93122 l 2.48261,2.07451 c -2.04054,2.90206 -4.65918,5.22597 -7.85594,6.97173 -3.174149,1.72309 -6.518308,2.58464 -10.032491,2.58464 m 7.685906,-26.93468 c -2.7e-5,-1.92711 -0.351447,-3.40081 -1.054262,-4.42109 -0.702865,-1.0429 -1.677773,-1.56436 -2.924725,-1.56439 -1.745787,3e-5 -3.400862,1.42838 -4.965231,4.28506 -1.541731,2.83406 -2.527975,6.42762 -2.958734,10.78068 1.33765,-0.15869 2.663977,-0.36274 3.978987,-0.61216 1.314973,-0.24937 2.357897,-0.54411 3.128776,-0.88422 1.700398,-0.74816 2.924701,-1.71173 3.67291,-2.89071 0.74816,-1.17894 1.122252,-2.74333 1.122279,-4.69317 m 50.128435,-1.6324 c -4e-5,1.02028 -0.14741,2.00652 -0.44211,2.95873 -0.29478,0.95226 -0.73689,1.76846 -1.32633,2.44861 -0.65753,0.77088 -1.34904,1.34902 -2.07452,1.73443 -0.72554,0.36278 -1.74579,0.54415 -3.06076,0.54413 -1.70045,2e-5 -3.03811,-0.41941 -4.01299,-1.25831 -0.97493,-0.83885 -1.46239,-1.77975 -1.46236,-2.8227 -3e-5,-0.97488 0.13601,-1.81375 0.4081,-2.51662 0.29471,-0.70282 0.74816,-1.76841 1.36034,-3.19679 -1.51907,0.63485 -2.82273,1.41704 -3.91097,2.34658 -1.0883,0.90692 -2.13122,1.94984 -3.12878,3.12877 l -5.37333,24.07797 -11.25679,0 4.69316,-20.91518 c 0.13603,-0.6348 0.30607,-1.46234 0.51013,-2.48262 0.22671,-1.02023 0.34007,-1.87044 0.34008,-2.55063 -1e-5,-1.31497 -0.26074,-2.21052 -0.78219,-2.68667 -0.4988,-0.47609 -1.47371,-0.71414 -2.92473,-0.71417 -0.72552,3e-5 -1.4737,0.11339 -2.24455,0.34008 -0.74819,0.22675 -1.39435,0.44214 -1.93849,0.64616 l 0.74819,-3.06076 c 1.83645,-0.74815 3.59355,-1.38297 5.27131,-1.90447 1.67774,-0.5441 3.2648,-0.81617 4.76118,-0.8162 2.67531,3e-5 4.67047,0.53283 5.98548,1.59839 1.33765,1.04296 2.22187,2.51666 2.65266,4.4211 l 0.23806,0 c 2.24453,-2.38056 4.149,-4.03563 5.71342,-4.96523 1.56436,-0.9522 3.2421,-1.42832 5.03324,-1.42836 1.92711,4e-5 3.44616,0.61219 4.55713,1.83646 1.11091,1.20166 1.66638,2.94743 1.66642,5.2373 m 20.60911,-2.07452 c -1.13364,5.60008 -2.11988,10.46328 -2.95874,14.58962 -0.81622,4.1037 -1.80246,8.40009 -2.95873,12.8892 -0.56682,2.19921 -1.50772,4.35307 -2.8227,6.4616 -1.29233,2.13119 -2.82271,3.96764 -4.59114,5.50937 -1.85913,1.63239 -3.87697,2.90204 -6.0535,3.80894 -2.15387,0.90688 -4.37575,1.36032 -6.66565,1.36034 -2.06318,-2e-5 -3.72959,-0.20407 -4.99924,-0.61215 -1.29231,-0.40812 -2.30123,-0.92958 -3.02675,-1.56439 -0.70283,-0.63484 -1.17895,-1.33768 -1.42836,-2.10852 -0.24938,-0.77087 -0.37408,-1.53039 -0.37409,-2.27857 10e-6,-1.315 0.47613,-2.48262 1.42835,-3.50287 0.92958,-0.99758 2.18789,-1.49637 3.77494,-1.49637 1.22431,0 2.28991,0.31741 3.19679,0.95224 0.88423,0.65749 1.64375,1.43968 2.27857,2.34658 0.63482,0.88421 1.20163,1.87045 1.70042,2.95873 0.47612,1.08826 0.85021,1.93847 1.12228,2.55063 0.95223,-1.04293 1.84779,-2.61865 2.68666,-4.72717 0.83888,-2.08585 1.62107,-4.87454 2.34658,-8.36607 l 6.08751,-28.77114 -6.59763,0 0.8162,-3.50286 6.52962,0 0.57814,-2.61865 c 0.47611,-2.13116 1.33766,-4.217009 2.58464,-6.257555 1.26964,-2.063134 2.80001,-3.899588 4.59114,-5.509366 1.72308,-1.587011 3.7069,-2.87933 5.95148,-3.876961 2.2672,-0.997528 4.53443,-1.496318 6.80168,-1.496371 1.97246,5.3e-5 3.60486,0.192767 4.89722,0.578143 1.31495,0.362809 2.34654,0.872935 3.09477,1.53038 0.68012,0.612202 1.13357,1.303706 1.36033,2.074514 0.24936,0.748233 0.37406,1.496418 0.3741,2.244557 -4e-5,0.498836 -0.10207,1.054306 -0.30608,1.666413 -0.18142,0.612196 -0.47616,1.167666 -0.88422,1.666413 -0.49883,0.56685 -1.03163,1.008959 -1.5984,1.326329 -0.54417,0.317453 -1.34903,0.476159 -2.41459,0.476118 -1.22434,4.1e-5 -2.2786,-0.317371 -3.16279,-0.952236 -0.88425,-0.657454 -1.63243,-1.428311 -2.24456,-2.312574 -0.65752,-0.929518 -1.21299,-1.927098 -1.66641,-2.992742 -0.45347,-1.065549 -0.82756,-1.915759 -1.12228,-2.550632 -0.92959,1.065646 -1.76846,2.618697 -2.51662,4.659155 -0.74821,2.040549 -1.51907,4.85191 -2.31257,8.434095 l -0.85021,3.91097 8.60413,0 -0.8162,3.50286 -8.43409,0 m 47.44176,9.14827 c -4e-5,2.85673 -0.54417,5.58874 -1.6324,8.19603 -1.08831,2.60733 -2.63003,4.87455 -4.62515,6.80169 -2.1539,2.06318 -4.68186,3.66158 -7.58388,4.79519 -2.87941,1.11094 -6.12154,1.66641 -9.72641,1.66641 -4.82921,0 -8.72884,-1.28098 -11.6989,-3.84295 -2.97008,-2.58463 -4.45511,-6.09884 -4.45511,-10.54261 0,-3.0154 0.55547,-5.81543 1.66642,-8.40009 1.13361,-2.58461 2.70933,-4.8405 4.72717,-6.76767 1.99515,-1.88177 4.44375,-3.36681 7.34582,-4.45511 2.90203,-1.11091 6.04214,-1.66638 9.42034,-1.66641 5.1239,3e-5 9.15957,1.25834 12.107,3.77493 2.97003,2.49398 4.45506,5.97418 4.4551,10.44059 M 204.094,114.48462 c -3e-5,-2.65263 -0.45347,-4.60245 -1.36033,-5.84945 -0.88425,-1.24694 -2.17657,-1.87043 -3.87696,-1.87046 -1.74579,3e-5 -3.34419,0.70287 -4.79519,2.10852 -1.45105,1.38304 -2.63001,3.42354 -3.53688,6.12152 -0.79355,2.24457 -1.36035,4.68184 -1.70042,7.31181 -0.3401,2.60733 -0.51014,4.94257 -0.51013,7.00574 -1e-5,2.74335 0.45343,4.73851 1.36034,5.98548 0.90687,1.22431 2.22186,1.83646 3.94498,1.83646 1.8591,0 3.46883,-0.75952 4.82919,-2.27857 1.36032,-1.51904 2.43725,-3.3895 3.2308,-5.61139 0.79351,-2.17653 1.39432,-4.57979 1.80245,-7.20979 0.40807,-2.65264 0.61212,-5.16926 0.61215,-7.54987 m 51.93087,-3.2308 c -4e-5,1.02028 -0.14741,2.00652 -0.44211,2.95873 -0.29478,0.95226 -0.73689,1.76846 -1.32633,2.44861 -0.65753,0.77088 -1.34904,1.34902 -2.07451,1.73443 -0.72555,0.36278 -1.7458,0.54415 -3.06076,0.54413 -1.70045,2e-5 -3.03812,-0.41941 -4.013,-1.25831 -0.97493,-0.83885 -1.46239,-1.77975 -1.46236,-2.8227 -3e-5,-0.97488 0.13601,-1.81375 0.4081,-2.51662 0.29471,-0.70282 0.74816,-1.76841 1.36034,-3.19679 -1.51907,0.63485 -2.82273,1.41704 -3.91097,2.34658 -1.08829,0.90692 -2.13122,1.94984 -3.12878,3.12877 l -5.37333,24.07797 -11.25679,0 4.69316,-20.91518 c 0.13603,-0.6348 0.30607,-1.46234 0.51013,-2.48262 0.22671,-1.02023 0.34007,-1.87044 0.34008,-2.55063 -1e-5,-1.31497 -0.26074,-2.21052 -0.78219,-2.68667 -0.4988,-0.47609 -1.47371,-0.71414 -2.92473,-0.71417 -0.72551,3e-5 -1.4737,0.11339 -2.24455,0.34008 -0.74819,0.22675 -1.39435,0.44214 -1.93848,0.64616 l 0.74818,-3.06076 c 1.83645,-0.74815 3.59356,-1.38297 5.27131,-1.90447 1.67774,-0.5441 3.2648,-0.81617 4.76118,-0.8162 2.67532,3e-5 4.67048,0.53283 5.98548,1.59839 1.33765,1.04296 2.22187,2.51666 2.65266,4.4211 l 0.23806,0 c 2.24453,-2.38056 4.14901,-4.03563 5.71342,-4.96523 1.56436,-0.9522 3.24211,-1.42832 5.03325,-1.42836 1.92711,4e-5 3.44615,0.61219 4.55713,1.83646 1.1109,1.20166 1.66637,2.94743 1.66641,5.2373 m 68.32294,22.24151 -0.74819,3.06076 c -2.24462,0.88422 -4.03573,1.56439 -5.37333,2.04051 -1.33773,0.45344 -2.89078,0.68017 -4.65915,0.68017 -2.69806,0 -4.79525,-0.66884 -6.29156,-2.0065 -1.49643,-1.36033 -2.24461,-3.03808 -2.24456,-5.03325 -5e-5,-0.54413 0.0226,-1.23563 0.068,-2.07451 0.068,-0.86154 0.26068,-1.92714 0.57814,-3.1968 l 2.44861,-9.04624 c 0.24934,-0.97489 0.43072,-1.84777 0.54413,-2.61865 0.13598,-0.7935 0.204,-1.43966 0.20405,-1.93848 -5e-5,-1.08824 -0.27212,-1.93845 -0.8162,-2.55063 -0.54419,-0.61212 -1.42841,-0.9182 -2.65266,-0.91823 -0.86159,3e-5 -1.9612,0.38546 -3.29882,1.15629 -1.31503,0.77088 -2.6527,1.80247 -4.01299,3.09477 l -5.61139,24.55408 -11.25679,0 4.76118,-20.74514 c 0.24936,-1.13359 0.43074,-2.05182 0.54413,-2.75468 0.136,-0.70282 0.20402,-1.31497 0.20405,-1.83646 -3e-5,-1.08824 -0.2721,-1.93845 -0.8162,-2.55063 -0.54416,-0.61212 -1.43972,-0.9182 -2.68667,-0.91823 -0.70286,3e-5 -1.67777,0.28343 -2.92472,0.85021 -1.247,0.56684 -2.81139,1.70045 -4.69317,3.40085 l -5.61139,24.55408 -11.25679,0 4.8292,-20.91518 c 0.13603,-0.6348 0.30607,-1.47368 0.51013,-2.51663 0.22671,-1.0429 0.34007,-1.88177 0.34008,-2.51662 -1e-5,-1.29229 -0.2494,-2.17651 -0.74818,-2.65266 -0.4988,-0.49876 -1.48505,-0.74815 -2.95874,-0.74818 -0.72552,3e-5 -1.4737,0.11339 -2.24455,0.34008 -0.74819,0.22675 -1.39435,0.44214 -1.93849,0.64616 l 0.74819,-3.06076 c 1.83645,-0.74815 3.59355,-1.38297 5.27131,-1.90447 1.67774,-0.5441 3.2648,-0.81617 4.76118,-0.8162 2.766,3e-5 4.76116,0.56684 5.98548,1.70042 1.22429,1.11097 2.08583,2.55066 2.58464,4.31907 l 0.23806,0 c 2.26721,-2.08582 4.45508,-3.67288 6.56363,-4.76118 2.10849,-1.08824 4.53442,-1.63237 7.2778,-1.63241 2.33521,4e-5 4.25102,0.62353 5.74743,1.87047 1.49633,1.24701 2.32387,2.78872 2.48261,4.62515 l 0.23806,0 c 2.42589,-2.08582 4.68178,-3.68422 6.76768,-4.79519 2.0858,-1.13358 4.46639,-1.70039 7.14177,-1.70043 2.51657,4e-5 4.48905,0.69154 5.91747,2.07452 1.42829,1.38304 2.14247,3.06079 2.14253,5.03325 -6e-5,0.52149 -0.0454,1.25834 -0.13603,2.21055 -0.0681,0.92958 -0.24946,1.92716 -0.54414,2.99274 l -2.58464,9.55637 c -0.22678,0.79354 -0.43083,1.70043 -0.61215,2.72067 -0.18144,1.02026 -0.27213,1.79112 -0.27207,2.31257 -6e-5,1.315 0.28334,2.21056 0.85021,2.68667 0.58942,0.47612 1.60967,0.71418 3.06076,0.71418 0.6801,0 1.45096,-0.11336 2.31257,-0.34009 0.86148,-0.24939 1.48497,-0.46477 1.87047,-0.64616 m 42.98666,-15.16776 c -4e-5,2.85673 -0.54417,5.58874 -1.6324,8.19603 -1.08831,2.60733 -2.63003,4.87455 -4.62515,6.80169 -2.1539,2.06318 -4.68186,3.66158 -7.58388,4.79519 -2.87941,1.11094 -6.12154,1.66641 -9.72641,1.66641 -4.82921,0 -8.72884,-1.28098 -11.6989,-3.84295 -2.97008,-2.58463 -4.45511,-6.09884 -4.45511,-10.54261 0,-3.0154 0.55547,-5.81543 1.66642,-8.40009 1.13361,-2.58461 2.70933,-4.8405 4.72717,-6.76767 1.99515,-1.88177 4.44375,-3.36681 7.34582,-4.45511 2.90203,-1.11091 6.04214,-1.66638 9.42034,-1.66641 5.1239,3e-5 9.15957,1.25834 12.107,3.77493 2.97003,2.49398 4.45506,5.97418 4.4551,10.44059 m -11.97097,-3.84295 c -3e-5,-2.65263 -0.45347,-4.60245 -1.36033,-5.84945 -0.88425,-1.24694 -2.17657,-1.87043 -3.87696,-1.87046 -1.74579,3e-5 -3.34419,0.70287 -4.79519,2.10852 -1.45105,1.38304 -2.63001,3.42354 -3.53688,6.12152 -0.79355,2.24457 -1.36035,4.68184 -1.70042,7.31181 -0.3401,2.60733 -0.51014,4.94257 -0.51013,7.00574 -1e-5,2.74335 0.45343,4.73851 1.36034,5.98548 0.90687,1.22431 2.22187,1.83646 3.94498,1.83646 1.8591,0 3.46883,-0.75952 4.82919,-2.27857 1.36032,-1.51904 2.43725,-3.3895 3.23081,-5.61139 0.7935,-2.17653 1.39431,-4.57979 1.80244,-7.20979 0.40807,-2.65264 0.61212,-5.16926 0.61215,-7.54987 m 41.62631,18.80666 -0.23805,0 c -2.38062,2.17655 -4.64785,3.78628 -6.80169,4.8292 -2.15389,1.04293 -4.64784,1.56439 -7.48186,1.56439 -2.51663,0 -4.46644,-0.69151 -5.84945,-2.07452 -1.36034,-1.383 -2.04051,-3.06075 -2.0405,-5.03324 -10e-6,-0.70284 0.034,-1.41701 0.10202,-2.14254 0.0907,-0.7255 0.30607,-1.74575 0.64616,-3.06075 l 2.55064,-9.55637 c 0.15869,-0.63481 0.34007,-1.49635 0.54413,-2.58464 0.22671,-1.11092 0.34008,-1.92712 0.34009,-2.44861 -10e-6,-1.24695 -0.26075,-2.11983 -0.7822,-2.61865 -0.4988,-0.52143 -1.48504,-0.78217 -2.95873,-0.78219 -0.72552,2e-5 -1.47371,0.11339 -2.24456,0.34008 -0.74819,0.22675 -1.39435,0.44214 -1.93848,0.64616 l 0.74819,-3.06076 c 1.83645,-0.74815 3.59355,-1.38298 5.2713,-1.90447 1.67774,-0.5441 3.2648,-0.81617 4.76118,-0.8162 2.69799,3e-5 4.7725,0.6802 6.22355,2.0405 1.47368,1.3377 2.21052,3.00411 2.21054,4.99924 -2e-5,0.40813 -0.0454,1.15631 -0.13603,2.24456 -0.0907,1.08829 -0.27209,2.09721 -0.54413,3.02675 l -2.48262,9.04624 c -0.22674,0.79354 -0.40812,1.65509 -0.54413,2.58464 -0.13605,0.9069 -0.20407,1.5644 -0.20406,1.97249 -10e-6,1.06561 0.24938,1.91582 0.74819,2.55063 0.49877,0.61216 1.36032,0.91824 2.58464,0.91823 0.8842,1e-5 2.05182,-0.36275 3.50287,-1.08827 1.47367,-0.74818 2.9247,-1.80244 4.35308,-3.16278 l 5.61139,-24.55409 10.84869,-0.47612 0.4081,0.47612 -4.8292,20.91519 c -0.15874,0.6575 -0.35146,1.53039 -0.57814,2.61864 -0.20409,1.08828 -0.30611,1.89315 -0.30608,2.4146 -3e-5,1.315 0.28337,2.21056 0.85022,2.68667 0.58943,0.47612 1.60969,0.71418 3.06075,0.71418 0.68013,0 1.45099,-0.11336 2.31258,-0.34009 0.8615,-0.24939 1.48499,-0.46477 1.87046,-0.64616 l -0.74818,3.06076 c -2.2446,0.88422 -4.03571,1.56439 -5.37334,2.04051 -1.3377,0.45344 -2.89075,0.68016 -4.65915,0.68017 -2.49399,-1e-5 -4.48915,-0.55548 -5.98549,-1.66642 -1.4964,-1.13361 -2.43729,-2.58463 -2.8227,-4.35308 m 35.23273,6.52962 c -2.85672,0 -5.22597,-0.23806 -7.10776,-0.71418 -1.85913,-0.45344 -3.33283,-1.04292 -4.42109,-1.76843 -1.11095,-0.72551 -1.87047,-1.49637 -2.27857,-2.31258 -0.4081,-0.83887 -0.61215,-1.62106 -0.61215,-2.34658 0,-1.31498 0.48745,-2.45993 1.46236,-3.43485 0.99758,-0.99757 2.31257,-1.49636 3.94498,-1.49637 1.36033,10e-6 2.49394,0.35143 3.40084,1.05426 0.92956,0.70285 1.70041,1.58707 2.31258,2.65266 0.56679,0.97491 1.04291,2.05184 1.42835,3.2308 0.38542,1.17896 0.65748,2.05184 0.8162,2.61865 2.56196,0 4.50043,-0.54414 5.81545,-1.63241 1.31497,-1.11093 1.97246,-2.61864 1.97248,-4.52312 -2e-5,-0.83886 -0.20407,-1.5417 -0.61215,-2.10852 -0.38545,-0.5668 -0.90691,-1.06559 -1.56439,-1.49637 -0.65751,-0.40809 -1.49638,-0.80486 -2.51662,-1.1903 -1.02027,-0.38541 -2.02918,-0.74817 -3.02675,-1.08827 -2.74336,-0.92955 -4.9199,-2.21053 -6.52962,-3.84295 -1.58706,-1.65506 -2.38059,-3.7069 -2.38059,-6.15553 0,-1.451 0.32874,-2.81133 0.98625,-4.08101 0.68016,-1.29229 1.73442,-2.48258 3.16278,-3.57088 1.40567,-1.0429 3.18544,-1.87043 5.33932,-2.48262 2.15385,-0.63479 4.67048,-0.9522 7.54988,-0.95224 1.72307,4e-5 3.32146,0.10206 4.79518,0.30608 1.47368,0.20409 2.84535,0.57818 4.11502,1.12228 1.2016,0.54417 2.13117,1.25834 2.7887,2.14253 0.68013,0.86158 1.02021,1.91584 1.02025,3.16278 -4e-5,1.24701 -0.47615,2.32394 -1.42835,3.23081 -0.9296,0.88424 -2.1539,1.32635 -3.67292,1.32632 -1.31502,3e-5 -2.41462,-0.34006 -3.29881,-1.02025 -0.86158,-0.68014 -1.56442,-1.48501 -2.10853,-2.4146 -0.54415,-0.95221 -0.97493,-1.92711 -1.29232,-2.92472 -0.31743,-1.02022 -0.57816,-1.87043 -0.78219,-2.55063 -1.58708,0.0907 -3.03811,0.66886 -4.35308,1.73443 -1.29234,1.04295 -1.9385,2.34661 -1.93848,3.91096 -2e-5,0.95227 0.14735,1.70045 0.44211,2.24456 0.31739,0.54416 0.73683,0.99761 1.25831,1.36034 0.58946,0.40812 1.32631,0.79355 2.21055,1.15629 0.90687,0.3401 2.02915,0.73687 3.36683,1.19029 3.08341,1.08829 5.40732,2.39195 6.97173,3.91097 1.56436,1.51906 2.34655,3.52555 2.34658,6.01949 -3e-5,1.63242 -0.38546,3.1968 -1.15628,4.69317 -0.74822,1.49637 -1.82515,2.74335 -3.2308,3.74092 -1.56442,1.08827 -3.36686,1.90448 -5.40734,2.44861 -2.04053,0.56681 -4.63651,0.85021 -7.78794,0.85021"
+         style="font-size:69.6492691px;font-style:italic;font-variant:normal;font-weight:bold;font-stretch:normal;fill:#000000;fill-opacity:1;stroke:none;filter:url(#filter3869-9);font-family:Goblin;-inkscape-font-specification:Goblin Bold Italic"
+         transform="matrix(0.8191171,0,0,1.0292651,21.130469,31.087293)" />
+      <path
+         inkscape:connector-curvature="0"
+         id="text2462"
+         d="m 82.144747,134.60581 c -4.3e-5,2.87033 -0.529324,5.44893 -1.587843,7.73581 -1.04003,2.2636 -2.544301,4.16547 -4.512815,5.7056 -1.950018,1.49351 -4.132138,2.60196 -6.546369,3.32535 -2.39572,0.72343 -5.042122,1.08514 -7.939213,1.08512 l -4.011391,0 -2.479263,13.47642 c -0.0743,0.39672 -0.1393,0.77009 -0.194998,1.12012 -0.03716,0.35004 -0.05573,0.6184 -0.05571,0.80508 -1.6e-5,1.05012 0.343553,1.8202 1.030705,2.31024 0.687119,0.49006 2.033534,0.86343 4.039248,1.12012 l -0.473567,2.55527 -21.477659,0 0.473567,-2.55527 c 0.464282,-0.0233 1.151418,-0.105 2.06141,-0.24502 0.92856,-0.16335 1.615696,-0.33837 2.061409,-0.52506 0.724276,-0.30337 1.272127,-0.75841 1.643556,-1.36514 0.389991,-0.60673 0.659275,-1.31847 0.80785,-2.13523 l 6.379227,-34.72366 c 0.09284,-0.49 0.157844,-0.89838 0.194998,-1.22513 0.03713,-0.32666 0.0557,-0.57168 0.05571,-0.73507 -1.2e-5,-0.98007 -0.399294,-1.73848 -1.197846,-2.27525 -0.780003,-0.56001 -2.061419,-1.00338 -3.84425,-1.33013 l 0.473567,-2.55528 21.421945,0 c 4.605639,6e-5 8.032032,0.85181 10.279191,2.55528 2.265652,1.70356 3.398498,4.32882 3.398541,7.87583 m -11.644179,5.84561 c 0.408536,-1.75015 0.61282,-3.66368 0.612851,-5.7406 -3.1e-5,-2.52023 -0.538597,-4.39876 -1.615699,-5.6356 -1.077162,-1.26009 -2.832144,-1.89016 -5.264952,-1.8902 l -2.033552,0 -4.067106,22.15734 1.810698,0 c 2.005674,2e-5 3.723513,-0.37335 5.153524,-1.12012 1.448531,-0.77006 2.618519,-1.83183 3.509968,-3.18534 0.854248,-1.30677 1.48567,-2.83527 1.894268,-4.58548 m 24.514062,34.54864 c -2.228569,0 -4.187834,-0.38504 -5.877806,-1.15512 -1.671421,-0.74675 -3.054978,-1.79685 -4.150676,-3.15033 -1.077137,-1.35347 -1.884986,-2.92864 -2.423549,-4.72549 -0.538569,-1.79686 -0.807851,-3.7804 -0.80785,-5.95064 -10e-7,-2.75361 0.408566,-5.42555 1.225703,-8.01585 0.817131,-2.59024 2.033548,-4.92382 3.649252,-7.00073 1.522835,-1.98351 3.454248,-3.59369 5.79423,-4.83051 2.339965,-1.23677 4.921365,-1.85516 7.744216,-1.85519 3.32423,3e-5 5.84992,0.6651 7.57707,1.99521 1.74567,1.33017 2.61852,3.32538 2.61855,5.98563 -3e-5,2.54362 -0.75216,4.73718 -2.25641,6.58069 -1.50429,1.82021 -3.54713,3.17368 -6.12851,4.06043 -2.042864,0.7701 -3.788553,1.31848 -5.237095,1.64518 -1.430005,0.32671 -3.18499,0.63008 -5.264954,0.91008 0.03713,1.02679 0.14856,2.18192 0.334284,3.46538 0.185698,1.28347 0.464271,2.38026 0.835702,3.29034 0.445698,1.05012 1.077121,1.8902 1.894276,2.52027 0.81712,0.60673 1.857103,0.9101 3.119965,0.91009 2.191396,1e-5 4.048512,-0.52505 5.571382,-1.57517 1.54139,-1.07343 3.00851,-2.76527 4.40139,-5.07553 l 2.03355,2.13523 c -1.67144,2.98698 -3.81642,5.3789 -6.43494,7.17576 -2.6,1.77351 -5.33926,2.66027 -8.21778,2.66027 m 6.29565,-27.72292 c -2e-5,-1.98352 -0.28787,-3.50033 -0.86356,-4.55048 -0.575732,-1.07341 -1.374296,-1.61014 -2.395696,-1.61016 -1.429996,2e-5 -2.785699,1.47018 -4.067099,4.41045 -1.262862,2.917 -2.070713,6.61572 -2.423553,11.09617 1.095693,-0.16333 2.182109,-0.37336 3.259256,-0.63007 1.07712,-0.25666 1.931395,-0.56003 2.562836,-0.91008 1.392822,-0.77007 2.395666,-1.76184 3.008546,-2.97533 0.61283,-1.21343 0.91925,-2.8236 0.91927,-4.8305 m 41.06105,-1.68017 c -3e-5,1.05014 -0.12074,2.06523 -0.36214,3.04531 -0.24145,0.98013 -0.60359,1.82022 -1.08641,2.52027 -0.5386,0.79344 -1.10503,1.3885 -1.69928,1.78519 -0.5943,0.37339 -1.43001,0.56007 -2.50711,0.56005 -1.39287,2e-5 -2.48858,-0.43168 -3.28712,-1.29513 -0.79858,-0.8634 -1.19786,-1.83183 -1.19784,-2.90531 -2e-5,-1.00341 0.1114,-1.86683 0.33428,-2.59027 0.2414,-0.72338 0.61283,-1.82017 1.11428,-3.29035 -1.2443,0.65343 -2.31214,1.45852 -3.20355,2.41526 -0.89144,0.93345 -1.74572,2.0069 -2.56284,3.22034 l -4.40138,24.78261 -9.22063,0 3.84426,-21.52727 c 0.11141,-0.65338 0.2507,-1.50514 0.41784,-2.55527 0.18571,-1.05008 0.27857,-1.92517 0.27858,-2.62528 -10e-6,-1.35345 -0.21358,-2.2752 -0.64071,-2.76529 -0.40858,-0.49002 -1.20715,-0.73504 -2.3957,-0.73508 -0.59428,4e-5 -1.20713,0.11672 -1.83855,0.35005 -0.61285,0.23338 -1.14214,0.45507 -1.58784,0.66506 l 0.61284,-3.15033 c 1.50428,-0.77005 2.94355,-1.42345 4.31782,-1.96021 1.37427,-0.56002 2.67425,-0.84005 3.89997,-0.84008 2.1914,3e-5 3.82566,0.54842 4.90281,1.64517 1.09569,1.07347 1.81997,2.5903 2.17284,4.55048 l 0.19499,0 c 1.83854,-2.45023 3.39852,-4.15374 4.67997,-5.11054 1.28139,-0.98007 2.65566,-1.47012 4.12282,-1.47015 1.57852,3e-5 2.8228,0.63009 3.73282,1.8902 0.90996,1.23682 1.36495,3.03368 1.36498,5.39057 m 16.88128,-2.13523 c -0.92858,5.76396 -1.73643,10.76949 -2.42355,15.01659 -0.66858,4.22378 -1.47643,8.64591 -2.42355,13.26639 -0.46429,2.26357 -1.235,4.48047 -2.31212,6.6507 -1.05857,2.19355 -2.31213,4.08375 -3.76068,5.6706 -1.52285,1.68016 -3.17569,2.98696 -4.95853,3.92041 -1.76427,0.93342 -3.58424,1.40014 -5.45995,1.40015 -1.68997,-1e-5 -3.05496,-0.21003 -4.09495,-0.63007 -1.05856,-0.42006 -1.88498,-0.95677 -2.47927,-1.61017 -0.5757,-0.65341 -0.9657,-1.37682 -1.16999,-2.17023 -0.20427,-0.79342 -0.30641,-1.57517 -0.30643,-2.34524 2e-5,-1.35348 0.39002,-2.55528 1.17,-3.60538 0.76142,-1.02678 1.79213,-1.54017 3.09211,-1.54017 1.00285,0 1.8757,0.32671 2.61855,0.9801 0.72428,0.67674 1.34641,1.48182 1.8664,2.41526 0.52001,0.91009 0.98429,1.9252 1.39285,3.04533 0.39,1.1201 0.69642,1.9952 0.91928,2.62527 0.77999,-1.07346 1.51356,-2.6953 2.20069,-4.86551 0.68714,-2.1469 1.32784,-5.0172 1.92213,-8.61091 l 4.98638,-29.61312 -5.40424,0 0.66857,-3.60538 5.34852,0 0.47357,-2.69529 c 0.38999,-2.19352 1.09569,-4.34042 2.11712,-6.44067 1.03998,-2.12352 2.29354,-4.01372 3.76068,-5.67061 1.4114,-1.63345 3.03639,-2.96359 4.87495,-3.99042 1.85711,-1.02671 3.71423,-1.5401 5.57138,-1.54016 1.61568,6e-5 2.95281,0.19841 4.0114,0.59507 1.0771,0.37342 1.92209,0.89848 2.53497,1.57516 0.55711,0.63011 0.92853,1.34186 1.11428,2.13523 0.20425,0.77012 0.30639,1.54021 0.30642,2.31024 -3e-5,0.51344 -0.0836,1.08516 -0.25071,1.71518 -0.1486,0.63011 -0.39003,1.20184 -0.72428,1.71518 -0.4086,0.58344 -0.84502,1.03849 -1.30927,1.36515 -0.44574,0.32674 -1.10502,0.49009 -1.97784,0.49005 -1.00288,4e-5 -1.86644,-0.32666 -2.59069,-0.98011 -0.72431,-0.67669 -1.33716,-1.47011 -1.83856,-2.38025 -0.53859,-0.95672 -0.99358,-1.9835 -1.36498,-3.08032 -0.37145,-1.09673 -0.67787,-1.97183 -0.91928,-2.62528 -0.76145,1.09683 -1.44858,2.69534 -2.06141,4.7955 -0.61287,2.10027 -1.24429,4.99391 -1.89427,8.68092 l -0.69642,4.02543 7.04779,0 -0.66857,3.60538 -6.9085,0 m 38.86035,9.41599 c -3e-5,2.94033 -0.44575,5.75228 -1.33713,8.43589 -0.89145,2.68362 -2.1543,5.01721 -3.78854,7.00074 -1.7643,2.12356 -3.83498,3.76872 -6.21209,4.93552 -2.35856,1.14345 -5.01425,1.71517 -7.96706,1.71517 -3.95569,0 -7.14994,-1.31846 -9.58277,-3.95541 -2.43283,-2.66028 -3.64925,-6.27731 -3.64925,-10.85114 0,-3.10365 0.45499,-5.98562 1.36498,-8.64592 0.92856,-2.66025 2.21926,-4.98216 3.87211,-6.96573 1.63427,-1.93684 3.63996,-3.46533 6.01709,-4.58548 2.37711,-1.14342 4.94922,-1.71515 7.71635,-1.71519 4.19709,4e-5 7.50277,1.29517 9.91706,3.88541 2.4328,2.56697 3.64922,6.14901 3.64925,10.74614 m -9.80562,-3.95542 c -3e-5,-2.73026 -0.37145,-4.73714 -1.11428,-6.02063 -0.7243,-1.28344 -1.78286,-1.92517 -3.17568,-1.9252 -1.43001,3e-5 -2.73928,0.72344 -3.92783,2.17022 -1.18857,1.42352 -2.15428,3.52373 -2.89711,6.30067 -0.65001,2.31027 -1.11429,4.81886 -1.39285,7.5258 -0.27857,2.68362 -0.41786,5.08721 -0.41785,7.21075 -1e-5,2.82364 0.37142,4.87719 1.11428,6.16065 0.74283,1.26013 1.81996,1.8902 3.2314,1.8902 1.52282,0 2.84138,-0.78174 3.95567,-2.34525 1.11426,-1.56349 1.99639,-3.48869 2.64641,-5.77561 0.64997,-2.24022 1.14211,-4.71381 1.47641,-7.42078 0.33426,-2.73026 0.5014,-5.32053 0.50143,-7.77082 m 42.53746,-3.32534 c -3e-5,1.05014 -0.12075,2.06523 -0.36214,3.04531 -0.24145,0.98013 -0.6036,1.82022 -1.08641,2.52027 -0.5386,0.79344 -1.10503,1.3885 -1.69928,1.78519 -0.59431,0.37339 -1.43001,0.56007 -2.50711,0.56005 -1.39288,2e-5 -2.48858,-0.43168 -3.28712,-1.29513 -0.79858,-0.8634 -1.19786,-1.83183 -1.19785,-2.90531 -1e-5,-1.00341 0.11141,-1.86683 0.33429,-2.59027 0.2414,-0.72338 0.61283,-1.82017 1.11427,-3.29035 -1.24429,0.65343 -2.31214,1.45852 -3.20354,2.41526 -0.89144,0.93345 -1.74572,2.0069 -2.56284,3.22034 l -4.40138,24.78261 -9.22063,0 3.84424,-21.52727 c 0.11143,-0.65338 0.25071,-1.50514 0.41786,-2.55527 0.18571,-1.05008 0.27857,-1.92517 0.27857,-2.62528 0,-1.35345 -0.21357,-2.2752 -0.64071,-2.76529 -0.40857,-0.49002 -1.20714,-0.73504 -2.39569,-0.73508 -0.59428,4e-5 -1.20713,0.11672 -1.83855,0.35005 -0.61285,0.23338 -1.14214,0.45507 -1.58785,0.66506 l 0.61285,-3.15033 c 1.50427,-0.77005 2.94355,-1.42345 4.31782,-1.96021 1.37427,-0.56002 2.67425,-0.84005 3.89997,-0.84008 2.19139,3e-5 3.82566,0.54842 4.90281,1.64517 1.09569,1.07347 1.81996,2.5903 2.17284,4.55048 l 0.19499,0 c 1.83854,-2.45023 3.39852,-4.15374 4.67996,-5.11054 1.2814,-0.98007 2.65566,-1.47012 4.12282,-1.47015 1.57853,3e-5 2.8228,0.63009 3.73283,1.8902 0.90996,1.23682 1.36495,3.03368 1.36498,5.39057 m 55.96449,22.8924 -0.61285,3.15034 c -1.83861,0.9101 -3.30574,1.61017 -4.4014,2.10022 -1.09574,0.46672 -2.36787,0.70008 -3.81639,0.70008 -2.21002,0 -3.92786,-0.68841 -5.15352,-2.06523 -1.22574,-1.40014 -1.83859,-3.12699 -1.83856,-5.18054 -3e-5,-0.56005 0.0185,-1.27179 0.0557,-2.13522 0.0557,-0.88676 0.21352,-1.98353 0.47357,-3.29035 l 2.0057,-9.31098 c 0.20423,-1.00342 0.3528,-1.90185 0.4457,-2.69529 0.11139,-0.81673 0.1671,-1.4818 0.16715,-1.99521 -5e-5,-1.12008 -0.2229,-1.99519 -0.66857,-2.62528 -0.44575,-0.63003 -1.17003,-0.94507 -2.17283,-0.94509 -0.70576,2e-5 -1.60646,0.39673 -2.70212,1.19012 -1.07718,0.79344 -2.17288,1.85523 -3.28712,3.18534 l -4.59638,25.27266 -9.22063,0 3.89996,-21.35225 c 0.20425,-1.16677 0.35283,-2.11186 0.44571,-2.8353 0.1114,-0.72339 0.16711,-1.35345 0.16714,-1.8902 -3e-5,-1.12008 -0.22288,-1.99519 -0.66856,-2.62528 -0.44574,-0.63003 -1.1793,-0.94507 -2.2007,-0.94509 -0.57573,2e-5 -1.37429,0.29172 -2.39569,0.87509 -1.02144,0.58342 -2.30286,1.75021 -3.84425,3.50037 l -4.59638,25.27266 -9.22063,0 3.95567,-21.52727 c 0.11143,-0.65338 0.25071,-1.5168 0.41786,-2.59028 0.1857,-1.07342 0.27855,-1.93684 0.27856,-2.59027 -10e-6,-1.33011 -0.20429,-2.24021 -0.61285,-2.73028 -0.40857,-0.51336 -1.21642,-0.77005 -2.42355,-0.77009 -0.59428,4e-5 -1.20713,0.11672 -1.83856,0.35005 -0.61284,0.23338 -1.14212,0.45507 -1.58784,0.66506 l 0.61286,-3.15033 c 1.50426,-0.77005 2.94354,-1.42345 4.31781,-1.96021 1.37427,-0.56002 2.67426,-0.84005 3.89997,-0.84008 2.26568,3e-5 3.89995,0.58343 4.90281,1.75018 1.00283,1.14349 1.70854,2.62531 2.11713,4.44547 l 0.19499,0 c 1.85711,-2.14686 3.64923,-3.78037 5.37638,-4.90052 1.7271,-1.12008 3.71423,-1.68014 5.96138,-1.68017 1.9128,3e-5 3.48207,0.64176 4.70781,1.92519 1.22567,1.28351 1.90352,2.87034 2.03355,4.76051 l 0.195,0 c 1.98709,-2.14686 3.83493,-3.79204 5.54352,-4.93552 1.70851,-1.16675 3.6585,-1.75015 5.84995,-1.75018 2.06136,3e-5 3.67705,0.71178 4.84709,2.13522 1.16994,1.42352 1.75494,3.15036 1.75499,5.18054 -5e-5,0.53675 -0.0372,1.29517 -0.11143,2.27524 -0.0558,0.9568 -0.20434,1.98358 -0.44571,3.08033 l -2.11712,9.83604 c -0.18577,0.81676 -0.35291,1.7502 -0.50143,2.80029 -0.14862,1.05012 -0.2229,1.84354 -0.22285,2.38025 -5e-5,1.35348 0.23209,2.27525 0.69642,2.7653 0.4828,0.49005 1.31851,0.73508 2.50712,0.73507 0.55708,1e-5 1.1885,-0.11667 1.89427,-0.35003 0.70565,-0.25669 1.21636,-0.47838 1.53213,-0.66508 m 35.21112,-15.61164 c -4e-5,2.94033 -0.44574,5.75228 -1.33713,8.43589 -0.89146,2.68362 -2.1543,5.01721 -3.78854,7.00074 -1.7643,2.12356 -3.83499,3.76872 -6.21208,4.93552 -2.35857,1.14345 -5.01426,1.71517 -7.96707,1.71517 -3.9557,0 -7.14995,-1.31846 -9.58278,-3.95541 -2.43283,-2.66028 -3.64925,-6.27731 -3.64925,-10.85114 0,-3.10365 0.45499,-5.98562 1.36499,-8.64592 0.92856,-2.66025 2.21926,-4.98216 3.87211,-6.96573 1.63426,-1.93684 3.63995,-3.46533 6.01709,-4.58548 2.3771,-1.14342 4.94922,-1.71515 7.71636,-1.71519 4.19707,4e-5 7.50275,1.29517 9.91705,3.88541 2.43279,2.56697 3.64921,6.14901 3.64925,10.74614 m -9.80563,-3.95542 c -3e-5,-2.73026 -0.37145,-4.73714 -1.11427,-6.02063 -0.7243,-1.28344 -1.78287,-1.92517 -3.17569,-1.9252 -1.43,3e-5 -2.73927,0.72344 -3.92781,2.17022 -1.18858,1.42352 -2.15429,3.52373 -2.89713,6.30067 -0.65,2.31027 -1.11428,4.81886 -1.39284,7.5258 -0.27858,2.68362 -0.41786,5.08721 -0.41785,7.21075 -1e-5,2.82364 0.37141,4.87719 1.11427,6.16065 0.74284,1.26013 1.81997,1.8902 3.2314,1.8902 1.52283,0 2.84138,-0.78174 3.95568,-2.34525 1.11425,-1.56349 1.99639,-3.48869 2.6464,-5.77561 0.64997,-2.24022 1.14211,-4.71381 1.47642,-7.42078 0.33426,-2.73026 0.50139,-5.32053 0.50142,-7.77082 m 34.09681,19.35704 -0.19499,0 c -1.95,2.24024 -3.80712,3.89709 -5.57138,4.97053 -1.76429,1.07345 -3.80712,1.61016 -6.12851,1.61016 -2.06142,0 -3.65855,-0.71173 -4.79139,-2.13522 -1.11428,-1.42348 -1.67141,-3.15032 -1.67141,-5.18054 0,-0.7234 0.0279,-1.45848 0.0836,-2.20523 0.0743,-0.74674 0.25071,-1.79685 0.52928,-3.15034 l 2.08926,-9.83603 c 0.13,-0.65339 0.27857,-1.54015 0.44572,-2.66028 0.18571,-1.14344 0.27855,-1.98352 0.27856,-2.52027 -1e-5,-1.28344 -0.21357,-2.18187 -0.64071,-2.69528 -0.40856,-0.5367 -1.21642,-0.80506 -2.42354,-0.80509 -0.59428,3e-5 -1.20713,0.1167 -1.83856,0.35003 -0.61285,0.2334 -1.14213,0.45508 -1.58784,0.66508 l 0.61285,-3.15034 c 1.50427,-0.77004 2.94355,-1.42344 4.31782,-1.9602 1.37427,-0.56002 2.67425,-0.84006 3.89997,-0.8401 2.20997,4e-5 3.90923,0.70011 5.09781,2.10023 1.20711,1.37684 1.81068,3.09202 1.81069,5.14555 -1e-5,0.42006 -0.0372,1.19014 -0.11143,2.31024 -0.0743,1.12014 -0.22287,2.15858 -0.4457,3.11532 l -2.03356,9.31099 c -0.18573,0.81676 -0.3343,1.70352 -0.44571,2.66028 -0.11144,0.93344 -0.16715,1.61017 -0.16714,2.03021 -10e-6,1.09679 0.20427,1.97188 0.61285,2.62528 0.40856,0.63007 1.11426,0.9451 2.11713,0.94509 0.72426,1e-5 1.68068,-0.37336 2.86926,-1.12011 1.2071,-0.77007 2.39566,-1.85519 3.56568,-3.25535 l 4.59638,-25.27266 8.88635,-0.49005 0.33428,0.49005 -3.95567,21.52727 c -0.13003,0.67675 -0.28789,1.57518 -0.47357,2.69529 -0.16718,1.12012 -0.25075,1.94854 -0.25071,2.48526 -4e-5,1.35348 0.2321,2.27525 0.69642,2.76529 0.48281,0.49006 1.31853,0.73508 2.50711,0.73508 0.5571,0 1.18853,-0.11668 1.89428,-0.35004 0.70566,-0.25669 1.21637,-0.47837 1.53212,-0.66507 l -0.61285,3.15033 c -1.83859,0.91009 -3.30571,1.61017 -4.40139,2.10022 -1.09573,0.46672 -2.36786,0.70007 -3.81639,0.70007 -2.04287,0 -3.67713,-0.57172 -4.90281,-1.71517 -1.22573,-1.1668 -1.99643,-2.66027 -2.31213,-4.48048 m 28.85975,6.72071 c -2.33998,0 -4.28068,-0.24503 -5.82208,-0.73508 -1.52286,-0.46671 -2.72998,-1.07344 -3.6214,-1.82018 -0.91,-0.74675 -1.53213,-1.54017 -1.86641,-2.38025 -0.33428,-0.86342 -0.50143,-1.66851 -0.50143,-2.41526 0,-1.35347 0.39929,-2.53193 1.19785,-3.53538 0.81713,-1.02676 1.89427,-1.54014 3.2314,-1.54015 1.11427,1e-5 2.04283,0.36171 2.78568,1.08511 0.76142,0.72341 1.39285,1.63351 1.89427,2.73028 0.46427,1.00345 0.85427,2.1119 1.17,3.32535 0.31569,1.21347 0.53855,2.1119 0.66856,2.69529 2.09854,0 3.68638,-0.56006 4.76352,-1.68018 1.07712,-1.14344 1.61569,-2.69528 1.61571,-4.65548 -2e-5,-0.86342 -0.16716,-1.58684 -0.50143,-2.17024 -0.31573,-0.58338 -0.74286,-1.09677 -1.28142,-1.54016 -0.53858,-0.42003 -1.22571,-0.82841 -2.06141,-1.22513 -0.83572,-0.3967 -1.66213,-0.77007 -2.47925,-1.12012 -2.24714,-0.95675 -4.02998,-2.27523 -5.34853,-3.95541 -1.29999,-1.70349 -1.94998,-3.81538 -1.94998,-6.33568 0,-1.49345 0.26928,-2.8936 0.80785,-4.20044 0.55713,-1.33011 1.4207,-2.55523 2.59069,-3.67538 1.15141,-1.07341 2.60925,-1.92518 4.37353,-2.55527 1.76426,-0.65337 3.82567,-0.98007 6.18423,-0.9801 1.4114,3e-5 2.72067,0.10504 3.92782,0.31502 1.2071,0.21006 2.33067,0.59511 3.37068,1.15513 0.98426,0.56009 1.74568,1.29517 2.28427,2.20523 0.55711,0.8868 0.83567,1.97191 0.83571,3.25534 -4e-5,1.2835 -0.39003,2.39196 -1.17,3.32536 -0.76144,0.91012 -1.76429,1.36516 -3.00854,1.36514 -1.07716,2e-5 -1.97786,-0.35001 -2.70212,-1.05011 -0.70572,-0.70005 -1.28143,-1.52847 -1.72712,-2.48526 -0.44574,-0.98008 -0.79858,-1.98352 -1.05857,-3.01032 -0.26002,-1.05008 -0.47358,-1.92517 -0.64071,-2.62528 -1.3,0.0934 -2.48856,0.68844 -3.56568,1.78519 -1.05857,1.07348 -1.58785,2.41529 -1.58784,4.02543 -10e-6,0.98012 0.1207,1.75021 0.36215,2.31024 0.25998,0.56008 0.60354,1.0268 1.0307,1.40015 0.48284,0.42007 1.0864,0.81677 1.8107,1.19013 0.74283,0.35005 1.6621,0.75843 2.75783,1.22512 2.52567,1.12014 4.42922,2.46194 5.71066,4.02542 1.28139,1.56352 1.9221,3.62874 1.92212,6.19566 -2e-5,1.68019 -0.31574,3.29036 -0.94713,4.83051 -0.61288,1.54017 -1.49501,2.82364 -2.64641,3.8504 -1.28143,1.12012 -2.75784,1.96021 -4.42924,2.52027 -1.67143,0.5834 -3.79784,0.87509 -6.37923,0.87509"
+         style="font-size:63.95185852px;font-style:italic;font-variant:normal;font-weight:bold;font-stretch:normal;fill:#c7e5ff;fill-opacity:1;stroke:none;font-family:Goblin;-inkscape-font-specification:Goblin Bold Italic" />
+    </g>
+  </g>
+</svg>
diff --git a/data/themes/default/mainmenu_back_highlight.svg b/data/themes/default/mainmenu_back_highlight.svg
new file mode 100644 (file)
index 0000000..18beace
--- /dev/null
@@ -0,0 +1,271 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Sodipodi ("http://www.sodipodi.com/") -->
+
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://creativecommons.org/ns#"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:xlink="http://www.w3.org/1999/xlink"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   version="1.0"
+   x="0"
+   y="0"
+   width="400"
+   height="80"
+   id="svg559"
+   sodipodi:version="0.32"
+   inkscape:version="0.48.4 r9939"
+   sodipodi:docname="mainmenu_back_highlight.svg"
+   inkscape:output_extension="org.inkscape.output.svg.inkscape">
+  <metadata
+     id="metadata35">
+    <rdf:RDF>
+      <cc:Work
+         rdf:about="">
+        <dc:format>image/svg+xml</dc:format>
+        <dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+        <dc:title />
+      </cc:Work>
+    </rdf:RDF>
+  </metadata>
+  <sodipodi:namedview
+     inkscape:window-height="879"
+     inkscape:window-width="1376"
+     inkscape:pageshadow="2"
+     inkscape:pageopacity="0.0"
+     guidetolerance="10.0"
+     gridtolerance="10.0"
+     objecttolerance="10.0"
+     borderopacity="1.0"
+     bordercolor="#666666"
+     pagecolor="#ffffff"
+     id="base"
+     inkscape:zoom="2.4609014"
+     inkscape:cx="264.61648"
+     inkscape:cy="41.573564"
+     inkscape:window-x="330"
+     inkscape:window-y="55"
+     inkscape:current-layer="svg559"
+     showgrid="false"
+     showguides="true"
+     inkscape:guide-bbox="true"
+     inkscape:window-maximized="0" />
+  <defs
+     id="defs561">
+    <linearGradient
+       id="linearGradient4557">
+      <stop
+         style="stop-color:#ffffff;stop-opacity:1;"
+         offset="0"
+         id="stop4559" />
+      <stop
+         style="stop-color:#0300da;stop-opacity:1;"
+         offset="1"
+         id="stop4561" />
+    </linearGradient>
+    <linearGradient
+       id="linearGradient3945">
+      <stop
+         style="stop-color:#ffffff;stop-opacity:1;"
+         offset="0"
+         id="stop3947" />
+      <stop
+         style="stop-color:#ffffff;stop-opacity:0;"
+         offset="1"
+         id="stop3949" />
+    </linearGradient>
+    <inkscape:perspective
+       sodipodi:type="inkscape:persp3d"
+       inkscape:vp_x="0 : 400 : 1"
+       inkscape:vp_y="0 : 1000 : 0"
+       inkscape:vp_z="1000 : 400 : 1"
+       inkscape:persp3d-origin="500 : 266.66667 : 1"
+       id="perspective62" />
+    <linearGradient
+       id="linearGradient6053">
+      <stop
+         style="stop-color:#000000;stop-opacity:1;"
+         offset="0"
+         id="stop6055" />
+      <stop
+         style="stop-color:#5f5f5f;stop-opacity:1;"
+         offset="1"
+         id="stop6057" />
+    </linearGradient>
+    <linearGradient
+       id="linearGradient6499"
+       inkscape:collect="always">
+      <stop
+         id="stop6501"
+         offset="0"
+         style="stop-color:white;stop-opacity:1;" />
+      <stop
+         id="stop6503"
+         offset="1"
+         style="stop-color:white;stop-opacity:0;" />
+    </linearGradient>
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient6499"
+       id="linearGradient3245"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(0.8327515,0,0,-0.6476426,-48.09403,12.672202)"
+       x1="311.95688"
+       y1="-116.67703"
+       x2="311.95688"
+       y2="-276.41519" />
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient6499"
+       id="linearGradient4108"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(1.3544445,0,0,1.7332213,31.621862,51.58815)"
+       x1="44.868057"
+       y1="260.4765"
+       x2="358.07056"
+       y2="260.4765" />
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient6499"
+       id="linearGradient4121"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(1.2483528,0,0,1.0242885,40.754503,133.62899)"
+       x1="44.868057"
+       y1="260.4765"
+       x2="358.07056"
+       y2="260.4765" />
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient6499"
+       id="linearGradient4127"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(1.2483528,0,0,1.0242885,40.754503,340.11416)"
+       x1="44.868057"
+       y1="260.4765"
+       x2="358.07056"
+       y2="260.4765" />
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient6499"
+       id="linearGradient4133"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(1.2483528,0,0,1.0242885,39.887975,233.1463)"
+       x1="44.868057"
+       y1="260.4765"
+       x2="358.07056"
+       y2="260.4765" />
+    <inkscape:perspective
+       id="perspective2871"
+       inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
+       inkscape:vp_z="1 : 0.5 : 1"
+       inkscape:vp_y="0 : 1000 : 0"
+       inkscape:vp_x="0 : 0.5 : 1"
+       sodipodi:type="inkscape:persp3d" />
+    <linearGradient
+       id="linearGradient3751">
+      <stop
+         id="stop3753"
+         offset="0"
+         style="stop-color:black;stop-opacity:1;" />
+      <stop
+         id="stop3755"
+         offset="1"
+         style="stop-color:black;stop-opacity:0;" />
+    </linearGradient>
+    <inkscape:perspective
+       id="perspective2871-4"
+       inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
+       inkscape:vp_z="1 : 0.5 : 1"
+       inkscape:vp_y="0 : 1000 : 0"
+       inkscape:vp_x="0 : 0.5 : 1"
+       sodipodi:type="inkscape:persp3d" />
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient6499-1"
+       id="linearGradient4108-1"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(1.3544445,0,0,1.7332213,31.621862,-148.41185)"
+       x1="44.868057"
+       y1="260.4765"
+       x2="358.07056"
+       y2="260.4765" />
+    <linearGradient
+       id="linearGradient6499-1">
+      <stop
+         id="stop6501-3"
+         offset="0"
+         style="stop-color:#000000;stop-opacity:1;" />
+      <stop
+         id="stop6503-0"
+         offset="1"
+         style="stop-color:white;stop-opacity:0;" />
+    </linearGradient>
+    <inkscape:perspective
+       id="perspective2849"
+       inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
+       inkscape:vp_z="1 : 0.5 : 1"
+       inkscape:vp_y="0 : 1000 : 0"
+       inkscape:vp_x="0 : 0.5 : 1"
+       sodipodi:type="inkscape:persp3d" />
+    <inkscape:perspective
+       id="perspective2854"
+       inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
+       inkscape:vp_z="1 : 0.5 : 1"
+       inkscape:vp_y="0 : 1000 : 0"
+       inkscape:vp_x="0 : 0.5 : 1"
+       sodipodi:type="inkscape:persp3d" />
+    <linearGradient
+       y2="260.4765"
+       x2="358.07056"
+       y1="260.4765"
+       x1="44.868057"
+       gradientTransform="matrix(1.3544445,0,0,1.8513768,-45.940851,-180.28458)"
+       gradientUnits="userSpaceOnUse"
+       id="linearGradient2880"
+       xlink:href="#linearGradient6499-1-4"
+       inkscape:collect="always" />
+    <linearGradient
+       id="linearGradient6499-1-4">
+      <stop
+         style="stop-color:#000000;stop-opacity:0.627451;"
+         offset="0"
+         id="stop3786" />
+      <stop
+         id="stop6503-0-4"
+         offset="1"
+         style="stop-color:#000000;stop-opacity:0;" />
+    </linearGradient>
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient6499-1-4"
+       id="linearGradient3786"
+       x1="27.637432"
+       y1="154.99852"
+       x2="403.24554"
+       y2="-42.490097"
+       gradientUnits="userSpaceOnUse" />
+  </defs>
+  <text
+     xml:space="preserve"
+     style="font-size:24.89476013px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;font-family:Goblin"
+     x="266.96185"
+     y="39.888062"
+     id="text2508"><tspan
+       sodipodi:role="line"
+       id="tspan2510"
+       x="266.96185"
+       y="39.888062" /></text>
+  <rect
+     y="1.2243493"
+     x="1.2243469"
+     height="77.551308"
+     width="397.5513"
+     id="rect6405"
+     style="fill:url(#linearGradient3786);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2.44899988000000013;marker:none;visibility:visible;display:inline;overflow:visible"
+     rx="2.6344144"
+     ry="3.6571968" />
+</svg>
diff --git a/data/themes/default/mainmenu_comment.svg b/data/themes/default/mainmenu_comment.svg
new file mode 100644 (file)
index 0000000..c0609a2
--- /dev/null
@@ -0,0 +1,76 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Sodipodi ("http://www.sodipodi.com/") -->
+
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://creativecommons.org/ns#"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   version="1.0"
+   x="0"
+   y="0"
+   width="80"
+   height="20"
+   id="svg559"
+   sodipodi:version="0.32"
+   inkscape:version="0.47 r22583"
+   sodipodi:docname="menu_comment.svg"
+   inkscape:output_extension="org.inkscape.output.svg.inkscape">
+  <defs
+     id="defs2522">
+    <inkscape:perspective
+       sodipodi:type="inkscape:persp3d"
+       inkscape:vp_x="0 : 300 : 1"
+       inkscape:vp_y="0 : 1000 : 0"
+       inkscape:vp_z="800 : 300 : 1"
+       inkscape:persp3d-origin="400 : 200 : 1"
+       id="perspective8" />
+  </defs>
+  <metadata
+     id="metadata35">
+    <rdf:RDF>
+      <cc:Work
+         rdf:about="">
+        <dc:format>image/svg+xml</dc:format>
+        <dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+        <dc:title />
+      </cc:Work>
+    </rdf:RDF>
+  </metadata>
+  <sodipodi:namedview
+     inkscape:window-height="1000"
+     inkscape:window-width="1680"
+     inkscape:pageshadow="2"
+     inkscape:pageopacity="0.0"
+     guidetolerance="10.0"
+     gridtolerance="10.0"
+     objecttolerance="10.0"
+     borderopacity="1.0"
+     bordercolor="#666666"
+     pagecolor="#ffffff"
+     id="base"
+     inkscape:zoom="3.5638182"
+     inkscape:cx="63.312761"
+     inkscape:cy="28.662714"
+     inkscape:window-x="-8"
+     inkscape:window-y="-8"
+     inkscape:current-layer="svg559"
+     showgrid="false"
+     inkscape:window-maximized="1" />
+  <text
+     x="1.2611415"
+     y="16.780357"
+     style="font-size:17.99999994px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;writing-mode:lr;text-anchor:start;fill:#060000;fill-opacity:1;stroke:none;display:inline;font-family:Goblin;-inkscape-font-specification:Goblin"
+     id="text10203"
+     xml:space="preserve"
+     sodipodi:linespacing="125%"
+     transform="scale(1.0082228,0.99184427)"><tspan
+       x="1.2611415"
+       y="16.780357"
+       id="tspan10205"
+       style="font-size:17.99999994px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;text-anchor:start;fill:#060000;fill-opacity:1;stroke:none;font-family:Goblin;-inkscape-font-specification:Goblin;writing-mode:lr;line-height:125%">Comment</tspan></text>
+</svg>
diff --git a/data/themes/default/mainmenu_comment_bg.svg b/data/themes/default/mainmenu_comment_bg.svg
new file mode 100644 (file)
index 0000000..e324e40
--- /dev/null
@@ -0,0 +1,131 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://creativecommons.org/ns#"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:xlink="http://www.w3.org/1999/xlink"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   width="1000"
+   height="35"
+   id="svg2919"
+   version="1.1"
+   inkscape:version="0.47pre4 r22446"
+   sodipodi:docname="menu_comment_bg.svg">
+  <defs
+     id="defs2921">
+    <inkscape:perspective
+       sodipodi:type="inkscape:persp3d"
+       inkscape:vp_x="0 : 526.18109 : 1"
+       inkscape:vp_y="0 : 1000 : 0"
+       inkscape:vp_z="744.09448 : 526.18109 : 1"
+       inkscape:persp3d-origin="372.04724 : 350.78739 : 1"
+       id="perspective2927" />
+    <inkscape:perspective
+       id="perspective2908"
+       inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
+       inkscape:vp_z="1 : 0.5 : 1"
+       inkscape:vp_y="0 : 1000 : 0"
+       inkscape:vp_x="0 : 0.5 : 1"
+       sodipodi:type="inkscape:persp3d" />
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient5448"
+       id="linearGradient5460"
+       gradientUnits="userSpaceOnUse"
+       x1="0"
+       y1="768"
+       x2="0"
+       y2="713.1153"
+       gradientTransform="translate(0,-2)" />
+    <linearGradient
+       id="linearGradient5448">
+      <stop
+         style="stop-color:#beb7c8;stop-opacity:1;"
+         offset="0"
+         id="stop5450" />
+      <stop
+         style="stop-color:#beb7c8;stop-opacity:0;"
+         offset="1"
+         id="stop5452" />
+    </linearGradient>
+    <linearGradient
+       y2="713.1153"
+       x2="0"
+       y1="768"
+       x1="0"
+       gradientTransform="matrix(1.0001729,0,0,0.66978968,-0.08644188,537.20848)"
+       gradientUnits="userSpaceOnUse"
+       id="linearGradient2917"
+       xlink:href="#linearGradient5448"
+       inkscape:collect="always" />
+    <inkscape:perspective
+       id="perspective2956"
+       inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
+       inkscape:vp_z="1 : 0.5 : 1"
+       inkscape:vp_y="0 : 1000 : 0"
+       inkscape:vp_x="0 : 0.5 : 1"
+       sodipodi:type="inkscape:persp3d" />
+    <inkscape:perspective
+       id="perspective2821"
+       inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
+       inkscape:vp_z="1 : 0.5 : 1"
+       inkscape:vp_y="0 : 1000 : 0"
+       inkscape:vp_x="0 : 0.5 : 1"
+       sodipodi:type="inkscape:persp3d" />
+  </defs>
+  <sodipodi:namedview
+     id="base"
+     pagecolor="#ffffff"
+     bordercolor="#666666"
+     borderopacity="1.0"
+     inkscape:pageopacity="0.0"
+     inkscape:pageshadow="2"
+     inkscape:zoom="0.70710678"
+     inkscape:cx="403.07156"
+     inkscape:cy="55.181507"
+     inkscape:document-units="px"
+     inkscape:current-layer="layer1"
+     showgrid="false"
+     inkscape:window-width="1280"
+     inkscape:window-height="726"
+     inkscape:window-x="0"
+     inkscape:window-y="25"
+     inkscape:window-maximized="1" />
+  <metadata
+     id="metadata2924">
+    <rdf:RDF>
+      <cc:Work
+         rdf:about="">
+        <dc:format>image/svg+xml</dc:format>
+        <dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+        <dc:title />
+      </cc:Work>
+    </rdf:RDF>
+  </metadata>
+  <g
+     inkscape:label="Capa 1"
+     inkscape:groupmode="layer"
+     id="layer1"
+     transform="translate(0,-1017.3622)">
+    <rect
+       style="fill:#ffffff;fill-opacity:1;stroke:#000000;stroke-width:0.82833934;stroke-opacity:1"
+       id="rect3982-4"
+       width="1003.9697"
+       height="34.171661"
+       x="-1.9808303"
+       y="1017.7764" />
+    <rect
+       style="fill:url(#linearGradient2917);fill-opacity:1;stroke:none"
+       id="rect3982"
+       width="1000.1728"
+       height="33.489483"
+       x="-0.086441576"
+       y="1018.1177" />
+  </g>
+</svg>
diff --git a/data/themes/default/mainmenu_option.svg b/data/themes/default/mainmenu_option.svg
new file mode 100644 (file)
index 0000000..2e6cd75
--- /dev/null
@@ -0,0 +1,76 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Sodipodi ("http://www.sodipodi.com/") -->
+
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://creativecommons.org/ns#"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   version="1.0"
+   x="0"
+   y="0"
+   width="140"
+   height="40"
+   id="svg559"
+   sodipodi:version="0.32"
+   inkscape:version="0.48.4 r9939"
+   sodipodi:docname="mainmenu_option.svg"
+   inkscape:output_extension="org.inkscape.output.svg.inkscape">
+  <defs
+     id="defs2522">
+    <inkscape:perspective
+       sodipodi:type="inkscape:persp3d"
+       inkscape:vp_x="0 : 300 : 1"
+       inkscape:vp_y="0 : 1000 : 0"
+       inkscape:vp_z="800 : 300 : 1"
+       inkscape:persp3d-origin="400 : 200 : 1"
+       id="perspective8" />
+  </defs>
+  <metadata
+     id="metadata35">
+    <rdf:RDF>
+      <cc:Work
+         rdf:about="">
+        <dc:format>image/svg+xml</dc:format>
+        <dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+        <dc:title />
+      </cc:Work>
+    </rdf:RDF>
+  </metadata>
+  <sodipodi:namedview
+     inkscape:window-height="879"
+     inkscape:window-width="1531"
+     inkscape:pageshadow="2"
+     inkscape:pageopacity="0.0"
+     guidetolerance="10.0"
+     gridtolerance="10.0"
+     objecttolerance="10.0"
+     borderopacity="1.0"
+     bordercolor="#666666"
+     pagecolor="#ffffff"
+     id="base"
+     inkscape:zoom="3.5638182"
+     inkscape:cx="21.19519"
+     inkscape:cy="28.662714"
+     inkscape:window-x="219"
+     inkscape:window-y="96"
+     inkscape:current-layer="svg559"
+     showgrid="false"
+     inkscape:window-maximized="0" />
+  <text
+     x="0.42621329"
+     y="29.832424"
+     style="font-size:30px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;text-align:start;line-height:125%;writing-mode:lr-tb;text-anchor:start;opacity:0.95999995000000005;fill:#ffffff;fill-opacity:0.25098041;stroke:#000000;stroke-width:0.96595240000000004;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;display:inline;font-family:Goblin"
+     id="text10203"
+     xml:space="preserve"
+     sodipodi:linespacing="125%"
+     transform="scale(1.0082228,0.99184427)"><tspan
+       x="0.42621329"
+       y="29.832424"
+       id="tspan10205"
+       style="font-size:30px;text-align:start;text-anchor:start;fill:#ffffff;fill-opacity:0.25098041;stroke:#000000;stroke-width:0.96595240000000004;stroke-opacity:1">option</tspan></text>
+</svg>
diff --git a/data/themes/default/mainmenu_option_selected.svg b/data/themes/default/mainmenu_option_selected.svg
new file mode 100644 (file)
index 0000000..e3fb953
--- /dev/null
@@ -0,0 +1,76 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Sodipodi ("http://www.sodipodi.com/") -->
+
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://creativecommons.org/ns#"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   version="1.0"
+   x="0"
+   y="0"
+   width="140"
+   height="40"
+   id="svg559"
+   sodipodi:version="0.32"
+   inkscape:version="0.48.4 r9939"
+   sodipodi:docname="mainmenu_option_selected.svg"
+   inkscape:output_extension="org.inkscape.output.svg.inkscape">
+  <defs
+     id="defs2522">
+    <inkscape:perspective
+       sodipodi:type="inkscape:persp3d"
+       inkscape:vp_x="0 : 300 : 1"
+       inkscape:vp_y="0 : 1000 : 0"
+       inkscape:vp_z="800 : 300 : 1"
+       inkscape:persp3d-origin="400 : 200 : 1"
+       id="perspective8" />
+  </defs>
+  <metadata
+     id="metadata35">
+    <rdf:RDF>
+      <cc:Work
+         rdf:about="">
+        <dc:format>image/svg+xml</dc:format>
+        <dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+        <dc:title />
+      </cc:Work>
+    </rdf:RDF>
+  </metadata>
+  <sodipodi:namedview
+     inkscape:window-height="879"
+     inkscape:window-width="1531"
+     inkscape:pageshadow="2"
+     inkscape:pageopacity="0.0"
+     guidetolerance="10.0"
+     gridtolerance="10.0"
+     objecttolerance="10.0"
+     borderopacity="1.0"
+     bordercolor="#666666"
+     pagecolor="#ffffff"
+     id="base"
+     inkscape:zoom="3.5638182"
+     inkscape:cx="1.0200212"
+     inkscape:cy="28.662714"
+     inkscape:window-x="259"
+     inkscape:window-y="109"
+     inkscape:current-layer="svg559"
+     showgrid="false"
+     inkscape:window-maximized="0" />
+  <text
+     x="0.42621329"
+     y="29.832424"
+     style="font-size:30px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;text-align:start;line-height:125%;writing-mode:lr-tb;text-anchor:start;fill:#ffffff;fill-opacity:1;stroke:#000000;stroke-width:0.9659524;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;display:inline;font-family:Goblin"
+     id="text10203"
+     xml:space="preserve"
+     sodipodi:linespacing="125%"
+     transform="scale(1.0082228,0.99184427)"><tspan
+       x="0.42621329"
+       y="29.832424"
+       id="tspan10205"
+       style="font-size:30px;text-align:start;text-anchor:start;fill:#ffffff;fill-opacity:1;stroke-width:0.9659524">option</tspan></text>
+</svg>
diff --git a/data/themes/default/mainmenu_scomment_bg.svg b/data/themes/default/mainmenu_scomment_bg.svg
new file mode 100644 (file)
index 0000000..e150054
--- /dev/null
@@ -0,0 +1,145 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://creativecommons.org/ns#"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:xlink="http://www.w3.org/1999/xlink"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   width="1000"
+   height="35"
+   id="svg2919"
+   version="1.1"
+   inkscape:version="0.47 r22583"
+   sodipodi:docname="menu_scomment_bg.svg">
+  <defs
+     id="defs2921">
+    <inkscape:perspective
+       sodipodi:type="inkscape:persp3d"
+       inkscape:vp_x="0 : 526.18109 : 1"
+       inkscape:vp_y="0 : 1000 : 0"
+       inkscape:vp_z="744.09448 : 526.18109 : 1"
+       inkscape:persp3d-origin="372.04724 : 350.78739 : 1"
+       id="perspective2927" />
+    <inkscape:perspective
+       id="perspective2908"
+       inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
+       inkscape:vp_z="1 : 0.5 : 1"
+       inkscape:vp_y="0 : 1000 : 0"
+       inkscape:vp_x="0 : 0.5 : 1"
+       sodipodi:type="inkscape:persp3d" />
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient5448"
+       id="linearGradient5460"
+       gradientUnits="userSpaceOnUse"
+       x1="0"
+       y1="768"
+       x2="0"
+       y2="713.1153"
+       gradientTransform="translate(0,-2)" />
+    <linearGradient
+       id="linearGradient5448">
+      <stop
+         style="stop-color:#beb7c8;stop-opacity:1;"
+         offset="0"
+         id="stop5450" />
+      <stop
+         style="stop-color:#beb7c8;stop-opacity:0;"
+         offset="1"
+         id="stop5452" />
+    </linearGradient>
+    <linearGradient
+       y2="713.1153"
+       x2="0"
+       y1="768"
+       x1="0"
+       gradientTransform="matrix(1.0001729,0,0,0.66978968,-0.08644188,537.20848)"
+       gradientUnits="userSpaceOnUse"
+       id="linearGradient2917"
+       xlink:href="#linearGradient5448"
+       inkscape:collect="always" />
+    <inkscape:perspective
+       id="perspective2956"
+       inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
+       inkscape:vp_z="1 : 0.5 : 1"
+       inkscape:vp_y="0 : 1000 : 0"
+       inkscape:vp_x="0 : 0.5 : 1"
+       sodipodi:type="inkscape:persp3d" />
+    <inkscape:perspective
+       id="perspective2821"
+       inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
+       inkscape:vp_z="1 : 0.5 : 1"
+       inkscape:vp_y="0 : 1000 : 0"
+       inkscape:vp_x="0 : 0.5 : 1"
+       sodipodi:type="inkscape:persp3d" />
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient5448"
+       id="linearGradient2822"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(0.99852984,0,0,0.66980918,0.81308358,537.19399)"
+       x1="0"
+       y1="768"
+       x2="0"
+       y2="713.1153" />
+  </defs>
+  <sodipodi:namedview
+     id="base"
+     pagecolor="#ffffff"
+     bordercolor="#666666"
+     borderopacity="1.0"
+     inkscape:pageopacity="0.0"
+     inkscape:pageshadow="2"
+     inkscape:zoom="0.70710678"
+     inkscape:cx="479.0479"
+     inkscape:cy="122.05966"
+     inkscape:document-units="px"
+     inkscape:current-layer="layer1"
+     showgrid="false"
+     inkscape:window-width="1280"
+     inkscape:window-height="725"
+     inkscape:window-x="0"
+     inkscape:window-y="25"
+     inkscape:window-maximized="1" />
+  <metadata
+     id="metadata2924">
+    <rdf:RDF>
+      <cc:Work
+         rdf:about="">
+        <dc:format>image/svg+xml</dc:format>
+        <dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+        <dc:title />
+      </cc:Work>
+    </rdf:RDF>
+  </metadata>
+  <g
+     inkscape:label="Capa 1"
+     inkscape:groupmode="layer"
+     id="layer1"
+     transform="translate(0,-1017.3622)">
+    <rect
+       style="fill:#ffffff;fill-opacity:1;stroke:#000000;stroke-width:0.8263821;stroke-opacity:1"
+       id="rect3982-4"
+       width="999.17365"
+       height="34.173618"
+       x="0.41319105"
+       y="1017.7752"
+       rx="10"
+       ry="10" />
+    <rect
+       style="fill:url(#linearGradient2822);fill-opacity:1;stroke:none"
+       id="rect3982"
+       width="998.52972"
+       height="33.490456"
+       x="0.81308591"
+       y="1018.1172"
+       rx="10"
+       ry="10" />
+  </g>
+</svg>
diff --git a/data/themes/default/mainmenu_short_comment.svg b/data/themes/default/mainmenu_short_comment.svg
new file mode 100644 (file)
index 0000000..14f30a0
--- /dev/null
@@ -0,0 +1,76 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Sodipodi ("http://www.sodipodi.com/") -->
+
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://creativecommons.org/ns#"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   version="1.0"
+   x="0"
+   y="0"
+   width="80"
+   height="20"
+   id="svg559"
+   sodipodi:version="0.32"
+   inkscape:version="0.47 r22583"
+   sodipodi:docname="menu_short_comment.svg"
+   inkscape:output_extension="org.inkscape.output.svg.inkscape">
+  <defs
+     id="defs2522">
+    <inkscape:perspective
+       sodipodi:type="inkscape:persp3d"
+       inkscape:vp_x="0 : 300 : 1"
+       inkscape:vp_y="0 : 1000 : 0"
+       inkscape:vp_z="800 : 300 : 1"
+       inkscape:persp3d-origin="400 : 200 : 1"
+       id="perspective8" />
+  </defs>
+  <metadata
+     id="metadata35">
+    <rdf:RDF>
+      <cc:Work
+         rdf:about="">
+        <dc:format>image/svg+xml</dc:format>
+        <dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+        <dc:title />
+      </cc:Work>
+    </rdf:RDF>
+  </metadata>
+  <sodipodi:namedview
+     inkscape:window-height="1000"
+     inkscape:window-width="1680"
+     inkscape:pageshadow="2"
+     inkscape:pageopacity="0.0"
+     guidetolerance="10.0"
+     gridtolerance="10.0"
+     objecttolerance="10.0"
+     borderopacity="1.0"
+     bordercolor="#666666"
+     pagecolor="#ffffff"
+     id="base"
+     inkscape:zoom="3.5638182"
+     inkscape:cx="63.312761"
+     inkscape:cy="28.101518"
+     inkscape:window-x="-8"
+     inkscape:window-y="-8"
+     inkscape:current-layer="svg559"
+     showgrid="false"
+     inkscape:window-maximized="1" />
+  <text
+     x="1.4361764"
+     y="16.829205"
+     style="font-size:13.92899985px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;writing-mode:lr;text-anchor:start;fill:#060000;fill-opacity:1;stroke:none;display:inline;font-family:Goblin;-inkscape-font-specification:Goblin"
+     id="text10203"
+     xml:space="preserve"
+     sodipodi:linespacing="125%"
+     transform="scale(1.0082228,0.99184427)"><tspan
+       x="1.4361764"
+       y="16.829205"
+       id="tspan10205"
+       style="font-size:13.92899985px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;text-anchor:start;fill:#060000;fill-opacity:1;stroke:none;font-family:Goblin;-inkscape-font-specification:Goblin;writing-mode:lr;line-height:125%">Comment</tspan></text>
+</svg>
diff --git a/data/themes/default/menu.ogg b/data/themes/default/menu.ogg
new file mode 100644 (file)
index 0000000..6d7347d
Binary files /dev/null and b/data/themes/default/menu.ogg differ
diff --git a/data/themes/default/message_text.svg b/data/themes/default/message_text.svg
new file mode 100644 (file)
index 0000000..f20068d
--- /dev/null
@@ -0,0 +1,76 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Sodipodi ("http://www.sodipodi.com/") -->
+
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://creativecommons.org/ns#"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   version="1.0"
+   x="0"
+   y="0"
+   width="110"
+   height="20"
+   id="svg559"
+   sodipodi:version="0.32"
+   inkscape:version="0.47 r22583"
+   sodipodi:docname="message_text.svg"
+   inkscape:output_extension="org.inkscape.output.svg.inkscape">
+  <defs
+     id="defs2522">
+    <inkscape:perspective
+       sodipodi:type="inkscape:persp3d"
+       inkscape:vp_x="0 : 300 : 1"
+       inkscape:vp_y="0 : 1000 : 0"
+       inkscape:vp_z="800 : 300 : 1"
+       inkscape:persp3d-origin="400 : 200 : 1"
+       id="perspective8" />
+  </defs>
+  <metadata
+     id="metadata35">
+    <rdf:RDF>
+      <cc:Work
+         rdf:about="">
+        <dc:format>image/svg+xml</dc:format>
+        <dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+        <dc:title />
+      </cc:Work>
+    </rdf:RDF>
+  </metadata>
+  <sodipodi:namedview
+     inkscape:window-height="854"
+     inkscape:window-width="1440"
+     inkscape:pageshadow="2"
+     inkscape:pageopacity="0.0"
+     guidetolerance="10.0"
+     gridtolerance="10.0"
+     objecttolerance="10.0"
+     borderopacity="1.0"
+     bordercolor="#666666"
+     pagecolor="#ffffff"
+     id="base"
+     inkscape:zoom="3.5638182"
+     inkscape:cx="60.101374"
+     inkscape:cy="22.158164"
+     inkscape:window-x="0"
+     inkscape:window-y="0"
+     inkscape:current-layer="svg559"
+     showgrid="false"
+     inkscape:window-maximized="1" />
+  <text
+     x="0.21655023"
+     y="13.585703"
+     style="font-size:22px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;text-align:start;line-height:125%;writing-mode:lr-tb;text-anchor:middle;fill:#ffffff;fill-opacity:1;stroke:#000000;stroke-width:0.9659524;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;display:inline;font-family:Droid Sans Mono"
+     id="text10203"
+     xml:space="preserve"
+     sodipodi:linespacing="125%"
+     transform="scale(1.0082228,0.99184427)"><tspan
+       x="0.21655023"
+       y="13.585703"
+       id="tspan10205"
+       style="font-size:22px;text-align:start;text-anchor:start;fill:#ffffff;fill-opacity:1;stroke-width:0.9659524">message</tspan></text>
+</svg>
diff --git a/data/themes/default/mine.svg b/data/themes/default/mine.svg
new file mode 100644 (file)
index 0000000..4463bbb
--- /dev/null
@@ -0,0 +1,128 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://creativecommons.org/ns#"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:xlink="http://www.w3.org/1999/xlink"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   width="64"
+   height="64"
+   id="svg2463"
+   sodipodi:version="0.32"
+   inkscape:version="0.47 r22583"
+   version="1.0"
+   sodipodi:docname="mine.svg"
+   inkscape:output_extension="org.inkscape.output.svg.inkscape">
+  <defs
+     id="defs2465">
+    <linearGradient
+       id="linearGradient3262">
+      <stop
+         style="stop-color:#f5f5f5;stop-opacity:0.22680412;"
+         offset="0"
+         id="stop3264" />
+      <stop
+         style="stop-color:#f5f5f5;stop-opacity:0.96078432;"
+         offset="1"
+         id="stop3266" />
+    </linearGradient>
+    <linearGradient
+       id="linearGradient3751"
+       inkscape:collect="always">
+      <stop
+         id="stop3753"
+         offset="0"
+         style="stop-color:black;stop-opacity:1;" />
+      <stop
+         id="stop3755"
+         offset="1"
+         style="stop-color:black;stop-opacity:0;" />
+    </linearGradient>
+    <inkscape:perspective
+       sodipodi:type="inkscape:persp3d"
+       inkscape:vp_x="0 : 526.18109 : 1"
+       inkscape:vp_y="0 : 1000 : 0"
+       inkscape:vp_z="744.09448 : 526.18109 : 1"
+       inkscape:persp3d-origin="372.04724 : 350.78739 : 1"
+       id="perspective2471" />
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient3751"
+       id="linearGradient3272"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(0.3868046,0,0,0.3868046,40.335717,481.59837)"
+       x1="665.12128"
+       y1="684.16162"
+       x2="381.28015"
+       y2="449.80624" />
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient3751"
+       id="linearGradient2406"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(0.3868046,0,0,0.3868046,43.114888,485.8841)"
+       x1="665.12128"
+       y1="684.16162"
+       x2="381.28015"
+       y2="449.80624" />
+  </defs>
+  <sodipodi:namedview
+     id="base"
+     pagecolor="#f5f5f5"
+     bordercolor="#666666"
+     borderopacity="1.0"
+     gridtolerance="10000"
+     guidetolerance="10"
+     objecttolerance="10"
+     inkscape:pageopacity="0"
+     inkscape:pageshadow="2"
+     inkscape:zoom="5.6"
+     inkscape:cx="27.116923"
+     inkscape:cy="40.003406"
+     inkscape:document-units="px"
+     inkscape:current-layer="layer1"
+     showgrid="false"
+     inkscape:window-width="860"
+     inkscape:window-height="806"
+     inkscape:window-x="568"
+     inkscape:window-y="26"
+     inkscape:window-maximized="0" />
+  <metadata
+     id="metadata2468">
+    <rdf:RDF>
+      <cc:Work
+         rdf:about="">
+        <dc:format>image/svg+xml</dc:format>
+        <dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+      </cc:Work>
+    </rdf:RDF>
+  </metadata>
+  <g
+     inkscape:label="Layer 1"
+     inkscape:groupmode="layer"
+     id="layer1"
+     transform="translate(-110.35967,-771.51188)">
+    <path
+       sodipodi:type="star"
+       style="fill:#1a1a1a;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1.50462699;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+       id="path2824"
+       sodipodi:sides="10"
+       sodipodi:cx="30.892857"
+       sodipodi:cy="33.285713"
+       sodipodi:r1="32.142857"
+       sodipodi:r2="20.415771"
+       sodipodi:arg1="1.5707963"
+       sodipodi:arg2="2.5575682"
+       inkscape:flatsided="false"
+       inkscape:rounded="0"
+       inkscape:randomized="0"
+       d="M 30.892857,65.42857 13.860991,44.54268 11.99976,59.289831 10.497109,32.381711 0.32318364,43.218403 14.92371,20.566041 0.32318311,23.353025 25.449981,13.608853 11.999759,7.2815965 38.055246,14.167557 30.892856,1.1428566 47.924722,22.028747 49.785953,7.2815955 51.288604,34.189715 61.46253,23.353023 46.862004,46.005386 61.46253,43.218401 36.335732,52.962574 49.785954,59.28983 23.730467,52.40387 l 7.16239,13.0247 z"
+       transform="matrix(1.0222549,0,0,0.97222224,110.7793,771.15077)" />
+  </g>
+</svg>
diff --git a/data/themes/default/neck_glow.svg b/data/themes/default/neck_glow.svg
new file mode 100644 (file)
index 0000000..7575eda
--- /dev/null
@@ -0,0 +1,293 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://creativecommons.org/ns#"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:xlink="http://www.w3.org/1999/xlink"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   version="1.0"
+   width="256"
+   height="128"
+   id="svg2"
+   sodipodi:version="0.32"
+   inkscape:version="0.47 r22583"
+   sodipodi:docname="neck_glow.svg"
+   inkscape:output_extension="org.inkscape.output.svg.inkscape"
+   sodipodi:modified="true">
+  <metadata
+     id="metadata3009">
+    <rdf:RDF>
+      <cc:Work
+         rdf:about="">
+        <dc:format>image/svg+xml</dc:format>
+        <dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+      </cc:Work>
+    </rdf:RDF>
+  </metadata>
+  <sodipodi:namedview
+     inkscape:window-height="854"
+     inkscape:window-width="1440"
+     inkscape:pageshadow="2"
+     inkscape:pageopacity="0.0"
+     borderopacity="1.0"
+     bordercolor="#666666"
+     pagecolor="#ffffff"
+     id="base"
+     inkscape:zoom="1.7759539"
+     inkscape:cx="9.4369493"
+     inkscape:cy="44.237484"
+     inkscape:window-x="0"
+     inkscape:window-y="0"
+     inkscape:current-layer="svg2"
+     showgrid="true"
+     showguides="false"
+     inkscape:snap-global="true"
+     inkscape:snap-bbox="true"
+     inkscape:snap-grids="true"
+     inkscape:window-maximized="1">
+    <inkscape:grid
+       type="xygrid"
+       id="grid3223"
+       visible="true"
+       enabled="true"
+       empspacing="5"
+       snapvisiblegridlinesonly="true" />
+  </sodipodi:namedview>
+  <defs
+     id="defs4">
+    <linearGradient
+       id="linearGradient3655">
+      <stop
+         style="stop-color:#ffffff;stop-opacity:0.627451;"
+         offset="0"
+         id="stop3657" />
+      <stop
+         style="stop-color:#ffffff;stop-opacity:0;"
+         offset="1"
+         id="stop3659" />
+    </linearGradient>
+    <inkscape:perspective
+       sodipodi:type="inkscape:persp3d"
+       inkscape:vp_x="0 : 260 : 1"
+       inkscape:vp_y="0 : 1000 : 0"
+       inkscape:vp_z="250 : 260 : 1"
+       inkscape:persp3d-origin="125 : 173.33333 : 1"
+       id="perspective42" />
+    <linearGradient
+       id="linearGradient4387">
+      <stop
+         style="stop-color:#530d0d;stop-opacity:0;"
+         offset="0"
+         id="stop4389" />
+      <stop
+         id="stop10272"
+         offset="0.03502782"
+         style="stop-color:#5b0d0d;stop-opacity:0.93333333;" />
+      <stop
+         id="stop4395"
+         offset="0.5"
+         style="stop-color:#a61010;stop-opacity:0.93333334;" />
+      <stop
+         style="stop-color:#5a0d0d;stop-opacity:0.93333333;"
+         offset="0.96107578"
+         id="stop10270" />
+      <stop
+         style="stop-color:#530d0d;stop-opacity:0;"
+         offset="1"
+         id="stop4391" />
+    </linearGradient>
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient4387"
+       id="linearGradient4393"
+       x1="3.9839032"
+       y1="259.35468"
+       x2="249.84105"
+       y2="259.35468"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(0.9893674,0,0,0.9937313,0,-260.73405)" />
+    <linearGradient
+       id="linearGradient4109">
+      <stop
+         style="stop-color:#beff92;stop-opacity:0.58778626;"
+         offset="0"
+         id="stop4111" />
+      <stop
+         id="stop4117"
+         offset="0.5"
+         style="stop-color:#7fff2a;stop-opacity:1;" />
+      <stop
+         style="stop-color:#beff92;stop-opacity:0.58823532;"
+         offset="1"
+         id="stop4113" />
+    </linearGradient>
+    <linearGradient
+       id="linearGradient3207">
+      <stop
+         style="stop-color:#999999;stop-opacity:1;"
+         offset="0"
+         id="stop3209" />
+      <stop
+         style="stop-color:#5f5f5f;stop-opacity:1;"
+         offset="1"
+         id="stop3211" />
+    </linearGradient>
+    <linearGradient
+       id="linearGradient2417">
+      <stop
+         style="stop-color:#f2f2f2;stop-opacity:1;"
+         offset="0"
+         id="stop2419" />
+      <stop
+         style="stop-color:#999999;stop-opacity:0.73282444;"
+         offset="1"
+         id="stop2421" />
+    </linearGradient>
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient2417"
+       id="linearGradient3337"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(0.8922696,0,0,1.2260835,253.8584,-0.7360251)"
+       spreadMethod="reflect"
+       x1="-142.75803"
+       y1="0.78900218"
+       x2="-142.75803"
+       y2="4.6783328" />
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient4109"
+       id="linearGradient4301"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="translate(14.263989,1.44282)"
+       x1="92.684113"
+       y1="164.62471"
+       x2="227.01991"
+       y2="194.92398" />
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient4109"
+       id="linearGradient4303"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="translate(-12,0)"
+       x1="64.430161"
+       y1="268.30783"
+       x2="146.39825"
+       y2="301.49274" />
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient2417"
+       id="linearGradient2851"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(0.8756075,0,0,1.2260835,249.99996,-0.7360251)"
+       spreadMethod="reflect"
+       x1="-142.75803"
+       y1="0.78900218"
+       x2="-142.75803"
+       y2="4.6783328" />
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient3207"
+       id="linearGradient2853"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(1.2794074,0,0,1.0054914,364.3677,-1.4243308)"
+       spreadMethod="repeat"
+       x1="-265.2009"
+       y1="-3.3672962"
+       x2="-265.91348"
+       y2="-0.3399277" />
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient2417"
+       id="linearGradient2857"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(0.8756075,0,0,1.2260835,249.99996,258.86732)"
+       spreadMethod="reflect"
+       x1="-142.75803"
+       y1="0.78900218"
+       x2="-142.75803"
+       y2="4.6783328" />
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient2417"
+       id="linearGradient2861"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(0.8756075,0,0,1.2260835,249.99996,518.66799)"
+       spreadMethod="reflect"
+       x1="-142.75803"
+       y1="0.78900218"
+       x2="-142.75803"
+       y2="4.6783328" />
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient3207"
+       id="linearGradient2865"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(1.0661728,0,0,1.0054914,357.56648,-1.4243308)"
+       spreadMethod="repeat"
+       x1="-265.2009"
+       y1="-3.3672962"
+       x2="-265.91348"
+       y2="-0.3399277" />
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient3207"
+       id="linearGradient2869"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(0.85293831,0,0,1.0054914,352.20807,-1.4243308)"
+       spreadMethod="repeat"
+       x1="-265.2009"
+       y1="-3.3672962"
+       x2="-265.91348"
+       y2="-0.3399277" />
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient3207"
+       id="linearGradient2873"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(0.6397037,0,0,1.0054914,345.40687,-1.4243308)"
+       spreadMethod="repeat"
+       x1="-265.2009"
+       y1="-3.3672962"
+       x2="-265.91348"
+       y2="-0.3399277" />
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient3207"
+       id="linearGradient2877"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(0.42646909,0,0,1.0054914,337.88424,-1.4243308)"
+       spreadMethod="repeat"
+       x1="-265.2009"
+       y1="-3.3672962"
+       x2="-265.91348"
+       y2="-0.3399277" />
+    <radialGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient3655"
+       id="radialGradient3661"
+       cx="162.5"
+       cy="256"
+       fx="162.5"
+       fy="256"
+       r="157.5"
+       gradientTransform="matrix(1,0,0,0.22222222,0,199.11111)"
+       gradientUnits="userSpaceOnUse" />
+  </defs>
+  <path
+     sodipodi:type="arc"
+     style="fill:url(#radialGradient3661);fill-opacity:1.0;fill-rule:nonzero;stroke:none"
+     id="path2879"
+     sodipodi:cx="162.5"
+     sodipodi:cy="256"
+     sodipodi:rx="157.5"
+     sodipodi:ry="35"
+     d="m 320,256 a 157.5,35 0 1 1 -315,0 157.5,35 0 1 1 315,0 z"
+     transform="matrix(0.81269841,0,0,1.8285714,-4.063492,-340.11428)" />
+</svg>
diff --git a/data/themes/default/no_cover.svg b/data/themes/default/no_cover.svg
new file mode 100644 (file)
index 0000000..0d83d30
--- /dev/null
@@ -0,0 +1,125 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://creativecommons.org/ns#"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:xlink="http://www.w3.org/1999/xlink"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   width="256"
+   height="256"
+   id="svg2"
+   sodipodi:version="0.32"
+   inkscape:version="0.46"
+   sodipodi:docbase="/home/yoda/UltraStar/sf/svn/UltraStar-ng/themes/lima"
+   sodipodi:docname="no_cover.svg"
+   inkscape:output_extension="org.inkscape.output.svg.inkscape"
+   version="1.0">
+  <defs
+     id="defs4">
+    <inkscape:perspective
+       sodipodi:type="inkscape:persp3d"
+       inkscape:vp_x="0 : 128 : 1"
+       inkscape:vp_y="0 : 1000 : 0"
+       inkscape:vp_z="256 : 128 : 1"
+       inkscape:persp3d-origin="128 : 85.333333 : 1"
+       id="perspective17" />
+    <linearGradient
+       id="linearGradient3751"
+       inkscape:collect="always">
+      <stop
+         id="stop3753"
+         offset="0"
+         style="stop-color:black;stop-opacity:1;" />
+      <stop
+         id="stop3755"
+         offset="1"
+         style="stop-color:black;stop-opacity:0;" />
+    </linearGradient>
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient3751"
+       id="linearGradient3484"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(0.336682,0,0,0.336682,-81.3739,-51.8729)"
+       x1="665.12128"
+       y1="684.16162"
+       x2="381.28015"
+       y2="449.80624" />
+  </defs>
+  <sodipodi:namedview
+     id="base"
+     pagecolor="#ffffff"
+     bordercolor="#666666"
+     borderopacity="1.0"
+     inkscape:pageopacity="0.0"
+     inkscape:pageshadow="2"
+     inkscape:zoom="1.1191406"
+     inkscape:cx="-30.603843"
+     inkscape:cy="70.174855"
+     inkscape:document-units="px"
+     inkscape:current-layer="layer1"
+     inkscape:window-width="1144"
+     inkscape:window-height="785"
+     inkscape:window-x="136"
+     inkscape:window-y="25"
+     showguides="true"
+     inkscape:guide-bbox="true"
+     width="256px"
+     height="256px"
+     borderlayer="false"
+     showgrid="false" />
+  <metadata
+     id="metadata7">
+    <rdf:RDF>
+      <cc:Work
+         rdf:about="">
+        <dc:format>image/svg+xml</dc:format>
+        <dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+      </cc:Work>
+    </rdf:RDF>
+  </metadata>
+  <g
+     inkscape:label="Capa 1"
+     inkscape:groupmode="layer"
+     id="layer1">
+    <rect
+       style="opacity:1;color:#000000;fill:#ffffff;fill-opacity:0.31313129000000001;fill-rule:nonzero;stroke:#7f7f7f;stroke-width:10.01399999999999935;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:block;overflow:visible"
+       id="rect1906"
+       width="246.30026"
+       height="246.30028"
+       x="4.8498545"
+       y="4.0691833"
+       inkscape:export-filename="/home/jesusda/docs/curro/yo/ultrastar-ng/base/theme-pod/images/no_cover.png"
+       inkscape:export-xdpi="89.889648"
+       inkscape:export-ydpi="89.889648" />
+    <rect
+       style="opacity:1;color:#000000;fill:#0000ff;fill-opacity:0.22608696;fill-rule:nonzero;stroke:none;stroke-width:10.60000038000000089;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:block;overflow:visible"
+       id="rect1913"
+       width="291.42856"
+       height="45.714287"
+       x="-16.285721"
+       y="181.50516" />
+    <path
+       style="font-size:39.83382034000000260px;font-family:Goblin;stroke:none;stroke-opacity:1;fill:#000000;fill-opacity:1"
+       d="M 58.72672,219.00823 L 44.00299,198.17717 L 44.00299,218.61923 L 40.30747,218.61923 L 40.30747,190.12482 L 41.86348,190.12482 L 56.19821,209.82778 L 56.19821,190.12482 L 59.89373,190.12482 L 59.89373,219.00823 L 58.72672,219.00823 M 64.3867,204.1289 C 64.3867,200.0055 65.41756,196.55635 67.47927,193.78144 C 69.55394,191.00659 72.34827,189.61915 75.86227,189.61912 C 79.8171,189.61915 82.84483,190.89637 84.94547,193.45079 C 87.05902,196.00526 88.11581,199.56463 88.11583,204.1289 C 88.11581,208.8099 87.05902,212.47949 84.94547,215.13766 C 82.83187,217.78288 79.80414,219.10548 75.86227,219.10548 C 72.27047,219.10548 69.45669,217.70508 67.42092,214.90426 C 65.39811,212.10345 64.3867,208.51167 64.3867,204.1289 M 68.47123,204.1289 C 68.47122,207.39653 69.11307,210.12603 70.39679,212.3174 C 71.69345,214.50878 73.51528,215.60447 75.86227,215.60447 C 78.52043,215.60447 80.54324,214.59955 81.9307,212.5897 C 83.33109,210.57986 84.03129,207.7596 84.03131,204.1289 C 84.03129,196.78975 81.30828,193.12017 75.86227,193.12014 C 73.45044,193.12017 71.61565,194.10564 70.35789,196.07656 C 69.10011,198.04752 68.47122,200.73163 68.47123,204.1289 M 122.75647,191.17513 L 121.45332,194.5011 C 120.20849,193.59345 118.25052,193.13962 115.57938,193.13959 C 113.07679,193.13962 111.06695,194.21585 109.54985,196.36831 C 108.0457,198.52081 107.29363,201.29569 107.29364,204.69296 C 107.29363,207.93465 108.06515,210.5669 109.6082,212.5897 C 111.1642,214.59955 113.16756,215.60447 115.61828,215.60447 C 118.28942,215.60447 120.34464,214.6579 121.78397,212.76475 L 123.92348,215.74062 C 121.66725,217.98386 118.7627,219.10548 115.20983,219.10548 C 111.48837,219.10548 108.55789,217.76343 106.41838,215.07931 C 104.27887,212.3952 103.20911,208.85529 103.20912,204.45955 C 103.20911,200.20648 104.35019,196.67305 106.63233,193.85925 C 108.91447,191.04549 111.8644,189.6386 115.48213,189.63857 C 118.58117,189.6386 121.00594,190.15079 122.75647,191.17513 M 127.01605,204.1289 C 127.01604,200.0055 128.0469,196.55635 130.10861,193.78144 C 132.18328,191.00659 134.97761,189.61915 138.49161,189.61912 C 142.44645,189.61915 145.47418,190.89637 147.57481,193.45079 C 149.68836,196.00526 150.74515,199.56463 150.74518,204.1289 C 150.74515,208.8099 149.68836,212.47949 147.57481,215.13766 C 145.46121,217.78288 142.43348,219.10548 138.49161,219.10548 C 134.89981,219.10548 132.08603,217.70508 130.05026,214.90426 C 128.02745,212.10345 127.01604,208.51167 127.01605,204.1289 M 131.10057,204.1289 C 131.10056,207.39653 131.74242,210.12603 133.02613,212.3174 C 134.32279,214.50878 136.14462,215.60447 138.49161,215.60447 C 141.14977,215.60447 143.17258,214.59955 144.56004,212.5897 C 145.96043,210.57986 146.66063,207.7596 146.66065,204.1289 C 146.66063,196.78975 143.93762,193.12017 138.49161,193.12014 C 136.07979,193.12017 134.24499,194.10564 132.98723,196.07656 C 131.72945,198.04752 131.10056,200.73163 131.10057,204.1289 M 165.13826,219.00823 L 163.1738,219.00823 L 152.55404,190.12482 L 156.87197,190.12482 L 164.20466,211.11149 L 171.26505,190.12482 L 175.44682,190.12482 L 165.13826,219.00823 M 182.52665,193.62584 L 182.52665,201.54204 L 191.94051,201.54204 L 191.94051,204.84856 L 182.52665,204.84856 L 182.52665,215.11821 L 195.44153,215.11821 L 195.44153,218.61923 L 178.63663,218.61923 L 178.63663,190.12482 L 195.65548,190.12482 L 195.65548,193.62584 L 182.52665,193.62584 M 215.76689,218.61923 L 208.1619,206.38511 C 207.29312,206.38513 205.91864,206.32029 204.03848,206.19061 L 204.03848,218.61923 L 200.14846,218.61923 L 200.14846,190.12482 C 200.29109,190.12485 201.29601,190.07947 203.16322,189.98867 C 205.04339,189.88497 206.41138,189.8331 207.26719,189.83307 C 214.11362,189.8331 217.53683,192.55611 217.53685,198.00212 C 217.53683,199.79155 216.98575,201.4059 215.88359,202.84519 C 214.7814,204.27155 213.47176,205.15977 211.95467,205.50986 L 220.22097,218.61923 L 215.76689,218.61923 M 204.03848,193.62584 L 204.03848,202.8841 C 204.97207,203.01378 205.87974,203.07861 206.76149,203.0786 C 209.09549,203.07861 210.79413,202.70258 211.85742,201.95049 C 212.92068,201.19844 213.45231,199.85638 213.45233,197.92432 C 213.45231,196.32943 212.88178,195.18188 211.74072,194.48165 C 210.59963,193.78147 208.79726,193.43137 206.33359,193.43134 C 205.94458,193.43137 205.17954,193.4962 204.03848,193.62584"
+       id="text1909" />
+    <path
+       style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:0.24020983px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+       d="M 179.91252,49.32409 L 175.05953,49.32409 L 174.08894,51.75058 L 175.05953,54.41971 L 174.57423,57.33149 L 172.14777,55.8756 L 170.20659,52.23587 L 166.08154,51.26527 L 164.38302,49.56674 L 160.74328,47.8682 L 156.61826,41.07404 L 156.8609,37.91961 L 167.05216,30.15485 L 171.90508,32.33868 L 172.63306,34.03723 L 172.63306,35.97841 L 173.84629,37.67695 L 176.27279,38.4049 L 177.97132,36.94901 L 178.21396,35.25047 L 177.48602,33.79458 L 176.03014,33.06663 L 175.05953,31.85339 L 177.24337,30.88279 L 176.75808,28.45631 L 176.75808,27.00042 L 175.3022,25.54453 L 174.57423,23.36069 L 171.66247,22.63274 L 169.23597,22.14745 L 164.14034,25.78718 L 151.27997,30.88279 L 148.36818,33.79458 L 146.18437,35.49312 L 145.69903,39.3755 L 146.66966,41.31668 L 149.09616,47.8682 L 152.25056,53.9344 L 155.64764,58.30208 L 150.30939,67.03743 L 144.24316,80.14045 L 140.60344,85.96402 L 134.53723,93.48612 L 134.29459,96.88321 L 131.14015,99.79499 L 135.99311,104.16267 L 134.77988,109.25828 L 135.26518,120.66277 L 137.44899,133.76579 L 139.63285,145.41292 L 142.0593,149.2953 L 145.45642,156.33211 L 150.79468,164.33951 L 152.25056,169.43511 L 153.70647,173.07485 L 149.33877,179.14107 L 141.57401,182.2955 L 140.84608,184.722 L 155.64764,184.2367 L 153.46382,188.11907 L 156.13294,190.54555 L 163.16975,191.27351 L 168.75068,186.42053 L 170.69189,179.62638 L 173.84629,173.80281 L 177.72867,170.40573 L 178.9419,166.52334 L 174.81692,166.2807 L 177.48602,163.61156 L 172.14777,165.31011 L 176.03014,161.42773 L 173.11835,160.69978 L 170.93451,158.03064 L 167.29477,150.50854 L 158.80208,143.47174 L 157.10356,142.98643 L 158.80208,141.53054 L 158.55944,137.40552 L 160.25799,133.76579 L 158.80208,134.00844 L 161.47122,129.39811 L 161.47122,124.78779 L 163.16975,122.3613 L 163.16975,119.20687 L 166.80948,114.3539 L 167.05216,110.22888 L 166.32418,106.8318 L 168.02275,102.94942 L 169.96392,99.79499 L 169.96392,97.8538 L 172.14777,97.61115 L 174.08894,95.66997 L 175.78749,90.81699 L 179.66987,86.44932 L 184.2802,84.75078 L 187.19194,87.17727 L 194.22879,89.3611 L 199.80969,92.27288 L 202.47881,95.66997 L 207.08912,96.15526 L 221.64807,102.46413 L 229.17014,105.13326 L 235.23639,109.74358 L 236.6923,109.25828 L 236.6923,107.8024 L 233.29522,105.13326 L 239.84671,106.8318 L 240.57467,105.61855 L 239.11875,104.16267 L 241.54525,104.16267 L 241.78792,102.70677 L 237.42021,101.73618 L 240.8173,100.76558 L 240.8173,99.06704 L 239.60405,98.8244 L 235.9643,99.06704 L 233.05255,97.8538 L 231.11135,96.88321 L 234.02314,94.45672 L 234.75109,92.75818 L 234.2658,91.54494 L 231.59668,92.03023 L 226.01573,94.94201 L 225.28782,96.39791 L 223.34661,95.91262 L 216.30978,92.03023 L 216.06716,89.3611 L 211.94212,87.17727 L 204.9053,83.53753 L 203.20677,84.75078 L 203.44942,83.05223 L 199.56705,79.41251 L 196.16996,78.44191 L 193.01553,74.80218 L 192.04494,73.58895 L 195.19937,75.77278 L 194.71409,73.34629 L 197.14055,74.55953 L 196.41261,70.91981 L 199.80969,74.07424 L 198.35382,71.8904 L 201.75086,73.34629 L 198.83911,69.22127 L 201.02293,69.94922 L 200.05234,66.06684 L 201.75086,67.52273 L 199.3244,63.88299 L 201.75086,64.61094 L 199.56705,61.69916 L 202.47881,61.45652 L 199.3244,59.51532 L 201.26558,58.54474 L 199.08175,58.30208 L 201.99351,55.63296 L 199.3244,55.8756 L 199.56705,54.17705 L 199.80969,49.32409 L 198.35382,52.72116 L 196.65525,47.8682 L 196.89791,51.75058 L 195.92732,51.99322 L 193.50082,51.99322 L 190.83168,48.11084 L 188.16256,48.11084 L 185.00813,45.44171 L 183.55222,46.8976 L 179.91252,49.32409 z "
+       id="path1939" />
+    <path
+       id="path2864"
+       d="M 51.95662,130.05789 L 47.10039,130.05789 L 48.40473,131.01205 L 51.87908,132.06164 L 54.12411,133.20664 L 50.33068,132.63414 L 44.97485,131.20289 L 39.93685,130.82122 L 36.64427,130.1533 L 31.40921,129.48538 L 20.90983,126.81372 L 18.19442,125.5733 L 21.11069,122.51996 L 28.01488,123.37871 L 30.33624,124.04664 L 32.15668,124.80996 L 34.96362,125.47789 L 38.07442,125.76413 L 38.40871,125.19163 L 37.05865,124.52371 L 34.96487,123.95121 L 32.82536,123.66496 L 30.71632,123.18789 L 31.9914,122.80622 L 29.23021,121.85205 L 27.8649,121.27955 L 25.04269,120.70704 L 22.26625,119.84829 L 18.66985,119.56204 L 15.78661,119.37122 L 14.10095,120.80247 L 6.01062,122.80622 L 5.82757,123.95121 L 5.23518,124.61913 L 8.39046,126.1458 L 11.18215,126.90913 L 19.7543,129.48538 L 28.59974,131.8708 L 36.09511,133.5883 L 38.94528,137.02331 L 45.16305,142.17581 L 46.98225,144.46581 L 47.96623,147.42373 L 50.90923,148.75957 L 50.48333,149.90457 L 59.43556,151.62207 L 63.00022,153.62582 L 74.18097,158.11041 L 88.6543,163.2629 L 101.76233,167.84291 L 107.83131,169.36957 L 117.82982,172.13667 L 130.68098,175.28542 L 136.91654,177.28916 L 141.78676,178.72041 L 143.10504,181.10583 L 138.29332,182.34625 L 139.84051,183.30042 L 154.19685,183.10959 L 155.65246,184.63625 L 160.59892,185.59042 L 168.32309,185.87668 L 169.35661,183.96834 L 164.92756,181.29668 L 162.62274,179.00666 L 163.32193,177.67084 L 160.89506,176.14417 L 156.53975,176.04875 L 156.70755,174.99916 L 152.9586,175.66708 L 153.20266,174.14042 L 149.60626,173.85417 L 144.91788,172.80458 L 134.22143,169.84666 L 119.12392,167.07958 L 116.96912,166.88874 L 117.30349,166.31624 L 113.19219,164.69416 L 111.47852,163.2629 L 110.24923,163.35833 L 108.5966,161.54541 L 104.27299,159.73248 L 103.6971,158.77832 L 100.73888,157.5379 L 99.82991,155.62956 L 96.20428,154.00749 L 92.29006,152.67165 L 90.34883,151.14498 L 89.33309,149.90457 L 87.51261,149.14123 L 89.47039,149.04582 L 89.59239,148.28249 L 86.74097,146.37415 L 86.52991,144.65665 L 89.55041,143.98873 L 94.73969,144.9429 L 103.82924,145.80165 L 112.14454,146.94665 L 118.00125,148.28249 L 123.06976,148.47331 L 143.55488,150.95414 L 153.58513,152.00373 L 163.97896,153.81666 L 164.98075,153.62582 L 163.61541,153.05332 L 157.71291,152.00373 L 165.86172,152.67165 L 165.45235,152.19457 L 162.63018,151.62207 L 165.05826,151.62207 L 163.93576,151.04957 L 158.65491,150.6679 L 161.14403,150.28623 L 159.55113,149.61832 L 158.10956,149.5229 L 154.69493,149.61832 L 150.64344,149.14123 L 147.7907,148.75957 L 148.42888,147.8054 L 147.56442,147.13749 L 145.94102,146.66039 L 143.7252,146.85123 L 140.87122,147.99623 L 141.50812,148.56873 L 139.11056,148.3779 L 128.42812,146.85123 L 125.68221,145.80165 L 119.50642,144.9429 L 109.05155,143.51164 L 108.48966,143.98873 L 107.13957,143.32081 L 99.84126,141.88956 L 95.53169,141.50789 L 88.9618,140.07664 L 86.85279,139.59956 L 92.05731,140.45831 L 89.29615,139.50414 L 92.86201,139.98123 L 88.72022,138.54997 L 95.07782,139.79039 L 91.57296,138.93164 L 96.33765,139.50414 L 89.55547,137.88206 L 92.42342,138.16831 L 87.81129,136.64163 L 90.8763,137.21415 L 85.03484,135.78288 L 88.14561,136.06914 L 83.22962,134.92414 L 85.9158,134.82872 L 80.93884,134.06539 L 81.97107,133.68372 L 79.55824,133.5883 L 79.96883,132.53872 L 77.5255,132.63414 L 76.1754,131.96622 L 71.8671,130.05789 L 73.59602,131.39371 L 67.34523,129.48538 L 71.22891,131.01205 L 70.48522,131.10747 L 68.05713,131.10747 L 61.74529,129.58081 L 59.07437,129.58081 L 53.41475,128.53122 L 53.32318,129.10371 L 51.95662,130.05789 z "
+       style="opacity:0.22790701;fill:url(#linearGradient3484);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.44754833px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
+    <path
+       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:#ffffff;stroke-width:0.57235873;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+       d="M 171.66025,21.79794 C 162.15973,18.28633 157.05504,31.44378 160.18449,38.80558 C 161.31181,48.09876 161.51381,57.85479 159.05213,66.89762 C 154.41828,71.75825 142.39215,74.87443 142.56497,83.03148"
+       id="path3759"
+       sodipodi:nodetypes="cccc" />
+  </g>
+</svg>
diff --git a/data/themes/default/no_player_image.svg b/data/themes/default/no_player_image.svg
new file mode 100644 (file)
index 0000000..6f1593d
--- /dev/null
@@ -0,0 +1,316 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://creativecommons.org/ns#"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:xlink="http://www.w3.org/1999/xlink"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   width="256"
+   height="256"
+   id="svg2"
+   sodipodi:version="0.32"
+   inkscape:version="0.47pre4 r22446"
+   sodipodi:docname="no_player_image.svg"
+   inkscape:output_extension="org.inkscape.output.svg.inkscape"
+   version="1.0">
+  <defs
+     id="defs4">
+    <inkscape:perspective
+       sodipodi:type="inkscape:persp3d"
+       inkscape:vp_x="0 : 128 : 1"
+       inkscape:vp_y="0 : 1000 : 0"
+       inkscape:vp_z="256 : 128 : 1"
+       inkscape:persp3d-origin="128 : 85.333333 : 1"
+       id="perspective17" />
+    <linearGradient
+       id="linearGradient3751"
+       inkscape:collect="always">
+      <stop
+         id="stop3753"
+         offset="0"
+         style="stop-color:black;stop-opacity:1;" />
+      <stop
+         id="stop3755"
+         offset="1"
+         style="stop-color:black;stop-opacity:0;" />
+    </linearGradient>
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient3751"
+       id="linearGradient3484"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(0.336682,0,0,0.336682,-102.85613,-37.340806)"
+       x1="665.12128"
+       y1="684.16162"
+       x2="381.28015"
+       y2="449.80624" />
+    <filter
+       id="filter5655"
+       height="1.5668966"
+       y="-0.28344828"
+       width="1.1522222"
+       x="-0.076111111"
+       inkscape:collect="always">
+      <feGaussianBlur
+         id="feGaussianBlur5657"
+         stdDeviation="1.4531044"
+         inkscape:collect="always" />
+    </filter>
+    <radialGradient
+       r="17.986024"
+       fy="17.727694"
+       fx="29.922075"
+       cy="17.727694"
+       cx="29.922075"
+       gradientTransform="matrix(0.558489,0,-1.377346e-8,0.563387,14.87134,4.364123)"
+       gradientUnits="userSpaceOnUse"
+       id="radialGradient3816"
+       xlink:href="#linearGradient4562"
+       inkscape:collect="always" />
+    <radialGradient
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(1.354517,0,-3.340511e-8,1.366395,-8.947464,-9.871365)"
+       r="17.986024"
+       fy="26.814409"
+       fx="24.753788"
+       cy="26.814409"
+       cx="24.753788"
+       id="radialGradient4568"
+       xlink:href="#linearGradient4562"
+       inkscape:collect="always" />
+    <linearGradient
+       y2="35.803486"
+       x2="30.935921"
+       y1="29.553486"
+       x1="30.935921"
+       gradientTransform="matrix(1.33835,0,0,1.33835,-33.47918,-20.70004)"
+       gradientUnits="userSpaceOnUse"
+       id="linearGradient1372"
+       xlink:href="#linearGradient3824"
+       inkscape:collect="always" />
+    <linearGradient
+       y2="35.739632"
+       x2="21.408455"
+       y1="36.390400"
+       x1="22.686766"
+       gradientTransform="matrix(-1.308485,0.281154,0.281154,1.308485,39.09106,-26.21225)"
+       gradientUnits="userSpaceOnUse"
+       id="linearGradient1366"
+       xlink:href="#linearGradient4356"
+       inkscape:collect="always" />
+    <linearGradient
+       gradientTransform="matrix(-1.308485,0.281154,0.281154,1.308485,57.41196,-17.2385)"
+       y2="35.739632"
+       x2="21.408455"
+       y1="36.390400"
+       x1="22.686766"
+       gradientUnits="userSpaceOnUse"
+       id="linearGradient4366"
+       xlink:href="#linearGradient4356"
+       inkscape:collect="always" />
+    <linearGradient
+       gradientTransform="matrix(1.3161,0.243028,-0.243028,1.3161,-9.262129,-16.07396)"
+       gradientUnits="userSpaceOnUse"
+       y2="36.217758"
+       x2="22.626925"
+       y1="35.817974"
+       x1="20.661695"
+       id="linearGradient4362"
+       xlink:href="#linearGradient4356"
+       inkscape:collect="always" />
+    <radialGradient
+       gradientUnits="userSpaceOnUse"
+       r="8.6620579"
+       fy="19.008621"
+       fx="31.112698"
+       cy="19.008621"
+       cx="31.112698"
+       id="radialGradient3822"
+       xlink:href="#linearGradient3816"
+       inkscape:collect="always" />
+    <linearGradient
+       id="linearGradient3816"
+       inkscape:collect="always">
+      <stop
+         id="stop3818"
+         offset="0"
+         style="stop-color:#000000;stop-opacity:1;" />
+      <stop
+         id="stop3820"
+         offset="1"
+         style="stop-color:#000000;stop-opacity:0;" />
+    </linearGradient>
+    <linearGradient
+       id="linearGradient3824">
+      <stop
+         id="stop3826"
+         offset="0"
+         style="stop-color:#ffffff;stop-opacity:1;" />
+      <stop
+         id="stop3828"
+         offset="1.0000000"
+         style="stop-color:#c9c9c9;stop-opacity:1.0000000;" />
+    </linearGradient>
+    <linearGradient
+       id="linearGradient4356"
+       inkscape:collect="always">
+      <stop
+         id="stop4358"
+         offset="0"
+         style="stop-color:#000000;stop-opacity:1;" />
+      <stop
+         id="stop4360"
+         offset="1"
+         style="stop-color:#000000;stop-opacity:0;" />
+    </linearGradient>
+    <linearGradient
+       id="linearGradient4562">
+      <stop
+         id="stop4564"
+         offset="0"
+         style="stop-color:#ffffff;stop-opacity:1;" />
+      <stop
+         id="stop4566"
+         offset="1"
+         style="stop-color:#d6d6d2;stop-opacity:1;" />
+    </linearGradient>
+    <inkscape:perspective
+       id="perspective2961"
+       inkscape:persp3d-origin="24 : 16 : 1"
+       inkscape:vp_z="48 : 24 : 1"
+       inkscape:vp_y="0 : 1000 : 0"
+       inkscape:vp_x="0 : 24 : 1"
+       sodipodi:type="inkscape:persp3d" />
+  </defs>
+  <sodipodi:namedview
+     id="base"
+     pagecolor="#ffffff"
+     bordercolor="#666666"
+     borderopacity="1.0"
+     inkscape:pageopacity="0.0"
+     inkscape:pageshadow="2"
+     inkscape:zoom="1.5827038"
+     inkscape:cx="99.986465"
+     inkscape:cy="125.13218"
+     inkscape:document-units="px"
+     inkscape:current-layer="layer1"
+     inkscape:window-width="1144"
+     inkscape:window-height="785"
+     inkscape:window-x="136"
+     inkscape:window-y="25"
+     showguides="true"
+     inkscape:guide-bbox="true"
+     width="256px"
+     height="256px"
+     borderlayer="false"
+     showgrid="false"
+     inkscape:window-maximized="0" />
+  <metadata
+     id="metadata7">
+    <rdf:RDF>
+      <cc:Work
+         rdf:about="">
+        <dc:format>image/svg+xml</dc:format>
+        <dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+      </cc:Work>
+    </rdf:RDF>
+  </metadata>
+  <g
+     inkscape:label="Capa 1"
+     inkscape:groupmode="layer"
+     id="layer1">
+    <g
+       id="g2985"
+       transform="matrix(5.5582986,0,0,5.5582986,-7.1199903,11.2277)">
+      <g
+         style="display:inline"
+         inkscape:label="cipek"
+         id="layer1-1">
+        <path
+           id="path4173"
+           d="m 13.365469,24.850231 5.678138,0 -3.312246,-3.075659 -0.709768,0.946357 -0.709768,-0.709767 -0.946356,2.839069 z"
+           style="color:#000000;fill:url(#linearGradient1372);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;marker:none;visibility:visible;display:inline;overflow:visible" />
+        <path
+           style="opacity:0.22784807;color:#000000;fill:url(#linearGradient1366);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;marker:none;visibility:visible;display:inline;overflow:visible"
+           d="m 19.882923,32.490544 c 1.647845,-0.777552 2.414892,-2.679807 2.414892,-2.679807 -1.283638,-5.410927 -5.321479,-9.158091 -5.321479,-9.158091 0,0 3.298488,8.488623 2.906587,11.837898 z"
+           id="path4370"
+           sodipodi:nodetypes="cccc" />
+      </g>
+      <g
+         style="display:inline"
+         inkscape:label="dalsi cipek"
+         id="layer2">
+        <rect
+           transform="matrix(0.9351852,0,0,0.9351852,1.5811694,2.2763322)"
+           ry="5.126524"
+           rx="5.126524"
+           y="35.448853"
+           x="5.3033009"
+           height="10.253048"
+           width="38.183765"
+           id="rect4608"
+           style="opacity:0.34857142;color:#000000;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.30000001;marker:none;visibility:visible;display:block;overflow:visible;filter:url(#filter5655);enable-background:accumulate" />
+        <path
+           sodipodi:nodetypes="cczcczc"
+           id="path4308"
+           d="m 17.918908,43.517006 14.195346,0 c 4.022015,0 8.003981,-1.47477 9.463562,-5.678138 1.386048,-3.991597 0.23659,-11.592866 -8.753795,-17.744182 l -16.797826,0 c -8.9903852,5.678137 -10.1138992,13.4435 -8.0440285,17.98077 2.1086975,4.62238 5.6781375,5.44155 9.9367415,5.44155 z"
+           style="color:#000000;fill:url(#radialGradient4568);fill-opacity:1;fill-rule:evenodd;stroke:#888a85;stroke-width:0.99999982px;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible" />
+        <path
+           inkscape:r_cy="true"
+           inkscape:r_cx="true"
+           style="opacity:0.29120878;color:#000000;fill:url(#linearGradient4366);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;marker:none;visibility:visible;display:inline;overflow:visible"
+           d="m 38.203826,41.464292 c 1.647845,-0.777552 2.414892,-2.679806 2.414892,-2.679806 -1.283638,-5.410928 -5.32148,-9.158091 -5.32148,-9.158091 0,0 3.298489,8.488622 2.906588,11.837897 z"
+           id="path4364"
+           sodipodi:nodetypes="cccc" />
+        <path
+           inkscape:r_cy="true"
+           inkscape:r_cx="true"
+           sodipodi:nodetypes="cccc"
+           id="path4354"
+           d="M 11.642995,42.046125 C 9.9732599,41.316765 9.2259419,39.559099 9.2259419,39.559099 10.351871,34.11317 14.204505,30.128795 14.204505,30.128795 c 0,0 -3.05053,8.580851 -2.56151,11.91733 z"
+           style="opacity:0.54945056;color:#000000;fill:url(#linearGradient4362);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;marker:none;visibility:visible;display:inline;overflow:visible" />
+        <path
+           style="opacity:0.64285715;color:#000000;fill:none;stroke:#ffffff;stroke-width:0.99999988px;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible"
+           d="m 17.593144,42.482789 14.527688,-0.03059 c 3.654575,0 7.272757,-1.340038 8.598996,-5.159397 C 41.97925,33.665864 40.58869,26.759027 32.419643,21.169679 L 16.464198,20.833163 C 8.295151,25.99256 6.714018,33.0485 8.6253819,37.507773 c 1.9113661,4.459273 4.7005121,4.944423 8.9677621,4.975016 z"
+           id="path4314"
+           sodipodi:nodetypes="cczcczc" />
+        <path
+           transform="matrix(1.33835,0,0,1.33835,-17.02698,-7.522361)"
+           sodipodi:type="arc"
+           style="color:#000000;fill:url(#radialGradient3822);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;marker:none;visibility:visible;display:inline;overflow:visible"
+           id="path4318"
+           sodipodi:cx="31.112698"
+           sodipodi:cy="19.008621"
+           sodipodi:rx="8.6620579"
+           sodipodi:ry="8.6620579"
+           d="m 39.774755,19.008621 c 0,4.783923 -3.878135,8.662058 -8.662057,8.662058 -4.783923,0 -8.662058,-3.878135 -8.662058,-8.662058 0,-4.783922 3.878135,-8.662058 8.662058,-8.662058 4.783922,0 8.662057,3.878136 8.662057,8.662058 z" />
+        <path
+           transform="matrix(1.33835,0,0,1.33835,-16.85969,-12.20659)"
+           d="m 39.774755,19.008621 c 0,4.783923 -3.878135,8.662058 -8.662057,8.662058 -4.783923,0 -8.662058,-3.878135 -8.662058,-8.662058 0,-4.783922 3.878135,-8.662058 8.662058,-8.662058 4.783922,0 8.662057,3.878136 8.662057,8.662058 z"
+           sodipodi:ry="8.6620579"
+           sodipodi:rx="8.6620579"
+           sodipodi:cy="19.008621"
+           sodipodi:cx="31.112698"
+           id="path4320"
+           style="color:#000000;fill:url(#radialGradient3816);fill-opacity:1;fill-rule:evenodd;stroke:#888a85;stroke-width:0.74718857px;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible"
+           sodipodi:type="arc" />
+        <path
+           transform="matrix(1.215123,0,0,1.215123,-13.02574,-9.864199)"
+           sodipodi:type="arc"
+           style="opacity:0.19620254;color:#000000;fill:none;stroke:#ffffff;stroke-width:0.82296228px;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible"
+           id="path4322"
+           sodipodi:cx="31.112698"
+           sodipodi:cy="19.008621"
+           sodipodi:rx="8.6620579"
+           sodipodi:ry="8.6620579"
+           d="m 39.774755,19.008621 c 0,4.783923 -3.878135,8.662058 -8.662057,8.662058 -4.783923,0 -8.662058,-3.878135 -8.662058,-8.662058 0,-4.783922 3.878135,-8.662058 8.662058,-8.662058 4.783922,0 8.662057,3.878136 8.662057,8.662058 z" />
+      </g>
+    </g>
+  </g>
+</svg>
diff --git a/data/themes/default/notebar.png b/data/themes/default/notebar.png
new file mode 100644 (file)
index 0000000..c966ddc
Binary files /dev/null and b/data/themes/default/notebar.png differ
diff --git a/data/themes/default/notebar.svg b/data/themes/default/notebar.svg
new file mode 100644 (file)
index 0000000..0f3e6c0
--- /dev/null
@@ -0,0 +1,120 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://creativecommons.org/ns#"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:xlink="http://www.w3.org/1999/xlink"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   width="128"
+   height="64"
+   id="svg1901"
+   sodipodi:version="0.32"
+   inkscape:version="0.46"
+   sodipodi:docname="notebar.svg"
+   sodipodi:docbase="/home/tsoots/ohj/translations/po"
+   inkscape:export-filename="notebar.png"
+   inkscape:export-xdpi="90"
+   inkscape:export-ydpi="90"
+   version="1.0"
+   inkscape:output_extension="org.inkscape.output.svg.inkscape">
+  <defs
+     id="defs1903">
+    <linearGradient
+       id="linearGradient2388">
+      <stop
+         style="stop-color:#b4e7e7;stop-opacity:1;"
+         offset="0"
+         id="stop2390" />
+      <stop
+         style="stop-color:#165069;stop-opacity:1;"
+         offset="1"
+         id="stop2392" />
+    </linearGradient>
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient2388"
+       id="linearGradient2394"
+       x1="319.99997"
+       y1="525.70605"
+       x2="319.99997"
+       y2="555.01825"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(1.0432362,0,0,1.0929825,-13.835593,-50.244212)" />
+    <filter
+       inkscape:collect="always"
+       id="filter3271"
+       x="-0.066881439"
+       width="1.1337629"
+       y="-0.3485957"
+       height="1.6971914">
+      <feGaussianBlur
+         inkscape:collect="always"
+         stdDeviation="1.3650731"
+         id="feGaussianBlur3273" />
+    </filter>
+  </defs>
+  <sodipodi:namedview
+     id="base"
+     pagecolor="#ffffff"
+     bordercolor="#666666"
+     borderopacity="1.0"
+     inkscape:pageopacity="0.0"
+     inkscape:pageshadow="2"
+     inkscape:zoom="7.9375"
+     inkscape:cx="64"
+     inkscape:cy="32"
+     inkscape:document-units="px"
+     inkscape:current-layer="layer1"
+     gridtolerance="10000"
+     inkscape:window-width="1279"
+     inkscape:window-height="725"
+     inkscape:window-x="505"
+     inkscape:window-y="123"
+     showgrid="false"
+     inkscape:snap-global="false">
+    <inkscape:grid
+       type="xygrid"
+       id="grid3154"
+       visible="true"
+       enabled="true" />
+  </sodipodi:namedview>
+  <metadata
+     id="metadata1906">
+    <rdf:RDF>
+      <cc:Work
+         rdf:about="">
+        <dc:format>image/svg+xml</dc:format>
+        <dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+      </cc:Work>
+    </rdf:RDF>
+  </metadata>
+  <g
+     inkscape:label="Taso 1"
+     inkscape:groupmode="layer"
+     id="layer1"
+     style="opacity:1"
+     transform="translate(-255.99998,-508.36216)">
+    <rect
+       style="fill:url(#linearGradient2394);fill-opacity:1;stroke:#000000;stroke-width:3;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+       id="rect2382"
+       width="62"
+       height="30"
+       x="288.80084"
+       y="525.16302"
+       rx="12"
+       ry="12" />
+    <path
+       sodipodi:type="inkscape:offset"
+       inkscape:radius="1.8614163"
+       inkscape:original="M 44.09375 20.03125 C 43.272831 20.03125 42.521517 20.241931 41.78125 20.46875 C 57.140936 27.84874 73.786659 26.922094 87.03125 20.6875 C 86.068989 20.275907 85.031058 20.03125 83.90625 20.03125 L 44.09375 20.03125 z "
+       style="fill:#ffffff;fill-opacity:0.45098039000000001;stroke:none;stroke-width:1.50000000000000000;stroke-miterlimit:4;stroke-opacity:1;filter:url(#filter3271)"
+       id="path3258"
+       d="M 44.09375,18.15625 C 42.954355,18.15625 42.018873,18.451916 41.25,18.6875 C 40.507736,18.902901 39.975772,19.554539 39.913311,20.324897 C 39.850849,21.095255 40.270884,21.824081 40.96875,22.15625 C 56.856448,29.789938 74.088462,28.835283 87.8125,22.375 C 88.481947,22.065076 88.905231,21.389083 88.891698,20.6515 C 88.878164,19.913917 88.430366,19.253906 87.75,18.96875 C 86.587974,18.471711 85.300976,18.15625 83.90625,18.15625 L 44.09375,18.15625 z"
+       transform="matrix(1.0432362,0,0,1.0929825,253.23285,506.83928)" />
+  </g>
+</svg>
diff --git a/data/themes/default/notebar_hi.svg b/data/themes/default/notebar_hi.svg
new file mode 100644 (file)
index 0000000..c3635e8
--- /dev/null
@@ -0,0 +1,124 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://creativecommons.org/ns#"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:xlink="http://www.w3.org/1999/xlink"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   width="128"
+   height="64"
+   id="svg1901"
+   sodipodi:version="0.32"
+   inkscape:version="0.46"
+   sodipodi:docname="notebar_hi.svg"
+   sodipodi:docbase="/home/tsoots/ohj/translations/po"
+   inkscape:export-filename="/home/knittl/git/performous/themes/default/notebar.png"
+   inkscape:export-xdpi="90"
+   inkscape:export-ydpi="90"
+   version="1.0"
+   inkscape:output_extension="org.inkscape.output.svg.inkscape">
+  <defs
+     id="defs1903">
+    <linearGradient
+       id="linearGradient2388">
+      <stop
+         style="stop-color:#f8fdfd;stop-opacity:1;"
+         offset="0"
+         id="stop2390" />
+      <stop
+         style="stop-color:#cee9f5;stop-opacity:1;"
+         offset="1"
+         id="stop2392" />
+    </linearGradient>
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient2388"
+       id="linearGradient2394"
+       x1="319.99997"
+       y1="525.70605"
+       x2="319.99997"
+       y2="555.01825"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(1.1601497,0,0,1.2215012,-51.225596,-119.66742)" />
+    <filter
+       inkscape:collect="always"
+       id="filter3271"
+       x="-0.066881439"
+       width="1.1337629"
+       y="-0.3485957"
+       height="1.6971914">
+      <feGaussianBlur
+         inkscape:collect="always"
+         stdDeviation="1.3650731"
+         id="feGaussianBlur3273" />
+    </filter>
+    <filter
+       inkscape:collect="always"
+       id="filter3331"
+       x="-0.13569231"
+       width="1.2713846"
+       y="-0.26727273"
+       height="1.5345455">
+      <feGaussianBlur
+         inkscape:collect="always"
+         stdDeviation="4.0678416"
+         id="feGaussianBlur3333" />
+    </filter>
+  </defs>
+  <sodipodi:namedview
+     id="base"
+     pagecolor="#ffffff"
+     bordercolor="#666666"
+     borderopacity="1.0"
+     inkscape:pageopacity="0.0"
+     inkscape:pageshadow="2"
+     inkscape:zoom="7.9375"
+     inkscape:cx="64"
+     inkscape:cy="32"
+     inkscape:document-units="px"
+     inkscape:current-layer="layer1"
+     gridtolerance="10000"
+     inkscape:window-width="1279"
+     inkscape:window-height="725"
+     inkscape:window-x="505"
+     inkscape:window-y="123"
+     showgrid="false"
+     inkscape:snap-global="false">
+    <inkscape:grid
+       type="xygrid"
+       id="grid3154"
+       visible="true"
+       enabled="true" />
+  </sodipodi:namedview>
+  <metadata
+     id="metadata1906">
+    <rdf:RDF>
+      <cc:Work
+         rdf:about="">
+        <dc:format>image/svg+xml</dc:format>
+        <dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+      </cc:Work>
+    </rdf:RDF>
+  </metadata>
+  <g
+     inkscape:label="Taso 1"
+     inkscape:groupmode="layer"
+     id="layer1"
+     style="opacity:1"
+     transform="translate(-255.99998,-508.36216)">
+    <rect
+       style="fill:url(#linearGradient2394);fill-opacity:1;stroke:#ffffff;stroke-width:3;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;filter:url(#filter3331)"
+       id="rect2382"
+       width="68.948219"
+       height="33.527557"
+       x="285.32672"
+       y="523.39923"
+       rx="12"
+       ry="12" />
+  </g>
+</svg>
diff --git a/data/themes/default/notebarfs-hl.png b/data/themes/default/notebarfs-hl.png
new file mode 100644 (file)
index 0000000..949b70e
Binary files /dev/null and b/data/themes/default/notebarfs-hl.png differ
diff --git a/data/themes/default/notebarfs.svg b/data/themes/default/notebarfs.svg
new file mode 100644 (file)
index 0000000..8cf7b44
--- /dev/null
@@ -0,0 +1,254 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://creativecommons.org/ns#"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:xlink="http://www.w3.org/1999/xlink"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   width="32"
+   height="256"
+   id="svg1901"
+   sodipodi:version="0.32"
+   inkscape:version="0.48.4 r9939"
+   sodipodi:docname="notebarfs.svg"
+   inkscape:export-filename="notebar.png"
+   inkscape:export-xdpi="90"
+   inkscape:export-ydpi="90"
+   version="1.0"
+   inkscape:output_extension="org.inkscape.output.svg.inkscape">
+  <defs
+     id="defs1903">
+    <inkscape:perspective
+       sodipodi:type="inkscape:persp3d"
+       inkscape:vp_x="0 : 32 : 1"
+       inkscape:vp_y="0 : 1000 : 0"
+       inkscape:vp_z="128 : 32 : 1"
+       inkscape:persp3d-origin="64 : 21.333333 : 1"
+       id="perspective2427" />
+    <linearGradient
+       inkscape:collect="always"
+       id="linearGradient4724">
+      <stop
+         style="stop-color:#000000;stop-opacity:1;"
+         offset="0"
+         id="stop4726" />
+      <stop
+         style="stop-color:#000000;stop-opacity:0;"
+         offset="1"
+         id="stop4728" />
+    </linearGradient>
+    <linearGradient
+       inkscape:collect="always"
+       id="linearGradient3186">
+      <stop
+         style="stop-color:#000000;stop-opacity:1;"
+         offset="0"
+         id="stop3188" />
+      <stop
+         style="stop-color:#000000;stop-opacity:0;"
+         offset="1"
+         id="stop3190" />
+    </linearGradient>
+    <linearGradient
+       id="linearGradient3156">
+      <stop
+         style="stop-color:#00ff00;stop-opacity:0;"
+         offset="0"
+         id="stop3168" />
+      <stop
+         id="stop3158"
+         offset="0.5"
+         style="stop-color:#00ff00;stop-opacity:0.50862068;" />
+      <stop
+         style="stop-color:#00ff00;stop-opacity:0;"
+         offset="1"
+         id="stop3160" />
+    </linearGradient>
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient3186"
+       id="linearGradient3192"
+       x1="287.99997"
+       y1="539.13879"
+       x2="289.02505"
+       y2="539.13879"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(1,0,0,0.8859366,-49.31992,55.572479)" />
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient4724"
+       id="linearGradient4730"
+       x1="351.99997"
+       y1="540.24847"
+       x2="353.0126"
+       y2="540.24847"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(1,0,0,0.9087975,0,49.529558)" />
+  </defs>
+  <sodipodi:namedview
+     id="base"
+     pagecolor="#ffffff"
+     bordercolor="#666666"
+     borderopacity="1.0"
+     inkscape:pageopacity="0.0"
+     inkscape:pageshadow="2"
+     inkscape:zoom="2.0728926"
+     inkscape:cx="231.53773"
+     inkscape:cy="176.60375"
+     inkscape:document-units="px"
+     inkscape:current-layer="layer1"
+     gridtolerance="10000"
+     inkscape:window-width="1918"
+     inkscape:window-height="1125"
+     inkscape:window-x="0"
+     inkscape:window-y="27"
+     showgrid="false"
+     inkscape:snap-global="false"
+     inkscape:window-maximized="0">
+    <inkscape:grid
+       type="xygrid"
+       id="grid3154"
+       visible="true"
+       enabled="true"
+       dotted="false"
+       spacingx="1px"
+       empspacing="8" />
+  </sodipodi:namedview>
+  <metadata
+     id="metadata1906">
+    <rdf:RDF>
+      <cc:Work
+         rdf:about="">
+        <dc:format>image/svg+xml</dc:format>
+        <dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+      </cc:Work>
+    </rdf:RDF>
+  </metadata>
+  <g
+     inkscape:label="Taso 1"
+     inkscape:groupmode="layer"
+     id="layer1"
+     style="opacity:1"
+     transform="translate(-255.99998,-508.36216)">
+    <path
+       style="fill:#11991a;fill-opacity:0.73043478;stroke:none;stroke-width:0.05000000000000000;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+       d="M 255.99998,524.36216 L 255.99998,748.36216 L 271.99998,764.36216 L 287.99998,748.36216 L 287.99998,524.36216 L 271.99998,508.36216 L 255.99998,524.36216 z"
+       id="rect31607"
+       sodipodi:nodetypes="ccccccc" />
+    <path
+       style="opacity:1;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.05000000000000000;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+       d="M 255.99998,548.36216 L 255.99998,724.36216 L 271.99998,740.36216 L 287.99998,724.36216 L 287.99998,548.36216 L 271.99998,532.36216 L 255.99998,548.36216 z"
+       id="path31629"
+       sodipodi:nodetypes="ccccccc" />
+    <text
+       xml:space="preserve"
+       style="font-size:160px;font-style:normal;font-variant:normal;font-weight:300;font-stretch:normal;fill:#ffffff;fill-opacity:1;stroke:#000000;stroke-width:1.25;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;font-family:Goblin;-inkscape-font-specification:Goblin"
+       x="414.11746"
+       y="740.15057"
+       id="text3170"><tspan
+         sodipodi:role="line"
+         id="tspan3172"
+         x="414.11746"
+         y="740.15057"
+         style="fill:#ffffff;fill-opacity:1;stroke-width:1.25;stroke-miterlimit:4;stroke-dasharray:none" /></text>
+    <text
+       xml:space="preserve"
+       style="font-size:160px;font-style:normal;font-variant:normal;font-weight:300;font-stretch:normal;fill:#ffffff;fill-opacity:1;stroke:#000000;stroke-width:1.25;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;font-family:Goblin;-inkscape-font-specification:Goblin"
+       x="424.41928"
+       y="727.78839"
+       id="text3174"><tspan
+         sodipodi:role="line"
+         id="tspan3176"
+         x="424.41928"
+         y="727.78839"
+         style="fill:#ffffff;fill-opacity:1;stroke-width:1.25;stroke-miterlimit:4;stroke-dasharray:none" /></text>
+    <text
+       xml:space="preserve"
+       style="font-size:52px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;fill:#ffffff;fill-opacity:1;stroke:#000000;stroke-width:1.25;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;font-family:Goblin;-inkscape-font-specification:Goblin"
+       x="227.65469"
+       y="623.74011"
+       id="text2433"><tspan
+         sodipodi:role="line"
+         id="tspan2435"
+         x="227.65469"
+         y="623.74011"
+         style="fill:#ffffff;fill-opacity:1;stroke-width:1.25;stroke-miterlimit:4;stroke-dasharray:none" /></text>
+    <g
+       id="g3044"
+       transform="translate(0,19.296706)">
+      <text
+         inkscape:tile-y0="16.344164"
+         inkscape:tile-x0="-24.188238"
+         inkscape:tile-h="32.000003"
+         inkscape:tile-w="24.000001"
+         inkscape:tile-cy="32.344166"
+         inkscape:tile-cx="-12.188238"
+         transform="matrix(0.5999227,-0.8243114,0.6961004,0.710419,0,0)"
+         id="text2437"
+         y="562.86029"
+         x="-366.6051"
+         style="font-size:22.18232727px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;fill:#ffffff;fill-opacity:1;stroke:#000000;stroke-width:1.25;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;font-family:Goblin"
+         xml:space="preserve"><tspan
+           style="fill:#ffffff;fill-opacity:1;stroke-width:1.25;stroke-miterlimit:4;stroke-dasharray:none"
+           y="562.86029"
+           x="-366.6051"
+           id="tspan2439"
+           sodipodi:role="line">FREESTYLE</tspan></text>
+      <use
+         height="64"
+         width="128"
+         style="fill:#ffffff;fill-opacity:1;stroke:#000000;stroke-width:1.25;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+         id="use31509"
+         xlink:href="#text2437"
+         inkscape:tiled-clone-of="#text2437"
+         y="0"
+         x="0" />
+      <use
+         height="64"
+         width="128"
+         style="fill:#ffffff;fill-opacity:1;stroke:#000000;stroke-width:1.25;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+         id="use31511"
+         transform="translate(32.000642,0)"
+         xlink:href="#text2437"
+         inkscape:tiled-clone-of="#text2437"
+         y="0"
+         x="0" />
+      <use
+         height="64"
+         width="128"
+         style="fill:#ffffff;fill-opacity:1;stroke:#000000;stroke-width:1.25;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+         id="use31513"
+         transform="translate(64.001284,0)"
+         xlink:href="#text2437"
+         inkscape:tiled-clone-of="#text2437"
+         y="0"
+         x="0" />
+      <use
+         height="64"
+         width="128"
+         style="fill:#ffffff;fill-opacity:1;stroke:#000000;stroke-width:1.25;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+         id="use31515"
+         transform="translate(96.001924,0)"
+         xlink:href="#text2437"
+         inkscape:tiled-clone-of="#text2437"
+         y="0"
+         x="0" />
+      <use
+         height="64"
+         width="128"
+         style="fill:#ffffff;fill-opacity:1;stroke:#000000;stroke-width:1.25;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+         id="use31517"
+         transform="translate(128.00257,0)"
+         xlink:href="#text2437"
+         inkscape:tiled-clone-of="#text2437"
+         y="0"
+         x="0" />
+    </g>
+  </g>
+</svg>
diff --git a/data/themes/default/notebargold.png b/data/themes/default/notebargold.png
new file mode 100644 (file)
index 0000000..d88a2c2
Binary files /dev/null and b/data/themes/default/notebargold.png differ
diff --git a/data/themes/default/notebargold.svg b/data/themes/default/notebargold.svg
new file mode 100644 (file)
index 0000000..ad02c4d
--- /dev/null
@@ -0,0 +1,437 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://creativecommons.org/ns#"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:xlink="http://www.w3.org/1999/xlink"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   width="128"
+   height="64"
+   id="svg1901"
+   sodipodi:version="0.32"
+   inkscape:version="0.46"
+   sodipodi:docname="notebargold.svg"
+   sodipodi:docbase="/home/tsoots/ohj/translations/po"
+   inkscape:export-filename="notebar.png"
+   inkscape:export-xdpi="90"
+   inkscape:export-ydpi="90"
+   version="1.0"
+   inkscape:output_extension="org.inkscape.output.svg.inkscape">
+  <defs
+     id="defs1903">
+    <linearGradient
+       id="linearGradient3207">
+      <stop
+         style="stop-color:#fffbb9;stop-opacity:1;"
+         offset="0"
+         id="stop3209" />
+      <stop
+         id="stop3211"
+         offset="0.44999999"
+         style="stop-color:#fff101;stop-opacity:1;" />
+      <stop
+         style="stop-color:#e63600;stop-opacity:1;"
+         offset="1"
+         id="stop3213" />
+    </linearGradient>
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient3207"
+       id="linearGradient3203"
+       gradientUnits="userSpaceOnUse"
+       x1="319.99997"
+       y1="525.70605"
+       x2="319.99997"
+       y2="555.27692"
+       gradientTransform="matrix(1.0432367,0,0,1.0929798,-13.83573,-50.242734)" />
+    <filter
+       inkscape:collect="always"
+       id="filter3215"
+       x="-0.070401584"
+       width="1.1408032"
+       y="-0.36694321"
+       height="1.7338864">
+      <feGaussianBlur
+         inkscape:collect="always"
+         stdDeviation="1.4369205"
+         id="feGaussianBlur3217" />
+    </filter>
+    <filter
+       inkscape:collect="always"
+       id="filter3314">
+      <feGaussianBlur
+         inkscape:collect="always"
+         stdDeviation="0.2676702"
+         id="feGaussianBlur3316" />
+    </filter>
+    <filter
+       height="1.5963658"
+       y="-0.29818292"
+       width="1.1144185"
+       x="-0.057209262"
+       id="filter3260"
+       inkscape:collect="always">
+      <feGaussianBlur
+         id="feGaussianBlur3262"
+         stdDeviation="1.1676607"
+         inkscape:collect="always" />
+    </filter>
+    <linearGradient
+       gradientTransform="matrix(1.0432362,0,0,1.0929825,-13.835593,-50.244212)"
+       gradientUnits="userSpaceOnUse"
+       y2="555.01825"
+       x2="319.99997"
+       y1="525.70605"
+       x1="319.99997"
+       id="linearGradient2394"
+       xlink:href="#linearGradient2388"
+       inkscape:collect="always" />
+    <linearGradient
+       id="linearGradient2388">
+      <stop
+         id="stop2390"
+         offset="0"
+         style="stop-color:#84c0d8;stop-opacity:1;" />
+      <stop
+         id="stop2392"
+         offset="1"
+         style="stop-color:#449ec4;stop-opacity:1;" />
+    </linearGradient>
+    <inkscape:perspective
+       id="perspective3325"
+       inkscape:persp3d-origin="64 : 21.333333 : 1"
+       inkscape:vp_z="128 : 32 : 1"
+       inkscape:vp_y="0 : 1000 : 0"
+       inkscape:vp_x="0 : 32 : 1"
+       sodipodi:type="inkscape:persp3d" />
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient2388"
+       id="linearGradient3341"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(1.0432362,0,0,1.0929825,27.678613,-33.716309)"
+       x1="319.99997"
+       y1="525.70605"
+       x2="319.99997"
+       y2="555.01825" />
+    <filter
+       inkscape:collect="always"
+       id="filter3359"
+       x="-0.070401515"
+       width="1.140803"
+       y="-0.36694285"
+       height="1.7338857">
+      <feGaussianBlur
+         inkscape:collect="always"
+         stdDeviation="1.4369191"
+         id="feGaussianBlur3361" />
+    </filter>
+  </defs>
+  <sodipodi:namedview
+     id="base"
+     pagecolor="#ffffff"
+     bordercolor="#666666"
+     borderopacity="1.0"
+     inkscape:pageopacity="0.0"
+     inkscape:pageshadow="2"
+     inkscape:zoom="9.125"
+     inkscape:cx="64"
+     inkscape:cy="32"
+     inkscape:document-units="px"
+     inkscape:current-layer="layer1"
+     gridtolerance="10000"
+     inkscape:window-width="1439"
+     inkscape:window-height="801"
+     inkscape:window-x="250"
+     inkscape:window-y="269"
+     showgrid="false"
+     inkscape:snap-global="false">
+    <inkscape:grid
+       type="xygrid"
+       id="grid3154"
+       visible="true"
+       enabled="true" />
+  </sodipodi:namedview>
+  <metadata
+     id="metadata1906">
+    <rdf:RDF>
+      <cc:Work
+         rdf:about="">
+        <dc:format>image/svg+xml</dc:format>
+        <dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+      </cc:Work>
+    </rdf:RDF>
+  </metadata>
+  <g
+     inkscape:label="Taso 1"
+     inkscape:groupmode="layer"
+     id="layer1"
+     style="opacity:1"
+     transform="translate(-255.99998,-508.36216)">
+    <path
+       sodipodi:type="inkscape:offset"
+       inkscape:radius="1.8614163"
+       inkscape:original="M 44.09375 20.03125 C 43.272831 20.03125 42.521517 20.241931 41.78125 20.46875 C 57.140936 27.84874 73.786659 26.922094 87.03125 20.6875 C 86.068989 20.275907 85.031058 20.03125 83.90625 20.03125 L 44.09375 20.03125 z "
+       style="opacity:1;fill:#ffffff;fill-opacity:0.78431373999999998;stroke:none;stroke-width:1.50000000000000000;stroke-miterlimit:4;stroke-opacity:1;filter:url(#filter3215)"
+       id="path3258"
+       d="M 44.09375,18.15625 C 42.954355,18.15625 42.018873,18.451916 41.25,18.6875 C 40.507736,18.902901 39.975772,19.554539 39.913311,20.324897 C 39.850849,21.095255 40.270884,21.824081 40.96875,22.15625 C 56.856448,29.789938 74.088462,28.835283 87.8125,22.375 C 88.481947,22.065076 88.905231,21.389083 88.891698,20.6515 C 88.878164,19.913917 88.430366,19.253906 87.75,18.96875 C 86.587974,18.471711 85.300976,18.15625 83.90625,18.15625 L 44.09375,18.15625 z"
+       transform="matrix(1.0432367,0,0,1.0929798,253.23284,506.09055)" />
+    <rect
+       style="opacity:1;fill:url(#linearGradient3203);fill-opacity:1;stroke:#000000;stroke-width:3;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+       id="rect3198"
+       width="62"
+       height="30"
+       x="288.80084"
+       y="525.16309"
+       rx="12"
+       ry="12" />
+    <path
+       sodipodi:type="inkscape:offset"
+       inkscape:radius="1.8614163"
+       inkscape:original="M 44.09375 20.03125 C 43.272831 20.03125 42.521517 20.241931 41.78125 20.46875 C 57.140936 27.84874 73.786659 26.922094 87.03125 20.6875 C 86.068989 20.275907 85.031058 20.03125 83.90625 20.03125 L 44.09375 20.03125 z "
+       style="opacity:1;fill:#ffffff;fill-opacity:0.56862747999999996;stroke:none;stroke-width:1.50000000000000000;stroke-miterlimit:4;stroke-opacity:1;filter:url(#filter3359)"
+       id="path3337"
+       d="M 44.09375,18.15625 C 42.954355,18.15625 42.018873,18.451916 41.25,18.6875 C 40.507736,18.902901 39.975772,19.554539 39.913311,20.324897 C 39.850849,21.095255 40.270884,21.824081 40.96875,22.15625 C 56.856448,29.789938 74.088462,28.835283 87.8125,22.375 C 88.481947,22.065076 88.905231,21.389083 88.891698,20.6515 C 88.878164,19.913917 88.430366,19.253906 87.75,18.96875 C 86.587974,18.471711 85.300976,18.15625 83.90625,18.15625 L 44.09375,18.15625 z"
+       transform="matrix(1.0432362,0,0,1.0929825,252.81598,508.3371)" />
+  </g>
+  <g
+     inkscape:groupmode="layer"
+     id="layer2"
+     inkscape:label="stars"
+     style="display:none">
+    <g
+       id="g3241"
+       transform="translate(-254.43583,-507.84078)"
+       style="opacity:0.66000001;filter:url(#filter3314)">
+      <path
+         sodipodi:type="star"
+         style="opacity:1;fill:#fff49f;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.5;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-opacity:1;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+         id="path3221"
+         sodipodi:sides="5"
+         sodipodi:cx="21.637474"
+         sodipodi:cy="12.382892"
+         sodipodi:r1="14.288825"
+         sodipodi:r2="7.1444125"
+         sodipodi:arg1="0.76604574"
+         sodipodi:arg2="1.3943643"
+         inkscape:flatsided="false"
+         inkscape:rounded="0.25"
+         inkscape:randomized="0.1"
+         d="M 31.160812,22.085001 C 29.756913,23.955488 25.54813,19.829732 23.293627,20.053134 C 21.039124,20.276535 17.245375,25.474203 14.971975,24.782986 C 12.698575,24.091769 15.245115,18.647267 14.313005,16.532585 C 13.380895,14.417902 6.9803643,12.208497 6.9519812,9.7565543 C 6.9235982,7.3046114 14.655317,7.8280513 16.440248,6.299865 C 18.225179,4.7716787 18.354583,-1.2069278 20.54349,-1.8373023 C 22.732398,-2.4676768 22.903473,5.8960807 24.965768,7.0572723 C 27.028062,8.2184639 33.821244,4.297162 34.602091,6.4464993 C 35.382938,8.5958367 28.742383,9.9662008 28.138106,12.336218 C 27.533828,14.706235 32.564711,20.214514 31.160812,22.085001 z"
+         transform="matrix(0.2517608,-0.3589923,0.3352142,0.2696192,284.77989,529.17981)" />
+      <path
+         sodipodi:type="star"
+         style="opacity:1;fill:#fff49f;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.5;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-opacity:1;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+         id="path3223"
+         sodipodi:sides="5"
+         sodipodi:cx="21.637474"
+         sodipodi:cy="12.382892"
+         sodipodi:r1="14.288825"
+         sodipodi:r2="7.1444125"
+         sodipodi:arg1="0.76604574"
+         sodipodi:arg2="1.3943643"
+         inkscape:flatsided="false"
+         inkscape:rounded="0.25"
+         inkscape:randomized="0.1"
+         d="M 31.160812,22.085001 C 29.756913,23.955488 25.54813,19.829732 23.293627,20.053134 C 21.039124,20.276535 17.245375,25.474203 14.971975,24.782986 C 12.698575,24.091769 15.245115,18.647267 14.313005,16.532585 C 13.380895,14.417902 6.9803643,12.208497 6.9519812,9.7565543 C 6.9235982,7.3046114 14.655317,7.8280513 16.440248,6.299865 C 18.225179,4.7716787 18.354583,-1.2069278 20.54349,-1.8373023 C 22.732398,-2.4676768 22.903473,5.8960807 24.965768,7.0572723 C 27.028062,8.2184639 33.821244,4.297162 34.602091,6.4464993 C 35.382938,8.5958367 28.742383,9.9662008 28.138106,12.336218 C 27.533828,14.706235 32.564711,20.214514 31.160812,22.085001 z"
+         transform="matrix(-0.4226537,0.1006544,-0.1006544,-0.4226537,343.62899,527.82816)" />
+      <path
+         sodipodi:type="star"
+         style="opacity:1;fill:#fff49f;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.5;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-opacity:1;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+         id="path3225"
+         sodipodi:sides="5"
+         sodipodi:cx="21.637474"
+         sodipodi:cy="12.382892"
+         sodipodi:r1="14.288825"
+         sodipodi:r2="7.1444125"
+         sodipodi:arg1="0.76604574"
+         sodipodi:arg2="1.3943643"
+         inkscape:flatsided="false"
+         inkscape:rounded="0.25"
+         inkscape:randomized="0.1"
+         d="M 31.160812,22.085001 C 29.756913,23.955488 25.54813,19.829732 23.293627,20.053134 C 21.039124,20.276535 17.245375,25.474203 14.971975,24.782986 C 12.698575,24.091769 15.245115,18.647267 14.313005,16.532585 C 13.380895,14.417902 6.9803643,12.208497 6.9519812,9.7565543 C 6.9235982,7.3046114 14.655317,7.8280513 16.440248,6.299865 C 18.225179,4.7716787 18.354583,-1.2069278 20.54349,-1.8373023 C 22.732398,-2.4676768 22.903473,5.8960807 24.965768,7.0572723 C 27.028062,8.2184639 33.821244,4.297162 34.602091,6.4464993 C 35.382938,8.5958367 28.742383,9.9662008 28.138106,12.336218 C 27.533828,14.706235 32.564711,20.214514 31.160812,22.085001 z"
+         transform="matrix(6.0995116e-2,-0.4715566,0.2973004,9.6746097e-2,343.8725,559.8055)" />
+      <path
+         sodipodi:type="star"
+         style="opacity:1;fill:#fff49f;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.5;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-opacity:1;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+         id="path3227"
+         sodipodi:sides="5"
+         sodipodi:cx="21.637474"
+         sodipodi:cy="12.382892"
+         sodipodi:r1="14.288825"
+         sodipodi:r2="7.1444125"
+         sodipodi:arg1="0.76604574"
+         sodipodi:arg2="1.3943643"
+         inkscape:flatsided="false"
+         inkscape:rounded="0.25"
+         inkscape:randomized="0.1"
+         d="M 31.160812,22.085001 C 29.756913,23.955488 25.54813,19.829732 23.293627,20.053134 C 21.039124,20.276535 17.245375,25.474203 14.971975,24.782986 C 12.698575,24.091769 15.245115,18.647267 14.313005,16.532585 C 13.380895,14.417902 6.9803643,12.208497 6.9519812,9.7565543 C 6.9235982,7.3046114 14.655317,7.8280513 16.440248,6.299865 C 18.225179,4.7716787 18.354583,-1.2069278 20.54349,-1.8373023 C 22.732398,-2.4676768 22.903473,5.8960807 24.965768,7.0572723 C 27.028062,8.2184639 33.821244,4.297162 34.602091,6.4464993 C 35.382938,8.5958367 28.742383,9.9662008 28.138106,12.336218 C 27.533828,14.706235 32.564711,20.214514 31.160812,22.085001 z"
+         transform="matrix(-2.3552595e-2,-0.4523683,0.3372133,-3.1595577e-2,319.91763,565.39226)" />
+      <path
+         sodipodi:type="star"
+         style="opacity:1;fill:#fff49f;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.5;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-opacity:1;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+         id="path3229"
+         sodipodi:sides="5"
+         sodipodi:cx="21.637474"
+         sodipodi:cy="12.382892"
+         sodipodi:r1="14.288825"
+         sodipodi:r2="7.1444125"
+         sodipodi:arg1="0.76604574"
+         sodipodi:arg2="1.3943643"
+         inkscape:flatsided="false"
+         inkscape:rounded="0.25"
+         inkscape:randomized="0.1"
+         d="M 31.160812,22.085001 C 29.756913,23.955488 25.54813,19.829732 23.293627,20.053134 C 21.039124,20.276535 17.245375,25.474203 14.971975,24.782986 C 12.698575,24.091769 15.245115,18.647267 14.313005,16.532585 C 13.380895,14.417902 6.9803643,12.208497 6.9519812,9.7565543 C 6.9235982,7.3046114 14.655317,7.8280513 16.440248,6.299865 C 18.225179,4.7716787 18.354583,-1.2069278 20.54349,-1.8373023 C 22.732398,-2.4676768 22.903473,5.8960807 24.965768,7.0572723 C 27.028062,8.2184639 33.821244,4.297162 34.602091,6.4464993 C 35.382938,8.5958367 28.742383,9.9662008 28.138106,12.336218 C 27.533828,14.706235 32.564711,20.214514 31.160812,22.085001 z"
+         transform="matrix(-0.4077357,-0.170593,0.1500638,-0.4635153,297.97321,561.11569)" />
+      <path
+         sodipodi:type="star"
+         style="opacity:1;fill:#fff49f;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.5;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-opacity:1;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+         id="path3231"
+         sodipodi:sides="5"
+         sodipodi:cx="21.637474"
+         sodipodi:cy="12.382892"
+         sodipodi:r1="14.288825"
+         sodipodi:r2="7.1444125"
+         sodipodi:arg1="0.76604574"
+         sodipodi:arg2="1.3943643"
+         inkscape:flatsided="false"
+         inkscape:rounded="0.25"
+         inkscape:randomized="0.1"
+         d="M 31.160812,22.085001 C 29.756913,23.955488 25.54813,19.829732 23.293627,20.053134 C 21.039124,20.276535 17.245375,25.474203 14.971975,24.782986 C 12.698575,24.091769 15.245115,18.647267 14.313005,16.532585 C 13.380895,14.417902 6.9803643,12.208497 6.9519812,9.7565543 C 6.9235982,7.3046114 14.655317,7.8280513 16.440248,6.299865 C 18.225179,4.7716787 18.354583,-1.2069278 20.54349,-1.8373023 C 22.732398,-2.4676768 22.903473,5.8960807 24.965768,7.0572723 C 27.028062,8.2184639 33.821244,4.297162 34.602091,6.4464993 C 35.382938,8.5958367 28.742383,9.9662008 28.138106,12.336218 C 27.533828,14.706235 32.564711,20.214514 31.160812,22.085001 z"
+         transform="matrix(-0.1402938,0.4111997,-0.4111997,-0.1402938,312.90301,550.0936)" />
+      <path
+         transform="matrix(-0.3760896,0.1189566,-0.1233495,-0.3626959,356.26327,529.09824)"
+         d="M 31.160812,22.085001 C 29.756913,23.955488 25.54813,19.829732 23.293627,20.053134 C 21.039124,20.276535 17.245375,25.474203 14.971975,24.782986 C 12.698575,24.091769 15.245115,18.647267 14.313005,16.532585 C 13.380895,14.417902 6.9803643,12.208497 6.9519812,9.7565543 C 6.9235982,7.3046114 14.655317,7.8280513 16.440248,6.299865 C 18.225179,4.7716787 18.354583,-1.2069278 20.54349,-1.8373023 C 22.732398,-2.4676768 22.903473,5.8960807 24.965768,7.0572723 C 27.028062,8.2184639 33.821244,4.297162 34.602091,6.4464993 C 35.382938,8.5958367 28.742383,9.9662008 28.138106,12.336218 C 27.533828,14.706235 32.564711,20.214514 31.160812,22.085001 z"
+         inkscape:randomized="0.1"
+         inkscape:rounded="0.25"
+         inkscape:flatsided="false"
+         sodipodi:arg2="1.3943643"
+         sodipodi:arg1="0.76604574"
+         sodipodi:r2="7.1444125"
+         sodipodi:r1="14.288825"
+         sodipodi:cy="12.382892"
+         sodipodi:cx="21.637474"
+         sodipodi:sides="5"
+         id="path3318"
+         style="opacity:1;fill:#fff49f;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.5;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-opacity:1;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+         sodipodi:type="star" />
+      <path
+         transform="matrix(-0.4128364,0.1354017,-0.1354017,-0.4128364,329.3917,550.03765)"
+         d="M 31.160812,22.085001 C 29.756913,23.955488 25.54813,19.829732 23.293627,20.053134 C 21.039124,20.276535 17.245375,25.474203 14.971975,24.782986 C 12.698575,24.091769 15.245115,18.647267 14.313005,16.532585 C 13.380895,14.417902 6.9803643,12.208497 6.9519812,9.7565543 C 6.9235982,7.3046114 14.655317,7.8280513 16.440248,6.299865 C 18.225179,4.7716787 18.354583,-1.2069278 20.54349,-1.8373023 C 22.732398,-2.4676768 22.903473,5.8960807 24.965768,7.0572723 C 27.028062,8.2184639 33.821244,4.297162 34.602091,6.4464993 C 35.382938,8.5958367 28.742383,9.9662008 28.138106,12.336218 C 27.533828,14.706235 32.564711,20.214514 31.160812,22.085001 z"
+         inkscape:randomized="0.1"
+         inkscape:rounded="0.25"
+         inkscape:flatsided="false"
+         sodipodi:arg2="1.3943643"
+         sodipodi:arg1="0.76604574"
+         sodipodi:r2="7.1444125"
+         sodipodi:r1="14.288825"
+         sodipodi:cy="12.382892"
+         sodipodi:cx="21.637474"
+         sodipodi:sides="5"
+         id="path3320"
+         style="opacity:1;fill:#fff49f;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.5;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-opacity:1;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+         sodipodi:type="star" />
+      <path
+         transform="matrix(-0.2934093,0.1234417,-9.6232117e-2,-0.3763705,308.24363,537.32112)"
+         d="M 31.160812,22.085001 C 29.756913,23.955488 25.54813,19.829732 23.293627,20.053134 C 21.039124,20.276535 17.245375,25.474203 14.971975,24.782986 C 12.698575,24.091769 15.245115,18.647267 14.313005,16.532585 C 13.380895,14.417902 6.9803643,12.208497 6.9519812,9.7565543 C 6.9235982,7.3046114 14.655317,7.8280513 16.440248,6.299865 C 18.225179,4.7716787 18.354583,-1.2069278 20.54349,-1.8373023 C 22.732398,-2.4676768 22.903473,5.8960807 24.965768,7.0572723 C 27.028062,8.2184639 33.821244,4.297162 34.602091,6.4464993 C 35.382938,8.5958367 28.742383,9.9662008 28.138106,12.336218 C 27.533828,14.706235 32.564711,20.214514 31.160812,22.085001 z"
+         inkscape:randomized="0.1"
+         inkscape:rounded="0.25"
+         inkscape:flatsided="false"
+         sodipodi:arg2="1.3943643"
+         sodipodi:arg1="0.76604574"
+         sodipodi:r2="7.1444125"
+         sodipodi:r1="14.288825"
+         sodipodi:cy="12.382892"
+         sodipodi:cx="21.637474"
+         sodipodi:sides="5"
+         id="path3322"
+         style="opacity:1;fill:#fff49f;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.5;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-opacity:1;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+         sodipodi:type="star" />
+      <path
+         sodipodi:type="star"
+         style="opacity:1;fill:#fff49f;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.5;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-opacity:1;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+         id="path3233"
+         sodipodi:sides="5"
+         sodipodi:cx="21.637474"
+         sodipodi:cy="12.382892"
+         sodipodi:r1="14.288825"
+         sodipodi:r2="7.1444125"
+         sodipodi:arg1="0.76604574"
+         sodipodi:arg2="1.3943643"
+         inkscape:flatsided="false"
+         inkscape:rounded="0.25"
+         inkscape:randomized="0.1"
+         d="M 31.160812,22.085001 C 29.756913,23.955488 25.54813,19.829732 23.293627,20.053134 C 21.039124,20.276535 17.245375,25.474203 14.971975,24.782986 C 12.698575,24.091769 15.245115,18.647267 14.313005,16.532585 C 13.380895,14.417902 6.9803643,12.208497 6.9519812,9.7565543 C 6.9235982,7.3046114 14.655317,7.8280513 16.440248,6.299865 C 18.225179,4.7716787 18.354583,-1.2069278 20.54349,-1.8373023 C 22.732398,-2.4676768 22.903473,5.8960807 24.965768,7.0572723 C 27.028062,8.2184639 33.821244,4.297162 34.602091,6.4464993 C 35.382938,8.5958367 28.742383,9.9662008 28.138106,12.336218 C 27.533828,14.706235 32.564711,20.214514 31.160812,22.085001 z"
+         transform="matrix(-0.2980027,0.1533418,-9.773864e-2,-0.4675352,353.52012,542.52182)" />
+      <path
+         sodipodi:type="star"
+         style="opacity:1;fill:#fff49f;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.5;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-opacity:1;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+         id="path3235"
+         sodipodi:sides="5"
+         sodipodi:cx="21.637474"
+         sodipodi:cy="12.382892"
+         sodipodi:r1="14.288825"
+         sodipodi:r2="7.1444125"
+         sodipodi:arg1="0.76604574"
+         sodipodi:arg2="1.3943643"
+         inkscape:flatsided="false"
+         inkscape:rounded="0.25"
+         inkscape:randomized="0.1"
+         d="M 31.160812,22.085001 C 29.756913,23.955488 25.54813,19.829732 23.293627,20.053134 C 21.039124,20.276535 17.245375,25.474203 14.971975,24.782986 C 12.698575,24.091769 15.245115,18.647267 14.313005,16.532585 C 13.380895,14.417902 6.9803643,12.208497 6.9519812,9.7565543 C 6.9235982,7.3046114 14.655317,7.8280513 16.440248,6.299865 C 18.225179,4.7716787 18.354583,-1.2069278 20.54349,-1.8373023 C 22.732398,-2.4676768 22.903473,5.8960807 24.965768,7.0572723 C 27.028062,8.2184639 33.821244,4.297162 34.602091,6.4464993 C 35.382938,8.5958367 28.742383,9.9662008 28.138106,12.336218 C 27.533828,14.706235 32.564711,20.214514 31.160812,22.085001 z"
+         transform="matrix(0.3282993,0.1583936,-0.128532,0.4045725,281.33727,530.5045)" />
+      <path
+         sodipodi:type="star"
+         style="opacity:1;fill:#fff49f;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.5;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-opacity:1;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+         id="path3237"
+         sodipodi:sides="5"
+         sodipodi:cx="21.637474"
+         sodipodi:cy="12.382892"
+         sodipodi:r1="14.288825"
+         sodipodi:r2="7.1444125"
+         sodipodi:arg1="0.76604574"
+         sodipodi:arg2="1.3943643"
+         inkscape:flatsided="false"
+         inkscape:rounded="0.25"
+         inkscape:randomized="0.1"
+         d="M 31.160812,22.085001 C 29.756913,23.955488 25.54813,19.829732 23.293627,20.053134 C 21.039124,20.276535 17.245375,25.474203 14.971975,24.782986 C 12.698575,24.091769 15.245115,18.647267 14.313005,16.532585 C 13.380895,14.417902 6.9803643,12.208497 6.9519812,9.7565543 C 6.9235982,7.3046114 14.655317,7.8280513 16.440248,6.299865 C 18.225179,4.7716787 18.354583,-1.2069278 20.54349,-1.8373023 C 22.732398,-2.4676768 22.903473,5.8960807 24.965768,7.0572723 C 27.028062,8.2184639 33.821244,4.297162 34.602091,6.4464993 C 35.382938,8.5958367 28.742383,9.9662008 28.138106,12.336218 C 27.533828,14.706235 32.564711,20.214514 31.160812,22.085001 z"
+         transform="matrix(-0.2767973,0.3022505,-0.4685346,-0.1785613,332.55143,518.72922)" />
+      <path
+         sodipodi:type="star"
+         style="opacity:1;fill:#fff49f;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.5;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-opacity:1;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+         id="path3239"
+         sodipodi:sides="5"
+         sodipodi:cx="21.637474"
+         sodipodi:cy="12.382892"
+         sodipodi:r1="14.288825"
+         sodipodi:r2="7.1444125"
+         sodipodi:arg1="0.76604574"
+         sodipodi:arg2="1.3943643"
+         inkscape:flatsided="false"
+         inkscape:rounded="0.25"
+         inkscape:randomized="0.1"
+         d="M 31.160812,22.085001 C 29.756913,23.955488 25.54813,19.829732 23.293627,20.053134 C 21.039124,20.276535 17.245375,25.474203 14.971975,24.782986 C 12.698575,24.091769 15.245115,18.647267 14.313005,16.532585 C 13.380895,14.417902 6.9803643,12.208497 6.9519812,9.7565543 C 6.9235982,7.3046114 14.655317,7.8280513 16.440248,6.299865 C 18.225179,4.7716787 18.354583,-1.2069278 20.54349,-1.8373023 C 22.732398,-2.4676768 22.903473,5.8960807 24.965768,7.0572723 C 27.028062,8.2184639 33.821244,4.297162 34.602091,6.4464993 C 35.382938,8.5958367 28.742383,9.9662008 28.138106,12.336218 C 27.533828,14.706235 32.564711,20.214514 31.160812,22.085001 z"
+         transform="matrix(0.4040586,0.1597003,-0.1597003,0.4040586,302.40603,518.8671)" />
+      <path
+         transform="matrix(0.4344738,0,0,0.4344738,328.72436,551.50037)"
+         d="M 31.160812,22.085001 C 29.756913,23.955488 25.54813,19.829732 23.293627,20.053134 C 21.039124,20.276535 17.245375,25.474203 14.971975,24.782986 C 12.698575,24.091769 15.245115,18.647267 14.313005,16.532585 C 13.380895,14.417902 6.9803643,12.208497 6.9519812,9.7565543 C 6.9235982,7.3046114 14.655317,7.8280513 16.440248,6.299865 C 18.225179,4.7716787 18.354583,-1.2069278 20.54349,-1.8373023 C 22.732398,-2.4676768 22.903473,5.8960807 24.965768,7.0572723 C 27.028062,8.2184639 33.821244,4.297162 34.602091,6.4464993 C 35.382938,8.5958367 28.742383,9.9662008 28.138106,12.336218 C 27.533828,14.706235 32.564711,20.214514 31.160812,22.085001 z"
+         inkscape:randomized="0.1"
+         inkscape:rounded="0.25"
+         inkscape:flatsided="false"
+         sodipodi:arg2="1.3943643"
+         sodipodi:arg1="0.76604574"
+         sodipodi:r2="7.1444125"
+         sodipodi:r1="14.288825"
+         sodipodi:cy="12.382892"
+         sodipodi:cx="21.637474"
+         sodipodi:sides="5"
+         id="path3219"
+         style="opacity:1;fill:#fff49f;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.5;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-opacity:1;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+         sodipodi:type="star" />
+    </g>
+  </g>
+</svg>
diff --git a/data/themes/default/notebargold_hi.svg b/data/themes/default/notebargold_hi.svg
new file mode 100644 (file)
index 0000000..7675c84
--- /dev/null
@@ -0,0 +1,417 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://creativecommons.org/ns#"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:xlink="http://www.w3.org/1999/xlink"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   width="128"
+   height="64"
+   id="svg1901"
+   sodipodi:version="0.32"
+   inkscape:version="0.46"
+   sodipodi:docname="notebargold_hi.svg"
+   sodipodi:docbase="/home/tsoots/ohj/translations/po"
+   inkscape:export-filename="/home/knittl/git/performous/themes/default/notebargold.png"
+   inkscape:export-xdpi="90"
+   inkscape:export-ydpi="90"
+   version="1.0"
+   inkscape:output_extension="org.inkscape.output.svg.inkscape">
+  <defs
+     id="defs1903">
+    <linearGradient
+       id="linearGradient3207">
+      <stop
+         style="stop-color:#fffff5;stop-opacity:1;"
+         offset="0"
+         id="stop3209" />
+      <stop
+         id="stop3211"
+         offset="0.44999999"
+         style="stop-color:#fffee1;stop-opacity:1;" />
+      <stop
+         style="stop-color:#ffd2c3;stop-opacity:1;"
+         offset="1"
+         id="stop3213" />
+    </linearGradient>
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient3207"
+       id="linearGradient3203"
+       gradientUnits="userSpaceOnUse"
+       x1="319.99997"
+       y1="525.70605"
+       x2="319.99997"
+       y2="555.27692"
+       gradientTransform="matrix(1.3567148,0,0,1.4375736,-114.08888,-236.38543)" />
+    <filter
+       inkscape:collect="always"
+       id="filter3215"
+       x="-0.070401584"
+       width="1.1408032"
+       y="-0.36694321"
+       height="1.7338864">
+      <feGaussianBlur
+         inkscape:collect="always"
+         stdDeviation="1.4369205"
+         id="feGaussianBlur3217" />
+    </filter>
+    <filter
+       inkscape:collect="always"
+       id="filter3314">
+      <feGaussianBlur
+         inkscape:collect="always"
+         stdDeviation="0.2676702"
+         id="feGaussianBlur3316" />
+    </filter>
+    <linearGradient
+       id="linearGradient2388">
+      <stop
+         id="stop2390"
+         offset="0"
+         style="stop-color:#84c0d8;stop-opacity:1;" />
+      <stop
+         id="stop2392"
+         offset="1"
+         style="stop-color:#449ec4;stop-opacity:1;" />
+    </linearGradient>
+    <inkscape:perspective
+       id="perspective3325"
+       inkscape:persp3d-origin="64 : 21.333333 : 1"
+       inkscape:vp_z="128 : 32 : 1"
+       inkscape:vp_y="0 : 1000 : 0"
+       inkscape:vp_x="0 : 32 : 1"
+       sodipodi:type="inkscape:persp3d" />
+    <filter
+       inkscape:collect="always"
+       id="filter3359"
+       x="-0.070401515"
+       width="1.140803"
+       y="-0.36694285"
+       height="1.7338857">
+      <feGaussianBlur
+         inkscape:collect="always"
+         stdDeviation="1.4369191"
+         id="feGaussianBlur3361" />
+    </filter>
+    <filter
+       inkscape:collect="always"
+       id="filter3383"
+       x="-0.18092308"
+       width="1.3618462"
+       y="-0.35636363"
+       height="1.7127273">
+      <feGaussianBlur
+         inkscape:collect="always"
+         stdDeviation="6.3044256"
+         id="feGaussianBlur3385" />
+    </filter>
+  </defs>
+  <sodipodi:namedview
+     id="base"
+     pagecolor="#ffffff"
+     bordercolor="#666666"
+     borderopacity="1.0"
+     inkscape:pageopacity="0.0"
+     inkscape:pageshadow="2"
+     inkscape:zoom="9.125"
+     inkscape:cx="64"
+     inkscape:cy="32"
+     inkscape:document-units="px"
+     inkscape:current-layer="layer1"
+     gridtolerance="10000"
+     inkscape:window-width="1439"
+     inkscape:window-height="801"
+     inkscape:window-x="250"
+     inkscape:window-y="269"
+     showgrid="false"
+     inkscape:snap-global="false">
+    <inkscape:grid
+       type="xygrid"
+       id="grid3154"
+       visible="true"
+       enabled="true" />
+  </sodipodi:namedview>
+  <metadata
+     id="metadata1906">
+    <rdf:RDF>
+      <cc:Work
+         rdf:about="">
+        <dc:format>image/svg+xml</dc:format>
+        <dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+      </cc:Work>
+    </rdf:RDF>
+  </metadata>
+  <g
+     inkscape:label="Taso 1"
+     inkscape:groupmode="layer"
+     id="layer1"
+     style="opacity:1"
+     transform="translate(-255.99998,-508.36216)">
+    <path
+       sodipodi:type="inkscape:offset"
+       inkscape:radius="1.8614163"
+       inkscape:original="M 44.09375 20.03125 C 43.272831 20.03125 42.521517 20.241931 41.78125 20.46875 C 57.140936 27.84874 73.786659 26.922094 87.03125 20.6875 C 86.068989 20.275907 85.031058 20.03125 83.90625 20.03125 L 44.09375 20.03125 z "
+       style="opacity:1;fill:#ffffff;fill-opacity:0.78431373999999998;stroke:none;stroke-width:1.50000000000000000;stroke-miterlimit:4;stroke-opacity:1;filter:url(#filter3215)"
+       id="path3258"
+       d="M 44.09375,18.15625 C 42.954355,18.15625 42.018873,18.451916 41.25,18.6875 C 40.507736,18.902901 39.975772,19.554539 39.913311,20.324897 C 39.850849,21.095255 40.270884,21.824081 40.96875,22.15625 C 56.856448,29.789938 74.088462,28.835283 87.8125,22.375 C 88.481947,22.065076 88.905231,21.389083 88.891698,20.6515 C 88.878164,19.913917 88.430366,19.253906 87.75,18.96875 C 86.587974,18.471711 85.300976,18.15625 83.90625,18.15625 L 44.09375,18.15625 z"
+       transform="matrix(1.0432367,0,0,1.0929798,253.23284,506.09055)" />
+    <rect
+       style="opacity:1;fill:url(#linearGradient3203);fill-opacity:1;stroke:#ffffff;stroke-width:3;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;filter:url(#filter3383)"
+       id="rect3198"
+       width="80.630135"
+       height="39.458378"
+       x="279.48578"
+       y="520.4339"
+       rx="12"
+       ry="12" />
+    <path
+       sodipodi:type="inkscape:offset"
+       inkscape:radius="1.8614163"
+       inkscape:original="M 44.09375 20.03125 C 43.272831 20.03125 42.521517 20.241931 41.78125 20.46875 C 57.140936 27.84874 73.786659 26.922094 87.03125 20.6875 C 86.068989 20.275907 85.031058 20.03125 83.90625 20.03125 L 44.09375 20.03125 z "
+       style="opacity:1;fill:#ffffff;fill-opacity:0.56862747999999996;stroke:none;stroke-width:1.50000000000000000;stroke-miterlimit:4;stroke-opacity:1;filter:url(#filter3359)"
+       id="path3337"
+       d="M 44.09375,18.15625 C 42.954355,18.15625 42.018873,18.451916 41.25,18.6875 C 40.507736,18.902901 39.975772,19.554539 39.913311,20.324897 C 39.850849,21.095255 40.270884,21.824081 40.96875,22.15625 C 56.856448,29.789938 74.088462,28.835283 87.8125,22.375 C 88.481947,22.065076 88.905231,21.389083 88.891698,20.6515 C 88.878164,19.913917 88.430366,19.253906 87.75,18.96875 C 86.587974,18.471711 85.300976,18.15625 83.90625,18.15625 L 44.09375,18.15625 z"
+       transform="matrix(1.0432362,0,0,1.0929825,252.81598,508.3371)" />
+  </g>
+  <g
+     inkscape:groupmode="layer"
+     id="layer2"
+     inkscape:label="stars"
+     style="display:none">
+    <g
+       id="g3241"
+       transform="translate(-254.43583,-507.84078)"
+       style="opacity:0.66000001;filter:url(#filter3314)">
+      <path
+         sodipodi:type="star"
+         style="opacity:1;fill:#fff49f;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.5;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-opacity:1;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+         id="path3221"
+         sodipodi:sides="5"
+         sodipodi:cx="21.637474"
+         sodipodi:cy="12.382892"
+         sodipodi:r1="14.288825"
+         sodipodi:r2="7.1444125"
+         sodipodi:arg1="0.76604574"
+         sodipodi:arg2="1.3943643"
+         inkscape:flatsided="false"
+         inkscape:rounded="0.25"
+         inkscape:randomized="0.1"
+         d="M 31.160812,22.085001 C 29.756913,23.955488 25.54813,19.829732 23.293627,20.053134 C 21.039124,20.276535 17.245375,25.474203 14.971975,24.782986 C 12.698575,24.091769 15.245115,18.647267 14.313005,16.532585 C 13.380895,14.417902 6.9803643,12.208497 6.9519812,9.7565543 C 6.9235982,7.3046114 14.655317,7.8280513 16.440248,6.299865 C 18.225179,4.7716787 18.354583,-1.2069278 20.54349,-1.8373023 C 22.732398,-2.4676768 22.903473,5.8960807 24.965768,7.0572723 C 27.028062,8.2184639 33.821244,4.297162 34.602091,6.4464993 C 35.382938,8.5958367 28.742383,9.9662008 28.138106,12.336218 C 27.533828,14.706235 32.564711,20.214514 31.160812,22.085001 z"
+         transform="matrix(0.2517608,-0.3589923,0.3352142,0.2696192,284.77989,529.17981)" />
+      <path
+         sodipodi:type="star"
+         style="opacity:1;fill:#fff49f;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.5;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-opacity:1;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+         id="path3223"
+         sodipodi:sides="5"
+         sodipodi:cx="21.637474"
+         sodipodi:cy="12.382892"
+         sodipodi:r1="14.288825"
+         sodipodi:r2="7.1444125"
+         sodipodi:arg1="0.76604574"
+         sodipodi:arg2="1.3943643"
+         inkscape:flatsided="false"
+         inkscape:rounded="0.25"
+         inkscape:randomized="0.1"
+         d="M 31.160812,22.085001 C 29.756913,23.955488 25.54813,19.829732 23.293627,20.053134 C 21.039124,20.276535 17.245375,25.474203 14.971975,24.782986 C 12.698575,24.091769 15.245115,18.647267 14.313005,16.532585 C 13.380895,14.417902 6.9803643,12.208497 6.9519812,9.7565543 C 6.9235982,7.3046114 14.655317,7.8280513 16.440248,6.299865 C 18.225179,4.7716787 18.354583,-1.2069278 20.54349,-1.8373023 C 22.732398,-2.4676768 22.903473,5.8960807 24.965768,7.0572723 C 27.028062,8.2184639 33.821244,4.297162 34.602091,6.4464993 C 35.382938,8.5958367 28.742383,9.9662008 28.138106,12.336218 C 27.533828,14.706235 32.564711,20.214514 31.160812,22.085001 z"
+         transform="matrix(-0.4226537,0.1006544,-0.1006544,-0.4226537,343.62899,527.82816)" />
+      <path
+         sodipodi:type="star"
+         style="opacity:1;fill:#fff49f;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.5;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-opacity:1;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+         id="path3225"
+         sodipodi:sides="5"
+         sodipodi:cx="21.637474"
+         sodipodi:cy="12.382892"
+         sodipodi:r1="14.288825"
+         sodipodi:r2="7.1444125"
+         sodipodi:arg1="0.76604574"
+         sodipodi:arg2="1.3943643"
+         inkscape:flatsided="false"
+         inkscape:rounded="0.25"
+         inkscape:randomized="0.1"
+         d="M 31.160812,22.085001 C 29.756913,23.955488 25.54813,19.829732 23.293627,20.053134 C 21.039124,20.276535 17.245375,25.474203 14.971975,24.782986 C 12.698575,24.091769 15.245115,18.647267 14.313005,16.532585 C 13.380895,14.417902 6.9803643,12.208497 6.9519812,9.7565543 C 6.9235982,7.3046114 14.655317,7.8280513 16.440248,6.299865 C 18.225179,4.7716787 18.354583,-1.2069278 20.54349,-1.8373023 C 22.732398,-2.4676768 22.903473,5.8960807 24.965768,7.0572723 C 27.028062,8.2184639 33.821244,4.297162 34.602091,6.4464993 C 35.382938,8.5958367 28.742383,9.9662008 28.138106,12.336218 C 27.533828,14.706235 32.564711,20.214514 31.160812,22.085001 z"
+         transform="matrix(6.0995116e-2,-0.4715566,0.2973004,9.6746097e-2,343.8725,559.8055)" />
+      <path
+         sodipodi:type="star"
+         style="opacity:1;fill:#fff49f;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.5;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-opacity:1;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+         id="path3227"
+         sodipodi:sides="5"
+         sodipodi:cx="21.637474"
+         sodipodi:cy="12.382892"
+         sodipodi:r1="14.288825"
+         sodipodi:r2="7.1444125"
+         sodipodi:arg1="0.76604574"
+         sodipodi:arg2="1.3943643"
+         inkscape:flatsided="false"
+         inkscape:rounded="0.25"
+         inkscape:randomized="0.1"
+         d="M 31.160812,22.085001 C 29.756913,23.955488 25.54813,19.829732 23.293627,20.053134 C 21.039124,20.276535 17.245375,25.474203 14.971975,24.782986 C 12.698575,24.091769 15.245115,18.647267 14.313005,16.532585 C 13.380895,14.417902 6.9803643,12.208497 6.9519812,9.7565543 C 6.9235982,7.3046114 14.655317,7.8280513 16.440248,6.299865 C 18.225179,4.7716787 18.354583,-1.2069278 20.54349,-1.8373023 C 22.732398,-2.4676768 22.903473,5.8960807 24.965768,7.0572723 C 27.028062,8.2184639 33.821244,4.297162 34.602091,6.4464993 C 35.382938,8.5958367 28.742383,9.9662008 28.138106,12.336218 C 27.533828,14.706235 32.564711,20.214514 31.160812,22.085001 z"
+         transform="matrix(-2.3552595e-2,-0.4523683,0.3372133,-3.1595577e-2,319.91763,565.39226)" />
+      <path
+         sodipodi:type="star"
+         style="opacity:1;fill:#fff49f;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.5;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-opacity:1;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+         id="path3229"
+         sodipodi:sides="5"
+         sodipodi:cx="21.637474"
+         sodipodi:cy="12.382892"
+         sodipodi:r1="14.288825"
+         sodipodi:r2="7.1444125"
+         sodipodi:arg1="0.76604574"
+         sodipodi:arg2="1.3943643"
+         inkscape:flatsided="false"
+         inkscape:rounded="0.25"
+         inkscape:randomized="0.1"
+         d="M 31.160812,22.085001 C 29.756913,23.955488 25.54813,19.829732 23.293627,20.053134 C 21.039124,20.276535 17.245375,25.474203 14.971975,24.782986 C 12.698575,24.091769 15.245115,18.647267 14.313005,16.532585 C 13.380895,14.417902 6.9803643,12.208497 6.9519812,9.7565543 C 6.9235982,7.3046114 14.655317,7.8280513 16.440248,6.299865 C 18.225179,4.7716787 18.354583,-1.2069278 20.54349,-1.8373023 C 22.732398,-2.4676768 22.903473,5.8960807 24.965768,7.0572723 C 27.028062,8.2184639 33.821244,4.297162 34.602091,6.4464993 C 35.382938,8.5958367 28.742383,9.9662008 28.138106,12.336218 C 27.533828,14.706235 32.564711,20.214514 31.160812,22.085001 z"
+         transform="matrix(-0.4077357,-0.170593,0.1500638,-0.4635153,297.97321,561.11569)" />
+      <path
+         sodipodi:type="star"
+         style="opacity:1;fill:#fff49f;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.5;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-opacity:1;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+         id="path3231"
+         sodipodi:sides="5"
+         sodipodi:cx="21.637474"
+         sodipodi:cy="12.382892"
+         sodipodi:r1="14.288825"
+         sodipodi:r2="7.1444125"
+         sodipodi:arg1="0.76604574"
+         sodipodi:arg2="1.3943643"
+         inkscape:flatsided="false"
+         inkscape:rounded="0.25"
+         inkscape:randomized="0.1"
+         d="M 31.160812,22.085001 C 29.756913,23.955488 25.54813,19.829732 23.293627,20.053134 C 21.039124,20.276535 17.245375,25.474203 14.971975,24.782986 C 12.698575,24.091769 15.245115,18.647267 14.313005,16.532585 C 13.380895,14.417902 6.9803643,12.208497 6.9519812,9.7565543 C 6.9235982,7.3046114 14.655317,7.8280513 16.440248,6.299865 C 18.225179,4.7716787 18.354583,-1.2069278 20.54349,-1.8373023 C 22.732398,-2.4676768 22.903473,5.8960807 24.965768,7.0572723 C 27.028062,8.2184639 33.821244,4.297162 34.602091,6.4464993 C 35.382938,8.5958367 28.742383,9.9662008 28.138106,12.336218 C 27.533828,14.706235 32.564711,20.214514 31.160812,22.085001 z"
+         transform="matrix(-0.1402938,0.4111997,-0.4111997,-0.1402938,312.90301,550.0936)" />
+      <path
+         transform="matrix(-0.3760896,0.1189566,-0.1233495,-0.3626959,356.26327,529.09824)"
+         d="M 31.160812,22.085001 C 29.756913,23.955488 25.54813,19.829732 23.293627,20.053134 C 21.039124,20.276535 17.245375,25.474203 14.971975,24.782986 C 12.698575,24.091769 15.245115,18.647267 14.313005,16.532585 C 13.380895,14.417902 6.9803643,12.208497 6.9519812,9.7565543 C 6.9235982,7.3046114 14.655317,7.8280513 16.440248,6.299865 C 18.225179,4.7716787 18.354583,-1.2069278 20.54349,-1.8373023 C 22.732398,-2.4676768 22.903473,5.8960807 24.965768,7.0572723 C 27.028062,8.2184639 33.821244,4.297162 34.602091,6.4464993 C 35.382938,8.5958367 28.742383,9.9662008 28.138106,12.336218 C 27.533828,14.706235 32.564711,20.214514 31.160812,22.085001 z"
+         inkscape:randomized="0.1"
+         inkscape:rounded="0.25"
+         inkscape:flatsided="false"
+         sodipodi:arg2="1.3943643"
+         sodipodi:arg1="0.76604574"
+         sodipodi:r2="7.1444125"
+         sodipodi:r1="14.288825"
+         sodipodi:cy="12.382892"
+         sodipodi:cx="21.637474"
+         sodipodi:sides="5"
+         id="path3318"
+         style="opacity:1;fill:#fff49f;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.5;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-opacity:1;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+         sodipodi:type="star" />
+      <path
+         transform="matrix(-0.4128364,0.1354017,-0.1354017,-0.4128364,329.3917,550.03765)"
+         d="M 31.160812,22.085001 C 29.756913,23.955488 25.54813,19.829732 23.293627,20.053134 C 21.039124,20.276535 17.245375,25.474203 14.971975,24.782986 C 12.698575,24.091769 15.245115,18.647267 14.313005,16.532585 C 13.380895,14.417902 6.9803643,12.208497 6.9519812,9.7565543 C 6.9235982,7.3046114 14.655317,7.8280513 16.440248,6.299865 C 18.225179,4.7716787 18.354583,-1.2069278 20.54349,-1.8373023 C 22.732398,-2.4676768 22.903473,5.8960807 24.965768,7.0572723 C 27.028062,8.2184639 33.821244,4.297162 34.602091,6.4464993 C 35.382938,8.5958367 28.742383,9.9662008 28.138106,12.336218 C 27.533828,14.706235 32.564711,20.214514 31.160812,22.085001 z"
+         inkscape:randomized="0.1"
+         inkscape:rounded="0.25"
+         inkscape:flatsided="false"
+         sodipodi:arg2="1.3943643"
+         sodipodi:arg1="0.76604574"
+         sodipodi:r2="7.1444125"
+         sodipodi:r1="14.288825"
+         sodipodi:cy="12.382892"
+         sodipodi:cx="21.637474"
+         sodipodi:sides="5"
+         id="path3320"
+         style="opacity:1;fill:#fff49f;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.5;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-opacity:1;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+         sodipodi:type="star" />
+      <path
+         transform="matrix(-0.2934093,0.1234417,-9.6232117e-2,-0.3763705,308.24363,537.32112)"
+         d="M 31.160812,22.085001 C 29.756913,23.955488 25.54813,19.829732 23.293627,20.053134 C 21.039124,20.276535 17.245375,25.474203 14.971975,24.782986 C 12.698575,24.091769 15.245115,18.647267 14.313005,16.532585 C 13.380895,14.417902 6.9803643,12.208497 6.9519812,9.7565543 C 6.9235982,7.3046114 14.655317,7.8280513 16.440248,6.299865 C 18.225179,4.7716787 18.354583,-1.2069278 20.54349,-1.8373023 C 22.732398,-2.4676768 22.903473,5.8960807 24.965768,7.0572723 C 27.028062,8.2184639 33.821244,4.297162 34.602091,6.4464993 C 35.382938,8.5958367 28.742383,9.9662008 28.138106,12.336218 C 27.533828,14.706235 32.564711,20.214514 31.160812,22.085001 z"
+         inkscape:randomized="0.1"
+         inkscape:rounded="0.25"
+         inkscape:flatsided="false"
+         sodipodi:arg2="1.3943643"
+         sodipodi:arg1="0.76604574"
+         sodipodi:r2="7.1444125"
+         sodipodi:r1="14.288825"
+         sodipodi:cy="12.382892"
+         sodipodi:cx="21.637474"
+         sodipodi:sides="5"
+         id="path3322"
+         style="opacity:1;fill:#fff49f;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.5;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-opacity:1;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+         sodipodi:type="star" />
+      <path
+         sodipodi:type="star"
+         style="opacity:1;fill:#fff49f;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.5;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-opacity:1;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+         id="path3233"
+         sodipodi:sides="5"
+         sodipodi:cx="21.637474"
+         sodipodi:cy="12.382892"
+         sodipodi:r1="14.288825"
+         sodipodi:r2="7.1444125"
+         sodipodi:arg1="0.76604574"
+         sodipodi:arg2="1.3943643"
+         inkscape:flatsided="false"
+         inkscape:rounded="0.25"
+         inkscape:randomized="0.1"
+         d="M 31.160812,22.085001 C 29.756913,23.955488 25.54813,19.829732 23.293627,20.053134 C 21.039124,20.276535 17.245375,25.474203 14.971975,24.782986 C 12.698575,24.091769 15.245115,18.647267 14.313005,16.532585 C 13.380895,14.417902 6.9803643,12.208497 6.9519812,9.7565543 C 6.9235982,7.3046114 14.655317,7.8280513 16.440248,6.299865 C 18.225179,4.7716787 18.354583,-1.2069278 20.54349,-1.8373023 C 22.732398,-2.4676768 22.903473,5.8960807 24.965768,7.0572723 C 27.028062,8.2184639 33.821244,4.297162 34.602091,6.4464993 C 35.382938,8.5958367 28.742383,9.9662008 28.138106,12.336218 C 27.533828,14.706235 32.564711,20.214514 31.160812,22.085001 z"
+         transform="matrix(-0.2980027,0.1533418,-9.773864e-2,-0.4675352,353.52012,542.52182)" />
+      <path
+         sodipodi:type="star"
+         style="opacity:1;fill:#fff49f;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.5;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-opacity:1;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+         id="path3235"
+         sodipodi:sides="5"
+         sodipodi:cx="21.637474"
+         sodipodi:cy="12.382892"
+         sodipodi:r1="14.288825"
+         sodipodi:r2="7.1444125"
+         sodipodi:arg1="0.76604574"
+         sodipodi:arg2="1.3943643"
+         inkscape:flatsided="false"
+         inkscape:rounded="0.25"
+         inkscape:randomized="0.1"
+         d="M 31.160812,22.085001 C 29.756913,23.955488 25.54813,19.829732 23.293627,20.053134 C 21.039124,20.276535 17.245375,25.474203 14.971975,24.782986 C 12.698575,24.091769 15.245115,18.647267 14.313005,16.532585 C 13.380895,14.417902 6.9803643,12.208497 6.9519812,9.7565543 C 6.9235982,7.3046114 14.655317,7.8280513 16.440248,6.299865 C 18.225179,4.7716787 18.354583,-1.2069278 20.54349,-1.8373023 C 22.732398,-2.4676768 22.903473,5.8960807 24.965768,7.0572723 C 27.028062,8.2184639 33.821244,4.297162 34.602091,6.4464993 C 35.382938,8.5958367 28.742383,9.9662008 28.138106,12.336218 C 27.533828,14.706235 32.564711,20.214514 31.160812,22.085001 z"
+         transform="matrix(0.3282993,0.1583936,-0.128532,0.4045725,281.33727,530.5045)" />
+      <path
+         sodipodi:type="star"
+         style="opacity:1;fill:#fff49f;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.5;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-opacity:1;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+         id="path3237"
+         sodipodi:sides="5"
+         sodipodi:cx="21.637474"
+         sodipodi:cy="12.382892"
+         sodipodi:r1="14.288825"
+         sodipodi:r2="7.1444125"
+         sodipodi:arg1="0.76604574"
+         sodipodi:arg2="1.3943643"
+         inkscape:flatsided="false"
+         inkscape:rounded="0.25"
+         inkscape:randomized="0.1"
+         d="M 31.160812,22.085001 C 29.756913,23.955488 25.54813,19.829732 23.293627,20.053134 C 21.039124,20.276535 17.245375,25.474203 14.971975,24.782986 C 12.698575,24.091769 15.245115,18.647267 14.313005,16.532585 C 13.380895,14.417902 6.9803643,12.208497 6.9519812,9.7565543 C 6.9235982,7.3046114 14.655317,7.8280513 16.440248,6.299865 C 18.225179,4.7716787 18.354583,-1.2069278 20.54349,-1.8373023 C 22.732398,-2.4676768 22.903473,5.8960807 24.965768,7.0572723 C 27.028062,8.2184639 33.821244,4.297162 34.602091,6.4464993 C 35.382938,8.5958367 28.742383,9.9662008 28.138106,12.336218 C 27.533828,14.706235 32.564711,20.214514 31.160812,22.085001 z"
+         transform="matrix(-0.2767973,0.3022505,-0.4685346,-0.1785613,332.55143,518.72922)" />
+      <path
+         sodipodi:type="star"
+         style="opacity:1;fill:#fff49f;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.5;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-opacity:1;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+         id="path3239"
+         sodipodi:sides="5"
+         sodipodi:cx="21.637474"
+         sodipodi:cy="12.382892"
+         sodipodi:r1="14.288825"
+         sodipodi:r2="7.1444125"
+         sodipodi:arg1="0.76604574"
+         sodipodi:arg2="1.3943643"
+         inkscape:flatsided="false"
+         inkscape:rounded="0.25"
+         inkscape:randomized="0.1"
+         d="M 31.160812,22.085001 C 29.756913,23.955488 25.54813,19.829732 23.293627,20.053134 C 21.039124,20.276535 17.245375,25.474203 14.971975,24.782986 C 12.698575,24.091769 15.245115,18.647267 14.313005,16.532585 C 13.380895,14.417902 6.9803643,12.208497 6.9519812,9.7565543 C 6.9235982,7.3046114 14.655317,7.8280513 16.440248,6.299865 C 18.225179,4.7716787 18.354583,-1.2069278 20.54349,-1.8373023 C 22.732398,-2.4676768 22.903473,5.8960807 24.965768,7.0572723 C 27.028062,8.2184639 33.821244,4.297162 34.602091,6.4464993 C 35.382938,8.5958367 28.742383,9.9662008 28.138106,12.336218 C 27.533828,14.706235 32.564711,20.214514 31.160812,22.085001 z"
+         transform="matrix(0.4040586,0.1597003,-0.1597003,0.4040586,302.40603,518.8671)" />
+      <path
+         transform="matrix(0.4344738,0,0,0.4344738,328.72436,551.50037)"
+         d="M 31.160812,22.085001 C 29.756913,23.955488 25.54813,19.829732 23.293627,20.053134 C 21.039124,20.276535 17.245375,25.474203 14.971975,24.782986 C 12.698575,24.091769 15.245115,18.647267 14.313005,16.532585 C 13.380895,14.417902 6.9803643,12.208497 6.9519812,9.7565543 C 6.9235982,7.3046114 14.655317,7.8280513 16.440248,6.299865 C 18.225179,4.7716787 18.354583,-1.2069278 20.54349,-1.8373023 C 22.732398,-2.4676768 22.903473,5.8960807 24.965768,7.0572723 C 27.028062,8.2184639 33.821244,4.297162 34.602091,6.4464993 C 35.382938,8.5958367 28.742383,9.9662008 28.138106,12.336218 C 27.533828,14.706235 32.564711,20.214514 31.160812,22.085001 z"
+         inkscape:randomized="0.1"
+         inkscape:rounded="0.25"
+         inkscape:flatsided="false"
+         sodipodi:arg2="1.3943643"
+         sodipodi:arg1="0.76604574"
+         sodipodi:r2="7.1444125"
+         sodipodi:r1="14.288825"
+         sodipodi:cy="12.382892"
+         sodipodi:cx="21.637474"
+         sodipodi:sides="5"
+         id="path3219"
+         style="opacity:1;fill:#fff49f;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.5;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-opacity:1;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+         sodipodi:type="star" />
+    </g>
+  </g>
+</svg>
diff --git a/data/themes/default/notelines.svg b/data/themes/default/notelines.svg
new file mode 100644 (file)
index 0000000..ee4d341
--- /dev/null
@@ -0,0 +1,292 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://creativecommons.org/ns#"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   width="1024"
+   height="256"
+   id="svg2"
+   sodipodi:version="0.32"
+   inkscape:version="0.48.4 r9939"
+   version="1.0"
+   sodipodi:docname="notelines.svg"
+   inkscape:output_extension="org.inkscape.output.svg.inkscape">
+  <defs
+     id="defs4">
+    <inkscape:perspective
+       sodipodi:type="inkscape:persp3d"
+       inkscape:vp_x="0 : 60 : 1"
+       inkscape:vp_y="0 : 1000 : 0"
+       inkscape:vp_z="1000 : 60 : 1"
+       inkscape:persp3d-origin="500 : 40 : 1"
+       id="perspective46" />
+  </defs>
+  <sodipodi:namedview
+     id="base"
+     pagecolor="#ffffff"
+     bordercolor="#666666"
+     borderopacity="1.0"
+     gridtolerance="10000"
+     guidetolerance="10"
+     objecttolerance="10"
+     inkscape:pageopacity="0.0"
+     inkscape:pageshadow="2"
+     inkscape:zoom="0.72619046"
+     inkscape:cx="188.34323"
+     inkscape:cy="-69.851903"
+     inkscape:document-units="px"
+     inkscape:current-layer="layer1"
+     width="1000px"
+     height="120px"
+     showgrid="false"
+     showguides="true"
+     inkscape:guide-bbox="true"
+     showborder="true"
+     borderlayer="false"
+     inkscape:showpageshadow="false"
+     inkscape:window-width="1920"
+     inkscape:window-height="1053"
+     inkscape:window-x="-1"
+     inkscape:window-y="-1"
+     inkscape:window-maximized="1">
+    <inkscape:grid
+       id="GridFromPre046Settings"
+       type="xygrid"
+       originx="0px"
+       originy="10.6667px"
+       spacingx="2.5px"
+       spacingy="10.6667px"
+       color="#0000ff"
+       empcolor="#0000ff"
+       opacity="0.2"
+       empopacity="0.4"
+       empspacing="5"
+       visible="true"
+       enabled="true" />
+  </sodipodi:namedview>
+  <metadata
+     id="metadata7">
+    <rdf:RDF>
+      <cc:Work
+         rdf:about="">
+        <dc:format>image/svg+xml</dc:format>
+        <dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+      </cc:Work>
+    </rdf:RDF>
+  </metadata>
+  <g
+     inkscape:label="Layer 1"
+     inkscape:groupmode="layer"
+     id="layer1">
+    <path
+       sodipodi:nodetypes="cc"
+       id="path3792"
+       d="M 297.00863,245.3005 L 1024.1494,245.3005"
+       style="fill:none;fill-rule:evenodd;stroke:#ff0000;stroke-width:6;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:0.50196081" />
+    <text
+       xml:space="preserve"
+       style="font-size:17.21700287px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;text-align:justify;line-height:125%;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Droid Sans Mono;-inkscape-font-specification:Droid Sans Mono"
+       x="357.41422"
+       y="13.133085"
+       id="text2160"
+       sodipodi:linespacing="125%"
+       transform="scale(0.8067704,1.23951)"><tspan
+         sodipodi:role="line"
+         id="tspan2162"
+         x="357.41422"
+         y="13.133085"
+         style="font-size:13.77360535px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;text-align:start;line-height:125%;writing-mode:lr-tb;text-anchor:start;fill:#808080;fill-opacity:1;font-family:Droid Sans Mono;-inkscape-font-specification:Droid Sans Mono">B</tspan><tspan
+         sodipodi:role="line"
+         x="357.41422"
+         y="30.350092"
+         id="tspan2164"
+         style="font-size:13.77360535px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;text-align:start;line-height:125%;writing-mode:lr-tb;text-anchor:start;fill:#808080;fill-opacity:1;font-family:Droid Sans Mono;-inkscape-font-specification:Droid Sans Mono">A#</tspan><tspan
+         sodipodi:role="line"
+         x="357.41422"
+         y="47.567101"
+         id="tspan2166"
+         style="font-size:13.77360535px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;text-align:start;line-height:125%;writing-mode:lr-tb;text-anchor:start;fill:#808080;fill-opacity:1;font-family:Droid Sans Mono;-inkscape-font-specification:Droid Sans Mono">A</tspan><tspan
+         sodipodi:role="line"
+         x="357.41422"
+         y="64.784103"
+         id="tspan2168"
+         style="font-size:13.77360535px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;text-align:start;line-height:125%;writing-mode:lr-tb;text-anchor:start;fill:#808080;fill-opacity:1;font-family:Droid Sans Mono;-inkscape-font-specification:Droid Sans Mono">G#</tspan><tspan
+         sodipodi:role="line"
+         x="357.41422"
+         y="82.001106"
+         id="tspan2170"
+         style="font-size:13.77360535px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;text-align:start;line-height:125%;writing-mode:lr-tb;text-anchor:start;fill:#808080;fill-opacity:1;font-family:Droid Sans Mono;-inkscape-font-specification:Droid Sans Mono">G</tspan><tspan
+         sodipodi:role="line"
+         x="357.41422"
+         y="99.218117"
+         id="tspan2172"
+         style="font-size:13.77360535px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;text-align:start;line-height:125%;writing-mode:lr-tb;text-anchor:start;fill:#808080;fill-opacity:1;font-family:Droid Sans Mono;-inkscape-font-specification:Droid Sans Mono">F#</tspan><tspan
+         sodipodi:role="line"
+         x="357.41422"
+         y="116.43513"
+         id="tspan2174"
+         style="font-size:13.77360535000000041px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;text-align:start;line-height:125%;writing-mode:lr-tb;text-anchor:start;fill:#0000ff;fill-opacity:1;font-family:Droid Sans Mono;-inkscape-font-specification:Droid Sans Mono">F</tspan><tspan
+         sodipodi:role="line"
+         x="357.41422"
+         y="133.65213"
+         id="tspan2176"
+         style="font-size:13.77360535px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;text-align:start;line-height:125%;writing-mode:lr-tb;text-anchor:start;fill:#808080;fill-opacity:1;font-family:Droid Sans Mono;-inkscape-font-specification:Droid Sans Mono">E</tspan><tspan
+         sodipodi:role="line"
+         x="357.41422"
+         y="150.86914"
+         id="tspan2178"
+         style="font-size:13.77360535px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;text-align:start;line-height:125%;writing-mode:lr-tb;text-anchor:start;fill:#808080;fill-opacity:1;font-family:Droid Sans Mono;-inkscape-font-specification:Droid Sans Mono">D#</tspan><tspan
+         sodipodi:role="line"
+         x="357.41422"
+         y="168.08615"
+         id="tspan2180"
+         style="font-size:13.77360535px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;text-align:start;line-height:125%;writing-mode:lr-tb;text-anchor:start;fill:#808080;fill-opacity:1;font-family:Droid Sans Mono;-inkscape-font-specification:Droid Sans Mono">D</tspan><tspan
+         sodipodi:role="line"
+         x="357.41422"
+         y="185.30315"
+         id="tspan2182"
+         style="font-size:13.77360535px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;text-align:start;line-height:125%;writing-mode:lr-tb;text-anchor:start;fill:#808080;fill-opacity:1;font-family:Droid Sans Mono;-inkscape-font-specification:Droid Sans Mono">C#</tspan><tspan
+         sodipodi:role="line"
+         x="357.41422"
+         y="202.52016"
+         id="tspan2184"
+         style="font-size:13.77360535000000041px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;text-align:start;text-anchor:start;fill:#ff0000;fill-opacity:1;font-family:Droid Sans Mono;-inkscape-font-specification:Droid Sans Mono">C</tspan></text>
+    <path
+       style="fill:none;fill-rule:evenodd;stroke:#808080;stroke-width:6;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:0.50196078000000000"
+       d="M 0.0074350522,10.699792 L 286.76721,10.699792"
+       id="path2186"
+       sodipodi:nodetypes="cc" />
+    <path
+       style="fill:none;fill-rule:evenodd;stroke:#808080;stroke-width:6;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:0.50196078000000000"
+       d="M 297.00863,10.699792 L 1024.1494,10.699792"
+       id="path2188"
+       sodipodi:nodetypes="cc" />
+    <path
+       style="fill:none;fill-rule:evenodd;stroke:#808080;stroke-width:6;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:6,6;stroke-opacity:0.50226247000000002;stroke-dashoffset:0"
+       d="M 0.0074350522,32.027129 L 286.76721,32.027129"
+       id="path5117"
+       sodipodi:nodetypes="cc" />
+    <path
+       style="fill:none;fill-rule:evenodd;stroke:#808080;stroke-width:6;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:6,6;stroke-opacity:0.50226247000000002;stroke-dashoffset:0"
+       d="M 302.12934,32.027129 L 1024.1494,32.027129"
+       id="path5119"
+       sodipodi:nodetypes="cc" />
+    <path
+       style="fill:none;fill-rule:evenodd;stroke:#808080;stroke-width:6;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:0.50196078000000000"
+       d="M 0.0074350522,53.354467 L 286.76721,53.354467"
+       id="path5121"
+       sodipodi:nodetypes="cc" />
+    <path
+       style="fill:none;fill-rule:evenodd;stroke:#808080;stroke-width:6;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:0.50196078000000000"
+       d="M 297.00863,53.354467 L 1024.1494,53.354467"
+       id="path5123"
+       sodipodi:nodetypes="cc" />
+    <path
+       style="fill:none;fill-rule:evenodd;stroke:#808080;stroke-width:6;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:6,6;stroke-opacity:0.50226247000000002;stroke-dashoffset:0"
+       d="M 302.12934,74.681804 L 1024.1494,74.681804"
+       id="path5131"
+       sodipodi:nodetypes="cc" />
+    <path
+       style="fill:none;fill-rule:evenodd;stroke:#808080;stroke-width:6;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:0.50196078000000000"
+       d="M 0.0074350522,96.009141 L 286.76721,96.009141"
+       id="path5169"
+       sodipodi:nodetypes="cc" />
+    <path
+       style="fill:none;fill-rule:evenodd;stroke:#808080;stroke-width:6;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:0.50196078000000000"
+       d="M 297.00863,96.009141 L 1024.1494,96.009141"
+       id="path5171"
+       sodipodi:nodetypes="cc" />
+    <path
+       style="fill:none;fill-rule:evenodd;stroke:#808080;stroke-width:6;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:6,6;stroke-opacity:0.50226247000000002;stroke-dashoffset:0"
+       d="M 0.0074350522,117.33647 L 286.76721,117.33647"
+       id="path5173"
+       sodipodi:nodetypes="cc" />
+    <path
+       style="fill:none;fill-rule:evenodd;stroke:#808080;stroke-width:6;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:6,6;stroke-opacity:0.50226247000000002;stroke-dashoffset:0"
+       d="M 302.12934,117.33647 L 1024.1494,117.33647"
+       id="path5175"
+       sodipodi:nodetypes="cc" />
+    <path
+       style="fill:#0000ff;fill-rule:evenodd;stroke:#2101ff;stroke-width:6;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:0.50196081000000004"
+       d="M 0.0074350522,138.66383 L 286.76721,138.66383"
+       id="path5177"
+       sodipodi:nodetypes="cc" />
+    <path
+       style="fill:#0000ff;fill-rule:evenodd;stroke:#2101ff;stroke-width:6;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:0.50196081000000004"
+       d="M 297.00863,138.66383 L 1024.1494,138.66383"
+       id="path5179"
+       sodipodi:nodetypes="cc" />
+    <path
+       style="fill:none;fill-rule:evenodd;stroke:#808080;stroke-width:6;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:0.50196078000000000"
+       d="M 0.0074350522,159.99115 L 286.76721,159.99115"
+       id="path5181"
+       sodipodi:nodetypes="cc" />
+    <path
+       style="fill:none;fill-rule:evenodd;stroke:#808080;stroke-width:6;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:0.50196078000000000"
+       d="M 297.00863,159.99115 L 1024.1494,159.99115"
+       id="path5183"
+       sodipodi:nodetypes="cc" />
+    <path
+       style="fill:none;fill-rule:evenodd;stroke:#808080;stroke-width:6;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:6,6;stroke-opacity:0.50226247000000002;stroke-dashoffset:0"
+       d="M 0.0074350522,181.31849 L 286.76721,181.31849"
+       id="path5185"
+       sodipodi:nodetypes="cc" />
+    <path
+       style="fill:none;fill-rule:evenodd;stroke:#808080;stroke-width:6;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:6,6;stroke-opacity:0.50226247000000002;stroke-dashoffset:0"
+       d="M 302.12934,181.31849 L 1024.1494,181.31849"
+       id="path5187"
+       sodipodi:nodetypes="cc" />
+    <path
+       style="fill:none;fill-rule:evenodd;stroke:#808080;stroke-width:6;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:0.50196078000000000"
+       d="M 0.0074350522,202.64585 L 286.76721,202.64585"
+       id="path5189"
+       sodipodi:nodetypes="cc" />
+    <path
+       style="fill:none;fill-rule:evenodd;stroke:#808080;stroke-width:6;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:0.50196078000000000"
+       d="M 297.00863,202.64585 L 1024.1494,202.64585"
+       id="path5191"
+       sodipodi:nodetypes="cc" />
+    <path
+       style="fill:none;fill-rule:evenodd;stroke:#808080;stroke-width:6;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:6,6;stroke-opacity:0.50226247000000002;stroke-dashoffset:0"
+       d="M 0.0074350522,223.97317 L 286.76721,223.97317"
+       id="path5193"
+       sodipodi:nodetypes="cc" />
+    <path
+       style="fill:none;fill-rule:evenodd;stroke:#808080;stroke-width:6;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:6,6;stroke-opacity:0.50226247000000002;stroke-dashoffset:0"
+       d="M 302.12934,223.97317 L 1024.1494,223.97317"
+       id="path5195"
+       sodipodi:nodetypes="cc" />
+    <path
+       style="fill:none;fill-rule:evenodd;stroke:#ff0000;stroke-width:6;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:0.50196081"
+       d="M 0.0074350522,245.3005 L 286.76721,245.3005"
+       id="path5197"
+       sodipodi:nodetypes="cc" />
+    <path
+       style="fill:none;fill-rule:evenodd;stroke:none;stroke-width:6;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:0.50196081000000004;fill-opacity:0.50196081000000004"
+       d="M 297.00863,245.3005 L 1024.1494,245.3005"
+       id="path5199"
+       sodipodi:nodetypes="cc" />
+    <path
+       style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:6;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+       d="M 307.25004,0.034974267 L 307.25004,255.96424"
+       id="path2192"
+       sodipodi:nodetypes="cc" />
+    <path
+       style="fill:none;fill-rule:evenodd;stroke:#808080;stroke-width:6;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:6,6;stroke-opacity:0.50226247000000002;stroke-dashoffset:0"
+       d="M 0.0074350522,74.669333 L 286.76721,74.669333"
+       id="path3271"
+       sodipodi:nodetypes="cc" />
+    <path
+       sodipodi:nodetypes="cc"
+       id="path3790"
+       d="M 0.0074350522,245.3005 L 286.76721,245.3005"
+       style="fill:none;fill-rule:evenodd;stroke:none;stroke-width:6;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:0.50196081000000004;fill-opacity:0.50196081000000004" />
+  </g>
+</svg>
diff --git a/data/themes/default/practice.ogg b/data/themes/default/practice.ogg
new file mode 100644 (file)
index 0000000..51c2ab8
Binary files /dev/null and b/data/themes/default/practice.ogg differ
diff --git a/data/themes/default/practice_bg.svg b/data/themes/default/practice_bg.svg
new file mode 100644 (file)
index 0000000..6be5527
--- /dev/null
@@ -0,0 +1,468 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Sodipodi ("http://www.sodipodi.com/") -->
+
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://creativecommons.org/ns#"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:xlink="http://www.w3.org/1999/xlink"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   version="1.0"
+   x="0"
+   y="0"
+   width="1000"
+   height="800"
+   id="svg559"
+   sodipodi:version="0.32"
+   inkscape:version="0.48.1 r9760"
+   sodipodi:docname="practice_bg.svg"
+   inkscape:output_extension="org.inkscape.output.svg.inkscape">
+  <metadata
+     id="metadata35">
+    <rdf:RDF>
+      <cc:Work
+         rdf:about="">
+        <dc:format>image/svg+xml</dc:format>
+        <dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+      </cc:Work>
+    </rdf:RDF>
+  </metadata>
+  <sodipodi:namedview
+     inkscape:window-height="725"
+     inkscape:window-width="1280"
+     inkscape:pageshadow="2"
+     inkscape:pageopacity="0.0"
+     guidetolerance="10.0"
+     gridtolerance="10.0"
+     objecttolerance="10.0"
+     borderopacity="1.0"
+     bordercolor="#666666"
+     pagecolor="#ffffff"
+     id="base"
+     inkscape:zoom="0.43503001"
+     inkscape:cx="437.45687"
+     inkscape:cy="359.05944"
+     inkscape:window-x="0"
+     inkscape:window-y="25"
+     inkscape:current-layer="svg559"
+     showgrid="false"
+     showguides="true"
+     inkscape:guide-bbox="true"
+     inkscape:window-maximized="1" />
+  <defs
+     id="defs561">
+    <linearGradient
+       id="linearGradient4557">
+      <stop
+         style="stop-color:#ffffff;stop-opacity:1;"
+         offset="0"
+         id="stop4559" />
+      <stop
+         style="stop-color:#0300da;stop-opacity:1;"
+         offset="1"
+         id="stop4561" />
+    </linearGradient>
+    <linearGradient
+       id="linearGradient3751"
+       inkscape:collect="always">
+      <stop
+         id="stop3753"
+         offset="0"
+         style="stop-color:black;stop-opacity:1;" />
+      <stop
+         id="stop3755"
+         offset="1"
+         style="stop-color:black;stop-opacity:0;" />
+    </linearGradient>
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient3751"
+       id="linearGradient2518"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(0.9434139,0,0,0.9434139,62.279262,39.359798)"
+       x1="665.12128"
+       y1="684.16162"
+       x2="381.28015"
+       y2="449.80624" />
+    <linearGradient
+       id="linearGradient3945">
+      <stop
+         style="stop-color:#ffffff;stop-opacity:1;"
+         offset="0"
+         id="stop3947" />
+      <stop
+         style="stop-color:#ffffff;stop-opacity:0;"
+         offset="1"
+         id="stop3949" />
+    </linearGradient>
+    <inkscape:perspective
+       sodipodi:type="inkscape:persp3d"
+       inkscape:vp_x="0 : 400 : 1"
+       inkscape:vp_y="0 : 1000 : 0"
+       inkscape:vp_z="1000 : 400 : 1"
+       inkscape:persp3d-origin="500 : 266.66667 : 1"
+       id="perspective62" />
+    <linearGradient
+       id="linearGradient6053">
+      <stop
+         style="stop-color:#000000;stop-opacity:1;"
+         offset="0"
+         id="stop6055" />
+      <stop
+         style="stop-color:#5f5f5f;stop-opacity:1;"
+         offset="1"
+         id="stop6057" />
+    </linearGradient>
+    <linearGradient
+       id="linearGradient6499"
+       inkscape:collect="always">
+      <stop
+         id="stop6501"
+         offset="0"
+         style="stop-color:white;stop-opacity:1;" />
+      <stop
+         id="stop6503"
+         offset="1"
+         style="stop-color:white;stop-opacity:0;" />
+    </linearGradient>
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient6499"
+       id="linearGradient3245"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(0.8327515,0,0,-0.6476426,-48.09403,12.672202)"
+       x1="311.95688"
+       y1="-116.67703"
+       x2="311.95688"
+       y2="-276.41519" />
+    <filter
+       inkscape:collect="always"
+       id="filter3869"
+       x="-0.019231318"
+       width="1.0384626"
+       y="-0.12226724"
+       height="1.2445345">
+      <feGaussianBlur
+         inkscape:collect="always"
+         stdDeviation="3.4581674"
+         id="feGaussianBlur3871" />
+    </filter>
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient6499"
+       id="linearGradient4108"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(1.2483528,0,0,1.0242885,40.754503,32.226123)"
+       x1="44.868057"
+       y1="260.4765"
+       x2="358.07056"
+       y2="260.4765" />
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient6499"
+       id="linearGradient4121"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(1.2483528,0,0,1.0242885,40.754503,133.62899)"
+       x1="44.868057"
+       y1="260.4765"
+       x2="358.07056"
+       y2="260.4765" />
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient6499"
+       id="linearGradient4127"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(1.2483528,0,0,1.0242885,40.754503,340.11416)"
+       x1="44.868057"
+       y1="260.4765"
+       x2="358.07056"
+       y2="260.4765" />
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient6499"
+       id="linearGradient4133"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(1.2483528,0,0,1.0242885,426.06823,341.18482)"
+       x1="44.868057"
+       y1="260.4765"
+       x2="358.07056"
+       y2="260.4765" />
+    <radialGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient4557"
+       id="radialGradient4563"
+       cx="754.52362"
+       cy="248.26866"
+       fx="754.52362"
+       fy="248.26866"
+       r="648.54285"
+       gradientTransform="matrix(-0.6867835,-1.4236353,1.4876169,-0.7176493,903.38936,1551.3895)"
+       gradientUnits="userSpaceOnUse" />
+    <filter
+       inkscape:collect="always"
+       id="filter5083">
+      <feGaussianBlur
+         inkscape:collect="always"
+         stdDeviation="2.8444007"
+         id="feGaussianBlur5085" />
+    </filter>
+    <inkscape:perspective
+       id="perspective3678"
+       inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
+       inkscape:vp_z="1 : 0.5 : 1"
+       inkscape:vp_y="0 : 1000 : 0"
+       inkscape:vp_x="0 : 0.5 : 1"
+       sodipodi:type="inkscape:persp3d" />
+    <inkscape:perspective
+       id="perspective2860"
+       inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
+       inkscape:vp_z="1 : 0.5 : 1"
+       inkscape:vp_y="0 : 1000 : 0"
+       inkscape:vp_x="0 : 0.5 : 1"
+       sodipodi:type="inkscape:persp3d" />
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient3694"
+       id="linearGradient3692"
+       x1="-340.13901"
+       y1="580.56818"
+       x2="-587.59583"
+       y2="385.5177"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="translate(681.47733,-205.59316)" />
+    <linearGradient
+       inkscape:collect="always"
+       id="linearGradient3694">
+      <stop
+         style="stop-color:black;stop-opacity:0.227"
+         offset="0"
+         id="stop3696" />
+      <stop
+         style="stop-color:black;stop-opacity:0;"
+         offset="1"
+         id="stop3698" />
+    </linearGradient>
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient3694"
+       id="linearGradient2933"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="translate(982.98897,55.807426)"
+       x1="-340.13901"
+       y1="580.56818"
+       x2="-587.59583"
+       y2="385.5177" />
+    <inkscape:perspective
+       id="perspective3779"
+       inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
+       inkscape:vp_z="1 : 0.5 : 1"
+       inkscape:vp_y="0 : 1000 : 0"
+       inkscape:vp_x="0 : 0.5 : 1"
+       sodipodi:type="inkscape:persp3d" />
+    <radialGradient
+       r="500"
+       fy="757.60583"
+       fx="727.25122"
+       cy="757.60583"
+       cx="727.25122"
+       gradientTransform="matrix(0.43355171,-0.84504566,1.805509,0.92631863,-980.8803,538.04792)"
+       gradientUnits="userSpaceOnUse"
+       id="radialGradient3750"
+       xlink:href="#linearGradient3629-3"
+       inkscape:collect="always" />
+    <linearGradient
+       id="linearGradient3629-3">
+      <stop
+         style="stop-color:#00cbff;stop-opacity:0;"
+         offset="0"
+         id="stop3631-1" />
+      <stop
+         style="stop-color:#000000;stop-opacity:1;"
+         offset="1"
+         id="stop3633-4" />
+    </linearGradient>
+    <radialGradient
+       r="500"
+       fy="757.60583"
+       fx="727.25122"
+       cy="757.60583"
+       cx="727.25122"
+       gradientTransform="matrix(0.43355171,-0.84504566,1.805509,0.92631863,-980.88026,538.04793)"
+       gradientUnits="userSpaceOnUse"
+       id="radialGradient3788"
+       xlink:href="#linearGradient3629-3"
+       inkscape:collect="always" />
+    <inkscape:perspective
+       id="perspective3661"
+       inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
+       inkscape:vp_z="1 : 0.5 : 1"
+       inkscape:vp_y="0 : 1000 : 0"
+       inkscape:vp_x="0 : 0.5 : 1"
+       sodipodi:type="inkscape:persp3d" />
+    <radialGradient
+       r="500"
+       fy="757.60583"
+       fx="727.25122"
+       cy="757.60583"
+       cx="727.25122"
+       gradientTransform="matrix(0.43355171,-0.84504566,1.805509,0.92631863,-980.88026,538.04793)"
+       gradientUnits="userSpaceOnUse"
+       id="radialGradient3788-1"
+       xlink:href="#linearGradient3629-3-6"
+       inkscape:collect="always" />
+    <linearGradient
+       id="linearGradient3629-3-6">
+      <stop
+         style="stop-color:#00cbff;stop-opacity:0;"
+         offset="0"
+         id="stop3631-1-5" />
+      <stop
+         style="stop-color:#000000;stop-opacity:1;"
+         offset="1"
+         id="stop3633-4-7" />
+    </linearGradient>
+  </defs>
+  <rect
+     style="fill:#ffffff;fill-opacity:1;stroke:none"
+     id="rect2855-8"
+     width="1000"
+     height="800"
+     x="0"
+     y="0" />
+  <rect
+     style="fill:url(#radialGradient3788);fill-opacity:1;stroke:none"
+     id="rect2855"
+     width="1000"
+     height="800"
+     x="0"
+     y="0" />
+  <text
+     xml:space="preserve"
+     style="font-size:24.89476013px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Goblin"
+     x="266.96185"
+     y="759.88806"
+     id="text2508"><tspan
+       sodipodi:role="line"
+       id="tspan2510"
+       x="266.96185"
+       y="759.88806" /></text>
+  <g
+     id="g3955"
+     transform="translate(18.488319,-59.198001)"
+     style="opacity:0.6;filter:url(#filter5083)">
+    <path
+       style="fill:#000000;fill-opacity:1"
+       d="m 710.75817,261.47303 c -24.8619,0.81505 -49.2611,8.55033 -68.6512,25.43509 -33.8487,27.20416 -45.3156,80.90572 -24.3753,120.11021 12.6486,25.44898 45.9923,30.70952 68.6512,17.78104 21.7012,-12.30047 26.2646,-41.57536 20.4894,-64.64756 -5.42,-25.10698 -34.3199,-39.60578 -56.0514,-29.43879 -9.4388,4.41596 -8.627,3.35172 -20.1361,12.83532 -1.6287,-17.11896 8.237,-32.05555 13.3063,-37.44613 19.2759,-20.49767 47.9999,-30.24403 75.01,-25.90612 29.7625,4.20493 48.5551,33.48396 55.4626,61.93918 9.4136,38.70202 11.1575,79.75225 4.9457,119.16817 -10.6592,64.75378 -54.6412,117.90361 -106.6861,151.66858 -23.5615,16.4422 -50.0202,27.00568 -75.5987,39.21245 -13.3021,6.51851 -0.6729,12.80562 7.7718,8.00736 63.476,-21.20757 125.7437,-53.00609 173.3355,-102.91797 38.2144,-39.44239 62.3285,-94.42174 61.4682,-151.07981 0,-9.45372 -0.4354,-18.99189 -1.5309,-28.37899 -4.0265,-44.97399 -28.8894,-90.38854 -70.653,-106.68612 -17.7612,-6.73739 -37.4209,-10.28987 -56.758,-9.65591 z m 184.64,37.09285 c -6.183,0.28246 -12.2184,2.88239 -16.4857,7.65409 -5.1736,5.33804 -7.476,13.22873 -6.8298,20.72489 0.4843,9.59273 6.8037,18.45696 15.3082,21.90246 8.5809,3.35825 19.019,2.00507 25.9061,-4.59245 5.3847,-4.83818 8.3959,-12.25578 8.2429,-19.66511 0.046,-5.66577 -1.4875,-11.39715 -4.828,-15.89694 -4.3366,-6.10149 -11.3437,-9.96642 -18.6053,-10.12694 -0.8819,-0.0563 -1.8251,-0.0403 -2.7084,0 z m 0,117.16634 c -6.1814,0.27232 -12.3099,2.88445 -16.4857,7.77184 -5.0365,5.41748 -7.497,13.22312 -6.8298,20.7249 0.4799,9.59774 6.7987,18.33779 15.3082,21.78469 8.5809,3.35803 19.019,2.00507 25.9061,-4.59245 5.3908,-4.84198 8.3958,-12.24996 8.2429,-19.66511 0.01,-3.5795 -0.5871,-7.09786 -2.0019,-10.36245 -3.8241,-8.66819 -12.2991,-15.27689 -21.5492,-15.54367 -0.879,-0.0541 -1.7075,-0.15665 -2.5906,-0.11775 z"
+       id="path2885-1" />
+    <path
+       style="fill:url(#linearGradient2933);fill-opacity:1"
+       d="m 348.97101,512.55804 c -24.13417,0.31885 -41.62643,3.34489 -45.94006,9.95021 -9.55792,10.64226 26.92567,31.65031 82.87192,46.9871 35.3722,9.95564 73.413,12.01356 84.528,6.95594 10.718,-4.81194 -10.8583,-16.26428 -37.2348,-25.29012 -27.8383,-9.82185 -69.68415,-15.49377 -82.33755,-11.51645 -5.49573,1.72752 -5.63418,1.31119 -8.67537,5.02118 -16.91428,-6.69694 -20.38554,-12.54013 -20.12958,-14.64893 0.97337,-8.01868 20.99477,-11.83146 51.8783,-10.13447 33.5171,1.64497 78.4531,13.09892 110.7685,24.2306 43.9708,15.14023 82.3688,31.19908 111.3518,46.61858 47.1599,25.33168 50.6356,46.12389 28.7398,59.33274 -8.8802,6.43219 -25.9067,10.56462 -40.5858,15.33991 -7.4816,2.55004 10.7615,5.00956 14.9217,3.13248 44.5397,-8.2964 78.4143,-20.73598 81.4394,-40.26151 2.996,-15.42986 -21.9814,-36.93778 -73.432,-59.10241 -8.4413,-3.69829 -17.3934,-7.42962 -26.8707,-11.10186 -44.1841,-17.59382 -109.5979,-35.35998 -165.9138,-41.7356 -23.777,-2.63566 -46.60876,-4.02539 -65.37976,-3.77739 z m 217.76046,14.51072 c -5.9308,0.1105 -9.6447,1.12759 -9.6513,2.99428 -0.4073,2.08824 4.336,5.17508 11.6756,8.10758 9.0496,3.75267 23.284,7.22036 34.865,8.56824 11.5795,1.31375 20.8093,0.78438 21.8055,-1.79657 1.0646,-1.89269 -2.5474,-4.79446 -9.3163,-7.69299 -5.0133,-2.21645 -11.6641,-4.45856 -19.0224,-6.21888 -9.7847,-2.3869 -20.2428,-3.89886 -27.6477,-3.96166 -0.9321,-0.022 -1.8611,-0.0158 -2.7084,0 z m 104.6186,45.83546 c -5.9383,0.10653 -9.7343,1.1284 -9.5462,3.04035 -0.1992,2.11931 4.3101,5.17288 11.6756,8.10758 9.0498,3.75463 23.1727,7.17374 34.7599,8.52217 11.5793,1.31366 20.8093,0.78438 21.8055,-1.79657 1.0673,-1.89418 -2.5423,-4.79218 -9.3163,-7.69299 -3.1881,-1.4003 -6.9248,-2.77668 -11.2545,-4.05379 -11.564,-3.391 -25.94,-5.97632 -35.4282,-6.08068 -0.9275,-0.0212 -1.8475,-0.0613 -2.6959,-0.0461 z"
+       id="path2885-9" />
+  </g>
+  <g
+     id="g4892"
+     transform="matrix(0.99721358,0,0,1,1.6801378,-0.03097843)">
+    <g
+       transform="matrix(1.2468256,0,0,1.1986102,1.2039301,52.246604)"
+       id="g2836">
+      <path
+         style="fill:none;stroke:#141414;stroke-width:4;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:0.61153846;stroke-dasharray:none"
+         d="m 0,165 800,0"
+         id="path2327"
+         sodipodi:nodetypes="cc" />
+      <path
+         style="fill:none;stroke:#141414;stroke-width:4;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:0.61153846;stroke-dasharray:none"
+         d="m 0,140 800,0"
+         id="path3298"
+         sodipodi:nodetypes="cc" />
+      <path
+         style="fill:none;stroke:#141414;stroke-width:4;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:0.61153846;stroke-dasharray:none"
+         d="m 0,190 800,0"
+         id="path3302"
+         sodipodi:nodetypes="cc" />
+      <path
+         style="fill:none;stroke:#141414;stroke-width:4;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:0.61153846;stroke-dasharray:none"
+         d="m 0,240 800,0"
+         id="path3306"
+         sodipodi:nodetypes="cc" />
+      <path
+         style="fill:none;stroke:#141414;stroke-width:4;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:0.61153846;stroke-dasharray:none"
+         d="m 0,215 800,0"
+         id="path3304"
+         sodipodi:nodetypes="cc" />
+    </g>
+    <g
+       transform="matrix(1.2468256,0,0,1.1986102,0.760128,231.91957)"
+       id="g2209">
+      <path
+         style="fill:none;stroke:#141414;stroke-width:4;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:0.61153846;stroke-dasharray:none"
+         d="m 0,165 800,0"
+         id="path2211"
+         sodipodi:nodetypes="cc" />
+      <path
+         style="fill:none;stroke:#141414;stroke-width:4;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:0.61153846;stroke-dasharray:none"
+         d="m 0,140 800,0"
+         id="path2213"
+         sodipodi:nodetypes="cc" />
+      <path
+         style="fill:none;stroke:#141414;stroke-width:4;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:0.61153846;stroke-dasharray:none"
+         d="m 0,190 800,0"
+         id="path2215"
+         sodipodi:nodetypes="cc" />
+      <path
+         style="fill:none;stroke:#141414;stroke-width:4;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:0.61153846;stroke-dasharray:none"
+         d="m 0,240 800,0"
+         id="path2217"
+         sodipodi:nodetypes="cc" />
+      <path
+         style="fill:none;stroke:#141414;stroke-width:4;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:0.61153846;stroke-dasharray:none"
+         d="m 0,215 800,0"
+         id="path2219"
+         sodipodi:nodetypes="cc" />
+    </g>
+    <g
+       transform="matrix(5.0734563,0,0,5.3232265,22.200477,397.25206)"
+       id="g2411">
+      <g
+         transform="translate(-230.9546,-533.6597)"
+         style="fill:#000000;fill-opacity:1"
+         id="g2883">
+        <path
+           d="m 248.25999,536.802 c 0.008,0.36938 -0.14955,0.73865 -0.43121,0.97985 -0.36025,0.32891 -0.90945,0.39628 -1.3583,0.22886 -0.44485,-0.17177 -0.7737,-0.61188 -0.79903,-1.09011 -0.0338,-0.37371 0.0854,-0.76581 0.35602,-1.03193 0.2551,-0.27187 0.63497,-0.4047 1.004,-0.38222 0.37984,0.008 0.74658,0.19956 0.97342,0.50374 0.17473,0.22433 0.25749,0.50935 0.2551,0.79181 z"
+           style="fill:#000000;fill-opacity:1"
+           id="path2885" />
+      </g>
+      <g
+         transform="translate(-230.9546,-533.6597)"
+         style="fill:#000000;fill-opacity:1"
+         id="g2887">
+        <path
+           d="m 248.25999,542.64502 c 0.008,0.36967 -0.14923,0.73944 -0.43121,0.98083 -0.36025,0.32891 -0.90945,0.39628 -1.3583,0.22887 -0.44511,-0.17184 -0.77393,-0.61235 -0.79903,-1.09083 -0.0349,-0.37399 0.0921,-0.76081 0.35555,-1.03089 0.24963,-0.27846 0.6336,-0.4051 1.00145,-0.3835 0.48385,0.0133 0.92314,0.34301 1.12317,0.77515 0.074,0.16275 0.10881,0.34192 0.10837,0.52037 z"
+           style="fill:#000000;fill-opacity:1"
+           id="path2889" />
+      </g>
+      <g
+         transform="translate(-230.9546,-533.6597)"
+         style="fill:#000000;fill-opacity:1"
+         id="g2891">
+        <path
+           d="m 243.979,540.86798 c 0.045,2.8246 -1.2154,5.57017 -3.21431,7.53651 -2.48942,2.48828 -5.74678,4.07085 -9.06707,5.12812 -0.44172,0.23921 -1.10792,-0.0762 -0.41212,-0.40117 1.33796,-0.60855 2.72769,-1.13094 3.96014,-1.95064 2.72235,-1.6833 5.01959,-4.33406 5.57715,-7.56226 0.32492,-1.96502 0.23445,-4.01059 -0.25795,-5.94002 -0.36132,-1.41859 -1.34451,-2.88302 -2.90132,-3.09265 -1.41284,-0.21626 -2.91467,0.27318 -3.92295,1.29506 -0.26516,0.26874 -0.78141,1.0131 -0.69622,1.86654 0.60202,-0.47279 0.56093,-0.42015 1.05465,-0.6403 1.13673,-0.50686 2.64449,0.21388 2.928,1.46555 0.30209,1.15023 0.0685,2.61366 -1.06664,3.22688 -1.18524,0.64453 -2.93424,0.37778 -3.59586,-0.89094 -1.09534,-1.95448 -0.49303,-4.62673 1.27752,-5.98295 1.80312,-1.49647 4.43407,-1.55482 6.55761,-0.78709 2.18456,0.81249 3.48666,3.07621 3.69728,5.31832 0.0573,0.46798 0.0821,0.93974 0.0821,1.41104 z"
+           style="fill:#000000;fill-opacity:1"
+           id="path2893" />
+      </g>
+    </g>
+    <g
+       inkscape:label="Calque 1"
+       id="layer1"
+       transform="matrix(1.2842911,0,0,1.3475176,-322.83945,-416.05452)">
+      <path
+         style="fill:#000000"
+         d="m 293.69923,599.2555 c -5.0833,-2.30755 -8.26176,-7.06977 -8.26692,-12.38618 -0.003,-3.04786 0.70465,-4.55839 3.39626,-7.25 4.12078,-4.12078 7.32215,-4.34612 11.52327,-0.81111 2.481,2.08762 3.07673,3.35498 3.07673,6.54546 0,4.57716 -3.45488,8.84457 -7.20454,8.89892 l -2.29546,0.0333 2.36078,1.96673 c 4.40817,3.67237 13.74161,1.83025 17.97132,-3.54695 2.68695,-3.4159 2.8725,-10.4474 0.58017,-21.98632 l -1.58928,-8 -8.1615,-0.0292 c -6.83293,-0.0244 -8.97541,-0.45585 -13.16149,-2.65039 -6.67455,-3.49912 -12.03482,-9.03283 -15.80893,-16.32046 -2.7541,-5.31803 -3.10958,-6.96613 -3.12752,-14.5 -0.017,-7.12783 0.40892,-9.42312 2.63829,-14.21836 3.69503,-7.94778 8.10406,-14.1647 15.55273,-21.92998 l 6.37727,-6.64834 -1.26075,-4.35166 c -0.69341,-2.39341 -1.25638,-9.52666 -1.25104,-15.85166 0.008,-9.66271 0.38331,-12.45859 2.34822,-17.5 2.41156,-6.18742 8.57143,-13.5 11.37193,-13.5 2.3357,0 6.35748,7.58778 8.22735,15.52231 3.64909,15.48447 -1.4259,36.48399 -10.97239,45.402 -3.04169,2.84145 -3.13291,4.02388 -0.97359,12.62017 l 1.62158,6.45552 3.91826,0 c 13.55768,0 23.53603,17.26888 18.39611,31.83696 -1.95613,5.54426 -5.12113,9.61309 -9.17655,11.79707 -3.88166,2.09042 -3.87522,2.04461 -1.88097,13.36597 0.8235,4.675 1.49048,10.3 1.48218,12.5 -0.0463,12.29085 -13.67914,19.99824 -25.71152,14.53618 z m 18.32225,-40.29576 c 0.26449,-0.26448 -0.9617,-7.51428 -2.72486,-16.11065 -2.15086,-10.48662 -3.63233,-15.62977 -4.5021,-15.62977 -0.713,0 -2.87307,1.38438 -4.80017,3.07639 -6.00998,5.27683 -5.77153,13.04837 0.56393,18.3793 3.26839,2.75017 3.66914,3.76974 1.12029,2.8502 -7.21634,-2.60341 -11.80118,-10.0042 -10.90186,-17.5976 0.71989,-6.07833 4.67165,-13.02449 8.7669,-15.4099 3.07673,-1.79216 3.08517,-1.82092 2.4339,-8.29839 -0.35945,-3.575 -1.00248,-6.84997 -1.42896,-7.27772 -1.18105,-1.18455 -9.63542,6.73915 -14.54996,13.63666 -5.57826,7.82905 -8.02781,15.12796 -7.2581,21.62696 1.60495,13.55125 12.49382,22.4315 26.49409,21.60685 3.46831,-0.20429 6.52241,-0.58784 6.7869,-0.85233 z m 10.79335,-8.74776 c 2.9889,-7.46999 1.47145,-15.15439 -3.92889,-19.89594 -3.35374,-2.94462 -7.9877,-4.89972 -9.06349,-3.82394 -0.28213,0.28214 0.86382,7.3714 2.54657,15.75391 1.68275,8.38251 3.05955,15.43636 3.05955,15.67521 0,0.23886 1.29882,-0.49055 2.88626,-1.62091 1.58744,-1.13036 3.61244,-3.87011 4.5,-6.08833 z M 304.9704,479.46932 c 8.1183,-8.85025 12.55342,-22.40329 9.07069,-27.71861 -4.87006,-7.43266 -13.9101,3.14073 -15.2864,17.87923 -0.65342,6.99729 0.20528,13.58938 1.77018,13.58938 0.55311,0 2.5536,-1.6875 4.44553,-3.75 z"
+         id="path2221" />
+    </g>
+  </g>
+</svg>
diff --git a/data/themes/default/practice_note.svg b/data/themes/default/practice_note.svg
new file mode 100644 (file)
index 0000000..acf897d
--- /dev/null
@@ -0,0 +1,68 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://creativecommons.org/ns#"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   width="80"
+   height="50"
+   id="svg2"
+   sodipodi:version="0.32"
+   inkscape:version="0.46"
+   version="1.0"
+   sodipodi:docbase="/root/USNG/branches/hacking/themes/lima"
+   sodipodi:docname="practice_note.svg"
+   inkscape:output_extension="org.inkscape.output.svg.inkscape">
+  <defs
+     id="defs4" />
+  <sodipodi:namedview
+     id="base"
+     pagecolor="#ffffff"
+     bordercolor="#666666"
+     borderopacity="1.0"
+     inkscape:pageopacity="0.0"
+     inkscape:pageshadow="2"
+     inkscape:zoom="9.04"
+     inkscape:cx="44.454683"
+     inkscape:cy="21.792349"
+     inkscape:document-units="px"
+     inkscape:current-layer="layer1"
+     inkscape:window-width="822"
+     inkscape:window-height="722"
+     inkscape:window-x="608"
+     inkscape:window-y="100"
+     showgrid="false"
+     width="80px"
+     height="50px" />
+  <metadata
+     id="metadata7">
+    <rdf:RDF>
+      <cc:Work
+         rdf:about="">
+        <dc:format>image/svg+xml</dc:format>
+        <dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+      </cc:Work>
+      <cc:Work
+         rdf:about="">
+        <dc:format>image/svg+xml</dc:format>
+        <dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+      </cc:Work>
+    </rdf:RDF>
+  </metadata>
+  <g
+     inkscape:label="Calque 1"
+     inkscape:groupmode="layer"
+     id="layer1"
+     transform="translate(-247.7219,-621.15445)">
+    <path
+       style="fill:#000000"
+       d="M 267.56476,668.82743 C 253.30212,663.34553 247.81274,656.94529 247.72256,645.69277 C 247.60494,631.01587 263.31926,621.12949 286.72594,621.15449 C 301.83554,621.17061 311.88394,624.42323 320.26658,632.01135 C 332.61008,643.18489 329.36062,657.70735 312.4874,666.77825 C 303.64922,671.52953 277.67742,672.71429 267.56476,668.82743 z M 299.89352,664.50729 C 305.17218,660.52725 304.77702,643.80935 299.22126,636.06521 C 290.68224,624.16267 275.94586,622.52677 272.065,633.05053 C 265.23,651.58501 285.95748,675.01491 299.89352,664.50729 z "
+       id="path2266" />
+  </g>
+</svg>
diff --git a/data/themes/default/practice_peak.svg b/data/themes/default/practice_peak.svg
new file mode 100644 (file)
index 0000000..2e343fd
--- /dev/null
@@ -0,0 +1,64 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://creativecommons.org/ns#"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   width="800"
+   height="600"
+   id="svg2"
+   sodipodi:version="0.32"
+   inkscape:version="0.46"
+   version="1.0"
+   sodipodi:docbase="/home/yoda/UltraStar/sf/UltraStar-ng/themes/lima"
+   sodipodi:docname="practice_peak.svg"
+   inkscape:output_extension="org.inkscape.output.svg.inkscape">
+  <defs
+     id="defs2881" />
+  <sodipodi:namedview
+     id="base"
+     pagecolor="#ffffff"
+     bordercolor="#666666"
+     borderopacity="1.0"
+     inkscape:pageopacity="0.0"
+     inkscape:pageshadow="2"
+     inkscape:zoom="1.9875"
+     inkscape:cx="401.5626"
+     inkscape:cy="86.866397"
+     inkscape:document-units="px"
+     inkscape:current-layer="layer1"
+     inkscape:window-width="1439"
+     inkscape:window-height="801"
+     inkscape:window-x="0"
+     inkscape:window-y="25"
+     width="800px"
+     height="600px"
+     showgrid="false" />
+  <metadata
+     id="metadata7">
+    <rdf:RDF>
+      <cc:Work
+         rdf:about="">
+        <dc:format>image/svg+xml</dc:format>
+        <dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+      </cc:Work>
+    </rdf:RDF>
+  </metadata>
+  <g
+     inkscape:label="Calque 1"
+     inkscape:groupmode="layer"
+     id="layer1">
+    <rect
+       style="fill:#000000;fill-opacity:0.3116883;stroke:none;stroke-width:0;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+       id="rect2159"
+       width="800"
+       height="8"
+       x="0"
+       y="591" />
+  </g>
+</svg>
diff --git a/data/themes/default/practice_sharp.svg b/data/themes/default/practice_sharp.svg
new file mode 100644 (file)
index 0000000..1ba903f
--- /dev/null
@@ -0,0 +1,65 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://creativecommons.org/ns#"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   id="svg2"
+   sodipodi:version="0.32"
+   inkscape:version="0.46"
+   width="50"
+   height="150"
+   version="1.0"
+   sodipodi:docbase="/root/USNG/branches/hacking/themes/lima"
+   sodipodi:docname="practice_sharp.svg"
+   inkscape:output_extension="org.inkscape.output.svg.inkscape">
+  <metadata
+     id="metadata7">
+    <rdf:RDF>
+      <cc:Work
+         rdf:about="">
+        <dc:format>image/svg+xml</dc:format>
+        <dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+      </cc:Work>
+      <cc:Work
+         rdf:about="">
+        <dc:format>image/svg+xml</dc:format>
+        <dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+      </cc:Work>
+    </rdf:RDF>
+  </metadata>
+  <defs
+     id="defs5" />
+  <sodipodi:namedview
+     inkscape:window-height="801"
+     inkscape:window-width="1439"
+     inkscape:pageshadow="2"
+     inkscape:pageopacity="0.0"
+     guidetolerance="10.0"
+     gridtolerance="10.0"
+     objecttolerance="10.0"
+     borderopacity="1.0"
+     bordercolor="#666666"
+     pagecolor="#ffffff"
+     id="base"
+     inkscape:zoom="6.1666667"
+     inkscape:cx="20"
+     inkscape:cy="75.341373"
+     inkscape:window-x="0"
+     inkscape:window-y="25"
+     inkscape:current-layer="svg2"
+     showgrid="false"
+     width="50px"
+     height="150px" />
+  <path
+     style="fill:#000000"
+     d="M 9.5186641,131.30669 C 9.5186641,113.18383 9.4060341,112.71134 5.2352651,113.33693 C 1.3752881,113.91594 0.89447711,113.01437 0.37132411,104.21651 C -0.15465039,95.371246 0.24796011,94.26612 4.6547231,92.458659 C 9.1961101,90.596035 9.5186641,89.560389 9.5186641,76.841322 C 9.5186641,63.33628 9.4776701,63.230019 4.7593321,64.507506 C 0.16666811,65.751012 8.108108e-09,65.44296 8.108108e-09,55.711236 C 8.108108e-09,46.666741 0.49100311,45.493368 4.7593321,44.337717 C 9.4172991,43.076551 9.5186641,42.634412 9.5186641,23.57824 C 9.5186641,11.966774 10.287106,4.107366 11.422395,4.107366 C 12.552339,4.107366 13.32613,11.717374 13.32613,22.830041 C 13.32613,41.243946 13.396771,41.532306 17.609527,40.314407 C 19.965391,39.633325 22.963784,39.063447 24.272601,39.048026 C 26.007516,39.027591 26.652268,33.733912 26.652268,19.509996 C 26.652268,7.8724459 27.420444,-5.8656388e-15 28.556,-5.8656388e-15 C 29.681927,-5.8656388e-15 30.459732,7.43524 30.459732,18.19837 L 30.459732,36.396739 L 35.219064,35.415262 C 39.742736,34.482399 39.978378,34.905746 39.978378,43.965612 C 39.978378,52.243239 39.352141,53.754282 35.219064,55.449475 C 30.802631,57.260829 30.459732,58.382973 30.459732,71.023888 C 30.459732,84.604925 30.474492,84.642301 35.320687,83.330196 C 40.122009,82.030213 40.174558,82.147196 39.604085,92.862535 C 39.100381,102.32385 38.478791,103.79493 34.743132,104.36728 C 30.646879,104.99488 30.459732,105.86979 30.459732,124.39072 C 30.459732,149.00403 26.985202,150.04501 26.247768,125.65262 L 25.7004,107.54741 L 19.513258,109.28188 L 13.32613,111.01635 L 13.32613,130.46761 C 13.32613,142.06603 12.557553,149.91892 11.422395,149.91892 C 10.293282,149.91892 9.5186641,142.34572 9.5186641,131.30669 z M 23.640954,87.061824 C 27.513014,85.458957 28.108842,59.539669 24.272601,59.584851 C 14.703403,59.697646 13.32613,61.662185 13.32613,75.19899 C 13.32613,88.954187 14.846289,90.702513 23.640954,87.061824 z "
+     id="path2161"
+     sodipodi:nodetypes="csssssssssssssscccssssssscccccsccssc" />
+</svg>
diff --git a/data/themes/default/practice_txt.svg b/data/themes/default/practice_txt.svg
new file mode 100644 (file)
index 0000000..e2b3fac
--- /dev/null
@@ -0,0 +1,70 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Sodipodi ("http://www.sodipodi.com/") -->
+
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://creativecommons.org/ns#"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   version="1.0"
+   x="0"
+   y="0"
+   width="800.000000"
+   height="600.000000"
+   id="svg559"
+   sodipodi:version="0.32"
+   inkscape:version="0.47 r22583"
+   sodipodi:docname="practice_txt.svg"
+   inkscape:output_extension="org.inkscape.output.svg.inkscape">
+  <metadata
+     id="metadata35">
+    <rdf:RDF>
+      <cc:Work
+         rdf:about="">
+        <dc:format>image/svg+xml</dc:format>
+        <dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+      </cc:Work>
+    </rdf:RDF>
+  </metadata>
+  <sodipodi:namedview
+     inkscape:window-height="797"
+     inkscape:window-width="1376"
+     inkscape:pageshadow="2"
+     inkscape:pageopacity="0.0"
+     guidetolerance="10.0"
+     gridtolerance="10.0"
+     objecttolerance="10.0"
+     borderopacity="1.0"
+     bordercolor="#666666"
+     pagecolor="#ffffff"
+     id="base"
+     inkscape:zoom="1.26"
+     inkscape:cx="400"
+     inkscape:cy="300"
+     inkscape:window-x="0"
+     inkscape:window-y="49"
+     inkscape:current-layer="svg559"
+     showgrid="false"
+     inkscape:window-maximized="0" />
+  <defs
+     id="defs561">
+    <inkscape:perspective
+       sodipodi:type="inkscape:persp3d"
+       inkscape:vp_x="0 : 300 : 1"
+       inkscape:vp_y="0 : 1000 : 0"
+       inkscape:vp_z="800 : 300 : 1"
+       inkscape:persp3d-origin="400 : 200 : 1"
+       id="perspective8" />
+  </defs>
+  <text
+     x="450"
+     y="430"
+     style="font-size:40px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;text-align:start;line-height:125%;writing-mode:lr-tb;text-anchor:start;fill:#ffd100;fill-opacity:1;stroke:#000000;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;display:inline;font-family:Droid Sans Mono"
+     id="text10203"
+     xml:space="preserve"
+     sodipodi:linespacing="125%">A#</text>
+</svg>
diff --git a/data/themes/default/score_bar_bg.svg b/data/themes/default/score_bar_bg.svg
new file mode 100644 (file)
index 0000000..66ac3ac
--- /dev/null
@@ -0,0 +1,231 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://creativecommons.org/ns#"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:xlink="http://www.w3.org/1999/xlink"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   width="64"
+   height="256"
+   id="svg2"
+   sodipodi:version="0.32"
+   inkscape:version="0.46"
+   version="1.0"
+   sodipodi:docname="bar_stroke.svg"
+   inkscape:output_extension="org.inkscape.output.svg.inkscape">
+  <defs
+     id="defs4">
+    <linearGradient
+       id="linearGradient2385">
+      <stop
+         style="stop-color:#808080;stop-opacity:1;"
+         offset="0"
+         id="stop2387" />
+      <stop
+         style="stop-color:#ffffff;stop-opacity:1;"
+         offset="1"
+         id="stop2389" />
+    </linearGradient>
+    <inkscape:perspective
+       sodipodi:type="inkscape:persp3d"
+       inkscape:vp_x="0 : 526.18109 : 1"
+       inkscape:vp_y="0 : 1000 : 0"
+       inkscape:vp_z="744.09448 : 526.18109 : 1"
+       inkscape:persp3d-origin="372.04724 : 350.78739 : 1"
+       id="perspective10" />
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient2385"
+       id="linearGradient2391"
+       x1="33.554657"
+       y1="258.01822"
+       x2="33.554657"
+       y2="-0.98177975"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(0.9544661,0,0,0.9886165,-2.6779771e-2,0.9447589)" />
+    <clipPath
+       clipPathUnits="userSpaceOnUse"
+       id="clipPath3476">
+      <rect
+         style="opacity:1;fill:url(#linearGradient3480);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2.9141736;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-opacity:1;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+         id="rect3478"
+         width="176.6787"
+         height="732.00079"
+         x="-208.22636"
+         y="72.247185"
+         ry="14.296889" />
+    </clipPath>
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient2385"
+       id="linearGradient3480"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(2.7606047,0,0,2.859378,-212.51815,70.765398)"
+       x1="33.554657"
+       y1="258.01822"
+       x2="33.554657"
+       y2="-0.98177975" />
+    <clipPath
+       clipPathUnits="userSpaceOnUse"
+       id="clipPath3482">
+      <rect
+         style="opacity:1;fill:url(#linearGradient3486);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2.9141736;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-opacity:1;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+         id="rect3484"
+         width="108.34083"
+         height="448.86887"
+         x="-47.562611"
+         y="52.756752"
+         ry="8.7669697" />
+    </clipPath>
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient2385"
+       id="linearGradient3486"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(1.6928254,0,0,1.753394,-50.19437,51.848108)"
+       x1="33.554657"
+       y1="258.01822"
+       x2="33.554657"
+       y2="-0.98177975" />
+    <clipPath
+       clipPathUnits="userSpaceOnUse"
+       id="clipPath3488">
+      <rect
+         style="opacity:1;fill:url(#linearGradient3492);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2.9141736;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-opacity:1;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+         id="rect3490"
+         width="84.279854"
+         height="349.1814"
+         x="-164.00085"
+         y="7.1028223"
+         ry="6.8199492"
+         transform="matrix(0.9492114,-0.314639,0.314639,0.9492114,0,0)" />
+    </clipPath>
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient2385"
+       id="linearGradient3492"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(1.3168727,0,0,1.3639898,-166.04815,6.3959756)"
+       x1="33.554657"
+       y1="258.01822"
+       x2="33.554657"
+       y2="-0.98177975" />
+    <clipPath
+       clipPathUnits="userSpaceOnUse"
+       id="clipPath3494">
+      <rect
+         style="opacity:1;fill:url(#linearGradient3498);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2.9141736;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-opacity:1;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+         id="rect3496"
+         width="79.174919"
+         height="328.03107"
+         x="-45.36124"
+         y="-25.200241"
+         ry="6.4068561"
+         transform="matrix(0.997851,-6.5523259e-2,6.5523259e-2,0.997851,0,0)" />
+    </clipPath>
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient2385"
+       id="linearGradient3498"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(1.2371081,0,0,1.2813713,-47.284519,-25.864273)"
+       x1="33.554657"
+       y1="258.01822"
+       x2="33.554657"
+       y2="-0.98177975" />
+    <clipPath
+       clipPathUnits="userSpaceOnUse"
+       id="clipPath3500">
+      <rect
+         style="opacity:1;fill:url(#linearGradient3504);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2.9141736;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-opacity:1;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+         id="rect3502"
+         width="73.717499"
+         height="305.42035"
+         x="-141.34662"
+         y="-77.569504"
+         ry="5.9652405"
+         transform="matrix(0.9657312,-0.2595445,0.2595445,0.9657312,0,0)" />
+    </clipPath>
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient2385"
+       id="linearGradient3504"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(1.151836,0,0,1.1930482,-143.13732,-78.187764)"
+       x1="33.554657"
+       y1="258.01822"
+       x2="33.554657"
+       y2="-0.98177975" />
+    <clipPath
+       clipPathUnits="userSpaceOnUse"
+       id="clipPath3506">
+      <rect
+         style="opacity:1;fill:url(#linearGradient3510);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2.9141736;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-opacity:1;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+         id="rect3508"
+         width="61.085831"
+         height="253.08583"
+         x="-150.72115"
+         y="-181.22908"
+         ry="4.9430823"
+         transform="matrix(0.5933644,-0.804934,0.804934,0.5933644,0,0)" />
+    </clipPath>
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient2385"
+       id="linearGradient3510"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(0.9544661,0,0,0.9886165,-152.20501,-181.74141)"
+       x1="33.554657"
+       y1="258.01822"
+       x2="33.554657"
+       y2="-0.98177975" />
+  </defs>
+  <sodipodi:namedview
+     id="base"
+     pagecolor="#ffffff"
+     bordercolor="#666666"
+     borderopacity="1.0"
+     gridtolerance="10000"
+     guidetolerance="10"
+     objecttolerance="10"
+     inkscape:pageopacity="0.0"
+     inkscape:pageshadow="2"
+     inkscape:zoom="2.4324324"
+     inkscape:cx="33.554656"
+     inkscape:cy="127.48178"
+     inkscape:document-units="px"
+     inkscape:current-layer="layer1"
+     showgrid="false"
+     inkscape:window-width="877"
+     inkscape:window-height="846"
+     inkscape:window-x="767"
+     inkscape:window-y="23" />
+  <metadata
+     id="metadata7">
+    <rdf:RDF>
+      <cc:Work
+         rdf:about="">
+        <dc:format>image/svg+xml</dc:format>
+        <dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+      </cc:Work>
+    </rdf:RDF>
+  </metadata>
+  <g
+     inkscape:label="Layer 1"
+     inkscape:groupmode="layer"
+     id="layer1">
+    <rect
+       style="opacity:1;fill:none;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:3;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-opacity:1;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+       id="rect2383"
+       width="61.085831"
+       height="253.08583"
+       x="1.4570868"
+       y="1.4570796"
+       ry="4.9430823" />
+  </g>
+</svg>
diff --git a/data/themes/default/score_bar_fg.svg b/data/themes/default/score_bar_fg.svg
new file mode 100644 (file)
index 0000000..9d351b8
--- /dev/null
@@ -0,0 +1,337 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://creativecommons.org/ns#"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:xlink="http://www.w3.org/1999/xlink"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   width="64"
+   height="256"
+   id="svg2"
+   sodipodi:version="0.32"
+   inkscape:version="0.46"
+   version="1.0"
+   sodipodi:docname="bar_fill.svg"
+   inkscape:output_extension="org.inkscape.output.svg.inkscape">
+  <defs
+     id="defs4">
+    <linearGradient
+       id="linearGradient2385">
+      <stop
+         style="stop-color:#808080;stop-opacity:1;"
+         offset="0"
+         id="stop2387" />
+      <stop
+         style="stop-color:#ffffff;stop-opacity:1;"
+         offset="1"
+         id="stop2389" />
+    </linearGradient>
+    <inkscape:perspective
+       sodipodi:type="inkscape:persp3d"
+       inkscape:vp_x="0 : 526.18109 : 1"
+       inkscape:vp_y="0 : 1000 : 0"
+       inkscape:vp_z="744.09448 : 526.18109 : 1"
+       inkscape:persp3d-origin="372.04724 : 350.78739 : 1"
+       id="perspective10" />
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient2385"
+       id="linearGradient2391"
+       x1="33.554657"
+       y1="258.01822"
+       x2="33.554657"
+       y2="-0.98177975"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(0.9544661,0,0,0.9886165,-2.6779771e-2,0.9447589)" />
+    <clipPath
+       clipPathUnits="userSpaceOnUse"
+       id="clipPath3476">
+      <rect
+         style="opacity:1;fill:url(#linearGradient3480);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2.9141736;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-opacity:1;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+         id="rect3478"
+         width="176.6787"
+         height="732.00079"
+         x="-208.22636"
+         y="72.247185"
+         ry="14.296889" />
+    </clipPath>
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient2385"
+       id="linearGradient3480"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(2.7606047,0,0,2.859378,-212.51815,70.765398)"
+       x1="33.554657"
+       y1="258.01822"
+       x2="33.554657"
+       y2="-0.98177975" />
+    <clipPath
+       clipPathUnits="userSpaceOnUse"
+       id="clipPath3482">
+      <rect
+         style="opacity:1;fill:url(#linearGradient3486);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2.9141736;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-opacity:1;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+         id="rect3484"
+         width="108.34083"
+         height="448.86887"
+         x="-47.562611"
+         y="52.756752"
+         ry="8.7669697" />
+    </clipPath>
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient2385"
+       id="linearGradient3486"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(1.6928254,0,0,1.753394,-50.19437,51.848108)"
+       x1="33.554657"
+       y1="258.01822"
+       x2="33.554657"
+       y2="-0.98177975" />
+    <clipPath
+       clipPathUnits="userSpaceOnUse"
+       id="clipPath3488">
+      <rect
+         style="opacity:1;fill:url(#linearGradient3492);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2.9141736;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-opacity:1;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+         id="rect3490"
+         width="84.279854"
+         height="349.1814"
+         x="-164.00085"
+         y="7.1028223"
+         ry="6.8199492"
+         transform="matrix(0.9492114,-0.314639,0.314639,0.9492114,0,0)" />
+    </clipPath>
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient2385"
+       id="linearGradient3492"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(1.3168727,0,0,1.3639898,-166.04815,6.3959756)"
+       x1="33.554657"
+       y1="258.01822"
+       x2="33.554657"
+       y2="-0.98177975" />
+    <clipPath
+       clipPathUnits="userSpaceOnUse"
+       id="clipPath3494">
+      <rect
+         style="opacity:1;fill:url(#linearGradient3498);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2.9141736;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-opacity:1;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+         id="rect3496"
+         width="79.174919"
+         height="328.03107"
+         x="-45.36124"
+         y="-25.200241"
+         ry="6.4068561"
+         transform="matrix(0.997851,-6.5523259e-2,6.5523259e-2,0.997851,0,0)" />
+    </clipPath>
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient2385"
+       id="linearGradient3498"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(1.2371081,0,0,1.2813713,-47.284519,-25.864273)"
+       x1="33.554657"
+       y1="258.01822"
+       x2="33.554657"
+       y2="-0.98177975" />
+    <clipPath
+       clipPathUnits="userSpaceOnUse"
+       id="clipPath3500">
+      <rect
+         style="opacity:1;fill:url(#linearGradient3504);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2.9141736;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-opacity:1;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+         id="rect3502"
+         width="73.717499"
+         height="305.42035"
+         x="-141.34662"
+         y="-77.569504"
+         ry="5.9652405"
+         transform="matrix(0.9657312,-0.2595445,0.2595445,0.9657312,0,0)" />
+    </clipPath>
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient2385"
+       id="linearGradient3504"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(1.151836,0,0,1.1930482,-143.13732,-78.187764)"
+       x1="33.554657"
+       y1="258.01822"
+       x2="33.554657"
+       y2="-0.98177975" />
+    <clipPath
+       clipPathUnits="userSpaceOnUse"
+       id="clipPath3506">
+      <rect
+         style="opacity:1;fill:url(#linearGradient3510);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2.9141736;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-opacity:1;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+         id="rect3508"
+         width="61.085831"
+         height="253.08583"
+         x="-150.72115"
+         y="-181.22908"
+         ry="4.9430823"
+         transform="matrix(0.5933644,-0.804934,0.804934,0.5933644,0,0)" />
+    </clipPath>
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient2385"
+       id="linearGradient3510"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(0.9544661,0,0,0.9886165,-152.20501,-181.74141)"
+       x1="33.554657"
+       y1="258.01822"
+       x2="33.554657"
+       y2="-0.98177975" />
+  </defs>
+  <sodipodi:namedview
+     id="base"
+     pagecolor="#ffffff"
+     bordercolor="#666666"
+     borderopacity="1.0"
+     gridtolerance="10000"
+     guidetolerance="10"
+     objecttolerance="10"
+     inkscape:pageopacity="0.0"
+     inkscape:pageshadow="2"
+     inkscape:zoom="2.4892738"
+     inkscape:cx="32.000002"
+     inkscape:cy="127.99999"
+     inkscape:document-units="px"
+     inkscape:current-layer="layer1"
+     showgrid="false"
+     inkscape:window-width="877"
+     inkscape:window-height="846"
+     inkscape:window-x="767"
+     inkscape:window-y="23" />
+  <metadata
+     id="metadata7">
+    <rdf:RDF>
+      <cc:Work
+         rdf:about="">
+        <dc:format>image/svg+xml</dc:format>
+        <dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+      </cc:Work>
+    </rdf:RDF>
+  </metadata>
+  <g
+     inkscape:label="Layer 1"
+     inkscape:groupmode="layer"
+     id="layer1">
+    <rect
+       style="opacity:1;fill:url(#linearGradient2391);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:3;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-opacity:1;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+       id="rect2383"
+       width="61.085831"
+       height="253.08583"
+       x="1.4570868"
+       y="1.4570796"
+       ry="4.9430823" />
+    <g
+       id="g3467"
+       transform="matrix(1.0029311,0,0,0.9897783,-9.3791356e-2,2.6018796)">
+      <path
+         sodipodi:type="star"
+         style="opacity:1;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:3;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-opacity:1;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+         id="path2415"
+         sodipodi:sides="5"
+         sodipodi:cx="-33.711109"
+         sodipodi:cy="140.88889"
+         sodipodi:r1="20.809898"
+         sodipodi:r2="41.619797"
+         sodipodi:arg1="0.97658264"
+         sodipodi:arg2="1.6049012"
+         inkscape:flatsided="false"
+         inkscape:rounded="0.1"
+         inkscape:randomized="0"
+         d="M -22.060534,158.13174 C -24.35061,159.67909 -32.368052,182.57872 -35.130272,182.48448 C -37.892492,182.39024 -44.330522,158.99741 -46.50981,157.29758 C -48.6891,155.59774 -72.945472,155.04908 -73.709416,152.39293 C -74.473359,149.73678 -54.214919,136.38507 -53.271717,133.78716 C -52.328515,131.18926 -59.302336,107.95053 -57.012259,106.40318 C -54.722183,104.85583 -35.763748,119.99685 -33.001528,120.09109 C -30.239308,120.18533 -10.292995,106.37167 -8.1137055,108.07151 C -5.9344165,109.77134 -14.4759,132.48071 -13.711956,135.13686 C -12.948012,137.79301 6.3533084,152.49443 5.4101064,155.09233 C 4.4669044,157.69024 -19.770457,156.58439 -22.060534,158.13174 z"
+         transform="matrix(0.5933644,0.804934,-0.804934,0.5933644,152.17823,182.68617)"
+         clip-path="url(#clipPath3506)" />
+      <path
+         sodipodi:type="star"
+         style="opacity:1;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:3;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-opacity:1;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+         id="path2417"
+         sodipodi:sides="5"
+         sodipodi:cx="-33.711109"
+         sodipodi:cy="140.88889"
+         sodipodi:r1="20.809898"
+         sodipodi:r2="41.619797"
+         sodipodi:arg1="0.97658264"
+         sodipodi:arg2="1.6049012"
+         inkscape:flatsided="false"
+         inkscape:rounded="0.1"
+         inkscape:randomized="0"
+         d="M -22.060534,158.13174 C -24.35061,159.67909 -32.368052,182.57872 -35.130272,182.48448 C -37.892492,182.39024 -44.330522,158.99741 -46.50981,157.29758 C -48.6891,155.59774 -72.945472,155.04908 -73.709416,152.39293 C -74.473359,149.73678 -54.214919,136.38507 -53.271717,133.78716 C -52.328515,131.18926 -59.302336,107.95053 -57.012259,106.40318 C -54.722183,104.85583 -35.763748,119.99685 -33.001528,120.09109 C -30.239308,120.18533 -10.292995,106.37167 -8.1137055,108.07151 C -5.9344165,109.77134 -14.4759,132.48071 -13.711956,135.13686 C -12.948012,137.79301 6.3533084,152.49443 5.4101064,155.09233 C 4.4669044,157.69024 -19.770457,156.58439 -22.060534,158.13174 z"
+         transform="matrix(0.8002508,0.2150709,-0.2150709,0.8002508,118.58362,65.734861)"
+         clip-path="url(#clipPath3500)" />
+      <path
+         sodipodi:type="star"
+         style="opacity:1;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:3;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-opacity:1;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+         id="path2419"
+         sodipodi:sides="5"
+         sodipodi:cx="-33.711109"
+         sodipodi:cy="140.88889"
+         sodipodi:r1="20.809898"
+         sodipodi:r2="41.619797"
+         sodipodi:arg1="0.97658264"
+         sodipodi:arg2="1.6049012"
+         inkscape:flatsided="false"
+         inkscape:rounded="0.1"
+         inkscape:randomized="0"
+         d="M -22.060534,158.13174 C -24.35061,159.67909 -32.368052,182.57872 -35.130272,182.48448 C -37.892492,182.39024 -44.330522,158.99741 -46.50981,157.29758 C -48.6891,155.59774 -72.945472,155.04908 -73.709416,152.39293 C -74.473359,149.73678 -54.214919,136.38507 -53.271717,133.78716 C -52.328515,131.18926 -59.302336,107.95053 -57.012259,106.40318 C -54.722183,104.85583 -35.763748,119.99685 -33.001528,120.09109 C -30.239308,120.18533 -10.292995,106.37167 -8.1137055,108.07151 C -5.9344165,109.77134 -14.4759,132.48071 -13.711956,135.13686 C -12.948012,137.79301 6.3533084,152.49443 5.4101064,155.09233 C 4.4669044,157.69024 -19.770457,156.58439 -22.060534,158.13174 z"
+         transform="matrix(0.7698721,5.0553166e-2,-5.0553166e-2,0.7698721,36.454649,20.899824)"
+         clip-path="url(#clipPath3494)" />
+      <path
+         sodipodi:type="star"
+         style="opacity:1;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:3;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-opacity:1;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+         id="path2421"
+         sodipodi:sides="5"
+         sodipodi:cx="-33.711109"
+         sodipodi:cy="140.88889"
+         sodipodi:r1="20.809898"
+         sodipodi:r2="41.619797"
+         sodipodi:arg1="0.97658264"
+         sodipodi:arg2="1.6049012"
+         inkscape:flatsided="false"
+         inkscape:rounded="0.1"
+         inkscape:randomized="0"
+         d="M -22.060534,158.13174 C -24.35061,159.67909 -32.368052,182.57872 -35.130272,182.48448 C -37.892492,182.39024 -44.330522,158.99741 -46.50981,157.29758 C -48.6891,155.59774 -72.945472,155.04908 -73.709416,152.39293 C -74.473359,149.73678 -54.214919,136.38507 -53.271717,133.78716 C -52.328515,131.18926 -59.302336,107.95053 -57.012259,106.40318 C -54.722183,104.85583 -35.763748,119.99685 -33.001528,120.09109 C -30.239308,120.18533 -10.292995,106.37167 -8.1137055,108.07151 C -5.9344165,109.77134 -14.4759,132.48071 -13.711956,135.13686 C -12.948012,137.79301 6.3533084,152.49443 5.4101064,155.09233 C 4.4669044,157.69024 -19.770457,156.58439 -22.060534,158.13174 z"
+         transform="matrix(0.6879861,0.2280496,-0.2280496,0.6879861,120.32451,-3.6910286)"
+         clip-path="url(#clipPath3488)" />
+      <path
+         sodipodi:type="star"
+         style="opacity:1;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:3;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-opacity:1;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+         id="path2423"
+         sodipodi:sides="5"
+         sodipodi:cx="-33.711109"
+         sodipodi:cy="140.88889"
+         sodipodi:r1="20.809898"
+         sodipodi:r2="41.619797"
+         sodipodi:arg1="0.97658264"
+         sodipodi:arg2="1.6049012"
+         inkscape:flatsided="false"
+         inkscape:rounded="0.1"
+         inkscape:randomized="0"
+         d="M -22.060534,158.13174 C -24.35061,159.67909 -32.368052,182.57872 -35.130272,182.48448 C -37.892492,182.39024 -44.330522,158.99741 -46.50981,157.29758 C -48.6891,155.59774 -72.945472,155.04908 -73.709416,152.39293 C -74.473359,149.73678 -54.214919,136.38507 -53.271717,133.78716 C -52.328515,131.18926 -59.302336,107.95053 -57.012259,106.40318 C -54.722183,104.85583 -35.763748,119.99685 -33.001528,120.09109 C -30.239308,120.18533 -10.292995,106.37167 -8.1137055,108.07151 C -5.9344165,109.77134 -14.4759,132.48071 -13.711956,135.13686 C -12.948012,137.79301 6.3533084,152.49443 5.4101064,155.09233 C 4.4669044,157.69024 -19.770457,156.58439 -22.060534,158.13174 z"
+         transform="matrix(0.5638302,0,0,0.5638302,28.274322,-28.28877)"
+         clip-path="url(#clipPath3482)" />
+      <path
+         transform="matrix(0.3457453,0,0,0.3457453,73.450372,-23.522045)"
+         d="M -22.060534,158.13174 C -24.35061,159.67909 -32.368052,182.57872 -35.130272,182.48448 C -37.892492,182.39024 -44.330522,158.99741 -46.50981,157.29758 C -48.6891,155.59774 -72.945472,155.04908 -73.709416,152.39293 C -74.473359,149.73678 -54.214919,136.38507 -53.271717,133.78716 C -52.328515,131.18926 -59.302336,107.95053 -57.012259,106.40318 C -54.722183,104.85583 -35.763748,119.99685 -33.001528,120.09109 C -30.239308,120.18533 -10.292995,106.37167 -8.1137055,108.07151 C -5.9344165,109.77134 -14.4759,132.48071 -13.711956,135.13686 C -12.948012,137.79301 6.3533084,152.49443 5.4101064,155.09233 C 4.4669044,157.69024 -19.770457,156.58439 -22.060534,158.13174 z"
+         inkscape:randomized="0"
+         inkscape:rounded="0.1"
+         inkscape:flatsided="false"
+         sodipodi:arg2="1.6049012"
+         sodipodi:arg1="0.97658264"
+         sodipodi:r2="41.619797"
+         sodipodi:r1="20.809898"
+         sodipodi:cy="140.88889"
+         sodipodi:cx="-33.711109"
+         sodipodi:sides="5"
+         id="path2413"
+         style="opacity:1;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:3;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-opacity:1;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+         sodipodi:type="star"
+         clip-path="url(#clipPath3476)" />
+    </g>
+  </g>
+</svg>
diff --git a/data/themes/default/score_level.svg b/data/themes/default/score_level.svg
new file mode 100644 (file)
index 0000000..48fd6b3
--- /dev/null
@@ -0,0 +1,61 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Sodipodi ("http://www.sodipodi.com/") -->
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://creativecommons.org/ns#"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   version="1.0"
+   x="0"
+   y="0"
+   width="800.000000"
+   height="600.000000"
+   id="svg559"
+   sodipodi:version="0.32"
+   inkscape:version="0.46"
+   sodipodi:docname="score_level.svg"
+   sodipodi:docbase="/home/yoda/UltraStar/sf/UltraStar-ng/themes/lima"
+   inkscape:output_extension="org.inkscape.output.svg.inkscape">
+  <metadata
+     id="metadata35">
+    <rdf:RDF>
+      <cc:Work
+         rdf:about="">
+        <dc:format>image/svg+xml</dc:format>
+        <dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+      </cc:Work>
+    </rdf:RDF>
+  </metadata>
+  <sodipodi:namedview
+     inkscape:window-height="797"
+     inkscape:window-width="1267"
+     inkscape:pageshadow="2"
+     inkscape:pageopacity="0.0"
+     guidetolerance="10.0"
+     gridtolerance="10.0"
+     objecttolerance="10.0"
+     borderopacity="1.0"
+     bordercolor="#666666"
+     pagecolor="#ffffff"
+     id="base"
+     inkscape:zoom="1.2233333"
+     inkscape:cx="400"
+     inkscape:cy="300"
+     inkscape:window-x="0"
+     inkscape:window-y="25"
+     inkscape:current-layer="svg559"
+     showgrid="false" />
+  <defs
+     id="defs561" />
+  <rect
+     style="opacity:1;fill:#000000;fill-opacity:0.69350648;stroke:#323232;stroke-width:2;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+     id="rect2174"
+     width="120.25723"
+     height="298.035"
+     x="108.52218"
+     y="279.1571" />
+</svg>
diff --git a/data/themes/default/score_rank.svg b/data/themes/default/score_rank.svg
new file mode 100644 (file)
index 0000000..06f3c43
--- /dev/null
@@ -0,0 +1,75 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Sodipodi ("http://www.sodipodi.com/") -->
+
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://creativecommons.org/ns#"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   version="1.0"
+   x="0"
+   y="0"
+   width="800.000000"
+   height="600.000000"
+   id="svg559"
+   sodipodi:version="0.32"
+   inkscape:version="0.48.4 r9939"
+   sodipodi:docname="score_rank.svg"
+   inkscape:output_extension="org.inkscape.output.svg.inkscape"
+   sodipodi:modified="true">
+  <metadata
+     id="metadata35">
+    <rdf:RDF>
+      <cc:Work
+         rdf:about="">
+        <dc:format>image/svg+xml</dc:format>
+        <dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+      </cc:Work>
+    </rdf:RDF>
+  </metadata>
+  <sodipodi:namedview
+     inkscape:window-height="879"
+     inkscape:window-width="1531"
+     inkscape:pageshadow="2"
+     inkscape:pageopacity="0.0"
+     guidetolerance="10.0"
+     gridtolerance="10.0"
+     objecttolerance="10.0"
+     borderopacity="1.0"
+     bordercolor="#666666"
+     pagecolor="#ffffff"
+     id="base"
+     inkscape:zoom="1.26"
+     inkscape:cx="285.76321"
+     inkscape:cy="363.49206"
+     inkscape:window-x="168"
+     inkscape:window-y="122"
+     inkscape:current-layer="svg559"
+     showgrid="false"
+     inkscape:window-maximized="0" />
+  <defs
+     id="defs561">
+    <inkscape:perspective
+       sodipodi:type="inkscape:persp3d"
+       inkscape:vp_x="0 : 300 : 1"
+       inkscape:vp_y="0 : 1000 : 0"
+       inkscape:vp_z="800 : 300 : 1"
+       inkscape:persp3d-origin="400 : 200 : 1"
+       id="perspective8" />
+  </defs>
+  <text
+     x="400"
+     y="119.71297"
+     style="font-size:70px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;text-align:center;line-height:125%;writing-mode:lr-tb;text-anchor:middle;fill:#ffd100;fill-opacity:1;stroke:#000000;stroke-width:1.58534133;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;display:inline;font-family:Goblin"
+     id="text10203"
+     xml:space="preserve"
+     sodipodi:linespacing="125%"><tspan
+       x="400"
+       y="119.71297"
+       id="tspan10205"
+       style="font-size:70px;text-align:center;text-anchor:middle;fill:#ffd100;fill-opacity:1;stroke-width:1.58534133">Lead Singer</tspan></text>
+</svg>
diff --git a/data/themes/default/score_txt.svg b/data/themes/default/score_txt.svg
new file mode 100644 (file)
index 0000000..4ddcce5
--- /dev/null
@@ -0,0 +1,75 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Sodipodi ("http://www.sodipodi.com/") -->
+
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://creativecommons.org/ns#"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   version="1.0"
+   x="0"
+   y="0"
+   width="800.000000"
+   height="600.000000"
+   id="svg559"
+   sodipodi:version="0.32"
+   inkscape:version="0.48.4 r9939"
+   sodipodi:docname="score_txt.svg"
+   inkscape:output_extension="org.inkscape.output.svg.inkscape"
+   sodipodi:modified="true">
+  <metadata
+     id="metadata35">
+    <rdf:RDF>
+      <cc:Work
+         rdf:about="">
+        <dc:format>image/svg+xml</dc:format>
+        <dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+      </cc:Work>
+    </rdf:RDF>
+  </metadata>
+  <sodipodi:namedview
+     inkscape:window-height="797"
+     inkscape:window-width="1280"
+     inkscape:pageshadow="2"
+     inkscape:pageopacity="0.0"
+     guidetolerance="10.0"
+     gridtolerance="10.0"
+     objecttolerance="10.0"
+     borderopacity="1.0"
+     bordercolor="#666666"
+     pagecolor="#ffffff"
+     id="base"
+     inkscape:zoom="1.26"
+     inkscape:cx="400"
+     inkscape:cy="268.25397"
+     inkscape:window-x="5"
+     inkscape:window-y="73"
+     inkscape:current-layer="svg559"
+     showgrid="false"
+     inkscape:window-maximized="0" />
+  <defs
+     id="defs561">
+    <inkscape:perspective
+       sodipodi:type="inkscape:persp3d"
+       inkscape:vp_x="0 : 300 : 1"
+       inkscape:vp_y="0 : 1000 : 0"
+       inkscape:vp_z="800 : 300 : 1"
+       inkscape:persp3d-origin="400 : 200 : 1"
+       id="perspective8" />
+  </defs>
+  <text
+     x="277.86353"
+     y="317.25027"
+     style="font-size:30px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;text-align:start;line-height:125%;writing-mode:lr-tb;text-anchor:start;opacity:1;fill:#ffffff;fill-opacity:1;stroke:#000000;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;display:inline;font-family:Goblin"
+     id="text10203"
+     xml:space="preserve"
+     sodipodi:linespacing="125%"><tspan
+       x="277.86353"
+       y="317.25027"
+       id="tspan10205"
+       style="fill:#ff7f2a;fill-opacity:1;font-size:30px">A#</tspan></text>
+</svg>
diff --git a/data/themes/default/score_window.svg b/data/themes/default/score_window.svg
new file mode 100644 (file)
index 0000000..29b42cf
--- /dev/null
@@ -0,0 +1,115 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Sodipodi ("http://www.sodipodi.com/") -->
+
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://creativecommons.org/ns#"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:xlink="http://www.w3.org/1999/xlink"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   version="1.0"
+   x="0"
+   y="0"
+   width="800.000000"
+   height="600.000000"
+   id="svg559"
+   sodipodi:version="0.32"
+   inkscape:version="0.48.4 r9939"
+   sodipodi:docname="score_window.svg"
+   inkscape:output_extension="org.inkscape.output.svg.inkscape">
+  <metadata
+     id="metadata35">
+    <rdf:RDF>
+      <cc:Work
+         rdf:about="">
+        <dc:format>image/svg+xml</dc:format>
+        <dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+      </cc:Work>
+    </rdf:RDF>
+  </metadata>
+  <sodipodi:namedview
+     inkscape:window-height="908"
+     inkscape:window-width="1487"
+     inkscape:pageshadow="2"
+     inkscape:pageopacity="0"
+     guidetolerance="10.0"
+     gridtolerance="10.0"
+     objecttolerance="10.0"
+     borderopacity="1.0"
+     bordercolor="#666666"
+     pagecolor="#ffffff"
+     id="base"
+     inkscape:zoom="1.1826361"
+     inkscape:cx="400.527"
+     inkscape:cy="360.08523"
+     inkscape:window-x="212"
+     inkscape:window-y="75"
+     inkscape:current-layer="svg559"
+     showgrid="false"
+     inkscape:window-maximized="0" />
+  <defs
+     id="defs561">
+    <inkscape:perspective
+       sodipodi:type="inkscape:persp3d"
+       inkscape:vp_x="0 : 300 : 1"
+       inkscape:vp_y="0 : 1000 : 0"
+       inkscape:vp_z="800 : 300 : 1"
+       inkscape:persp3d-origin="400 : 200 : 1"
+       id="perspective2513" />
+    <linearGradient
+       id="linearGradient3751"
+       inkscape:collect="always">
+      <stop
+         id="stop3753"
+         offset="0"
+         style="stop-color:black;stop-opacity:1;" />
+      <stop
+         id="stop3755"
+         offset="1"
+         style="stop-color:black;stop-opacity:0;" />
+    </linearGradient>
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient3751"
+       id="linearGradient2391"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(0.755727,0,0,0.755727,-21.47999,-0.08973963)"
+       x1="665.12128"
+       y1="684.16162"
+       x2="381.28015"
+       y2="449.80624" />
+  </defs>
+  <rect
+     style="fill:#ffffff;fill-opacity:0.74766355;stroke:#000000;stroke-width:1.37750208;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+     id="rect2383"
+     width="665.36389"
+     height="441.10852"
+     x="67.317955"
+     y="79.44574"
+     rx="30.002518"
+     ry="27.710554" />
+  <g
+     id="g2386"
+     transform="translate(64.263217,-9.3473116)">
+    <path
+       style="opacity:0.22790701;fill:url(#linearGradient2391);fill-opacity:1;fill-rule:evenodd;stroke:none"
+       d="m 277.79837,408.27854 -10.90046,0 2.92777,2.14176 7.79864,2.35593 5.03927,2.57011 -8.51485,-1.28506 -12.02188,-3.21262 -11.30847,-0.85671 -7.39064,-1.49923 -11.7508,-1.49923 -23.56727,-5.99692 -6.09509,-2.78428 6.54596,-6.85362 15.49739,1.92758 5.21059,1.49923 4.08621,1.7134 6.30058,1.49924 6.98261,0.64252 0.75036,-1.28506 -3.03039,-1.49922 -4.69979,-1.28506 -4.80242,-0.64252 -4.73402,-1.07088 2.86209,-0.8567 -6.19787,-2.14176 -3.06463,-1.28506 -6.3348,-1.28505 -6.2321,-1.92758 -8.0726,-0.64253 -6.47182,-0.42835 -3.7837,3.21264 -18.15982,4.49769 -0.41089,2.5701 -1.3297,1.49923 7.08245,3.42681 6.26633,1.71341 19.24134,5.78274 19.85476,5.35439 16.82438,3.85516 6.3976,7.71032 13.95662,11.56549 4.08342,5.14021 2.20869,6.63945 6.60596,2.99846 -0.956,2.57011 20.09448,3.85517 8.00134,4.49768 25.09671,10.06626 32.48734,11.56548 29.42272,10.28044 13.62266,3.4268 22.44298,6.2111 28.84617,7.0678 13.99652,4.49767 10.93189,3.21264 2.95905,5.35439 -10.80055,2.78428 3.47287,2.14178 32.22473,-0.42835 3.26731,3.42679 11.10299,2.14176 17.33796,0.64253 2.31986,-4.28352 -9.94159,-5.9969 -5.17348,-5.14023 1.56942,-2.99845 -5.44743,-3.42681 -9.77609,-0.21418 0.37666,-2.35594 -8.41502,1.49924 0.54782,-3.42681 -8.0726,-0.64253 -10.52372,-2.35593 -24.0096,-6.63945 -33.88839,-6.21109 -4.83672,-0.42835 0.75051,-1.28506 -9.22834,-3.64098 -3.84657,-3.21264 -2.75931,0.21418 -3.70956,-4.06934 -9.7049,-4.06934 -1.29267,-2.14176 -6.64012,-2.78428 -2.04031,-4.28351 -8.1382,-3.64098 -8.786,-2.99847 -4.35737,-3.4268 -2.27996,-2.78429 -4.08629,-1.7134 4.39448,-0.21418 0.27387,-1.7134 -6.4004,-4.28351 -0.47377,-3.85517 6.77993,-1.49923 11.64802,2.14175 20.40274,1.92759 18.6648,2.5701 13.14617,2.99847 11.37694,0.42835 45.98161,5.56856 22.51424,2.35594 23.33035,4.06934 2.24866,-0.42836 -3.0647,-1.28505 -13.24895,-2.35593 18.29109,1.49922 -0.91889,-1.07087 -6.33473,-1.28505 5.45015,0 -2.51959,-1.28506 -11.85358,-0.8567 5.58717,-0.8567 -3.5755,-1.49924 -3.2358,-0.21417 -7.66458,0.21417 -9.09412,-1.07087 -6.40335,-0.85671 1.43248,-2.14175 -1.9404,-1.49923 -3.64396,-1.07089 -4.97367,0.42836 -6.40615,2.5701 1.42961,1.28506 -5.38168,-0.42835 -23.97816,-3.42681 -6.16356,-2.35593 -13.86238,-1.92759 -23.46736,-3.21263 -1.26123,1.07088 -3.03047,-1.49923 -16.38204,-3.21264 -9.67338,-0.85669 -14.74703,-3.21265 -4.73395,-1.07087 11.68225,1.92758 -6.19779,-2.14176 8.00405,1.07088 -9.2968,-3.21263 14.27047,2.78428 -7.86712,-1.92758 10.69498,1.28505 -15.22352,-3.64098 6.43751,0.64253 -10.35255,-3.42682 6.87983,1.28506 -13.11194,-3.21264 6.98254,0.64253 -11.03459,-2.57011 6.02949,-0.21418 -11.17146,-1.7134 2.31698,-0.8567 -5.41591,-0.21418 0.9216,-2.35593 -5.48438,0.21417 -3.03047,-1.49922 -9.67058,-4.28352 3.88081,2.99846 -14.03075,-4.28351 8.71746,3.42681 -1.66933,0.21418 -5.45015,0 -14.16776,-3.42681 -5.99526,0 -12.70377,-2.35593 -0.20556,1.28504 -3.06742,2.14176 z"
+       id="path2864"
+       inkscape:connector-curvature="0" />
+    <path
+       id="path1939"
+       d="m 562.76779,223.0222 -10.8932,0 -2.17861,5.44657 2.17861,5.99123 -1.08931,6.53589 -5.44652,-3.26795 -4.35722,-8.16985 -9.25925,-2.17864 -3.81256,-3.81259 -8.16987,-3.81261 -9.25916,-15.2504 0.54465,-7.08055 22.87563,-17.42903 10.89305,4.90191 1.63403,3.81261 0,4.35726 2.72326,3.81259 5.4466,1.63398 3.81257,-3.26795 0.54465,-3.8126 -1.63395,-3.26794 -3.26792,-1.63397 -2.17868,-2.72329 4.90194,-2.17862 -1.0893,-5.44658 0,-3.26795 -3.26792,-3.26794 -1.63403,-4.90191 -6.53583,-1.63397 -5.4466,-1.08932 -11.43785,8.16986 -28.86681,11.43781 -6.5359,6.53588 -4.90187,3.8126 -1.08939,8.71452 2.17869,4.35726 5.4466,14.70574 7.08048,13.61643 7.62521,9.80383 -11.98243,19.60767 -13.61646,29.41149 -8.16986,13.07177 -13.61639,16.88438 -0.54465,7.62521 -7.08056,6.53588 10.89313,9.80384 -2.72327,11.43779 1.08931,25.5989 4.90187,29.41149 4.90195,26.14356 5.44652,8.71451 7.62529,15.79506 11.98243,17.97369 3.26791,11.43777 3.26799,8.16987 -9.80389,13.61643 -17.42903,7.08055 -1.63396,5.44661 33.2241,-1.08931 -4.90187,8.71449 5.99118,5.44656 15.79507,1.634 12.52716,-10.89317 4.35729,-15.25037 7.08048,-13.07179 8.71452,-7.62519 2.72326,-8.71454 -9.25909,-0.54465 5.99118,-5.99124 -11.98243,3.81261 8.71451,-8.71452 -6.5359,-1.63397 -4.90195,-5.99123 -8.16986,-16.88438 -19.06299,-15.79506 -3.81257,-1.08931 3.81257,-3.26795 -0.54465,-9.25917 3.81264,-8.16986 -3.26799,0.54466 5.99125,-10.34849 0,-10.34849 3.81257,-5.44657 0,-7.08055 8.16986,-10.89315 0.54473,-9.25916 -1.63403,-7.62521 3.81264,-8.71452 4.35722,-7.08054 0,-4.35726 4.90195,-0.54465 4.35722,-4.35726 3.81264,-10.89314 8.71451,-9.80384 10.34848,-3.8126 6.53582,5.44657 15.79515,4.90192 12.52708,6.53588 5.99118,7.62521 10.34847,1.08931 32.67953,14.16109 16.8843,5.99124 13.61646,10.34848 3.26799,-1.08932 0,-3.26794 -7.62521,-5.99122 14.70569,3.81259 1.63404,-2.72329 -3.26799,-3.26793 5.4466,0 0.54465,-3.26795 -9.80382,-2.17863 7.62513,-2.17863 0,-3.8126 -2.72326,-0.54465 -8.16986,0.54465 -6.53583,-2.72329 -4.35729,-2.17862 6.5359,-5.44658 1.63396,-3.8126 -1.08931,-2.72329 -5.99117,1.08932 -12.52724,6.53588 -1.63388,3.26795 -4.35729,-1.08931 -15.79508,-8.71452 -0.54465,-5.99123 -9.25917,-4.90192 -15.79507,-8.16986 -3.81257,2.72329 0.54466,-3.8126 -8.71452,-8.16986 -7.62521,-2.17863 -7.08056,-8.16986 -2.1786,-2.72329 7.08055,4.90192 -1.0893,-5.44658 5.44652,2.72329 -1.63396,-8.16986 7.62521,7.08055 -3.26791,-4.90191 7.62513,3.26793 -6.53583,-9.25916 4.90188,1.63397 -2.17861,-8.71452 3.81256,3.26794 -5.44652,-8.16986 5.44652,1.63397 -4.90187,-6.53588 6.53583,-0.54466 -7.08048,-4.35726 4.35722,-2.17862 -4.90187,-0.54467 6.53583,-5.99122 -5.99118,0.54465 0.54465,-3.8126 0.54465,-10.89314 -3.26791,7.6252 -3.81264,-10.89315 0.54465,8.71452 -2.17861,0.54466 -5.4466,0 -5.99125,-8.71452 -5.99118,0 -7.08056,-5.99123 -3.26799,3.26794 -8.16978,5.44658 z"
+       style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:0.5391832px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+       inkscape:connector-curvature="0" />
+    <path
+       sodipodi:nodetypes="cccc"
+       id="path3759"
+       d="m 537.51011,167.72564 c -21.32518,-7.88231 -32.78336,21.65136 -25.75888,38.1759 2.53041,20.85981 2.98384,42.75852 -2.54173,63.05637 -10.4013,10.91035 -37.39557,17.90502 -37.00765,36.2146"
+       style="fill:none;stroke:#ffffff;stroke-width:1.28473592;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+       inkscape:connector-curvature="0" />
+  </g>
+</svg>
diff --git a/data/themes/default/sing-songinfo.svg b/data/themes/default/sing-songinfo.svg
new file mode 100644 (file)
index 0000000..a3f2a7b
--- /dev/null
@@ -0,0 +1,76 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://creativecommons.org/ns#"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   version="1.0"
+   width="1000"
+   height="800"
+   id="svg3465"
+   sodipodi:version="0.32"
+   inkscape:version="0.48.4 r9939"
+   sodipodi:docname="sing-songinfo.svg"
+   inkscape:output_extension="org.inkscape.output.svg.inkscape">
+  <metadata
+     id="metadata3115">
+    <rdf:RDF>
+      <cc:Work
+         rdf:about="">
+        <dc:format>image/svg+xml</dc:format>
+        <dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+        <dc:title />
+      </cc:Work>
+    </rdf:RDF>
+  </metadata>
+  <sodipodi:namedview
+     inkscape:window-height="1056"
+     inkscape:window-width="1920"
+     inkscape:pageshadow="2"
+     inkscape:pageopacity="0.0"
+     guidetolerance="10.0"
+     gridtolerance="10.0"
+     objecttolerance="10.0"
+     borderopacity="1.0"
+     bordercolor="#666666"
+     pagecolor="#ffffff"
+     id="base"
+     showgrid="false"
+     inkscape:zoom="10.82"
+     inkscape:cx="14.619393"
+     inkscape:cy="58.017773"
+     inkscape:window-x="0"
+     inkscape:window-y="24"
+     inkscape:current-layer="svg3465"
+     inkscape:window-maximized="1" />
+  <defs
+     id="defs3467">
+    <inkscape:perspective
+       sodipodi:type="inkscape:persp3d"
+       inkscape:vp_x="0 : 300 : 1"
+       inkscape:vp_y="0 : 1000 : 0"
+       inkscape:vp_z="800 : 300 : 1"
+       inkscape:persp3d-origin="400 : 200 : 1"
+       id="perspective9" />
+  </defs>
+  <text
+     sodipodi:linespacing="125%"
+     xml:space="preserve"
+     id="timer_text"
+     style="font-size:6.53677082px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;text-align:start;line-height:125%;text-anchor:start;fill:#ffffff;fill-opacity:1;stroke:#000000;stroke-width:0.18157697;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;display:inline;font-family:Droid Sans Mono"
+     y="855.92041"
+     x="5.7089458"
+     transform="scale(1.1354379,0.8807175)"><tspan
+       id="tspan4717"
+       y="857.18573"
+       x="5.7089458"
+       style="font-size:7.26307869px;text-align:start;text-anchor:start;fill:#ffffff;fill-opacity:1;stroke:#000000;stroke-width:0.18157697;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none">00:00</tspan></text>
+  <!--       style="font-size:25px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;text-align:start;line-height:125%;writing-mode:lr-tb;text-anchor:start;opacity:1;fill:black;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:0.56078384;display:inline;font-family:Droid Sans Mono"
+-->
+</svg>
diff --git a/data/themes/default/sing_bg_bottom.svg b/data/themes/default/sing_bg_bottom.svg
new file mode 100644 (file)
index 0000000..d133e4e
--- /dev/null
@@ -0,0 +1,694 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://creativecommons.org/ns#"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:xlink="http://www.w3.org/1999/xlink"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   version="1.0"
+   width="1000"
+   height="230"
+   id="svg3465"
+   sodipodi:version="0.32"
+   inkscape:version="0.46"
+   sodipodi:docname="sing_bg_bottom.svg"
+   sodipodi:docbase="/root/USNG/trunk/themes/lima"
+   inkscape:output_extension="org.inkscape.output.svg.inkscape">
+  <metadata
+     id="metadata30">
+    <rdf:RDF>
+      <cc:Work
+         rdf:about="">
+        <dc:format>image/svg+xml</dc:format>
+        <dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+      </cc:Work>
+    </rdf:RDF>
+  </metadata>
+  <sodipodi:namedview
+     inkscape:cy="115"
+     inkscape:cx="434.23317"
+     inkscape:zoom="0.30370236"
+     inkscape:window-height="726"
+     inkscape:window-width="960"
+     inkscape:pageshadow="2"
+     inkscape:pageopacity="0.0"
+     guidetolerance="10.0"
+     gridtolerance="10.0"
+     objecttolerance="10.0"
+     borderopacity="1.0"
+     bordercolor="#666666"
+     pagecolor="#ffffff"
+     id="base"
+     inkscape:window-x="21"
+     inkscape:window-y="92"
+     inkscape:current-layer="svg3465"
+     showgrid="false">
+    <inkscape:grid
+       type="xygrid"
+       id="grid2419"
+       visible="true"
+       enabled="true" />
+  </sodipodi:namedview>
+  <defs
+     id="defs3467">
+    <linearGradient
+       id="linearGradient6239">
+      <stop
+         style="stop-color:#414141;stop-opacity:1;"
+         offset="0"
+         id="stop6241" />
+      <stop
+         style="stop-color:#151515;stop-opacity:1;"
+         offset="1"
+         id="stop6243" />
+    </linearGradient>
+    <inkscape:perspective
+       sodipodi:type="inkscape:persp3d"
+       inkscape:vp_x="0 : 400 : 1"
+       inkscape:vp_y="0 : 1000 : 0"
+       inkscape:vp_z="1000 : 400 : 1"
+       inkscape:persp3d-origin="500 : 266.66667 : 1"
+       id="perspective57" />
+    <linearGradient
+       id="linearGradient3667">
+      <stop
+         style="stop-color:#000000;stop-opacity:1;"
+         offset="0"
+         id="stop3669" />
+      <stop
+         style="stop-color:#000000;stop-opacity:0;"
+         offset="1"
+         id="stop3671" />
+    </linearGradient>
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient3667"
+       id="linearGradient2549"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(1.2504205,0,0,1.1424679,-3.6234642e-2,-3.1313995)"
+       x1="365.07416"
+       y1="121.63737"
+       x2="365.07416"
+       y2="151.1951" />
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient3667"
+       id="linearGradient5768"
+       x1="551.00964"
+       y1="660.33606"
+       x2="551.00964"
+       y2="605.34015"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(1.0140491,0,0,0.8428048,-5.1350533,117.20059)" />
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient3667"
+       id="linearGradient3212"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(1.25042,0,0,1.5212915,-9.8590088e-8,-230.00001)"
+       x1="367.8764"
+       y1="131.46725"
+       x2="367.8764"
+       y2="151.18733" />
+    <radialGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient6239"
+       id="radialGradient6281"
+       cx="-52.682827"
+       cy="22.638672"
+       fx="-52.682827"
+       fy="22.638672"
+       r="139.13554"
+       gradientTransform="matrix(0.5485002,4.7588748e-2,-3.8008734e-2,0.486111,-22.925821,11.758401)"
+       gradientUnits="userSpaceOnUse"
+       spreadMethod="reflect" />
+    <radialGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient6239"
+       id="radialGradient6283"
+       cx="54.552696"
+       cy="61.81908"
+       fx="54.552696"
+       fy="61.81908"
+       r="85.972984"
+       gradientTransform="matrix(0.8491493,-0.5169578,0.3359319,0.5286533,-12.537687,75.354409)"
+       gradientUnits="userSpaceOnUse"
+       spreadMethod="reflect" />
+    <radialGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient6239"
+       id="radialGradient6285"
+       cx="-108.65945"
+       cy="46.669819"
+       fx="-108.65945"
+       fy="46.669819"
+       r="85.972984"
+       gradientTransform="matrix(1,0,0,1.2958795,0,-0.2762501)"
+       gradientUnits="userSpaceOnUse"
+       spreadMethod="reflect" />
+    <radialGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient6239"
+       id="radialGradient6287"
+       cx="-0.00043312719"
+       cy="0.93365741"
+       fx="-0.00043312719"
+       fy="0.93365741"
+       r="85.972984"
+       gradientTransform="matrix(0.7054225,-0.6154847,1,0.8642415,-0.933785,0.1264853)"
+       gradientUnits="userSpaceOnUse"
+       spreadMethod="reflect" />
+    <radialGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient6239"
+       id="radialGradient6289"
+       cx="-55.975525"
+       cy="110.75415"
+       fx="-55.975525"
+       fy="110.75415"
+       r="139.13554"
+       gradientTransform="matrix(0.4023117,1.7847586e-8,-2.8882931e-8,0.8902338,-33.455913,0.1024879)"
+       gradientUnits="userSpaceOnUse"
+       spreadMethod="reflect" />
+    <radialGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient6239"
+       id="radialGradient6291"
+       cx="-84.775795"
+       cy="102.82321"
+       fx="-84.775795"
+       fy="102.82321"
+       r="139.13554"
+       gradientTransform="matrix(0.609306,0,-1.7525848e-8,0.8902338,-33.121388,0.102488)"
+       gradientUnits="userSpaceOnUse"
+       spreadMethod="reflect" />
+    <radialGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient6239"
+       id="radialGradient6293"
+       cx="121.82938"
+       cy="29.891867"
+       fx="121.82938"
+       fy="29.891867"
+       r="85.972984"
+       gradientTransform="matrix(1,0,0,1.2958795,0,-0.2762501)"
+       gradientUnits="userSpaceOnUse"
+       spreadMethod="reflect" />
+    <radialGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient6239"
+       id="radialGradient6295"
+       cx="-54.119453"
+       cy="-33.586506"
+       fx="-54.119453"
+       fy="-33.586506"
+       r="85.972984"
+       gradientTransform="matrix(1,0,0,1.2958795,0,-0.2762501)"
+       gradientUnits="userSpaceOnUse"
+       spreadMethod="reflect" />
+    <radialGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient6239"
+       id="radialGradient6297"
+       cx="73.08477"
+       cy="-64.148376"
+       fx="73.08477"
+       fy="-64.148376"
+       r="139.13554"
+       gradientTransform="matrix(1.2783381,0.4169453,-0.272318,0.846931,-30.398528,-33.221331)"
+       gradientUnits="userSpaceOnUse"
+       spreadMethod="reflect" />
+    <filter
+       inkscape:collect="always"
+       id="filter6415">
+      <feGaussianBlur
+         inkscape:collect="always"
+         stdDeviation="5.5378501"
+         id="feGaussianBlur6417" />
+    </filter>
+    <filter
+       inkscape:collect="always"
+       id="filter6435">
+      <feGaussianBlur
+         inkscape:collect="always"
+         stdDeviation="5.8924159"
+         id="feGaussianBlur6437" />
+    </filter>
+    <filter
+       inkscape:collect="always"
+       id="filter6439">
+      <feGaussianBlur
+         inkscape:collect="always"
+         stdDeviation="6.8900544"
+         id="feGaussianBlur6441" />
+    </filter>
+    <radialGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient6239"
+       id="radialGradient6443"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(1,0,0,0.8902338,0,0.1024869)"
+       spreadMethod="reflect"
+       cx="0.00033175375"
+       cy="0.93368369"
+       fx="0.00033175375"
+       fy="0.93368369"
+       r="139.13554" />
+    <radialGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient6239"
+       id="radialGradient6445"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(1,0,0,0.8902338,0,0.1024869)"
+       spreadMethod="reflect"
+       cx="0.00033175375"
+       cy="0.93368369"
+       fx="0.00033175375"
+       fy="0.93368369"
+       r="139.13554" />
+    <radialGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient6239"
+       id="radialGradient6447"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(1,0,0,1.2958795,0,-0.2762501)"
+       spreadMethod="reflect"
+       cx="-0.00043312719"
+       cy="0.93365741"
+       fx="-0.00043312719"
+       fy="0.93365741"
+       r="85.972984" />
+    <radialGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient6239"
+       id="radialGradient6449"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(1,0,0,1.2958795,0,-0.2762501)"
+       spreadMethod="reflect"
+       cx="-0.00043312719"
+       cy="0.93365741"
+       fx="-0.00043312719"
+       fy="0.93365741"
+       r="85.972984" />
+    <radialGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient6239"
+       id="radialGradient6451"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(1,0,0,1.2958795,0,-0.2762501)"
+       spreadMethod="reflect"
+       cx="-0.00043312719"
+       cy="0.93365741"
+       fx="-0.00043312719"
+       fy="0.93365741"
+       r="85.972984" />
+    <radialGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient6239"
+       id="radialGradient6453"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(1,0,0,1.2958795,0,-0.2762501)"
+       spreadMethod="reflect"
+       cx="-0.00043312719"
+       cy="0.93365741"
+       fx="-0.00043312719"
+       fy="0.93365741"
+       r="85.972984" />
+    <radialGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient6239"
+       id="radialGradient6455"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(1,0,0,1.2958795,0,-0.2762501)"
+       spreadMethod="reflect"
+       cx="-0.00043312719"
+       cy="0.93365741"
+       fx="-0.00043312719"
+       fy="0.93365741"
+       r="85.972984" />
+    <radialGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient6239"
+       id="radialGradient6457"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(1,0,0,1.2958795,0,-0.2762501)"
+       spreadMethod="reflect"
+       cx="-0.00043312719"
+       cy="0.93365741"
+       fx="-0.00043312719"
+       fy="0.93365741"
+       r="85.972984" />
+    <radialGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient6239"
+       id="radialGradient6459"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(1,0,0,0.8902338,0,0.1024869)"
+       spreadMethod="reflect"
+       cx="0.00033175375"
+       cy="0.93368369"
+       fx="0.00033175375"
+       fy="0.93368369"
+       r="139.13554" />
+    <radialGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient6239"
+       id="radialGradient6461"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(1,0,0,0.8902338,0,0.1024869)"
+       spreadMethod="reflect"
+       cx="0.00033175375"
+       cy="0.93368369"
+       fx="0.00033175375"
+       fy="0.93368369"
+       r="139.13554" />
+    <radialGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient6239"
+       id="radialGradient6463"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(1,0,0,0.8902338,0,0.1024869)"
+       spreadMethod="reflect"
+       cx="0.00033175375"
+       cy="0.93368369"
+       fx="0.00033175375"
+       fy="0.93368369"
+       r="139.13554" />
+    <radialGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient6239"
+       id="radialGradient6465"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(1,0,0,0.8902338,0,0.1024869)"
+       spreadMethod="reflect"
+       cx="0.00033175375"
+       cy="0.93368369"
+       fx="0.00033175375"
+       fy="0.93368369"
+       r="139.13554" />
+    <radialGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient6239"
+       id="radialGradient6467"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(1,0,0,1.2958795,0,-0.2762501)"
+       spreadMethod="reflect"
+       cx="-0.00043312719"
+       cy="0.93365741"
+       fx="-0.00043312719"
+       fy="0.93365741"
+       r="85.972984" />
+    <radialGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient6239"
+       id="radialGradient6469"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(1,0,0,1.2958795,0,-0.2762501)"
+       spreadMethod="reflect"
+       cx="-0.00043312719"
+       cy="0.93365741"
+       fx="-0.00043312719"
+       fy="0.93365741"
+       r="85.972984" />
+    <radialGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient6239"
+       id="radialGradient6471"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(1,0,0,1.2958795,0,-0.2762501)"
+       spreadMethod="reflect"
+       cx="-0.00043312719"
+       cy="0.93365741"
+       fx="-0.00043312719"
+       fy="0.93365741"
+       r="85.972984" />
+    <radialGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient6239"
+       id="radialGradient6473"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(1,0,0,1.2958795,0,-0.2762501)"
+       spreadMethod="reflect"
+       cx="-0.00043312719"
+       cy="0.93365741"
+       fx="-0.00043312719"
+       fy="0.93365741"
+       r="85.972984" />
+    <radialGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient6239"
+       id="radialGradient6475"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(1,0,0,0.8902338,0,0.1024869)"
+       spreadMethod="reflect"
+       cx="0.00033175375"
+       cy="0.93368369"
+       fx="0.00033175375"
+       fy="0.93368369"
+       r="139.13554" />
+    <radialGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient6239"
+       id="radialGradient6477"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(1,0,0,0.8902338,0,0.1024869)"
+       spreadMethod="reflect"
+       cx="0.00033175375"
+       cy="0.93368369"
+       fx="0.00033175375"
+       fy="0.93368369"
+       r="139.13554" />
+    <filter
+       inkscape:collect="always"
+       id="filter6529">
+      <feGaussianBlur
+         inkscape:collect="always"
+         stdDeviation="4.8307749"
+         id="feGaussianBlur6531" />
+    </filter>
+    <filter
+       inkscape:collect="always"
+       id="filter6557">
+      <feGaussianBlur
+         inkscape:collect="always"
+         stdDeviation="6.374635"
+         id="feGaussianBlur6559" />
+    </filter>
+    <filter
+       inkscape:collect="always"
+       id="filter6593">
+      <feGaussianBlur
+         inkscape:collect="always"
+         stdDeviation="3.9535839"
+         id="feGaussianBlur6595" />
+    </filter>
+    <filter
+       inkscape:collect="always"
+       id="filter6609">
+      <feGaussianBlur
+         inkscape:collect="always"
+         stdDeviation="3.7116756"
+         id="feGaussianBlur6611" />
+    </filter>
+    <filter
+       inkscape:collect="always"
+       id="filter6693">
+      <feGaussianBlur
+         inkscape:collect="always"
+         stdDeviation="4.3837536"
+         id="feGaussianBlur6695" />
+    </filter>
+    <filter
+       inkscape:collect="always"
+       id="filter6781">
+      <feGaussianBlur
+         inkscape:collect="always"
+         stdDeviation="5.8770044"
+         id="feGaussianBlur6783" />
+    </filter>
+  </defs>
+  <rect
+     id="rect3210"
+     style="fill:url(#linearGradient3212);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:17;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+     y="-230"
+     x="0"
+     height="230"
+     width="1000.336"
+     transform="scale(1,-1)" />
+  <g
+     id="layer1"
+     inkscape:label="Layer 1"
+     transform="matrix(0.8066215,0,0,0.8008797,451.66415,145.2047)"
+     style="fill:url(#radialGradient6297);fill-opacity:1;filter:url(#filter6439)">
+    <g
+       inkscape:export-ydpi="90"
+       inkscape:export-xdpi="90"
+       inkscape:export-filename="H:\new\rect2273.png"
+       style="fill:url(#radialGradient6477);fill-opacity:1.0"
+       transform="matrix(0.7844778,0,0,0.7844778,-1023.124,-443.46103)"
+       id="yleiso1">
+      <path
+         sodipodi:nodetypes="ccccccccccccccccccccccccccccccccccccsscccccccccccccccccccccccccc"
+         id="path2504"
+         d="M 1181.224,723.79257 C 1199.0901,718.60987 1185.0396,697.72457 1187.3691,684.83127 C 1184.688,666.26335 1171.3704,651.43231 1166.9813,633.26001 C 1160.1207,617.38632 1158.849,599.92929 1153.3602,583.77252 C 1148.7636,571.05526 1143.9694,558.30454 1136.8115,547.14829 C 1128.5489,534.23416 1123.5923,519.2203 1129.3182,503.92685 C 1132.0217,485.7828 1137.0229,468.14408 1139.758,449.9947 C 1147.1751,438.85268 1133.8906,413.77294 1144.9766,408.88718 C 1142.6569,431.31121 1149.9781,411.49517 1156.9042,420.49538 C 1163.9095,414.90467 1162.3914,422.35289 1165.1341,424.4142 C 1171.0661,408.35972 1174.8698,420.56041 1167.9972,429.41733 C 1158.1154,441.97928 1151.3706,461.5574 1152.7012,478.30944 C 1151.2265,485.96869 1154.1129,504.61879 1156.3028,486.18395 C 1158.9392,478.09567 1160.2787,493.25406 1162.4626,493.72715 C 1149.4183,507.35899 1182.8488,491.53847 1169.1093,504.67272 C 1166.0703,513.41577 1149.4599,518.83806 1158.526,528.3426 C 1168.2568,540.01484 1174.4634,555.0484 1186.5999,564.4929 C 1190.7679,563.86303 1203.8036,554.27654 1201.5915,549.09252 C 1197.8442,536.68637 1191.1228,521.94383 1205.0553,510.09744 C 1216.4312,504.07671 1232.7978,494.0759 1243.5494,504.55673 C 1246.6613,520.95199 1254.265,537.76964 1250.3939,554.72426 C 1248.4661,561.95805 1240.3264,580.70989 1254.9838,573.2705 C 1271.4972,566.56068 1275.1832,552.0784 1276.7458,535.84879 C 1279.4894,520.74532 1287.8045,503.8597 1279.1376,489.28238 C 1273.8191,481.68486 1274.1639,470.71136 1281.5231,482.34879 C 1286.0476,477.77342 1287.1139,449.21899 1289.5758,468.75447 C 1291.0788,472.96237 1296.3003,457.53592 1296.8529,471.34617 C 1308.9366,483.16143 1297.2902,498.12169 1298.4281,512.20436 C 1298.4145,519.98988 1293.6444,543.41817 1305.982,528.27346 C 1317.9778,518.59866 1320.579,502.46967 1329.3504,490.31893 C 1337.7237,474.96976 1345.9566,457.63035 1345.2772,439.88738 C 1347.1841,429.39723 1338.239,408.68409 1351.9681,419.34584 C 1351.7099,408.58687 1372.1739,403.35257 1358.9283,415.91499 C 1352.3722,431.19226 1379.9442,395.69031 1370.6096,417.32897 C 1363.9548,422.72554 1365.2976,432.86515 1376.385,420.28147 C 1382.8759,422.22298 1366.3058,440.99887 1364.4973,449.02262 C 1353.2056,469.14576 1350.0496,492.5316 1342.1625,513.96454 C 1336.3527,529.75235 1328.4691,543.59904 1319.8074,557.94366 C 1310.2192,573.82279 1300.026,589.53545 1288.6205,604.10045 C 1279.6747,615.09562 1303.4822,605.24803 1309.6406,610.88682 C 1322.1586,603.01307 1339.0256,609.81366 1341.3848,624.79192 C 1349.9202,631.66381 1338.4258,651.99891 1346.2108,653.04492 C 1353.1707,644.68823 1376.9006,642.82214 1362.6019,629.38502 C 1357.722,615.77507 1349.112,596.42578 1365.5608,586.80732 C 1384.541,575.74506 1394.6894,599.25542 1400.1051,611.32032 C 1398.9907,617.63272 1389.1106,635.48514 1401.404,634.41192 C 1413.3743,639.52316 1418.5455,631.84517 1411.1806,621.42007 C 1405.5681,613.80634 1409.1866,605.72051 1413.6207,617.53459 C 1418.9418,625.96867 1410.3211,591.87473 1418.5981,610.56244 C 1419.8123,609.90142 1423.3305,600.47095 1423.688,611.9527 C 1425.0173,622.38725 1428.2675,619.37152 1430.9161,612.17672 C 1434.0491,621.97072 1430.2978,634.12309 1434.7731,643.22177 C 1449.9279,660.26567 1469.4341,673.70517 1481.0786,693.61147 C 1483.1005,704.21417 1478.731,717.48727 1471.0841,724.34877 C 1374.4648,724.20307 1277.8372,724.75587 1181.224,723.79257 z M 1455.1965,693.09877 C 1449.7389,685.43527 1439.2771,687.73167 1451.6474,693.45447 C 1452.1444,694.17817 1455.238,694.94177 1455.1965,693.09877 z M 1318.1514,671.71397 C 1326.34,655.59568 1302.2616,649.4392 1304.2731,633.07932 C 1303.9936,626.0403 1303.0497,612.64652 1295.8858,625.46256 C 1287.107,632.2499 1304.5643,642.48038 1298.2368,652.57004 C 1300.012,661.49008 1290.9202,673.70597 1306.224,672.69467 C 1310.013,673.91017 1315.3324,675.81437 1318.1514,671.71397 z"
+         style="fill:url(#radialGradient6475);fill-opacity:1.0" />
+    </g>
+  </g>
+  <g
+     id="g2670"
+     inkscape:label="Layer 1"
+     transform="matrix(1,0,0,0.8832743,320.27471,120.95505)"
+     style="fill:url(#radialGradient6295);fill-opacity:1;filter:url(#filter6435)">
+    <g
+       inkscape:export-ydpi="90"
+       inkscape:export-xdpi="90"
+       inkscape:export-filename="H:\new\rect2273.png"
+       style="fill:url(#radialGradient6473);fill-opacity:1.0"
+       transform="matrix(0.6938009,0,0,0.6938009,-870.0051,-393.95863)"
+       id="yleiso2">
+      <path
+         sodipodi:nodetypes="cccccccccccccccccccccccccccssccc"
+         id="path2270"
+         d="M 1326.7136,723.79257 C 1308.8475,718.60987 1322.898,697.72457 1320.5685,684.83127 C 1323.2496,666.26335 1336.5672,651.43231 1340.9563,633.26001 C 1347.8169,617.38632 1347.0159,604.07478 1352.5047,587.91801 C 1361.2467,575.89167 1367.4228,568.66827 1371.1261,556.13019 C 1376.625,539.07057 1380.8907,527.51129 1375.1648,512.21784 C 1372.4613,494.07379 1367.4601,476.43507 1364.725,458.28569 C 1357.3079,447.14367 1370.5924,422.06393 1359.5064,417.17817 C 1361.8261,439.6022 1354.5049,419.78616 1347.5788,428.78637 C 1340.5735,423.19566 1342.0916,430.64388 1339.3489,432.70519 C 1333.4169,416.65071 1329.6132,428.8514 1336.4858,437.70832 C 1346.3676,450.27027 1353.1124,469.84839 1351.7818,486.60043 C 1355.3852,518.74824 1355.8198,515.10521 1345.957,536.63359 C 1336.2262,548.30583 1330.7105,562.64847 1318.574,572.09297 C 1314.406,571.4631 1283.4065,595.73147 1306.3461,549.09252 C 1310.0934,536.68637 1316.8148,521.94383 1302.8823,510.09744 C 1291.5064,504.07671 1275.1398,494.0759 1264.3882,504.55673 C 1261.2763,520.95199 1253.6726,537.76964 1257.5437,554.72426 C 1259.4715,561.95805 1267.6112,580.70989 1252.9538,573.2705 C 1230.0238,552.25689 1236.3043,558.74018 1201.9556,528.27346 C 1189.9598,518.59866 1187.3586,502.46967 1178.5872,490.31893 C 1170.2139,474.96976 1161.981,457.63035 1162.6604,439.88738 C 1160.7535,429.39723 1169.6986,408.68409 1155.9695,419.34584 C 1156.2277,408.58687 1135.7637,403.35257 1149.0093,415.91499 C 1155.5654,431.19226 1127.9934,395.69031 1137.328,417.32897 C 1143.9828,422.72554 1142.64,432.86515 1131.5526,420.28147 C 1125.0617,422.22298 1141.6318,440.99887 1143.4403,449.02262 C 1154.732,469.14576 1157.888,492.5316 1165.7751,513.96454 C 1171.5849,529.75235 1179.4685,543.59904 1188.1302,557.94366 C 1197.7184,573.82279 1207.9116,589.53545 1219.3171,604.10045 C 1230.9206,658.44183 1215.0079,686.0741 1203.8726,715.91823 C 1236.4598,732.80965 1210.5013,732.69947 1326.7136,723.79257 z"
+         style="fill:url(#radialGradient6471);fill-opacity:1.0" />
+    </g>
+  </g>
+  <g
+     id="g2674"
+     inkscape:label="Layer 1"
+     transform="matrix(-1,0,0,0.8711992,487.08999,112.44614)"
+     style="fill:url(#radialGradient6293);fill-opacity:1;filter:url(#filter6593)">
+    <g
+       inkscape:export-ydpi="90"
+       inkscape:export-xdpi="90"
+       inkscape:export-filename="H:\new\rect2273.png"
+       style="fill:url(#radialGradient6469);fill-opacity:1.0"
+       transform="matrix(0.6938009,0,0,0.6938009,-870.0051,-393.95863)"
+       id="g2676">
+      <path
+         sodipodi:nodetypes="cccccccccccccccccccccccccccssccc"
+         id="path2678"
+         d="M 1326.7136,723.79257 C 1308.8475,718.60987 1322.898,697.72457 1320.5685,684.83127 C 1323.2496,666.26335 1336.5672,651.43231 1340.9563,633.26001 C 1347.8169,617.38632 1347.0159,604.07478 1352.5047,587.91801 C 1361.2467,575.89167 1367.4228,568.66827 1371.1261,556.13019 C 1376.625,539.07057 1380.8907,527.51129 1375.1648,512.21784 C 1372.4613,494.07379 1367.4601,476.43507 1364.725,458.28569 C 1357.3079,447.14367 1370.5924,422.06393 1359.5064,417.17817 C 1361.8261,439.6022 1354.5049,419.78616 1347.5788,428.78637 C 1340.5735,423.19566 1342.0916,430.64388 1339.3489,432.70519 C 1333.4169,416.65071 1329.6132,428.8514 1336.4858,437.70832 C 1346.3676,450.27027 1353.1124,469.84839 1351.7818,486.60043 C 1355.3852,518.74824 1355.8198,515.10521 1345.957,536.63359 C 1336.2262,548.30583 1330.7105,562.64847 1318.574,572.09297 C 1314.406,571.4631 1283.4065,595.73147 1306.3461,549.09252 C 1310.0934,536.68637 1316.8148,521.94383 1302.8823,510.09744 C 1291.5064,504.07671 1275.1398,494.0759 1264.3882,504.55673 C 1261.2763,520.95199 1253.6726,537.76964 1257.5437,554.72426 C 1259.4715,561.95805 1267.6112,580.70989 1252.9538,573.2705 C 1230.0238,552.25689 1236.3043,558.74018 1201.9556,528.27346 C 1189.9598,518.59866 1187.3586,502.46967 1178.5872,490.31893 C 1170.2139,474.96976 1161.981,457.63035 1162.6604,439.88738 C 1160.7535,429.39723 1169.6986,408.68409 1155.9695,419.34584 C 1156.2277,408.58687 1135.7637,403.35257 1149.0093,415.91499 C 1155.5654,431.19226 1127.9934,395.69031 1137.328,417.32897 C 1143.9828,422.72554 1142.64,432.86515 1131.5526,420.28147 C 1125.0617,422.22298 1141.6318,440.99887 1143.4403,449.02262 C 1154.732,469.14576 1157.888,492.5316 1165.7751,513.96454 C 1171.5849,529.75235 1179.4685,543.59904 1188.1302,557.94366 C 1197.7184,573.82279 1207.9116,589.53545 1219.3171,604.10045 C 1230.9206,658.44183 1215.0079,686.0741 1203.8726,715.91823 C 1236.4598,732.80965 1210.5013,732.69947 1326.7136,723.79257 z"
+         style="fill:url(#radialGradient6467);fill-opacity:1.0" />
+    </g>
+  </g>
+  <g
+     id="g2680"
+     inkscape:label="Layer 1"
+     transform="matrix(0.8624259,0,0,0.8624259,266.15497,141.15386)"
+     style="fill:url(#radialGradient6291);fill-opacity:1;filter:url(#filter6609)">
+    <g
+       inkscape:export-ydpi="90"
+       inkscape:export-xdpi="90"
+       inkscape:export-filename="H:\new\rect2273.png"
+       style="fill:url(#radialGradient6465);fill-opacity:1.0"
+       transform="matrix(0.7844778,0,0,0.7844778,-1023.124,-443.46103)"
+       id="g2682">
+      <path
+         sodipodi:nodetypes="ccccccccccccccccccccccccccccccccccccsscccccccccccccccccccccccccc"
+         id="path2684"
+         d="M 1181.224,723.79257 C 1199.0901,718.60987 1185.0396,697.72457 1187.3691,684.83127 C 1184.688,666.26335 1171.3704,651.43231 1166.9813,633.26001 C 1160.1207,617.38632 1158.849,599.92929 1153.3602,583.77252 C 1148.7636,571.05526 1143.9694,558.30454 1136.8115,547.14829 C 1128.5489,534.23416 1123.5923,519.2203 1129.3182,503.92685 C 1132.0217,485.7828 1137.0229,468.14408 1139.758,449.9947 C 1147.1751,438.85268 1133.8906,413.77294 1144.9766,408.88718 C 1142.6569,431.31121 1149.9781,411.49517 1156.9042,420.49538 C 1163.9095,414.90467 1162.3914,422.35289 1165.1341,424.4142 C 1171.0661,408.35972 1174.8698,420.56041 1167.9972,429.41733 C 1158.1154,441.97928 1151.3706,461.5574 1152.7012,478.30944 C 1151.2265,485.96869 1154.1129,504.61879 1156.3028,486.18395 C 1158.9392,478.09567 1160.2787,493.25406 1162.4626,493.72715 C 1149.4183,507.35899 1182.8488,491.53847 1169.1093,504.67272 C 1166.0703,513.41577 1149.4599,518.83806 1158.526,528.3426 C 1168.2568,540.01484 1174.4634,555.0484 1186.5999,564.4929 C 1190.7679,563.86303 1203.8036,554.27654 1201.5915,549.09252 C 1197.8442,536.68637 1191.1228,521.94383 1205.0553,510.09744 C 1216.4312,504.07671 1232.7978,494.0759 1243.5494,504.55673 C 1246.6613,520.95199 1254.265,537.76964 1250.3939,554.72426 C 1248.4661,561.95805 1240.3264,580.70989 1254.9838,573.2705 C 1271.4972,566.56068 1275.1832,552.0784 1276.7458,535.84879 C 1279.4894,520.74532 1287.8045,503.8597 1279.1376,489.28238 C 1273.8191,481.68486 1274.1639,470.71136 1281.5231,482.34879 C 1286.0476,477.77342 1287.1139,449.21899 1289.5758,468.75447 C 1291.0788,472.96237 1296.3003,457.53592 1296.8529,471.34617 C 1308.9366,483.16143 1297.2902,498.12169 1298.4281,512.20436 C 1298.4145,519.98988 1293.6444,543.41817 1305.982,528.27346 C 1317.9778,518.59866 1320.579,502.46967 1329.3504,490.31893 C 1337.7237,474.96976 1345.9566,457.63035 1345.2772,439.88738 C 1347.1841,429.39723 1338.239,408.68409 1351.9681,419.34584 C 1351.7099,408.58687 1372.1739,403.35257 1358.9283,415.91499 C 1352.3722,431.19226 1379.9442,395.69031 1370.6096,417.32897 C 1363.9548,422.72554 1365.2976,432.86515 1376.385,420.28147 C 1382.8759,422.22298 1366.3058,440.99887 1364.4973,449.02262 C 1353.2056,469.14576 1350.0496,492.5316 1342.1625,513.96454 C 1336.3527,529.75235 1328.4691,543.59904 1319.8074,557.94366 C 1310.2192,573.82279 1300.026,589.53545 1288.6205,604.10045 C 1279.6747,615.09562 1303.4822,605.24803 1309.6406,610.88682 C 1322.1586,603.01307 1339.0256,609.81366 1341.3848,624.79192 C 1349.9202,631.66381 1338.4258,651.99891 1346.2108,653.04492 C 1353.1707,644.68823 1376.9006,642.82214 1362.6019,629.38502 C 1357.722,615.77507 1349.112,596.42578 1365.5608,586.80732 C 1384.541,575.74506 1394.6894,599.25542 1400.1051,611.32032 C 1398.9907,617.63272 1389.1106,635.48514 1401.404,634.41192 C 1413.3743,639.52316 1418.5455,631.84517 1411.1806,621.42007 C 1405.5681,613.80634 1409.1866,605.72051 1413.6207,617.53459 C 1418.9418,625.96867 1410.3211,591.87473 1418.5981,610.56244 C 1419.8123,609.90142 1423.3305,600.47095 1423.688,611.9527 C 1425.0173,622.38725 1428.2675,619.37152 1430.9161,612.17672 C 1434.0491,621.97072 1430.2978,634.12309 1434.7731,643.22177 C 1449.9279,660.26567 1469.4341,673.70517 1481.0786,693.61147 C 1483.1005,704.21417 1478.731,717.48727 1471.0841,724.34877 C 1374.4648,724.20307 1277.8372,724.75587 1181.224,723.79257 z M 1455.1965,693.09877 C 1449.7389,685.43527 1439.2771,687.73167 1451.6474,693.45447 C 1452.1444,694.17817 1455.238,694.94177 1455.1965,693.09877 z M 1318.1514,671.71397 C 1326.34,655.59568 1302.2616,649.4392 1304.2731,633.07932 C 1303.9936,626.0403 1303.0497,612.64652 1295.8858,625.46256 C 1287.107,632.2499 1304.5643,642.48038 1298.2368,652.57004 C 1300.012,661.49008 1290.9202,673.70597 1306.224,672.69467 C 1310.013,673.91017 1315.3324,675.81437 1318.1514,671.71397 z"
+         style="fill:url(#radialGradient6463);fill-opacity:1.0" />
+    </g>
+  </g>
+  <g
+     id="g2686"
+     inkscape:label="Layer 1"
+     transform="matrix(1,0,0,0.8551852,53.906246,135.77945)"
+     style="fill:url(#radialGradient6289);fill-opacity:1;filter:url(#filter6781)">
+    <g
+       inkscape:export-ydpi="90"
+       inkscape:export-xdpi="90"
+       inkscape:export-filename="H:\new\rect2273.png"
+       style="fill:url(#radialGradient6461);fill-opacity:1.0"
+       transform="matrix(0.7844778,0,0,0.7844778,-1023.124,-443.46103)"
+       id="g2688">
+      <path
+         sodipodi:nodetypes="ccccccccccccccccccccccccccccccccccccsscccccccccccccccccccccccccc"
+         id="path2690"
+         d="M 1181.224,723.79257 C 1199.0901,718.60987 1185.0396,697.72457 1187.3691,684.83127 C 1184.688,666.26335 1171.3704,651.43231 1166.9813,633.26001 C 1160.1207,617.38632 1158.849,599.92929 1153.3602,583.77252 C 1148.7636,571.05526 1143.9694,558.30454 1136.8115,547.14829 C 1128.5489,534.23416 1123.5923,519.2203 1129.3182,503.92685 C 1132.0217,485.7828 1137.0229,468.14408 1139.758,449.9947 C 1147.1751,438.85268 1133.8906,413.77294 1144.9766,408.88718 C 1142.6569,431.31121 1149.9781,411.49517 1156.9042,420.49538 C 1163.9095,414.90467 1162.3914,422.35289 1165.1341,424.4142 C 1171.0661,408.35972 1174.8698,420.56041 1167.9972,429.41733 C 1158.1154,441.97928 1151.3706,461.5574 1152.7012,478.30944 C 1151.2265,485.96869 1154.1129,504.61879 1156.3028,486.18395 C 1158.9392,478.09567 1160.2787,493.25406 1162.4626,493.72715 C 1149.4183,507.35899 1182.8488,491.53847 1169.1093,504.67272 C 1166.0703,513.41577 1149.4599,518.83806 1158.526,528.3426 C 1168.2568,540.01484 1174.4634,555.0484 1186.5999,564.4929 C 1190.7679,563.86303 1203.8036,554.27654 1201.5915,549.09252 C 1197.8442,536.68637 1191.1228,521.94383 1205.0553,510.09744 C 1216.4312,504.07671 1232.7978,494.0759 1243.5494,504.55673 C 1246.6613,520.95199 1254.265,537.76964 1250.3939,554.72426 C 1248.4661,561.95805 1240.3264,580.70989 1254.9838,573.2705 C 1271.4972,566.56068 1275.1832,552.0784 1276.7458,535.84879 C 1279.4894,520.74532 1287.8045,503.8597 1279.1376,489.28238 C 1273.8191,481.68486 1274.1639,470.71136 1281.5231,482.34879 C 1286.0476,477.77342 1287.1139,449.21899 1289.5758,468.75447 C 1291.0788,472.96237 1296.3003,457.53592 1296.8529,471.34617 C 1308.9366,483.16143 1297.2902,498.12169 1298.4281,512.20436 C 1298.4145,519.98988 1293.6444,543.41817 1305.982,528.27346 C 1317.9778,518.59866 1320.579,502.46967 1329.3504,490.31893 C 1337.7237,474.96976 1345.9566,457.63035 1345.2772,439.88738 C 1347.1841,429.39723 1338.239,408.68409 1351.9681,419.34584 C 1351.7099,408.58687 1372.1739,403.35257 1358.9283,415.91499 C 1352.3722,431.19226 1379.9442,395.69031 1370.6096,417.32897 C 1363.9548,422.72554 1365.2976,432.86515 1376.385,420.28147 C 1382.8759,422.22298 1366.3058,440.99887 1364.4973,449.02262 C 1353.2056,469.14576 1350.0496,492.5316 1342.1625,513.96454 C 1336.3527,529.75235 1328.4691,543.59904 1319.8074,557.94366 C 1310.2192,573.82279 1300.026,589.53545 1288.6205,604.10045 C 1279.6747,615.09562 1303.4822,605.24803 1309.6406,610.88682 C 1322.1586,603.01307 1339.0256,609.81366 1341.3848,624.79192 C 1349.9202,631.66381 1338.4258,651.99891 1346.2108,653.04492 C 1353.1707,644.68823 1376.9006,642.82214 1362.6019,629.38502 C 1357.722,615.77507 1349.112,596.42578 1365.5608,586.80732 C 1384.541,575.74506 1394.6894,599.25542 1400.1051,611.32032 C 1398.9907,617.63272 1389.1106,635.48514 1401.404,634.41192 C 1413.3743,639.52316 1418.5455,631.84517 1411.1806,621.42007 C 1405.5681,613.80634 1409.1866,605.72051 1413.6207,617.53459 C 1418.9418,625.96867 1410.3211,591.87473 1418.5981,610.56244 C 1419.8123,609.90142 1423.3305,600.47095 1423.688,611.9527 C 1425.0173,622.38725 1428.2675,619.37152 1430.9161,612.17672 C 1434.0491,621.97072 1430.2978,634.12309 1434.7731,643.22177 C 1449.9279,660.26567 1469.4341,673.70517 1481.0786,693.61147 C 1483.1005,704.21417 1478.731,717.48727 1471.0841,724.34877 C 1374.4648,724.20307 1277.8372,724.75587 1181.224,723.79257 z M 1455.1965,693.09877 C 1449.7389,685.43527 1439.2771,687.73167 1451.6474,693.45447 C 1452.1444,694.17817 1455.238,694.94177 1455.1965,693.09877 z M 1318.1514,671.71397 C 1326.34,655.59568 1302.2616,649.4392 1304.2731,633.07932 C 1303.9936,626.0403 1303.0497,612.64652 1295.8858,625.46256 C 1287.107,632.2499 1304.5643,642.48038 1298.2368,652.57004 C 1300.012,661.49008 1290.9202,673.70597 1306.224,672.69467 C 1310.013,673.91017 1315.3324,675.81437 1318.1514,671.71397 z"
+         style="fill:url(#radialGradient6459);fill-opacity:1.0" />
+    </g>
+  </g>
+  <g
+     id="g2692"
+     inkscape:label="Layer 1"
+     transform="matrix(-0.7704983,0,0,0.8872993,563.32327,145.61496)"
+     style="fill:url(#radialGradient6287);fill-opacity:1;filter:url(#filter6529)">
+    <g
+       inkscape:export-ydpi="90"
+       inkscape:export-xdpi="90"
+       inkscape:export-filename="H:\new\rect2273.png"
+       style="fill:url(#radialGradient6457);fill-opacity:1.0"
+       transform="matrix(0.6938009,0,0,0.6938009,-870.0051,-393.95863)"
+       id="g2694">
+      <path
+         sodipodi:nodetypes="cccccccccccccccccccccccccccssccc"
+         id="path2696"
+         d="M 1326.7136,723.79257 C 1308.8475,718.60987 1322.898,697.72457 1320.5685,684.83127 C 1323.2496,666.26335 1336.5672,651.43231 1340.9563,633.26001 C 1347.8169,617.38632 1347.0159,604.07478 1352.5047,587.91801 C 1361.2467,575.89167 1367.4228,568.66827 1371.1261,556.13019 C 1376.625,539.07057 1380.8907,527.51129 1375.1648,512.21784 C 1372.4613,494.07379 1367.4601,476.43507 1364.725,458.28569 C 1357.3079,447.14367 1370.5924,422.06393 1359.5064,417.17817 C 1361.8261,439.6022 1354.5049,419.78616 1347.5788,428.78637 C 1340.5735,423.19566 1342.0916,430.64388 1339.3489,432.70519 C 1333.4169,416.65071 1329.6132,428.8514 1336.4858,437.70832 C 1346.3676,450.27027 1353.1124,469.84839 1351.7818,486.60043 C 1355.3852,518.74824 1355.8198,515.10521 1345.957,536.63359 C 1336.2262,548.30583 1330.7105,562.64847 1318.574,572.09297 C 1314.406,571.4631 1283.4065,595.73147 1306.3461,549.09252 C 1310.0934,536.68637 1316.8148,521.94383 1302.8823,510.09744 C 1291.5064,504.07671 1275.1398,494.0759 1264.3882,504.55673 C 1261.2763,520.95199 1253.6726,537.76964 1257.5437,554.72426 C 1259.4715,561.95805 1267.6112,580.70989 1252.9538,573.2705 C 1230.0238,552.25689 1236.3043,558.74018 1201.9556,528.27346 C 1189.9598,518.59866 1187.3586,502.46967 1178.5872,490.31893 C 1170.2139,474.96976 1161.981,457.63035 1162.6604,439.88738 C 1160.7535,429.39723 1169.6986,408.68409 1155.9695,419.34584 C 1156.2277,408.58687 1135.7637,403.35257 1149.0093,415.91499 C 1155.5654,431.19226 1127.9934,395.69031 1137.328,417.32897 C 1143.9828,422.72554 1142.64,432.86515 1131.5526,420.28147 C 1125.0617,422.22298 1141.6318,440.99887 1143.4403,449.02262 C 1154.732,469.14576 1157.888,492.5316 1165.7751,513.96454 C 1171.5849,529.75235 1179.4685,543.59904 1188.1302,557.94366 C 1197.7184,573.82279 1207.9116,589.53545 1219.3171,604.10045 C 1230.9206,658.44183 1215.0079,686.0741 1203.8726,715.91823 C 1236.4598,732.80965 1210.5013,732.69947 1326.7136,723.79257 z"
+         style="fill:url(#radialGradient6455);fill-opacity:1.0" />
+    </g>
+  </g>
+  <g
+     id="g2698"
+     inkscape:label="Layer 1"
+     transform="matrix(-1,0,0,1,643.14381,132.95368)"
+     style="fill:url(#radialGradient6285);fill-opacity:1;filter:url(#filter6415)">
+    <g
+       inkscape:export-ydpi="90"
+       inkscape:export-xdpi="90"
+       inkscape:export-filename="H:\new\rect2273.png"
+       style="fill:url(#radialGradient6453);fill-opacity:1.0"
+       transform="matrix(0.6938009,0,0,0.6938009,-870.0051,-393.95863)"
+       id="g2700">
+      <path
+         sodipodi:nodetypes="cccccccccccccccccccccccccccssccc"
+         id="path2702"
+         d="M 1326.7136,723.79257 C 1308.8475,718.60987 1322.898,697.72457 1320.5685,684.83127 C 1323.2496,666.26335 1336.5672,651.43231 1340.9563,633.26001 C 1347.8169,617.38632 1347.0159,604.07478 1352.5047,587.91801 C 1361.2467,575.89167 1367.4228,568.66827 1371.1261,556.13019 C 1376.625,539.07057 1380.8907,527.51129 1375.1648,512.21784 C 1372.4613,494.07379 1367.4601,476.43507 1364.725,458.28569 C 1357.3079,447.14367 1370.5924,422.06393 1359.5064,417.17817 C 1361.8261,439.6022 1354.5049,419.78616 1347.5788,428.78637 C 1340.5735,423.19566 1342.0916,430.64388 1339.3489,432.70519 C 1333.4169,416.65071 1329.6132,428.8514 1336.4858,437.70832 C 1346.3676,450.27027 1353.1124,469.84839 1351.7818,486.60043 C 1355.3852,518.74824 1355.8198,515.10521 1345.957,536.63359 C 1336.2262,548.30583 1330.7105,562.64847 1318.574,572.09297 C 1314.406,571.4631 1283.4065,595.73147 1306.3461,549.09252 C 1310.0934,536.68637 1316.8148,521.94383 1302.8823,510.09744 C 1291.5064,504.07671 1275.1398,494.0759 1264.3882,504.55673 C 1261.2763,520.95199 1253.6726,537.76964 1257.5437,554.72426 C 1259.4715,561.95805 1267.6112,580.70989 1252.9538,573.2705 C 1230.0238,552.25689 1236.3043,558.74018 1201.9556,528.27346 C 1189.9598,518.59866 1187.3586,502.46967 1178.5872,490.31893 C 1170.2139,474.96976 1161.981,457.63035 1162.6604,439.88738 C 1160.7535,429.39723 1169.6986,408.68409 1155.9695,419.34584 C 1156.2277,408.58687 1135.7637,403.35257 1149.0093,415.91499 C 1155.5654,431.19226 1127.9934,395.69031 1137.328,417.32897 C 1143.9828,422.72554 1142.64,432.86515 1131.5526,420.28147 C 1125.0617,422.22298 1141.6318,440.99887 1143.4403,449.02262 C 1154.732,469.14576 1157.888,492.5316 1165.7751,513.96454 C 1171.5849,529.75235 1179.4685,543.59904 1188.1302,557.94366 C 1197.7184,573.82279 1207.9116,589.53545 1219.3171,604.10045 C 1230.9206,658.44183 1215.0079,686.0741 1203.8726,715.91823 C 1236.4598,732.80965 1210.5013,732.69947 1326.7136,723.79257 z"
+         style="fill:url(#radialGradient6451);fill-opacity:1.0" />
+    </g>
+  </g>
+  <g
+     id="g2704"
+     inkscape:label="Layer 1"
+     transform="matrix(1.0260797,0,0,1.0483003,955.70074,136.49604)"
+     style="fill:url(#radialGradient6283);fill-opacity:1;filter:url(#filter6693)">
+    <g
+       inkscape:export-ydpi="90"
+       inkscape:export-xdpi="90"
+       inkscape:export-filename="H:\new\rect2273.png"
+       style="fill:url(#radialGradient6449);fill-opacity:1.0"
+       transform="matrix(0.6938009,0,0,0.6938009,-870.0051,-393.95863)"
+       id="g2706">
+      <path
+         sodipodi:nodetypes="cccccccccccccccccccccccccccssccc"
+         id="path2708"
+         d="M 1326.7136,723.79257 C 1308.8475,718.60987 1322.898,697.72457 1320.5685,684.83127 C 1323.2496,666.26335 1336.5672,651.43231 1340.9563,633.26001 C 1347.8169,617.38632 1347.0159,604.07478 1352.5047,587.91801 C 1361.2467,575.89167 1367.4228,568.66827 1371.1261,556.13019 C 1376.625,539.07057 1380.8907,527.51129 1375.1648,512.21784 C 1372.4613,494.07379 1367.4601,476.43507 1364.725,458.28569 C 1357.3079,447.14367 1370.5924,422.06393 1359.5064,417.17817 C 1361.8261,439.6022 1354.5049,419.78616 1347.5788,428.78637 C 1340.5735,423.19566 1342.0916,430.64388 1339.3489,432.70519 C 1333.4169,416.65071 1329.6132,428.8514 1336.4858,437.70832 C 1346.3676,450.27027 1353.1124,469.84839 1351.7818,486.60043 C 1355.3852,518.74824 1355.8198,515.10521 1345.957,536.63359 C 1336.2262,548.30583 1330.7105,562.64847 1318.574,572.09297 C 1314.406,571.4631 1283.4065,595.73147 1306.3461,549.09252 C 1310.0934,536.68637 1316.8148,521.94383 1302.8823,510.09744 C 1291.5064,504.07671 1275.1398,494.0759 1264.3882,504.55673 C 1261.2763,520.95199 1253.6726,537.76964 1257.5437,554.72426 C 1259.4715,561.95805 1267.6112,580.70989 1252.9538,573.2705 C 1230.0238,552.25689 1236.3043,558.74018 1201.9556,528.27346 C 1189.9598,518.59866 1187.3586,502.46967 1178.5872,490.31893 C 1170.2139,474.96976 1161.981,457.63035 1162.6604,439.88738 C 1160.7535,429.39723 1169.6986,408.68409 1155.9695,419.34584 C 1156.2277,408.58687 1135.7637,403.35257 1149.0093,415.91499 C 1155.5654,431.19226 1127.9934,395.69031 1137.328,417.32897 C 1143.9828,422.72554 1142.64,432.86515 1131.5526,420.28147 C 1125.0617,422.22298 1141.6318,440.99887 1143.4403,449.02262 C 1154.732,469.14576 1157.888,492.5316 1165.7751,513.96454 C 1171.5849,529.75235 1179.4685,543.59904 1188.1302,557.94366 C 1197.7184,573.82279 1207.9116,589.53545 1219.3171,604.10045 C 1230.9206,658.44183 1215.0079,686.0741 1203.8726,715.91823 C 1236.4598,732.80965 1210.5013,732.69947 1326.7136,723.79257 z"
+         style="fill:url(#radialGradient6447);fill-opacity:1.0" />
+    </g>
+  </g>
+  <g
+     id="g2710"
+     inkscape:label="Layer 1"
+     transform="matrix(1,0,0,0.9493148,799.19772,126.72296)"
+     style="fill:url(#radialGradient6281);fill-opacity:1;filter:url(#filter6557)">
+    <g
+       inkscape:export-ydpi="90"
+       inkscape:export-xdpi="90"
+       inkscape:export-filename="H:\new\rect2273.png"
+       style="fill:url(#radialGradient6445);fill-opacity:1.0"
+       transform="matrix(0.7844778,0,0,0.7844778,-1023.124,-443.46103)"
+       id="g2712">
+      <path
+         sodipodi:nodetypes="ccccccccccccccccccccccccccccccccccccsscccccccccccccccccccccccccc"
+         id="path2714"
+         d="M 1181.224,723.79257 C 1199.0901,718.60987 1185.0396,697.72457 1187.3691,684.83127 C 1184.688,666.26335 1171.3704,651.43231 1166.9813,633.26001 C 1160.1207,617.38632 1158.849,599.92929 1153.3602,583.77252 C 1148.7636,571.05526 1143.9694,558.30454 1136.8115,547.14829 C 1128.5489,534.23416 1123.5923,519.2203 1129.3182,503.92685 C 1132.0217,485.7828 1137.0229,468.14408 1139.758,449.9947 C 1147.1751,438.85268 1133.8906,413.77294 1144.9766,408.88718 C 1142.6569,431.31121 1149.9781,411.49517 1156.9042,420.49538 C 1163.9095,414.90467 1162.3914,422.35289 1165.1341,424.4142 C 1171.0661,408.35972 1174.8698,420.56041 1167.9972,429.41733 C 1158.1154,441.97928 1151.3706,461.5574 1152.7012,478.30944 C 1151.2265,485.96869 1154.1129,504.61879 1156.3028,486.18395 C 1158.9392,478.09567 1160.2787,493.25406 1162.4626,493.72715 C 1149.4183,507.35899 1182.8488,491.53847 1169.1093,504.67272 C 1166.0703,513.41577 1149.4599,518.83806 1158.526,528.3426 C 1168.2568,540.01484 1174.4634,555.0484 1186.5999,564.4929 C 1190.7679,563.86303 1203.8036,554.27654 1201.5915,549.09252 C 1197.8442,536.68637 1191.1228,521.94383 1205.0553,510.09744 C 1216.4312,504.07671 1232.7978,494.0759 1243.5494,504.55673 C 1246.6613,520.95199 1254.265,537.76964 1250.3939,554.72426 C 1248.4661,561.95805 1240.3264,580.70989 1254.9838,573.2705 C 1271.4972,566.56068 1275.1832,552.0784 1276.7458,535.84879 C 1279.4894,520.74532 1287.8045,503.8597 1279.1376,489.28238 C 1273.8191,481.68486 1274.1639,470.71136 1281.5231,482.34879 C 1286.0476,477.77342 1287.1139,449.21899 1289.5758,468.75447 C 1291.0788,472.96237 1296.3003,457.53592 1296.8529,471.34617 C 1308.9366,483.16143 1297.2902,498.12169 1298.4281,512.20436 C 1298.4145,519.98988 1293.6444,543.41817 1305.982,528.27346 C 1317.9778,518.59866 1320.579,502.46967 1329.3504,490.31893 C 1337.7237,474.96976 1345.9566,457.63035 1345.2772,439.88738 C 1347.1841,429.39723 1338.239,408.68409 1351.9681,419.34584 C 1351.7099,408.58687 1372.1739,403.35257 1358.9283,415.91499 C 1352.3722,431.19226 1379.9442,395.69031 1370.6096,417.32897 C 1363.9548,422.72554 1365.2976,432.86515 1376.385,420.28147 C 1382.8759,422.22298 1366.3058,440.99887 1364.4973,449.02262 C 1353.2056,469.14576 1350.0496,492.5316 1342.1625,513.96454 C 1336.3527,529.75235 1328.4691,543.59904 1319.8074,557.94366 C 1310.2192,573.82279 1300.026,589.53545 1288.6205,604.10045 C 1279.6747,615.09562 1303.4822,605.24803 1309.6406,610.88682 C 1322.1586,603.01307 1339.0256,609.81366 1341.3848,624.79192 C 1349.9202,631.66381 1338.4258,651.99891 1346.2108,653.04492 C 1353.1707,644.68823 1376.9006,642.82214 1362.6019,629.38502 C 1357.722,615.77507 1349.112,596.42578 1365.5608,586.80732 C 1384.541,575.74506 1394.6894,599.25542 1400.1051,611.32032 C 1398.9907,617.63272 1389.1106,635.48514 1401.404,634.41192 C 1413.3743,639.52316 1418.5455,631.84517 1411.1806,621.42007 C 1405.5681,613.80634 1409.1866,605.72051 1413.6207,617.53459 C 1418.9418,625.96867 1410.3211,591.87473 1418.5981,610.56244 C 1419.8123,609.90142 1423.3305,600.47095 1423.688,611.9527 C 1425.0173,622.38725 1428.2675,619.37152 1430.9161,612.17672 C 1434.0491,621.97072 1430.2978,634.12309 1434.7731,643.22177 C 1449.9279,660.26567 1469.4341,673.70517 1481.0786,693.61147 C 1483.1005,704.21417 1478.731,717.48727 1471.0841,724.34877 C 1374.4648,724.20307 1277.8372,724.75587 1181.224,723.79257 z M 1455.1965,693.09877 C 1449.7389,685.43527 1439.2771,687.73167 1451.6474,693.45447 C 1452.1444,694.17817 1455.238,694.94177 1455.1965,693.09877 z M 1318.1514,671.71397 C 1326.34,655.59568 1302.2616,649.4392 1304.2731,633.07932 C 1303.9936,626.0403 1303.0497,612.64652 1295.8858,625.46256 C 1287.107,632.2499 1304.5643,642.48038 1298.2368,652.57004 C 1300.012,661.49008 1290.9202,673.70597 1306.224,672.69467 C 1310.013,673.91017 1315.3324,675.81437 1318.1514,671.71397 z"
+         style="fill:url(#radialGradient6443);fill-opacity:1.0" />
+    </g>
+  </g>
+</svg>
diff --git a/data/themes/default/sing_bg_top.svg b/data/themes/default/sing_bg_top.svg
new file mode 100644 (file)
index 0000000..3cfee81
--- /dev/null
@@ -0,0 +1,215 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://creativecommons.org/ns#"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:xlink="http://www.w3.org/1999/xlink"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   version="1.0"
+   width="1000"
+   height="230"
+   id="svg3465"
+   sodipodi:version="0.32"
+   inkscape:version="0.46"
+   sodipodi:docname="sing_bg_top.svg"
+   sodipodi:docbase="/root/USNG/trunk/themes/lima"
+   inkscape:output_extension="org.inkscape.output.svg.inkscape">
+  <metadata
+     id="metadata30">
+    <rdf:RDF>
+      <cc:Work
+         rdf:about="">
+        <dc:format>image/svg+xml</dc:format>
+        <dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+      </cc:Work>
+    </rdf:RDF>
+  </metadata>
+  <sodipodi:namedview
+     inkscape:cy="93.369316"
+     inkscape:cx="498.16821"
+     inkscape:zoom="0.85529109"
+     inkscape:window-height="726"
+     inkscape:window-width="960"
+     inkscape:pageshadow="2"
+     inkscape:pageopacity="0.0"
+     guidetolerance="10.0"
+     gridtolerance="10.0"
+     objecttolerance="10.0"
+     borderopacity="1.0"
+     bordercolor="#666666"
+     pagecolor="#ffffff"
+     id="base"
+     inkscape:window-x="179"
+     inkscape:window-y="25"
+     inkscape:current-layer="svg3465"
+     showgrid="true">
+    <inkscape:grid
+       type="xygrid"
+       id="grid2392"
+       visible="true"
+       enabled="true" />
+  </sodipodi:namedview>
+  <defs
+     id="defs3467">
+    <inkscape:perspective
+       sodipodi:type="inkscape:persp3d"
+       inkscape:vp_x="0 : 400 : 1"
+       inkscape:vp_y="6.1230318e-14 : 1000 : 0"
+       inkscape:vp_z="1000 : 400 : 1"
+       inkscape:persp3d-origin="500 : 266.66667 : 1"
+       id="perspective57" />
+    <linearGradient
+       id="linearGradient3667">
+      <stop
+         style="stop-color:#000000;stop-opacity:1;"
+         offset="0"
+         id="stop3669" />
+      <stop
+         style="stop-color:#000000;stop-opacity:0;"
+         offset="1"
+         id="stop3671" />
+    </linearGradient>
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient3667"
+       id="linearGradient2549"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="scale(1.2504205,1.5212915)"
+       x1="367.87625"
+       y1="131.46724"
+       x2="367.87625"
+       y2="151.18733" />
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient3667"
+       id="linearGradient5768"
+       x1="551.00964"
+       y1="660.33606"
+       x2="551.00964"
+       y2="605.34015"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(1.0140491,0,0,0.8428048,-5.1350533,117.20059)" />
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient3667"
+       id="linearGradient3212"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(1.2504205,0,0,1.1424679,-3.6234642e-2,-800.15761)"
+       x1="365.07416"
+       y1="121.63737"
+       x2="365.07416"
+       y2="151.1951" />
+  </defs>
+  <rect
+     id="rect3040"
+     style="fill:url(#linearGradient2549);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:17;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+     y="0"
+     x="0"
+     height="230"
+     width="1000.3364" />
+  <g
+     id="g10046"
+     transform="matrix(0.3236326,1.2078137,-1.2078137,0.3236326,300.76337,-154.11351)">
+    <path
+       sodipodi:type="star"
+       style="opacity:0.22790701;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:#ffffff;stroke-width:1.70000005;stroke-linecap:round;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:block;overflow:visible"
+       id="path6523"
+       sodipodi:sides="5"
+       sodipodi:cx="141.42136"
+       sodipodi:cy="350.13498"
+       sodipodi:r1="78.688225"
+       sodipodi:r2="45.665279"
+       sodipodi:arg1="1.0612041"
+       sodipodi:arg2="1.6895226"
+       inkscape:flatsided="false"
+       inkscape:rounded="0"
+       inkscape:randomized="0"
+       d="M 179.80715,418.82535 L 136.01242,395.47879 L 87.954791,407.86853 L 96.625376,359.00278 L 69.991407,317.1259 L 119.14486,310.27177 L 150.74179,272.0007 L 172.4497,316.63036 L 218.61165,334.85441 L 182.87443,369.29119 L 179.80715,418.82535 z"
+       transform="matrix(0.76534,5.189341e-2,-5.189341e-2,0.76534,85.64202,-32.57281)" />
+    <path
+       transform="matrix(0.494335,-0.204386,0.204386,0.494335,90.19682,29.75748)"
+       d="M 179.80715,418.82535 L 136.01242,395.47879 L 87.954791,407.86853 L 96.625376,359.00278 L 69.991407,317.1259 L 119.14486,310.27177 L 150.74179,272.0007 L 172.4497,316.63036 L 218.61165,334.85441 L 182.87443,369.29119 L 179.80715,418.82535 z"
+       inkscape:randomized="0"
+       inkscape:rounded="0"
+       inkscape:flatsided="false"
+       sodipodi:arg2="1.6895226"
+       sodipodi:arg1="1.0612041"
+       sodipodi:r2="45.665279"
+       sodipodi:r1="78.688225"
+       sodipodi:cy="350.13498"
+       sodipodi:cx="141.42136"
+       sodipodi:sides="5"
+       id="path5574"
+       style="opacity:0.22790701;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:#ffffff;stroke-width:1.70000005;stroke-linecap:round;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:block;overflow:visible"
+       sodipodi:type="star" />
+    <path
+       sodipodi:type="star"
+       style="opacity:0.22790701;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:#ffffff;stroke-width:1.70000005;stroke-linecap:round;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:block;overflow:visible"
+       id="path5576"
+       sodipodi:sides="5"
+       sodipodi:cx="141.42136"
+       sodipodi:cy="350.13498"
+       sodipodi:r1="78.688225"
+       sodipodi:r2="45.665279"
+       sodipodi:arg1="1.0612041"
+       sodipodi:arg2="1.6895226"
+       inkscape:flatsided="false"
+       inkscape:rounded="0"
+       inkscape:randomized="0"
+       d="M 179.80715,418.82535 L 136.01242,395.47879 L 87.954791,407.86853 L 96.625376,359.00278 L 69.991407,317.1259 L 119.14486,310.27177 L 150.74179,272.0007 L 172.4497,316.63036 L 218.61165,334.85441 L 182.87443,369.29119 L 179.80715,418.82535 z"
+       transform="matrix(0.430025,1.278809e-2,-1.278809e-2,0.430025,134.5255,-35.15791)" />
+    <path
+       transform="matrix(0.308608,-0.157328,0.157328,0.308608,141.4555,-15.54061)"
+       d="M 179.80715,418.82535 L 136.01242,395.47879 L 87.954791,407.86853 L 96.625376,359.00278 L 69.991407,317.1259 L 119.14486,310.27177 L 150.74179,272.0007 L 172.4497,316.63036 L 218.61165,334.85441 L 182.87443,369.29119 L 179.80715,418.82535 z"
+       inkscape:randomized="0"
+       inkscape:rounded="0"
+       inkscape:flatsided="false"
+       sodipodi:arg2="1.6895226"
+       sodipodi:arg1="1.0612041"
+       sodipodi:r2="45.665279"
+       sodipodi:r1="78.688225"
+       sodipodi:cy="350.13498"
+       sodipodi:cx="141.42136"
+       sodipodi:sides="5"
+       id="path5578"
+       style="opacity:0.22790701;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:#ffffff;stroke-width:1.70000005;stroke-linecap:round;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:block;overflow:visible"
+       sodipodi:type="star" />
+    <path
+       sodipodi:type="star"
+       style="opacity:0.22790701;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:#ffffff;stroke-width:1.70000005;stroke-linecap:round;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:block;overflow:visible"
+       id="path5580"
+       sodipodi:sides="5"
+       sodipodi:cx="141.42136"
+       sodipodi:cy="350.13498"
+       sodipodi:r1="78.688225"
+       sodipodi:r2="45.665279"
+       sodipodi:arg1="1.0612041"
+       sodipodi:arg2="1.6895226"
+       inkscape:flatsided="false"
+       inkscape:rounded="0"
+       inkscape:randomized="0"
+       d="M 179.80715,418.82535 L 136.01242,395.47879 L 87.954791,407.86853 L 96.625376,359.00278 L 69.991407,317.1259 L 119.14486,310.27177 L 150.74179,272.0007 L 172.4497,316.63036 L 218.61165,334.85441 L 182.87443,369.29119 L 179.80715,418.82535 z"
+       transform="matrix(0.218514,5.453603e-2,-5.453603e-2,0.218514,186.3547,-54.97931)" />
+    <path
+       transform="matrix(0.164046,9.96525e-3,-9.96525e-3,0.164046,210.6113,-58.34981)"
+       d="M 179.80715,418.82535 L 136.01242,395.47879 L 87.954791,407.86853 L 96.625376,359.00278 L 69.991407,317.1259 L 119.14486,310.27177 L 150.74179,272.0007 L 172.4497,316.63036 L 218.61165,334.85441 L 182.87443,369.29119 L 179.80715,418.82535 z"
+       inkscape:randomized="0"
+       inkscape:rounded="0"
+       inkscape:flatsided="false"
+       sodipodi:arg2="1.6895226"
+       sodipodi:arg1="1.0612041"
+       sodipodi:r2="45.665279"
+       sodipodi:r1="78.688225"
+       sodipodi:cy="350.13498"
+       sodipodi:cx="141.42136"
+       sodipodi:sides="5"
+       id="path5582"
+       style="opacity:0.22790701;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:#ffffff;stroke-width:1.70000005;stroke-linecap:round;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:block;overflow:visible"
+       sodipodi:type="star" />
+  </g>
+</svg>
diff --git a/data/themes/default/sing_lyricscurrent.svg b/data/themes/default/sing_lyricscurrent.svg
new file mode 100644 (file)
index 0000000..2299677
--- /dev/null
@@ -0,0 +1,72 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://creativecommons.org/ns#"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   version="1.0"
+   width="800"
+   height="600"
+   id="svg3465"
+   sodipodi:version="0.32"
+   inkscape:version="0.48.4 r9939"
+   sodipodi:docname="sing_lyricscurrent.svg"
+   inkscape:output_extension="org.inkscape.output.svg.inkscape">
+  <metadata
+     id="metadata19">
+    <rdf:RDF>
+      <cc:Work
+         rdf:about="">
+        <dc:format>image/svg+xml</dc:format>
+        <dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+      </cc:Work>
+    </rdf:RDF>
+  </metadata>
+  <sodipodi:namedview
+     inkscape:window-height="726"
+     inkscape:window-width="922"
+     inkscape:pageshadow="2"
+     inkscape:pageopacity="0.0"
+     guidetolerance="10.0"
+     gridtolerance="10.0"
+     objecttolerance="10.0"
+     borderopacity="1.0"
+     bordercolor="#666666"
+     pagecolor="#ffffff"
+     id="base"
+     inkscape:zoom="0.43596296"
+     inkscape:cx="458.84961"
+     inkscape:cy="340.50263"
+     inkscape:window-x="101"
+     inkscape:window-y="100"
+     inkscape:current-layer="svg3465"
+     showgrid="false"
+     inkscape:window-maximized="0" />
+  <defs
+     id="defs3467">
+    <inkscape:perspective
+       sodipodi:type="inkscape:persp3d"
+       inkscape:vp_x="0 : 300 : 1"
+       inkscape:vp_y="0 : 1000 : 0"
+       inkscape:vp_z="800 : 300 : 1"
+       inkscape:persp3d-origin="400 : 200 : 1"
+       id="perspective9" />
+  </defs>
+  <text
+     sodipodi:linespacing="125%"
+     xml:space="preserve"
+     id="text3481"
+     style="font-size:30px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;text-align:center;line-height:125%;writing-mode:lr-tb;text-anchor:middle;fill:#ffffff;fill-opacity:1;stroke:#000000;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;display:inline;font-family:Goblin"
+     y="527.65424"
+     x="400"><tspan
+       style="font-size:30px;text-align:center;text-anchor:middle;fill:#ffffff;fill-opacity:1"
+       id="tspan2921"
+       y="527.65424"
+       x="400">lyrics</tspan></text>
+</svg>
diff --git a/data/themes/default/sing_lyricshighlight.svg b/data/themes/default/sing_lyricshighlight.svg
new file mode 100644 (file)
index 0000000..3cc1f90
--- /dev/null
@@ -0,0 +1,75 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://creativecommons.org/ns#"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   version="1.0"
+   width="800"
+   height="600"
+   id="svg3465"
+   sodipodi:version="0.32"
+   inkscape:version="0.48.4 r9939"
+   sodipodi:docname="sing_lyricshighlight.svg"
+   inkscape:output_extension="org.inkscape.output.svg.inkscape">
+  <metadata
+     id="metadata19">
+    <rdf:RDF>
+      <cc:Work
+         rdf:about="">
+        <dc:format>image/svg+xml</dc:format>
+        <dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+      </cc:Work>
+    </rdf:RDF>
+  </metadata>
+  <sodipodi:namedview
+     inkscape:window-height="1145"
+     inkscape:window-width="1920"
+     inkscape:pageshadow="2"
+     inkscape:pageopacity="0.0"
+     guidetolerance="10.0"
+     gridtolerance="10.0"
+     objecttolerance="10.0"
+     borderopacity="1.0"
+     bordercolor="#666666"
+     pagecolor="#ffffff"
+     id="base"
+     inkscape:zoom="0.63333333"
+     inkscape:cx="400"
+     inkscape:cy="-74.420971"
+     inkscape:window-x="0"
+     inkscape:window-y="27"
+     inkscape:current-layer="layer10"
+     showgrid="false"
+     inkscape:window-maximized="1" />
+  <defs
+     id="defs3467">
+    <inkscape:perspective
+       sodipodi:type="inkscape:persp3d"
+       inkscape:vp_x="0 : 300 : 1"
+       inkscape:vp_y="0 : 1000 : 0"
+       inkscape:vp_z="800 : 300 : 1"
+       inkscape:persp3d-origin="400 : 200 : 1"
+       id="perspective2388" />
+  </defs>
+  <g
+     style="opacity:1"
+     id="layer10">
+    <text
+       x="400"
+       y="527.52618"
+       style="font-size:30px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;text-align:center;line-height:125%;writing-mode:lr-tb;text-anchor:middle;opacity:1;fill:#ffd100;fill-opacity:1;stroke:black;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;display:inline;font-family:Goblin"
+       id="text10203"
+       xml:space="preserve"><tspan
+         x="400"
+         y="527.52618"
+         id="tspan10205"
+         style="fill:#ffd100;fill-opacity:1;text-anchor:middle;text-align:center;font-size:30px">lyrics</tspan></text>
+  </g>
+</svg>
diff --git a/data/themes/default/sing_lyricsnext.svg b/data/themes/default/sing_lyricsnext.svg
new file mode 100644 (file)
index 0000000..eb07415
--- /dev/null
@@ -0,0 +1,74 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://creativecommons.org/ns#"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   version="1.0"
+   width="800"
+   height="600"
+   id="svg3465"
+   sodipodi:version="0.32"
+   inkscape:version="0.48.4 r9939"
+   sodipodi:docname="sing_lyricsnext.svg"
+   inkscape:output_extension="org.inkscape.output.svg.inkscape">
+  <metadata
+     id="metadata19">
+    <rdf:RDF>
+      <cc:Work
+         rdf:about="">
+        <dc:format>image/svg+xml</dc:format>
+        <dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+      </cc:Work>
+    </rdf:RDF>
+  </metadata>
+  <sodipodi:namedview
+     inkscape:cy="417.84947"
+     inkscape:cx="305.25953"
+     inkscape:zoom="0.43415836"
+     inkscape:window-height="616"
+     inkscape:window-width="762"
+     inkscape:pageshadow="2"
+     inkscape:pageopacity="0.0"
+     guidetolerance="10.0"
+     gridtolerance="10.0"
+     objecttolerance="10.0"
+     borderopacity="1.0"
+     bordercolor="#666666"
+     pagecolor="#ffffff"
+     id="base"
+     showgrid="false"
+     inkscape:window-x="10"
+     inkscape:window-y="97"
+     inkscape:current-layer="svg3465"
+     inkscape:window-maximized="0" />
+  <defs
+     id="defs3467">
+    <inkscape:perspective
+       sodipodi:type="inkscape:persp3d"
+       inkscape:vp_x="0 : 300 : 1"
+       inkscape:vp_y="0 : 1000 : 0"
+       inkscape:vp_z="800 : 300 : 1"
+       inkscape:persp3d-origin="400 : 200 : 1"
+       id="perspective2397" />
+  </defs>
+  <g
+     id="layer17">
+    <text
+       x="400"
+       y="575.25488"
+       style="font-size:30px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;text-align:center;line-height:125%;writing-mode:lr-tb;text-anchor:middle;fill:#d3d7cf;fill-opacity:1;stroke:black;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;display:inline;font-family:Goblin"
+       id="text6611"
+       xml:space="preserve"><tspan
+         x="400"
+         y="575.25488"
+         id="tspan6613"
+         style="fill:#d3d7cf;text-anchor:middle;text-align:center;font-size:30px">lyrics</tspan></text>
+  </g>
+</svg>
diff --git a/data/themes/default/sing_pause.svg b/data/themes/default/sing_pause.svg
new file mode 100644 (file)
index 0000000..cd1d636
--- /dev/null
@@ -0,0 +1,118 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://creativecommons.org/ns#"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   width="500"
+   height="400"
+   id="svg2"
+   sodipodi:version="0.32"
+   inkscape:version="0.47 r22583"
+   version="1.0"
+   sodipodi:docname="sing_pause.svg"
+   inkscape:output_extension="org.inkscape.output.svg.inkscape">
+  <defs
+     id="defs4">
+    <inkscape:perspective
+       sodipodi:type="inkscape:persp3d"
+       inkscape:vp_x="0 : 526.18109 : 1"
+       inkscape:vp_y="0 : 1000 : 0"
+       inkscape:vp_z="744.09448 : 526.18109 : 1"
+       inkscape:persp3d-origin="372.04724 : 350.78739 : 1"
+       id="perspective10" />
+    <inkscape:perspective
+       id="perspective2963"
+       inkscape:persp3d-origin="88 : 58.666667 : 1"
+       inkscape:vp_z="176 : 88 : 1"
+       inkscape:vp_y="0 : 1000 : 0"
+       inkscape:vp_x="0 : 88 : 1"
+       sodipodi:type="inkscape:persp3d" />
+  </defs>
+  <sodipodi:namedview
+     id="base"
+     pagecolor="#ffffff"
+     bordercolor="#666666"
+     borderopacity="1.0"
+     inkscape:pageopacity="0.0"
+     inkscape:pageshadow="2"
+     inkscape:zoom="0.98994949"
+     inkscape:cx="239.68036"
+     inkscape:cy="233.3315"
+     inkscape:document-units="px"
+     inkscape:current-layer="layer1"
+     showgrid="false"
+     inkscape:window-width="1313"
+     inkscape:window-height="722"
+     inkscape:window-x="0"
+     inkscape:window-y="25"
+     inkscape:window-maximized="0" />
+  <metadata
+     id="metadata7">
+    <rdf:RDF>
+      <cc:Work
+         rdf:about="">
+        <dc:format>image/svg+xml</dc:format>
+        <dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+      </cc:Work>
+    </rdf:RDF>
+  </metadata>
+  <g
+     inkscape:label="Calque 1"
+     inkscape:groupmode="layer"
+     id="layer1"
+     transform="translate(0,80)">
+    <rect
+       style="fill:#ffffff;fill-opacity:0.65016503;stroke:#000000;stroke-width:1.5;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+       id="rect2383"
+       width="478.5"
+       height="378.5"
+       x="10.75"
+       y="-69.25"
+       rx="53.877144"
+       ry="55.004662" />
+    <text
+       xml:space="preserve"
+       style="font-size:49.19297028px;font-style:normal;font-weight:normal;text-align:center;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;font-family:Goblin"
+       x="127.49952"
+       y="10.672979"
+       id="text3179"
+       transform="scale(0.93017475,1.0750668)"><tspan
+         sodipodi:role="line"
+         id="tspan3181"
+         x="127.49952"
+         y="10.672979"
+         style="-inkscape-font-specification:Goblin;font-family:Goblin">QUIT NOW?</tspan></text>
+    <text
+       xml:space="preserve"
+       style="font-size:28px;font-style:normal;font-weight:normal;text-align:center;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;font-family:Goblin"
+       x="139.50516"
+       y="255.35054"
+       id="text2817"><tspan
+         sodipodi:role="line"
+         x="139.50516"
+         y="255.35054"
+         id="tspan2823"
+         style="-inkscape-font-specification:Goblin;font-family:Goblin">Enter/Start to quit</tspan><tspan
+         sodipodi:role="line"
+         x="139.50516"
+         y="290.35056"
+         id="tspan2821" /></text>
+    <g
+       id="g2966"
+       transform="translate(159.78738,34.3101)">
+      <path
+         id="path2955"
+         d="M 0,87.7 C 0,39.2 39.2,0 87.7,0 l 0,0 v 15 15 c -16,0 -30.3,6.4 -40.8,16.9 l 0,0 C 36.4,57.4 30,71.7 30,87.7 l 0,0 c 0,16 6.4,30.3 16.9,40.8 l 0,0 c 10.5,10.5 24.8,16.9 40.8,16.9 l 0,0 c 16,0 30.3,-6.4 40.8,-16.9 l 0,0 C 139,118 145.4,103.7 145.4,87.7 l 0,0 c 0,-16 -6.4,-30.3 -16.9,-40.8 l 0,0 C 118,36.4 103.6,30 87.7,30 l 0,0 V 15 0 c 48.4,0 87.7,39.2 87.7,87.7 l 0,0 c 0,48.4 -39.2,87.7 -87.7,87.7 l 0,0 C 39.2,175.3 0,136.1 0,87.7 l 0,0 z" />
+      <path
+         id="path2957"
+         d="m 72.7,115.4 v -55 c 0,-8.3 6.7,-15 15,-15 l 0,0 c 8.3,0 15,6.7 15,15 l 0,0 v 55 c 0,8.3 -6.7,15 -15,15 l 0,0 c -8.3,0 -15,-6.8 -15,-15 l 0,0 z" />
+    </g>
+  </g>
+</svg>
diff --git a/data/themes/default/sing_pbox.svg b/data/themes/default/sing_pbox.svg
new file mode 100644 (file)
index 0000000..8c6ac1e
--- /dev/null
@@ -0,0 +1,95 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://creativecommons.org/ns#"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   version="1.0"
+   width="59.375919"
+   height="63.933247"
+   id="svg3465"
+   sodipodi:version="0.32"
+   inkscape:version="0.46"
+   sodipodi:docname="sing_pbox.svg"
+   sodipodi:docbase="/home/jesusda/docs/curro/yo/ultrastar-ng/base/theme-pod/themes/default"
+   inkscape:output_extension="org.inkscape.output.svg.inkscape">
+  <metadata
+     id="metadata13361">
+    <rdf:RDF>
+      <cc:Work
+         rdf:about="">
+        <dc:format>image/svg+xml</dc:format>
+        <dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+      </cc:Work>
+    </rdf:RDF>
+  </metadata>
+  <sodipodi:namedview
+     inkscape:cy="38.708266"
+     inkscape:cx="37.588867"
+     inkscape:zoom="17.799815"
+     inkscape:window-height="1125"
+     inkscape:window-width="1920"
+     inkscape:pageshadow="2"
+     inkscape:pageopacity="0.0"
+     guidetolerance="10.0"
+     gridtolerance="10.0"
+     objecttolerance="10.0"
+     borderopacity="1.0"
+     bordercolor="#666666"
+     pagecolor="#ffffff"
+     id="base"
+     showguides="true"
+     inkscape:guide-bbox="true"
+     inkscape:window-x="0"
+     inkscape:window-y="25"
+     inkscape:current-layer="svg3465"
+     showgrid="false">
+    <sodipodi:guide
+       orientation="vertical"
+       position="-118.28318"
+       id="guide17996" />
+    <sodipodi:guide
+       orientation="vertical"
+       position="-110.34334"
+       id="guide17998" />
+  </sodipodi:namedview>
+  <defs
+     id="defs3467">
+    <inkscape:perspective
+       sodipodi:type="inkscape:persp3d"
+       inkscape:vp_x="0 : 300 : 1"
+       inkscape:vp_y="0 : 1000 : 0"
+       inkscape:vp_z="800 : 300 : 1"
+       inkscape:persp3d-origin="400 : 200 : 1"
+       id="perspective14" />
+  </defs>
+  <path
+     style="fill:#323232;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;marker:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:block;overflow:visible"
+     d="M 25.824924,11.905843 C 12.794899,12.576431 2.359432,23.508941 2.3594227,36.801008 C 2.3594227,50.521855 13.475822,61.725153 27.090222,61.725153 C 40.70463,61.725153 51.821021,50.521855 51.821021,36.801008 C 51.821021,36.547547 51.79979,36.299178 51.792263,36.047488 L 44.545564,36.047488 C 44.556147,36.300872 44.574321,36.544903 44.574321,36.801008 C 44.574321,46.577208 36.790593,54.421799 27.090222,54.421799 C 17.38986,54.421799 9.5773652,46.577208 9.5773652,36.801008 C 9.5773652,27.28092 16.99677,19.577764 26.342546,19.180217 L 26.342546,11.905843 C 26.169803,11.911099 25.996784,11.897 25.824924,11.905843 z"
+     id="path16205" />
+  <path
+     style="fill:#323232;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:block;overflow:visible"
+     d="M 48.051209,2.432816 C 43.190794,2.432816 39.251646,7.3242706 39.251646,13.339456 C 39.251646,13.483351 39.27593,13.623977 39.280402,13.766525 L 56.850772,13.766525 C 56.855244,13.623977 56.879529,13.483351 56.879529,13.339456 C 56.879529,7.3242726 52.911632,2.4328141 48.051209,2.432816 z"
+     id="path17986" />
+  <path
+     style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:block;overflow:visible"
+     d="M 39.379856,16.204808 C 39.375373,16.325202 39.351036,16.443972 39.351036,16.565501 C 39.351036,18.958237 40.221147,21.141277 41.656577,22.780497 L 44.394406,33.684488 L 51.858595,33.684488 L 54.538786,22.94697 C 56.068613,21.290663 57.017241,19.039227 57.017241,16.565501 C 57.017241,16.443971 56.992905,16.325203 56.988421,16.204808 L 39.379856,16.204808 z"
+     id="path17991" />
+  <text
+     xml:space="preserve"
+     id="text18005"
+     style="font-size:34.76020813000000231px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;text-align:start;line-height:100%;writing-mode:lr-tb;text-anchor:start;fill:#ffffff;fill-opacity:1;stroke:#000000;stroke-width:1.99999996;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;display:inline;font-family:Droid Sans Mono"
+     y="49.370342"
+     x="17.111099"
+     sodipodi:linespacing="100%"
+     transform="scale(0.9961138,1.0039014)"><tspan
+       id="tspan18007"
+       style="fill:#ffffff;fill-opacity:1;stroke:#000000;stroke-width:1.99999996;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+       y="49.370342"
+       x="17.111099">P</tspan></text>
+</svg>
diff --git a/data/themes/default/sing_popup_text.svg b/data/themes/default/sing_popup_text.svg
new file mode 100644 (file)
index 0000000..4b5e4e4
--- /dev/null
@@ -0,0 +1,78 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://creativecommons.org/ns#"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   version="1.0"
+   width="256"
+   height="128"
+   id="svg3465"
+   sodipodi:version="0.32"
+   inkscape:version="0.47 r22583"
+   sodipodi:docname="sing_popup_text.svg"
+   inkscape:output_extension="org.inkscape.output.svg.inkscape">
+  <metadata
+     id="metadata3075">
+    <rdf:RDF>
+      <cc:Work
+         rdf:about="">
+        <dc:format>image/svg+xml</dc:format>
+        <dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+      </cc:Work>
+    </rdf:RDF>
+  </metadata>
+  <sodipodi:namedview
+     inkscape:window-height="722"
+     inkscape:window-width="1248"
+     inkscape:pageshadow="2"
+     inkscape:pageopacity="0.0"
+     guidetolerance="10.0"
+     gridtolerance="10.0"
+     objecttolerance="10.0"
+     borderopacity="1.0"
+     bordercolor="#666666"
+     pagecolor="#ffffff"
+     id="base"
+     showgrid="false"
+     inkscape:zoom="1.3525"
+     inkscape:cx="199.2681"
+     inkscape:cy="91.992898"
+     inkscape:window-x="0"
+     inkscape:window-y="25"
+     inkscape:current-layer="svg3465"
+     inkscape:window-maximized="0" />
+  <defs
+     id="defs3467">
+    <inkscape:perspective
+       sodipodi:type="inkscape:persp3d"
+       inkscape:vp_x="0 : 300 : 1"
+       inkscape:vp_y="0 : 1000 : 0"
+       inkscape:vp_z="800 : 300 : 1"
+       inkscape:persp3d-origin="400 : 200 : 1"
+       id="perspective9" />
+  </defs>
+  <g
+     style="fill:#ffffff;fill-opacity:1;stroke:#000000;stroke-width:2;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+     id="layer15"
+     transform="translate(-32.532348,10.07024)">
+    <text
+       x="47.081493"
+       y="77.530563"
+       style="font-size:70.43302155px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;text-align:start;line-height:125%;writing-mode:lr-tb;text-anchor:start;fill:#ffffff;fill-opacity:1;stroke:#000000;stroke-width:1.99999988;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;display:inline;font-family:Goblin"
+       id="text10199"
+       xml:space="preserve"
+       sodipodi:linespacing="125%"
+       transform="scale(0.98936247,1.0107519)"><tspan
+         x="47.081493"
+         y="77.530563"
+         style="fill:#ffffff;fill-opacity:1;stroke:#000000;stroke-width:1.99999988;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+         id="tspan10201">3..2..1</tspan></text>
+  </g>
+</svg>
diff --git a/data/themes/default/sing_progressbg.svg b/data/themes/default/sing_progressbg.svg
new file mode 100644 (file)
index 0000000..5fbb769
--- /dev/null
@@ -0,0 +1,99 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://creativecommons.org/ns#"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:xlink="http://www.w3.org/1999/xlink"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   version="1.0"
+   width="500"
+   height="40"
+   id="svg3465"
+   sodipodi:version="0.32"
+   inkscape:version="0.47pre0 r21549"
+   sodipodi:docname="sing_progressbg.svg"
+   inkscape:output_extension="org.inkscape.output.svg.inkscape">
+  <metadata
+     id="metadata13394">
+    <rdf:RDF>
+      <cc:Work
+         rdf:about="">
+        <dc:format>image/svg+xml</dc:format>
+        <dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+      </cc:Work>
+    </rdf:RDF>
+  </metadata>
+  <sodipodi:namedview
+     inkscape:cy="20"
+     inkscape:cx="384.05366"
+     inkscape:zoom="1.868"
+     inkscape:window-height="722"
+     inkscape:window-width="1022"
+     inkscape:pageshadow="2"
+     inkscape:pageopacity="0.4745098"
+     guidetolerance="10.0"
+     gridtolerance="10.0"
+     objecttolerance="10.0"
+     borderopacity="1.0"
+     bordercolor="#666666"
+     pagecolor="#8e8e8e"
+     id="base"
+     inkscape:window-x="250"
+     inkscape:window-y="25"
+     inkscape:current-layer="svg3465"
+     showgrid="false"
+     inkscape:window-maximized="0">
+    <inkscape:grid
+       type="xygrid"
+       id="grid2385"
+       visible="true"
+       enabled="true"
+       empspacing="5"
+       snapvisiblegridlinesonly="true" />
+  </sodipodi:namedview>
+  <defs
+     id="defs3467">
+    <inkscape:perspective
+       sodipodi:type="inkscape:persp3d"
+       inkscape:vp_x="0 : 20 : 1"
+       inkscape:vp_y="0 : 1000 : 0"
+       inkscape:vp_z="500 : 20 : 1"
+       inkscape:persp3d-origin="250 : 13.333333 : 1"
+       id="perspective13" />
+    <linearGradient
+       id="linearGradient2382">
+      <stop
+         style="stop-color:#ffffff;stop-opacity:1;"
+         offset="0"
+         id="stop2384" />
+      <stop
+         id="stop2390"
+         offset="0.25"
+         style="stop-color:#a4a4a4;stop-opacity:1;" />
+      <stop
+         style="stop-color:#404040;stop-opacity:1;"
+         offset="1"
+         id="stop2386" />
+    </linearGradient>
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient2382"
+       id="linearGradient2388"
+       x1="250.26767"
+       y1="3.1680942"
+       x2="250.26767"
+       y2="37.752678"
+       gradientUnits="userSpaceOnUse" />
+  </defs>
+  <path
+     style="fill:url(#linearGradient2388);fill-opacity:1;fill-rule:nonzero;marker:none;marker-start:none;marker-mid:none;marker-end:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;stroke:none;stroke-opacity:1;stroke-width:3;opacity:0.69999999999999996"
+     d="M 484.25269,4.6680942 C 490.90069,4.6680942 496.25269,10.020094 496.25269,16.668094 L 496.25269,24.252677 C 496.25269,30.900677 490.90069,36.252677 484.25269,36.252677 L 4.2826552,36.252677 L 4.2826552,4.6680942 L 484.25269,4.6680942 z"
+     id="rect2380"
+     sodipodi:nodetypes="ccccccc" />
+</svg>
diff --git a/data/themes/default/sing_progressfg.svg b/data/themes/default/sing_progressfg.svg
new file mode 100644 (file)
index 0000000..ac94f55
--- /dev/null
@@ -0,0 +1,6343 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://creativecommons.org/ns#"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:xlink="http://www.w3.org/1999/xlink"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   version="1.0"
+   width="500"
+   height="40"
+   id="svg3465"
+   sodipodi:version="0.32"
+   inkscape:version="0.47pre0 r21549"
+   sodipodi:docname="sing_progressfg.svg"
+   inkscape:output_extension="org.inkscape.output.svg.inkscape">
+  <metadata
+     id="metadata13394">
+    <rdf:RDF>
+      <cc:Work
+         rdf:about="">
+        <dc:format>image/svg+xml</dc:format>
+        <dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+      </cc:Work>
+    </rdf:RDF>
+  </metadata>
+  <sodipodi:namedview
+     inkscape:cy="20"
+     inkscape:cx="512.7357"
+     inkscape:zoom="1.744"
+     inkscape:window-height="722"
+     inkscape:window-width="960"
+     inkscape:pageshadow="2"
+     inkscape:pageopacity="0.0"
+     guidetolerance="10.0"
+     gridtolerance="10.0"
+     objecttolerance="10.0"
+     borderopacity="1.0"
+     bordercolor="#666666"
+     pagecolor="#ffffff"
+     id="base"
+     inkscape:window-x="312"
+     inkscape:window-y="25"
+     inkscape:current-layer="svg3465"
+     showgrid="true"
+     inkscape:window-maximized="0">
+    <inkscape:grid
+       type="xygrid"
+       id="grid2385"
+       visible="true"
+       enabled="true"
+       empspacing="5"
+       snapvisiblegridlinesonly="true" />
+  </sodipodi:namedview>
+  <defs
+     id="defs3467">
+    <inkscape:perspective
+       sodipodi:type="inkscape:persp3d"
+       inkscape:vp_x="0 : 20 : 1"
+       inkscape:vp_y="0 : 1000 : 0"
+       inkscape:vp_z="500 : 20 : 1"
+       inkscape:persp3d-origin="250 : 13.333333 : 1"
+       id="perspective1383" />
+    <linearGradient
+       id="linearGradient2403">
+      <stop
+         style="stop-color:#f9fbf0;stop-opacity:1;"
+         offset="0"
+         id="stop2405" />
+      <stop
+         id="stop2411"
+         offset="0.25"
+         style="stop-color:#c379ff;stop-opacity:1;" />
+      <stop
+         style="stop-color:#272c13;stop-opacity:1;"
+         offset="1"
+         id="stop2407" />
+    </linearGradient>
+    <filter
+       id="filter3238">
+      <feGaussianBlur
+         stdDeviation="0.065319548"
+         id="feGaussianBlur3240" />
+    </filter>
+    <filter
+       id="filter3244">
+      <feGaussianBlur
+         stdDeviation="0.1306391"
+         id="feGaussianBlur3246" />
+    </filter>
+    <filter
+       id="filter3250">
+      <feGaussianBlur
+         stdDeviation="0.19595864"
+         id="feGaussianBlur3252" />
+    </filter>
+    <filter
+       id="filter3256">
+      <feGaussianBlur
+         stdDeviation="0.26127819"
+         id="feGaussianBlur3258" />
+    </filter>
+    <filter
+       x="-0.12"
+       width="1.24"
+       y="-0.12"
+       height="1.24"
+       id="filter3262">
+      <feGaussianBlur
+         stdDeviation="0.32659774"
+         id="feGaussianBlur3264" />
+    </filter>
+    <filter
+       x="-0.144"
+       width="1.288"
+       y="-0.144"
+       height="1.288"
+       id="filter3268">
+      <feGaussianBlur
+         stdDeviation="0.39191729"
+         id="feGaussianBlur3270" />
+    </filter>
+    <filter
+       x="-0.168"
+       width="1.336"
+       y="-0.168"
+       height="1.336"
+       id="filter3274">
+      <feGaussianBlur
+         stdDeviation="0.45723683"
+         id="feGaussianBlur3276" />
+    </filter>
+    <filter
+       x="-0.192"
+       width="1.384"
+       y="-0.192"
+       height="1.384"
+       id="filter3280">
+      <feGaussianBlur
+         stdDeviation="0.52255638"
+         id="feGaussianBlur3282" />
+    </filter>
+    <filter
+       x="-0.216"
+       width="1.432"
+       y="-0.216"
+       height="1.432"
+       id="filter3286">
+      <feGaussianBlur
+         stdDeviation="0.58787593"
+         id="feGaussianBlur3288" />
+    </filter>
+    <filter
+       id="filter3294">
+      <feGaussianBlur
+         stdDeviation="0.1306391"
+         id="feGaussianBlur3296" />
+    </filter>
+    <filter
+       id="filter3300">
+      <feGaussianBlur
+         stdDeviation="0.26127819"
+         id="feGaussianBlur3302" />
+    </filter>
+    <filter
+       x="-0.144"
+       width="1.288"
+       y="-0.144"
+       height="1.288"
+       id="filter3306">
+      <feGaussianBlur
+         stdDeviation="0.39191729"
+         id="feGaussianBlur3308" />
+    </filter>
+    <filter
+       x="-0.192"
+       width="1.384"
+       y="-0.192"
+       height="1.384"
+       id="filter3312">
+      <feGaussianBlur
+         stdDeviation="0.52255638"
+         id="feGaussianBlur3314" />
+    </filter>
+    <filter
+       x="-0.24"
+       width="1.48"
+       y="-0.24"
+       height="1.48"
+       id="filter3318">
+      <feGaussianBlur
+         stdDeviation="0.65319548"
+         id="feGaussianBlur3320" />
+    </filter>
+    <filter
+       x="-0.288"
+       width="1.576"
+       y="-0.288"
+       height="1.576"
+       id="filter3324">
+      <feGaussianBlur
+         stdDeviation="0.78383457"
+         id="feGaussianBlur3326" />
+    </filter>
+    <filter
+       x="-0.336"
+       width="1.672"
+       y="-0.336"
+       height="1.672"
+       id="filter3330">
+      <feGaussianBlur
+         stdDeviation="0.91447367"
+         id="feGaussianBlur3332" />
+    </filter>
+    <filter
+       x="-0.384"
+       width="1.768"
+       y="-0.384"
+       height="1.768"
+       id="filter3336">
+      <feGaussianBlur
+         stdDeviation="1.0451128"
+         id="feGaussianBlur3338" />
+    </filter>
+    <filter
+       x="-0.432"
+       width="1.864"
+       y="-0.432"
+       height="1.864"
+       id="filter3342">
+      <feGaussianBlur
+         stdDeviation="1.1757519"
+         id="feGaussianBlur3344" />
+    </filter>
+    <filter
+       id="filter3348">
+      <feGaussianBlur
+         stdDeviation="0.016100971"
+         id="feGaussianBlur3350" />
+    </filter>
+    <filter
+       id="filter3354">
+      <feGaussianBlur
+         stdDeviation="0.12295691"
+         id="feGaussianBlur3356" />
+    </filter>
+    <filter
+       id="filter3360">
+      <feGaussianBlur
+         stdDeviation="0.20468029"
+         id="feGaussianBlur3362" />
+    </filter>
+    <filter
+       x="-0.12734667"
+       width="1.2546933"
+       y="-0.12734667"
+       height="1.2546933"
+       id="filter3366">
+      <feGaussianBlur
+         stdDeviation="0.34659277"
+         id="feGaussianBlur3368" />
+    </filter>
+    <filter
+       x="-0.17696159"
+       width="1.3539232"
+       y="-0.17696159"
+       height="1.3539232"
+       id="filter3372">
+      <feGaussianBlur
+         stdDeviation="0.48162712"
+         id="feGaussianBlur3374" />
+    </filter>
+    <filter
+       x="-0.2615855"
+       width="1.523171"
+       y="-0.2615855"
+       height="1.523171"
+       id="filter3378">
+      <feGaussianBlur
+         stdDeviation="0.7119436"
+         id="feGaussianBlur3380" />
+    </filter>
+    <filter
+       x="-0.27089858"
+       width="1.5417972"
+       y="-0.27089858"
+       height="1.5417972"
+       id="filter3384">
+      <feGaussianBlur
+         stdDeviation="0.73729053"
+         id="feGaussianBlur3386" />
+    </filter>
+    <filter
+       x="-0.34566025"
+       width="1.6913205"
+       y="-0.34566025"
+       height="1.6913205"
+       id="filter3390">
+      <feGaussianBlur
+         stdDeviation="0.94076547"
+         id="feGaussianBlur3392" />
+    </filter>
+    <filter
+       x="-0.36905274"
+       width="1.7381055"
+       y="-0.36905274"
+       height="1.7381055"
+       id="filter3396">
+      <feGaussianBlur
+         stdDeviation="1.0044316"
+         id="feGaussianBlur3398" />
+    </filter>
+    <filter
+       x="-0.44557215"
+       width="1.8911443"
+       y="-0.44557215"
+       height="1.8911443"
+       id="filter3402">
+      <feGaussianBlur
+         stdDeviation="1.2126905"
+         id="feGaussianBlur3404" />
+    </filter>
+    <filter
+       id="filter3408">
+      <feGaussianBlur
+         stdDeviation="0.0058695606"
+         id="feGaussianBlur3410" />
+    </filter>
+    <filter
+       id="filter3414">
+      <feGaussianBlur
+         stdDeviation="0.094802867"
+         id="feGaussianBlur3416" />
+    </filter>
+    <filter
+       id="filter3420">
+      <feGaussianBlur
+         stdDeviation="0.23013024"
+         id="feGaussianBlur3422" />
+    </filter>
+    <filter
+       x="-0.16110983"
+       width="1.3222197"
+       y="-0.16110983"
+       height="1.3222197"
+       id="filter3426">
+      <feGaussianBlur
+         stdDeviation="0.43848421"
+         id="feGaussianBlur3428" />
+    </filter>
+    <filter
+       x="-0.19001597"
+       width="1.3800319"
+       y="-0.19001597"
+       height="1.3800319"
+       id="filter3432">
+      <feGaussianBlur
+         stdDeviation="0.51715655"
+         id="feGaussianBlur3434" />
+    </filter>
+    <filter
+       x="-0.24963756"
+       width="1.4992751"
+       y="-0.24963756"
+       height="1.4992751"
+       id="filter3438">
+      <feGaussianBlur
+         stdDeviation="0.67942553"
+         id="feGaussianBlur3440" />
+    </filter>
+    <filter
+       x="-0.30495973"
+       width="1.6099195"
+       y="-0.30495973"
+       height="1.6099195"
+       id="filter3444">
+      <feGaussianBlur
+         stdDeviation="0.82999298"
+         id="feGaussianBlur3446" />
+    </filter>
+    <filter
+       x="-0.35848079"
+       width="1.7169616"
+       y="-0.35848079"
+       height="1.7169616"
+       id="filter3450">
+      <feGaussianBlur
+         stdDeviation="0.97565846"
+         id="feGaussianBlur3452" />
+    </filter>
+    <filter
+       x="-0.39967076"
+       width="1.7993415"
+       y="-0.39967076"
+       height="1.7993415"
+       id="filter3456">
+      <feGaussianBlur
+         stdDeviation="1.0877631"
+         id="feGaussianBlur3458" />
+    </filter>
+    <filter
+       x="-0.43950696"
+       width="1.8790139"
+       y="-0.43950696"
+       height="1.8790139"
+       id="filter3462">
+      <feGaussianBlur
+         stdDeviation="1.1961832"
+         id="feGaussianBlur3464" />
+    </filter>
+    <filter
+       id="filter3468">
+      <feGaussianBlur
+         stdDeviation="0.037862217"
+         id="feGaussianBlur3470" />
+    </filter>
+    <filter
+       id="filter3474">
+      <feGaussianBlur
+         stdDeviation="0.092522311"
+         id="feGaussianBlur3476" />
+    </filter>
+    <filter
+       x="-0.11896952"
+       width="1.237939"
+       y="-0.11896952"
+       height="1.237939"
+       id="filter3480">
+      <feGaussianBlur
+         stdDeviation="0.32379313"
+         id="feGaussianBlur3482" />
+    </filter>
+    <filter
+       x="-0.13209167"
+       width="1.2641833"
+       y="-0.13209167"
+       height="1.2641833"
+       id="filter3486">
+      <feGaussianBlur
+         stdDeviation="0.35950701"
+         id="feGaussianBlur3488" />
+    </filter>
+    <filter
+       x="-0.20052982"
+       width="1.4010596"
+       y="-0.20052982"
+       height="1.4010596"
+       id="filter3492">
+      <feGaussianBlur
+         stdDeviation="0.54577154"
+         id="feGaussianBlur3494" />
+    </filter>
+    <filter
+       x="-0.21604349"
+       width="1.432087"
+       y="-0.21604349"
+       height="1.432087"
+       id="filter3498">
+      <feGaussianBlur
+         stdDeviation="0.58799429"
+         id="feGaussianBlur3500" />
+    </filter>
+    <filter
+       x="-0.30274683"
+       width="1.6054937"
+       y="-0.30274683"
+       height="1.6054937"
+       id="filter3504">
+      <feGaussianBlur
+         stdDeviation="0.82397024"
+         id="feGaussianBlur3506" />
+    </filter>
+    <filter
+       x="-0.31279226"
+       width="1.6255845"
+       y="-0.31279226"
+       height="1.6255845"
+       id="filter3510">
+      <feGaussianBlur
+         stdDeviation="0.85131037"
+         id="feGaussianBlur3512" />
+    </filter>
+    <filter
+       x="-0.37510316"
+       width="1.7502063"
+       y="-0.37510316"
+       height="1.7502063"
+       id="filter3516">
+      <feGaussianBlur
+         stdDeviation="1.0208987"
+         id="feGaussianBlur3518" />
+    </filter>
+    <filter
+       x="-0.41353827"
+       width="1.8270765"
+       y="-0.41353827"
+       height="1.8270765"
+       id="filter3522">
+      <feGaussianBlur
+         stdDeviation="1.1255055"
+         id="feGaussianBlur3524" />
+    </filter>
+    <filter
+       id="filter3530">
+      <feGaussianBlur
+         stdDeviation="0.16623526"
+         id="feGaussianBlur3532" />
+    </filter>
+    <filter
+       x="-0.10506134"
+       width="1.2101227"
+       y="-0.10506134"
+       height="1.2101227"
+       id="filter3536">
+      <feGaussianBlur
+         stdDeviation="0.28593998"
+         id="feGaussianBlur3538" />
+    </filter>
+    <filter
+       x="-0.12861052"
+       width="1.257221"
+       y="-0.12861052"
+       height="1.257221"
+       id="filter3542">
+      <feGaussianBlur
+         stdDeviation="0.35003254"
+         id="feGaussianBlur3544" />
+    </filter>
+    <filter
+       x="-0.19883595"
+       width="1.3976719"
+       y="-0.19883595"
+       height="1.3976719"
+       id="filter3548">
+      <feGaussianBlur
+         stdDeviation="0.54116143"
+         id="feGaussianBlur3550" />
+    </filter>
+    <filter
+       x="-0.2409557"
+       width="1.4819114"
+       y="-0.2409557"
+       height="1.4819114"
+       id="filter3554">
+      <feGaussianBlur
+         stdDeviation="0.65579654"
+         id="feGaussianBlur3556" />
+    </filter>
+    <filter
+       x="-0.26879351"
+       width="1.537587"
+       y="-0.26879351"
+       height="1.537587"
+       id="filter3560">
+      <feGaussianBlur
+         stdDeviation="0.73156128"
+         id="feGaussianBlur3562" />
+    </filter>
+    <filter
+       x="-0.35946567"
+       width="1.7189313"
+       y="-0.35946567"
+       height="1.7189313"
+       id="filter3566">
+      <feGaussianBlur
+         stdDeviation="0.97833895"
+         id="feGaussianBlur3568" />
+    </filter>
+    <filter
+       x="-0.38856919"
+       width="1.7771384"
+       y="-0.38856919"
+       height="1.7771384"
+       id="filter3572">
+      <feGaussianBlur
+         stdDeviation="1.0575485"
+         id="feGaussianBlur3574" />
+    </filter>
+    <filter
+       x="-0.43591387"
+       width="1.8718277"
+       y="-0.43591387"
+       height="1.8718277"
+       id="filter3578">
+      <feGaussianBlur
+         stdDeviation="1.186404"
+         id="feGaussianBlur3580" />
+    </filter>
+    <filter
+       id="filter3586">
+      <feGaussianBlur
+         stdDeviation="0.15889766"
+         id="feGaussianBlur3588" />
+    </filter>
+    <filter
+       id="filter3592">
+      <feGaussianBlur
+         stdDeviation="0.24359875"
+         id="feGaussianBlur3594" />
+    </filter>
+    <filter
+       x="-0.12719755"
+       width="1.2543951"
+       y="-0.12719755"
+       height="1.2543951"
+       id="filter3598">
+      <feGaussianBlur
+         stdDeviation="0.34618693"
+         id="feGaussianBlur3600" />
+    </filter>
+    <filter
+       x="-0.18586325"
+       width="1.3717265"
+       y="-0.18586325"
+       height="1.3717265"
+       id="filter3604">
+      <feGaussianBlur
+         stdDeviation="0.50585432"
+         id="feGaussianBlur3606" />
+    </filter>
+    <filter
+       x="-0.23098861"
+       width="1.4619772"
+       y="-0.23098861"
+       height="1.4619772"
+       id="filter3610">
+      <feGaussianBlur
+         stdDeviation="0.62866965"
+         id="feGaussianBlur3612" />
+    </filter>
+    <filter
+       x="-0.29000815"
+       width="1.5800163"
+       y="-0.29000815"
+       height="1.5800163"
+       id="filter3616">
+      <feGaussianBlur
+         stdDeviation="0.78930006"
+         id="feGaussianBlur3618" />
+    </filter>
+    <filter
+       x="-0.32139738"
+       width="1.6427948"
+       y="-0.32139738"
+       height="1.6427948"
+       id="filter3622">
+      <feGaussianBlur
+         stdDeviation="0.87473047"
+         id="feGaussianBlur3624" />
+    </filter>
+    <filter
+       x="-0.38570958"
+       width="1.7714192"
+       y="-0.38570958"
+       height="1.7714192"
+       id="filter3628">
+      <feGaussianBlur
+         stdDeviation="1.0497656"
+         id="feGaussianBlur3630" />
+    </filter>
+    <filter
+       x="-0.4235"
+       width="1.847"
+       y="-0.4235"
+       height="1.847"
+       id="filter3634">
+      <feGaussianBlur
+         stdDeviation="1.1526179"
+         id="feGaussianBlur3636" />
+    </filter>
+    <filter
+       id="filter3642">
+      <feGaussianBlur
+         stdDeviation="0.14855346"
+         id="feGaussianBlur3644" />
+    </filter>
+    <filter
+       x="-0.11320439"
+       width="1.2264088"
+       y="-0.11320439"
+       height="1.2264088"
+       id="filter3648">
+      <feGaussianBlur
+         stdDeviation="0.30810248"
+         id="feGaussianBlur3650" />
+    </filter>
+    <filter
+       x="-0.15350734"
+       width="1.3070147"
+       y="-0.15350734"
+       height="1.3070147"
+       id="filter3654">
+      <feGaussianBlur
+         stdDeviation="0.4177929"
+         id="feGaussianBlur3656" />
+    </filter>
+    <filter
+       x="-0.18690465"
+       width="1.3738093"
+       y="-0.18690465"
+       height="1.3738093"
+       id="filter3660">
+      <feGaussianBlur
+         stdDeviation="0.50868864"
+         id="feGaussianBlur3662" />
+    </filter>
+    <filter
+       x="-0.2426177"
+       width="1.4852354"
+       y="-0.2426177"
+       height="1.4852354"
+       id="filter3666">
+      <feGaussianBlur
+         stdDeviation="0.66031993"
+         id="feGaussianBlur3668" />
+    </filter>
+    <filter
+       x="-0.26952794"
+       width="1.5390559"
+       y="-0.26952794"
+       height="1.5390559"
+       id="filter3672">
+      <feGaussianBlur
+         stdDeviation="0.73356014"
+         id="feGaussianBlur3674" />
+    </filter>
+    <filter
+       x="-0.35780211"
+       width="1.7156042"
+       y="-0.35780211"
+       height="1.7156042"
+       id="filter3678">
+      <feGaussianBlur
+         stdDeviation="0.97381134"
+         id="feGaussianBlur3680" />
+    </filter>
+    <filter
+       x="-0.39091087"
+       width="1.7818217"
+       y="-0.39091087"
+       height="1.7818217"
+       id="filter3684">
+      <feGaussianBlur
+         stdDeviation="1.0639217"
+         id="feGaussianBlur3686" />
+    </filter>
+    <filter
+       x="-0.42711946"
+       width="1.8542389"
+       y="-0.42711946"
+       height="1.8542389"
+       id="filter3690">
+      <feGaussianBlur
+         stdDeviation="1.1624687"
+         id="feGaussianBlur3692" />
+    </filter>
+    <filter
+       id="filter3696">
+      <feGaussianBlur
+         stdDeviation="0.0025130313"
+         id="feGaussianBlur3698" />
+    </filter>
+    <filter
+       id="filter3702">
+      <feGaussianBlur
+         stdDeviation="0.030306293"
+         id="feGaussianBlur3704" />
+    </filter>
+    <filter
+       id="filter3708">
+      <feGaussianBlur
+         stdDeviation="0.041643686"
+         id="feGaussianBlur3710" />
+    </filter>
+    <filter
+       id="filter3714">
+      <feGaussianBlur
+         stdDeviation="0.053741342"
+         id="feGaussianBlur3716" />
+    </filter>
+    <filter
+       id="filter3720">
+      <feGaussianBlur
+         stdDeviation="0.019336084"
+         id="feGaussianBlur3722" />
+    </filter>
+    <filter
+       id="filter3728">
+      <feGaussianBlur
+         stdDeviation="0.027538608"
+         id="feGaussianBlur3730" />
+    </filter>
+    <filter
+       id="filter3734">
+      <feGaussianBlur
+         stdDeviation="0.011980234"
+         id="feGaussianBlur3736" />
+    </filter>
+    <filter
+       id="filter3746">
+      <feGaussianBlur
+         stdDeviation="0.014656308"
+         id="feGaussianBlur3748" />
+    </filter>
+    <filter
+       id="filter3752">
+      <feGaussianBlur
+         stdDeviation="0.042458024"
+         id="feGaussianBlur3754" />
+    </filter>
+    <filter
+       id="filter3760">
+      <feGaussianBlur
+         stdDeviation="0.062609655"
+         id="feGaussianBlur3762" />
+    </filter>
+    <filter
+       id="filter3768">
+      <feGaussianBlur
+         stdDeviation="0.036467731"
+         id="feGaussianBlur3770" />
+    </filter>
+    <filter
+       id="filter3774">
+      <feGaussianBlur
+         stdDeviation="0.01110042"
+         id="feGaussianBlur3776" />
+    </filter>
+    <filter
+       id="filter3782">
+      <feGaussianBlur
+         stdDeviation="0.034789708"
+         id="feGaussianBlur3784" />
+    </filter>
+    <filter
+       id="filter3788">
+      <feGaussianBlur
+         stdDeviation="0.046814356"
+         id="feGaussianBlur3790" />
+    </filter>
+    <filter
+       id="filter3796">
+      <feGaussianBlur
+         stdDeviation="0.0065951182"
+         id="feGaussianBlur3798" />
+    </filter>
+    <filter
+       id="filter3802">
+      <feGaussianBlur
+         stdDeviation="0.039575814"
+         id="feGaussianBlur3804" />
+    </filter>
+    <filter
+       id="filter3810">
+      <feGaussianBlur
+         stdDeviation="0.012845602"
+         id="feGaussianBlur3812" />
+    </filter>
+    <filter
+       id="filter3822">
+      <feGaussianBlur
+         stdDeviation="0.037223405"
+         id="feGaussianBlur3824" />
+    </filter>
+    <filter
+       id="filter3832">
+      <feGaussianBlur
+         stdDeviation="0.036069328"
+         id="feGaussianBlur3834" />
+    </filter>
+    <filter
+       id="filter3838">
+      <feGaussianBlur
+         stdDeviation="0.011604354"
+         id="feGaussianBlur3840" />
+    </filter>
+    <filter
+       id="filter3846">
+      <feGaussianBlur
+         stdDeviation="0.050664069"
+         id="feGaussianBlur3848" />
+    </filter>
+    <filter
+       id="filter3852">
+      <feGaussianBlur
+         stdDeviation="0.057634159"
+         id="feGaussianBlur3854" />
+    </filter>
+    <filter
+       id="filter3858">
+      <feGaussianBlur
+         stdDeviation="0.09241646"
+         id="feGaussianBlur3860" />
+    </filter>
+    <filter
+       id="filter3864">
+      <feGaussianBlur
+         stdDeviation="0.11148776"
+         id="feGaussianBlur3866" />
+    </filter>
+    <filter
+       id="filter3870">
+      <feGaussianBlur
+         stdDeviation="0.19170749"
+         id="feGaussianBlur3872" />
+    </filter>
+    <filter
+       id="filter3876">
+      <feGaussianBlur
+         stdDeviation="0.14382612"
+         id="feGaussianBlur3878" />
+    </filter>
+    <filter
+       id="filter3882">
+      <feGaussianBlur
+         stdDeviation="0.12959385"
+         id="feGaussianBlur3884" />
+    </filter>
+    <filter
+       id="filter3888">
+      <feGaussianBlur
+         stdDeviation="0.095568269"
+         id="feGaussianBlur3890" />
+    </filter>
+    <filter
+       id="filter3894">
+      <feGaussianBlur
+         stdDeviation="0.092541076"
+         id="feGaussianBlur3896" />
+    </filter>
+    <filter
+       id="filter3900">
+      <feGaussianBlur
+         stdDeviation="0.082877444"
+         id="feGaussianBlur3902" />
+    </filter>
+    <filter
+       id="filter3906">
+      <feGaussianBlur
+         stdDeviation="0.10108857"
+         id="feGaussianBlur3908" />
+    </filter>
+    <filter
+       id="filter3912">
+      <feGaussianBlur
+         stdDeviation="0.18823146"
+         id="feGaussianBlur3914" />
+    </filter>
+    <filter
+       id="filter3918">
+      <feGaussianBlur
+         stdDeviation="0.18802618"
+         id="feGaussianBlur3920" />
+    </filter>
+    <filter
+       id="filter3924">
+      <feGaussianBlur
+         stdDeviation="0.15128426"
+         id="feGaussianBlur3926" />
+    </filter>
+    <filter
+       id="filter3930">
+      <feGaussianBlur
+         stdDeviation="0.11362967"
+         id="feGaussianBlur3932" />
+    </filter>
+    <filter
+       id="filter3936">
+      <feGaussianBlur
+         stdDeviation="0.11237512"
+         id="feGaussianBlur3938" />
+    </filter>
+    <filter
+       id="filter3942">
+      <feGaussianBlur
+         stdDeviation="0.16972173"
+         id="feGaussianBlur3944" />
+    </filter>
+    <filter
+       id="filter3948">
+      <feGaussianBlur
+         stdDeviation="0.11464002"
+         id="feGaussianBlur3950" />
+    </filter>
+    <filter
+       id="filter3954">
+      <feGaussianBlur
+         stdDeviation="0.12702098"
+         id="feGaussianBlur3956" />
+    </filter>
+    <filter
+       id="filter3960">
+      <feGaussianBlur
+         stdDeviation="0.15175032"
+         id="feGaussianBlur3962" />
+    </filter>
+    <filter
+       id="filter3966">
+      <feGaussianBlur
+         stdDeviation="0.099671626"
+         id="feGaussianBlur3968" />
+    </filter>
+    <filter
+       id="filter3972">
+      <feGaussianBlur
+         stdDeviation="0.12162902"
+         id="feGaussianBlur3974" />
+    </filter>
+    <filter
+       id="filter3978">
+      <feGaussianBlur
+         stdDeviation="0.14496786"
+         id="feGaussianBlur3980" />
+    </filter>
+    <filter
+       id="filter3984">
+      <feGaussianBlur
+         stdDeviation="0.12788032"
+         id="feGaussianBlur3986" />
+    </filter>
+    <filter
+       id="filter3990">
+      <feGaussianBlur
+         stdDeviation="0.18945703"
+         id="feGaussianBlur3992" />
+    </filter>
+    <filter
+       id="filter3996">
+      <feGaussianBlur
+         stdDeviation="0.089071601"
+         id="feGaussianBlur3998" />
+    </filter>
+    <filter
+       id="filter4002">
+      <feGaussianBlur
+         stdDeviation="0.083169844"
+         id="feGaussianBlur4004" />
+    </filter>
+    <filter
+       id="filter4008">
+      <feGaussianBlur
+         stdDeviation="0.17416514"
+         id="feGaussianBlur4010" />
+    </filter>
+    <filter
+       id="filter4014">
+      <feGaussianBlur
+         stdDeviation="0.1082853"
+         id="feGaussianBlur4016" />
+    </filter>
+    <filter
+       id="filter4020">
+      <feGaussianBlur
+         stdDeviation="0.1621304"
+         id="feGaussianBlur4022" />
+    </filter>
+    <filter
+       id="filter4026">
+      <feGaussianBlur
+         stdDeviation="0.079451294"
+         id="feGaussianBlur4028" />
+    </filter>
+    <filter
+       id="filter4032">
+      <feGaussianBlur
+         stdDeviation="0.17703656"
+         id="feGaussianBlur4034" />
+    </filter>
+    <filter
+       id="filter4038">
+      <feGaussianBlur
+         stdDeviation="0.098025244"
+         id="feGaussianBlur4040" />
+    </filter>
+    <filter
+       id="filter4044">
+      <feGaussianBlur
+         stdDeviation="0.14845643"
+         id="feGaussianBlur4046" />
+    </filter>
+    <filter
+       id="filter4050">
+      <feGaussianBlur
+         stdDeviation="0.0731429"
+         id="feGaussianBlur4052" />
+    </filter>
+    <filter
+       id="filter4056">
+      <feGaussianBlur
+         stdDeviation="0.07459914"
+         id="feGaussianBlur4058" />
+    </filter>
+    <filter
+       id="filter4062">
+      <feGaussianBlur
+         stdDeviation="0.19529029"
+         id="feGaussianBlur4064" />
+    </filter>
+    <filter
+       id="filter4068">
+      <feGaussianBlur
+         stdDeviation="0.19070701"
+         id="feGaussianBlur4070" />
+    </filter>
+    <filter
+       id="filter4074">
+      <feGaussianBlur
+         stdDeviation="0.098566893"
+         id="feGaussianBlur4076" />
+    </filter>
+    <filter
+       id="filter4084">
+      <feGaussianBlur
+         stdDeviation="0.089230872"
+         id="feGaussianBlur4086" />
+    </filter>
+    <filter
+       id="filter4090">
+      <feGaussianBlur
+         stdDeviation="0.096409182"
+         id="feGaussianBlur4092" />
+    </filter>
+    <filter
+       id="filter4096">
+      <feGaussianBlur
+         stdDeviation="0.25146046"
+         id="feGaussianBlur4098" />
+    </filter>
+    <filter
+       id="filter4102">
+      <feGaussianBlur
+         stdDeviation="0.20135046"
+         id="feGaussianBlur4104" />
+    </filter>
+    <filter
+       x="-0.13916724"
+       width="1.2783345"
+       y="-0.13916724"
+       height="1.2783345"
+       id="filter4108">
+      <feGaussianBlur
+         stdDeviation="0.37876421"
+         id="feGaussianBlur4110" />
+    </filter>
+    <filter
+       x="-0.13306715"
+       width="1.2661343"
+       y="-0.13306715"
+       height="1.2661343"
+       id="filter4114">
+      <feGaussianBlur
+         stdDeviation="0.36216191"
+         id="feGaussianBlur4116" />
+    </filter>
+    <filter
+       x="-0.20670517"
+       width="1.4134103"
+       y="-0.20670517"
+       height="1.4134103"
+       id="filter4120">
+      <feGaussianBlur
+         stdDeviation="0.56257867"
+         id="feGaussianBlur4122" />
+    </filter>
+    <filter
+       x="-0.18020422"
+       width="1.3604084"
+       y="-0.18020422"
+       height="1.3604084"
+       id="filter4126">
+      <feGaussianBlur
+         stdDeviation="0.49045243"
+         id="feGaussianBlur4128" />
+    </filter>
+    <filter
+       x="-0.24330299"
+       width="1.486606"
+       y="-0.24330299"
+       height="1.486606"
+       id="filter4132">
+      <feGaussianBlur
+         stdDeviation="0.66218504"
+         id="feGaussianBlur4134" />
+    </filter>
+    <filter
+       x="-0.22830934"
+       width="1.4566187"
+       y="-0.22830934"
+       height="1.4566187"
+       id="filter4138">
+      <feGaussianBlur
+         stdDeviation="0.62137763"
+         id="feGaussianBlur4140" />
+    </filter>
+    <filter
+       x="-0.27706333"
+       width="1.5541267"
+       y="-0.27706333"
+       height="1.5541267"
+       id="filter4144">
+      <feGaussianBlur
+         stdDeviation="0.75406882"
+         id="feGaussianBlur4146" />
+    </filter>
+    <filter
+       x="-0.27553757"
+       width="1.5510751"
+       y="-0.27553757"
+       height="1.5510751"
+       id="filter4150">
+      <feGaussianBlur
+         stdDeviation="0.74991622"
+         id="feGaussianBlur4152" />
+    </filter>
+    <filter
+       x="-0.34308911"
+       width="1.6861782"
+       y="-0.34308911"
+       height="1.6861782"
+       id="filter4156">
+      <feGaussianBlur
+         stdDeviation="0.93376772"
+         id="feGaussianBlur4158" />
+    </filter>
+    <filter
+       x="-0.3349122"
+       width="1.6698244"
+       y="-0.3349122"
+       height="1.6698244"
+       id="filter4162">
+      <feGaussianBlur
+         stdDeviation="0.91151305"
+         id="feGaussianBlur4164" />
+    </filter>
+    <filter
+       x="-0.36139917"
+       width="1.7227983"
+       y="-0.36139917"
+       height="1.7227983"
+       id="filter4168">
+      <feGaussianBlur
+         stdDeviation="0.98360125"
+         id="feGaussianBlur4170" />
+    </filter>
+    <filter
+       x="-0.40340122"
+       width="1.8068024"
+       y="-0.40340122"
+       height="1.8068024"
+       id="filter4174">
+      <feGaussianBlur
+         stdDeviation="1.0979161"
+         id="feGaussianBlur4176" />
+    </filter>
+    <filter
+       x="-0.43055346"
+       width="1.8611069"
+       y="-0.43055346"
+       height="1.8611069"
+       id="filter4180">
+      <feGaussianBlur
+         stdDeviation="1.1718149"
+         id="feGaussianBlur4182" />
+    </filter>
+    <filter
+       x="-0.42024881"
+       width="1.8404976"
+       y="-0.42024881"
+       height="1.8404976"
+       id="filter4186">
+      <feGaussianBlur
+         stdDeviation="1.1437693"
+         id="feGaussianBlur4188" />
+    </filter>
+    <filter
+       x="-0.46258698"
+       width="1.925174"
+       y="-0.46258698"
+       height="1.925174"
+       id="filter4192">
+      <feGaussianBlur
+         stdDeviation="1.2589988"
+         id="feGaussianBlur4194" />
+    </filter>
+    <filter
+       x="-0.48890042"
+       width="1.9778008"
+       y="-0.48890042"
+       height="1.9778008"
+       id="filter4198">
+      <feGaussianBlur
+         stdDeviation="1.3306148"
+         id="feGaussianBlur4200" />
+    </filter>
+    <filter
+       x="-0.52896512"
+       width="2.0579302"
+       y="-0.52896512"
+       height="2.0579302"
+       id="filter4204">
+      <feGaussianBlur
+         stdDeviation="1.4396568"
+         id="feGaussianBlur4206" />
+    </filter>
+    <filter
+       x="-0.50763412"
+       width="2.0152682"
+       y="-0.50763412"
+       height="2.0152682"
+       id="filter4210">
+      <feGaussianBlur
+         stdDeviation="1.3816013"
+         id="feGaussianBlur4212" />
+    </filter>
+    <filter
+       x="-0.55778624"
+       width="2.1155725"
+       y="-0.55778624"
+       height="2.1155725"
+       id="filter4216">
+      <feGaussianBlur
+         stdDeviation="1.5180977"
+         id="feGaussianBlur4218" />
+    </filter>
+    <filter
+       x="-0.57883381"
+       width="2.1576676"
+       y="-0.57883381"
+       height="2.1576676"
+       id="filter4222">
+      <feGaussianBlur
+         stdDeviation="1.5753818"
+         id="feGaussianBlur4224" />
+    </filter>
+    <filter
+       x="-0.64235606"
+       width="2.2847121"
+       y="-0.64235606"
+       height="2.2847121"
+       id="filter4228">
+      <feGaussianBlur
+         stdDeviation="1.748267"
+         id="feGaussianBlur4230" />
+    </filter>
+    <filter
+       x="-0.63339319"
+       width="2.2667864"
+       y="-0.63339319"
+       height="2.2667864"
+       id="filter4234">
+      <feGaussianBlur
+         stdDeviation="1.7238732"
+         id="feGaussianBlur4236" />
+    </filter>
+    <filter
+       x="-0.65576071"
+       width="2.3115214"
+       y="-0.65576071"
+       height="2.3115214"
+       id="filter4240">
+      <feGaussianBlur
+         stdDeviation="1.7847497"
+         id="feGaussianBlur4242" />
+    </filter>
+    <filter
+       x="-0.68369688"
+       width="2.3673938"
+       y="-0.68369688"
+       height="2.3673938"
+       id="filter4246">
+      <feGaussianBlur
+         stdDeviation="1.8607821"
+         id="feGaussianBlur4248" />
+    </filter>
+    <filter
+       x="-0.69638685"
+       width="2.3927737"
+       y="-0.69638685"
+       height="2.3927737"
+       id="filter4252">
+      <feGaussianBlur
+         stdDeviation="1.8953197"
+         id="feGaussianBlur4254" />
+    </filter>
+    <filter
+       x="-0.72525579"
+       width="2.4505116"
+       y="-0.72525579"
+       height="2.4505116"
+       id="filter4258">
+      <feGaussianBlur
+         stdDeviation="1.9738908"
+         id="feGaussianBlur4260" />
+    </filter>
+    <filter
+       id="filter4264">
+      <feGaussianBlur
+         stdDeviation="0.034680434"
+         id="feGaussianBlur4266" />
+    </filter>
+    <filter
+       x="-0.11297701"
+       width="1.225954"
+       y="-0.11297701"
+       height="1.225954"
+       id="filter4270">
+      <feGaussianBlur
+         stdDeviation="0.30748365"
+         id="feGaussianBlur4272" />
+    </filter>
+    <filter
+       x="-0.22957316"
+       width="1.4591463"
+       y="-0.22957316"
+       height="1.4591463"
+       id="filter4276">
+      <feGaussianBlur
+         stdDeviation="0.6248173"
+         id="feGaussianBlur4278" />
+    </filter>
+    <filter
+       id="filter4282">
+      <feGaussianBlur
+         stdDeviation="0.044224069"
+         id="feGaussianBlur4284" />
+    </filter>
+    <filter
+       id="filter4288">
+      <feGaussianBlur
+         stdDeviation="0.19195257"
+         id="feGaussianBlur4290" />
+    </filter>
+    <filter
+       x="-0.11241407"
+       width="1.2248281"
+       y="-0.11241407"
+       height="1.2248281"
+       id="filter4294">
+      <feGaussianBlur
+         stdDeviation="0.30595151"
+         id="feGaussianBlur4296" />
+    </filter>
+    <filter
+       x="-0.1211947"
+       width="1.2423894"
+       y="-0.1211947"
+       height="1.2423894"
+       id="filter4300">
+      <feGaussianBlur
+         stdDeviation="0.3298493"
+         id="feGaussianBlur4302" />
+    </filter>
+    <filter
+       x="-0.1786772"
+       width="1.3573544"
+       y="-0.1786772"
+       height="1.3573544"
+       id="filter4306">
+      <feGaussianBlur
+         stdDeviation="0.48629641"
+         id="feGaussianBlur4308" />
+    </filter>
+    <filter
+       x="-0.23906237"
+       width="1.4781247"
+       y="-0.23906237"
+       height="1.4781247"
+       id="filter4312">
+      <feGaussianBlur
+         stdDeviation="0.65064357"
+         id="feGaussianBlur4314" />
+    </filter>
+    <filter
+       x="-0.27745368"
+       width="1.5549074"
+       y="-0.27745368"
+       height="1.5549074"
+       id="filter4318">
+      <feGaussianBlur
+         stdDeviation="0.7551312"
+         id="feGaussianBlur4320" />
+    </filter>
+    <filter
+       id="filter4324">
+      <feGaussianBlur
+         stdDeviation="0.044895378"
+         id="feGaussianBlur4326" />
+    </filter>
+    <filter
+       id="filter4330">
+      <feGaussianBlur
+         stdDeviation="0.16513667"
+         id="feGaussianBlur4332" />
+    </filter>
+    <filter
+       x="-0.10720606"
+       width="1.2144121"
+       y="-0.10720606"
+       height="1.2144121"
+       id="filter4336">
+      <feGaussianBlur
+         stdDeviation="0.29177714"
+         id="feGaussianBlur4338" />
+    </filter>
+    <filter
+       x="-0.15838918"
+       width="1.3167784"
+       y="-0.15838918"
+       height="1.3167784"
+       id="filter4342">
+      <feGaussianBlur
+         stdDeviation="0.43107955"
+         id="feGaussianBlur4344" />
+    </filter>
+    <filter
+       x="-0.17001974"
+       width="1.3400395"
+       y="-0.17001974"
+       height="1.3400395"
+       id="filter4348">
+      <feGaussianBlur
+         stdDeviation="0.46273386"
+         id="feGaussianBlur4350" />
+    </filter>
+    <filter
+       x="-0.25167186"
+       width="1.5033437"
+       y="-0.25167186"
+       height="1.5033437"
+       id="filter4354">
+      <feGaussianBlur
+         stdDeviation="0.68496216"
+         id="feGaussianBlur4356" />
+    </filter>
+    <filter
+       x="-0.267254"
+       width="1.534508"
+       y="-0.267254"
+       height="1.534508"
+       id="filter4360">
+      <feGaussianBlur
+         stdDeviation="0.72737128"
+         id="feGaussianBlur4362" />
+    </filter>
+    <filter
+       x="-0.33158342"
+       width="1.6631668"
+       y="-0.33158342"
+       height="1.6631668"
+       id="filter4366">
+      <feGaussianBlur
+         stdDeviation="0.90245328"
+         id="feGaussianBlur4368" />
+    </filter>
+    <filter
+       x="-0.36609217"
+       width="1.7321843"
+       y="-0.36609217"
+       height="1.7321843"
+       id="filter4372">
+      <feGaussianBlur
+         stdDeviation="0.99637396"
+         id="feGaussianBlur4374" />
+    </filter>
+    <filter
+       x="-0.42796274"
+       width="1.8559255"
+       y="-0.42796274"
+       height="1.8559255"
+       id="filter4378">
+      <feGaussianBlur
+         stdDeviation="1.1647639"
+         id="feGaussianBlur4380" />
+    </filter>
+    <filter
+       x="-0.46923011"
+       width="1.9384602"
+       y="-0.46923011"
+       height="1.9384602"
+       id="filter4384">
+      <feGaussianBlur
+         stdDeviation="1.2770791"
+         id="feGaussianBlur4386" />
+    </filter>
+    <filter
+       x="-0.50640947"
+       width="2.0128189"
+       y="-0.50640947"
+       height="2.0128189"
+       id="filter4390">
+      <feGaussianBlur
+         stdDeviation="1.3782682"
+         id="feGaussianBlur4392" />
+    </filter>
+    <filter
+       id="filter4398">
+      <feGaussianBlur
+         stdDeviation="0.17426681"
+         id="feGaussianBlur4400" />
+    </filter>
+    <filter
+       id="filter4404">
+      <feGaussianBlur
+         stdDeviation="0.20695621"
+         id="feGaussianBlur4406" />
+    </filter>
+    <filter
+       x="-0.12453349"
+       width="1.249067"
+       y="-0.12453349"
+       height="1.249067"
+       id="filter4410">
+      <feGaussianBlur
+         stdDeviation="0.3389363"
+         id="feGaussianBlur4412" />
+    </filter>
+    <filter
+       x="-0.21439888"
+       width="1.4287978"
+       y="-0.21439888"
+       height="1.4287978"
+       id="filter4416">
+      <feGaussianBlur
+         stdDeviation="0.58351825"
+         id="feGaussianBlur4418" />
+    </filter>
+    <filter
+       x="-0.22219737"
+       width="1.4443947"
+       y="-0.22219737"
+       height="1.4443947"
+       id="filter4422">
+      <feGaussianBlur
+         stdDeviation="0.60474299"
+         id="feGaussianBlur4424" />
+    </filter>
+    <filter
+       x="-0.28352954"
+       width="1.5670591"
+       y="-0.28352954"
+       height="1.5670591"
+       id="filter4428">
+      <feGaussianBlur
+         stdDeviation="0.77166757"
+         id="feGaussianBlur4430" />
+    </filter>
+    <filter
+       x="-0.33932692"
+       width="1.6786538"
+       y="-0.33932692"
+       height="1.6786538"
+       id="filter4434">
+      <feGaussianBlur
+         stdDeviation="0.92352837"
+         id="feGaussianBlur4436" />
+    </filter>
+    <filter
+       x="-0.37341844"
+       width="1.7468369"
+       y="-0.37341844"
+       height="1.7468369"
+       id="filter4440">
+      <feGaussianBlur
+         stdDeviation="1.0163135"
+         id="feGaussianBlur4442" />
+    </filter>
+    <filter
+       x="-0.45418671"
+       width="1.9083734"
+       y="-0.45418671"
+       height="1.9083734"
+       id="filter4446">
+      <feGaussianBlur
+         stdDeviation="1.2361363"
+         id="feGaussianBlur4448" />
+    </filter>
+    <filter
+       x="-0.49428011"
+       width="1.9885602"
+       y="-0.49428011"
+       height="1.9885602"
+       id="filter4452">
+      <feGaussianBlur
+         stdDeviation="1.3452564"
+         id="feGaussianBlur4454" />
+    </filter>
+    <filter
+       x="-0.50507958"
+       width="2.0101592"
+       y="-0.50507958"
+       height="2.0101592"
+       id="filter4458">
+      <feGaussianBlur
+         stdDeviation="1.3746487"
+         id="feGaussianBlur4460" />
+    </filter>
+    <filter
+       x="-0.62152089"
+       width="2.2430418"
+       y="-0.62152089"
+       height="2.2430418"
+       id="filter4464">
+      <feGaussianBlur
+         stdDeviation="1.691561"
+         id="feGaussianBlur4466" />
+    </filter>
+    <filter
+       id="filter4472">
+      <feGaussianBlur
+         stdDeviation="0.10453632"
+         id="feGaussianBlur4474" />
+    </filter>
+    <filter
+       x="-0.11349907"
+       width="1.2269981"
+       y="-0.11349907"
+       height="1.2269981"
+       id="filter4478">
+      <feGaussianBlur
+         stdDeviation="0.30890451"
+         id="feGaussianBlur4480" />
+    </filter>
+    <filter
+       x="-0.14892072"
+       width="1.2978414"
+       y="-0.14892072"
+       height="1.2978414"
+       id="filter4484">
+      <feGaussianBlur
+         stdDeviation="0.40530974"
+         id="feGaussianBlur4486" />
+    </filter>
+    <filter
+       x="-0.1916642"
+       width="1.3833284"
+       y="-0.1916642"
+       height="1.3833284"
+       id="filter4490">
+      <feGaussianBlur
+         stdDeviation="0.52164246"
+         id="feGaussianBlur4492" />
+    </filter>
+    <filter
+       x="-0.21627814"
+       width="1.4325563"
+       y="-0.21627814"
+       height="1.4325563"
+       id="filter4496">
+      <feGaussianBlur
+         stdDeviation="0.58863293"
+         id="feGaussianBlur4498" />
+    </filter>
+    <filter
+       x="-0.28472778"
+       width="1.5694556"
+       y="-0.28472778"
+       height="1.5694556"
+       id="filter4502">
+      <feGaussianBlur
+         stdDeviation="0.77492875"
+         id="feGaussianBlur4504" />
+    </filter>
+    <filter
+       x="-0.3422242"
+       width="1.6844484"
+       y="-0.3422242"
+       height="1.6844484"
+       id="filter4508">
+      <feGaussianBlur
+         stdDeviation="0.93141376"
+         id="feGaussianBlur4510" />
+    </filter>
+    <filter
+       x="-0.36766771"
+       width="1.7353354"
+       y="-0.36766771"
+       height="1.7353354"
+       id="filter4514">
+      <feGaussianBlur
+         stdDeviation="1.000662"
+         id="feGaussianBlur4516" />
+    </filter>
+    <filter
+       x="-0.41660377"
+       width="1.8332075"
+       y="-0.41660377"
+       height="1.8332075"
+       id="filter4520">
+      <feGaussianBlur
+         stdDeviation="1.1338487"
+         id="feGaussianBlur4522" />
+    </filter>
+    <filter
+       x="-0.47618939"
+       width="1.9523788"
+       y="-0.47618939"
+       height="1.9523788"
+       id="filter4526">
+      <feGaussianBlur
+         stdDeviation="1.2960198"
+         id="feGaussianBlur4528" />
+    </filter>
+    <filter
+       x="-0.53310171"
+       width="2.0662034"
+       y="-0.53310171"
+       height="2.0662034"
+       id="filter4532">
+      <feGaussianBlur
+         stdDeviation="1.4509151"
+         id="feGaussianBlur4534" />
+    </filter>
+    <filter
+       x="-0.59997276"
+       width="2.1999455"
+       y="-0.59997276"
+       height="2.1999455"
+       id="filter4538">
+      <feGaussianBlur
+         stdDeviation="1.6329145"
+         id="feGaussianBlur4540" />
+    </filter>
+    <filter
+       id="filter4544">
+      <feGaussianBlur
+         stdDeviation="0.039304547"
+         id="feGaussianBlur4546" />
+    </filter>
+    <filter
+       id="filter4550">
+      <feGaussianBlur
+         stdDeviation="0.076149485"
+         id="feGaussianBlur4552" />
+    </filter>
+    <filter
+       id="filter4556">
+      <feGaussianBlur
+         stdDeviation="0.25570443"
+         id="feGaussianBlur4558" />
+    </filter>
+    <filter
+       x="-0.16335574"
+       width="1.3267115"
+       y="-0.16335574"
+       height="1.3267115"
+       id="filter4562">
+      <feGaussianBlur
+         stdDeviation="0.4445968"
+         id="feGaussianBlur4564" />
+    </filter>
+    <filter
+       x="-0.21579389"
+       width="1.4315878"
+       y="-0.21579389"
+       height="1.4315878"
+       id="filter4568">
+      <feGaussianBlur
+         stdDeviation="0.58731498"
+         id="feGaussianBlur4570" />
+    </filter>
+    <filter
+       x="-0.21950715"
+       width="1.4390143"
+       y="-0.21950715"
+       height="1.4390143"
+       id="filter4574">
+      <feGaussianBlur
+         stdDeviation="0.59742115"
+         id="feGaussianBlur4576" />
+    </filter>
+    <filter
+       x="-0.30035485"
+       width="1.6007097"
+       y="-0.30035485"
+       height="1.6007097"
+       id="filter4580">
+      <feGaussianBlur
+         stdDeviation="0.81746013"
+         id="feGaussianBlur4582" />
+    </filter>
+    <filter
+       x="-0.3512889"
+       width="1.7025778"
+       y="-0.3512889"
+       height="1.7025778"
+       id="filter4586">
+      <feGaussianBlur
+         stdDeviation="0.95608466"
+         id="feGaussianBlur4588" />
+    </filter>
+    <filter
+       x="-0.3972534"
+       width="1.7945068"
+       y="-0.3972534"
+       height="1.7945068"
+       id="filter4592">
+      <feGaussianBlur
+         stdDeviation="1.0811839"
+         id="feGaussianBlur4594" />
+    </filter>
+    <filter
+       x="-0.43123736"
+       width="1.8624747"
+       y="-0.43123736"
+       height="1.8624747"
+       id="filter4598">
+      <feGaussianBlur
+         stdDeviation="1.1736762"
+         id="feGaussianBlur4600" />
+    </filter>
+    <filter
+       x="-0.45863873"
+       width="1.9172775"
+       y="-0.45863873"
+       height="1.9172775"
+       id="filter4604">
+      <feGaussianBlur
+         stdDeviation="1.2482531"
+         id="feGaussianBlur4606" />
+    </filter>
+    <filter
+       x="-0.52975784"
+       width="2.0595157"
+       y="-0.52975784"
+       height="2.0595157"
+       id="filter4610">
+      <feGaussianBlur
+         stdDeviation="1.4418143"
+         id="feGaussianBlur4612" />
+    </filter>
+    <filter
+       id="filter4618">
+      <feGaussianBlur
+         stdDeviation="0.13866498"
+         id="feGaussianBlur4620" />
+    </filter>
+    <filter
+       id="filter4624">
+      <feGaussianBlur
+         stdDeviation="0.22698549"
+         id="feGaussianBlur4626" />
+    </filter>
+    <filter
+       x="-0.14005551"
+       width="1.280111"
+       y="-0.14005551"
+       height="1.280111"
+       id="filter4630">
+      <feGaussianBlur
+         stdDeviation="0.38118177"
+         id="feGaussianBlur4632" />
+    </filter>
+    <filter
+       x="-0.18402733"
+       width="1.3680547"
+       y="-0.18402733"
+       height="1.3680547"
+       id="filter4636">
+      <feGaussianBlur
+         stdDeviation="0.50085759"
+         id="feGaussianBlur4638" />
+    </filter>
+    <filter
+       x="-0.24011992"
+       width="1.4802398"
+       y="-0.24011992"
+       height="1.4802398"
+       id="filter4642">
+      <feGaussianBlur
+         stdDeviation="0.65352186"
+         id="feGaussianBlur4644" />
+    </filter>
+    <filter
+       x="-0.26466253"
+       width="1.5293251"
+       y="-0.26466253"
+       height="1.5293251"
+       id="filter4648">
+      <feGaussianBlur
+         stdDeviation="0.72031819"
+         id="feGaussianBlur4650" />
+    </filter>
+    <filter
+       x="-0.35128942"
+       width="1.7025788"
+       y="-0.35128942"
+       height="1.7025788"
+       id="filter4654">
+      <feGaussianBlur
+         stdDeviation="0.95608608"
+         id="feGaussianBlur4656" />
+    </filter>
+    <filter
+       x="-0.38661167"
+       width="1.7732233"
+       y="-0.38661167"
+       height="1.7732233"
+       id="filter4660">
+      <feGaussianBlur
+         stdDeviation="1.0522208"
+         id="feGaussianBlur4662" />
+    </filter>
+    <filter
+       x="-0.42591019"
+       width="1.8518204"
+       y="-0.42591019"
+       height="1.8518204"
+       id="filter4666">
+      <feGaussianBlur
+         stdDeviation="1.1591776"
+         id="feGaussianBlur4668" />
+    </filter>
+    <filter
+       x="-0.48898656"
+       width="1.9779731"
+       y="-0.48898656"
+       height="1.9779731"
+       id="filter4672">
+      <feGaussianBlur
+         stdDeviation="1.3308492"
+         id="feGaussianBlur4674" />
+    </filter>
+    <filter
+       x="-0.51718517"
+       width="2.0343703"
+       y="-0.51718517"
+       height="2.0343703"
+       id="filter4678">
+      <feGaussianBlur
+         stdDeviation="1.4075959"
+         id="feGaussianBlur4680" />
+    </filter>
+    <filter
+       id="filter4684">
+      <feGaussianBlur
+         stdDeviation="0.02770413"
+         id="feGaussianBlur4686" />
+    </filter>
+    <filter
+       id="filter4690">
+      <feGaussianBlur
+         stdDeviation="0.16484802"
+         id="feGaussianBlur4692" />
+    </filter>
+    <filter
+       x="-0.11950933"
+       width="1.2390187"
+       y="-0.11950933"
+       height="1.2390187"
+       id="filter4696">
+      <feGaussianBlur
+         stdDeviation="0.3252623"
+         id="feGaussianBlur4698" />
+    </filter>
+    <filter
+       x="-0.16372041"
+       width="1.3274408"
+       y="-0.16372041"
+       height="1.3274408"
+       id="filter4702">
+      <feGaussianBlur
+         stdDeviation="0.44558929"
+         id="feGaussianBlur4704" />
+    </filter>
+    <filter
+       x="-0.21350999"
+       width="1.42702"
+       y="-0.21350999"
+       height="1.42702"
+       id="filter4708">
+      <feGaussianBlur
+         stdDeviation="0.58109899"
+         id="feGaussianBlur4710" />
+    </filter>
+    <filter
+       x="-0.23795555"
+       width="1.4759111"
+       y="-0.23795555"
+       height="1.4759111"
+       id="filter4714">
+      <feGaussianBlur
+         stdDeviation="0.64763119"
+         id="feGaussianBlur4716" />
+    </filter>
+    <filter
+       x="-0.30613573"
+       width="1.6122715"
+       y="-0.30613573"
+       height="1.6122715"
+       id="filter4720">
+      <feGaussianBlur
+         stdDeviation="0.83319365"
+         id="feGaussianBlur4722" />
+    </filter>
+    <filter
+       x="-0.34147808"
+       width="1.6829562"
+       y="-0.34147808"
+       height="1.6829562"
+       id="filter4726">
+      <feGaussianBlur
+         stdDeviation="0.92938307"
+         id="feGaussianBlur4728" />
+    </filter>
+    <filter
+       x="-0.36392297"
+       width="1.7278459"
+       y="-0.36392297"
+       height="1.7278459"
+       id="filter4732">
+      <feGaussianBlur
+         stdDeviation="0.99047016"
+         id="feGaussianBlur4734" />
+    </filter>
+    <filter
+       x="-0.41394345"
+       width="1.8278869"
+       y="-0.41394345"
+       height="1.8278869"
+       id="filter4738">
+      <feGaussianBlur
+         stdDeviation="1.1266083"
+         id="feGaussianBlur4740" />
+    </filter>
+    <filter
+       x="-0.47322939"
+       width="1.9464588"
+       y="-0.47322939"
+       height="1.9464588"
+       id="filter4744">
+      <feGaussianBlur
+         stdDeviation="1.2879637"
+         id="feGaussianBlur4746" />
+    </filter>
+    <filter
+       x="-0.52612452"
+       width="2.052249"
+       y="-0.52612452"
+       height="2.052249"
+       id="filter4750">
+      <feGaussianBlur
+         stdDeviation="1.4319256"
+         id="feGaussianBlur4752" />
+    </filter>
+    <filter
+       x="-0.63714375"
+       width="2.2742875"
+       y="-0.63714375"
+       height="2.2742875"
+       id="filter4756">
+      <feGaussianBlur
+         stdDeviation="1.7340809"
+         id="feGaussianBlur4758" />
+    </filter>
+    <filter
+       id="filter4762">
+      <feGaussianBlur
+         stdDeviation="0.050140689"
+         id="feGaussianBlur4764" />
+    </filter>
+    <filter
+       id="filter4768">
+      <feGaussianBlur
+         stdDeviation="0.16502112"
+         id="feGaussianBlur4770" />
+    </filter>
+    <filter
+       id="filter4774">
+      <feGaussianBlur
+         stdDeviation="0.26536165"
+         id="feGaussianBlur4776" />
+    </filter>
+    <filter
+       x="-0.16123556"
+       width="1.3224711"
+       y="-0.16123556"
+       height="1.3224711"
+       id="filter4780">
+      <feGaussianBlur
+         stdDeviation="0.43882641"
+         id="feGaussianBlur4782" />
+    </filter>
+    <filter
+       x="-0.16855596"
+       width="1.3371119"
+       y="-0.16855596"
+       height="1.3371119"
+       id="filter4786">
+      <feGaussianBlur
+         stdDeviation="0.45874995"
+         id="feGaussianBlur4788" />
+    </filter>
+    <filter
+       x="-0.26058865"
+       width="1.5211773"
+       y="-0.26058865"
+       height="1.5211773"
+       id="filter4792">
+      <feGaussianBlur
+         stdDeviation="0.70923054"
+         id="feGaussianBlur4794" />
+    </filter>
+    <filter
+       x="-0.27111149"
+       width="1.542223"
+       y="-0.27111149"
+       height="1.542223"
+       id="filter4798">
+      <feGaussianBlur
+         stdDeviation="0.73787001"
+         id="feGaussianBlur4800" />
+    </filter>
+    <filter
+       x="-0.34126693"
+       width="1.6825339"
+       y="-0.34126693"
+       height="1.6825339"
+       id="filter4804">
+      <feGaussianBlur
+         stdDeviation="0.92880839"
+         id="feGaussianBlur4806" />
+    </filter>
+    <filter
+       x="-0.37664924"
+       width="1.7532985"
+       y="-0.37664924"
+       height="1.7532985"
+       id="filter4810">
+      <feGaussianBlur
+         stdDeviation="1.0251066"
+         id="feGaussianBlur4812" />
+    </filter>
+    <filter
+       x="-0.42212308"
+       width="1.8442462"
+       y="-0.42212308"
+       height="1.8442462"
+       id="filter4816">
+      <feGaussianBlur
+         stdDeviation="1.1488704"
+         id="feGaussianBlur4818" />
+    </filter>
+    <filter
+       x="-0.54796313"
+       width="2.0959263"
+       y="-0.54796313"
+       height="2.0959263"
+       id="filter4822">
+      <feGaussianBlur
+         stdDeviation="1.4913626"
+         id="feGaussianBlur4824" />
+    </filter>
+    <filter
+       x="-0.61144477"
+       width="2.2228895"
+       y="-0.61144477"
+       height="2.2228895"
+       id="filter4828">
+      <feGaussianBlur
+         stdDeviation="1.6641373"
+         id="feGaussianBlur4830" />
+    </filter>
+    <filter
+       id="filter4836">
+      <feGaussianBlur
+         stdDeviation="0.14138356"
+         id="feGaussianBlur4838" />
+    </filter>
+    <filter
+       id="filter4842">
+      <feGaussianBlur
+         stdDeviation="0.21300944"
+         id="feGaussianBlur4844" />
+    </filter>
+    <filter
+       x="-0.16566398"
+       width="1.331328"
+       y="-0.16566398"
+       height="1.331328"
+       id="filter4848">
+      <feGaussianBlur
+         stdDeviation="0.450879"
+         id="feGaussianBlur4850" />
+    </filter>
+    <filter
+       x="-0.17854326"
+       width="1.3570865"
+       y="-0.17854326"
+       height="1.3570865"
+       id="filter4854">
+      <feGaussianBlur
+         stdDeviation="0.48593187"
+         id="feGaussianBlur4856" />
+    </filter>
+    <filter
+       x="-0.26394315"
+       width="1.5278863"
+       y="-0.26394315"
+       height="1.5278863"
+       id="filter4860">
+      <feGaussianBlur
+         stdDeviation="0.71836031"
+         id="feGaussianBlur4862" />
+    </filter>
+    <filter
+       x="-0.28286261"
+       width="1.5657252"
+       y="-0.28286261"
+       height="1.5657252"
+       id="filter4866">
+      <feGaussianBlur
+         stdDeviation="0.76985241"
+         id="feGaussianBlur4868" />
+    </filter>
+    <filter
+       x="-0.35806459"
+       width="1.7161292"
+       y="-0.35806459"
+       height="1.7161292"
+       id="filter4872">
+      <feGaussianBlur
+         stdDeviation="0.97452571"
+         id="feGaussianBlur4874" />
+    </filter>
+    <filter
+       x="-0.36446966"
+       width="1.7289393"
+       y="-0.36446966"
+       height="1.7289393"
+       id="filter4878">
+      <feGaussianBlur
+         stdDeviation="0.99195806"
+         id="feGaussianBlur4880" />
+    </filter>
+    <filter
+       x="-0.41216202"
+       width="1.824324"
+       y="-0.41216202"
+       height="1.824324"
+       id="filter4884">
+      <feGaussianBlur
+         stdDeviation="1.1217599"
+         id="feGaussianBlur4886" />
+    </filter>
+    <filter
+       x="-0.51496336"
+       width="2.0299267"
+       y="-0.51496336"
+       height="2.0299267"
+       id="filter4890">
+      <feGaussianBlur
+         stdDeviation="1.4015489"
+         id="feGaussianBlur4892" />
+    </filter>
+    <filter
+       x="-0.57460021"
+       width="2.1492004"
+       y="-0.57460021"
+       height="2.1492004"
+       id="filter4896">
+      <feGaussianBlur
+         stdDeviation="1.5638594"
+         id="feGaussianBlur4898" />
+    </filter>
+    <filter
+       id="filter4902">
+      <feGaussianBlur
+         stdDeviation="0.0013317619"
+         id="feGaussianBlur4904" />
+    </filter>
+    <filter
+       id="filter4908">
+      <feGaussianBlur
+         stdDeviation="0.17993542"
+         id="feGaussianBlur4910" />
+    </filter>
+    <filter
+       id="filter4914">
+      <feGaussianBlur
+         stdDeviation="0.22234618"
+         id="feGaussianBlur4916" />
+    </filter>
+    <filter
+       x="-0.13154667"
+       width="1.2630933"
+       y="-0.13154667"
+       height="1.2630933"
+       id="filter4920">
+      <feGaussianBlur
+         stdDeviation="0.3580237"
+         id="feGaussianBlur4922" />
+    </filter>
+    <filter
+       x="-0.19450341"
+       width="1.3890068"
+       y="-0.19450341"
+       height="1.3890068"
+       id="filter4926">
+      <feGaussianBlur
+         stdDeviation="0.52936977"
+         id="feGaussianBlur4928" />
+    </filter>
+    <filter
+       x="-0.25316937"
+       width="1.5063387"
+       y="-0.25316937"
+       height="1.5063387"
+       id="filter4932">
+      <feGaussianBlur
+         stdDeviation="0.68903787"
+         id="feGaussianBlur4934" />
+    </filter>
+    <filter
+       x="-0.26844285"
+       width="1.5368857"
+       y="-0.26844285"
+       height="1.5368857"
+       id="filter4938">
+      <feGaussianBlur
+         stdDeviation="0.73060691"
+         id="feGaussianBlur4940" />
+    </filter>
+    <filter
+       x="-0.31303411"
+       width="1.6260682"
+       y="-0.31303411"
+       height="1.6260682"
+       id="filter4944">
+      <feGaussianBlur
+         stdDeviation="0.85196861"
+         id="feGaussianBlur4946" />
+    </filter>
+    <filter
+       x="-0.37922017"
+       width="1.7584403"
+       y="-0.37922017"
+       height="1.7584403"
+       id="filter4950">
+      <feGaussianBlur
+         stdDeviation="1.0321037"
+         id="feGaussianBlur4952" />
+    </filter>
+    <filter
+       x="-0.45238806"
+       width="1.9047761"
+       y="-0.45238806"
+       height="1.9047761"
+       id="filter4956">
+      <feGaussianBlur
+         stdDeviation="1.231241"
+         id="feGaussianBlur4958" />
+    </filter>
+    <filter
+       x="-0.49715436"
+       width="1.9943087"
+       y="-0.49715436"
+       height="1.9943087"
+       id="filter4962">
+      <feGaussianBlur
+         stdDeviation="1.3530791"
+         id="feGaussianBlur4964" />
+    </filter>
+    <filter
+       x="-0.51654396"
+       width="2.0330879"
+       y="-0.51654396"
+       height="2.0330879"
+       id="filter4968">
+      <feGaussianBlur
+         stdDeviation="1.4058507"
+         id="feGaussianBlur4970" />
+    </filter>
+    <filter
+       x="-0.59793803"
+       width="2.1958761"
+       y="-0.59793803"
+       height="2.1958761"
+       id="filter4974">
+      <feGaussianBlur
+         stdDeviation="1.6273767"
+         id="feGaussianBlur4976" />
+    </filter>
+    <filter
+       x="-0.62197601"
+       width="2.243952"
+       y="-0.62197601"
+       height="2.243952"
+       id="filter4980">
+      <feGaussianBlur
+         stdDeviation="1.6927997"
+         id="feGaussianBlur4982" />
+    </filter>
+    <filter
+       x="-0.68659262"
+       width="2.3731852"
+       y="-0.68659262"
+       height="2.3731852"
+       id="filter4986">
+      <feGaussianBlur
+         stdDeviation="1.8686633"
+         id="feGaussianBlur4988" />
+    </filter>
+    <filter
+       id="filter4994">
+      <feGaussianBlur
+         stdDeviation="0.18558608"
+         id="feGaussianBlur4996" />
+    </filter>
+    <filter
+       id="filter5000">
+      <feGaussianBlur
+         stdDeviation="0.23596101"
+         id="feGaussianBlur5002" />
+    </filter>
+    <filter
+       x="-0.16091065"
+       width="1.3218213"
+       y="-0.16091065"
+       height="1.3218213"
+       id="filter5006">
+      <feGaussianBlur
+         stdDeviation="0.43794211"
+         id="feGaussianBlur5008" />
+    </filter>
+    <filter
+       x="-0.20955819"
+       width="1.4191164"
+       y="-0.20955819"
+       height="1.4191164"
+       id="filter5012">
+      <feGaussianBlur
+         stdDeviation="0.57034358"
+         id="feGaussianBlur5014" />
+    </filter>
+    <filter
+       x="-0.26085608"
+       width="1.5217122"
+       y="-0.26085608"
+       height="1.5217122"
+       id="filter5018">
+      <feGaussianBlur
+         stdDeviation="0.70995837"
+         id="feGaussianBlur5020" />
+    </filter>
+    <filter
+       x="-0.30604953"
+       width="1.6120991"
+       y="-0.30604953"
+       height="1.6120991"
+       id="filter5024">
+      <feGaussianBlur
+         stdDeviation="0.83295903"
+         id="feGaussianBlur5026" />
+    </filter>
+    <filter
+       x="-0.33957928"
+       width="1.6791586"
+       y="-0.33957928"
+       height="1.6791586"
+       id="filter5030">
+      <feGaussianBlur
+         stdDeviation="0.92421522"
+         id="feGaussianBlur5032" />
+    </filter>
+    <filter
+       x="-0.40447062"
+       width="1.8089412"
+       y="-0.40447062"
+       height="1.8089412"
+       id="filter5036">
+      <feGaussianBlur
+         stdDeviation="1.1008266"
+         id="feGaussianBlur5038" />
+    </filter>
+    <filter
+       x="-0.4379643"
+       width="1.8759286"
+       y="-0.4379643"
+       height="1.8759286"
+       id="filter5042">
+      <feGaussianBlur
+         stdDeviation="1.1919846"
+         id="feGaussianBlur5044" />
+    </filter>
+    <filter
+       x="-0.45773017"
+       width="1.9154603"
+       y="-0.45773017"
+       height="1.9154603"
+       id="filter5048">
+      <feGaussianBlur
+         stdDeviation="1.2457803"
+         id="feGaussianBlur5050" />
+    </filter>
+    <filter
+       x="-0.50957661"
+       width="2.0191532"
+       y="-0.50957661"
+       height="2.0191532"
+       id="filter5054">
+      <feGaussianBlur
+         stdDeviation="1.3868881"
+         id="feGaussianBlur5056" />
+    </filter>
+    <filter
+       x="-0.58042361"
+       width="2.1608472"
+       y="-0.58042361"
+       height="2.1608472"
+       id="filter5060">
+      <feGaussianBlur
+         stdDeviation="1.5797087"
+         id="feGaussianBlur5062" />
+    </filter>
+    <filter
+       x="-0.62967944"
+       width="2.2593589"
+       y="-0.62967944"
+       height="2.2593589"
+       id="filter5066">
+      <feGaussianBlur
+         stdDeviation="1.7137657"
+         id="feGaussianBlur5068" />
+    </filter>
+    <filter
+       x="-0.74144341"
+       width="2.4828868"
+       y="-0.74144341"
+       height="2.4828868"
+       id="filter5072">
+      <feGaussianBlur
+         stdDeviation="2.0179479"
+         id="feGaussianBlur5074" />
+    </filter>
+    <filter
+       id="filter5080">
+      <feGaussianBlur
+         stdDeviation="0.17029257"
+         id="feGaussianBlur5082" />
+    </filter>
+    <filter
+       x="-0.11567812"
+       width="1.2313562"
+       y="-0.11567812"
+       height="1.2313562"
+       id="filter5086">
+      <feGaussianBlur
+         stdDeviation="0.3148351"
+         id="feGaussianBlur5088" />
+    </filter>
+    <filter
+       x="-0.15034645"
+       width="1.3006929"
+       y="-0.15034645"
+       height="1.3006929"
+       id="filter5092">
+      <feGaussianBlur
+         stdDeviation="0.40919008"
+         id="feGaussianBlur5094" />
+    </filter>
+    <filter
+       x="-0.1730106"
+       width="1.3460212"
+       y="-0.1730106"
+       height="1.3460212"
+       id="filter5098">
+      <feGaussianBlur
+         stdDeviation="0.47087391"
+         id="feGaussianBlur5100" />
+    </filter>
+    <filter
+       x="-0.24966288"
+       width="1.4993258"
+       y="-0.24966288"
+       height="1.4993258"
+       id="filter5104">
+      <feGaussianBlur
+         stdDeviation="0.67949444"
+         id="feGaussianBlur5106" />
+    </filter>
+    <filter
+       x="-0.27470021"
+       width="1.5494004"
+       y="-0.27470021"
+       height="1.5494004"
+       id="filter5110">
+      <feGaussianBlur
+         stdDeviation="0.74763723"
+         id="feGaussianBlur5112" />
+    </filter>
+    <filter
+       x="-0.33193051"
+       width="1.663861"
+       y="-0.33193051"
+       height="1.663861"
+       id="filter5116">
+      <feGaussianBlur
+         stdDeviation="0.90339795"
+         id="feGaussianBlur5118" />
+    </filter>
+    <filter
+       x="-0.37834318"
+       width="1.7566864"
+       y="-0.37834318"
+       height="1.7566864"
+       id="filter5122">
+      <feGaussianBlur
+         stdDeviation="1.0297169"
+         id="feGaussianBlur5124" />
+    </filter>
+    <filter
+       x="-0.42757149"
+       width="1.855143"
+       y="-0.42757149"
+       height="1.855143"
+       id="filter5128">
+      <feGaussianBlur
+         stdDeviation="1.163699"
+         id="feGaussianBlur5130" />
+    </filter>
+    <filter
+       x="-0.45836088"
+       width="1.9167218"
+       y="-0.45836088"
+       height="1.9167218"
+       id="filter5134">
+      <feGaussianBlur
+         stdDeviation="1.2474969"
+         id="feGaussianBlur5136" />
+    </filter>
+    <filter
+       x="-0.53482938"
+       width="2.0696588"
+       y="-0.53482938"
+       height="2.0696588"
+       id="filter5140">
+      <feGaussianBlur
+         stdDeviation="1.4556172"
+         id="feGaussianBlur5142" />
+    </filter>
+    <filter
+       x="-0.55211873"
+       width="2.1042375"
+       y="-0.55211873"
+       height="2.1042375"
+       id="filter5146">
+      <feGaussianBlur
+         stdDeviation="1.5026727"
+         id="feGaussianBlur5148" />
+    </filter>
+    <filter
+       id="filter5152">
+      <feGaussianBlur
+         stdDeviation="0.035280871"
+         id="feGaussianBlur5154" />
+    </filter>
+    <filter
+       id="filter5158">
+      <feGaussianBlur
+         stdDeviation="0.13696103"
+         id="feGaussianBlur5160" />
+    </filter>
+    <filter
+       id="filter5164">
+      <feGaussianBlur
+         stdDeviation="0.19666941"
+         id="feGaussianBlur5166" />
+    </filter>
+    <filter
+       x="-0.13237757"
+       width="1.2647551"
+       y="-0.13237757"
+       height="1.2647551"
+       id="filter5170">
+      <feGaussianBlur
+         stdDeviation="0.36028513"
+         id="feGaussianBlur5172" />
+    </filter>
+    <filter
+       x="-0.17811526"
+       width="1.3562305"
+       y="-0.17811526"
+       height="1.3562305"
+       id="filter5176">
+      <feGaussianBlur
+         stdDeviation="0.48476701"
+         id="feGaussianBlur5178" />
+    </filter>
+    <filter
+       x="-0.21755012"
+       width="1.4351002"
+       y="-0.21755012"
+       height="1.4351002"
+       id="filter5182">
+      <feGaussianBlur
+         stdDeviation="0.59209481"
+         id="feGaussianBlur5184" />
+    </filter>
+    <filter
+       x="-0.28877711"
+       width="1.5775542"
+       y="-0.28877711"
+       height="1.5775542"
+       id="filter5188">
+      <feGaussianBlur
+         stdDeviation="0.78594958"
+         id="feGaussianBlur5190" />
+    </filter>
+    <filter
+       x="-0.31668856"
+       width="1.6333771"
+       y="-0.31668856"
+       height="1.6333771"
+       id="filter5194">
+      <feGaussianBlur
+         stdDeviation="0.86191473"
+         id="feGaussianBlur5196" />
+    </filter>
+    <filter
+       x="-0.38432137"
+       width="1.7686427"
+       y="-0.38432137"
+       height="1.7686427"
+       id="filter5200">
+      <feGaussianBlur
+         stdDeviation="1.0459874"
+         id="feGaussianBlur5202" />
+    </filter>
+    <filter
+       x="-0.41358611"
+       width="1.8271722"
+       y="-0.41358611"
+       height="1.8271722"
+       id="filter5206">
+      <feGaussianBlur
+         stdDeviation="1.1256357"
+         id="feGaussianBlur5208" />
+    </filter>
+    <filter
+       x="-0.50195004"
+       width="2.0039001"
+       y="-0.50195004"
+       height="2.0039001"
+       id="filter5212">
+      <feGaussianBlur
+         stdDeviation="1.3661312"
+         id="feGaussianBlur5214" />
+    </filter>
+    <filter
+       x="-0.50617579"
+       width="2.0123516"
+       y="-0.50617579"
+       height="2.0123516"
+       id="filter5218">
+      <feGaussianBlur
+         stdDeviation="1.3776322"
+         id="feGaussianBlur5220" />
+    </filter>
+    <filter
+       x="-0.57016796"
+       width="2.1403359"
+       y="-0.57016796"
+       height="2.1403359"
+       id="filter5224">
+      <feGaussianBlur
+         stdDeviation="1.5517964"
+         id="feGaussianBlur5226" />
+    </filter>
+    <filter
+       x="-0.63365438"
+       width="2.2673088"
+       y="-0.63365438"
+       height="2.2673088"
+       id="filter5230">
+      <feGaussianBlur
+         stdDeviation="1.7245841"
+         id="feGaussianBlur5232" />
+    </filter>
+    <filter
+       x="-0.65428753"
+       width="2.3085751"
+       y="-0.65428753"
+       height="2.3085751"
+       id="filter5236">
+      <feGaussianBlur
+         stdDeviation="1.7807402"
+         id="feGaussianBlur5238" />
+    </filter>
+    <filter
+       x="-0.69856106"
+       width="2.3971221"
+       y="-0.69856106"
+       height="2.3971221"
+       id="filter5242">
+      <feGaussianBlur
+         stdDeviation="1.9012372"
+         id="feGaussianBlur5244" />
+    </filter>
+    <filter
+       x="-0.75819736"
+       width="2.5163947"
+       y="-0.75819736"
+       height="2.5163947"
+       id="filter5248">
+      <feGaussianBlur
+         stdDeviation="2.0635462"
+         id="feGaussianBlur5250" />
+    </filter>
+    <filter
+       x="-0.81891541"
+       width="2.6378308"
+       y="-0.81891541"
+       height="2.6378308"
+       id="filter5254">
+      <feGaussianBlur
+         stdDeviation="2.2287993"
+         id="feGaussianBlur5256" />
+    </filter>
+    <filter
+       x="-0.86442673"
+       width="2.7288535"
+       y="-0.86442673"
+       height="2.7288535"
+       id="filter5260">
+      <feGaussianBlur
+         stdDeviation="2.3526651"
+         id="feGaussianBlur5262" />
+    </filter>
+    <filter
+       x="-0.89497776"
+       width="2.7899555"
+       y="-0.89497776"
+       height="2.7899555"
+       id="filter5266">
+      <feGaussianBlur
+         stdDeviation="2.4358143"
+         id="feGaussianBlur5268" />
+    </filter>
+    <filter
+       id="filter5272">
+      <feGaussianBlur
+         stdDeviation="0.021919463"
+         id="feGaussianBlur5274" />
+    </filter>
+    <filter
+       id="filter5278">
+      <feGaussianBlur
+         stdDeviation="0.17527714"
+         id="feGaussianBlur5280" />
+    </filter>
+    <filter
+       id="filter5284">
+      <feGaussianBlur
+         stdDeviation="0.2407119"
+         id="feGaussianBlur5286" />
+    </filter>
+    <filter
+       x="-0.13745977"
+       width="1.2749195"
+       y="-0.13745977"
+       height="1.2749195"
+       id="filter5290">
+      <feGaussianBlur
+         stdDeviation="0.37411709"
+         id="feGaussianBlur5292" />
+    </filter>
+    <filter
+       x="-0.2094002"
+       width="1.4188004"
+       y="-0.2094002"
+       height="1.4188004"
+       id="filter5296">
+      <feGaussianBlur
+         stdDeviation="0.56991358"
+         id="feGaussianBlur5298" />
+    </filter>
+    <filter
+       x="-0.2599545"
+       width="1.519909"
+       y="-0.2599545"
+       height="1.519909"
+       id="filter5302">
+      <feGaussianBlur
+         stdDeviation="0.7075046"
+         id="feGaussianBlur5304" />
+    </filter>
+    <filter
+       x="-0.27280182"
+       width="1.5456036"
+       y="-0.27280182"
+       height="1.5456036"
+       id="filter5308">
+      <feGaussianBlur
+         stdDeviation="0.74247047"
+         id="feGaussianBlur5310" />
+    </filter>
+    <filter
+       x="-0.35972402"
+       width="1.719448"
+       y="-0.35972402"
+       height="1.719448"
+       id="filter5314">
+      <feGaussianBlur
+         stdDeviation="0.97904208"
+         id="feGaussianBlur5316" />
+    </filter>
+    <filter
+       x="-0.37282339"
+       width="1.7456468"
+       y="-0.37282339"
+       height="1.7456468"
+       id="filter5320">
+      <feGaussianBlur
+         stdDeviation="1.014694"
+         id="feGaussianBlur5322" />
+    </filter>
+    <filter
+       x="-0.43005659"
+       width="1.8601132"
+       y="-0.43005659"
+       height="1.8601132"
+       id="filter5326">
+      <feGaussianBlur
+         stdDeviation="1.1704626"
+         id="feGaussianBlur5328" />
+    </filter>
+    <filter
+       x="-0.47489843"
+       width="1.9497969"
+       y="-0.47489843"
+       height="1.9497969"
+       id="filter5332">
+      <feGaussianBlur
+         stdDeviation="1.2925063"
+         id="feGaussianBlur5334" />
+    </filter>
+    <filter
+       x="-0.52891314"
+       width="2.0578263"
+       y="-0.52891314"
+       height="2.0578263"
+       id="filter5338">
+      <feGaussianBlur
+         stdDeviation="1.4395153"
+         id="feGaussianBlur5340" />
+    </filter>
+    <filter
+       x="-0.56779924"
+       width="2.1355985"
+       y="-0.56779924"
+       height="2.1355985"
+       id="filter5344">
+      <feGaussianBlur
+         stdDeviation="1.5453496"
+         id="feGaussianBlur5346" />
+    </filter>
+    <filter
+       x="-0.60192537"
+       width="2.2038507"
+       y="-0.60192537"
+       height="2.2038507"
+       id="filter5350">
+      <feGaussianBlur
+         stdDeviation="1.6382289"
+         id="feGaussianBlur5352" />
+    </filter>
+    <filter
+       x="-0.66254317"
+       width="2.3250863"
+       y="-0.66254317"
+       height="2.3250863"
+       id="filter5356">
+      <feGaussianBlur
+         stdDeviation="1.8032092"
+         id="feGaussianBlur5358" />
+    </filter>
+    <filter
+       x="-0.72886442"
+       width="2.4577288"
+       y="-0.72886442"
+       height="2.4577288"
+       id="filter5362">
+      <feGaussianBlur
+         stdDeviation="1.9837122"
+         id="feGaussianBlur5364" />
+    </filter>
+    <filter
+       id="filter5370">
+      <feGaussianBlur
+         stdDeviation="0.19528857"
+         id="feGaussianBlur5372" />
+    </filter>
+    <filter
+       id="filter5376">
+      <feGaussianBlur
+         stdDeviation="0.20908881"
+         id="feGaussianBlur5378" />
+    </filter>
+    <filter
+       x="-0.12360948"
+       width="1.247219"
+       y="-0.12360948"
+       height="1.247219"
+       id="filter5382">
+      <feGaussianBlur
+         stdDeviation="0.33642147"
+         id="feGaussianBlur5384" />
+    </filter>
+    <filter
+       x="-0.18519643"
+       width="1.3703929"
+       y="-0.18519643"
+       height="1.3703929"
+       id="filter5388">
+      <feGaussianBlur
+         stdDeviation="0.50403945"
+         id="feGaussianBlur5390" />
+    </filter>
+    <filter
+       x="-0.24661936"
+       width="1.4932387"
+       y="-0.24661936"
+       height="1.4932387"
+       id="filter5394">
+      <feGaussianBlur
+         stdDeviation="0.67121104"
+         id="feGaussianBlur5396" />
+    </filter>
+    <filter
+       x="-0.27509966"
+       width="1.5501993"
+       y="-0.27509966"
+       height="1.5501993"
+       id="filter5400">
+      <feGaussianBlur
+         stdDeviation="0.7487244"
+         id="feGaussianBlur5402" />
+    </filter>
+    <filter
+       x="-0.33566427"
+       width="1.6713285"
+       y="-0.33566427"
+       height="1.6713285"
+       id="filter5406">
+      <feGaussianBlur
+         stdDeviation="0.91355992"
+         id="feGaussianBlur5408" />
+    </filter>
+    <filter
+       x="-0.38258444"
+       width="1.7651689"
+       y="-0.38258444"
+       height="1.7651689"
+       id="filter5412">
+      <feGaussianBlur
+         stdDeviation="1.0412601"
+         id="feGaussianBlur5414" />
+    </filter>
+    <filter
+       x="-0.44217586"
+       width="1.8843517"
+       y="-0.44217586"
+       height="1.8843517"
+       id="filter5418">
+      <feGaussianBlur
+         stdDeviation="1.203447"
+         id="feGaussianBlur5420" />
+    </filter>
+    <filter
+       x="-0.49581082"
+       width="1.9916216"
+       y="-0.49581082"
+       height="1.9916216"
+       id="filter5424">
+      <feGaussianBlur
+         stdDeviation="1.3494224"
+         id="feGaussianBlur5426" />
+    </filter>
+    <filter
+       x="-0.52568585"
+       width="2.0513717"
+       y="-0.52568585"
+       height="2.0513717"
+       id="filter5430">
+      <feGaussianBlur
+         stdDeviation="1.4307318"
+         id="feGaussianBlur5432" />
+    </filter>
+    <filter
+       x="-0.57013143"
+       width="2.1402629"
+       y="-0.57013143"
+       height="2.1402629"
+       id="filter5436">
+      <feGaussianBlur
+         stdDeviation="1.551697"
+         id="feGaussianBlur5438" />
+    </filter>
+    <filter
+       x="-0.62791495"
+       width="2.2558299"
+       y="-0.62791495"
+       height="2.2558299"
+       id="filter5442">
+      <feGaussianBlur
+         stdDeviation="1.7089634"
+         id="feGaussianBlur5444" />
+    </filter>
+    <filter
+       x="-0.68211453"
+       width="2.3642291"
+       y="-0.68211453"
+       height="2.3642291"
+       id="filter5448">
+      <feGaussianBlur
+         stdDeviation="1.8564755"
+         id="feGaussianBlur5450" />
+    </filter>
+    <filter
+       x="-0.7302541"
+       width="2.4605082"
+       y="-0.7302541"
+       height="2.4605082"
+       id="filter5454">
+      <feGaussianBlur
+         stdDeviation="1.9874945"
+         id="feGaussianBlur5456" />
+    </filter>
+    <filter
+       id="filter5462">
+      <feGaussianBlur
+         stdDeviation="0.13601415"
+         id="feGaussianBlur5464" />
+    </filter>
+    <filter
+       x="-0.11336916"
+       width="1.2267383"
+       y="-0.11336916"
+       height="1.2267383"
+       id="filter5468">
+      <feGaussianBlur
+         stdDeviation="0.30855092"
+         id="feGaussianBlur5470" />
+    </filter>
+    <filter
+       x="-0.1573958"
+       width="1.3147916"
+       y="-0.1573958"
+       height="1.3147916"
+       id="filter5474">
+      <feGaussianBlur
+         stdDeviation="0.42837595"
+         id="feGaussianBlur5476" />
+    </filter>
+    <filter
+       x="-0.19491618"
+       width="1.3898324"
+       y="-0.19491618"
+       height="1.3898324"
+       id="filter5480">
+      <feGaussianBlur
+         stdDeviation="0.5304932"
+         id="feGaussianBlur5482" />
+    </filter>
+    <filter
+       x="-0.25450608"
+       width="1.5090122"
+       y="-0.25450608"
+       height="1.5090122"
+       id="filter5486">
+      <feGaussianBlur
+         stdDeviation="0.69267591"
+         id="feGaussianBlur5488" />
+    </filter>
+    <filter
+       x="-0.29523575"
+       width="1.5904715"
+       y="-0.29523575"
+       height="1.5904715"
+       id="filter5492">
+      <feGaussianBlur
+         stdDeviation="0.80352773"
+         id="feGaussianBlur5494" />
+    </filter>
+    <filter
+       x="-0.35264913"
+       width="1.7052983"
+       y="-0.35264913"
+       height="1.7052983"
+       id="filter5498">
+      <feGaussianBlur
+         stdDeviation="0.95978672"
+         id="feGaussianBlur5500" />
+    </filter>
+    <filter
+       x="-0.3986366"
+       width="1.7972732"
+       y="-0.3986366"
+       height="1.7972732"
+       id="filter5504">
+      <feGaussianBlur
+         stdDeviation="1.0849484"
+         id="feGaussianBlur5506" />
+    </filter>
+    <filter
+       x="-0.4171793"
+       width="1.8343586"
+       y="-0.4171793"
+       height="1.8343586"
+       id="filter5510">
+      <feGaussianBlur
+         stdDeviation="1.1354151"
+         id="feGaussianBlur5512" />
+    </filter>
+    <filter
+       x="-0.4655886"
+       width="1.9311772"
+       y="-0.4655886"
+       height="1.9311772"
+       id="filter5516">
+      <feGaussianBlur
+         stdDeviation="1.2671682"
+         id="feGaussianBlur5518" />
+    </filter>
+    <filter
+       x="-0.52720701"
+       width="2.054414"
+       y="-0.52720701"
+       height="2.054414"
+       id="filter5522">
+      <feGaussianBlur
+         stdDeviation="1.4348718"
+         id="feGaussianBlur5524" />
+    </filter>
+    <filter
+       x="-0.59928454"
+       width="2.1985691"
+       y="-0.59928454"
+       height="2.1985691"
+       id="filter5528">
+      <feGaussianBlur
+         stdDeviation="1.6310415"
+         id="feGaussianBlur5530" />
+    </filter>
+    <filter
+       x="-0.62463266"
+       width="2.2492653"
+       y="-0.62463266"
+       height="2.2492653"
+       id="filter5534">
+      <feGaussianBlur
+         stdDeviation="1.7000301"
+         id="feGaussianBlur5536" />
+    </filter>
+    <filter
+       x="-0.69508563"
+       width="2.3901713"
+       y="-0.69508563"
+       height="2.3901713"
+       id="filter5540">
+      <feGaussianBlur
+         stdDeviation="1.8917783"
+         id="feGaussianBlur5542" />
+    </filter>
+    <filter
+       x="-0.70150783"
+       width="2.4030157"
+       y="-0.70150783"
+       height="2.4030157"
+       id="filter5546">
+      <feGaussianBlur
+         stdDeviation="1.9092573"
+         id="feGaussianBlur5548" />
+    </filter>
+    <filter
+       id="filter5552">
+      <feGaussianBlur
+         stdDeviation="0.031516855"
+         id="feGaussianBlur5554" />
+    </filter>
+    <filter
+       id="filter5558">
+      <feGaussianBlur
+         stdDeviation="0.17453672"
+         id="feGaussianBlur5560" />
+    </filter>
+    <filter
+       x="-0.11090171"
+       width="1.2218034"
+       y="-0.11090171"
+       height="1.2218034"
+       id="filter5564">
+      <feGaussianBlur
+         stdDeviation="0.30183538"
+         id="feGaussianBlur5566" />
+    </filter>
+    <filter
+       x="-0.15718692"
+       width="1.3143738"
+       y="-0.15718692"
+       height="1.3143738"
+       id="filter5570">
+      <feGaussianBlur
+         stdDeviation="0.42780745"
+         id="feGaussianBlur5572" />
+    </filter>
+    <filter
+       x="-0.19976663"
+       width="1.3995333"
+       y="-0.19976663"
+       height="1.3995333"
+       id="filter5576">
+      <feGaussianBlur
+         stdDeviation="0.5436944"
+         id="feGaussianBlur5578" />
+    </filter>
+    <filter
+       x="-0.23846873"
+       width="1.4769375"
+       y="-0.23846873"
+       height="1.4769375"
+       id="filter5582">
+      <feGaussianBlur
+         stdDeviation="0.64902791"
+         id="feGaussianBlur5584" />
+    </filter>
+    <filter
+       x="-0.30749818"
+       width="1.6149964"
+       y="-0.30749818"
+       height="1.6149964"
+       id="filter5588">
+      <feGaussianBlur
+         stdDeviation="0.83690175"
+         id="feGaussianBlur5590" />
+    </filter>
+    <filter
+       x="-0.33735202"
+       width="1.674704"
+       y="-0.33735202"
+       height="1.674704"
+       id="filter5594">
+      <feGaussianBlur
+         stdDeviation="0.91815338"
+         id="feGaussianBlur5596" />
+    </filter>
+    <filter
+       x="-0.38645435"
+       width="1.7729087"
+       y="-0.38645435"
+       height="1.7729087"
+       id="filter5600">
+      <feGaussianBlur
+         stdDeviation="1.0517926"
+         id="feGaussianBlur5602" />
+    </filter>
+    <filter
+       x="-0.42705495"
+       width="1.8541099"
+       y="-0.42705495"
+       height="1.8541099"
+       id="filter5606">
+      <feGaussianBlur
+         stdDeviation="1.1622932"
+         id="feGaussianBlur5608" />
+    </filter>
+    <filter
+       x="-0.47124098"
+       width="1.942482"
+       y="-0.47124098"
+       height="1.942482"
+       id="filter5612">
+      <feGaussianBlur
+         stdDeviation="1.282552"
+         id="feGaussianBlur5614" />
+    </filter>
+    <filter
+       x="-0.5180253"
+       width="2.0360506"
+       y="-0.5180253"
+       height="2.0360506"
+       id="filter5618">
+      <feGaussianBlur
+         stdDeviation="1.4098824"
+         id="feGaussianBlur5620" />
+    </filter>
+    <filter
+       x="-0.59234003"
+       width="2.1846801"
+       y="-0.59234003"
+       height="2.1846801"
+       id="filter5624">
+      <feGaussianBlur
+         stdDeviation="1.6121409"
+         id="feGaussianBlur5626" />
+    </filter>
+    <filter
+       x="-0.60827391"
+       width="2.2165478"
+       y="-0.60827391"
+       height="2.2165478"
+       id="filter5630">
+      <feGaussianBlur
+         stdDeviation="1.6555073"
+         id="feGaussianBlur5632" />
+    </filter>
+    <filter
+       x="-0.6758845"
+       width="2.351769"
+       y="-0.6758845"
+       height="2.351769"
+       id="filter5636">
+      <feGaussianBlur
+         stdDeviation="1.8395196"
+         id="feGaussianBlur5638" />
+    </filter>
+    <filter
+       x="-0.73917164"
+       width="2.4783433"
+       y="-0.73917164"
+       height="2.4783433"
+       id="filter5642">
+      <feGaussianBlur
+         stdDeviation="2.0117649"
+         id="feGaussianBlur5644" />
+    </filter>
+    <filter
+       id="filter5650">
+      <feGaussianBlur
+         stdDeviation="0.10022346"
+         id="feGaussianBlur5652" />
+    </filter>
+    <filter
+       id="filter5656">
+      <feGaussianBlur
+         stdDeviation="0.22444948"
+         id="feGaussianBlur5658" />
+    </filter>
+    <filter
+       x="-0.14653994"
+       width="1.2930799"
+       y="-0.14653994"
+       height="1.2930799"
+       id="filter5662">
+      <feGaussianBlur
+         stdDeviation="0.39883011"
+         id="feGaussianBlur5664" />
+    </filter>
+    <filter
+       x="-0.18200616"
+       width="1.3640123"
+       y="-0.18200616"
+       height="1.3640123"
+       id="filter5668">
+      <feGaussianBlur
+         stdDeviation="0.49535668"
+         id="feGaussianBlur5670" />
+    </filter>
+    <filter
+       x="-0.25990758"
+       width="1.5198152"
+       y="-0.25990758"
+       height="1.5198152"
+       id="filter5674">
+      <feGaussianBlur
+         stdDeviation="0.70737691"
+         id="feGaussianBlur5676" />
+    </filter>
+    <filter
+       x="-0.26938972"
+       width="1.5387794"
+       y="-0.26938972"
+       height="1.5387794"
+       id="filter5680">
+      <feGaussianBlur
+         stdDeviation="0.73318394"
+         id="feGaussianBlur5682" />
+    </filter>
+    <filter
+       x="-0.35722372"
+       width="1.7144474"
+       y="-0.35722372"
+       height="1.7144474"
+       id="filter5686">
+      <feGaussianBlur
+         stdDeviation="0.97223715"
+         id="feGaussianBlur5688" />
+    </filter>
+    <filter
+       x="-0.3635238"
+       width="1.7270476"
+       y="-0.3635238"
+       height="1.7270476"
+       id="filter5692">
+      <feGaussianBlur
+         stdDeviation="0.98938375"
+         id="feGaussianBlur5694" />
+    </filter>
+    <filter
+       x="-0.42368537"
+       width="1.8473707"
+       y="-0.42368537"
+       height="1.8473707"
+       id="filter5698">
+      <feGaussianBlur
+         stdDeviation="1.1531224"
+         id="feGaussianBlur5700" />
+    </filter>
+    <filter
+       x="-0.4661622"
+       width="1.9323244"
+       y="-0.4661622"
+       height="1.9323244"
+       id="filter5704">
+      <feGaussianBlur
+         stdDeviation="1.2687293"
+         id="feGaussianBlur5706" />
+    </filter>
+    <filter
+       x="-0.51480731"
+       width="2.0296146"
+       y="-0.51480731"
+       height="2.0296146"
+       id="filter5710">
+      <feGaussianBlur
+         stdDeviation="1.4011242"
+         id="feGaussianBlur5712" />
+    </filter>
+    <filter
+       x="-0.55782573"
+       width="2.1156515"
+       y="-0.55782573"
+       height="2.1156515"
+       id="filter5716">
+      <feGaussianBlur
+         stdDeviation="1.5182052"
+         id="feGaussianBlur5718" />
+    </filter>
+    <filter
+       x="-0.63964466"
+       width="2.2792893"
+       y="-0.63964466"
+       height="2.2792893"
+       id="filter5722">
+      <feGaussianBlur
+         stdDeviation="1.7408875"
+         id="feGaussianBlur5724" />
+    </filter>
+    <filter
+       x="-0.69012254"
+       width="2.3802451"
+       y="-0.69012254"
+       height="2.3802451"
+       id="filter5728">
+      <feGaussianBlur
+         stdDeviation="1.8782705"
+         id="feGaussianBlur5730" />
+    </filter>
+    <filter
+       x="-0.71274255"
+       width="2.4254851"
+       y="-0.71274255"
+       height="2.4254851"
+       id="filter5734">
+      <feGaussianBlur
+         stdDeviation="1.9398342"
+         id="feGaussianBlur5736" />
+    </filter>
+    <filter
+       id="filter5740">
+      <feGaussianBlur
+         stdDeviation="0.042788383"
+         id="feGaussianBlur5742" />
+    </filter>
+    <filter
+       id="filter5746">
+      <feGaussianBlur
+         stdDeviation="0.093772311"
+         id="feGaussianBlur5748" />
+    </filter>
+    <filter
+       id="filter5752">
+      <feGaussianBlur
+         stdDeviation="0.26771321"
+         id="feGaussianBlur5754" />
+    </filter>
+    <filter
+       x="-0.1613237"
+       width="1.3226474"
+       y="-0.1613237"
+       height="1.3226474"
+       id="filter5758">
+      <feGaussianBlur
+         stdDeviation="0.4390663"
+         id="feGaussianBlur5760" />
+    </filter>
+    <filter
+       x="-0.19788927"
+       width="1.3957785"
+       y="-0.19788927"
+       height="1.3957785"
+       id="filter5764">
+      <feGaussianBlur
+         stdDeviation="0.5385849"
+         id="feGaussianBlur5766" />
+    </filter>
+    <filter
+       x="-0.23588237"
+       width="1.4717647"
+       y="-0.23588237"
+       height="1.4717647"
+       id="filter5770">
+      <feGaussianBlur
+         stdDeviation="0.64198873"
+         id="feGaussianBlur5772" />
+    </filter>
+    <filter
+       x="-0.26484779"
+       width="1.5296956"
+       y="-0.26484779"
+       height="1.5296956"
+       id="filter5776">
+      <feGaussianBlur
+         stdDeviation="0.72082242"
+         id="feGaussianBlur5778" />
+    </filter>
+    <filter
+       x="-0.3247203"
+       width="1.6494406"
+       y="-0.3247203"
+       height="1.6494406"
+       id="filter5782">
+      <feGaussianBlur
+         stdDeviation="0.8837743"
+         id="feGaussianBlur5784" />
+    </filter>
+    <filter
+       x="-0.37819233"
+       width="1.7563847"
+       y="-0.37819233"
+       height="1.7563847"
+       id="filter5788">
+      <feGaussianBlur
+         stdDeviation="1.0293063"
+         id="feGaussianBlur5790" />
+    </filter>
+    <filter
+       x="-0.44158728"
+       width="1.8831746"
+       y="-0.44158728"
+       height="1.8831746"
+       id="filter5794">
+      <feGaussianBlur
+         stdDeviation="1.2018451"
+         id="feGaussianBlur5796" />
+    </filter>
+    <filter
+       x="-0.50000077"
+       width="2.0000015"
+       y="-0.50000077"
+       height="2.0000015"
+       id="filter5800">
+      <feGaussianBlur
+         stdDeviation="1.360826"
+         id="feGaussianBlur5802" />
+    </filter>
+    <filter
+       x="-0.54056897"
+       width="2.0811379"
+       y="-0.54056897"
+       height="2.0811379"
+       id="filter5806">
+      <feGaussianBlur
+         stdDeviation="1.4712383"
+         id="feGaussianBlur5808" />
+    </filter>
+    <filter
+       x="-0.59840471"
+       width="2.1968094"
+       y="-0.59840471"
+       height="2.1968094"
+       id="filter5812">
+      <feGaussianBlur
+         stdDeviation="1.6286469"
+         id="feGaussianBlur5814" />
+    </filter>
+    <filter
+       x="-0.64247705"
+       width="2.2849541"
+       y="-0.64247705"
+       height="2.2849541"
+       id="filter5818">
+      <feGaussianBlur
+         stdDeviation="1.7485963"
+         id="feGaussianBlur5820" />
+    </filter>
+    <filter
+       x="-0.68534552"
+       width="2.370691"
+       y="-0.68534552"
+       height="2.370691"
+       id="filter5824">
+      <feGaussianBlur
+         stdDeviation="1.8652691"
+         id="feGaussianBlur5826" />
+    </filter>
+    <filter
+       x="-0.71034244"
+       width="2.4206849"
+       y="-0.71034244"
+       height="2.4206849"
+       id="filter5830">
+      <feGaussianBlur
+         stdDeviation="1.9333019"
+         id="feGaussianBlur5832" />
+    </filter>
+    <filter
+       id="filter5838">
+      <feGaussianBlur
+         stdDeviation="0.166259"
+         id="feGaussianBlur5840" />
+    </filter>
+    <filter
+       x="-0.10453114"
+       width="1.2090623"
+       y="-0.10453114"
+       height="1.2090623"
+       id="filter5844">
+      <feGaussianBlur
+         stdDeviation="0.28449694"
+         id="feGaussianBlur5846" />
+    </filter>
+    <filter
+       x="-0.14391859"
+       width="1.2878372"
+       y="-0.14391859"
+       height="1.2878372"
+       id="filter5850">
+      <feGaussianBlur
+         stdDeviation="0.39169571"
+         id="feGaussianBlur5852" />
+    </filter>
+    <filter
+       x="-0.17055307"
+       width="1.3411061"
+       y="-0.17055307"
+       height="1.3411061"
+       id="filter5856">
+      <feGaussianBlur
+         stdDeviation="0.4641854"
+         id="feGaussianBlur5858" />
+    </filter>
+    <filter
+       x="-0.23708238"
+       width="1.4741648"
+       y="-0.23708238"
+       height="1.4741648"
+       id="filter5862">
+      <feGaussianBlur
+         stdDeviation="0.64525473"
+         id="feGaussianBlur5864" />
+    </filter>
+    <filter
+       x="-0.26532448"
+       width="1.530649"
+       y="-0.26532448"
+       height="1.530649"
+       id="filter5868">
+      <feGaussianBlur
+         stdDeviation="0.72211978"
+         id="feGaussianBlur5870" />
+    </filter>
+    <filter
+       x="-0.3548713"
+       width="1.7097426"
+       y="-0.3548713"
+       height="1.7097426"
+       id="filter5874">
+      <feGaussianBlur
+         stdDeviation="0.96583471"
+         id="feGaussianBlur5876" />
+    </filter>
+    <filter
+       x="-0.38708365"
+       width="1.7741673"
+       y="-0.38708365"
+       height="1.7741673"
+       id="filter5880">
+      <feGaussianBlur
+         stdDeviation="1.0535054"
+         id="feGaussianBlur5882" />
+    </filter>
+    <filter
+       x="-0.45394458"
+       width="1.9078892"
+       y="-0.45394458"
+       height="1.9078892"
+       id="filter5886">
+      <feGaussianBlur
+         stdDeviation="1.2354773"
+         id="feGaussianBlur5888" />
+    </filter>
+    <filter
+       x="-0.4729181"
+       width="1.9458362"
+       y="-0.4729181"
+       height="1.9458362"
+       id="filter5892">
+      <feGaussianBlur
+         stdDeviation="1.2871165"
+         id="feGaussianBlur5894" />
+    </filter>
+    <filter
+       x="-0.52062042"
+       width="2.0412408"
+       y="-0.52062042"
+       height="2.0412408"
+       id="filter5898">
+      <feGaussianBlur
+         stdDeviation="1.4169454"
+         id="feGaussianBlur5900" />
+    </filter>
+    <filter
+       x="-0.5688333"
+       width="2.1376666"
+       y="-0.5688333"
+       height="2.1376666"
+       id="filter5904">
+      <feGaussianBlur
+         stdDeviation="1.5481639"
+         id="feGaussianBlur5906" />
+    </filter>
+    <filter
+       x="-0.61848415"
+       width="2.2369683"
+       y="-0.61848415"
+       height="2.2369683"
+       id="filter5910">
+      <feGaussianBlur
+         stdDeviation="1.683296"
+         id="feGaussianBlur5912" />
+    </filter>
+    <filter
+       x="-0.68914787"
+       width="2.3782957"
+       y="-0.68914787"
+       height="2.3782957"
+       id="filter5916">
+      <feGaussianBlur
+         stdDeviation="1.8756178"
+         id="feGaussianBlur5918" />
+    </filter>
+    <filter
+       x="-0.69820109"
+       width="2.3964022"
+       y="-0.69820109"
+       height="2.3964022"
+       id="filter5922">
+      <feGaussianBlur
+         stdDeviation="1.9002575"
+         id="feGaussianBlur5924" />
+    </filter>
+    <filter
+       id="filter5928">
+      <feGaussianBlur
+         stdDeviation="0.018955645"
+         id="feGaussianBlur5930" />
+    </filter>
+    <filter
+       id="filter5934">
+      <feGaussianBlur
+         stdDeviation="0.12696207"
+         id="feGaussianBlur5936" />
+    </filter>
+    <filter
+       x="-0.1147896"
+       width="1.2295792"
+       y="-0.1147896"
+       height="1.2295792"
+       id="filter5940">
+      <feGaussianBlur
+         stdDeviation="0.31241687"
+         id="feGaussianBlur5942" />
+    </filter>
+    <filter
+       x="-0.15539087"
+       width="1.3107817"
+       y="-0.15539087"
+       height="1.3107817"
+       id="filter5946">
+      <feGaussianBlur
+         stdDeviation="0.42291921"
+         id="feGaussianBlur5948" />
+    </filter>
+    <filter
+       x="-0.20480674"
+       width="1.4096135"
+       y="-0.20480674"
+       height="1.4096135"
+       id="filter5952">
+      <feGaussianBlur
+         stdDeviation="0.55741181"
+         id="feGaussianBlur5954" />
+    </filter>
+    <filter
+       x="-0.23532796"
+       width="1.4706559"
+       y="-0.23532796"
+       height="1.4706559"
+       id="filter5958">
+      <feGaussianBlur
+         stdDeviation="0.64047983"
+         id="feGaussianBlur5960" />
+    </filter>
+    <filter
+       x="-0.27664169"
+       width="1.5532834"
+       y="-0.27664169"
+       height="1.5532834"
+       id="filter5964">
+      <feGaussianBlur
+         stdDeviation="0.75292124"
+         id="feGaussianBlur5966" />
+    </filter>
+    <filter
+       x="-0.34431334"
+       width="1.6886267"
+       y="-0.34431334"
+       height="1.6886267"
+       id="filter5970">
+      <feGaussianBlur
+         stdDeviation="0.93709965"
+         id="feGaussianBlur5972" />
+    </filter>
+    <filter
+       x="-0.40041561"
+       width="1.8008312"
+       y="-0.40041561"
+       height="1.8008312"
+       id="filter5976">
+      <feGaussianBlur
+         stdDeviation="1.0897903"
+         id="feGaussianBlur5978" />
+    </filter>
+    <filter
+       x="-0.41222664"
+       width="1.8244533"
+       y="-0.41222664"
+       height="1.8244533"
+       id="filter5982">
+      <feGaussianBlur
+         stdDeviation="1.1219357"
+         id="feGaussianBlur5984" />
+    </filter>
+    <filter
+       x="-0.46832641"
+       width="1.9366528"
+       y="-0.46832641"
+       height="1.9366528"
+       id="filter5988">
+      <feGaussianBlur
+         stdDeviation="1.2746196"
+         id="feGaussianBlur5990" />
+    </filter>
+    <filter
+       x="-0.53659992"
+       width="2.0731998"
+       y="-0.53659992"
+       height="2.0731998"
+       id="filter5994">
+      <feGaussianBlur
+         stdDeviation="1.460436"
+         id="feGaussianBlur5996" />
+    </filter>
+    <filter
+       x="-0.58164518"
+       width="2.1632904"
+       y="-0.58164518"
+       height="2.1632904"
+       id="filter6000">
+      <feGaussianBlur
+         stdDeviation="1.5830333"
+         id="feGaussianBlur6002" />
+    </filter>
+    <filter
+       x="-0.61650886"
+       width="2.2330177"
+       y="-0.61650886"
+       height="2.2330177"
+       id="filter6006">
+      <feGaussianBlur
+         stdDeviation="1.67792"
+         id="feGaussianBlur6008" />
+    </filter>
+    <filter
+       x="-0.67358133"
+       width="2.3471627"
+       y="-0.67358133"
+       height="2.3471627"
+       id="filter6012">
+      <feGaussianBlur
+         stdDeviation="1.8332511"
+         id="feGaussianBlur6014" />
+    </filter>
+    <filter
+       x="-0.70804482"
+       width="2.4160896"
+       y="-0.70804482"
+       height="2.4160896"
+       id="filter6018">
+      <feGaussianBlur
+         stdDeviation="1.9270486"
+         id="feGaussianBlur6020" />
+    </filter>
+    <filter
+       id="filter6026">
+      <feGaussianBlur
+         stdDeviation="0.15441969"
+         id="feGaussianBlur6028" />
+    </filter>
+    <filter
+       x="-0.10392503"
+       width="1.2078501"
+       y="-0.10392503"
+       height="1.2078501"
+       id="filter6032">
+      <feGaussianBlur
+         stdDeviation="0.28284734"
+         id="feGaussianBlur6034" />
+    </filter>
+    <filter
+       x="-0.13646467"
+       width="1.2729293"
+       y="-0.13646467"
+       height="1.2729293"
+       id="filter6038">
+      <feGaussianBlur
+         stdDeviation="0.37140877"
+         id="feGaussianBlur6040" />
+    </filter>
+    <filter
+       x="-0.19164705"
+       width="1.3832941"
+       y="-0.19164705"
+       height="1.3832941"
+       id="filter6044">
+      <feGaussianBlur
+         stdDeviation="0.52159577"
+         id="feGaussianBlur6046" />
+    </filter>
+    <filter
+       x="-0.26128656"
+       width="1.5225731"
+       y="-0.26128656"
+       height="1.5225731"
+       id="filter6050">
+      <feGaussianBlur
+         stdDeviation="0.71113"
+         id="feGaussianBlur6052" />
+    </filter>
+    <filter
+       x="-0.26759372"
+       width="1.5351874"
+       y="-0.26759372"
+       height="1.5351874"
+       id="filter6056">
+      <feGaussianBlur
+         stdDeviation="0.72829587"
+         id="feGaussianBlur6058" />
+    </filter>
+    <filter
+       x="-0.3369152"
+       width="1.6738304"
+       y="-0.3369152"
+       height="1.6738304"
+       id="filter6062">
+      <feGaussianBlur
+         stdDeviation="0.91696453"
+         id="feGaussianBlur6064" />
+    </filter>
+    <filter
+       x="-0.39783707"
+       width="1.7956741"
+       y="-0.39783707"
+       height="1.7956741"
+       id="filter6068">
+      <feGaussianBlur
+         stdDeviation="1.0827724"
+         id="feGaussianBlur6070" />
+    </filter>
+    <filter
+       x="-0.43505875"
+       width="1.8701175"
+       y="-0.43505875"
+       height="1.8701175"
+       id="filter6074">
+      <feGaussianBlur
+         stdDeviation="1.1840767"
+         id="feGaussianBlur6076" />
+    </filter>
+    <filter
+       x="-0.48850195"
+       width="1.9770039"
+       y="-0.48850195"
+       height="1.9770039"
+       id="filter6080">
+      <feGaussianBlur
+         stdDeviation="1.3295303"
+         id="feGaussianBlur6082" />
+    </filter>
+    <filter
+       x="-0.52136748"
+       width="2.042735"
+       y="-0.52136748"
+       height="2.042735"
+       id="filter6086">
+      <feGaussianBlur
+         stdDeviation="1.4189787"
+         id="feGaussianBlur6088" />
+    </filter>
+    <filter
+       x="-0.59508286"
+       width="2.1901657"
+       y="-0.59508286"
+       height="2.1901657"
+       id="filter6092">
+      <feGaussianBlur
+         stdDeviation="1.619606"
+         id="feGaussianBlur6094" />
+    </filter>
+    <filter
+       x="-0.60056817"
+       width="2.2011363"
+       y="-0.60056817"
+       height="2.2011363"
+       id="filter6098">
+      <feGaussianBlur
+         stdDeviation="1.6345351"
+         id="feGaussianBlur6100" />
+    </filter>
+    <filter
+       x="-0.6929372"
+       width="2.3858744"
+       y="-0.6929372"
+       height="2.3858744"
+       id="filter6104">
+      <feGaussianBlur
+         stdDeviation="1.885931"
+         id="feGaussianBlur6106" />
+    </filter>
+    <filter
+       x="-0.72121728"
+       width="2.4424346"
+       y="-0.72121728"
+       height="2.4424346"
+       id="filter6110">
+      <feGaussianBlur
+         stdDeviation="1.9628994"
+         id="feGaussianBlur6112" />
+    </filter>
+    <filter
+       id="filter6116">
+      <feGaussianBlur
+         stdDeviation="0.063753828"
+         id="feGaussianBlur6118" />
+    </filter>
+    <filter
+       id="filter6122">
+      <feGaussianBlur
+         stdDeviation="0.1844166"
+         id="feGaussianBlur6124" />
+    </filter>
+    <filter
+       id="filter6128">
+      <feGaussianBlur
+         stdDeviation="0.25456758"
+         id="feGaussianBlur6130" />
+    </filter>
+    <filter
+       x="-0.13203832"
+       width="1.2640766"
+       y="-0.13203832"
+       height="1.2640766"
+       id="filter6134">
+      <feGaussianBlur
+         stdDeviation="0.35936179"
+         id="feGaussianBlur6136" />
+    </filter>
+    <filter
+       x="-0.17676232"
+       width="1.3535246"
+       y="-0.17676232"
+       height="1.3535246"
+       id="filter6140">
+      <feGaussianBlur
+         stdDeviation="0.48108478"
+         id="feGaussianBlur6142" />
+    </filter>
+    <filter
+       x="-0.23231775"
+       width="1.4646355"
+       y="-0.23231775"
+       height="1.4646355"
+       id="filter6146">
+      <feGaussianBlur
+         stdDeviation="0.63228711"
+         id="feGaussianBlur6148" />
+    </filter>
+    <filter
+       x="-0.29090587"
+       width="1.5818117"
+       y="-0.29090587"
+       height="1.5818117"
+       id="filter6152">
+      <feGaussianBlur
+         stdDeviation="0.79174333"
+         id="feGaussianBlur6154" />
+    </filter>
+    <filter
+       x="-0.35430643"
+       width="1.7086129"
+       y="-0.35430643"
+       height="1.7086129"
+       id="filter6158">
+      <feGaussianBlur
+         stdDeviation="0.96429731"
+         id="feGaussianBlur6160" />
+    </filter>
+    <filter
+       x="-0.40390887"
+       width="1.8078177"
+       y="-0.40390887"
+       height="1.8078177"
+       id="filter6164">
+      <feGaussianBlur
+         stdDeviation="1.0992977"
+         id="feGaussianBlur6166" />
+    </filter>
+    <filter
+       x="-0.41606408"
+       width="1.8321282"
+       y="-0.41606408"
+       height="1.8321282"
+       id="filter6170">
+      <feGaussianBlur
+         stdDeviation="1.1323799"
+         id="feGaussianBlur6172" />
+    </filter>
+    <filter
+       x="-0.46446558"
+       width="1.9289312"
+       y="-0.46446558"
+       height="1.9289312"
+       id="filter6176">
+      <feGaussianBlur
+         stdDeviation="1.2641117"
+         id="feGaussianBlur6178" />
+    </filter>
+    <filter
+       x="-0.53631256"
+       width="2.0726251"
+       y="-0.53631256"
+       height="2.0726251"
+       id="filter6182">
+      <feGaussianBlur
+         stdDeviation="1.4596539"
+         id="feGaussianBlur6184" />
+    </filter>
+    <filter
+       x="-0.57524745"
+       width="2.1504949"
+       y="-0.57524745"
+       height="2.1504949"
+       id="filter6188">
+      <feGaussianBlur
+         stdDeviation="1.565621"
+         id="feGaussianBlur6190" />
+    </filter>
+    <filter
+       x="-0.62242994"
+       width="2.2448599"
+       y="-0.62242994"
+       height="2.2448599"
+       id="filter6194">
+      <feGaussianBlur
+         stdDeviation="1.6940351"
+         id="feGaussianBlur6196" />
+    </filter>
+    <filter
+       x="-0.68973088"
+       width="2.3794618"
+       y="-0.68973088"
+       height="2.3794618"
+       id="filter6200">
+      <feGaussianBlur
+         stdDeviation="1.8772045"
+         id="feGaussianBlur6202" />
+    </filter>
+    <filter
+       x="-0.69778596"
+       width="2.3955719"
+       y="-0.69778596"
+       height="2.3955719"
+       id="filter6206">
+      <feGaussianBlur
+         stdDeviation="1.8991276"
+         id="feGaussianBlur6208" />
+    </filter>
+    <filter
+       id="filter6214">
+      <feGaussianBlur
+         stdDeviation="0.1365937"
+         id="feGaussianBlur6216" />
+    </filter>
+    <filter
+       x="-0.10548826"
+       width="1.2109765"
+       y="-0.10548826"
+       height="1.2109765"
+       id="filter6220">
+      <feGaussianBlur
+         stdDeviation="0.28710189"
+         id="feGaussianBlur6222" />
+    </filter>
+    <filter
+       x="-0.14012679"
+       width="1.2802536"
+       y="-0.14012679"
+       height="1.2802536"
+       id="filter6226">
+      <feGaussianBlur
+         stdDeviation="0.38137578"
+         id="feGaussianBlur6228" />
+    </filter>
+    <filter
+       x="-0.17189177"
+       width="1.3437835"
+       y="-0.17189177"
+       height="1.3437835"
+       id="filter6232">
+      <feGaussianBlur
+         stdDeviation="0.46782887"
+         id="feGaussianBlur6234" />
+    </filter>
+    <filter
+       x="-0.23378948"
+       width="1.467579"
+       y="-0.23378948"
+       height="1.467579"
+       id="filter6238">
+      <feGaussianBlur
+         stdDeviation="0.63629262"
+         id="feGaussianBlur6240" />
+    </filter>
+    <filter
+       x="-0.28048249"
+       width="1.560965"
+       y="-0.28048249"
+       height="1.560965"
+       id="filter6244">
+      <feGaussianBlur
+         stdDeviation="0.76337456"
+         id="feGaussianBlur6246" />
+    </filter>
+    <filter
+       x="-0.35779101"
+       width="1.715582"
+       y="-0.35779101"
+       height="1.715582"
+       id="filter6250">
+      <feGaussianBlur
+         stdDeviation="0.97378113"
+         id="feGaussianBlur6252" />
+    </filter>
+    <filter
+       x="-0.37216094"
+       width="1.7443219"
+       y="-0.37216094"
+       height="1.7443219"
+       id="filter6256">
+      <feGaussianBlur
+         stdDeviation="1.012891"
+         id="feGaussianBlur6258" />
+    </filter>
+    <filter
+       x="-0.41585719"
+       width="1.8317144"
+       y="-0.41585719"
+       height="1.8317144"
+       id="filter6262">
+      <feGaussianBlur
+         stdDeviation="1.1318168"
+         id="feGaussianBlur6264" />
+    </filter>
+    <filter
+       x="-0.47041279"
+       width="1.9408256"
+       y="-0.47041279"
+       height="1.9408256"
+       id="filter6268">
+      <feGaussianBlur
+         stdDeviation="1.2802979"
+         id="feGaussianBlur6270" />
+    </filter>
+    <filter
+       x="-0.54230805"
+       width="2.0846161"
+       y="-0.54230805"
+       height="2.0846161"
+       id="filter6274">
+      <feGaussianBlur
+         stdDeviation="1.4759715"
+         id="feGaussianBlur6276" />
+    </filter>
+    <filter
+       x="-0.57787096"
+       width="2.1557419"
+       y="-0.57787096"
+       height="2.1557419"
+       id="filter6280">
+      <feGaussianBlur
+         stdDeviation="1.5727612"
+         id="feGaussianBlur6282" />
+    </filter>
+    <filter
+       x="-0.6178386"
+       width="2.2356772"
+       y="-0.6178386"
+       height="2.2356772"
+       id="filter6286">
+      <feGaussianBlur
+         stdDeviation="1.6815391"
+         id="feGaussianBlur6288" />
+    </filter>
+    <filter
+       x="-0.6938956"
+       width="2.3877912"
+       y="-0.6938956"
+       height="2.3877912"
+       id="filter6292">
+      <feGaussianBlur
+         stdDeviation="1.8885395"
+         id="feGaussianBlur6294" />
+    </filter>
+    <filter
+       x="-0.74112398"
+       width="2.482248"
+       y="-0.74112398"
+       height="2.482248"
+       id="filter6298">
+      <feGaussianBlur
+         stdDeviation="2.0170785"
+         id="feGaussianBlur6300" />
+    </filter>
+    <filter
+       id="filter6304">
+      <feGaussianBlur
+         stdDeviation="0.057392849"
+         id="feGaussianBlur6306" />
+    </filter>
+    <filter
+       id="filter6310">
+      <feGaussianBlur
+         stdDeviation="0.11679798"
+         id="feGaussianBlur6312" />
+    </filter>
+    <filter
+       id="filter6316">
+      <feGaussianBlur
+         stdDeviation="0.21225022"
+         id="feGaussianBlur6318" />
+    </filter>
+    <filter
+       x="-0.1585007"
+       width="1.3170014"
+       y="-0.1585007"
+       height="1.3170014"
+       id="filter6322">
+      <feGaussianBlur
+         stdDeviation="0.43138309"
+         id="feGaussianBlur6324" />
+    </filter>
+    <filter
+       x="-0.19644302"
+       width="1.392886"
+       y="-0.19644302"
+       height="1.392886"
+       id="filter6328">
+      <feGaussianBlur
+         stdDeviation="0.53464872"
+         id="feGaussianBlur6330" />
+    </filter>
+    <filter
+       x="-0.21882678"
+       width="1.4376536"
+       y="-0.21882678"
+       height="1.4376536"
+       id="filter6334">
+      <feGaussianBlur
+         stdDeviation="0.59556943"
+         id="feGaussianBlur6336" />
+    </filter>
+    <filter
+       x="-0.31141295"
+       width="1.6228259"
+       y="-0.31141295"
+       height="1.6228259"
+       id="filter6340">
+      <feGaussianBlur
+         stdDeviation="0.84755638"
+         id="feGaussianBlur6342" />
+    </filter>
+    <filter
+       x="-0.32723746"
+       width="1.6544749"
+       y="-0.32723746"
+       height="1.6544749"
+       id="filter6346">
+      <feGaussianBlur
+         stdDeviation="0.89062513"
+         id="feGaussianBlur6348" />
+    </filter>
+    <filter
+       x="-0.40541529"
+       width="1.8108306"
+       y="-0.40541529"
+       height="1.8108306"
+       id="filter6352">
+      <feGaussianBlur
+         stdDeviation="1.1033976"
+         id="feGaussianBlur6354" />
+    </filter>
+    <filter
+       x="-0.44868409"
+       width="1.8973682"
+       y="-0.44868409"
+       height="1.8973682"
+       id="filter6358">
+      <feGaussianBlur
+         stdDeviation="1.2211601"
+         id="feGaussianBlur6360" />
+    </filter>
+    <filter
+       x="-0.49784906"
+       width="1.9956981"
+       y="-0.49784906"
+       height="1.9956981"
+       id="filter6364">
+      <feGaussianBlur
+         stdDeviation="1.3549698"
+         id="feGaussianBlur6366" />
+    </filter>
+    <filter
+       x="-0.53134588"
+       width="2.0626918"
+       y="-0.53134588"
+       height="2.0626918"
+       id="filter6370">
+      <feGaussianBlur
+         stdDeviation="1.4461363"
+         id="feGaussianBlur6372" />
+    </filter>
+    <filter
+       x="-0.56037449"
+       width="2.120749"
+       y="-0.56037449"
+       height="2.120749"
+       id="filter6376">
+      <feGaussianBlur
+         stdDeviation="1.525142"
+         id="feGaussianBlur6378" />
+    </filter>
+    <filter
+       x="-0.63780207"
+       width="2.2756041"
+       y="-0.63780207"
+       height="2.2756041"
+       id="filter6382">
+      <feGaussianBlur
+         stdDeviation="1.7358726"
+         id="feGaussianBlur6384" />
+    </filter>
+    <filter
+       x="-0.66999303"
+       width="2.3399861"
+       y="-0.66999303"
+       height="2.3399861"
+       id="filter6388">
+      <feGaussianBlur
+         stdDeviation="1.8234851"
+         id="feGaussianBlur6390" />
+    </filter>
+    <filter
+       x="-0.73159249"
+       width="2.463185"
+       y="-0.73159249"
+       height="2.463185"
+       id="filter6394">
+      <feGaussianBlur
+         stdDeviation="1.9911371"
+         id="feGaussianBlur6396" />
+    </filter>
+    <filter
+       id="filter6400">
+      <feGaussianBlur
+         stdDeviation="0.010980855"
+         id="feGaussianBlur6402" />
+    </filter>
+    <filter
+       id="filter6406">
+      <feGaussianBlur
+         stdDeviation="0.16290031"
+         id="feGaussianBlur6408" />
+    </filter>
+    <filter
+       x="-0.10384288"
+       width="1.2076858"
+       y="-0.10384288"
+       height="1.2076858"
+       id="filter6412">
+      <feGaussianBlur
+         stdDeviation="0.28262374"
+         id="feGaussianBlur6414" />
+    </filter>
+    <filter
+       x="-0.12371628"
+       width="1.2474326"
+       y="-0.12371628"
+       height="1.2474326"
+       id="filter6418">
+      <feGaussianBlur
+         stdDeviation="0.33671214"
+         id="feGaussianBlur6420" />
+    </filter>
+    <filter
+       x="-0.2011107"
+       width="1.4022214"
+       y="-0.2011107"
+       height="1.4022214"
+       id="filter6424">
+      <feGaussianBlur
+         stdDeviation="0.5473525"
+         id="feGaussianBlur6426" />
+    </filter>
+    <filter
+       x="-0.25264489"
+       width="1.5052898"
+       y="-0.25264489"
+       height="1.5052898"
+       id="filter6430">
+      <feGaussianBlur
+         stdDeviation="0.68761042"
+         id="feGaussianBlur6432" />
+    </filter>
+    <filter
+       x="-0.29839475"
+       width="1.5967895"
+       y="-0.29839475"
+       height="1.5967895"
+       id="filter6436">
+      <feGaussianBlur
+         stdDeviation="0.81212541"
+         id="feGaussianBlur6438" />
+    </filter>
+    <filter
+       x="-0.319692"
+       width="1.639384"
+       y="-0.319692"
+       height="1.639384"
+       id="filter6442">
+      <feGaussianBlur
+         stdDeviation="0.87008903"
+         id="feGaussianBlur6444" />
+    </filter>
+    <filter
+       x="-0.37637117"
+       width="1.7527423"
+       y="-0.37637117"
+       height="1.7527423"
+       id="filter6448">
+      <feGaussianBlur
+         stdDeviation="1.0243498"
+         id="feGaussianBlur6450" />
+    </filter>
+    <filter
+       x="-0.45446711"
+       width="1.9089342"
+       y="-0.45446711"
+       height="1.9089342"
+       id="filter6454">
+      <feGaussianBlur
+         stdDeviation="1.2368994"
+         id="feGaussianBlur6456" />
+    </filter>
+    <filter
+       x="-0.50050647"
+       width="2.0010129"
+       y="-0.50050647"
+       height="2.0010129"
+       id="filter6460">
+      <feGaussianBlur
+         stdDeviation="1.3622023"
+         id="feGaussianBlur6462" />
+    </filter>
+    <filter
+       x="-0.53891647"
+       width="2.0778329"
+       y="-0.53891647"
+       height="2.0778329"
+       id="filter6466">
+      <feGaussianBlur
+         stdDeviation="1.4667408"
+         id="feGaussianBlur6468" />
+    </filter>
+    <filter
+       x="-0.57981734"
+       width="2.1596347"
+       y="-0.57981734"
+       height="2.1596347"
+       id="filter6472">
+      <feGaussianBlur
+         stdDeviation="1.5780586"
+         id="feGaussianBlur6474" />
+    </filter>
+    <filter
+       x="-0.63649951"
+       width="2.272999"
+       y="-0.63649951"
+       height="2.272999"
+       id="filter6478">
+      <feGaussianBlur
+         stdDeviation="1.7323275"
+         id="feGaussianBlur6480" />
+    </filter>
+    <filter
+       x="-0.67015353"
+       width="2.3403071"
+       y="-0.67015353"
+       height="2.3403071"
+       id="filter6484">
+      <feGaussianBlur
+         stdDeviation="1.8239219"
+         id="feGaussianBlur6486" />
+    </filter>
+    <filter
+       x="-0.71081765"
+       width="2.4216353"
+       y="-0.71081765"
+       height="2.4216353"
+       id="filter6490">
+      <feGaussianBlur
+         stdDeviation="1.9345953"
+         id="feGaussianBlur6492" />
+    </filter>
+    <filter
+       id="filter6496">
+      <feGaussianBlur
+         stdDeviation="0.0085460739"
+         id="feGaussianBlur6498" />
+    </filter>
+    <filter
+       id="filter6502">
+      <feGaussianBlur
+         stdDeviation="0.1321657"
+         id="feGaussianBlur6504" />
+    </filter>
+    <filter
+       x="-0.11789382"
+       width="1.2357876"
+       y="-0.11789382"
+       height="1.2357876"
+       id="filter6508">
+      <feGaussianBlur
+         stdDeviation="0.32086547"
+         id="feGaussianBlur6510" />
+    </filter>
+    <filter
+       x="-0.15538907"
+       width="1.3107781"
+       y="-0.15538907"
+       height="1.3107781"
+       id="filter6514">
+      <feGaussianBlur
+         stdDeviation="0.42291433"
+         id="feGaussianBlur6516" />
+    </filter>
+    <filter
+       x="-0.20978849"
+       width="1.419577"
+       y="-0.20978849"
+       height="1.419577"
+       id="filter6520">
+      <feGaussianBlur
+         stdDeviation="0.57097039"
+         id="feGaussianBlur6522" />
+    </filter>
+    <filter
+       x="-0.22490103"
+       width="1.4498021"
+       y="-0.22490103"
+       height="1.4498021"
+       id="filter6526">
+      <feGaussianBlur
+         stdDeviation="0.61210141"
+         id="feGaussianBlur6528" />
+    </filter>
+    <filter
+       x="-0.30732421"
+       width="1.6146484"
+       y="-0.30732421"
+       height="1.6146484"
+       id="filter6532">
+      <feGaussianBlur
+         stdDeviation="0.83642827"
+         id="feGaussianBlur6534" />
+    </filter>
+    <filter
+       x="-0.32557592"
+       width="1.6511518"
+       y="-0.32557592"
+       height="1.6511518"
+       id="filter6538">
+      <feGaussianBlur
+         stdDeviation="0.886103"
+         id="feGaussianBlur6540" />
+    </filter>
+    <filter
+       x="-0.38493679"
+       width="1.7698736"
+       y="-0.38493679"
+       height="1.7698736"
+       id="filter6544">
+      <feGaussianBlur
+         stdDeviation="1.0476624"
+         id="feGaussianBlur6546" />
+    </filter>
+    <filter
+       x="-0.40980004"
+       width="1.8196001"
+       y="-0.40980004"
+       height="1.8196001"
+       id="filter6550">
+      <feGaussianBlur
+         stdDeviation="1.1153314"
+         id="feGaussianBlur6552" />
+    </filter>
+    <filter
+       x="-0.49357227"
+       width="1.9871445"
+       y="-0.49357227"
+       height="1.9871445"
+       id="filter6556">
+      <feGaussianBlur
+         stdDeviation="1.3433299"
+         id="feGaussianBlur6558" />
+    </filter>
+    <filter
+       x="-0.53786552"
+       width="2.075731"
+       y="-0.53786552"
+       height="2.075731"
+       id="filter6562">
+      <feGaussianBlur
+         stdDeviation="1.4638805"
+         id="feGaussianBlur6564" />
+    </filter>
+    <filter
+       x="-0.57913498"
+       width="2.15827"
+       y="-0.57913498"
+       height="2.15827"
+       id="filter6568">
+      <feGaussianBlur
+         stdDeviation="1.5762015"
+         id="feGaussianBlur6570" />
+    </filter>
+    <filter
+       x="-0.62891391"
+       width="2.2578278"
+       y="-0.62891391"
+       height="2.2578278"
+       id="filter6574">
+      <feGaussianBlur
+         stdDeviation="1.7116822"
+         id="feGaussianBlur6576" />
+    </filter>
+    <filter
+       x="-0.66066309"
+       width="2.3213262"
+       y="-0.66066309"
+       height="2.3213262"
+       id="filter6580">
+      <feGaussianBlur
+         stdDeviation="1.7980923"
+         id="feGaussianBlur6582" />
+    </filter>
+    <filter
+       x="-0.72407835"
+       width="2.4481567"
+       y="-0.72407835"
+       height="2.4481567"
+       id="filter6586">
+      <feGaussianBlur
+         stdDeviation="1.9706862"
+         id="feGaussianBlur6588" />
+    </filter>
+    <filter
+       id="filter6594">
+      <feGaussianBlur
+         stdDeviation="0.19261968"
+         id="feGaussianBlur6596" />
+    </filter>
+    <filter
+       id="filter6600">
+      <feGaussianBlur
+         stdDeviation="0.21907614"
+         id="feGaussianBlur6602" />
+    </filter>
+    <filter
+       x="-0.15396558"
+       width="1.3079312"
+       y="-0.15396558"
+       height="1.3079312"
+       id="filter6606">
+      <feGaussianBlur
+         stdDeviation="0.41904009"
+         id="feGaussianBlur6608" />
+    </filter>
+    <filter
+       x="-0.20594025"
+       width="1.4118805"
+       y="-0.20594025"
+       height="1.4118805"
+       id="filter6612">
+      <feGaussianBlur
+         stdDeviation="0.56049683"
+         id="feGaussianBlur6614" />
+    </filter>
+    <filter
+       x="-0.22375318"
+       width="1.4475064"
+       y="-0.22375318"
+       height="1.4475064"
+       id="filter6618">
+      <feGaussianBlur
+         stdDeviation="0.60897736"
+         id="feGaussianBlur6620" />
+    </filter>
+    <filter
+       x="-0.30591461"
+       width="1.6118292"
+       y="-0.30591461"
+       height="1.6118292"
+       id="filter6624">
+      <feGaussianBlur
+         stdDeviation="0.83259183"
+         id="feGaussianBlur6626" />
+    </filter>
+    <filter
+       x="-0.34566394"
+       width="1.6913279"
+       y="-0.34566394"
+       height="1.6913279"
+       id="filter6630">
+      <feGaussianBlur
+         stdDeviation="0.94077551"
+         id="feGaussianBlur6632" />
+    </filter>
+    <filter
+       x="-0.36881846"
+       width="1.7376369"
+       y="-0.36881846"
+       height="1.7376369"
+       id="filter6636">
+      <feGaussianBlur
+         stdDeviation="1.003794"
+         id="feGaussianBlur6638" />
+    </filter>
+    <filter
+       x="-0.44040758"
+       width="1.8808152"
+       y="-0.44040758"
+       height="1.8808152"
+       id="filter6642">
+      <feGaussianBlur
+         stdDeviation="1.1986343"
+         id="feGaussianBlur6644" />
+    </filter>
+    <filter
+       x="-0.47236998"
+       width="1.94474"
+       y="-0.47236998"
+       height="1.94474"
+       id="filter6648">
+      <feGaussianBlur
+         stdDeviation="1.2856247"
+         id="feGaussianBlur6650" />
+    </filter>
+    <filter
+       x="-0.53184245"
+       width="2.0636849"
+       y="-0.53184245"
+       height="2.0636849"
+       id="filter6654">
+      <feGaussianBlur
+         stdDeviation="1.4474878"
+         id="feGaussianBlur6656" />
+    </filter>
+    <filter
+       x="-0.57481744"
+       width="2.1496349"
+       y="-0.57481744"
+       height="2.1496349"
+       id="filter6660">
+      <feGaussianBlur
+         stdDeviation="1.5644506"
+         id="feGaussianBlur6662" />
+    </filter>
+    <filter
+       x="-0.61887746"
+       width="2.2377549"
+       y="-0.61887746"
+       height="2.2377549"
+       id="filter6666">
+      <feGaussianBlur
+         stdDeviation="1.6843665"
+         id="feGaussianBlur6668" />
+    </filter>
+    <filter
+       x="-0.68936342"
+       width="2.3787268"
+       y="-0.68936342"
+       height="2.3787268"
+       id="filter6672">
+      <feGaussianBlur
+         stdDeviation="1.8762045"
+         id="feGaussianBlur6674" />
+    </filter>
+    <filter
+       x="-0.71643346"
+       width="2.4328669"
+       y="-0.71643346"
+       height="2.4328669"
+       id="filter6678">
+      <feGaussianBlur
+         stdDeviation="1.9498796"
+         id="feGaussianBlur6680" />
+    </filter>
+    <filter
+       id="filter6686">
+      <feGaussianBlur
+         stdDeviation="0.17404206"
+         id="feGaussianBlur6688" />
+    </filter>
+    <filter
+       x="-0.11791305"
+       width="1.2358261"
+       y="-0.11791305"
+       height="1.2358261"
+       id="filter6692">
+      <feGaussianBlur
+         stdDeviation="0.32091779"
+         id="feGaussianBlur6694" />
+    </filter>
+    <filter
+       x="-0.16623413"
+       width="1.3324683"
+       y="-0.16623413"
+       height="1.3324683"
+       id="filter6698">
+      <feGaussianBlur
+         stdDeviation="0.45243076"
+         id="feGaussianBlur6700" />
+    </filter>
+    <filter
+       x="-0.2155926"
+       width="1.4311852"
+       y="-0.2155926"
+       height="1.4311852"
+       id="filter6704">
+      <feGaussianBlur
+         stdDeviation="0.58676712"
+         id="feGaussianBlur6706" />
+    </filter>
+    <filter
+       x="-0.23551813"
+       width="1.4710363"
+       y="-0.23551813"
+       height="1.4710363"
+       id="filter6710">
+      <feGaussianBlur
+         stdDeviation="0.64099741"
+         id="feGaussianBlur6712" />
+    </filter>
+    <filter
+       x="-0.2803208"
+       width="1.5606416"
+       y="-0.2803208"
+       height="1.5606416"
+       id="filter6716">
+      <feGaussianBlur
+         stdDeviation="0.7629345"
+         id="feGaussianBlur6718" />
+    </filter>
+    <filter
+       x="-0.33068048"
+       width="1.661361"
+       y="-0.33068048"
+       height="1.661361"
+       id="filter6722">
+      <feGaussianBlur
+         stdDeviation="0.8999958"
+         id="feGaussianBlur6724" />
+    </filter>
+    <filter
+       x="-0.37719608"
+       width="1.7543922"
+       y="-0.37719608"
+       height="1.7543922"
+       id="filter6728">
+      <feGaussianBlur
+         stdDeviation="1.0265949"
+         id="feGaussianBlur6730" />
+    </filter>
+    <filter
+       x="-0.42792371"
+       width="1.8558474"
+       y="-0.42792371"
+       height="1.8558474"
+       id="filter6734">
+      <feGaussianBlur
+         stdDeviation="1.1646576"
+         id="feGaussianBlur6736" />
+    </filter>
+    <filter
+       x="-0.45717451"
+       width="1.914349"
+       y="-0.45717451"
+       height="1.914349"
+       id="filter6740">
+      <feGaussianBlur
+         stdDeviation="1.244268"
+         id="feGaussianBlur6742" />
+    </filter>
+    <filter
+       x="-0.54232757"
+       width="2.0846551"
+       y="-0.54232757"
+       height="2.0846551"
+       id="filter6746">
+      <feGaussianBlur
+         stdDeviation="1.4760246"
+         id="feGaussianBlur6748" />
+    </filter>
+    <filter
+       x="-0.56890442"
+       width="2.1378088"
+       y="-0.56890442"
+       height="2.1378088"
+       id="filter6752">
+      <feGaussianBlur
+         stdDeviation="1.5483575"
+         id="feGaussianBlur6754" />
+    </filter>
+    <filter
+       x="-0.61241698"
+       width="2.224834"
+       y="-0.61241698"
+       height="2.224834"
+       id="filter6758">
+      <feGaussianBlur
+         stdDeviation="1.6667833"
+         id="feGaussianBlur6760" />
+    </filter>
+    <filter
+       x="-0.65605612"
+       width="2.3121122"
+       y="-0.65605612"
+       height="2.3121122"
+       id="filter6764">
+      <feGaussianBlur
+         stdDeviation="1.7855537"
+         id="feGaussianBlur6766" />
+    </filter>
+    <filter
+       x="-0.73258731"
+       width="2.4651746"
+       y="-0.73258731"
+       height="2.4651746"
+       id="filter6770">
+      <feGaussianBlur
+         stdDeviation="1.9938446"
+         id="feGaussianBlur6772" />
+    </filter>
+    <filter
+       id="filter6778">
+      <feGaussianBlur
+         stdDeviation="0.17704693"
+         id="feGaussianBlur6780" />
+    </filter>
+    <filter
+       id="filter6784">
+      <feGaussianBlur
+         stdDeviation="0.22443559"
+         id="feGaussianBlur6786" />
+    </filter>
+    <filter
+       x="-0.12897283"
+       width="1.2579457"
+       y="-0.12897283"
+       height="1.2579457"
+       id="filter6790">
+      <feGaussianBlur
+         stdDeviation="0.35101863"
+         id="feGaussianBlur6792" />
+    </filter>
+    <filter
+       x="-0.18554558"
+       width="1.3710912"
+       y="-0.18554558"
+       height="1.3710912"
+       id="filter6796">
+      <feGaussianBlur
+         stdDeviation="0.50498972"
+         id="feGaussianBlur6798" />
+    </filter>
+    <filter
+       x="-0.26304068"
+       width="1.5260814"
+       y="-0.26304068"
+       height="1.5260814"
+       id="filter6802">
+      <feGaussianBlur
+         stdDeviation="0.71590409"
+         id="feGaussianBlur6804" />
+    </filter>
+    <filter
+       x="-0.30296886"
+       width="1.6059377"
+       y="-0.30296886"
+       height="1.6059377"
+       id="filter6808">
+      <feGaussianBlur
+         stdDeviation="0.82457455"
+         id="feGaussianBlur6810" />
+    </filter>
+    <filter
+       x="-0.31767266"
+       width="1.6353453"
+       y="-0.31767266"
+       height="1.6353453"
+       id="filter6814">
+      <feGaussianBlur
+         stdDeviation="0.8645931"
+         id="feGaussianBlur6816" />
+    </filter>
+    <filter
+       x="-0.36306796"
+       width="1.7261359"
+       y="-0.36306796"
+       height="1.7261359"
+       id="filter6820">
+      <feGaussianBlur
+         stdDeviation="0.98814313"
+         id="feGaussianBlur6822" />
+    </filter>
+    <filter
+       x="-0.44088922"
+       width="1.8817784"
+       y="-0.44088922"
+       height="1.8817784"
+       id="filter6826">
+      <feGaussianBlur
+         stdDeviation="1.1999452"
+         id="feGaussianBlur6828" />
+    </filter>
+    <filter
+       x="-0.48130078"
+       width="1.9626016"
+       y="-0.48130078"
+       height="1.9626016"
+       id="filter6832">
+      <feGaussianBlur
+         stdDeviation="1.3099312"
+         id="feGaussianBlur6834" />
+    </filter>
+    <filter
+       x="-0.52350828"
+       width="2.0470166"
+       y="-0.52350828"
+       height="2.0470166"
+       id="filter6838">
+      <feGaussianBlur
+         stdDeviation="1.4248052"
+         id="feGaussianBlur6840" />
+    </filter>
+    <filter
+       x="-0.57182086"
+       width="2.1436417"
+       y="-0.57182086"
+       height="2.1436417"
+       id="filter6844">
+      <feGaussianBlur
+         stdDeviation="1.556295"
+         id="feGaussianBlur6846" />
+    </filter>
+    <filter
+       x="-0.61671473"
+       width="2.2334295"
+       y="-0.61671473"
+       height="2.2334295"
+       id="filter6850">
+      <feGaussianBlur
+         stdDeviation="1.6784803"
+         id="feGaussianBlur6852" />
+    </filter>
+    <filter
+       x="-0.66886465"
+       width="2.3377293"
+       y="-0.66886465"
+       height="2.3377293"
+       id="filter6856">
+      <feGaussianBlur
+         stdDeviation="1.820414"
+         id="feGaussianBlur6858" />
+    </filter>
+    <filter
+       x="-0.7290382"
+       width="2.4580764"
+       y="-0.7290382"
+       height="2.4580764"
+       id="filter6862">
+      <feGaussianBlur
+         stdDeviation="1.9841852"
+         id="feGaussianBlur6864" />
+    </filter>
+    <filter
+       id="filter6870">
+      <feGaussianBlur
+         stdDeviation="0.17628727"
+         id="feGaussianBlur6872" />
+    </filter>
+    <filter
+       id="filter6876">
+      <feGaussianBlur
+         stdDeviation="0.22236866"
+         id="feGaussianBlur6878" />
+    </filter>
+    <filter
+       x="-0.14369669"
+       width="1.2873934"
+       y="-0.14369669"
+       height="1.2873934"
+       id="filter6882">
+      <feGaussianBlur
+         stdDeviation="0.39109178"
+         id="feGaussianBlur6884" />
+    </filter>
+    <filter
+       x="-0.18089999"
+       width="1.3618"
+       y="-0.18089999"
+       height="1.3618"
+       id="filter6888">
+      <feGaussianBlur
+         stdDeviation="0.49234605"
+         id="feGaussianBlur6890" />
+    </filter>
+    <filter
+       x="-0.25288716"
+       width="1.5057743"
+       y="-0.25288716"
+       height="1.5057743"
+       id="filter6894">
+      <feGaussianBlur
+         stdDeviation="0.68826979"
+         id="feGaussianBlur6896" />
+    </filter>
+    <filter
+       x="-0.30356191"
+       width="1.6071238"
+       y="-0.30356191"
+       height="1.6071238"
+       id="filter6900">
+      <feGaussianBlur
+         stdDeviation="0.82618862"
+         id="feGaussianBlur6902" />
+    </filter>
+    <filter
+       x="-0.32955703"
+       width="1.6591141"
+       y="-0.32955703"
+       height="1.6591141"
+       id="filter6906">
+      <feGaussianBlur
+         stdDeviation="0.89693816"
+         id="feGaussianBlur6908" />
+    </filter>
+    <filter
+       x="-0.3610998"
+       width="1.7221996"
+       y="-0.3610998"
+       height="1.7221996"
+       id="filter6912">
+      <feGaussianBlur
+         stdDeviation="0.98278649"
+         id="feGaussianBlur6914" />
+    </filter>
+    <filter
+       x="-0.44923516"
+       width="1.8984703"
+       y="-0.44923516"
+       height="1.8984703"
+       id="filter6918">
+      <feGaussianBlur
+         stdDeviation="1.2226599"
+         id="feGaussianBlur6920" />
+    </filter>
+    <filter
+       x="-0.46588398"
+       width="1.931768"
+       y="-0.46588398"
+       height="1.931768"
+       id="filter6924">
+      <feGaussianBlur
+         stdDeviation="1.2679721"
+         id="feGaussianBlur6926" />
+    </filter>
+    <filter
+       x="-0.50764574"
+       width="2.0152915"
+       y="-0.50764574"
+       height="2.0152915"
+       id="filter6930">
+      <feGaussianBlur
+         stdDeviation="1.3816329"
+         id="feGaussianBlur6932" />
+    </filter>
+    <filter
+       x="-0.5613094"
+       width="2.1226188"
+       y="-0.5613094"
+       height="2.1226188"
+       id="filter6936">
+      <feGaussianBlur
+         stdDeviation="1.5276865"
+         id="feGaussianBlur6938" />
+    </filter>
+    <filter
+       x="-0.60467442"
+       width="2.2093488"
+       y="-0.60467442"
+       height="2.2093488"
+       id="filter6942">
+      <feGaussianBlur
+         stdDeviation="1.6457108"
+         id="feGaussianBlur6944" />
+    </filter>
+    <filter
+       x="-0.67410516"
+       width="2.3482103"
+       y="-0.67410516"
+       height="2.3482103"
+       id="filter6948">
+      <feGaussianBlur
+         stdDeviation="1.8346768"
+         id="feGaussianBlur6950" />
+    </filter>
+    <filter
+       x="-0.7023943"
+       width="2.4047886"
+       y="-0.7023943"
+       height="2.4047886"
+       id="filter6954">
+      <feGaussianBlur
+         stdDeviation="1.9116699"
+         id="feGaussianBlur6956" />
+    </filter>
+    <filter
+       id="filter6960">
+      <feGaussianBlur
+         stdDeviation="0.05473096"
+         id="feGaussianBlur6962" />
+    </filter>
+    <filter
+       id="filter6966">
+      <feGaussianBlur
+         stdDeviation="0.19394764"
+         id="feGaussianBlur6968" />
+    </filter>
+    <filter
+       id="filter6972">
+      <feGaussianBlur
+         stdDeviation="0.21402328"
+         id="feGaussianBlur6974" />
+    </filter>
+    <filter
+       x="-0.16304401"
+       width="1.326088"
+       y="-0.16304401"
+       height="1.326088"
+       id="filter6978">
+      <feGaussianBlur
+         stdDeviation="0.44374837"
+         id="feGaussianBlur6980" />
+    </filter>
+    <filter
+       x="-0.19531386"
+       width="1.3906277"
+       y="-0.19531386"
+       height="1.3906277"
+       id="filter6984">
+      <feGaussianBlur
+         stdDeviation="0.53157555"
+         id="feGaussianBlur6986" />
+    </filter>
+    <filter
+       x="-0.23800023"
+       width="1.4760005"
+       y="-0.23800023"
+       height="1.4760005"
+       id="filter6990">
+      <feGaussianBlur
+         stdDeviation="0.64775281"
+         id="feGaussianBlur6992" />
+    </filter>
+    <filter
+       x="-0.26649845"
+       width="1.5329969"
+       y="-0.26649845"
+       height="1.5329969"
+       id="filter6996">
+      <feGaussianBlur
+         stdDeviation="0.72531493"
+         id="feGaussianBlur6998" />
+    </filter>
+    <filter
+       x="-0.32301244"
+       width="1.6460249"
+       y="-0.32301244"
+       height="1.6460249"
+       id="filter7002">
+      <feGaussianBlur
+         stdDeviation="0.8791261"
+         id="feGaussianBlur7004" />
+    </filter>
+    <filter
+       x="-0.39225201"
+       width="1.784504"
+       y="-0.39225201"
+       height="1.784504"
+       id="filter7008">
+      <feGaussianBlur
+         stdDeviation="1.0675718"
+         id="feGaussianBlur7010" />
+    </filter>
+    <filter
+       x="-0.44851422"
+       width="1.8970284"
+       y="-0.44851422"
+       height="1.8970284"
+       id="filter7014">
+      <feGaussianBlur
+         stdDeviation="1.2206977"
+         id="feGaussianBlur7016" />
+    </filter>
+    <filter
+       x="-0.48467421"
+       width="1.9693484"
+       y="-0.48467421"
+       height="1.9693484"
+       id="filter7020">
+      <feGaussianBlur
+         stdDeviation="1.3191125"
+         id="feGaussianBlur7022" />
+    </filter>
+    <filter
+       x="-0.53841505"
+       width="2.0768301"
+       y="-0.53841505"
+       height="2.0768301"
+       id="filter7026">
+      <feGaussianBlur
+         stdDeviation="1.4653761"
+         id="feGaussianBlur7028" />
+    </filter>
+    <filter
+       x="-0.5796361"
+       width="2.1592722"
+       y="-0.5796361"
+       height="2.1592722"
+       id="filter7032">
+      <feGaussianBlur
+         stdDeviation="1.5775653"
+         id="feGaussianBlur7034" />
+    </filter>
+    <filter
+       x="-0.60622794"
+       width="2.2124559"
+       y="-0.60622794"
+       height="2.2124559"
+       id="filter7038">
+      <feGaussianBlur
+         stdDeviation="1.6499389"
+         id="feGaussianBlur7040" />
+    </filter>
+    <filter
+       x="-0.66712939"
+       width="2.3342588"
+       y="-0.66712939"
+       height="2.3342588"
+       id="filter7044">
+      <feGaussianBlur
+         stdDeviation="1.8156912"
+         id="feGaussianBlur7046" />
+    </filter>
+    <filter
+       x="-0.71994351"
+       width="2.439887"
+       y="-0.71994351"
+       height="2.439887"
+       id="filter7050">
+      <feGaussianBlur
+         stdDeviation="1.9594327"
+         id="feGaussianBlur7052" />
+    </filter>
+    <filter
+       id="filter7056">
+      <feGaussianBlur
+         stdDeviation="0.056953873"
+         id="feGaussianBlur7058" />
+    </filter>
+    <filter
+       id="filter7062">
+      <feGaussianBlur
+         stdDeviation="0.14798624"
+         id="feGaussianBlur7064" />
+    </filter>
+    <filter
+       id="filter7068">
+      <feGaussianBlur
+         stdDeviation="0.22042735"
+         id="feGaussianBlur7070" />
+    </filter>
+    <filter
+       x="-0.16040743"
+       width="1.3208149"
+       y="-0.16040743"
+       height="1.3208149"
+       id="filter7074">
+      <feGaussianBlur
+         stdDeviation="0.43657253"
+         id="feGaussianBlur7076" />
+    </filter>
+    <filter
+       x="-0.18517369"
+       width="1.3703474"
+       y="-0.18517369"
+       height="1.3703474"
+       id="filter7080">
+      <feGaussianBlur
+         stdDeviation="0.50397757"
+         id="feGaussianBlur7082" />
+    </filter>
+    <filter
+       x="-0.24156458"
+       width="1.4831292"
+       y="-0.24156458"
+       height="1.4831292"
+       id="filter7086">
+      <feGaussianBlur
+         stdDeviation="0.65745372"
+         id="feGaussianBlur7088" />
+    </filter>
+    <filter
+       x="-0.31129266"
+       width="1.6225853"
+       y="-0.31129266"
+       height="1.6225853"
+       id="filter7092">
+      <feGaussianBlur
+         stdDeviation="0.84722898"
+         id="feGaussianBlur7094" />
+    </filter>
+    <filter
+       x="-0.34690492"
+       width="1.6938098"
+       y="-0.34690492"
+       height="1.6938098"
+       id="filter7098">
+      <feGaussianBlur
+         stdDeviation="0.94415301"
+         id="feGaussianBlur7100" />
+    </filter>
+    <filter
+       x="-0.38568544"
+       width="1.7713709"
+       y="-0.38568544"
+       height="1.7713709"
+       id="filter7104">
+      <feGaussianBlur
+         stdDeviation="1.0496999"
+         id="feGaussianBlur7106" />
+    </filter>
+    <filter
+       x="-0.43894386"
+       width="1.8778877"
+       y="-0.43894386"
+       height="1.8778877"
+       id="filter7110">
+      <feGaussianBlur
+         stdDeviation="1.1946506"
+         id="feGaussianBlur7112" />
+    </filter>
+    <filter
+       x="-0.495835"
+       width="1.99167"
+       y="-0.495835"
+       height="1.99167"
+       id="filter7116">
+      <feGaussianBlur
+         stdDeviation="1.3494883"
+         id="feGaussianBlur7118" />
+    </filter>
+    <filter
+       x="-0.5121696"
+       width="2.0243392"
+       y="-0.5121696"
+       height="2.0243392"
+       id="filter7122">
+      <feGaussianBlur
+         stdDeviation="1.3939453"
+         id="feGaussianBlur7124" />
+    </filter>
+    <filter
+       x="-0.56884728"
+       width="2.1376946"
+       y="-0.56884728"
+       height="2.1376946"
+       id="filter7128">
+      <feGaussianBlur
+         stdDeviation="1.5482019"
+         id="feGaussianBlur7130" />
+    </filter>
+    <filter
+       x="-0.6379785"
+       width="2.275957"
+       y="-0.6379785"
+       height="2.275957"
+       id="filter7134">
+      <feGaussianBlur
+         stdDeviation="1.7363528"
+         id="feGaussianBlur7136" />
+    </filter>
+    <filter
+       x="-0.68678536"
+       width="2.3735707"
+       y="-0.68678536"
+       height="2.3735707"
+       id="filter7140">
+      <feGaussianBlur
+         stdDeviation="1.8691879"
+         id="feGaussianBlur7142" />
+    </filter>
+    <filter
+       x="-0.72018375"
+       width="2.4403675"
+       y="-0.72018375"
+       height="2.4403675"
+       id="filter7146">
+      <feGaussianBlur
+         stdDeviation="1.9600865"
+         id="feGaussianBlur7148" />
+    </filter>
+    <filter
+       id="filter7154">
+      <feGaussianBlur
+         stdDeviation="0.14639612"
+         id="feGaussianBlur7156" />
+    </filter>
+    <filter
+       id="filter7160">
+      <feGaussianBlur
+         stdDeviation="0.22992421"
+         id="feGaussianBlur7162" />
+    </filter>
+    <filter
+       x="-0.13258697"
+       width="1.2651739"
+       y="-0.13258697"
+       height="1.2651739"
+       id="filter7166">
+      <feGaussianBlur
+         stdDeviation="0.36085502"
+         id="feGaussianBlur7168" />
+    </filter>
+    <filter
+       x="-0.17472936"
+       width="1.3494587"
+       y="-0.17472936"
+       height="1.3494587"
+       id="filter7172">
+      <feGaussianBlur
+         stdDeviation="0.47555178"
+         id="feGaussianBlur7174" />
+    </filter>
+    <filter
+       x="-0.26382247"
+       width="1.5276449"
+       y="-0.26382247"
+       height="1.5276449"
+       id="filter7178">
+      <feGaussianBlur
+         stdDeviation="0.71803186"
+         id="feGaussianBlur7180" />
+    </filter>
+    <filter
+       x="-0.30015438"
+       width="1.6003088"
+       y="-0.30015438"
+       height="1.6003088"
+       id="filter7184">
+      <feGaussianBlur
+         stdDeviation="0.8169145"
+         id="feGaussianBlur7186" />
+    </filter>
+    <filter
+       x="-0.31587524"
+       width="1.6317505"
+       y="-0.31587524"
+       height="1.6317505"
+       id="filter7190">
+      <feGaussianBlur
+         stdDeviation="0.85970116"
+         id="feGaussianBlur7192" />
+    </filter>
+    <filter
+       x="-0.36437445"
+       width="1.7287489"
+       y="-0.36437445"
+       height="1.7287489"
+       id="filter7196">
+      <feGaussianBlur
+         stdDeviation="0.99169893"
+         id="feGaussianBlur7198" />
+    </filter>
+    <filter
+       x="-0.44884049"
+       width="1.897681"
+       y="-0.44884049"
+       height="1.897681"
+       id="filter7202">
+      <feGaussianBlur
+         stdDeviation="1.2215857"
+         id="feGaussianBlur7204" />
+    </filter>
+    <filter
+       x="-0.48894584"
+       width="1.9778917"
+       y="-0.48894584"
+       height="1.9778917"
+       id="filter7208">
+      <feGaussianBlur
+         stdDeviation="1.3307384"
+         id="feGaussianBlur7210" />
+    </filter>
+    <filter
+       x="-0.52802143"
+       width="2.0560429"
+       y="-0.52802143"
+       height="2.0560429"
+       id="filter7214">
+      <feGaussianBlur
+         stdDeviation="1.4370884"
+         id="feGaussianBlur7216" />
+    </filter>
+    <filter
+       x="-0.58778518"
+       width="2.1755704"
+       y="-0.58778518"
+       height="2.1755704"
+       id="filter7220">
+      <feGaussianBlur
+         stdDeviation="1.5997443"
+         id="feGaussianBlur7222" />
+    </filter>
+    <filter
+       x="-0.6197702"
+       width="2.2395404"
+       y="-0.6197702"
+       height="2.2395404"
+       id="filter7226">
+      <feGaussianBlur
+         stdDeviation="1.6867962"
+         id="feGaussianBlur7228" />
+    </filter>
+    <filter
+       x="-0.66538648"
+       width="2.330773"
+       y="-0.66538648"
+       height="2.330773"
+       id="filter7232">
+      <feGaussianBlur
+         stdDeviation="1.8109477"
+         id="feGaussianBlur7234" />
+    </filter>
+    <filter
+       x="-0.72134945"
+       width="2.4426989"
+       y="-0.72134945"
+       height="2.4426989"
+       id="filter7238">
+      <feGaussianBlur
+         stdDeviation="1.9632592"
+         id="feGaussianBlur7240" />
+    </filter>
+    <filter
+       id="filter7246">
+      <feGaussianBlur
+         stdDeviation="0.12013419"
+         id="feGaussianBlur7248" />
+    </filter>
+    <filter
+       id="filter7252">
+      <feGaussianBlur
+         stdDeviation="0.23799125"
+         id="feGaussianBlur7254" />
+    </filter>
+    <filter
+       x="-0.15228462"
+       width="1.3045692"
+       y="-0.15228462"
+       height="1.3045692"
+       id="filter7258">
+      <feGaussianBlur
+         stdDeviation="0.41446511"
+         id="feGaussianBlur7260" />
+    </filter>
+    <filter
+       x="-0.17834175"
+       width="1.3566835"
+       y="-0.17834175"
+       height="1.3566835"
+       id="filter7264">
+      <feGaussianBlur
+         stdDeviation="0.48538343"
+         id="feGaussianBlur7266" />
+    </filter>
+    <filter
+       x="-0.25800698"
+       width="1.516014"
+       y="-0.25800698"
+       height="1.516014"
+       id="filter7270">
+      <feGaussianBlur
+         stdDeviation="0.70220413"
+         id="feGaussianBlur7272" />
+    </filter>
+    <filter
+       x="-0.28247705"
+       width="1.5649541"
+       y="-0.28247705"
+       height="1.5649541"
+       id="filter7276">
+      <feGaussianBlur
+         stdDeviation="0.76880306"
+         id="feGaussianBlur7278" />
+    </filter>
+    <filter
+       x="-0.32085344"
+       width="1.6417069"
+       y="-0.32085344"
+       height="1.6417069"
+       id="filter7282">
+      <feGaussianBlur
+         stdDeviation="0.87325005"
+         id="feGaussianBlur7284" />
+    </filter>
+    <filter
+       x="-0.36242229"
+       width="1.7248446"
+       y="-0.36242229"
+       height="1.7248446"
+       id="filter7288">
+      <feGaussianBlur
+         stdDeviation="0.98638583"
+         id="feGaussianBlur7290" />
+    </filter>
+    <filter
+       x="-0.41116864"
+       width="1.8223373"
+       y="-0.41116864"
+       height="1.8223373"
+       id="filter7294">
+      <feGaussianBlur
+         stdDeviation="1.1190562"
+         id="feGaussianBlur7296" />
+    </filter>
+    <filter
+       x="-0.47396793"
+       width="1.9479359"
+       y="-0.47396793"
+       height="1.9479359"
+       id="filter7300">
+      <feGaussianBlur
+         stdDeviation="1.2899738"
+         id="feGaussianBlur7302" />
+    </filter>
+    <filter
+       x="-0.55093383"
+       width="2.1018677"
+       y="-0.55093383"
+       height="2.1018677"
+       id="filter7306">
+      <feGaussianBlur
+         stdDeviation="1.4994479"
+         id="feGaussianBlur7308" />
+    </filter>
+    <filter
+       x="-0.585909"
+       width="2.171818"
+       y="-0.585909"
+       height="2.171818"
+       id="filter7312">
+      <feGaussianBlur
+         stdDeviation="1.594638"
+         id="feGaussianBlur7314" />
+    </filter>
+    <filter
+       x="-0.64305777"
+       width="2.2861155"
+       y="-0.64305777"
+       height="2.2861155"
+       id="filter7318">
+      <feGaussianBlur
+         stdDeviation="1.7501768"
+         id="feGaussianBlur7320" />
+    </filter>
+    <filter
+       x="-0.67211517"
+       width="2.3442303"
+       y="-0.67211517"
+       height="2.3442303"
+       id="filter7324">
+      <feGaussianBlur
+         stdDeviation="1.8292608"
+         id="feGaussianBlur7326" />
+    </filter>
+    <filter
+       x="-0.69974219"
+       width="2.3994844"
+       y="-0.69974219"
+       height="2.3994844"
+       id="filter7330">
+      <feGaussianBlur
+         stdDeviation="1.9044518"
+         id="feGaussianBlur7332" />
+    </filter>
+    <filter
+       id="filter7338">
+      <feGaussianBlur
+         stdDeviation="0.078269889"
+         id="feGaussianBlur7340" />
+    </filter>
+    <filter
+       id="filter7344">
+      <feGaussianBlur
+         stdDeviation="0.21580285"
+         id="feGaussianBlur7346" />
+    </filter>
+    <filter
+       x="-0.15003761"
+       width="1.3000752"
+       y="-0.15003761"
+       height="1.3000752"
+       id="filter7350">
+      <feGaussianBlur
+         stdDeviation="0.40834953"
+         id="feGaussianBlur7352" />
+    </filter>
+    <filter
+       x="-0.1846199"
+       width="1.3692398"
+       y="-0.1846199"
+       height="1.3692398"
+       id="filter7356">
+      <feGaussianBlur
+         stdDeviation="0.50247035"
+         id="feGaussianBlur7358" />
+    </filter>
+    <filter
+       x="-0.23605978"
+       width="1.4721196"
+       y="-0.23605978"
+       height="1.4721196"
+       id="filter7362">
+      <feGaussianBlur
+         stdDeviation="0.64247157"
+         id="feGaussianBlur7364" />
+    </filter>
+    <filter
+       x="-0.29499853"
+       width="1.5899971"
+       y="-0.29499853"
+       height="1.5899971"
+       id="filter7368">
+      <feGaussianBlur
+         stdDeviation="0.80288211"
+         id="feGaussianBlur7370" />
+    </filter>
+    <filter
+       x="-0.35463518"
+       width="1.7092704"
+       y="-0.35463518"
+       height="1.7092704"
+       id="filter7374">
+      <feGaussianBlur
+         stdDeviation="0.96519207"
+         id="feGaussianBlur7376" />
+    </filter>
+    <filter
+       x="-0.3999415"
+       width="1.799883"
+       y="-0.3999415"
+       height="1.799883"
+       id="filter7380">
+      <feGaussianBlur
+         stdDeviation="1.0884999"
+         id="feGaussianBlur7382" />
+    </filter>
+    <filter
+       x="-0.44039729"
+       width="1.8807946"
+       y="-0.44039729"
+       height="1.8807946"
+       id="filter7386">
+      <feGaussianBlur
+         stdDeviation="1.1986063"
+         id="feGaussianBlur7388" />
+    </filter>
+    <filter
+       x="-0.49047727"
+       width="1.9809545"
+       y="-0.49047727"
+       height="1.9809545"
+       id="filter7392">
+      <feGaussianBlur
+         stdDeviation="1.3349064"
+         id="feGaussianBlur7394" />
+    </filter>
+    <filter
+       x="-0.5195796"
+       width="2.0391592"
+       y="-0.5195796"
+       height="2.0391592"
+       id="filter7398">
+      <feGaussianBlur
+         stdDeviation="1.4141127"
+         id="feGaussianBlur7400" />
+    </filter>
+    <filter
+       x="-0.57114803"
+       width="2.1422961"
+       y="-0.57114803"
+       height="2.1422961"
+       id="filter7404">
+      <feGaussianBlur
+         stdDeviation="1.5544638"
+         id="feGaussianBlur7406" />
+    </filter>
+    <filter
+       x="-0.62999173"
+       width="2.2599835"
+       y="-0.62999173"
+       height="2.2599835"
+       id="filter7410">
+      <feGaussianBlur
+         stdDeviation="1.7146156"
+         id="feGaussianBlur7412" />
+    </filter>
+    <filter
+       x="-0.66404376"
+       width="2.3280875"
+       y="-0.66404376"
+       height="2.3280875"
+       id="filter7416">
+      <feGaussianBlur
+         stdDeviation="1.8072933"
+         id="feGaussianBlur7418" />
+    </filter>
+    <filter
+       x="-0.71785688"
+       width="2.4357138"
+       y="-0.71785688"
+       height="2.4357138"
+       id="filter7422">
+      <feGaussianBlur
+         stdDeviation="1.9537536"
+         id="feGaussianBlur7424" />
+    </filter>
+    <inkscape:perspective
+       id="perspective4209"
+       inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
+       inkscape:vp_z="1 : 0.5 : 1"
+       inkscape:vp_y="0 : 1000 : 0"
+       inkscape:vp_x="0 : 0.5 : 1"
+       sodipodi:type="inkscape:persp3d" />
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient2382"
+       id="linearGradient2388"
+       x1="250.26767"
+       y1="3.1680942"
+       x2="250.26767"
+       y2="37.752678"
+       gradientUnits="userSpaceOnUse" />
+    <linearGradient
+       id="linearGradient2382">
+      <stop
+         style="stop-color:#ffffff;stop-opacity:1;"
+         offset="0"
+         id="stop2384" />
+      <stop
+         id="stop2390"
+         offset="0.25"
+         style="stop-color:#a4a4a4;stop-opacity:1;" />
+      <stop
+         style="stop-color:#404040;stop-opacity:1;"
+         offset="1"
+         id="stop2386" />
+    </linearGradient>
+  </defs>
+  <path
+     style="opacity:0.69999999999999996;fill:#ffffff;fill-opacity:0.5350877;fill-rule:nonzero;stroke:none;stroke-width:3;stroke-opacity:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+     d="m 484.25269,4.668094 c 6.648,0 12,5.352 12,12 l 0,7.584583 c 0,6.648 -5.352,12 -12,12 l -479.9700348,0 0,-31.584583 479.9700348,0 z"
+     id="rect2380"
+     sodipodi:nodetypes="ccccccc" />
+</svg>
diff --git a/data/themes/default/sing_score_text.svg b/data/themes/default/sing_score_text.svg
new file mode 100644 (file)
index 0000000..6495db4
--- /dev/null
@@ -0,0 +1,73 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://creativecommons.org/ns#"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   version="1.0"
+   width="800"
+   height="600"
+   id="svg3465"
+   sodipodi:version="0.32"
+   inkscape:version="0.46"
+   sodipodi:docname="sing_score_text.svg"
+   inkscape:output_extension="org.inkscape.output.svg.inkscape">
+  <metadata
+     id="metadata3075">
+    <rdf:RDF>
+      <cc:Work
+         rdf:about="">
+        <dc:format>image/svg+xml</dc:format>
+        <dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+      </cc:Work>
+    </rdf:RDF>
+  </metadata>
+  <sodipodi:namedview
+     inkscape:window-height="722"
+     inkscape:window-width="1248"
+     inkscape:pageshadow="2"
+     inkscape:pageopacity="0.0"
+     guidetolerance="10.0"
+     gridtolerance="10.0"
+     objecttolerance="10.0"
+     borderopacity="1.0"
+     bordercolor="#666666"
+     pagecolor="#ffffff"
+     id="base"
+     showgrid="false"
+     inkscape:zoom="0.67625"
+     inkscape:cx="400"
+     inkscape:cy="300"
+     inkscape:window-x="0"
+     inkscape:window-y="25"
+     inkscape:current-layer="svg3465" />
+  <defs
+     id="defs3467">
+    <inkscape:perspective
+       sodipodi:type="inkscape:persp3d"
+       inkscape:vp_x="0 : 300 : 1"
+       inkscape:vp_y="0 : 1000 : 0"
+       inkscape:vp_z="800 : 300 : 1"
+       inkscape:persp3d-origin="400 : 200 : 1"
+       id="perspective9" />
+  </defs>
+  <g
+     style="opacity:1;fill:#ffffff;fill-opacity:1;stroke:#000000;stroke-opacity:1;stroke-width:2;stroke-miterlimit:4;stroke-dasharray:none"
+     id="layer15">
+    <text
+       x="102.33772"
+       y="94.271713"
+       style="font-size:40px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;text-align:start;line-height:125%;writing-mode:lr-tb;text-anchor:start;fill:#ffffff;fill-opacity:1;stroke:#000000;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;display:inline;font-family:Droid Sans Mono;stroke-miterlimit:4;stroke-dasharray:none"
+       id="text10199"
+       xml:space="preserve"><tspan
+         x="102.33772"
+         y="94.271713"
+         style="fill:#ffffff;fill-opacity:1;stroke:#000000;stroke-opacity:1;stroke-width:2;stroke-miterlimit:4;stroke-dasharray:none"
+         id="tspan10201">0000</tspan></text>
+  </g>
+</svg>
diff --git a/data/themes/default/sing_timetxt.svg b/data/themes/default/sing_timetxt.svg
new file mode 100644 (file)
index 0000000..61c57a9
--- /dev/null
@@ -0,0 +1,71 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://creativecommons.org/ns#"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   version="1.0"
+   width="1000"
+   height="800"
+   id="svg3465"
+   sodipodi:version="0.32"
+   inkscape:version="0.46"
+   sodipodi:docname="sing_timetxt.svg"
+   inkscape:output_extension="org.inkscape.output.svg.inkscape">
+  <metadata
+     id="metadata3115">
+    <rdf:RDF>
+      <cc:Work
+         rdf:about="">
+        <dc:format>image/svg+xml</dc:format>
+        <dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+      </cc:Work>
+    </rdf:RDF>
+  </metadata>
+  <sodipodi:namedview
+     inkscape:window-height="801"
+     inkscape:window-width="1439"
+     inkscape:pageshadow="2"
+     inkscape:pageopacity="0.0"
+     guidetolerance="10.0"
+     gridtolerance="10.0"
+     objecttolerance="10.0"
+     borderopacity="1.0"
+     bordercolor="#666666"
+     pagecolor="#ffffff"
+     id="base"
+     showgrid="false"
+     inkscape:zoom="0.95636192"
+     inkscape:cx="394.87412"
+     inkscape:cy="477.44917"
+     inkscape:window-x="20"
+     inkscape:window-y="145"
+     inkscape:current-layer="svg3465" />
+  <defs
+     id="defs3467">
+    <inkscape:perspective
+       sodipodi:type="inkscape:persp3d"
+       inkscape:vp_x="0 : 300 : 1"
+       inkscape:vp_y="0 : 1000 : 0"
+       inkscape:vp_z="800 : 300 : 1"
+       inkscape:persp3d-origin="400 : 200 : 1"
+       id="perspective9" />
+  </defs>
+  <text
+     sodipodi:linespacing="125%"
+     xml:space="preserve"
+     id="timer_text"
+     style="font-size:18px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;text-align:start;line-height:125%;text-anchor:start;fill:#ffffff;fill-opacity:1;stroke:#000000;stroke-width:0.50000000000000000;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;display:inline;font-family:Droid Sans Mono"
+     y="21.253304"
+     x="400"><tspan
+       id="tspan4717"
+       y="24.737442"
+       x="400"
+       style="font-size:20px;text-align:start;text-anchor:start;fill:#ffffff;fill-opacity:1;stroke:#000000;stroke-width:0.50000000000000000;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1">00:00</tspan></text>
+<!--       style="font-size:25px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;text-align:start;line-height:125%;writing-mode:lr-tb;text-anchor:start;opacity:1;fill:black;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:0.56078384;display:inline;font-family:Droid Sans Mono"
+--></svg>
diff --git a/data/themes/default/sing_tostartfg.svg b/data/themes/default/sing_tostartfg.svg
new file mode 100644 (file)
index 0000000..05f0d54
--- /dev/null
@@ -0,0 +1,168 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://creativecommons.org/ns#"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   version="1.0"
+   width="800"
+   height="600"
+   id="svg3465"
+   sodipodi:version="0.32"
+   inkscape:version="0.46"
+   sodipodi:docname="sing_tostartfg.svg"
+   sodipodi:docbase="/home/yoda/UltraStar/sf/UltraStar-ng/themes/lima"
+   inkscape:output_extension="org.inkscape.output.svg.inkscape"
+   sodipodi:modified="true">
+  <metadata
+     id="metadata30">
+    <rdf:RDF>
+      <cc:Work
+         rdf:about="">
+        <dc:format>image/svg+xml</dc:format>
+        <dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+      </cc:Work>
+    </rdf:RDF>
+  </metadata>
+  <sodipodi:namedview
+     inkscape:cy="279.34391"
+     inkscape:cx="281.09948"
+     inkscape:zoom="0.86831672"
+     inkscape:window-height="785"
+     inkscape:window-width="1144"
+     inkscape:pageshadow="2"
+     inkscape:pageopacity="0.0"
+     guidetolerance="10.0"
+     gridtolerance="10.0"
+     objecttolerance="10.0"
+     borderopacity="1.0"
+     bordercolor="#666666"
+     pagecolor="#ffffff"
+     id="base"
+     inkscape:window-x="0"
+     inkscape:window-y="25"
+     inkscape:current-layer="svg3465"
+     showgrid="false" />
+  <defs
+     id="defs3467" />
+  <rect
+     style="opacity:1;color:black;fill:white;fill-opacity:0.39215686;fill-rule:nonzero;stroke:none;stroke-width:0.93757653;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:block;overflow:visible"
+     id="rect10068"
+     width="829.06262"
+     height="17.235523"
+     x="-21.343824"
+     y="-10.045292" />
+  <g
+     transform="matrix(-0.289276,1.079594,1.079594,0.289276,546.785,265.1065)"
+     id="g10054"
+     style="fill:white;fill-opacity:1;opacity:1;color:black;fill-rule:nonzero;stroke:white;stroke-width:1.52101099;stroke-linecap:round;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:block;overflow:visible">
+    <path
+       sodipodi:type="star"
+       style="opacity:0.22790701;color:black;fill:white;fill-opacity:1;fill-rule:nonzero;stroke:white;stroke-width:2.84342982;stroke-linecap:round;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:block;overflow:visible"
+       id="path10056"
+       sodipodi:sides="5"
+       sodipodi:cx="141.42136"
+       sodipodi:cy="350.13498"
+       sodipodi:r1="78.688225"
+       sodipodi:r2="45.665279"
+       sodipodi:arg1="1.0612041"
+       sodipodi:arg2="1.6895226"
+       inkscape:flatsided="false"
+       inkscape:rounded="0"
+       inkscape:randomized="0"
+       d="M 179.80715,418.82535 L 136.01242,395.47879 L 87.954791,407.86853 L 96.625376,359.00278 L 69.991407,317.1259 L 119.14486,310.27177 L 150.74179,272.0007 L 172.4497,316.63036 L 218.61165,334.85441 L 182.87443,369.29119 L 179.80715,418.82535 z "
+       transform="matrix(0.494335,-0.204386,0.204386,0.494335,90.19682,29.75748)" />
+    <path
+       transform="matrix(0.430025,1.278809e-2,-1.278809e-2,0.430025,134.5255,-35.15791)"
+       d="M 179.80715,418.82535 L 136.01242,395.47879 L 87.954791,407.86853 L 96.625376,359.00278 L 69.991407,317.1259 L 119.14486,310.27177 L 150.74179,272.0007 L 172.4497,316.63036 L 218.61165,334.85441 L 182.87443,369.29119 L 179.80715,418.82535 z "
+       inkscape:randomized="0"
+       inkscape:rounded="0"
+       inkscape:flatsided="false"
+       sodipodi:arg2="1.6895226"
+       sodipodi:arg1="1.0612041"
+       sodipodi:r2="45.665279"
+       sodipodi:r1="78.688225"
+       sodipodi:cy="350.13498"
+       sodipodi:cx="141.42136"
+       sodipodi:sides="5"
+       id="path10058"
+       style="opacity:0.22790701;color:black;fill:white;fill-opacity:1;fill-rule:nonzero;stroke:white;stroke-width:3.53546628;stroke-linecap:round;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:block;overflow:visible"
+       sodipodi:type="star" />
+    <path
+       sodipodi:type="star"
+       style="opacity:0.22790701;color:black;fill:white;fill-opacity:1;fill-rule:nonzero;stroke:white;stroke-width:4.39094525;stroke-linecap:round;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:block;overflow:visible"
+       id="path10060"
+       sodipodi:sides="5"
+       sodipodi:cx="141.42136"
+       sodipodi:cy="350.13498"
+       sodipodi:r1="78.688225"
+       sodipodi:r2="45.665279"
+       sodipodi:arg1="1.0612041"
+       sodipodi:arg2="1.6895226"
+       inkscape:flatsided="false"
+       inkscape:rounded="0"
+       inkscape:randomized="0"
+       d="M 179.80715,418.82535 L 136.01242,395.47879 L 87.954791,407.86853 L 96.625376,359.00278 L 69.991407,317.1259 L 119.14486,310.27177 L 150.74179,272.0007 L 172.4497,316.63036 L 218.61165,334.85441 L 182.87443,369.29119 L 179.80715,418.82535 z "
+       transform="matrix(0.308608,-0.157328,0.157328,0.308608,141.4555,-15.54061)" />
+    <path
+       transform="matrix(0.218514,5.453603e-2,-5.453603e-2,0.218514,186.3547,-54.97931)"
+       d="M 179.80715,418.82535 L 136.01242,395.47879 L 87.954791,407.86853 L 96.625376,359.00278 L 69.991407,317.1259 L 119.14486,310.27177 L 150.74179,272.0007 L 172.4497,316.63036 L 218.61165,334.85441 L 182.87443,369.29119 L 179.80715,418.82535 z "
+       inkscape:randomized="0"
+       inkscape:rounded="0"
+       inkscape:flatsided="false"
+       sodipodi:arg2="1.6895226"
+       sodipodi:arg1="1.0612041"
+       sodipodi:r2="45.665279"
+       sodipodi:r1="78.688225"
+       sodipodi:cy="350.13498"
+       sodipodi:cx="141.42136"
+       sodipodi:sides="5"
+       id="path10062"
+       style="opacity:0.22790701;color:black;fill:white;fill-opacity:1;fill-rule:nonzero;stroke:white;stroke-width:6.75354546;stroke-linecap:round;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:block;overflow:visible"
+       sodipodi:type="star" />
+    <path
+       sodipodi:type="star"
+       style="opacity:0.22790701;color:black;fill:white;fill-opacity:1;fill-rule:nonzero;stroke:white;stroke-width:9.25479653;stroke-linecap:round;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:block;overflow:visible"
+       id="path10064"
+       sodipodi:sides="5"
+       sodipodi:cx="141.42136"
+       sodipodi:cy="350.13498"
+       sodipodi:r1="78.688225"
+       sodipodi:r2="45.665279"
+       sodipodi:arg1="1.0612041"
+       sodipodi:arg2="1.6895226"
+       inkscape:flatsided="false"
+       inkscape:rounded="0"
+       inkscape:randomized="0"
+       d="M 179.80715,418.82535 L 136.01242,395.47879 L 87.954791,407.86853 L 96.625376,359.00278 L 69.991407,317.1259 L 119.14486,310.27177 L 150.74179,272.0007 L 172.4497,316.63036 L 218.61165,334.85441 L 182.87443,369.29119 L 179.80715,418.82535 z "
+       transform="matrix(0.164046,9.96525e-3,-9.96525e-3,0.164046,210.6113,-58.34981)" />
+    <path
+       transform="matrix(0.76534,5.189341e-2,-5.189341e-2,0.76534,85.64202,-32.57281)"
+       d="M 179.80715,418.82535 L 136.01242,395.47879 L 87.954791,407.86853 L 96.625376,359.00278 L 69.991407,317.1259 L 119.14486,310.27177 L 150.74179,272.0007 L 172.4497,316.63036 L 218.61165,334.85441 L 182.87443,369.29119 L 179.80715,418.82535 z "
+       inkscape:randomized="0"
+       inkscape:rounded="0"
+       inkscape:flatsided="false"
+       sodipodi:arg2="1.6895226"
+       sodipodi:arg1="1.0612041"
+       sodipodi:r2="45.665279"
+       sodipodi:r1="78.688225"
+       sodipodi:cy="350.13498"
+       sodipodi:cx="141.42136"
+       sodipodi:sides="5"
+       id="path10066"
+       style="opacity:0.22790701;color:black;fill:white;fill-opacity:1;fill-rule:nonzero;stroke:white;stroke-width:1.98281369;stroke-linecap:round;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:block;overflow:visible"
+       sodipodi:type="star" />
+  </g>
+  <rect
+     width="29.287586"
+     height="74.28759"
+     x="10.356207"
+     y="495.35623"
+     style="fill:#000000;fill-opacity:1;stroke:#ffffff;stroke-width:0.71241343;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;display:inline"
+     id="rect2246" />
+</svg>
diff --git a/data/themes/default/songs_bg.svg b/data/themes/default/songs_bg.svg
new file mode 100644 (file)
index 0000000..be56dcc
--- /dev/null
@@ -0,0 +1,155 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Sodipodi ("http://www.sodipodi.com/") -->
+
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://creativecommons.org/ns#"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:xlink="http://www.w3.org/1999/xlink"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   version="1.0"
+   x="0"
+   y="0"
+   width="1000"
+   height="800"
+   id="svg559"
+   sodipodi:version="0.32"
+   inkscape:version="0.48.3.1 r9886"
+   sodipodi:docname="songs_bg.svg"
+   inkscape:output_extension="org.inkscape.output.svg.inkscape">
+  <metadata
+     id="metadata35">
+    <rdf:RDF>
+      <cc:Work
+         rdf:about="">
+        <dc:format>image/svg+xml</dc:format>
+        <dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+      </cc:Work>
+    </rdf:RDF>
+  </metadata>
+  <sodipodi:namedview
+     inkscape:window-height="1053"
+     inkscape:window-width="1920"
+     inkscape:pageshadow="2"
+     inkscape:pageopacity="0.0"
+     guidetolerance="10.0"
+     gridtolerance="10.0"
+     objecttolerance="10.0"
+     borderopacity="1.0"
+     bordercolor="#666666"
+     pagecolor="#ffffff"
+     id="base"
+     inkscape:zoom="1.2304507"
+     inkscape:cx="573.70744"
+     inkscape:cy="517.1618"
+     inkscape:window-x="0"
+     inkscape:window-y="-1"
+     inkscape:current-layer="svg559"
+     showgrid="false"
+     inkscape:window-maximized="1" />
+  <defs
+     id="defs561">
+    <linearGradient
+       id="linearGradient3772">
+      <stop
+         style="stop-color:#000000;stop-opacity:1;"
+         offset="0"
+         id="stop3774" />
+      <stop
+         style="stop-color:#000000;stop-opacity:0;"
+         offset="1"
+         id="stop3776" />
+    </linearGradient>
+    <inkscape:perspective
+       sodipodi:type="inkscape:persp3d"
+       inkscape:vp_x="0 : 400 : 1"
+       inkscape:vp_y="0 : 1000 : 0"
+       inkscape:vp_z="1000 : 400 : 1"
+       inkscape:persp3d-origin="500 : 266.66667 : 1"
+       id="perspective62" />
+    <linearGradient
+       id="linearGradient6053">
+      <stop
+         style="stop-color:#000000;stop-opacity:1;"
+         offset="0"
+         id="stop6055" />
+      <stop
+         style="stop-color:#5f5f5f;stop-opacity:1;"
+         offset="1"
+         id="stop6057" />
+    </linearGradient>
+    <linearGradient
+       id="linearGradient6499">
+      <stop
+         id="stop6501"
+         offset="0"
+         style="stop-color:white;stop-opacity:1;" />
+      <stop
+         id="stop6503"
+         offset="1"
+         style="stop-color:white;stop-opacity:0;" />
+    </linearGradient>
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient6053"
+       id="linearGradient3242"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(3.0616996,0,0,3.9597975,-718.21316,1166.9898)"
+       x1="410.25833"
+       y1="-446.23236"
+       x2="410.25833"
+       y2="-496.73999" />
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient6499"
+       id="linearGradient3245"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(0.8327515,0,0,-0.6476426,-48.09403,12.672202)"
+       x1="311.95688"
+       y1="-116.67703"
+       x2="311.95688"
+       y2="-276.41519" />
+    <linearGradient
+       id="linearGradient3751">
+      <stop
+         id="stop3753"
+         offset="0"
+         style="stop-color:#ffffff;stop-opacity:1;" />
+      <stop
+         id="stop3755"
+         offset="1"
+         style="stop-color:#ffffff;stop-opacity:0;" />
+    </linearGradient>
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient3772"
+       id="linearGradient3778"
+       x1="254.3235"
+       y1="472.55856"
+       x2="889.60565"
+       y2="472.55856"
+       gradientUnits="userSpaceOnUse" />
+  </defs>
+  <text
+     xml:space="preserve"
+     style="font-size:24.89476013px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Goblin"
+     x="266.96185"
+     y="759.88806"
+     id="text2508"><tspan
+       sodipodi:role="line"
+       id="tspan2510"
+       x="266.96185"
+       y="759.88806" /></text>
+  <rect
+     style="opacity:0.81779659;fill:url(#linearGradient3778);fill-opacity:1;stroke:none"
+     id="rect3770"
+     width="898.04504"
+     height="61.114971"
+     x="-1.6254208"
+     y="420.46426"
+     ry="0" />
+</svg>
diff --git a/data/themes/default/songs_bg_default.svg b/data/themes/default/songs_bg_default.svg
new file mode 100644 (file)
index 0000000..fdc2600
--- /dev/null
@@ -0,0 +1,251 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Sodipodi ("http://www.sodipodi.com/") -->
+
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://creativecommons.org/ns#"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:xlink="http://www.w3.org/1999/xlink"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   version="1.0"
+   x="0"
+   y="0"
+   width="1000"
+   height="800"
+   id="svg559"
+   sodipodi:version="0.32"
+   inkscape:version="0.48.0 r9654"
+   sodipodi:docname="songs_bg_default.svg"
+   inkscape:output_extension="org.inkscape.output.svg.inkscape">
+  <metadata
+     id="metadata35">
+    <rdf:RDF>
+      <cc:Work
+         rdf:about="">
+        <dc:format>image/svg+xml</dc:format>
+        <dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+      </cc:Work>
+    </rdf:RDF>
+  </metadata>
+  <sodipodi:namedview
+     inkscape:window-height="992"
+     inkscape:window-width="1920"
+     inkscape:pageshadow="2"
+     inkscape:pageopacity="0.0"
+     guidetolerance="10.0"
+     gridtolerance="10.0"
+     objecttolerance="10.0"
+     borderopacity="1.0"
+     bordercolor="#666666"
+     pagecolor="#ffffff"
+     id="base"
+     inkscape:zoom="0.43503001"
+     inkscape:cx="-54.572096"
+     inkscape:cy="419.08372"
+     inkscape:window-x="0"
+     inkscape:window-y="29"
+     inkscape:current-layer="svg559"
+     showgrid="false"
+     showguides="true"
+     inkscape:guide-bbox="true"
+     inkscape:window-maximized="1" />
+  <defs
+     id="defs561">
+    <linearGradient
+       id="linearGradient4557">
+      <stop
+         style="stop-color:#ffffff;stop-opacity:1;"
+         offset="0"
+         id="stop4559" />
+      <stop
+         style="stop-color:#000000;stop-opacity:1;"
+         offset="1"
+         id="stop4561" />
+    </linearGradient>
+    <linearGradient
+       id="linearGradient3751">
+      <stop
+         id="stop3753"
+         offset="0"
+         style="stop-color:#ffffff;stop-opacity:1;" />
+      <stop
+         id="stop3755"
+         offset="1"
+         style="stop-color:#ffffff;stop-opacity:0;" />
+    </linearGradient>
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient3751"
+       id="linearGradient2518"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(0.9434139,0,0,0.9434139,62.279262,39.359798)"
+       x1="665.12128"
+       y1="684.16162"
+       x2="381.28015"
+       y2="449.80624" />
+    <linearGradient
+       id="linearGradient3945">
+      <stop
+         style="stop-color:#ffffff;stop-opacity:1;"
+         offset="0"
+         id="stop3947" />
+      <stop
+         style="stop-color:#ffffff;stop-opacity:0;"
+         offset="1"
+         id="stop3949" />
+    </linearGradient>
+    <inkscape:perspective
+       sodipodi:type="inkscape:persp3d"
+       inkscape:vp_x="0 : 400 : 1"
+       inkscape:vp_y="0 : 1000 : 0"
+       inkscape:vp_z="1000 : 400 : 1"
+       inkscape:persp3d-origin="500 : 266.66667 : 1"
+       id="perspective62" />
+    <linearGradient
+       id="linearGradient6053">
+      <stop
+         style="stop-color:#000000;stop-opacity:1;"
+         offset="0"
+         id="stop6055" />
+      <stop
+         style="stop-color:#5f5f5f;stop-opacity:1;"
+         offset="1"
+         id="stop6057" />
+    </linearGradient>
+    <linearGradient
+       id="linearGradient6499"
+       inkscape:collect="always">
+      <stop
+         id="stop6501"
+         offset="0"
+         style="stop-color:white;stop-opacity:1;" />
+      <stop
+         id="stop6503"
+         offset="1"
+         style="stop-color:white;stop-opacity:0;" />
+    </linearGradient>
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient6499"
+       id="linearGradient3245"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(0.8327515,0,0,-0.6476426,-48.09403,12.672202)"
+       x1="311.95688"
+       y1="-116.67703"
+       x2="311.95688"
+       y2="-276.41519" />
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient6499"
+       id="linearGradient4108"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(1.2483528,0,0,1.0242885,40.754503,32.226123)"
+       x1="44.868057"
+       y1="260.4765"
+       x2="358.07056"
+       y2="260.4765" />
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient6499"
+       id="linearGradient4121"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(1.2483528,0,0,1.0242885,40.754503,133.62899)"
+       x1="44.868057"
+       y1="260.4765"
+       x2="358.07056"
+       y2="260.4765" />
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient6499"
+       id="linearGradient4127"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(1.2483528,0,0,1.0242885,40.754503,340.11416)"
+       x1="44.868057"
+       y1="260.4765"
+       x2="358.07056"
+       y2="260.4765" />
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient6499"
+       id="linearGradient4133"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(1.2483528,0,0,1.0242885,426.06823,341.18482)"
+       x1="44.868057"
+       y1="260.4765"
+       x2="358.07056"
+       y2="260.4765" />
+    <radialGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient4557"
+       id="radialGradient4563"
+       cx="754.52362"
+       cy="248.26866"
+       fx="754.52362"
+       fy="248.26866"
+       r="648.54285"
+       gradientTransform="matrix(-0.6867835,-1.4236353,1.4876169,-0.7176493,903.38936,1551.3895)"
+       gradientUnits="userSpaceOnUse" />
+    <inkscape:perspective
+       id="perspective3691"
+       inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
+       inkscape:vp_z="1 : 0.5 : 1"
+       inkscape:vp_y="0 : 1000 : 0"
+       inkscape:vp_x="0 : 0.5 : 1"
+       sodipodi:type="inkscape:persp3d" />
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient3751"
+       id="linearGradient3986"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(0.9434139,0,0,0.9434139,44.209028,-124.00654)"
+       x1="665.12128"
+       y1="684.16162"
+       x2="381.28015"
+       y2="449.80624" />
+    <filter
+       inkscape:collect="always"
+       id="filter4599">
+      <feGaussianBlur
+         inkscape:collect="always"
+         stdDeviation="3.4283654"
+         id="feGaussianBlur4601" />
+    </filter>
+  </defs>
+  <rect
+     style="fill:#000000;fill-opacity:1"
+     id="rect2851"
+     width="1000"
+     height="800"
+     x="0"
+     y="0" />
+  <text
+     xml:space="preserve"
+     style="font-size:24.89476013px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Goblin"
+     x="266.96185"
+     y="759.88806"
+     id="text2508"><tspan
+       sodipodi:role="line"
+       id="tspan2510"
+       x="266.96185"
+       y="759.88806" /></text>
+  <g
+     id="g3989"
+     transform="matrix(0.65125866,0,0,0.65125866,222.97032,194.47551)"
+     style="filter:url(#filter4599);opacity:1">
+    <path
+       id="path1939"
+       d="m 776.35866,159.55735 -13.59856,0 -2.71967,6.79924 2.71967,7.47917 -1.35984,8.15909 -6.79918,-4.07955 -5.43934,-10.19886 -11.55882,-2.71971 -4.75942,-4.75946 -10.19888,-4.75948 -11.55869,-19.03788 0.67991,-8.83902 28.55686,-21.75758 13.59837,6.11931 2.03984,4.75948 0,5.4394 3.39959,4.75946 6.79928,2.03978 4.75943,-4.07955 0.67992,-4.75947 -2.03975,-4.07954 -4.07951,-2.03977 -2.71977,-3.39963 6.11936,-2.71969 -1.35984,-6.79925 0,-4.07956 -4.07951,-4.07954 -2.03985,-6.11931 -8.15902,-2.03977 -6.79928,-1.35986 -14.27847,10.19887 -36.03596,14.27842 -8.15911,8.15909 -6.11927,4.75947 -1.35994,10.87879 2.71977,5.4394 6.79928,18.35795 8.83894,16.99811 9.51895,12.23864 -14.9583,24.47729 -16.99814,36.71591 -10.19887,16.31818 -16.99806,21.07767 -0.67992,9.51895 -8.83903,8.15908 13.59847,12.23866 -3.3996,14.27839 1.35984,31.95646 6.11926,36.71592 6.11936,32.63638 6.79918,10.87879 9.51906,19.7178 14.9583,22.43751 4.0795,14.27837 4.0796,10.19888 -12.23871,16.99811 -21.75758,8.83902 -2.03976,6.7993 41.4754,-1.35985 -6.11926,10.87876 7.47911,6.79923 19.71782,2.03981 15.63831,-13.59852 5.43944,-19.03784 8.83893,-16.31821 10.8788,-9.51893 3.39959,-10.87882 -11.55861,-0.67991 7.4791,-7.47918 -14.9583,4.75948 10.87879,-10.8788 -8.15911,-2.03977 -6.11937,-7.47917 -10.19886,-21.07766 -23.79734,-19.71781 -4.75943,-1.35984 4.75943,-4.07955 -0.67992,-11.55872 4.75952,-10.19886 -4.0796,0.67992 7.47919,-12.91856 0,-12.91857 4.75944,-6.79924 0,-8.83902 10.19886,-13.5985 0.68002,-11.5587 -2.03985,-9.51895 4.75952,-10.87879 5.43935,-8.83902 0,-5.43939 6.11936,-0.67992 5.43935,-5.4394 4.75952,-13.59848 10.87878,-12.23865 12.91856,-4.75947 8.15901,6.79924 19.71792,6.11933 15.63821,8.15908 7.47911,9.51895 12.91854,1.35985 40.79558,17.67803 21.07757,7.47918 16.99814,12.91856 4.07961,-1.35986 0,-4.07954 -9.51896,-7.47916 18.35789,4.75946 2.03986,-3.39963 -4.0796,-4.07952 6.79928,0 0.67991,-4.07956 -12.23863,-2.7197 9.51886,-2.7197 0,-4.75947 -3.39959,-0.67991 -10.19887,0.67991 -8.15902,-3.39962 -5.43944,-2.71969 8.15911,-6.79925 2.03976,-4.75947 -1.35984,-3.39963 -7.4791,1.35986 -15.63841,8.15908 -2.03966,4.07955 -5.43944,-1.35984 -19.71783,-10.87879 -0.67991,-7.47917 -11.55871,-6.11933 -19.71782,-10.19887 -4.75944,3.39963 0.67993,-4.75947 -10.87879,-10.19887 -9.51896,-2.7197 -8.83903,-10.19886 -2.71966,-3.39963 8.83902,6.11933 -1.35983,-6.79926 6.79918,3.39963 -2.03976,-10.19887 9.51895,8.83903 -4.0795,-6.11932 9.51885,4.07953 -8.15902,-11.5587 6.11927,2.03977 -2.71967,-10.87879 4.75942,4.07954 -6.79918,-10.19887 6.79918,2.03977 -6.11926,-8.15908 8.15902,-0.67993 -8.83894,-5.4394 5.43935,-2.71968 -6.11926,-0.67994 8.15902,-7.47916 -7.47911,0.67992 0.67992,-4.75947 0.67991,-13.59848 -4.0795,9.51894 -4.75952,-13.5985 0.67991,10.8788 -2.71967,0.67992 -6.79928,0 -7.47919,-10.87879 -7.47911,0 -8.83904,-7.47917 -4.0796,4.07954 -10.19877,6.79926 z"
+       style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:#ffffff;stroke-width:0.67309087999999995px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+       inkscape:connector-curvature="0" />
+    <path
+       sodipodi:nodetypes="cssc"
+       id="path3759"
+       d="m 745.83064,91.72488 c -26.62135,-9.8399 -37.65223,26.15318 -32.15617,47.65699 6.43181,25.16505 8.4097,56.02071 -3.17298,78.7166 -8.29967,16.26295 -46.68286,22.35178 -46.1986,45.20859"
+       style="fill:none;stroke:#000000;stroke-width:1.60380363000000004;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+       inkscape:connector-curvature="0" />
+  </g>
+</svg>
diff --git a/data/themes/default/songs_bg_ground.svg b/data/themes/default/songs_bg_ground.svg
new file mode 100644 (file)
index 0000000..f7c2ec5
--- /dev/null
@@ -0,0 +1,264 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Sodipodi ("http://www.sodipodi.com/") -->
+
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://creativecommons.org/ns#"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:xlink="http://www.w3.org/1999/xlink"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   version="1.0"
+   x="0"
+   y="0"
+   width="1000"
+   height="800"
+   id="svg559"
+   sodipodi:version="0.32"
+   inkscape:version="0.48.4 r9939"
+   sodipodi:docname="songs_bg_ground.svg"
+   inkscape:output_extension="org.inkscape.output.svg.inkscape">
+  <metadata
+     id="metadata35">
+    <rdf:RDF>
+      <cc:Work
+         rdf:about="">
+        <dc:format>image/svg+xml</dc:format>
+        <dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+        <dc:title />
+      </cc:Work>
+    </rdf:RDF>
+  </metadata>
+  <sodipodi:namedview
+     inkscape:window-height="859"
+     inkscape:window-width="1537"
+     inkscape:pageshadow="2"
+     inkscape:pageopacity="0.0"
+     guidetolerance="10.0"
+     gridtolerance="10.0"
+     objecttolerance="10.0"
+     borderopacity="1.0"
+     bordercolor="#666666"
+     pagecolor="#ffffff"
+     id="base"
+     inkscape:zoom="0.87006002"
+     inkscape:cx="232.66006"
+     inkscape:cy="328.41019"
+     inkscape:window-x="225"
+     inkscape:window-y="127"
+     inkscape:current-layer="svg559"
+     showgrid="false"
+     showguides="true"
+     inkscape:guide-bbox="true"
+     inkscape:window-maximized="0" />
+  <defs
+     id="defs561">
+    <linearGradient
+       id="linearGradient4557">
+      <stop
+         style="stop-color:#ffffff;stop-opacity:1;"
+         offset="0"
+         id="stop4559" />
+      <stop
+         style="stop-color:#000000;stop-opacity:1;"
+         offset="1"
+         id="stop4561" />
+    </linearGradient>
+    <linearGradient
+       id="linearGradient3751">
+      <stop
+         id="stop3753"
+         offset="0"
+         style="stop-color:#ffffff;stop-opacity:1;" />
+      <stop
+         id="stop3755"
+         offset="1"
+         style="stop-color:#ffffff;stop-opacity:0;" />
+    </linearGradient>
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient3751"
+       id="linearGradient2518"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(0.9434139,0,0,0.9434139,62.279262,39.359798)"
+       x1="665.12128"
+       y1="684.16162"
+       x2="381.28015"
+       y2="449.80624" />
+    <linearGradient
+       id="linearGradient3945">
+      <stop
+         style="stop-color:#ffffff;stop-opacity:1;"
+         offset="0"
+         id="stop3947" />
+      <stop
+         style="stop-color:#ffffff;stop-opacity:0;"
+         offset="1"
+         id="stop3949" />
+    </linearGradient>
+    <inkscape:perspective
+       sodipodi:type="inkscape:persp3d"
+       inkscape:vp_x="0 : 400 : 1"
+       inkscape:vp_y="0 : 1000 : 0"
+       inkscape:vp_z="1000 : 400 : 1"
+       inkscape:persp3d-origin="500 : 266.66667 : 1"
+       id="perspective62" />
+    <linearGradient
+       id="linearGradient6053">
+      <stop
+         style="stop-color:#000000;stop-opacity:1;"
+         offset="0"
+         id="stop6055" />
+      <stop
+         style="stop-color:#5f5f5f;stop-opacity:1;"
+         offset="1"
+         id="stop6057" />
+    </linearGradient>
+    <linearGradient
+       id="linearGradient6499"
+       inkscape:collect="always">
+      <stop
+         id="stop6501"
+         offset="0"
+         style="stop-color:white;stop-opacity:1;" />
+      <stop
+         id="stop6503"
+         offset="1"
+         style="stop-color:white;stop-opacity:0;" />
+    </linearGradient>
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient6499"
+       id="linearGradient3245"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(0.8327515,0,0,-0.6476426,-48.09403,12.672202)"
+       x1="311.95688"
+       y1="-116.67703"
+       x2="311.95688"
+       y2="-276.41519" />
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient6499"
+       id="linearGradient4108"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(1.2483528,0,0,1.0242885,40.754503,32.226123)"
+       x1="44.868057"
+       y1="260.4765"
+       x2="358.07056"
+       y2="260.4765" />
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient6499"
+       id="linearGradient4121"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(1.2483528,0,0,1.0242885,40.754503,133.62899)"
+       x1="44.868057"
+       y1="260.4765"
+       x2="358.07056"
+       y2="260.4765" />
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient6499"
+       id="linearGradient4127"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(1.2483528,0,0,1.0242885,40.754503,340.11416)"
+       x1="44.868057"
+       y1="260.4765"
+       x2="358.07056"
+       y2="260.4765" />
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient6499"
+       id="linearGradient4133"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(1.2483528,0,0,1.0242885,426.06823,341.18482)"
+       x1="44.868057"
+       y1="260.4765"
+       x2="358.07056"
+       y2="260.4765" />
+    <radialGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient4557"
+       id="radialGradient4563"
+       cx="754.52362"
+       cy="248.26866"
+       fx="754.52362"
+       fy="248.26866"
+       r="648.54285"
+       gradientTransform="matrix(-0.6867835,-1.4236353,1.4876169,-0.7176493,903.38936,1551.3895)"
+       gradientUnits="userSpaceOnUse" />
+    <inkscape:perspective
+       id="perspective3691"
+       inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
+       inkscape:vp_z="1 : 0.5 : 1"
+       inkscape:vp_y="0 : 1000 : 0"
+       inkscape:vp_x="0 : 0.5 : 1"
+       sodipodi:type="inkscape:persp3d" />
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient3751"
+       id="linearGradient3986"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(0.9434139,0,0,0.9434139,44.209028,-124.00654)"
+       x1="665.12128"
+       y1="684.16162"
+       x2="381.28015"
+       y2="449.80624" />
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient6053-8"
+       id="linearGradient3242"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(3.0616996,0,0,3.9597975,-718.21316,1166.9898)"
+       x1="410.25833"
+       y1="-446.23236"
+       x2="410.25833"
+       y2="-496.73999" />
+    <linearGradient
+       id="linearGradient6053-8">
+      <stop
+         style="stop-color:#000000;stop-opacity:0;"
+         offset="0"
+         id="stop6055-7" />
+      <stop
+         id="stop3782"
+         offset="0.20999999"
+         style="stop-color:#242424;stop-opacity:1;" />
+      <stop
+         style="stop-color:#5f5f5f;stop-opacity:1;"
+         offset="1"
+         id="stop6057-9" />
+    </linearGradient>
+    <linearGradient
+       y2="-496.73999"
+       x2="410.25833"
+       y1="-446.23236"
+       x1="410.25833"
+       gradientTransform="matrix(3.0616996,0,0,4.7562535,-718.21316,1562.6214)"
+       gradientUnits="userSpaceOnUse"
+       id="linearGradient4031"
+       xlink:href="#linearGradient6053-8"
+       inkscape:collect="always" />
+  </defs>
+  <text
+     xml:space="preserve"
+     style="font-size:24.89476013px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Goblin"
+     x="266.96185"
+     y="759.88806"
+     id="text2508"><tspan
+       sodipodi:role="line"
+       id="tspan2510"
+       x="266.96185"
+       y="759.88806" /></text>
+  <rect
+     y="-800"
+     x="0"
+     height="240.22711"
+     width="1000"
+     id="rect6051"
+     style="fill:url(#linearGradient4031);fill-opacity:1"
+     transform="scale(1,-1)" />
+</svg>
diff --git a/data/themes/default/songs_has_hiscore.svg b/data/themes/default/songs_has_hiscore.svg
new file mode 100644 (file)
index 0000000..17b2465
--- /dev/null
@@ -0,0 +1,72 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Sodipodi ("http://www.sodipodi.com/") -->
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://creativecommons.org/ns#"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   version="1.0"
+   x="0"
+   y="0"
+   width="800.000000"
+   height="600.000000"
+   id="svg559"
+   sodipodi:version="0.32"
+   inkscape:version="0.46"
+   sodipodi:docname="songs_hiscore.svg"
+   sodipodi:docbase="/home/yoda/UltraStar/sf/UltraStar-ng/themes/default"
+   inkscape:output_extension="org.inkscape.output.svg.inkscape">
+  <metadata
+     id="metadata35">
+    <rdf:RDF>
+      <cc:Work
+         rdf:about="">
+        <dc:format>image/svg+xml</dc:format>
+        <dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+      </cc:Work>
+    </rdf:RDF>
+  </metadata>
+  <sodipodi:namedview
+     inkscape:window-height="797"
+     inkscape:window-width="1081"
+     inkscape:pageshadow="2"
+     inkscape:pageopacity="0.0"
+     guidetolerance="10.0"
+     gridtolerance="10.0"
+     objecttolerance="10.0"
+     borderopacity="1.0"
+     bordercolor="#666666"
+     pagecolor="#ffffff"
+     id="base"
+     inkscape:zoom="0.89095454"
+     inkscape:cx="141.39663"
+     inkscape:cy="249.62029"
+     inkscape:window-x="235"
+     inkscape:window-y="25"
+     inkscape:current-layer="svg559"
+     showgrid="false" />
+  <defs
+     id="defs561">
+    <inkscape:perspective
+       sodipodi:type="inkscape:persp3d"
+       inkscape:vp_x="0 : 300 : 1"
+       inkscape:vp_y="0 : 1000 : 0"
+       inkscape:vp_z="800 : 300 : 1"
+       inkscape:persp3d-origin="400 : 200 : 1"
+       id="perspective8" />
+  </defs>
+  <text
+     xml:space="preserve"
+     style="font-size:18px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;text-align:center;text-anchor:middle;fill:#ffffff;fill-opacity:1;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Goblin;-inkscape-font-specification:Goblin Bold"
+     x="400"
+     y="240.31577"
+     id="text1990"><tspan
+       sodipodi:role="line"
+       id="tspan1992"
+       x="400"
+       y="332.31577">Hiscore</tspan></text>
+</svg>
diff --git a/data/themes/default/songs_hiscores.svg b/data/themes/default/songs_hiscores.svg
new file mode 100644 (file)
index 0000000..22f7ab3
--- /dev/null
@@ -0,0 +1,82 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Sodipodi ("http://www.sodipodi.com/") -->
+
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://creativecommons.org/ns#"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   version="1.0"
+   x="0"
+   y="0"
+   width="800.000000"
+   height="600.000000"
+   id="svg559"
+   sodipodi:version="0.32"
+   inkscape:version="0.48.4 r9939"
+   sodipodi:docname="songs_hiscores.svg"
+   inkscape:output_extension="org.inkscape.output.svg.inkscape">
+  <metadata
+     id="metadata35">
+    <rdf:RDF>
+      <cc:Work
+         rdf:about="">
+        <dc:format>image/svg+xml</dc:format>
+        <dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+        <dc:title />
+      </cc:Work>
+    </rdf:RDF>
+  </metadata>
+  <sodipodi:namedview
+     inkscape:window-height="1145"
+     inkscape:window-width="1920"
+     inkscape:pageshadow="2"
+     inkscape:pageopacity="0.0"
+     guidetolerance="10.0"
+     gridtolerance="10.0"
+     objecttolerance="10.0"
+     borderopacity="1.0"
+     bordercolor="#666666"
+     pagecolor="#ffffff"
+     id="base"
+     inkscape:zoom="0.89095454"
+     inkscape:cx="188.14938"
+     inkscape:cy="292.77184"
+     inkscape:window-x="0"
+     inkscape:window-y="27"
+     inkscape:current-layer="svg559"
+     showgrid="false"
+     inkscape:window-maximized="1" />
+  <defs
+     id="defs561">
+    <inkscape:perspective
+       sodipodi:type="inkscape:persp3d"
+       inkscape:vp_x="0 : 300 : 1"
+       inkscape:vp_y="0 : 1000 : 0"
+       inkscape:vp_z="800 : 300 : 1"
+       inkscape:persp3d-origin="400 : 200 : 1"
+       id="perspective8" />
+    <inkscape:perspective
+       id="perspective2864"
+       inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
+       inkscape:vp_z="1 : 0.5 : 1"
+       inkscape:vp_y="0 : 1000 : 0"
+       inkscape:vp_x="0 : 0.5 : 1"
+       sodipodi:type="inkscape:persp3d" />
+  </defs>
+  <text
+     xml:space="preserve"
+     style="font-size:10px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;text-align:start;text-anchor:start;fill:#ffffff;fill-opacity:1;stroke:#000000;stroke-width:0.797997px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Goblin;-inkscape-font-specification:Goblin Bold"
+     x="476.60596"
+     y="260.27982"
+     id="text1990"><tspan
+       sodipodi:role="line"
+       id="tspan1992"
+       x="476.60596"
+       y="260.27982"
+       style="font-size:10px;text-align:start;text-anchor:start;stroke-width:0.797997">hiscores</tspan></text>
+</svg>
diff --git a/data/themes/default/songs_order.svg b/data/themes/default/songs_order.svg
new file mode 100644 (file)
index 0000000..16d0e80
--- /dev/null
@@ -0,0 +1,73 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Sodipodi ("http://www.sodipodi.com/") -->
+
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://creativecommons.org/ns#"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   version="1.0"
+   x="0"
+   y="0"
+   width="800.000000"
+   height="600.000000"
+   id="svg559"
+   sodipodi:version="0.32"
+   inkscape:version="0.48.4 r9939"
+   sodipodi:docname="songs_order.svg"
+   inkscape:output_extension="org.inkscape.output.svg.inkscape">
+  <metadata
+     id="metadata35">
+    <rdf:RDF>
+      <cc:Work
+         rdf:about="">
+        <dc:format>image/svg+xml</dc:format>
+        <dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+      </cc:Work>
+    </rdf:RDF>
+  </metadata>
+  <sodipodi:namedview
+     inkscape:window-height="776"
+     inkscape:window-width="1280"
+     inkscape:pageshadow="2"
+     inkscape:pageopacity="0.0"
+     guidetolerance="10.0"
+     gridtolerance="10.0"
+     objecttolerance="10.0"
+     borderopacity="1.0"
+     bordercolor="#666666"
+     pagecolor="#ffffff"
+     id="base"
+     inkscape:zoom="0.89095454"
+     inkscape:cx="436.75329"
+     inkscape:cy="249.62029"
+     inkscape:window-x="0"
+     inkscape:window-y="24"
+     inkscape:current-layer="svg559"
+     showgrid="false"
+     inkscape:window-maximized="1" />
+  <defs
+     id="defs561">
+    <inkscape:perspective
+       sodipodi:type="inkscape:persp3d"
+       inkscape:vp_x="0 : 300 : 1"
+       inkscape:vp_y="0 : 1000 : 0"
+       inkscape:vp_z="800 : 300 : 1"
+       inkscape:persp3d-origin="400 : 200 : 1"
+       id="perspective8" />
+  </defs>
+  <text
+     xml:space="preserve"
+     style="font-size:16px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;text-align:center;text-anchor:middle;fill:#ffffff;fill-opacity:1;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Goblin,sans-serif;-inkscape-font-specification:Goblin Bold"
+     x="420.20306"
+     y="508.53128"
+     id="text1990"><tspan
+       sodipodi:role="line"
+       id="tspan1992"
+       x="420.20306"
+       y="508.53128">Order by</tspan></text>
+</svg>
diff --git a/data/themes/default/songs_song.svg b/data/themes/default/songs_song.svg
new file mode 100644 (file)
index 0000000..17a24d6
--- /dev/null
@@ -0,0 +1,79 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Sodipodi ("http://www.sodipodi.com/") -->
+
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://creativecommons.org/ns#"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   version="1.0"
+   x="0"
+   y="0"
+   width="800.000000"
+   height="600.000000"
+   id="svg559"
+   sodipodi:version="0.32"
+   inkscape:version="0.48.3.1 r9886"
+   sodipodi:docname="songs_song.svg"
+   inkscape:output_extension="org.inkscape.output.svg.inkscape">
+  <metadata
+     id="metadata35">
+    <rdf:RDF>
+      <cc:Work
+         rdf:about="">
+        <dc:format>image/svg+xml</dc:format>
+        <dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+      </cc:Work>
+    </rdf:RDF>
+  </metadata>
+  <sodipodi:namedview
+     inkscape:window-height="1053"
+     inkscape:window-width="1920"
+     inkscape:pageshadow="2"
+     inkscape:pageopacity="0.0"
+     guidetolerance="10.0"
+     gridtolerance="10.0"
+     objecttolerance="10.0"
+     borderopacity="1.0"
+     bordercolor="#666666"
+     pagecolor="#ffffff"
+     id="base"
+     inkscape:zoom="1.26"
+     inkscape:cx="335.39093"
+     inkscape:cy="318.08787"
+     inkscape:window-x="0"
+     inkscape:window-y="-1"
+     inkscape:current-layer="svg559"
+     showgrid="false"
+     inkscape:window-maximized="1" />
+  <defs
+     id="defs561">
+    <inkscape:perspective
+       sodipodi:type="inkscape:persp3d"
+       inkscape:vp_x="0 : 300 : 1"
+       inkscape:vp_y="0 : 1000 : 0"
+       inkscape:vp_z="800 : 300 : 1"
+       inkscape:persp3d-origin="400 : 200 : 1"
+       id="perspective8" />
+  </defs>
+  <text
+     xml:space="preserve"
+     style="font-size:24px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;text-align:start;text-anchor:start;fill:#aaddff;fill-opacity:1;stroke:none;font-family:NewRocker,Goblin"
+     x="25.426828"
+     y="342.27066"
+     id="text1990"><tspan
+       sodipodi:role="line"
+       x="25.426828"
+       y="342.27066"
+       id="tspan3151"
+       style="font-size:32px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;fill:#aaddff;fill-opacity:1;stroke:none;font-family:NewRocker,Goblin">Artist - Song</tspan><tspan
+       sodipodi:role="line"
+       x="25.426828"
+       y="382.27066"
+       id="tspan3155"
+       style="font-size:32px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;fill:#aaddff;fill-opacity:1;stroke:none;font-family:NewRocker,Goblin" /></text>
+</svg>
diff --git a/data/themes/default/star.svg b/data/themes/default/star.svg
new file mode 100644 (file)
index 0000000..3465490
--- /dev/null
@@ -0,0 +1,187 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://creativecommons.org/ns#"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:xlink="http://www.w3.org/1999/xlink"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   width="64"
+   height="64"
+   id="svg2463"
+   sodipodi:version="0.32"
+   inkscape:version="0.47 r22583"
+   version="1.0"
+   sodipodi:docname="star.svg"
+   inkscape:output_extension="org.inkscape.output.svg.inkscape">
+  <defs
+     id="defs2465">
+    <linearGradient
+       id="linearGradient3596">
+      <stop
+         style="stop-color:#ffffff;stop-opacity:1;"
+         offset="0"
+         id="stop3598" />
+      <stop
+         id="stop3604"
+         offset="0.35157821"
+         style="stop-color:#ffffff;stop-opacity:0.82681566;" />
+      <stop
+         style="stop-color:#ffffff;stop-opacity:1;"
+         offset="1"
+         id="stop3600" />
+    </linearGradient>
+    <linearGradient
+       id="linearGradient3262">
+      <stop
+         style="stop-color:#f5f5f5;stop-opacity:0.22680412;"
+         offset="0"
+         id="stop3264" />
+      <stop
+         style="stop-color:#f5f5f5;stop-opacity:0.96078432;"
+         offset="1"
+         id="stop3266" />
+    </linearGradient>
+    <linearGradient
+       id="linearGradient3751"
+       inkscape:collect="always">
+      <stop
+         id="stop3753"
+         offset="0"
+         style="stop-color:black;stop-opacity:1;" />
+      <stop
+         id="stop3755"
+         offset="1"
+         style="stop-color:black;stop-opacity:0;" />
+    </linearGradient>
+    <inkscape:perspective
+       sodipodi:type="inkscape:persp3d"
+       inkscape:vp_x="0 : 526.18109 : 1"
+       inkscape:vp_y="0 : 1000 : 0"
+       inkscape:vp_z="744.09448 : 526.18109 : 1"
+       inkscape:persp3d-origin="372.04724 : 350.78739 : 1"
+       id="perspective2471" />
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient3751"
+       id="linearGradient3272"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(0.3868046,0,0,0.3868046,40.335717,481.59837)"
+       x1="665.12128"
+       y1="684.16162"
+       x2="381.28015"
+       y2="449.80624" />
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient3751"
+       id="linearGradient2406"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(0.3868046,0,0,0.3868046,43.114888,485.8841)"
+       x1="665.12128"
+       y1="684.16162"
+       x2="381.28015"
+       y2="449.80624" />
+    <radialGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient3596"
+       id="radialGradient3602"
+       cx="31.851444"
+       cy="31.795218"
+       fx="31.851444"
+       fy="31.795218"
+       r="30.551558"
+       gradientTransform="matrix(1,0,0,0.95456924,0,1.3128087)"
+       gradientUnits="userSpaceOnUse" />
+    <filter
+       id="filter3086"
+       inkscape:label="Drop shadow"
+       width="1.5"
+       height="1.5"
+       x="-.25"
+       y="-.25">
+      <feGaussianBlur
+         id="feGaussianBlur3088"
+         in="SourceAlpha"
+         stdDeviation="4,000000"
+         result="blur" />
+      <feColorMatrix
+         id="feColorMatrix3090"
+         result="bluralpha"
+         type="matrix"
+         values="-1 0 0 0 1 0 -1 0 0 1 0 0 -1 0 1 0 0 0 0,500000 0 " />
+      <feOffset
+         id="feOffset3092"
+         in="bluralpha"
+         dx="0,000000"
+         dy="0,000000"
+         result="offsetBlur" />
+      <feMerge
+         id="feMerge3094">
+        <feMergeNode
+           id="feMergeNode3096"
+           in="offsetBlur" />
+        <feMergeNode
+           id="feMergeNode3098"
+           in="SourceGraphic" />
+      </feMerge>
+    </filter>
+  </defs>
+  <sodipodi:namedview
+     id="base"
+     pagecolor="#f5f5f5"
+     bordercolor="#666666"
+     borderopacity="1.0"
+     gridtolerance="10000"
+     guidetolerance="10"
+     objecttolerance="10"
+     inkscape:pageopacity="0"
+     inkscape:pageshadow="2"
+     inkscape:zoom="5.6"
+     inkscape:cx="26.939127"
+     inkscape:cy="39.646263"
+     inkscape:document-units="px"
+     inkscape:current-layer="layer1"
+     showgrid="false"
+     inkscape:window-width="1440"
+     inkscape:window-height="854"
+     inkscape:window-x="0"
+     inkscape:window-y="0"
+     inkscape:window-maximized="1" />
+  <metadata
+     id="metadata2468">
+    <rdf:RDF>
+      <cc:Work
+         rdf:about="">
+        <dc:format>image/svg+xml</dc:format>
+        <dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+      </cc:Work>
+    </rdf:RDF>
+  </metadata>
+  <g
+     inkscape:label="Layer 1"
+     inkscape:groupmode="layer"
+     id="layer1"
+     transform="translate(-110.35967,-771.51188)">
+    <path
+       sodipodi:type="star"
+       style="fill:url(#radialGradient3602);fill-opacity:1;fill-rule:nonzero;stroke:none;filter:url(#filter3086)"
+       id="path2822"
+       sodipodi:sides="5"
+       sodipodi:cx="31.964287"
+       sodipodi:cy="31.857143"
+       sodipodi:r1="32.125885"
+       sodipodi:r2="4.8188829"
+       sodipodi:arg1="0.93111088"
+       sodipodi:arg2="1.5577518"
+       inkscape:flatsided="false"
+       inkscape:rounded="0"
+       inkscape:randomized="0"
+       d="M 51.141613,57.631213 32.027145,36.675616 13.377809,58.06049 27.401071,33.405915 1.2998864,22.277632 29.081206,27.995864 31.599122,-0.26666619 34.745661,27.92197 62.403003,21.583048 36.566351,33.286352 51.141613,57.631213 z"
+       transform="matrix(1.0474097,0,0,1.0972591,108.99816,771.80448)" />
+  </g>
+</svg>
diff --git a/data/themes/default/star_glow.svg b/data/themes/default/star_glow.svg
new file mode 100644 (file)
index 0000000..be078b4
--- /dev/null
@@ -0,0 +1,209 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://creativecommons.org/ns#"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:xlink="http://www.w3.org/1999/xlink"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   width="64"
+   height="64"
+   id="svg2463"
+   sodipodi:version="0.32"
+   inkscape:version="0.47 r22583"
+   version="1.0"
+   sodipodi:docname="star_glow.svg"
+   inkscape:output_extension="org.inkscape.output.svg.inkscape">
+  <defs
+     id="defs2465">
+    <linearGradient
+       id="linearGradient3596">
+      <stop
+         style="stop-color:#ffffff;stop-opacity:1;"
+         offset="0"
+         id="stop3598" />
+      <stop
+         id="stop3604"
+         offset="0.35157821"
+         style="stop-color:#ffffff;stop-opacity:0.82681566;" />
+      <stop
+         style="stop-color:#ffffff;stop-opacity:1;"
+         offset="1"
+         id="stop3600" />
+    </linearGradient>
+    <linearGradient
+       id="linearGradient3262">
+      <stop
+         style="stop-color:#f5f5f5;stop-opacity:0.22680412;"
+         offset="0"
+         id="stop3264" />
+      <stop
+         style="stop-color:#f5f5f5;stop-opacity:0.96078432;"
+         offset="1"
+         id="stop3266" />
+    </linearGradient>
+    <linearGradient
+       id="linearGradient3751"
+       inkscape:collect="always">
+      <stop
+         id="stop3753"
+         offset="0"
+         style="stop-color:black;stop-opacity:1;" />
+      <stop
+         id="stop3755"
+         offset="1"
+         style="stop-color:black;stop-opacity:0;" />
+    </linearGradient>
+    <inkscape:perspective
+       sodipodi:type="inkscape:persp3d"
+       inkscape:vp_x="0 : 526.18109 : 1"
+       inkscape:vp_y="0 : 1000 : 0"
+       inkscape:vp_z="744.09448 : 526.18109 : 1"
+       inkscape:persp3d-origin="372.04724 : 350.78739 : 1"
+       id="perspective2471" />
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient3751"
+       id="linearGradient3272"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(0.3868046,0,0,0.3868046,40.335717,481.59837)"
+       x1="665.12128"
+       y1="684.16162"
+       x2="381.28015"
+       y2="449.80624" />
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient3751"
+       id="linearGradient2406"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(0.3868046,0,0,0.3868046,43.114888,485.8841)"
+       x1="665.12128"
+       y1="684.16162"
+       x2="381.28015"
+       y2="449.80624" />
+    <filter
+       id="filter3086"
+       inkscape:label="Noisy blur"
+       width="1.5"
+       height="1.5"
+       x="-0.25"
+       y="-0.25"
+       inkscape:menu="Blurs"
+       inkscape:menu-tooltip="Small-scale roughening and blurring to edges and content"
+       color-interpolation-filters="sRGB">
+      <feGaussianBlur
+         id="feGaussianBlur3088"
+         in="SourceAlpha"
+         stdDeviation="4,000000"
+         result="blur" />
+      <feColorMatrix
+         id="feColorMatrix3090"
+         result="bluralpha"
+         type="matrix"
+         values="-1 0 0 0 1 0 -1 0 0 1 0 0 -1 0 1 0 0 0 0,500000 0 " />
+      <feOffset
+         id="feOffset3092"
+         in="bluralpha"
+         dx="0,000000"
+         dy="0,000000"
+         result="offsetBlur" />
+      <feMerge
+         id="feMerge3094"
+         result="fbSourceGraphic">
+        <feMergeNode
+           id="feMergeNode3096"
+           in="offsetBlur" />
+        <feMergeNode
+           id="feMergeNode3098"
+           in="SourceGraphic" />
+      </feMerge>
+      <feColorMatrix
+         result="fbSourceGraphicAlpha"
+         in="fbSourceGraphic"
+         values="0 0 0 -1 0 0 0 0 -1 0 0 0 0 -1 0 0 0 0 1 0"
+         id="feColorMatrix2833" />
+      <feGaussianBlur
+         id="feGaussianBlur2835"
+         stdDeviation="5"
+         result="result1"
+         in="fbSourceGraphic" />
+      <feTurbulence
+         id="feTurbulence2837"
+         numOctaves="1"
+         seed="0"
+         type="fractalNoise"
+         baseFrequency="0.1"
+         result="result2" />
+      <feDisplacementMap
+         id="feDisplacementMap2839"
+         in2="result2"
+         scale="5"
+         yChannelSelector="G"
+         xChannelSelector="R"
+         result="result3"
+         in="result1" />
+      <feComposite
+         id="feComposite2841"
+         in2="result3"
+         operator="atop" />
+    </filter>
+  </defs>
+  <sodipodi:namedview
+     id="base"
+     pagecolor="#f5f5f5"
+     bordercolor="#666666"
+     borderopacity="1.0"
+     gridtolerance="10000"
+     guidetolerance="10"
+     objecttolerance="10"
+     inkscape:pageopacity="0"
+     inkscape:pageshadow="2"
+     inkscape:zoom="5.6"
+     inkscape:cx="26.939127"
+     inkscape:cy="25.003406"
+     inkscape:document-units="px"
+     inkscape:current-layer="layer1"
+     showgrid="false"
+     inkscape:window-width="1440"
+     inkscape:window-height="852"
+     inkscape:window-x="0"
+     inkscape:window-y="0"
+     inkscape:window-maximized="1" />
+  <metadata
+     id="metadata2468">
+    <rdf:RDF>
+      <cc:Work
+         rdf:about="">
+        <dc:format>image/svg+xml</dc:format>
+        <dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+      </cc:Work>
+    </rdf:RDF>
+  </metadata>
+  <g
+     inkscape:label="Layer 1"
+     inkscape:groupmode="layer"
+     id="layer1"
+     transform="translate(-110.35967,-771.51188)">
+    <path
+       sodipodi:type="star"
+       style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;filter:url(#filter3086)"
+       id="path2822"
+       sodipodi:sides="5"
+       sodipodi:cx="31.964287"
+       sodipodi:cy="31.857143"
+       sodipodi:r1="32.125885"
+       sodipodi:r2="20.280416"
+       sodipodi:arg1="0.93111088"
+       sodipodi:arg2="1.55929"
+       inkscape:flatsided="false"
+       inkscape:rounded="0"
+       inkscape:randomized="0"
+       d="M 51.141613,57.631213 32.197635,52.136217 13.377809,58.06049 12.74985,38.345649 1.2998864,22.277632 19.855764,15.588186 31.599122,-0.26666619 43.695245,15.313869 62.403003,21.583048 51.322941,37.901795 51.141613,57.631213 z"
+       transform="matrix(1.0474097,0,0,1.0972591,108.99816,771.80448)" />
+  </g>
+</svg>
diff --git a/data/themes/default/tail.svg b/data/themes/default/tail.svg
new file mode 100644 (file)
index 0000000..06522d9
--- /dev/null
@@ -0,0 +1,318 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://creativecommons.org/ns#"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:xlink="http://www.w3.org/1999/xlink"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   width="64"
+   height="256"
+   id="svg2463"
+   sodipodi:version="0.32"
+   inkscape:version="0.47 r22583"
+   version="1.0"
+   sodipodi:docname="tail.svg"
+   inkscape:output_extension="org.inkscape.output.svg.inkscape">
+  <defs
+     id="defs2465">
+    <marker
+       inkscape:stockid="Arrow2Lend"
+       orient="auto"
+       refY="0.0"
+       refX="0.0"
+       id="Arrow2Lend"
+       style="overflow:visible;">
+      <path
+         id="path3829"
+         style="font-size:12.0;fill-rule:evenodd;stroke-width:0.62500000;stroke-linejoin:round;"
+         d="M 8.7185878,4.0337352 L -2.2072895,0.016013256 L 8.7185884,-4.0017078 C 6.9730900,-1.6296469 6.9831476,1.6157441 8.7185878,4.0337352 z "
+         transform="scale(1.1) rotate(180) translate(1,0)" />
+    </marker>
+    <marker
+       inkscape:stockid="Tail"
+       orient="auto"
+       refY="0.0"
+       refX="0.0"
+       id="Tail"
+       style="overflow:visible">
+      <g
+         id="g3844"
+         transform="scale(-1.2)">
+        <path
+           id="path3846"
+           d="M -3.8048674,-3.9585227 L 0.54352094,0"
+           style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:0.8;marker-start:none;marker-end:none;stroke-linecap:round" />
+        <path
+           id="path3848"
+           d="M -1.2866832,-3.9585227 L 3.0617053,0"
+           style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:0.8;marker-start:none;marker-end:none;stroke-linecap:round" />
+        <path
+           id="path3850"
+           d="M 1.3053582,-3.9585227 L 5.6537466,0"
+           style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:0.8;marker-start:none;marker-end:none;stroke-linecap:round" />
+        <path
+           id="path3852"
+           d="M -3.8048674,4.1775838 L 0.54352094,0.21974226"
+           style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:0.8;marker-start:none;marker-end:none;stroke-linecap:round" />
+        <path
+           id="path3854"
+           d="M -1.2866832,4.1775838 L 3.0617053,0.21974226"
+           style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:0.8;marker-start:none;marker-end:none;stroke-linecap:round" />
+        <path
+           id="path3856"
+           d="M 1.3053582,4.1775838 L 5.6537466,0.21974226"
+           style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:0.8;marker-start:none;marker-end:none;stroke-linecap:round" />
+      </g>
+    </marker>
+    <marker
+       inkscape:stockid="Arrow1Lend"
+       orient="auto"
+       refY="0.0"
+       refX="0.0"
+       id="Arrow1Lend"
+       style="overflow:visible;">
+      <path
+         id="path3811"
+         d="M 0.0,0.0 L 5.0,-5.0 L -12.5,0.0 L 5.0,5.0 L 0.0,0.0 z "
+         style="fill-rule:evenodd;stroke:#000000;stroke-width:1.0pt;marker-start:none;"
+         transform="scale(0.8) rotate(180) translate(12.5,0)" />
+    </marker>
+    <marker
+       inkscape:stockid="Arrow1Lstart"
+       orient="auto"
+       refY="0.0"
+       refX="0.0"
+       id="Arrow1Lstart"
+       style="overflow:visible">
+      <path
+         id="path3808"
+         d="M 0.0,0.0 L 5.0,-5.0 L -12.5,0.0 L 5.0,5.0 L 0.0,0.0 z "
+         style="fill-rule:evenodd;stroke:#000000;stroke-width:1.0pt;marker-start:none"
+         transform="scale(0.8) translate(12.5,0)" />
+    </marker>
+    <marker
+       inkscape:stockid="DotL"
+       orient="auto"
+       refY="0.0"
+       refX="0.0"
+       id="DotL"
+       style="overflow:visible">
+      <path
+         id="path3870"
+         d="M -2.5,-1.0 C -2.5,1.7600000 -4.7400000,4.0 -7.5,4.0 C -10.260000,4.0 -12.5,1.7600000 -12.5,-1.0 C -12.5,-3.7600000 -10.260000,-6.0 -7.5,-6.0 C -4.7400000,-6.0 -2.5,-3.7600000 -2.5,-1.0 z "
+         style="fill-rule:evenodd;stroke:#000000;stroke-width:1.0pt;marker-start:none;marker-end:none"
+         transform="scale(0.8) translate(7.4, 1)" />
+    </marker>
+    <linearGradient
+       id="linearGradient3262">
+      <stop
+         style="stop-color:#f5f5f5;stop-opacity:0.22680412;"
+         offset="0"
+         id="stop3264" />
+      <stop
+         style="stop-color:#f5f5f5;stop-opacity:0.96078432;"
+         offset="1"
+         id="stop3266" />
+    </linearGradient>
+    <linearGradient
+       id="linearGradient3751"
+       inkscape:collect="always">
+      <stop
+         id="stop3753"
+         offset="0"
+         style="stop-color:black;stop-opacity:1;" />
+      <stop
+         id="stop3755"
+         offset="1"
+         style="stop-color:black;stop-opacity:0;" />
+    </linearGradient>
+    <inkscape:perspective
+       sodipodi:type="inkscape:persp3d"
+       inkscape:vp_x="0 : 526.18109 : 1"
+       inkscape:vp_y="0 : 1000 : 0"
+       inkscape:vp_z="744.09448 : 526.18109 : 1"
+       inkscape:persp3d-origin="372.04724 : 350.78739 : 1"
+       id="perspective2471" />
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient3751"
+       id="linearGradient3272"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(0.3868046,0,0,0.3868046,40.335717,481.59837)"
+       x1="665.12128"
+       y1="684.16162"
+       x2="381.28015"
+       y2="449.80624" />
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient3751"
+       id="linearGradient2406"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(0.3868046,0,0,0.3868046,43.114888,485.8841)"
+       x1="665.12128"
+       y1="684.16162"
+       x2="381.28015"
+       y2="449.80624" />
+    <inkscape:perspective
+       id="perspective3603"
+       inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
+       inkscape:vp_z="1 : 0.5 : 1"
+       inkscape:vp_y="0 : 1000 : 0"
+       inkscape:vp_x="0 : 0.5 : 1"
+       sodipodi:type="inkscape:persp3d" />
+    <filter
+       id="filter4437"
+       y="-0.25"
+       height="1.5"
+       inkscape:menu-tooltip="Darkens the edge with an inner blur and adds a flexible glow"
+       inkscape:menu="Shadows and Glows"
+       inkscape:label="Dark and Glow"
+       color-interpolation-filters="sRGB">
+      <feGaussianBlur
+         id="feGaussianBlur4439"
+         stdDeviation="5"
+         result="result6" />
+      <feComposite
+         id="feComposite4441"
+         in2="result6"
+         result="result8"
+         in="SourceGraphic"
+         operator="atop" />
+      <feComposite
+         id="feComposite4443"
+         in2="SourceAlpha"
+         result="result9"
+         operator="over"
+         in="result8" />
+      <feColorMatrix
+         id="feColorMatrix4445"
+         values="1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 1 0 "
+         result="result10" />
+      <feBlend
+         id="feBlend4447"
+         in2="result6"
+         in="result10"
+         mode="normal" />
+    </filter>
+    <filter
+       id="filter5783"
+       y="-0.25"
+       height="1.5"
+       inkscape:menu-tooltip="Darkens the edge with an inner blur and adds a flexible glow"
+       inkscape:menu="Shadows and Glows"
+       inkscape:label="Dark and Glow"
+       color-interpolation-filters="sRGB">
+      <feGaussianBlur
+         id="feGaussianBlur5785"
+         stdDeviation="5"
+         result="result6" />
+      <feComposite
+         id="feComposite5787"
+         in2="result6"
+         result="result8"
+         in="SourceGraphic"
+         operator="atop" />
+      <feComposite
+         id="feComposite5789"
+         in2="SourceAlpha"
+         result="result9"
+         operator="over"
+         in="result8" />
+      <feColorMatrix
+         id="feColorMatrix5791"
+         values="1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 1 0 "
+         result="result10" />
+      <feBlend
+         id="feBlend5793"
+         in2="result6"
+         in="result10"
+         mode="normal" />
+    </filter>
+    <filter
+       id="filter5813"
+       y="-0.25"
+       height="1.5"
+       inkscape:menu-tooltip="Darkens the edge with an inner blur and adds a flexible glow"
+       inkscape:menu="Shadows and Glows"
+       inkscape:label="Dark and Glow"
+       color-interpolation-filters="sRGB">
+      <feGaussianBlur
+         id="feGaussianBlur5815"
+         stdDeviation="5"
+         result="result6" />
+      <feComposite
+         id="feComposite5817"
+         in2="result6"
+         result="result8"
+         in="SourceGraphic"
+         operator="atop" />
+      <feComposite
+         id="feComposite5819"
+         in2="SourceAlpha"
+         result="result9"
+         operator="over"
+         in="result8" />
+      <feColorMatrix
+         id="feColorMatrix5821"
+         values="1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 1 0 "
+         result="result10" />
+      <feBlend
+         id="feBlend5823"
+         in2="result6"
+         in="result10"
+         mode="normal" />
+    </filter>
+  </defs>
+  <sodipodi:namedview
+     id="base"
+     pagecolor="#f5f5f5"
+     bordercolor="#666666"
+     borderopacity="1.0"
+     gridtolerance="10000"
+     guidetolerance="10"
+     objecttolerance="10"
+     inkscape:pageopacity="0"
+     inkscape:pageshadow="2"
+     inkscape:zoom="1.5550825"
+     inkscape:cx="32"
+     inkscape:cy="128"
+     inkscape:document-units="px"
+     inkscape:current-layer="layer1"
+     showgrid="false"
+     inkscape:window-width="1099"
+     inkscape:window-height="818"
+     inkscape:window-x="200"
+     inkscape:window-y="26"
+     inkscape:window-maximized="0" />
+  <metadata
+     id="metadata2468">
+    <rdf:RDF>
+      <cc:Work
+         rdf:about="">
+        <dc:format>image/svg+xml</dc:format>
+        <dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+      </cc:Work>
+    </rdf:RDF>
+  </metadata>
+  <g
+     inkscape:label="Layer 1"
+     inkscape:groupmode="layer"
+     id="layer1"
+     transform="translate(-110.35967,-643.51188)">
+    <rect
+       style="fill:#ffffff;fill-opacity:1;stroke:none;filter:url(#filter5813)"
+       id="rect5811"
+       width="24"
+       height="300"
+       x="130.35966"
+       y="647.5119"
+       rx="12"
+       ry="42.907162" />
+  </g>
+</svg>
diff --git a/data/themes/default/tail_drumfill.svg b/data/themes/default/tail_drumfill.svg
new file mode 100644 (file)
index 0000000..1a38db5
--- /dev/null
@@ -0,0 +1,375 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://creativecommons.org/ns#"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:xlink="http://www.w3.org/1999/xlink"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   width="64"
+   height="256"
+   id="svg2463"
+   sodipodi:version="0.32"
+   inkscape:version="0.47 r22583"
+   version="1.0"
+   sodipodi:docname="tail_drumfill.svg"
+   inkscape:output_extension="org.inkscape.output.svg.inkscape">
+  <defs
+     id="defs2465">
+    <marker
+       inkscape:stockid="Arrow2Lend"
+       orient="auto"
+       refY="0.0"
+       refX="0.0"
+       id="Arrow2Lend"
+       style="overflow:visible;">
+      <path
+         id="path3829"
+         style="font-size:12.0;fill-rule:evenodd;stroke-width:0.62500000;stroke-linejoin:round;"
+         d="M 8.7185878,4.0337352 L -2.2072895,0.016013256 L 8.7185884,-4.0017078 C 6.9730900,-1.6296469 6.9831476,1.6157441 8.7185878,4.0337352 z "
+         transform="scale(1.1) rotate(180) translate(1,0)" />
+    </marker>
+    <marker
+       inkscape:stockid="Tail"
+       orient="auto"
+       refY="0.0"
+       refX="0.0"
+       id="Tail"
+       style="overflow:visible">
+      <g
+         id="g3844"
+         transform="scale(-1.2)">
+        <path
+           id="path3846"
+           d="M -3.8048674,-3.9585227 L 0.54352094,0"
+           style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:0.8;marker-start:none;marker-end:none;stroke-linecap:round" />
+        <path
+           id="path3848"
+           d="M -1.2866832,-3.9585227 L 3.0617053,0"
+           style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:0.8;marker-start:none;marker-end:none;stroke-linecap:round" />
+        <path
+           id="path3850"
+           d="M 1.3053582,-3.9585227 L 5.6537466,0"
+           style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:0.8;marker-start:none;marker-end:none;stroke-linecap:round" />
+        <path
+           id="path3852"
+           d="M -3.8048674,4.1775838 L 0.54352094,0.21974226"
+           style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:0.8;marker-start:none;marker-end:none;stroke-linecap:round" />
+        <path
+           id="path3854"
+           d="M -1.2866832,4.1775838 L 3.0617053,0.21974226"
+           style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:0.8;marker-start:none;marker-end:none;stroke-linecap:round" />
+        <path
+           id="path3856"
+           d="M 1.3053582,4.1775838 L 5.6537466,0.21974226"
+           style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:0.8;marker-start:none;marker-end:none;stroke-linecap:round" />
+      </g>
+    </marker>
+    <marker
+       inkscape:stockid="Arrow1Lend"
+       orient="auto"
+       refY="0.0"
+       refX="0.0"
+       id="Arrow1Lend"
+       style="overflow:visible;">
+      <path
+         id="path3811"
+         d="M 0.0,0.0 L 5.0,-5.0 L -12.5,0.0 L 5.0,5.0 L 0.0,0.0 z "
+         style="fill-rule:evenodd;stroke:#000000;stroke-width:1.0pt;marker-start:none;"
+         transform="scale(0.8) rotate(180) translate(12.5,0)" />
+    </marker>
+    <marker
+       inkscape:stockid="Arrow1Lstart"
+       orient="auto"
+       refY="0.0"
+       refX="0.0"
+       id="Arrow1Lstart"
+       style="overflow:visible">
+      <path
+         id="path3808"
+         d="M 0.0,0.0 L 5.0,-5.0 L -12.5,0.0 L 5.0,5.0 L 0.0,0.0 z "
+         style="fill-rule:evenodd;stroke:#000000;stroke-width:1.0pt;marker-start:none"
+         transform="scale(0.8) translate(12.5,0)" />
+    </marker>
+    <marker
+       inkscape:stockid="DotL"
+       orient="auto"
+       refY="0.0"
+       refX="0.0"
+       id="DotL"
+       style="overflow:visible">
+      <path
+         id="path3870"
+         d="M -2.5,-1.0 C -2.5,1.7600000 -4.7400000,4.0 -7.5,4.0 C -10.260000,4.0 -12.5,1.7600000 -12.5,-1.0 C -12.5,-3.7600000 -10.260000,-6.0 -7.5,-6.0 C -4.7400000,-6.0 -2.5,-3.7600000 -2.5,-1.0 z "
+         style="fill-rule:evenodd;stroke:#000000;stroke-width:1.0pt;marker-start:none;marker-end:none"
+         transform="scale(0.8) translate(7.4, 1)" />
+    </marker>
+    <linearGradient
+       id="linearGradient3262">
+      <stop
+         style="stop-color:#f5f5f5;stop-opacity:0.22680412;"
+         offset="0"
+         id="stop3264" />
+      <stop
+         style="stop-color:#f5f5f5;stop-opacity:0.96078432;"
+         offset="1"
+         id="stop3266" />
+    </linearGradient>
+    <linearGradient
+       id="linearGradient3751"
+       inkscape:collect="always">
+      <stop
+         id="stop3753"
+         offset="0"
+         style="stop-color:black;stop-opacity:1;" />
+      <stop
+         id="stop3755"
+         offset="1"
+         style="stop-color:black;stop-opacity:0;" />
+    </linearGradient>
+    <inkscape:perspective
+       sodipodi:type="inkscape:persp3d"
+       inkscape:vp_x="0 : 526.18109 : 1"
+       inkscape:vp_y="0 : 1000 : 0"
+       inkscape:vp_z="744.09448 : 526.18109 : 1"
+       inkscape:persp3d-origin="372.04724 : 350.78739 : 1"
+       id="perspective2471" />
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient3751"
+       id="linearGradient3272"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(0.3868046,0,0,0.3868046,40.335717,481.59837)"
+       x1="665.12128"
+       y1="684.16162"
+       x2="381.28015"
+       y2="449.80624" />
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient3751"
+       id="linearGradient2406"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(0.3868046,0,0,0.3868046,43.114888,485.8841)"
+       x1="665.12128"
+       y1="684.16162"
+       x2="381.28015"
+       y2="449.80624" />
+    <inkscape:perspective
+       id="perspective3603"
+       inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
+       inkscape:vp_z="1 : 0.5 : 1"
+       inkscape:vp_y="0 : 1000 : 0"
+       inkscape:vp_x="0 : 0.5 : 1"
+       sodipodi:type="inkscape:persp3d" />
+    <filter
+       id="filter4437"
+       y="-0.25"
+       height="1.5"
+       inkscape:menu-tooltip="Darkens the edge with an inner blur and adds a flexible glow"
+       inkscape:menu="Shadows and Glows"
+       inkscape:label="Dark and Glow"
+       color-interpolation-filters="sRGB">
+      <feGaussianBlur
+         id="feGaussianBlur4439"
+         stdDeviation="5"
+         result="result6" />
+      <feComposite
+         id="feComposite4441"
+         in2="result6"
+         result="result8"
+         in="SourceGraphic"
+         operator="atop" />
+      <feComposite
+         id="feComposite4443"
+         in2="SourceAlpha"
+         result="result9"
+         operator="over"
+         in="result8" />
+      <feColorMatrix
+         id="feColorMatrix4445"
+         values="1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 1 0 "
+         result="result10" />
+      <feBlend
+         id="feBlend4447"
+         in2="result6"
+         in="result10"
+         mode="normal" />
+    </filter>
+    <filter
+       id="filter5783"
+       y="-0.25"
+       height="1.5"
+       inkscape:menu-tooltip="Darkens the edge with an inner blur and adds a flexible glow"
+       inkscape:menu="Shadows and Glows"
+       inkscape:label="Dark and Glow"
+       color-interpolation-filters="sRGB">
+      <feGaussianBlur
+         id="feGaussianBlur5785"
+         stdDeviation="5"
+         result="result6" />
+      <feComposite
+         id="feComposite5787"
+         in2="result6"
+         result="result8"
+         in="SourceGraphic"
+         operator="atop" />
+      <feComposite
+         id="feComposite5789"
+         in2="SourceAlpha"
+         result="result9"
+         operator="over"
+         in="result8" />
+      <feColorMatrix
+         id="feColorMatrix5791"
+         values="1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 1 0 "
+         result="result10" />
+      <feBlend
+         id="feBlend5793"
+         in2="result6"
+         in="result10"
+         mode="normal" />
+    </filter>
+    <filter
+       id="filter5813"
+       y="-0.25"
+       height="1.5"
+       inkscape:menu-tooltip="Darkens the edge with an inner blur and adds a flexible glow"
+       inkscape:menu="Shadows and Glows"
+       inkscape:label="Dark and Glow"
+       color-interpolation-filters="sRGB">
+      <feGaussianBlur
+         id="feGaussianBlur5815"
+         stdDeviation="5"
+         result="result6" />
+      <feComposite
+         id="feComposite5817"
+         in2="result6"
+         result="result8"
+         in="SourceGraphic"
+         operator="atop" />
+      <feComposite
+         id="feComposite5819"
+         in2="SourceAlpha"
+         result="result9"
+         operator="over"
+         in="result8" />
+      <feColorMatrix
+         id="feColorMatrix5821"
+         values="1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 1 0 "
+         result="result10" />
+      <feBlend
+         id="feBlend5823"
+         in2="result6"
+         in="result10"
+         mode="normal" />
+    </filter>
+    <filter
+       id="filter3704"
+       inkscape:label="Darken edges"
+       inkscape:menu="Shadows and Glows"
+       inkscape:menu-tooltip="Darken the edges with an inner blur"
+       color-interpolation-filters="sRGB">
+      <feGaussianBlur
+         id="feGaussianBlur3706"
+         result="result6"
+         stdDeviation="1.5" />
+      <feComposite
+         id="feComposite3708"
+         in2="result6"
+         operator="atop"
+         in="SourceGraphic"
+         result="result8" />
+      <feComposite
+         id="feComposite3710"
+         in2="SourceAlpha"
+         in="result8"
+         operator="atop"
+         result="result9" />
+    </filter>
+    <filter
+       id="filter3720"
+       y="-0.25"
+       height="1.5"
+       inkscape:menu-tooltip="Darkens the edge with an inner blur and adds a flexible glow"
+       inkscape:menu="Shadows and Glows"
+       inkscape:label="Dark and Glow"
+       color-interpolation-filters="sRGB">
+      <feGaussianBlur
+         id="feGaussianBlur3722"
+         stdDeviation="5"
+         result="result6" />
+      <feComposite
+         id="feComposite3724"
+         in2="result6"
+         result="result8"
+         in="SourceGraphic"
+         operator="atop" />
+      <feComposite
+         id="feComposite3726"
+         in2="SourceAlpha"
+         result="result9"
+         operator="over"
+         in="result8" />
+      <feColorMatrix
+         id="feColorMatrix3728"
+         values="1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 1 0 "
+         result="result10" />
+      <feBlend
+         id="feBlend3730"
+         in2="result6"
+         in="result10"
+         mode="normal" />
+    </filter>
+  </defs>
+  <sodipodi:namedview
+     id="base"
+     pagecolor="#f5f5f5"
+     bordercolor="#666666"
+     borderopacity="1.0"
+     gridtolerance="10000"
+     guidetolerance="10"
+     objecttolerance="10"
+     inkscape:pageopacity="0"
+     inkscape:pageshadow="2"
+     inkscape:zoom="1.5550825"
+     inkscape:cx="-84.392539"
+     inkscape:cy="128"
+     inkscape:document-units="px"
+     inkscape:current-layer="layer1"
+     showgrid="false"
+     inkscape:window-width="1099"
+     inkscape:window-height="818"
+     inkscape:window-x="200"
+     inkscape:window-y="26"
+     inkscape:window-maximized="0" />
+  <metadata
+     id="metadata2468">
+    <rdf:RDF>
+      <cc:Work
+         rdf:about="">
+        <dc:format>image/svg+xml</dc:format>
+        <dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+      </cc:Work>
+    </rdf:RDF>
+  </metadata>
+  <g
+     inkscape:label="Layer 1"
+     inkscape:groupmode="layer"
+     id="layer1"
+     transform="translate(-110.35967,-643.51188)">
+    <rect
+       style="fill:#dedede;fill-opacity:0.87058824;stroke:none;filter:url(#filter3720)"
+       id="rect5811"
+       width="44"
+       height="250"
+       x="120.35967"
+       y="646.5119"
+       rx="22"
+       ry="29.325443" />
+  </g>
+</svg>
diff --git a/data/themes/default/tail_glow.svg b/data/themes/default/tail_glow.svg
new file mode 100644 (file)
index 0000000..abe540f
--- /dev/null
@@ -0,0 +1,193 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://creativecommons.org/ns#"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:xlink="http://www.w3.org/1999/xlink"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   width="64"
+   height="256"
+   id="svg2463"
+   sodipodi:version="0.32"
+   inkscape:version="0.47 r22583"
+   version="1.0"
+   sodipodi:docname="tail_glow.svg"
+   inkscape:output_extension="org.inkscape.output.svg.inkscape">
+  <defs
+     id="defs2465">
+    <linearGradient
+       id="linearGradient3262">
+      <stop
+         style="stop-color:#f5f5f5;stop-opacity:0.22680412;"
+         offset="0"
+         id="stop3264" />
+      <stop
+         style="stop-color:#f5f5f5;stop-opacity:0.96078432;"
+         offset="1"
+         id="stop3266" />
+    </linearGradient>
+    <linearGradient
+       id="linearGradient3751"
+       inkscape:collect="always">
+      <stop
+         id="stop3753"
+         offset="0"
+         style="stop-color:black;stop-opacity:1;" />
+      <stop
+         id="stop3755"
+         offset="1"
+         style="stop-color:black;stop-opacity:0;" />
+    </linearGradient>
+    <inkscape:perspective
+       sodipodi:type="inkscape:persp3d"
+       inkscape:vp_x="0 : 526.18109 : 1"
+       inkscape:vp_y="0 : 1000 : 0"
+       inkscape:vp_z="744.09448 : 526.18109 : 1"
+       inkscape:persp3d-origin="372.04724 : 350.78739 : 1"
+       id="perspective2471" />
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient3751"
+       id="linearGradient3272"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(0.3868046,0,0,0.3868046,40.335717,481.59837)"
+       x1="665.12128"
+       y1="684.16162"
+       x2="381.28015"
+       y2="449.80624" />
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient3751"
+       id="linearGradient2406"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(0.3868046,0,0,0.3868046,43.114888,485.8841)"
+       x1="665.12128"
+       y1="684.16162"
+       x2="381.28015"
+       y2="449.80624" />
+    <inkscape:perspective
+       id="perspective3615"
+       inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
+       inkscape:vp_z="1 : 0.5 : 1"
+       inkscape:vp_y="0 : 1000 : 0"
+       inkscape:vp_x="0 : 0.5 : 1"
+       sodipodi:type="inkscape:persp3d" />
+    <filter
+       id="filter3684"
+       inkscape:label="Glow"
+       inkscape:menu="Shadows and Glows"
+       inkscape:menu-tooltip="Glow of object's own color at the edges"
+       color-interpolation-filters="sRGB">
+      <feGaussianBlur
+         id="feGaussianBlur3686"
+         result="result6"
+         stdDeviation="1.5" />
+      <feComposite
+         id="feComposite3688"
+         in2="result6"
+         operator="atop"
+         in="SourceGraphic"
+         result="result8" />
+      <feComposite
+         id="feComposite3690"
+         in2="SourceAlpha"
+         in="result8"
+         operator="atop"
+         result="fbSourceGraphic" />
+      <feColorMatrix
+         result="fbSourceGraphicAlpha"
+         in="fbSourceGraphic"
+         values="0 0 0 -1 0 0 0 0 -1 0 0 0 0 -1 0 0 0 0 1 0"
+         id="feColorMatrix3700" />
+      <feGaussianBlur
+         id="feGaussianBlur3702"
+         stdDeviation="5"
+         result="result91"
+         in="fbSourceGraphic" />
+      <feComposite
+         id="feComposite3704"
+         in2="result91"
+         in="fbSourceGraphic"
+         operator="over" />
+    </filter>
+  </defs>
+  <sodipodi:namedview
+     id="base"
+     pagecolor="#f5f5f5"
+     bordercolor="#666666"
+     borderopacity="1.0"
+     gridtolerance="10000"
+     guidetolerance="10"
+     objecttolerance="10"
+     inkscape:pageopacity="0"
+     inkscape:pageshadow="2"
+     inkscape:zoom="1.4"
+     inkscape:cx="-33.154762"
+     inkscape:cy="129.0314"
+     inkscape:document-units="px"
+     inkscape:current-layer="g3643"
+     showgrid="false"
+     inkscape:window-width="1099"
+     inkscape:window-height="818"
+     inkscape:window-x="306"
+     inkscape:window-y="14"
+     inkscape:window-maximized="0" />
+  <metadata
+     id="metadata2468">
+    <rdf:RDF>
+      <cc:Work
+         rdf:about="">
+        <dc:format>image/svg+xml</dc:format>
+        <dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+      </cc:Work>
+    </rdf:RDF>
+  </metadata>
+  <g
+     inkscape:label="Layer 1"
+     inkscape:groupmode="layer"
+     id="layer1"
+     transform="translate(-110.35967,-643.51188)">
+    <g
+       id="g3643">
+      <g
+         id="g3676"
+         style="stroke:#ffffff;stroke-opacity:1;filter:url(#filter3684)">
+        <g
+           id="g3651"
+           style="stroke:#ffffff;stroke-opacity:1">
+          <path
+             sodipodi:nodetypes="cc"
+             id="path2822-9"
+             d="m 142.35967,643.51188 c -1.82001,9.86717 -24.72011,65.93297 0,128"
+             style="fill:none;stroke:#ffffff;stroke-width:8;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
+          <path
+             style="fill:none;stroke:#ffffff;stroke-width:8;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+             d="m 142.35967,899.51188 c 1.82001,-9.86717 24.72011,-65.93297 0,-128"
+             id="path3649"
+             sodipodi:nodetypes="cc" />
+        </g>
+        <g
+           transform="matrix(-1,0,0,1,284.71934,0)"
+           id="g3670"
+           style="stroke:#ffffff;stroke-opacity:1">
+          <path
+             style="fill:none;stroke:#ffffff;stroke-width:8;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+             d="m 142.35967,643.51188 c -1.82001,9.86717 -24.72011,65.93297 0,128"
+             id="path3672"
+             sodipodi:nodetypes="cc" />
+          <path
+             sodipodi:nodetypes="cc"
+             id="path3674"
+             d="m 142.35967,899.51188 c 1.82001,-9.86717 24.72011,-65.93297 0,-128"
+             style="fill:none;stroke:#ffffff;stroke-width:8;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
+        </g>
+      </g>
+    </g>
+  </g>
+</svg>
diff --git a/data/themes/default/tap.svg b/data/themes/default/tap.svg
new file mode 100644 (file)
index 0000000..2976aed
--- /dev/null
@@ -0,0 +1,114 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://creativecommons.org/ns#"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:xlink="http://www.w3.org/1999/xlink"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   width="64"
+   height="64"
+   id="svg2463"
+   sodipodi:version="0.32"
+   inkscape:version="0.46"
+   version="1.0"
+   sodipodi:docname="tap.svg"
+   inkscape:output_extension="org.inkscape.output.svg.inkscape">
+  <defs
+     id="defs2465">
+    <linearGradient
+       id="linearGradient3262">
+      <stop
+         style="stop-color:#f5f5f5;stop-opacity:0.22680412;"
+         offset="0"
+         id="stop3264" />
+      <stop
+         style="stop-color:#f5f5f5;stop-opacity:0.96078432;"
+         offset="1"
+         id="stop3266" />
+    </linearGradient>
+    <linearGradient
+       id="linearGradient3751"
+       inkscape:collect="always">
+      <stop
+         id="stop3753"
+         offset="0"
+         style="stop-color:black;stop-opacity:1;" />
+      <stop
+         id="stop3755"
+         offset="1"
+         style="stop-color:black;stop-opacity:0;" />
+    </linearGradient>
+    <inkscape:perspective
+       sodipodi:type="inkscape:persp3d"
+       inkscape:vp_x="0 : 526.18109 : 1"
+       inkscape:vp_y="0 : 1000 : 0"
+       inkscape:vp_z="744.09448 : 526.18109 : 1"
+       inkscape:persp3d-origin="372.04724 : 350.78739 : 1"
+       id="perspective2471" />
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient3751"
+       id="linearGradient3272"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(0.3868046,0,0,0.3868046,40.335717,481.59837)"
+       x1="665.12128"
+       y1="684.16162"
+       x2="381.28015"
+       y2="449.80624" />
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient3751"
+       id="linearGradient2406"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(0.3868046,0,0,0.3868046,43.114888,485.8841)"
+       x1="665.12128"
+       y1="684.16162"
+       x2="381.28015"
+       y2="449.80624" />
+  </defs>
+  <sodipodi:namedview
+     id="base"
+     pagecolor="#f5f5f5"
+     bordercolor="#666666"
+     borderopacity="1.0"
+     gridtolerance="10000"
+     guidetolerance="10"
+     objecttolerance="10"
+     inkscape:pageopacity="0"
+     inkscape:pageshadow="2"
+     inkscape:zoom="5.6"
+     inkscape:cx="-1.9902199"
+     inkscape:cy="38.579797"
+     inkscape:document-units="px"
+     inkscape:current-layer="layer1"
+     showgrid="false"
+     inkscape:window-width="1021"
+     inkscape:window-height="720"
+     inkscape:window-x="87"
+     inkscape:window-y="34" />
+  <metadata
+     id="metadata2468">
+    <rdf:RDF>
+      <cc:Work
+         rdf:about="">
+        <dc:format>image/svg+xml</dc:format>
+        <dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+      </cc:Work>
+    </rdf:RDF>
+  </metadata>
+  <g
+     inkscape:label="Layer 1"
+     inkscape:groupmode="layer"
+     id="layer1"
+     transform="translate(-110.35967,-771.51188)">
+    <path
+       style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1.16799999999999993;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;stroke-miterlimit:4;stroke-dasharray:none"
+       d="M 145.82521,786.11711 L 144.45057,786.11711 L 144.17565,786.80444 L 144.45057,787.56047 L 144.31311,788.38526 L 143.62581,787.97287 L 143.07595,786.94189 L 141.90751,786.66697 L 141.42639,786.18585 L 140.39542,785.70472 L 139.22698,783.78023 L 139.29572,782.88672 L 142.18244,780.6873 L 143.55706,781.30589 L 143.76326,781.78703 L 143.76326,782.33687 L 144.10692,782.81799 L 144.79423,783.02419 L 145.27535,782.61179 L 145.34408,782.13067 L 145.13789,781.71829 L 144.7255,781.51209 L 144.45057,781.16843 L 145.06916,780.89351 L 144.9317,780.20618 L 144.9317,779.7938 L 144.51932,779.3814 L 144.31311,778.76281 L 143.48834,778.55663 L 142.80102,778.41916 L 141.35765,779.45014 L 137.71489,780.89351 L 136.8901,781.71829 L 136.27151,782.19941 L 136.13404,783.29911 L 136.40899,783.84896 L 137.09631,785.70472 L 137.98981,787.42302 L 138.95205,788.66018 L 137.43996,791.13453 L 135.72166,794.84603 L 134.69068,796.49558 L 132.97241,798.62627 L 132.90367,799.58851 L 132.01017,800.4133 L 133.38479,801.65047 L 133.04114,803.09384 L 133.1786,806.32421 L 133.79717,810.03572 L 134.41577,813.33485 L 135.10307,814.43455 L 136.06533,816.42776 L 137.57742,818.69592 L 137.98981,820.13927 L 138.4022,821.17025 L 137.16502,822.88855 L 134.96561,823.78205 L 134.75943,824.46937 L 138.95205,824.33192 L 138.33347,825.43162 L 139.08951,826.11894 L 141.08274,826.32513 L 142.66356,824.9505 L 143.21342,823.02602 L 144.10692,821.37645 L 145.20662,820.41421 L 145.55028,819.3145 L 144.38186,819.24576 L 145.13789,818.48971 L 143.62581,818.97084 L 144.7255,817.87112 L 143.90073,817.66494 L 143.28213,816.90889 L 142.25117,814.77821 L 139.84556,812.785 L 139.36445,812.64753 L 139.84556,812.23514 L 139.77683,811.06671 L 140.25796,810.03572 L 139.84556,810.10446 L 140.60161,808.79856 L 140.60161,807.49266 L 141.08274,806.80534 L 141.08274,805.91182 L 142.1137,804.53718 L 142.18244,803.36875 L 141.97624,802.40652 L 142.45737,801.3068 L 143.0072,800.4133 L 143.0072,799.86344 L 143.62581,799.7947 L 144.17565,799.24485 L 144.65677,797.87022 L 145.75648,796.63305 L 147.06237,796.15193 L 147.88715,796.83925 L 149.88037,797.45783 L 151.4612,798.28261 L 152.21723,799.24485 L 153.52314,799.38231 L 157.64704,801.16934 L 159.77771,801.92538 L 161.49601,803.23129 L 161.90839,803.09384 L 161.90839,802.68144 L 160.94616,801.92538 L 162.8019,802.40652 L 163.0081,802.06285 L 162.59571,801.65047 L 163.28303,801.65047 L 163.35176,801.23808 L 162.11459,800.96314 L 163.07683,800.68821 L 163.07683,800.2071 L 162.73317,800.13837 L 161.70219,800.2071 L 160.87743,799.86344 L 160.32757,799.58851 L 161.15235,798.90119 L 161.35855,798.42008 L 161.22108,798.07642 L 160.46504,798.21388 L 158.8842,799.03866 L 158.67802,799.45105 L 158.12816,799.31359 L 156.13494,798.21388 L 156.0662,797.45783 L 154.89777,796.83925 L 152.90456,795.80826 L 152.42345,796.15193 L 152.49216,795.6708 L 151.39247,794.63983 L 150.43021,794.36491 L 149.53671,793.33393 L 149.26179,792.99027 L 150.1553,793.60886 L 150.01784,792.92154 L 150.70515,793.26519 L 150.49895,792.23422 L 151.4612,793.12772 L 151.04882,792.50914 L 152.01105,792.92154 L 151.18628,791.75311 L 151.80485,791.95929 L 151.52993,790.8596 L 152.01105,791.27198 L 151.32373,790.24102 L 152.01105,790.44721 L 151.39247,789.62243 L 152.21723,789.55369 L 151.32373,789.00384 L 151.87358,788.72892 L 151.25501,788.66018 L 152.07977,787.90413 L 151.32373,787.97287 L 151.39247,787.49175 L 151.4612,786.11711 L 151.04882,787.07936 L 150.56768,785.70472 L 150.63642,786.80444 L 150.36149,786.87316 L 149.67417,786.87316 L 148.91813,785.77346 L 148.16207,785.77346 L 147.26856,785.0174 L 146.85617,785.42979 L 145.82521,786.11711 z"
+       id="path1939" />
+  </g>
+</svg>
diff --git a/data/themes/default/vumeter_bg.svg b/data/themes/default/vumeter_bg.svg
new file mode 100644 (file)
index 0000000..6080845
--- /dev/null
@@ -0,0 +1,143 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://creativecommons.org/ns#"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   width="64"
+   height="256"
+   id="svg1901"
+   sodipodi:version="0.32"
+   inkscape:version="0.46"
+   sodipodi:docname="vumeter_bg.svg"
+   sodipodi:docbase="/home/tsoots/ohj/translations/po"
+   version="1.0"
+   inkscape:output_extension="org.inkscape.output.svg.inkscape">
+  <defs
+     id="defs1903">
+    <inkscape:perspective
+       sodipodi:type="inkscape:persp3d"
+       inkscape:vp_x="0 : 526.18109 : 1"
+       inkscape:vp_y="0 : 1000 : 0"
+       inkscape:vp_z="744.09448 : 526.18109 : 1"
+       inkscape:persp3d-origin="372.04724 : 350.78739 : 1"
+       id="perspective7" />
+  </defs>
+  <sodipodi:namedview
+     id="base"
+     pagecolor="#ffffff"
+     bordercolor="#666666"
+     borderopacity="1.0"
+     inkscape:pageopacity="0.0"
+     inkscape:pageshadow="2"
+     inkscape:zoom="4.9720185"
+     inkscape:cx="-36.525743"
+     inkscape:cy="96.674529"
+     inkscape:document-units="px"
+     inkscape:current-layer="layer1"
+     gridtolerance="10000"
+     inkscape:window-width="1920"
+     inkscape:window-height="1125"
+     inkscape:window-x="0"
+     inkscape:window-y="25"
+     showgrid="true"
+     inkscape:showpageshadow="false">
+    <inkscape:grid
+       type="xygrid"
+       id="grid3164"
+       visible="true"
+       enabled="true" />
+  </sodipodi:namedview>
+  <metadata
+     id="metadata1906">
+    <rdf:RDF>
+      <cc:Work
+         rdf:about="">
+        <dc:format>image/svg+xml</dc:format>
+        <dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+      </cc:Work>
+    </rdf:RDF>
+  </metadata>
+  <g
+     inkscape:label="Taso 1"
+     inkscape:groupmode="layer"
+     id="layer1"
+     style="opacity:1">
+    <rect
+       style="fill:#000000;fill-opacity:0.75294119;stroke:none;stroke-width:0.05000000000000000;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+       id="rect2380"
+       width="62"
+       height="254"
+       x="1"
+       y="1"
+       rx="5"
+       ry="5" />
+    <text
+       xml:space="preserve"
+       style="font-size:29.48888778999999971px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;fill:#d9d9d9;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Droid Sans Mono"
+       x="18.861689"
+       y="199.61098"
+       id="text3152"
+       transform="scale(0.7952629,1.2574459)"><tspan
+         sodipodi:role="line"
+         id="tspan3154"
+         x="18.861689"
+         y="199.61098">dB</tspan></text>
+    <text
+       xml:space="preserve"
+       style="font-size:20.84702301px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;fill:#808080;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Droid Sans Mono"
+       x="4.7968478"
+       y="21.889374"
+       id="text3156"
+       transform="scale(1.0423512,0.9593696)"><tspan
+         sodipodi:role="line"
+         id="tspan3158"
+         x="4.7968478"
+         y="21.889374">CLIP</tspan></text>
+    <text
+       xml:space="preserve"
+       style="font-size:20px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;fill:#808080;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Droid Sans Mono"
+       x="15"
+       y="111"
+       id="text3160"><tspan
+         sodipodi:role="line"
+         id="tspan3162"
+         x="15"
+         y="111">-20</tspan></text>
+    <text
+       xml:space="preserve"
+       style="font-size:20px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;opacity:1;fill:#808080;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Droid Sans Mono"
+       x="15"
+       y="61"
+       id="text3166"><tspan
+         sodipodi:role="line"
+         id="tspan3168"
+         x="15"
+         y="61">-10</tspan></text>
+    <text
+       xml:space="preserve"
+       style="font-size:20px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;opacity:1;fill:#808080;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Droid Sans Mono"
+       x="15"
+       y="211"
+       id="text3170"><tspan
+         sodipodi:role="line"
+         id="tspan3172"
+         x="15"
+         y="211">-40</tspan></text>
+    <text
+       xml:space="preserve"
+       style="font-size:20px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;opacity:1;fill:#808080;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Droid Sans Mono"
+       x="15"
+       y="161"
+       id="text3174"><tspan
+         sodipodi:role="line"
+         id="tspan3176"
+         x="15"
+         y="161">-30</tspan></text>
+  </g>
+</svg>
diff --git a/data/themes/default/vumeter_fg.svg b/data/themes/default/vumeter_fg.svg
new file mode 100644 (file)
index 0000000..c85c2b0
--- /dev/null
@@ -0,0 +1,110 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://creativecommons.org/ns#"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:xlink="http://www.w3.org/1999/xlink"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   width="64"
+   height="256"
+   id="svg1901"
+   sodipodi:version="0.32"
+   inkscape:version="0.46"
+   sodipodi:docname="vumeter_fg.svg"
+   sodipodi:docbase="/home/tsoots/ohj/translations/po"
+   version="1.0"
+   inkscape:output_extension="org.inkscape.output.svg.inkscape">
+  <defs
+     id="defs1903">
+    <linearGradient
+       id="linearGradient3220">
+      <stop
+         style="stop-color:#ff0000;stop-opacity:0.75294119;"
+         offset="0"
+         id="stop3222" />
+      <stop
+         id="stop3228"
+         offset="0.16923039"
+         style="stop-color:#ffff41;stop-opacity:0.75294119;" />
+      <stop
+         style="stop-color:#ffff41;stop-opacity:0.75294119;"
+         offset="0.38175285"
+         id="stop3230" />
+      <stop
+         style="stop-color:#00ff00;stop-opacity:0.75294119;"
+         offset="1"
+         id="stop3224" />
+    </linearGradient>
+    <inkscape:perspective
+       sodipodi:type="inkscape:persp3d"
+       inkscape:vp_x="0 : 526.18109 : 1"
+       inkscape:vp_y="0 : 1000 : 0"
+       inkscape:vp_z="744.09448 : 526.18109 : 1"
+       inkscape:persp3d-origin="372.04724 : 350.78739 : 1"
+       id="perspective7" />
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient3220"
+       id="linearGradient3226"
+       x1="30"
+       y1="6"
+       x2="30"
+       y2="221"
+       gradientUnits="userSpaceOnUse" />
+  </defs>
+  <sodipodi:namedview
+     id="base"
+     pagecolor="#ffffff"
+     bordercolor="#666666"
+     borderopacity="1.0"
+     inkscape:pageopacity="0.0"
+     inkscape:pageshadow="2"
+     inkscape:zoom="3.515748"
+     inkscape:cx="32"
+     inkscape:cy="128"
+     inkscape:document-units="px"
+     inkscape:current-layer="layer1"
+     gridtolerance="10000"
+     inkscape:window-width="1920"
+     inkscape:window-height="1125"
+     inkscape:window-x="0"
+     inkscape:window-y="25"
+     showgrid="true"
+     inkscape:showpageshadow="false">
+    <inkscape:grid
+       type="xygrid"
+       id="grid3164"
+       visible="true"
+       enabled="true" />
+  </sodipodi:namedview>
+  <metadata
+     id="metadata1906">
+    <rdf:RDF>
+      <cc:Work
+         rdf:about="">
+        <dc:format>image/svg+xml</dc:format>
+        <dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+      </cc:Work>
+    </rdf:RDF>
+  </metadata>
+  <g
+     inkscape:label="Taso 1"
+     inkscape:groupmode="layer"
+     id="layer1"
+     style="opacity:1">
+    <rect
+       style="fill:url(#linearGradient3226);fill-opacity:1.0;stroke:none;stroke-width:0.05000000000000000;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+       id="rect3218"
+       width="55"
+       height="215"
+       x="5"
+       y="6"
+       rx="5"
+       ry="5" />
+  </g>
+</svg>
diff --git a/data/themes/default/warning.svg b/data/themes/default/warning.svg
new file mode 100644 (file)
index 0000000..d763eed
--- /dev/null
@@ -0,0 +1,142 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://creativecommons.org/ns#"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:xlink="http://www.w3.org/1999/xlink"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   width="800"
+   height="400"
+   id="svg1901"
+   sodipodi:version="0.32"
+   inkscape:version="0.46"
+   sodipodi:docname="warning.svg"
+   sodipodi:docbase="/home/tsoots/ohj/translations/po"
+   version="1.0"
+   inkscape:output_extension="org.inkscape.output.svg.inkscape">
+  <defs
+     id="defs1903">
+    <linearGradient
+       id="linearGradient4769">
+      <stop
+         style="stop-color:#ffff00;stop-opacity:1;"
+         offset="0"
+         id="stop4771" />
+      <stop
+         id="stop4783"
+         offset="0.25"
+         style="stop-color:#ffff00;stop-opacity:1;" />
+      <stop
+         style="stop-color:#000000;stop-opacity:1;"
+         offset="0.25"
+         id="stop4785" />
+      <stop
+         id="stop4777"
+         offset="0.5"
+         style="stop-color:#000000;stop-opacity:1;" />
+      <stop
+         style="stop-color:#000000;stop-opacity:1;"
+         offset="0.75"
+         id="stop4779" />
+      <stop
+         id="stop4781"
+         offset="0.75"
+         style="stop-color:#ffff00;stop-opacity:1;" />
+      <stop
+         style="stop-color:#ffff00;stop-opacity:1;"
+         offset="1"
+         id="stop4773" />
+    </linearGradient>
+    <inkscape:perspective
+       sodipodi:type="inkscape:persp3d"
+       inkscape:vp_x="0 : 526.18109 : 1"
+       inkscape:vp_y="0 : 1000 : 0"
+       inkscape:vp_z="744.09448 : 526.18109 : 1"
+       inkscape:persp3d-origin="372.04724 : 350.78739 : 1"
+       id="perspective7" />
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient4769"
+       id="linearGradient4775"
+       x1="-28.971428"
+       y1="411.42859"
+       x2="14.287568"
+       y2="368.16959"
+       gradientUnits="userSpaceOnUse"
+       spreadMethod="repeat" />
+    <filter
+       inkscape:collect="always"
+       id="filter4825">
+      <feGaussianBlur
+         inkscape:collect="always"
+         stdDeviation="8.445"
+         id="feGaussianBlur4827" />
+    </filter>
+  </defs>
+  <sodipodi:namedview
+     id="base"
+     pagecolor="#ffffff"
+     bordercolor="#666666"
+     borderopacity="1.0"
+     inkscape:pageopacity="0.0"
+     inkscape:pageshadow="2"
+     inkscape:zoom="1.3103852"
+     inkscape:cx="400.00001"
+     inkscape:cy="199.99998"
+     inkscape:document-units="px"
+     inkscape:current-layer="layer1"
+     gridtolerance="10000"
+     inkscape:window-width="1920"
+     inkscape:window-height="1125"
+     inkscape:window-x="0"
+     inkscape:window-y="25"
+     showgrid="true">
+    <inkscape:grid
+       type="xygrid"
+       id="grid4789"
+       visible="true"
+       enabled="true" />
+  </sodipodi:namedview>
+  <metadata
+     id="metadata1906">
+    <rdf:RDF>
+      <cc:Work
+         rdf:about="">
+        <dc:format>image/svg+xml</dc:format>
+        <dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+      </cc:Work>
+    </rdf:RDF>
+  </metadata>
+  <g
+     inkscape:label="Taso 1"
+     inkscape:groupmode="layer"
+     id="layer1"
+     style="opacity:1">
+    <rect
+       style="opacity:1;fill:#000000;fill-opacity:1;stroke:#000000;stroke-width:3;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;filter:url(#filter4825)"
+       id="rect4791"
+       width="760"
+       height="360"
+       x="20"
+       y="20" />
+    <rect
+       style="fill:url(#linearGradient4775);fill-opacity:1;stroke:#000000;stroke-width:3;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+       id="rect2380"
+       width="760"
+       height="360"
+       x="20"
+       y="20" />
+    <rect
+       style="fill:#ffff00;fill-opacity:1;stroke:#000000;stroke-width:3;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+       id="rect4787"
+       width="720"
+       height="320"
+       x="40"
+       y="40" />
+  </g>
+</svg>
diff --git a/data/themes/default/wave.png b/data/themes/default/wave.png
new file mode 100644 (file)
index 0000000..81e1ced
Binary files /dev/null and b/data/themes/default/wave.png differ
diff --git a/data/xsl/songlist-to-tex.xsl b/data/xsl/songlist-to-tex.xsl
new file mode 100644 (file)
index 0000000..ac1c808
--- /dev/null
@@ -0,0 +1,58 @@
+<?xml version="1.0"?>
+
+<!-- Use xmlstarlet tr songlist-to-tex.xsl songlist.xml > songlist.tex -->
+<!-- Then compile the tex into pdf with pdflatex songlist.tex -->
+
+<xsl:stylesheet  version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
+
+<xsl:output method="text" encoding="UTF-8" use-character-maps="tex"/>
+
+<!-- LaTex escaping, doesn't work with xmlstarlet :/
+<xsl:character-map name="tex">
+  <xsl:output-character character="&lt;" string="\textless{}"/>
+  <xsl:output-character character="&gt;" string="\textgreater{}"/>
+  <xsl:output-character character="~" string="\textasciitilde{}"/>
+  <xsl:output-character character="^" string="\textasciicircum{}"/>
+  <xsl:output-character character="&amp;" string="\&amp;"/>
+  <xsl:output-character character="#" string="\#"/>
+  <xsl:output-character character="_" string="\_"/>
+  <xsl:output-character character="$" string="\$"/>
+  <xsl:output-character character="%" string="\%"/>
+  <xsl:output-character character="|" string="\docbooktolatexpipe{}"/>
+  <xsl:output-character character="{" string="\{"/>
+  <xsl:output-character character="}" string="\}"/>
+  <xsl:output-character character="\" string="\textbackslash "/>
+</xsl:character-map>
+-->
+
+<xsl:template match="/songlist">
+
+\documentclass[a4paper,6pt]{report}
+\usepackage[utf8]{inputenc}
+\usepackage{graphicx}
+\usepackage{multicol}
+\oddsidemargin -0.5in
+\textwidth 185mm
+\begin{document}
+\tiny
+\begin{multicols}{4}
+<xsl:for-each select="song">
+\begin{minipage}{45 mm}
+<xsl:choose>
+<xsl:when test="cover">\includegraphics[width=1cm]{<xsl:value-of select="cover"/>}</xsl:when>
+<xsl:otherwise>\hspace{1cm}</xsl:otherwise>
+</xsl:choose>
+\begin{minipage}{35 cm}
+\textbf{<xsl:value-of select="title"/>}
+\newline
+<xsl:value-of select="artist"/>
+\end{minipage}
+\end{minipage}
+</xsl:for-each>
+\end{multicols}
+\end{document}
+
+</xsl:template>
+
+</xsl:stylesheet>
+
diff --git a/data/xsl/songlist-to-xhtml.xsl b/data/xsl/songlist-to-xhtml.xsl
new file mode 100644 (file)
index 0000000..945f922
--- /dev/null
@@ -0,0 +1,61 @@
+<?xml version="1.0"?>
+
+<!-- Use xmlstarlet tr songlist-to-xhtml.xsl songlist.xml > songlist.xhtml -->
+
+<xsl:stylesheet  version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns="http://www.w3.org/1999/xhtml">
+
+<xsl:output method="xml" indent="yes" encoding="UTF-8"/>
+
+<xsl:template match="/songlist">
+  <html>
+    <head>
+      <title>Karaoke</title>
+      <meta http-equiv="Content-type" content="application/xhtml+xml; charset=UTF-8"/>
+      <style>
+       body { font-size: xx-small; font-family: sans; }
+       tr { overflow: auto; }
+       th { text-align: left; }
+       td { white-space: pre; overflow: hidden; }
+        #layout { border-spacing: 10mm; }
+        table { float: left; margin: 3mm; table-layout: fixed; width: 46%; border: 2px solid black; border-collapse: collapse; }
+        th:first-child, td:first-child { text-align: right; width: 5ex; }
+        th, td { padding: 2px; padding-left: 3mm; padding-right: 3mm; }
+        table th { background: black; color: white; border-bottom: 2px solid black; }
+        #byArtist tr.fifth { background: #ddf; }
+        #byTitle tr.fifth { background: #cfc; }
+      </style>
+    </head>
+    <body>
+            <table id="byArtist">
+              <thead>
+                <tr><th>#</th><th>Artist</th><th>Title</th></tr>
+              </thead>
+              <tbody>
+                <xsl:for-each select="song">
+                  <tr>
+                    <xsl:if test="position() mod 5 = 0"><xsl:attribute name="class">fifth</xsl:attribute></xsl:if>
+                    <td><xsl:value-of select="@num"/></td><td><xsl:value-of select="artist"/></td><td><xsl:value-of select="title"/></td>
+                  </tr>
+                </xsl:for-each>
+              </tbody>
+            </table>
+            <table id="byTitle">
+              <thead>
+                <tr><th>#</th><th>Title</th><th>Artist</th></tr>
+              </thead>
+              <tbody>
+                <xsl:for-each select="song">
+                  <xsl:sort select="collate/title"/>
+                  <tr>
+                    <xsl:if test="position() mod 5 = 0"><xsl:attribute name="class">fifth</xsl:attribute></xsl:if>
+                    <td><xsl:value-of select="@num"/></td><td><xsl:value-of select="title"/></td><td><xsl:value-of select="artist"/></td>
+                  </tr>
+                </xsl:for-each>
+              </tbody>
+            </table>
+    </body>
+  </html>
+</xsl:template>
+
+</xsl:stylesheet>
+
diff --git a/docs/Authors.txt b/docs/Authors.txt
new file mode 100644 (file)
index 0000000..0780a05
--- /dev/null
@@ -0,0 +1,130 @@
+ACTIVE DEVELOPERS
+-----------------
+
+Vincent Le Ligeour  <yoda-jm at users.sourceforge.net>
+       * Original author
+       * Core developer
+
+Lasse Kärkkäinen  <tronic+ndrm at trn.iki.fi>
+       * Core developer
+       * FFT/Analyzer, LibDA and a lot of other things
+
+Tapio Vierros <aave000 at users.sourceforge.net>
+       * Core developer
+       * Lots of stuff in various areas
+       * Overall quality control
+
+Niek Nooijens <https://github.com/nieknooijens>
+       * Playlist Support
+       * Webserver support
+       * SDL2.0 Port
+       * Some minor usability improvements
+
+
+INACTIVE DEVELOPERS
+-------------------
+
+No commits for a long time, but their stuff is still used.
+
+Stefan Kristiansson  <stekern at users.sourceforge.net>
+       * Core developer
+
+jEsuSdA  <info at jesusda.com>
+       * SVG design (the original lima theme)
+
+Tobias Gehrig <tgehrig at users.sourceforge.net>
+       * Pre-calculate FFT window patch
+
+Topnob <topnob at users.sourceforge.net>
+       * Non-power-of-two texture loading on older hardware
+       * Many other fixes
+       * SVG design (tux theme)
+
+Jack_MD <jack-md at users.sourceforge.net>
+       * OSX build fixes and testing
+
+zarrn <zarrn at users.sourceforge.net>
+       * OSX build fixes and testing
+
+knittl <knittl at users.sourceforge.net>
+       * Code documentation (Doxygen comments)
+       * SVG design
+
+Fabian Fingerle  <fabian at datensalat.eu>
+       * Dependency testing
+
+Miguel Sánchez de León Peque <msdeleonpeque at gmail.com>
+       * Main menu
+       * SVG design
+
+Xaldyz <xaldyz at users.sourceforge.net>
+       * Windows build fixes and testing
+
+Markus Raab <ich at markus-raab.org>
+       * Hiscore (xml + ultrastar format)
+
+Matti Kemppainen <mpkemppa at users.sf.net>
+       * Prototyping dance game
+       
+Jaakko Nikkola <jnikkola at users.sourceforge.net>
+       * Dance game developer
+
+Fredrik Klasson <scientica at gmail.com>
+       * Logging stuff, xml i18n, image loading tweaks
+
+
+GUEST DEVELOPERS
+----------------
+
+These guys have provided some important part for the game, but have never been
+directly involved in the project.
+
+Tryad <http://tryad.org/>
+       * The menu song (CC-by-sa)
+
+Oxetti choir <http://www.oxetti.info/>
+       * Practice background vocalization (recorded for this project)
+
+Joonas Kerttula / Frets on Fire <http://fretsonfire.sourceforge.net/>
+       * SVGs borrowed from FoF under GNU GPL :)
+
+
+PAST DEVELOPERS
+---------------
+
+Cool guys who have contributed to the project in the past, but whose
+contributions have been superceded and are no longer part of the distribution.
+
+John Stumpo <stump at jstump.com>
+       * Windows compilation scripts
+
+dex7 <dex7 at users.sourceforge.net>
+       * Website layout
+
+Jami Pekkanen  <jami.pekkanen at ateco.fi>
+       * Cairotosdl and pitchgraph class
+
+Sebastian Sproesser  <sebastian at sproesser.org>
+       * Background management
+       * Song sync improvement
+       * Current position in the track
+
+Matias Holte  <matiasholte at users.sourceforge.net>
+       * Screen sing propositions and patchs
+
+Ignacio Casal Quinteiro  <nacho.resa at gmail.com>
+       * GStreamer implementation
+
+Sylvain Henry <hsyl20 at yahoo.fr>
+       * Long sentence display patch
+
+Olli Salli <osalli at cc.hut.fi>
+       * Silky Strings glfw window management, input and graphics
+
+Ville Virkkala <vvirkkal at cc.hut.fi>
+       * Silky Strings original MIDI parser
+       * Silky Strings game logic
+       
+Tuomas Perälä <tuomas.perala at hut.fi>
+       * Silky Strings Qt-based launcher
+
diff --git a/docs/CMakeLists.txt b/docs/CMakeLists.txt
new file mode 100644 (file)
index 0000000..790aefd
--- /dev/null
@@ -0,0 +1,3 @@
+if(UNIX)
+       add_subdirectory(man)
+endif(UNIX)
diff --git a/docs/Compiling.txt b/docs/Compiling.txt
new file mode 100644 (file)
index 0000000..2a0d822
--- /dev/null
@@ -0,0 +1,64 @@
+To install from git:
+
+       # Checkout the git
+       git clone git://github.com/performous/performous.git
+       # Create separate build folder under trunk to avoid polluting the source tree
+       mkdir performous/build
+       cd performous/build
+       # Compile the game and its support libraries
+       cmake ../
+       make
+       sudo make install
+       # Run the game
+       performous
+       
+       In order to change installation location (the default is /usr/local/),
+       use cmake parameter -DCMAKE_INSTALL_PREFIX=/where/to.
+       
+Dependencies:
+
+       - OpenGL : graphics
+
+       - Boost : threads, parsers/conversions, pointer containers, ...
+
+       - SDL : window management and input
+
+       - FFmpeg (avcodec, avformat and swscale): A/V decoding
+       
+       - Cairo >= 1.2 : scalable graphical support
+
+       - librsvg : svg rendering (themes)
+
+       - libxml++ : XML parser, used for themes etc.
+
+       - PortAudio v19 : audio capture and playback
+
+       - Gettext (optional) for internationalization
+
+       - PortMidi (optional) for MIDI drum support
+
+       - OpenCV (optional) for webcam support
+
+       https://github.com/performous/performous/wiki/Building-and-installing-from-source
+       
+       for package names on various systems (or just performous.org if the above no
+       longer works).
+       
+
+You can find songs online by Google or at your favorite Torrent sites. We
+recommend starting with the ultrastar-songs package that can be download from
+our project website. You need to extract that tarball into ~/.ultrastar/ or to
+one of the other folders that the game searches songs for. Run ultrastar from
+a terminal to see the list of folders.
+
+If your songs are not in UTF-8 (most songs aren't yet), please do:
+       recode CP1252..UTF-8 songs/*/*.txt
+
+After that make sure that all the characters display correctly. If they don't,
+you need to guess which charset the original used (instead of CP1252) and retry.
+
+If you want to improve the game, join our IRC channel #Performous (Freenode) and
+you'll get git write access.
+
+For more (up to date) information, see http://performous.org/
+
diff --git a/docs/doxygen.config b/docs/doxygen.config
new file mode 100644 (file)
index 0000000..960836b
--- /dev/null
@@ -0,0 +1,1522 @@
+# Doxyfile 1.5.8
+
+# This file describes the settings to be used by the documentation system
+# doxygen (www.doxygen.org) for a project
+#
+# All text after a hash (#) is considered a comment and will be ignored
+# The format is:
+#       TAG = value [value, ...]
+# For lists items can also be appended using:
+#       TAG += value [value, ...]
+# Values that contain spaces should be placed between quotes (" ")
+
+#---------------------------------------------------------------------------
+# Project related configuration options
+#---------------------------------------------------------------------------
+
+# This tag specifies the encoding used for all characters in the config file 
+# that follow. The default is UTF-8 which is also the encoding used for all 
+# text before the first occurrence of this tag. Doxygen uses libiconv (or the 
+# iconv built into libc) for the transcoding. See 
+# http://www.gnu.org/software/libiconv for the list of possible encodings.
+
+DOXYFILE_ENCODING      = UTF-8
+
+# The PROJECT_NAME tag is a single word (or a sequence of words surrounded 
+# by quotes) that should identify the project.
+
+PROJECT_NAME           = Performous
+
+# The PROJECT_NUMBER tag can be used to enter a project or revision number. 
+# This could be handy for archiving the generated documentation or 
+# if some version control system is used.
+
+PROJECT_NUMBER         = 
+
+# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) 
+# base path where the generated documentation will be put. 
+# If a relative path is entered, it will be relative to the location 
+# where doxygen was started. If left blank the current directory will be used.
+
+# the index file will be docs/doxygen/html/index.html
+# N.B: don't add docs/doxygen to git!
+OUTPUT_DIRECTORY       = docs/doxygen
+
+# If the CREATE_SUBDIRS tag is set to YES, then doxygen will create 
+# 4096 sub-directories (in 2 levels) under the output directory of each output 
+# format and will distribute the generated files over these directories. 
+# Enabling this option can be useful when feeding doxygen a huge amount of 
+# source files, where putting all generated files in the same directory would 
+# otherwise cause performance problems for the file system.
+
+CREATE_SUBDIRS         = NO
+
+# The OUTPUT_LANGUAGE tag is used to specify the language in which all 
+# documentation generated by doxygen is written. Doxygen will use this 
+# information to generate all constant output in the proper language. 
+# The default language is English, other supported languages are: 
+# Afrikaans, Arabic, Brazilian, Catalan, Chinese, Chinese-Traditional, 
+# Croatian, Czech, Danish, Dutch, Farsi, Finnish, French, German, Greek, 
+# Hungarian, Italian, Japanese, Japanese-en (Japanese with English messages), 
+# Korean, Korean-en, Lithuanian, Norwegian, Macedonian, Persian, Polish, 
+# Portuguese, Romanian, Russian, Serbian, Serbian-Cyrilic, Slovak, Slovene, 
+# Spanish, Swedish, and Ukrainian.
+
+OUTPUT_LANGUAGE        = English
+
+# If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will 
+# include brief member descriptions after the members that are listed in 
+# the file and class documentation (similar to JavaDoc). 
+# Set to NO to disable this.
+
+BRIEF_MEMBER_DESC      = YES
+
+# If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend 
+# the brief description of a member or function before the detailed description. 
+# Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the 
+# brief descriptions will be completely suppressed.
+
+REPEAT_BRIEF           = YES
+
+# This tag implements a quasi-intelligent brief description abbreviator 
+# that is used to form the text in various listings. Each string 
+# in this list, if found as the leading text of the brief description, will be 
+# stripped from the text and the result after processing the whole list, is 
+# used as the annotated text. Otherwise, the brief description is used as-is. 
+# If left blank, the following values are used ("$name" is automatically 
+# replaced with the name of the entity): "The $name class" "The $name widget" 
+# "The $name file" "is" "provides" "specifies" "contains" 
+# "represents" "a" "an" "the"
+
+ABBREVIATE_BRIEF       = 
+
+# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then 
+# Doxygen will generate a detailed section even if there is only a brief 
+# description.
+
+ALWAYS_DETAILED_SEC    = NO
+
+# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all 
+# inherited members of a class in the documentation of that class as if those 
+# members were ordinary class members. Constructors, destructors and assignment 
+# operators of the base classes will not be shown.
+
+INLINE_INHERITED_MEMB  = NO
+
+# If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full 
+# path before files name in the file list and in the header files. If set 
+# to NO the shortest path that makes the file name unique will be used.
+
+FULL_PATH_NAMES        = YES
+
+# If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag 
+# can be used to strip a user-defined part of the path. Stripping is 
+# only done if one of the specified strings matches the left-hand part of 
+# the path. The tag can be used to show relative paths in the file list. 
+# If left blank the directory from which doxygen is run is used as the 
+# path to strip.
+
+STRIP_FROM_PATH        = 
+
+# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of 
+# the path mentioned in the documentation of a class, which tells 
+# the reader which header file to include in order to use a class. 
+# If left blank only the name of the header file containing the class 
+# definition is used. Otherwise one should specify the include paths that 
+# are normally passed to the compiler using the -I flag.
+
+STRIP_FROM_INC_PATH    = 
+
+# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter 
+# (but less readable) file names. This can be useful is your file systems 
+# doesn't support long names like on DOS, Mac, or CD-ROM.
+
+SHORT_NAMES            = NO
+
+# If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen 
+# will interpret the first line (until the first dot) of a JavaDoc-style 
+# comment as the brief description. If set to NO, the JavaDoc 
+# comments will behave just like regular Qt-style comments 
+# (thus requiring an explicit @brief command for a brief description.)
+
+JAVADOC_AUTOBRIEF      = NO
+
+# If the QT_AUTOBRIEF tag is set to YES then Doxygen will 
+# interpret the first line (until the first dot) of a Qt-style 
+# comment as the brief description. If set to NO, the comments 
+# will behave just like regular Qt-style comments (thus requiring 
+# an explicit \brief command for a brief description.)
+
+QT_AUTOBRIEF           = YES
+
+# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen 
+# treat a multi-line C++ special comment block (i.e. a block of //! or /// 
+# comments) as a brief description. This used to be the default behaviour. 
+# The new default is to treat a multi-line C++ comment block as a detailed 
+# description. Set this tag to YES if you prefer the old behaviour instead.
+
+MULTILINE_CPP_IS_BRIEF = NO
+
+# If the INHERIT_DOCS tag is set to YES (the default) then an undocumented 
+# member inherits the documentation from any documented member that it 
+# re-implements.
+
+INHERIT_DOCS           = YES
+
+# If the SEPARATE_MEMBER_PAGES tag is set to YES, then doxygen will produce 
+# a new page for each member. If set to NO, the documentation of a member will 
+# be part of the file/class/namespace that contains it.
+
+SEPARATE_MEMBER_PAGES  = NO
+
+# The TAB_SIZE tag can be used to set the number of spaces in a tab. 
+# Doxygen uses this value to replace tabs by spaces in code fragments.
+
+TAB_SIZE               = 4
+
+# This tag can be used to specify a number of aliases that acts 
+# as commands in the documentation. An alias has the form "name=value". 
+# For example adding "sideeffect=\par Side Effects:\n" will allow you to 
+# put the command \sideeffect (or @sideeffect) in the documentation, which 
+# will result in a user-defined paragraph with heading "Side Effects:". 
+# You can put \n's in the value part of an alias to insert newlines.
+
+ALIASES                = 
+
+# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C 
+# sources only. Doxygen will then generate output that is more tailored for C. 
+# For instance, some of the names that are used will be different. The list 
+# of all members will be omitted, etc.
+
+OPTIMIZE_OUTPUT_FOR_C  = NO
+
+# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java 
+# sources only. Doxygen will then generate output that is more tailored for 
+# Java. For instance, namespaces will be presented as packages, qualified 
+# scopes will look different, etc.
+
+OPTIMIZE_OUTPUT_JAVA   = NO
+
+# Set the OPTIMIZE_FOR_FORTRAN tag to YES if your project consists of Fortran 
+# sources only. Doxygen will then generate output that is more tailored for 
+# Fortran.
+
+OPTIMIZE_FOR_FORTRAN   = NO
+
+# Set the OPTIMIZE_OUTPUT_VHDL tag to YES if your project consists of VHDL 
+# sources. Doxygen will then generate output that is tailored for 
+# VHDL.
+
+OPTIMIZE_OUTPUT_VHDL   = NO
+
+# Doxygen selects the parser to use depending on the extension of the files it parses. 
+# With this tag you can assign which parser to use for a given extension. 
+# Doxygen has a built-in mapping, but you can override or extend it using this tag. 
+# The format is ext=language, where ext is a file extension, and language is one of 
+# the parsers supported by doxygen: IDL, Java, Javascript, C#, C, C++, D, PHP, 
+# Objective-C, Python, Fortran, VHDL, C, C++. For instance to make doxygen treat 
+# .inc files as Fortran files (default is PHP), and .f files as C (default is Fortran), 
+# use: inc=Fortran f=C
+
+EXTENSION_MAPPING      = 
+
+# If you use STL classes (i.e. std::string, std::vector, etc.) but do not want 
+# to include (a tag file for) the STL sources as input, then you should 
+# set this tag to YES in order to let doxygen match functions declarations and 
+# definitions whose arguments contain STL classes (e.g. func(std::string); v.s. 
+# func(std::string) {}). This also make the inheritance and collaboration 
+# diagrams that involve STL classes more complete and accurate.
+
+BUILTIN_STL_SUPPORT    = YES
+
+# If you use Microsoft's C++/CLI language, you should set this option to YES to 
+# enable parsing support.
+
+CPP_CLI_SUPPORT        = NO
+
+# Set the SIP_SUPPORT tag to YES if your project consists of sip sources only. 
+# Doxygen will parse them like normal C++ but will assume all classes use public 
+# instead of private inheritance when no explicit protection keyword is present.
+
+SIP_SUPPORT            = NO
+
+# For Microsoft's IDL there are propget and propput attributes to indicate getter 
+# and setter methods for a property. Setting this option to YES (the default) 
+# will make doxygen to replace the get and set methods by a property in the 
+# documentation. This will only work if the methods are indeed getting or 
+# setting a simple type. If this is not the case, or you want to show the 
+# methods anyway, you should set this option to NO.
+
+IDL_PROPERTY_SUPPORT   = YES
+
+# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC 
+# tag is set to YES, then doxygen will reuse the documentation of the first 
+# member in the group (if any) for the other members of the group. By default 
+# all members of a group must be documented explicitly.
+
+DISTRIBUTE_GROUP_DOC   = NO
+
+# Set the SUBGROUPING tag to YES (the default) to allow class member groups of 
+# the same type (for instance a group of public functions) to be put as a 
+# subgroup of that type (e.g. under the Public Functions section). Set it to 
+# NO to prevent subgrouping. Alternatively, this can be done per class using 
+# the \nosubgrouping command.
+
+SUBGROUPING            = YES
+
+# When TYPEDEF_HIDES_STRUCT is enabled, a typedef of a struct, union, or enum 
+# is documented as struct, union, or enum with the name of the typedef. So 
+# typedef struct TypeS {} TypeT, will appear in the documentation as a struct 
+# with name TypeT. When disabled the typedef will appear as a member of a file, 
+# namespace, or class. And the struct will be named TypeS. This can typically 
+# be useful for C code in case the coding convention dictates that all compound 
+# types are typedef'ed and only the typedef is referenced, never the tag name.
+
+TYPEDEF_HIDES_STRUCT   = NO
+
+# The SYMBOL_CACHE_SIZE determines the size of the internal cache use to 
+# determine which symbols to keep in memory and which to flush to disk. 
+# When the cache is full, less often used symbols will be written to disk. 
+# For small to medium size projects (<1000 input files) the default value is 
+# probably good enough. For larger projects a too small cache size can cause 
+# doxygen to be busy swapping symbols to and from disk most of the time 
+# causing a significant performance penality. 
+# If the system has enough physical memory increasing the cache will improve the 
+# performance by keeping more symbols in memory. Note that the value works on 
+# a logarithmic scale so increasing the size by one will rougly double the 
+# memory usage. The cache size is given by this formula: 
+# 2^(16+SYMBOL_CACHE_SIZE). The valid range is 0..9, the default is 0, 
+# corresponding to a cache size of 2^16 = 65536 symbols
+
+SYMBOL_CACHE_SIZE      = 0
+
+#---------------------------------------------------------------------------
+# Build related configuration options
+#---------------------------------------------------------------------------
+
+# If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in 
+# documentation are documented, even if no documentation was available. 
+# Private class members and static file members will be hidden unless 
+# the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES
+
+EXTRACT_ALL            = YES
+
+# If the EXTRACT_PRIVATE tag is set to YES all private members of a class 
+# will be included in the documentation.
+
+EXTRACT_PRIVATE        = YES
+
+# If the EXTRACT_STATIC tag is set to YES all static members of a file 
+# will be included in the documentation.
+
+EXTRACT_STATIC         = YES
+
+# If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs) 
+# defined locally in source files will be included in the documentation. 
+# If set to NO only classes defined in header files are included.
+
+EXTRACT_LOCAL_CLASSES  = YES
+
+# This flag is only useful for Objective-C code. When set to YES local 
+# methods, which are defined in the implementation section but not in 
+# the interface are included in the documentation. 
+# If set to NO (the default) only methods in the interface are included.
+
+EXTRACT_LOCAL_METHODS  = NO
+
+# If this flag is set to YES, the members of anonymous namespaces will be 
+# extracted and appear in the documentation as a namespace called 
+# 'anonymous_namespace{file}', where file will be replaced with the base 
+# name of the file that contains the anonymous namespace. By default 
+# anonymous namespace are hidden.
+
+EXTRACT_ANON_NSPACES   = YES
+
+# If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all 
+# undocumented members of documented classes, files or namespaces. 
+# If set to NO (the default) these members will be included in the 
+# various overviews, but no documentation section is generated. 
+# This option has no effect if EXTRACT_ALL is enabled.
+
+HIDE_UNDOC_MEMBERS     = NO
+
+# If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all 
+# undocumented classes that are normally visible in the class hierarchy. 
+# If set to NO (the default) these classes will be included in the various 
+# overviews. This option has no effect if EXTRACT_ALL is enabled.
+
+HIDE_UNDOC_CLASSES     = NO
+
+# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all 
+# friend (class|struct|union) declarations. 
+# If set to NO (the default) these declarations will be included in the 
+# documentation.
+
+HIDE_FRIEND_COMPOUNDS  = NO
+
+# If the HIDE_IN_BODY_DOCS tag is set to YES, Doxygen will hide any 
+# documentation blocks found inside the body of a function. 
+# If set to NO (the default) these blocks will be appended to the 
+# function's detailed documentation block.
+
+HIDE_IN_BODY_DOCS      = NO
+
+# The INTERNAL_DOCS tag determines if documentation 
+# that is typed after a \internal command is included. If the tag is set 
+# to NO (the default) then the documentation will be excluded. 
+# Set it to YES to include the internal documentation.
+
+INTERNAL_DOCS          = YES
+
+# If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate 
+# file names in lower-case letters. If set to YES upper-case letters are also 
+# allowed. This is useful if you have classes or files whose names only differ 
+# in case and if your file system supports case sensitive file names. Windows 
+# and Mac users are advised to set this option to NO.
+
+CASE_SENSE_NAMES       = YES
+
+# If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen 
+# will show members with their full class and namespace scopes in the 
+# documentation. If set to YES the scope will be hidden.
+
+HIDE_SCOPE_NAMES       = NO
+
+# If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen 
+# will put a list of the files that are included by a file in the documentation 
+# of that file.
+
+SHOW_INCLUDE_FILES     = YES
+
+# If the INLINE_INFO tag is set to YES (the default) then a tag [inline] 
+# is inserted in the documentation for inline members.
+
+INLINE_INFO            = YES
+
+# If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen 
+# will sort the (detailed) documentation of file and class members 
+# alphabetically by member name. If set to NO the members will appear in 
+# declaration order.
+
+SORT_MEMBER_DOCS       = YES
+
+# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the 
+# brief documentation of file, namespace and class members alphabetically 
+# by member name. If set to NO (the default) the members will appear in 
+# declaration order.
+
+SORT_BRIEF_DOCS        = YES
+
+# If the SORT_GROUP_NAMES tag is set to YES then doxygen will sort the 
+# hierarchy of group names into alphabetical order. If set to NO (the default) 
+# the group names will appear in their defined order.
+
+SORT_GROUP_NAMES       = YES
+
+# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be 
+# sorted by fully-qualified names, including namespaces. If set to 
+# NO (the default), the class list will be sorted only by class name, 
+# not including the namespace part. 
+# Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES. 
+# Note: This option applies only to the class list, not to the 
+# alphabetical list.
+
+SORT_BY_SCOPE_NAME     = YES
+
+# The GENERATE_TODOLIST tag can be used to enable (YES) or 
+# disable (NO) the todo list. This list is created by putting \todo 
+# commands in the documentation.
+
+GENERATE_TODOLIST      = YES
+
+# The GENERATE_TESTLIST tag can be used to enable (YES) or 
+# disable (NO) the test list. This list is created by putting \test 
+# commands in the documentation.
+
+GENERATE_TESTLIST      = YES
+
+# The GENERATE_BUGLIST tag can be used to enable (YES) or 
+# disable (NO) the bug list. This list is created by putting \bug 
+# commands in the documentation.
+
+GENERATE_BUGLIST       = YES
+
+# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or 
+# disable (NO) the deprecated list. This list is created by putting 
+# \deprecated commands in the documentation.
+
+GENERATE_DEPRECATEDLIST= YES
+
+# The ENABLED_SECTIONS tag can be used to enable conditional 
+# documentation sections, marked by \if sectionname ... \endif.
+
+ENABLED_SECTIONS       = 
+
+# The MAX_INITIALIZER_LINES tag determines the maximum number of lines 
+# the initial value of a variable or define consists of for it to appear in 
+# the documentation. If the initializer consists of more lines than specified 
+# here it will be hidden. Use a value of 0 to hide initializers completely. 
+# The appearance of the initializer of individual variables and defines in the 
+# documentation can be controlled using \showinitializer or \hideinitializer 
+# command in the documentation regardless of this setting.
+
+MAX_INITIALIZER_LINES  = 30
+
+# Set the SHOW_USED_FILES tag to NO to disable the list of files generated 
+# at the bottom of the documentation of classes and structs. If set to YES the 
+# list will mention the files that were used to generate the documentation.
+
+SHOW_USED_FILES        = YES
+
+# If the sources in your project are distributed over multiple directories 
+# then setting the SHOW_DIRECTORIES tag to YES will show the directory hierarchy 
+# in the documentation. The default is NO.
+
+SHOW_DIRECTORIES       = YES
+
+# Set the SHOW_FILES tag to NO to disable the generation of the Files page. 
+# This will remove the Files entry from the Quick Index and from the 
+# Folder Tree View (if specified). The default is YES.
+
+SHOW_FILES             = YES
+
+# Set the SHOW_NAMESPACES tag to NO to disable the generation of the 
+# Namespaces page. 
+# This will remove the Namespaces entry from the Quick Index 
+# and from the Folder Tree View (if specified). The default is YES.
+
+SHOW_NAMESPACES        = YES
+
+# The FILE_VERSION_FILTER tag can be used to specify a program or script that 
+# doxygen should invoke to get the current version for each file (typically from 
+# the version control system). Doxygen will invoke the program by executing (via 
+# popen()) the command <command> <input-file>, where <command> is the value of 
+# the FILE_VERSION_FILTER tag, and <input-file> is the name of an input file 
+# provided by doxygen. Whatever the program writes to standard output 
+# is used as the file version. See the manual for examples.
+
+FILE_VERSION_FILTER    = 
+
+# The LAYOUT_FILE tag can be used to specify a layout file which will be parsed by 
+# doxygen. The layout file controls the global structure of the generated output files 
+# in an output format independent way. The create the layout file that represents 
+# doxygen's defaults, run doxygen with the -l option. You can optionally specify a 
+# file name after the option, if omitted DoxygenLayout.xml will be used as the name 
+# of the layout file.
+
+LAYOUT_FILE            = 
+
+#---------------------------------------------------------------------------
+# configuration options related to warning and progress messages
+#---------------------------------------------------------------------------
+
+# The QUIET tag can be used to turn on/off the messages that are generated 
+# by doxygen. Possible values are YES and NO. If left blank NO is used.
+
+QUIET                  = YES
+
+# The WARNINGS tag can be used to turn on/off the warning messages that are 
+# generated by doxygen. Possible values are YES and NO. If left blank 
+# NO is used.
+
+WARNINGS               = YES
+
+# If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings 
+# for undocumented members. If EXTRACT_ALL is set to YES then this flag will 
+# automatically be disabled.
+
+WARN_IF_UNDOCUMENTED   = YES
+
+# If WARN_IF_DOC_ERROR is set to YES, doxygen will generate warnings for 
+# potential errors in the documentation, such as not documenting some 
+# parameters in a documented function, or documenting parameters that 
+# don't exist or using markup commands wrongly.
+
+WARN_IF_DOC_ERROR      = YES
+
+# This WARN_NO_PARAMDOC option can be abled to get warnings for 
+# functions that are documented, but have no documentation for their parameters 
+# or return value. If set to NO (the default) doxygen will only warn about 
+# wrong or incomplete parameter documentation, but not about the absence of 
+# documentation.
+
+WARN_NO_PARAMDOC       = YES
+
+# The WARN_FORMAT tag determines the format of the warning messages that 
+# doxygen can produce. The string should contain the $file, $line, and $text 
+# tags, which will be replaced by the file and line number from which the 
+# warning originated and the warning text. Optionally the format may contain 
+# $version, which will be replaced by the version of the file (if it could 
+# be obtained via FILE_VERSION_FILTER)
+
+WARN_FORMAT            = "$file:$line: $text"
+
+# The WARN_LOGFILE tag can be used to specify a file to which warning 
+# and error messages should be written. If left blank the output is written 
+# to stderr.
+
+WARN_LOGFILE           = 
+
+#---------------------------------------------------------------------------
+# configuration options related to the input files
+#---------------------------------------------------------------------------
+
+# The INPUT tag can be used to specify the files and/or directories that contain 
+# documented source files. You may enter file names like "myfile.cpp" or 
+# directories like "/usr/src/myproject". Separate the files or directories 
+# with spaces.
+
+INPUT                  = 
+
+# This tag can be used to specify the character encoding of the source files 
+# that doxygen parses. Internally doxygen uses the UTF-8 encoding, which is 
+# also the default input encoding. Doxygen uses libiconv (or the iconv built 
+# into libc) for the transcoding. See http://www.gnu.org/software/libiconv for 
+# the list of possible encodings.
+
+INPUT_ENCODING         = UTF-8
+
+# If the value of the INPUT tag contains directories, you can use the 
+# FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp 
+# and *.h) to filter out the source-files in the directories. If left 
+# blank the following patterns are tested: 
+# *.c *.cc *.cxx *.cpp *.c++ *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh *.hxx 
+# *.hpp *.h++ *.idl *.odl *.cs *.php *.php3 *.inc *.m *.mm *.py *.f90
+
+#FILE_PATTERNS          = *.cc *.hh *.c *.h *.txt
+FILE_PATTERNS          = 
+
+# The RECURSIVE tag can be used to turn specify whether or not subdirectories 
+# should be searched for input files as well. Possible values are YES and NO. 
+# If left blank NO is used.
+
+RECURSIVE              = YES
+
+# The EXCLUDE tag can be used to specify files and/or directories that should 
+# excluded from the INPUT source files. This way you can easily exclude a 
+# subdirectory from a directory tree whose root is specified with the INPUT tag.
+
+# Exclude the build directory, lest we get config.h file pollution
+EXCLUDE                = build
+
+# The EXCLUDE_SYMLINKS tag can be used select whether or not files or 
+# directories that are symbolic links (a Unix filesystem feature) are excluded 
+# from the input.
+
+EXCLUDE_SYMLINKS       = NO
+
+# If the value of the INPUT tag contains directories, you can use the 
+# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude 
+# certain files from those directories. Note that the wildcards are matched 
+# against the file with absolute path, so to exclude all test directories 
+# for example use the pattern */test/*
+
+EXCLUDE_PATTERNS       = 
+
+# The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names 
+# (namespaces, classes, functions, etc.) that should be excluded from the 
+# output. The symbol name can be a fully qualified name, a word, or if the 
+# wildcard * is used, a substring. Examples: ANamespace, AClass, 
+# AClass::ANamespace, ANamespace::*Test
+
+EXCLUDE_SYMBOLS        = 
+
+# The EXAMPLE_PATH tag can be used to specify one or more files or 
+# directories that contain example code fragments that are included (see 
+# the \include command).
+
+EXAMPLE_PATH           = 
+
+# If the value of the EXAMPLE_PATH tag contains directories, you can use the 
+# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp 
+# and *.h) to filter out the source-files in the directories. If left 
+# blank all files are included.
+
+EXAMPLE_PATTERNS       = 
+
+# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be 
+# searched for input files to be used with the \include or \dontinclude 
+# commands irrespective of the value of the RECURSIVE tag. 
+# Possible values are YES and NO. If left blank NO is used.
+
+EXAMPLE_RECURSIVE      = NO
+
+# The IMAGE_PATH tag can be used to specify one or more files or 
+# directories that contain image that are included in the documentation (see 
+# the \image command).
+
+IMAGE_PATH             = 
+
+# The INPUT_FILTER tag can be used to specify a program that doxygen should 
+# invoke to filter for each input file. Doxygen will invoke the filter program 
+# by executing (via popen()) the command <filter> <input-file>, where <filter> 
+# is the value of the INPUT_FILTER tag, and <input-file> is the name of an 
+# input file. Doxygen will then use the output that the filter program writes 
+# to standard output. 
+# If FILTER_PATTERNS is specified, this tag will be 
+# ignored.
+
+INPUT_FILTER           = 
+
+# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern 
+# basis. 
+# Doxygen will compare the file name with each pattern and apply the 
+# filter if there is a match. 
+# The filters are a list of the form: 
+# pattern=filter (like *.cpp=my_cpp_filter). See INPUT_FILTER for further 
+# info on how filters are used. If FILTER_PATTERNS is empty, INPUT_FILTER 
+# is applied to all files.
+
+FILTER_PATTERNS        = 
+
+# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using 
+# INPUT_FILTER) will be used to filter the input files when producing source 
+# files to browse (i.e. when SOURCE_BROWSER is set to YES).
+
+FILTER_SOURCE_FILES    = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to source browsing
+#---------------------------------------------------------------------------
+
+# If the SOURCE_BROWSER tag is set to YES then a list of source files will 
+# be generated. Documented entities will be cross-referenced with these sources. 
+# Note: To get rid of all source code in the generated output, make sure also 
+# VERBATIM_HEADERS is set to NO.
+
+SOURCE_BROWSER         = YES
+
+# Setting the INLINE_SOURCES tag to YES will include the body 
+# of functions and classes directly in the documentation.
+
+INLINE_SOURCES         = NO
+
+# Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct 
+# doxygen to hide any special comment blocks from generated source code 
+# fragments. Normal C and C++ comments will always remain visible.
+
+STRIP_CODE_COMMENTS    = YES
+
+# If the REFERENCED_BY_RELATION tag is set to YES 
+# then for each documented function all documented 
+# functions referencing it will be listed.
+
+REFERENCED_BY_RELATION = NO
+
+# If the REFERENCES_RELATION tag is set to YES 
+# then for each documented function all documented entities 
+# called/used by that function will be listed.
+
+REFERENCES_RELATION    = NO
+
+# If the REFERENCES_LINK_SOURCE tag is set to YES (the default) 
+# and SOURCE_BROWSER tag is set to YES, then the hyperlinks from 
+# functions in REFERENCES_RELATION and REFERENCED_BY_RELATION lists will 
+# link to the source code. 
+# Otherwise they will link to the documentation.
+
+REFERENCES_LINK_SOURCE = YES
+
+# If the USE_HTAGS tag is set to YES then the references to source code 
+# will point to the HTML generated by the htags(1) tool instead of doxygen 
+# built-in source browser. The htags tool is part of GNU's global source 
+# tagging system (see http://www.gnu.org/software/global/global.html). You 
+# will need version 4.8.6 or higher.
+
+USE_HTAGS              = NO
+
+# If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen 
+# will generate a verbatim copy of the header file for each class for 
+# which an include is specified. Set to NO to disable this.
+
+VERBATIM_HEADERS       = YES
+
+#---------------------------------------------------------------------------
+# configuration options related to the alphabetical class index
+#---------------------------------------------------------------------------
+
+# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index 
+# of all compounds will be generated. Enable this if the project 
+# contains a lot of classes, structs, unions or interfaces.
+
+ALPHABETICAL_INDEX     = YES
+
+# If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then 
+# the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns 
+# in which this list will be split (can be a number in the range [1..20])
+
+COLS_IN_ALPHA_INDEX    = 5
+
+# In case all classes in a project start with a common prefix, all 
+# classes will be put under the same header in the alphabetical index. 
+# The IGNORE_PREFIX tag can be used to specify one or more prefixes that 
+# should be ignored while generating the index headers.
+
+IGNORE_PREFIX          = 
+
+#---------------------------------------------------------------------------
+# configuration options related to the HTML output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_HTML tag is set to YES (the default) Doxygen will 
+# generate HTML output.
+
+GENERATE_HTML          = YES
+
+# The HTML_OUTPUT tag is used to specify where the HTML docs will be put. 
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be 
+# put in front of it. If left blank `html' will be used as the default path.
+
+HTML_OUTPUT            = html
+
+# The HTML_FILE_EXTENSION tag can be used to specify the file extension for 
+# each generated HTML page (for example: .htm,.php,.asp). If it is left blank 
+# doxygen will generate files with .html extension.
+
+HTML_FILE_EXTENSION    = .html
+
+# The HTML_HEADER tag can be used to specify a personal HTML header for 
+# each generated HTML page. If it is left blank doxygen will generate a 
+# standard header.
+
+HTML_HEADER            = 
+
+# The HTML_FOOTER tag can be used to specify a personal HTML footer for 
+# each generated HTML page. If it is left blank doxygen will generate a 
+# standard footer.
+
+HTML_FOOTER            = 
+
+# The HTML_STYLESHEET tag can be used to specify a user-defined cascading 
+# style sheet that is used by each HTML page. It can be used to 
+# fine-tune the look of the HTML output. If the tag is left blank doxygen 
+# will generate a default style sheet. Note that doxygen will try to copy 
+# the style sheet file to the HTML output directory, so don't put your own 
+# stylesheet in the HTML output directory as well, or it will be erased!
+
+HTML_STYLESHEET        = 
+
+# If the HTML_ALIGN_MEMBERS tag is set to YES, the members of classes, 
+# files or namespaces will be aligned in HTML using tables. If set to 
+# NO a bullet list will be used.
+
+HTML_ALIGN_MEMBERS     = YES
+
+# If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML 
+# documentation will contain sections that can be hidden and shown after the 
+# page has loaded. For this to work a browser that supports 
+# JavaScript and DHTML is required (for instance Mozilla 1.0+, Firefox 
+# Netscape 6.0+, Internet explorer 5.0+, Konqueror, or Safari).
+
+HTML_DYNAMIC_SECTIONS  = YES
+
+# If the GENERATE_DOCSET tag is set to YES, additional index files 
+# will be generated that can be used as input for Apple's Xcode 3 
+# integrated development environment, introduced with OSX 10.5 (Leopard). 
+# To create a documentation set, doxygen will generate a Makefile in the 
+# HTML output directory. Running make will produce the docset in that 
+# directory and running "make install" will install the docset in 
+# ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find 
+# it at startup. 
+# See http://developer.apple.com/tools/creatingdocsetswithdoxygen.html for more information.
+
+GENERATE_DOCSET        = NO
+
+# When GENERATE_DOCSET tag is set to YES, this tag determines the name of the 
+# feed. A documentation feed provides an umbrella under which multiple 
+# documentation sets from a single provider (such as a company or product suite) 
+# can be grouped.
+
+DOCSET_FEEDNAME        = "Doxygen generated docs"
+
+# When GENERATE_DOCSET tag is set to YES, this tag specifies a string that 
+# should uniquely identify the documentation set bundle. This should be a 
+# reverse domain-name style string, e.g. com.mycompany.MyDocSet. Doxygen 
+# will append .docset to the name.
+
+DOCSET_BUNDLE_ID       = org.doxygen.Project
+
+# If the GENERATE_HTMLHELP tag is set to YES, additional index files 
+# will be generated that can be used as input for tools like the 
+# Microsoft HTML help workshop to generate a compiled HTML help file (.chm) 
+# of the generated HTML documentation.
+
+GENERATE_HTMLHELP      = NO
+
+# If the GENERATE_HTMLHELP tag is set to YES, the CHM_FILE tag can 
+# be used to specify the file name of the resulting .chm file. You 
+# can add a path in front of the file if the result should not be 
+# written to the html output directory.
+
+CHM_FILE               = 
+
+# If the GENERATE_HTMLHELP tag is set to YES, the HHC_LOCATION tag can 
+# be used to specify the location (absolute path including file name) of 
+# the HTML help compiler (hhc.exe). If non-empty doxygen will try to run 
+# the HTML help compiler on the generated index.hhp.
+
+HHC_LOCATION           = 
+
+# If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag 
+# controls if a separate .chi index file is generated (YES) or that 
+# it should be included in the master .chm file (NO).
+
+GENERATE_CHI           = NO
+
+# If the GENERATE_HTMLHELP tag is set to YES, the CHM_INDEX_ENCODING 
+# is used to encode HtmlHelp index (hhk), content (hhc) and project file 
+# content.
+
+CHM_INDEX_ENCODING     = 
+
+# If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag 
+# controls whether a binary table of contents is generated (YES) or a 
+# normal table of contents (NO) in the .chm file.
+
+BINARY_TOC             = NO
+
+# The TOC_EXPAND flag can be set to YES to add extra items for group members 
+# to the contents of the HTML help documentation and to the tree view.
+
+TOC_EXPAND             = NO
+
+# If the GENERATE_QHP tag is set to YES and both QHP_NAMESPACE and QHP_VIRTUAL_FOLDER 
+# are set, an additional index file will be generated that can be used as input for 
+# Qt's qhelpgenerator to generate a Qt Compressed Help (.qch) of the generated 
+# HTML documentation.
+
+GENERATE_QHP           = NO
+
+# If the QHG_LOCATION tag is specified, the QCH_FILE tag can 
+# be used to specify the file name of the resulting .qch file. 
+# The path specified is relative to the HTML output folder.
+
+QCH_FILE               = 
+
+# The QHP_NAMESPACE tag specifies the namespace to use when generating 
+# Qt Help Project output. For more information please see 
+# http://doc.trolltech.com/qthelpproject.html#namespace
+
+QHP_NAMESPACE          = 
+
+# The QHP_VIRTUAL_FOLDER tag specifies the namespace to use when generating 
+# Qt Help Project output. For more information please see 
+# http://doc.trolltech.com/qthelpproject.html#virtual-folders
+
+QHP_VIRTUAL_FOLDER     = doc
+
+# If QHP_CUST_FILTER_NAME is set, it specifies the name of a custom filter to add. 
+# For more information please see 
+# http://doc.trolltech.com/qthelpproject.html#custom-filters
+
+QHP_CUST_FILTER_NAME   = 
+
+# The QHP_CUST_FILT_ATTRS tag specifies the list of the attributes of the custom filter to add.For more information please see 
+# <a href="http://doc.trolltech.com/qthelpproject.html#custom-filters">Qt Help Project / Custom Filters</a>.
+
+QHP_CUST_FILTER_ATTRS  = 
+
+# The QHP_SECT_FILTER_ATTRS tag specifies the list of the attributes this project's 
+# filter section matches. 
+# <a href="http://doc.trolltech.com/qthelpproject.html#filter-attributes">Qt Help Project / Filter Attributes</a>.
+
+QHP_SECT_FILTER_ATTRS  = 
+
+# If the GENERATE_QHP tag is set to YES, the QHG_LOCATION tag can 
+# be used to specify the location of Qt's qhelpgenerator. 
+# If non-empty doxygen will try to run qhelpgenerator on the generated 
+# .qhp file.
+
+QHG_LOCATION           = 
+
+# The DISABLE_INDEX tag can be used to turn on/off the condensed index at 
+# top of each HTML page. The value NO (the default) enables the index and 
+# the value YES disables it.
+
+DISABLE_INDEX          = NO
+
+# This tag can be used to set the number of enum values (range [1..20]) 
+# that doxygen will group on one line in the generated HTML documentation.
+
+ENUM_VALUES_PER_LINE   = 4
+
+# The GENERATE_TREEVIEW tag is used to specify whether a tree-like index 
+# structure should be generated to display hierarchical information. 
+# If the tag value is set to FRAME, a side panel will be generated 
+# containing a tree-like index structure (just like the one that 
+# is generated for HTML Help). For this to work a browser that supports 
+# JavaScript, DHTML, CSS and frames is required (for instance Mozilla 1.0+, 
+# Netscape 6.0+, Internet explorer 5.0+, or Konqueror). Windows users are 
+# probably better off using the HTML help feature. Other possible values 
+# for this tag are: HIERARCHIES, which will generate the Groups, Directories, 
+# and Class Hierarchy pages using a tree view instead of an ordered list; 
+# ALL, which combines the behavior of FRAME and HIERARCHIES; and NONE, which 
+# disables this behavior completely. For backwards compatibility with previous 
+# releases of Doxygen, the values YES and NO are equivalent to FRAME and NONE 
+# respectively.
+
+#GENERATE_TREEVIEW      = FRAME
+GENERATE_TREEVIEW      = ALL
+
+# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be 
+# used to set the initial width (in pixels) of the frame in which the tree 
+# is shown.
+
+TREEVIEW_WIDTH         = 250
+
+# Use this tag to change the font size of Latex formulas included 
+# as images in the HTML documentation. The default is 10. Note that 
+# when you change the font size after a successful doxygen run you need 
+# to manually remove any form_*.png images from the HTML output directory 
+# to force them to be regenerated.
+
+FORMULA_FONTSIZE       = 10
+
+#---------------------------------------------------------------------------
+# configuration options related to the LaTeX output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_LATEX tag is set to YES (the default) Doxygen will 
+# generate Latex output.
+
+GENERATE_LATEX         = NO
+
+# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. 
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be 
+# put in front of it. If left blank `latex' will be used as the default path.
+
+LATEX_OUTPUT           = latex
+
+# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be 
+# invoked. If left blank `latex' will be used as the default command name.
+
+LATEX_CMD_NAME         = latex
+
+# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to 
+# generate index for LaTeX. If left blank `makeindex' will be used as the 
+# default command name.
+
+MAKEINDEX_CMD_NAME     = makeindex
+
+# If the COMPACT_LATEX tag is set to YES Doxygen generates more compact 
+# LaTeX documents. This may be useful for small projects and may help to 
+# save some trees in general.
+
+COMPACT_LATEX          = NO
+
+# The PAPER_TYPE tag can be used to set the paper type that is used 
+# by the printer. Possible values are: a4, a4wide, letter, legal and 
+# executive. If left blank a4wide will be used.
+
+PAPER_TYPE             = a4wide
+
+# The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX 
+# packages that should be included in the LaTeX output.
+
+EXTRA_PACKAGES         = 
+
+# The LATEX_HEADER tag can be used to specify a personal LaTeX header for 
+# the generated latex document. The header should contain everything until 
+# the first chapter. If it is left blank doxygen will generate a 
+# standard header. Notice: only use this tag if you know what you are doing!
+
+LATEX_HEADER           = 
+
+# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated 
+# is prepared for conversion to pdf (using ps2pdf). The pdf file will 
+# contain links (just like the HTML output) instead of page references 
+# This makes the output suitable for online browsing using a pdf viewer.
+
+PDF_HYPERLINKS         = YES
+
+# If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of 
+# plain latex in the generated Makefile. Set this option to YES to get a 
+# higher quality PDF documentation.
+
+USE_PDFLATEX           = YES
+
+# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode. 
+# command to the generated LaTeX files. This will instruct LaTeX to keep 
+# running if errors occur, instead of asking the user for help. 
+# This option is also used when generating formulas in HTML.
+
+LATEX_BATCHMODE        = NO
+
+# If LATEX_HIDE_INDICES is set to YES then doxygen will not 
+# include the index chapters (such as File Index, Compound Index, etc.) 
+# in the output.
+
+LATEX_HIDE_INDICES     = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to the RTF output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output 
+# The RTF output is optimized for Word 97 and may not look very pretty with 
+# other RTF readers or editors.
+
+GENERATE_RTF           = NO
+
+# The RTF_OUTPUT tag is used to specify where the RTF docs will be put. 
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be 
+# put in front of it. If left blank `rtf' will be used as the default path.
+
+RTF_OUTPUT             = rtf
+
+# If the COMPACT_RTF tag is set to YES Doxygen generates more compact 
+# RTF documents. This may be useful for small projects and may help to 
+# save some trees in general.
+
+COMPACT_RTF            = NO
+
+# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated 
+# will contain hyperlink fields. The RTF file will 
+# contain links (just like the HTML output) instead of page references. 
+# This makes the output suitable for online browsing using WORD or other 
+# programs which support those fields. 
+# Note: wordpad (write) and others do not support links.
+
+RTF_HYPERLINKS         = NO
+
+# Load stylesheet definitions from file. Syntax is similar to doxygen's 
+# config file, i.e. a series of assignments. You only have to provide 
+# replacements, missing definitions are set to their default value.
+
+RTF_STYLESHEET_FILE    = 
+
+# Set optional variables used in the generation of an rtf document. 
+# Syntax is similar to doxygen's config file.
+
+RTF_EXTENSIONS_FILE    = 
+
+#---------------------------------------------------------------------------
+# configuration options related to the man page output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_MAN tag is set to YES (the default) Doxygen will 
+# generate man pages
+
+GENERATE_MAN           = NO
+
+# The MAN_OUTPUT tag is used to specify where the man pages will be put. 
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be 
+# put in front of it. If left blank `man' will be used as the default path.
+
+MAN_OUTPUT             = man
+
+# The MAN_EXTENSION tag determines the extension that is added to 
+# the generated man pages (default is the subroutine's section .3)
+
+MAN_EXTENSION          = .3
+
+# If the MAN_LINKS tag is set to YES and Doxygen generates man output, 
+# then it will generate one additional man file for each entity 
+# documented in the real man page(s). These additional files 
+# only source the real man page, but without them the man command 
+# would be unable to find the correct page. The default is NO.
+
+MAN_LINKS              = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to the XML output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_XML tag is set to YES Doxygen will 
+# generate an XML file that captures the structure of 
+# the code including all documentation.
+
+GENERATE_XML           = NO
+
+# The XML_OUTPUT tag is used to specify where the XML pages will be put. 
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be 
+# put in front of it. If left blank `xml' will be used as the default path.
+
+XML_OUTPUT             = xml
+
+# The XML_SCHEMA tag can be used to specify an XML schema, 
+# which can be used by a validating XML parser to check the 
+# syntax of the XML files.
+
+XML_SCHEMA             = 
+
+# The XML_DTD tag can be used to specify an XML DTD, 
+# which can be used by a validating XML parser to check the 
+# syntax of the XML files.
+
+XML_DTD                = 
+
+# If the XML_PROGRAMLISTING tag is set to YES Doxygen will 
+# dump the program listings (including syntax highlighting 
+# and cross-referencing information) to the XML output. Note that 
+# enabling this will significantly increase the size of the XML output.
+
+XML_PROGRAMLISTING     = YES
+
+#---------------------------------------------------------------------------
+# configuration options for the AutoGen Definitions output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_AUTOGEN_DEF tag is set to YES Doxygen will 
+# generate an AutoGen Definitions (see autogen.sf.net) file 
+# that captures the structure of the code including all 
+# documentation. Note that this feature is still experimental 
+# and incomplete at the moment.
+
+GENERATE_AUTOGEN_DEF   = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to the Perl module output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_PERLMOD tag is set to YES Doxygen will 
+# generate a Perl module file that captures the structure of 
+# the code including all documentation. Note that this 
+# feature is still experimental and incomplete at the 
+# moment.
+
+GENERATE_PERLMOD       = NO
+
+# If the PERLMOD_LATEX tag is set to YES Doxygen will generate 
+# the necessary Makefile rules, Perl scripts and LaTeX code to be able 
+# to generate PDF and DVI output from the Perl module output.
+
+PERLMOD_LATEX          = NO
+
+# If the PERLMOD_PRETTY tag is set to YES the Perl module output will be 
+# nicely formatted so it can be parsed by a human reader. 
+# This is useful 
+# if you want to understand what is going on. 
+# On the other hand, if this 
+# tag is set to NO the size of the Perl module output will be much smaller 
+# and Perl will parse it just the same.
+
+PERLMOD_PRETTY         = YES
+
+# The names of the make variables in the generated doxyrules.make file 
+# are prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX. 
+# This is useful so different doxyrules.make files included by the same 
+# Makefile don't overwrite each other's variables.
+
+PERLMOD_MAKEVAR_PREFIX = 
+
+#---------------------------------------------------------------------------
+# Configuration options related to the preprocessor   
+#---------------------------------------------------------------------------
+
+# If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will 
+# evaluate all C-preprocessor directives found in the sources and include 
+# files.
+
+ENABLE_PREPROCESSING   = YES
+
+# If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro 
+# names in the source code. If set to NO (the default) only conditional 
+# compilation will be performed. Macro expansion can be done in a controlled 
+# way by setting EXPAND_ONLY_PREDEF to YES.
+
+MACRO_EXPANSION        = NO
+
+# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES 
+# then the macro expansion is limited to the macros specified with the 
+# PREDEFINED and EXPAND_AS_DEFINED tags.
+
+EXPAND_ONLY_PREDEF     = NO
+
+# If the SEARCH_INCLUDES tag is set to YES (the default) the includes files 
+# in the INCLUDE_PATH (see below) will be search if a #include is found.
+
+SEARCH_INCLUDES        = YES
+
+# The INCLUDE_PATH tag can be used to specify one or more directories that 
+# contain include files that are not input files but should be processed by 
+# the preprocessor.
+
+INCLUDE_PATH           = /usr/include/qt4
+
+# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard 
+# patterns (like *.h and *.hpp) to filter out the header-files in the 
+# directories. If left blank, the patterns specified with FILE_PATTERNS will 
+# be used.
+
+INCLUDE_FILE_PATTERNS  = *.h *.hpp
+
+# The PREDEFINED tag can be used to specify one or more macro names that 
+# are defined before the preprocessor is started (similar to the -D option of 
+# gcc). The argument of the tag is a list of macros of the form: name 
+# or name=definition (no spaces). If the definition and the = are 
+# omitted =1 is assumed. To prevent a macro definition from being 
+# undefined via #undef or recursively expanded use the := operator 
+# instead of the = operator.
+
+PREDEFINED             = 
+
+# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then 
+# this tag can be used to specify a list of macro names that should be expanded. 
+# The macro definition that is found in the sources will be used. 
+# Use the PREDEFINED tag if you want to use a different macro definition.
+
+EXPAND_AS_DEFINED      = 
+
+# If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then 
+# doxygen's preprocessor will remove all function-like macros that are alone 
+# on a line, have an all uppercase name, and do not end with a semicolon. Such 
+# function macros are typically used for boiler-plate code, and will confuse 
+# the parser if not removed.
+
+SKIP_FUNCTION_MACROS   = YES
+
+#---------------------------------------------------------------------------
+# Configuration::additions related to external references   
+#---------------------------------------------------------------------------
+
+# The TAGFILES option can be used to specify one or more tagfiles. 
+# Optionally an initial location of the external documentation 
+# can be added for each tagfile. The format of a tag file without 
+# this location is as follows: 
+#  
+# TAGFILES = file1 file2 ... 
+# Adding location for the tag files is done as follows: 
+#  
+# TAGFILES = file1=loc1 "file2 = loc2" ... 
+# where "loc1" and "loc2" can be relative or absolute paths or 
+# URLs. If a location is present for each tag, the installdox tool 
+# does not have to be run to correct the links. 
+# Note that each tag file must have a unique name 
+# (where the name does NOT include the path) 
+# If a tag file is not located in the directory in which doxygen 
+# is run, you must also specify the path to the tagfile here.
+
+TAGFILES               = 
+
+# When a file name is specified after GENERATE_TAGFILE, doxygen will create 
+# a tag file that is based on the input files it reads.
+
+GENERATE_TAGFILE       = 
+
+# If the ALLEXTERNALS tag is set to YES all external classes will be listed 
+# in the class index. If set to NO only the inherited external classes 
+# will be listed.
+
+ALLEXTERNALS           = NO
+
+# If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed 
+# in the modules index. If set to NO, only the current project's groups will 
+# be listed.
+
+EXTERNAL_GROUPS        = YES
+
+# The PERL_PATH should be the absolute path and name of the perl script 
+# interpreter (i.e. the result of `which perl').
+
+PERL_PATH              = /usr/bin/perl
+
+#---------------------------------------------------------------------------
+# Configuration options related to the dot tool   
+#---------------------------------------------------------------------------
+
+# If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will 
+# generate a inheritance diagram (in HTML, RTF and LaTeX) for classes with base 
+# or super classes. Setting the tag to NO turns the diagrams off. Note that 
+# this option is superseded by the HAVE_DOT option below. This is only a 
+# fallback. It is recommended to install and use dot, since it yields more 
+# powerful graphs.
+
+CLASS_DIAGRAMS         = YES
+
+# You can define message sequence charts within doxygen comments using the \msc 
+# command. Doxygen will then run the mscgen tool (see 
+# http://www.mcternan.me.uk/mscgen/) to produce the chart and insert it in the 
+# documentation. The MSCGEN_PATH tag allows you to specify the directory where 
+# the mscgen tool resides. If left empty the tool is assumed to be found in the 
+# default search path.
+
+MSCGEN_PATH            = 
+
+# If set to YES, the inheritance and collaboration graphs will hide 
+# inheritance and usage relations if the target is undocumented 
+# or is not a class.
+
+#HIDE_UNDOC_RELATIONS   = YES
+HIDE_UNDOC_RELATIONS   = NO
+
+# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is 
+# available from the path. This tool is part of Graphviz, a graph visualization 
+# toolkit from AT&T and Lucent Bell Labs. The other options in this section 
+# have no effect if this option is set to NO (the default)
+
+#HAVE_DOT               = NO
+HAVE_DOT               = YES
+
+# By default doxygen will write a font called FreeSans.ttf to the output 
+# directory and reference it in all dot files that doxygen generates. This 
+# font does not include all possible unicode characters however, so when you need 
+# these (or just want a differently looking font) you can specify the font name 
+# using DOT_FONTNAME. You need need to make sure dot is able to find the font, 
+# which can be done by putting it in a standard location or by setting the 
+# DOTFONTPATH environment variable or by setting DOT_FONTPATH to the directory 
+# containing the font.
+
+DOT_FONTNAME           = FreeSans
+
+# The DOT_FONTSIZE tag can be used to set the size of the font of dot graphs. 
+# The default size is 10pt.
+
+DOT_FONTSIZE           = 10
+
+# By default doxygen will tell dot to use the output directory to look for the 
+# FreeSans.ttf font (which doxygen will put there itself). If you specify a 
+# different font using DOT_FONTNAME you can set the path where dot 
+# can find it using this tag.
+
+DOT_FONTPATH           = 
+
+# If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen 
+# will generate a graph for each documented class showing the direct and 
+# indirect inheritance relations. Setting this tag to YES will force the 
+# the CLASS_DIAGRAMS tag to NO.
+
+CLASS_GRAPH            = YES
+
+# If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen 
+# will generate a graph for each documented class showing the direct and 
+# indirect implementation dependencies (inheritance, containment, and 
+# class references variables) of the class with other documented classes.
+
+COLLABORATION_GRAPH    = YES
+
+# If the GROUP_GRAPHS and HAVE_DOT tags are set to YES then doxygen 
+# will generate a graph for groups, showing the direct groups dependencies
+
+GROUP_GRAPHS           = YES
+
+# If the UML_LOOK tag is set to YES doxygen will generate inheritance and 
+# collaboration diagrams in a style similar to the OMG's Unified Modeling 
+# Language.
+
+#UML_LOOK               = NO
+UML_LOOK               = YES
+
+# If set to YES, the inheritance and collaboration graphs will show the 
+# relations between templates and their instances.
+
+#TEMPLATE_RELATIONS     = NO
+TEMPLATE_RELATIONS     = YES
+
+# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT 
+# tags are set to YES then doxygen will generate a graph for each documented 
+# file showing the direct and indirect include dependencies of the file with 
+# other documented files.
+
+INCLUDE_GRAPH          = YES
+
+# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and 
+# HAVE_DOT tags are set to YES then doxygen will generate a graph for each 
+# documented header file showing the documented files that directly or 
+# indirectly include this file.
+
+INCLUDED_BY_GRAPH      = YES
+
+# If the CALL_GRAPH and HAVE_DOT options are set to YES then 
+# doxygen will generate a call dependency graph for every global function 
+# or class method. Note that enabling this option will significantly increase 
+# the time of a run. So in most cases it will be better to enable call graphs 
+# for selected functions only using the \callgraph command.
+
+#CALL_GRAPH             = NO
+CALL_GRAPH             = YES
+
+# If the CALLER_GRAPH and HAVE_DOT tags are set to YES then 
+# doxygen will generate a caller dependency graph for every global function 
+# or class method. Note that enabling this option will significantly increase 
+# the time of a run. So in most cases it will be better to enable caller 
+# graphs for selected functions only using the \callergraph command.
+
+#CALLER_GRAPH           = NO
+CALLER_GRAPH           = YES
+
+# If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen 
+# will graphical hierarchy of all classes instead of a textual one.
+
+GRAPHICAL_HIERARCHY    = YES
+
+# If the DIRECTORY_GRAPH, SHOW_DIRECTORIES and HAVE_DOT tags are set to YES 
+# then doxygen will show the dependencies a directory has on other directories 
+# in a graphical way. The dependency relations are determined by the #include 
+# relations between the files in the directories.
+
+DIRECTORY_GRAPH        = YES
+
+# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images 
+# generated by dot. Possible values are png, jpg, or gif 
+# If left blank png will be used.
+
+DOT_IMAGE_FORMAT       = png
+
+# The tag DOT_PATH can be used to specify the path where the dot tool can be 
+# found. If left blank, it is assumed the dot tool can be found in the path.
+
+DOT_PATH               = 
+
+# The DOTFILE_DIRS tag can be used to specify one or more directories that 
+# contain dot files that are included in the documentation (see the 
+# \dotfile command).
+
+DOTFILE_DIRS           = 
+
+# The DOT_GRAPH_MAX_NODES tag can be used to set the maximum number of 
+# nodes that will be shown in the graph. If the number of nodes in a graph 
+# becomes larger than this value, doxygen will truncate the graph, which is 
+# visualized by representing a node as a red box. Note that doxygen if the 
+# number of direct children of the root node in a graph is already larger than 
+# DOT_GRAPH_MAX_NODES then the graph will not be shown at all. Also note 
+# that the size of a graph can be further restricted by MAX_DOT_GRAPH_DEPTH.
+
+DOT_GRAPH_MAX_NODES    = 50
+
+# The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the 
+# graphs generated by dot. A depth value of 3 means that only nodes reachable 
+# from the root by following a path via at most 3 edges will be shown. Nodes 
+# that lay further from the root node will be omitted. Note that setting this 
+# option to 1 or 2 may greatly reduce the computation time needed for large 
+# code bases. Also note that the size of a graph can be further restricted by 
+# DOT_GRAPH_MAX_NODES. Using a depth of 0 means no depth restriction.
+
+MAX_DOT_GRAPH_DEPTH    = 0
+
+# Set the DOT_TRANSPARENT tag to YES to generate images with a transparent 
+# background. This is disabled by default, because dot on Windows does not 
+# seem to support this out of the box. Warning: Depending on the platform used, 
+# enabling this option may lead to badly anti-aliased labels on the edges of 
+# a graph (i.e. they become hard to read).
+
+#DOT_TRANSPARENT        = NO
+DOT_TRANSPARENT        = YES
+
+# Set the DOT_MULTI_TARGETS tag to YES allow dot to generate multiple output 
+# files in one run (i.e. multiple -o and -T options on the command line). This 
+# makes dot run faster, but since only newer versions of dot (>1.8.10) 
+# support this, this feature is disabled by default.
+
+DOT_MULTI_TARGETS      = NO
+
+# If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will 
+# generate a legend page explaining the meaning of the various boxes and 
+# arrows in the dot generated graphs.
+
+GENERATE_LEGEND        = YES
+
+# If the DOT_CLEANUP tag is set to YES (the default) Doxygen will 
+# remove the intermediate dot files that are used to generate 
+# the various graphs.
+
+DOT_CLEANUP            = YES
+
+#---------------------------------------------------------------------------
+# Options related to the search engine
+#---------------------------------------------------------------------------
+
+# The SEARCHENGINE tag specifies whether or not a search engine should be 
+# used. If set to NO the values of all tags below this one will be ignored.
+
+SEARCHENGINE           = NO
diff --git a/docs/instruments.txt b/docs/instruments.txt
new file mode 100644 (file)
index 0000000..e3e5135
--- /dev/null
@@ -0,0 +1,187 @@
+This file aims to list common band instruments (including dance carpet).
+B means button
+A means axis (+: positive values, -: negative values)
+SDL report axis or button ID minus one.
+
+Ex: A5- => SDL axis 4 with negative value
+
+[Guitar Hero III: Legends of Rock] PS3 Guitar
+ USB id: 12ba:0100
+ SDL name: Licensed by Sony Computer Entertainment Guitar Hero3 for PlayStation (R) 3
+ GREEN FRET:  B2
+ RED FRET:    B3
+ YELLOW FRET: B1
+ BLUE FRET:   B4
+ ORANGE FRET: B5
+ START:       B10
+ SELECT:      B9
+ PS3:         B13
+ STAR POWER:  N/A?
+ MIC SWITCH:  N/A?
+ DOWN:        A6+
+ UP:          A6-
+ LEFT:        A5-
+ RIGHT:       A5+
+ BEND:        A3+
+ PICK DOWN:   A6+
+ PICK UP:     A6-
+
+[Guitar Hero World Tour] PS3 Guitar
+ USB id: 12ba:0100
+ SDL name: Licensed by Sony Computer Entertainment Guitar Hero4 for PlayStation (R) 3
+ GREEN FRET:  B2
+ RED FRET:    B3
+ YELLOW FRET: B1
+ BLUE FRET:   B4
+ ORANGE FRET: B5
+ HAMMER ZONE: A4 APPROX  VALUES:
+       - GREEN -26000
+       - RED   -10000
+       - YELLOW  2000
+       - BLUE   16000
+       - ORANGE 32000
+ START:       B10
+ SELECT:      B9 (Also activate star power)
+ PS3:         B13
+ DOWN:        A6+
+ UP:          A6-
+ LEFT:        A5-
+ RIGHT:       A5+
+ BEND:        A3+
+ PICK DOWN:   A6+
+ PICK UP:     A6-
+
+[Rock Band I] PS3 Guitar
+ USB id: 12ba:0200
+ SDL name: Licensed by Sony Computer Entertainment America Harmonix Guitar for PlayStation®3   (Note: Latin-1 encoding)
+ GREEN FRET:  B2
+ RED FRET:    B3
+ YELLOW FRET: B4
+ BLUE FRET:   B1
+ ORANGE FRET: B5
+ START:       B10
+ SELECT:      B9
+ PS3:         B13
+ STAR POWER:  B5
+ MIC SWITCH:  A4
+ DOWN:        A6+
+ UP:          A6-
+ LEFT:        A5-
+ RIGHT:       A5+
+ BEND:        A3 = 1.0 (fully pressed) .. -1.0 (fully released), but resets to 0.0 after a while when fully released
+ PICK DOWN:   A6+
+ PICK UP:     A6-
+
+[Rock Band I] Xbox360 Guitar
+ SDL name: Controller (Harmonix Guitar for Xbox 360) (at least on Windows)
+ GREEN FRET:  B1
+ RED FRET:    B2
+ YELLOW FRET: B4
+ BLUE FRET:   B3
+ ORANGE FRET: B5
+ START:       B8
+ SELECT:      B7
+ MIC SWITCH:  A3
+ TILT:        A4
+ WHAMMY:      A5
+ UP:          HAT0: 4
+ DOWN:        HAT0: 1
+ LEFT:        HAT0: 8
+ RIGHT:       HAT0: 2
+
+[Guitar Hero X0] Guitar Hero X-plorer
+ USB id: 1430:4748
+ SDL name: Guitar Hero X-plorer
+ GREEN FRET:  B1
+ RED FRET:    B2
+ YELLOW FRET: B4
+ BLUE FRET:   B3
+ ORANGE FRET: B5
+ START:       B8
+ SELECT:      B7  (Says "BACK" on the guitar)
+ STAR POWER:  A4  (Y axis on Windows, didn't verify that it is A4 but A3 is X axis)
+ DOWN:        A6+
+ UP:          A6-
+ LEFT:        A5-
+ RIGHT:       A5+
+ BEND:        A3
+ PICK DOWN:   A6+
+ PICK UP:     A6-
+
+
+[Guitar Hero World Tour] PS3 Drumkit
+ USB id: 12ba:0120
+ SDL name: Licensed by Sony Computer Entertainment Guitar Hero4 for PlayStation (R) 3
+ RED FRET or CIRCLE:      B3
+ YELLOW FRET or TRIANGLE: B4
+ BLUE FRET or SQUARE:     B1
+ ORANGE FRET:             B6
+ GREEN FRET or CROSS:     B2
+ KICK:                    B5
+ START:                   B10
+ SELECT:                  B9
+ PS3:                     B13
+ DOWN:                    A6+
+ UP:                      A6-
+ LEFT:                    A5-
+ RIGHT:                   A5+
+
+[Rock Band I] PS3 Drumkit
+ USB id: 12ba:0210
+ SDL name: Licensed by Sony Computer Entertainment America Harmonix Drum Kit for PlayStation(R)3
+ RED PAD or CIRCLE:       B3
+ YELLOW PAD or TRIANGLE:  B4
+ BLUE PAD or SQUARE:      B1
+ GREEN PAD or CROSS:      B2
+ KICK:                    B5
+ START:                   B10
+ SELECT:                  B9
+ PS3:                     B13
+ DOWN:                    A6+
+ UP:                      A6-
+ LEFT:                    A5-
+ RIGHT:                   A5+
+
+[Rock Band I] Xbox360 Drumkit
+ SDL name: Controller (Harmonix Drum Kit for Xbox 360) (at least on Windows)
+ RED PAD       B2
+ YELLOW PAD    B4
+ BLUE PAD      B3
+ GREEN PAD     B1
+ KICK:         B5
+ START:        B8
+ SELECT:       B7
+ UP:           HAT0: 1
+ DOWN:         HAT0: 4
+ LEFT:         HAT0: 8
+ RIGHT:        HAT0: 2
+
+Performous InputDev button numbers
+----------------------------------
+
+drums:
+0 = kick
+1 = red
+2 = yellow
+3 = blue
+4 = green (also orange of GHWT drums)
+
+guitar:
+0 = green
+1 = red
+2 = yellow
+3 = blue
+4 = orange
+
+dancepad:
+0 = left
+1 = down
+2 = up
+3 = right
+4 = down left
+5 = down right
+6 = up left
+7 = up right
+8 = start
+9 = select
+
diff --git a/docs/license/Performous.txt b/docs/license/Performous.txt
new file mode 100644 (file)
index 0000000..5861375
--- /dev/null
@@ -0,0 +1,346 @@
+GNU GPLv2 or later. Some parts of the project may have more liberal licenses.
+See Authors.txt for information on copyright holders and licenses of specific
+parts. Fonts are licensed under SIL OFL.
+
+
+                   GNU GENERAL PUBLIC LICENSE
+                      Version 2, June 1991
+
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.
+                       51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+                           Preamble
+
+  The licenses for most software are designed to take away your
+freedom to share and change it.  By contrast, the GNU General Public
+License is intended to guarantee your freedom to share and change free
+software--to make sure the software is free for all its users.  This
+General Public License applies to most of the Free Software
+Foundation's software and to any other program whose authors commit to
+using it.  (Some other Free Software Foundation software is covered by
+the GNU Library General Public License instead.)  You can apply it to
+your programs, too.
+
+  When we speak of free software, we are referring to freedom, not
+price.  Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+this service if you wish), that you receive source code or can get it
+if you want it, that you can change the software or use pieces of it
+in new free programs; and that you know you can do these things.
+
+  To protect your rights, we need to make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if you
+distribute copies of the software, or if you modify it.
+
+  For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must give the recipients all the rights that
+you have.  You must make sure that they, too, receive or can get the
+source code.  And you must show them these terms so they know their
+rights.
+
+  We protect your rights with two steps: (1) copyright the software, and
+(2) offer you this license which gives you legal permission to copy,
+distribute and/or modify the software.
+
+  Also, for each author's protection and ours, we want to make certain
+that everyone understands that there is no warranty for this free
+software.  If the software is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original, so
+that any problems introduced by others will not reflect on the original
+authors' reputations.
+
+  Finally, any free program is threatened constantly by software
+patents.  We wish to avoid the danger that redistributors of a free
+program will individually obtain patent licenses, in effect making the
+program proprietary.  To prevent this, we have made it clear that any
+patent must be licensed for everyone's free use or not licensed at all.
+
+  The precise terms and conditions for copying, distribution and
+modification follow.
+\f
+                   GNU GENERAL PUBLIC LICENSE
+   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+  0. This License applies to any program or other work which contains
+a notice placed by the copyright holder saying it may be distributed
+under the terms of this General Public License.  The "Program", below,
+refers to any such program or work, and a "work based on the Program"
+means either the Program or any derivative work under copyright law:
+that is to say, a work containing the Program or a portion of it,
+either verbatim or with modifications and/or translated into another
+language.  (Hereinafter, translation is included without limitation in
+the term "modification".)  Each licensee is addressed as "you".
+
+Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope.  The act of
+running the Program is not restricted, and the output from the Program
+is covered only if its contents constitute a work based on the
+Program (independent of having been made by running the Program).
+Whether that is true depends on what the Program does.
+
+  1. You may copy and distribute verbatim copies of the Program's
+source code as you receive it, in any medium, provided that you
+conspicuously and appropriately publish on each copy an appropriate
+copyright notice and disclaimer of warranty; keep intact all the
+notices that refer to this License and to the absence of any warranty;
+and give any other recipients of the Program a copy of this License
+along with the Program.
+
+You may charge a fee for the physical act of transferring a copy, and
+you may at your option offer warranty protection in exchange for a fee.
+
+  2. You may modify your copy or copies of the Program or any portion
+of it, thus forming a work based on the Program, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+    a) You must cause the modified files to carry prominent notices
+    stating that you changed the files and the date of any change.
+
+    b) You must cause any work that you distribute or publish, that in
+    whole or in part contains or is derived from the Program or any
+    part thereof, to be licensed as a whole at no charge to all third
+    parties under the terms of this License.
+
+    c) If the modified program normally reads commands interactively
+    when run, you must cause it, when started running for such
+    interactive use in the most ordinary way, to print or display an
+    announcement including an appropriate copyright notice and a
+    notice that there is no warranty (or else, saying that you provide
+    a warranty) and that users may redistribute the program under
+    these conditions, and telling the user how to view a copy of this
+    License.  (Exception: if the Program itself is interactive but
+    does not normally print such an announcement, your work based on
+    the Program is not required to print an announcement.)
+\f
+These requirements apply to the modified work as a whole.  If
+identifiable sections of that work are not derived from the Program,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works.  But when you
+distribute the same sections as part of a whole which is a work based
+on the Program, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Program.
+
+In addition, mere aggregation of another work not based on the Program
+with the Program (or with a work based on the Program) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+  3. You may copy and distribute the Program (or a work based on it,
+under Section 2) in object code or executable form under the terms of
+Sections 1 and 2 above provided that you also do one of the following:
+
+    a) Accompany it with the complete corresponding machine-readable
+    source code, which must be distributed under the terms of Sections
+    1 and 2 above on a medium customarily used for software interchange; or,
+
+    b) Accompany it with a written offer, valid for at least three
+    years, to give any third party, for a charge no more than your
+    cost of physically performing source distribution, a complete
+    machine-readable copy of the corresponding source code, to be
+    distributed under the terms of Sections 1 and 2 above on a medium
+    customarily used for software interchange; or,
+
+    c) Accompany it with the information you received as to the offer
+    to distribute corresponding source code.  (This alternative is
+    allowed only for noncommercial distribution and only if you
+    received the program in object code or executable form with such
+    an offer, in accord with Subsection b above.)
+
+The source code for a work means the preferred form of the work for
+making modifications to it.  For an executable work, complete source
+code means all the source code for all modules it contains, plus any
+associated interface definition files, plus the scripts used to
+control compilation and installation of the executable.  However, as a
+special exception, the source code distributed need not include
+anything that is normally distributed (in either source or binary
+form) with the major components (compiler, kernel, and so on) of the
+operating system on which the executable runs, unless that component
+itself accompanies the executable.
+
+If distribution of executable or object code is made by offering
+access to copy from a designated place, then offering equivalent
+access to copy the source code from the same place counts as
+distribution of the source code, even though third parties are not
+compelled to copy the source along with the object code.
+\f
+  4. You may not copy, modify, sublicense, or distribute the Program
+except as expressly provided under this License.  Any attempt
+otherwise to copy, modify, sublicense or distribute the Program is
+void, and will automatically terminate your rights under this License.
+However, parties who have received copies, or rights, from you under
+this License will not have their licenses terminated so long as such
+parties remain in full compliance.
+
+  5. You are not required to accept this License, since you have not
+signed it.  However, nothing else grants you permission to modify or
+distribute the Program or its derivative works.  These actions are
+prohibited by law if you do not accept this License.  Therefore, by
+modifying or distributing the Program (or any work based on the
+Program), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Program or works based on it.
+
+  6. Each time you redistribute the Program (or any work based on the
+Program), the recipient automatically receives a license from the
+original licensor to copy, distribute or modify the Program subject to
+these terms and conditions.  You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties to
+this License.
+
+  7. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License.  If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Program at all.  For example, if a patent
+license would not permit royalty-free redistribution of the Program by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Program.
+
+If any portion of this section is held invalid or unenforceable under
+any particular circumstance, the balance of the section is intended to
+apply and the section as a whole is intended to apply in other
+circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system, which is
+implemented by public license practices.  Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+\f
+  8. If the distribution and/or use of the Program is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Program under this License
+may add an explicit geographical distribution limitation excluding
+those countries, so that distribution is permitted only in or among
+countries not thus excluded.  In such case, this License incorporates
+the limitation as if written in the body of this License.
+
+  9. The Free Software Foundation may publish revised and/or new versions
+of the General Public License from time to time.  Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+Each version is given a distinguishing version number.  If the Program
+specifies a version number of this License which applies to it and "any
+later version", you have the option of following the terms and conditions
+either of that version or of any later version published by the Free
+Software Foundation.  If the Program does not specify a version number of
+this License, you may choose any version ever published by the Free Software
+Foundation.
+
+  10. If you wish to incorporate parts of the Program into other free
+programs whose distribution conditions are different, write to the author
+to ask for permission.  For software which is copyrighted by the Free
+Software Foundation, write to the Free Software Foundation; we sometimes
+make exceptions for this.  Our decision will be guided by the two goals
+of preserving the free status of all derivatives of our free software and
+of promoting the sharing and reuse of software generally.
+
+                           NO WARRANTY
+
+  11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
+FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW.  EXCEPT WHEN
+OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
+PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.  THE ENTIRE RISK AS
+TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU.  SHOULD THE
+PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
+REPAIR OR CORRECTION.
+
+  12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
+REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
+INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
+OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
+TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
+YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
+PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGES.
+
+                    END OF TERMS AND CONDITIONS
+\f
+           How to Apply These Terms to Your New Programs
+
+  If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+  To do so, attach the following notices to the program.  It is safest
+to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+    <one line to give the program's name and a brief idea of what it does.>
+    Copyright (C) <year>  <name of author>
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+
+
+Also add information on how to contact you by electronic and paper mail.
+
+If the program is interactive, make it output a short notice like this
+when it starts in an interactive mode:
+
+    Gnomovision version 69, Copyright (C) year name of author
+    Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+    This is free software, and you are welcome to redistribute it
+    under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License.  Of course, the commands you use may
+be called something other than `show w' and `show c'; they could even be
+mouse-clicks or menu items--whatever suits your program.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the program, if
+necessary.  Here is a sample; alter the names:
+
+  Yoyodyne, Inc., hereby disclaims all copyright interest in the program
+  `Gnomovision' (which makes passes at compilers) written by James Hacker.
+
+  <signature of Ty Coon>, 1 April 1989
+  Ty Coon, President of Vice
+
+This General Public License does not permit incorporating your program into
+proprietary programs.  If your program is a subroutine library, you may
+consider it more useful to permit linking proprietary applications with the
+library.  If this is what you want to do, use the GNU Library General
+Public License instead of this License.
+
diff --git a/docs/license/SIL OFL Font License New Rocker.txt b/docs/license/SIL OFL Font License New Rocker.txt
new file mode 100644 (file)
index 0000000..f2fc8fb
--- /dev/null
@@ -0,0 +1,96 @@
+Copyright (c) 2011, Pablo Impallari (www.impallari.com|impallari@gmail.com),
+Copyright (c) 2011, Brenda Gallo (gbrenda1987@gmail.com),
+Copyright (c) 2011, Rodrigo Fuenzalida (www.rfuenzalida.com|hello@rfuenzalida.com), 
+with Reserved Font Name &#39;New Rocker&#39;
+
+This Font Software is licensed under the SIL Open Font License, Version 1.1.
+This license is copied below, and is also available with a FAQ at:
+http://scripts.sil.org/OFL
+
+
+-----------------------------------------------------------
+SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
+-----------------------------------------------------------
+
+PREAMBLE
+The goals of the Open Font License (OFL) are to stimulate worldwide
+development of collaborative font projects, to support the font creation
+efforts of academic and linguistic communities, and to provide a free and
+open framework in which fonts may be shared and improved in partnership
+with others.
+
+The OFL allows the licensed fonts to be used, studied, modified and
+redistributed freely as long as they are not sold by themselves. The
+fonts, including any derivative works, can be bundled, embedded, 
+redistributed and/or sold with any software provided that any reserved
+names are not used by derivative works. The fonts and derivatives,
+however, cannot be released under any other type of license. The
+requirement for fonts to remain under this license does not apply
+to any document created using the fonts or their derivatives.
+
+DEFINITIONS
+&quot;Font Software&quot; refers to the set of files released by the Copyright
+Holder(s) under this license and clearly marked as such. This may
+include source files, build scripts and documentation.
+
+&quot;Reserved Font Name&quot; refers to any names specified as such after the
+copyright statement(s).
+
+&quot;Original Version&quot; refers to the collection of Font Software components as
+distributed by the Copyright Holder(s).
+
+&quot;Modified Version&quot; refers to any derivative made by adding to, deleting,
+or substituting -- in part or in whole -- any of the components of the
+Original Version, by changing formats or by porting the Font Software to a
+new environment.
+
+&quot;Author&quot; refers to any designer, engineer, programmer, technical
+writer or other person who contributed to the Font Software.
+
+PERMISSION &amp; CONDITIONS
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of the Font Software, to use, study, copy, merge, embed, modify,
+redistribute, and sell modified and unmodified copies of the Font
+Software, subject to the following conditions:
+
+1) Neither the Font Software nor any of its individual components,
+in Original or Modified Versions, may be sold by itself.
+
+2) Original or Modified Versions of the Font Software may be bundled,
+redistributed and/or sold with any software, provided that each copy
+contains the above copyright notice and this license. These can be
+included either as stand-alone text files, human-readable headers or
+in the appropriate machine-readable metadata fields within text or
+binary files as long as those fields can be easily viewed by the user.
+
+3) No Modified Version of the Font Software may use the Reserved Font
+Name(s) unless explicit written permission is granted by the corresponding
+Copyright Holder. This restriction only applies to the primary font name as
+presented to the users.
+
+4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font
+Software shall not be used to promote, endorse or advertise any
+Modified Version, except to acknowledge the contribution(s) of the
+Copyright Holder(s) and the Author(s) or with their explicit written
+permission.
+
+5) The Font Software, modified or unmodified, in part or in whole,
+must be distributed entirely under this license, and must not be
+distributed under any other license. The requirement for fonts to
+remain under this license does not apply to any document created
+using the Font Software.
+
+TERMINATION
+This license becomes null and void if any of the above conditions are
+not met.
+
+DISCLAIMER
+THE FONT SOFTWARE IS PROVIDED &quot;AS IS&quot;, WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
+OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE
+COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
+DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM
+OTHER DEALINGS IN THE FONT SOFTWARE.
diff --git a/docs/license/SIL OFL Goblin.txt b/docs/license/SIL OFL Goblin.txt
new file mode 100644 (file)
index 0000000..68e0492
--- /dev/null
@@ -0,0 +1,82 @@
+PREAMBLE
+The goals of the Open Font License (OFL) are to stimulate worldwide
+development of collaborative font projects, to support the font creation
+efforts of academic and linguistic communities, and to provide a free and
+open framework in which fonts may be shared and improved in partnership
+with others.
+
+The OFL allows the licensed fonts to be used, studied, modified and
+redistributed freely as long as they are not sold by themselves. The
+fonts, including any derivative works, can be bundled, embedded, 
+redistributed and/or sold with any software provided that any reserved
+names are not used by derivative works. The fonts and derivatives,
+however, cannot be released under any other type of license. The
+requirement for fonts to remain under this license does not apply
+to any document created using the fonts or their derivatives.
+
+DEFINITIONS
+&quot;Font Software&quot; refers to the set of files released by the Copyright
+Holder(s) under this license and clearly marked as such. This may
+include source files, build scripts and documentation.
+
+&quot;Reserved Font Name&quot; refers to any names specified as such after the
+copyright statement(s).
+
+&quot;Original Version&quot; refers to the collection of Font Software components as
+distributed by the Copyright Holder(s).
+
+&quot;Modified Version&quot; refers to any derivative made by adding to, deleting,
+or substituting -- in part or in whole -- any of the components of the
+Original Version, by changing formats or by porting the Font Software to a
+new environment.
+
+&quot;Author&quot; refers to any designer, engineer, programmer, technical
+writer or other person who contributed to the Font Software.
+
+PERMISSION &amp; CONDITIONS
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of the Font Software, to use, study, copy, merge, embed, modify,
+redistribute, and sell modified and unmodified copies of the Font
+Software, subject to the following conditions:
+
+1) Neither the Font Software nor any of its individual components,
+in Original or Modified Versions, may be sold by itself.
+
+2) Original or Modified Versions of the Font Software may be bundled,
+redistributed and/or sold with any software, provided that each copy
+contains the above copyright notice and this license. These can be
+included either as stand-alone text files, human-readable headers or
+in the appropriate machine-readable metadata fields within text or
+binary files as long as those fields can be easily viewed by the user.
+
+3) No Modified Version of the Font Software may use the Reserved Font
+Name(s) unless explicit written permission is granted by the corresponding
+Copyright Holder. This restriction only applies to the primary font name as
+presented to the users.
+
+4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font
+Software shall not be used to promote, endorse or advertise any
+Modified Version, except to acknowledge the contribution(s) of the
+Copyright Holder(s) and the Author(s) or with their explicit written
+permission.
+
+5) The Font Software, modified or unmodified, in part or in whole,
+must be distributed entirely under this license, and must not be
+distributed under any other license. The requirement for fonts to
+remain under this license does not apply to any document created
+using the Font Software.
+
+TERMINATION
+This license becomes null and void if any of the above conditions are
+not met.
+
+DISCLAIMER
+THE FONT SOFTWARE IS PROVIDED &quot;AS IS&quot;, WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
+OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE
+COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
+DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM
+OTHER DEALINGS IN THE FONT SOFTWARE.
\ No newline at end of file
diff --git a/docs/man/CMakeLists.txt b/docs/man/CMakeLists.txt
new file mode 100644 (file)
index 0000000..b06ad5a
--- /dev/null
@@ -0,0 +1,45 @@
+find_program(HELP2MAN help2man DOC "Location of the help2man program")
+find_program(GZIP gzip DOC "Location of the gzip program")
+mark_as_advanced(HELP2MAN)
+mark_as_advanced(GZIP)
+if(HELP2MAN AND GZIP)
+       set(MANFILE ${CMAKE_CURRENT_BINARY_DIR}/performous.6.gz)
+       set(H2MFILE ${CMAKE_CURRENT_SOURCE_DIR}/performous.h2m)
+       set(PERFORMOUS_EXEC ${CMAKE_BINARY_DIR}/performous)
+       add_custom_command(
+               OUTPUT ${MANFILE}
+               COMMAND ${HELP2MAN} ${PERFORMOUS_EXEC} -s 6 -i ${H2MFILE} -N | ${GZIP} > ${MANFILE}
+               MAIN_DEPENDENCY ${H2MFILE}
+               DEPENDS ${PERFORMOUS_EXEC}
+               COMMENT "Building Performous man page"
+               VERBATIM
+       )
+       add_custom_target(manpage ALL DEPENDS ${MANFILE})
+       iF (APPLE)
+           install(FILES ${MANFILE} DESTINATION Resources/man/man6)
+       else(APPLE)
+       install(FILES ${MANFILE} DESTINATION share/man/man6)
+       endif()
+else(HELP2MAN AND GZIP)
+       message("WARNING: One of the following is missing: help2man, gzip; performous man page will not be generated")
+endif(HELP2MAN AND GZIP)
+if(ENABLE_TOOLS AND GZIP)
+       set(TOOLS 
+               "ss_pak_extract" "ss_extract" "ss_cover_conv"
+               "ss_adpcm_decode" "ss_ipu_conv" "ss_chc_decode"
+               "gh_fsb_decrypt" "gh_xen_decrypt")
+       set(MAN_SECTION "1")
+       foreach(TOOL ${TOOLS})
+               set(TOOL_MANFILE ${CMAKE_CURRENT_SOURCE_DIR}/${TOOL}.${MAN_SECTION})
+               set(TOOL_MANFILE_GZ ${CMAKE_CURRENT_BINARY_DIR}/${TOOL}.${MAN_SECTION}.gz)
+               add_custom_command(
+                       OUTPUT ${TOOL_MANFILE_GZ}
+                       COMMAND ${GZIP} -c ${TOOL_MANFILE} > ${TOOL_MANFILE_GZ}
+                       MAIN_DEPENDENCY ${TOOL_MANFILE}
+                       COMMENT "Building ${TOOL} man page"
+                       VERBATIM
+               )
+               add_custom_target(${TOOL}.${MAN_SECTION} ALL DEPENDS ${TOOL_MANFILE_GZ})
+               install(FILES ${TOOL_MANFILE_GZ} DESTINATION share/man/man${MAN_SECTION})
+       endforeach(TOOL)
+endif(ENABLE_TOOLS AND GZIP)
diff --git a/docs/man/gh_fsb_decrypt.1 b/docs/man/gh_fsb_decrypt.1
new file mode 100644 (file)
index 0000000..e025573
--- /dev/null
@@ -0,0 +1,12 @@
+.TH "gh_fsb_decrypt" "1" "" "" ""
+.SH "NAME"
+gh_fsb_decrypt \- Tool for decoding FMOD Sample Bank (FSB) files
+.SH "SYNOPSIS"
+\fBgh_fsb_decrypt\fR input.fsb
+.TP
+\fBinput.fsb\fR
+FSB source file
+.SH "DESCRIPTION"
+Tool for decoding FMOD Sample Bank (FSB) files
+.SH "SEE ALSO"
+\fIperformous\fR(6)
diff --git a/docs/man/gh_xen_decrypt.1 b/docs/man/gh_xen_decrypt.1
new file mode 100644 (file)
index 0000000..d11b5a2
--- /dev/null
@@ -0,0 +1,15 @@
+.TH "gh_xen_decrypt" "1" "" "" ""
+.SH "NAME"
+gh_xen_decrypt \- Tool for decrypting Guitar Hero xen files
+.SH "SYNOPSIS"
+\fBgh_xen_decrypt\fR input.xen output
+.TP
+\fBinput.xen\fR
+Xen source file
+.TP
+\fBoutput\fR
+destination file
+.SH "DESCRIPTION"
+Tool for decrypting Guitar Hero xen files
+.SH "SEE ALSO"
+\fIperformous\fR(6)
diff --git a/docs/man/performous.h2m b/docs/man/performous.h2m
new file mode 100644 (file)
index 0000000..cad1c42
--- /dev/null
@@ -0,0 +1,95 @@
+Include file for Performous man page
+
+[name]
+performous \- The free music and rhythm game
+
+[description]
+Performous is a free cross-platform karaoke, band and dancing game, where
+one or more players perform a song and the game scores their performances
+based on timing and accuracy.
+
+Performous supports songs in UltraStar, Frets on Fire and StepMania formats.
+Also, microphones and instruments from SingStar, Guitar Hero and Rock Band
+as well as some dance pads are autodetected.
+
+If you have trouble with the program (no songs found, audio not working, etc),
+try running it on a terminal. Some useful debug information is printed there.
+
+[navigation]
+In-game navigation uses the following keys:
+.SS "Global shortcuts:"
+.TP
+\fBLeft\fR/\fBRight\fR/\fBUp\fR/\fBDown\fR/
+Change selected option/song
+.TP
+\fBEnter\fR
+Enter selection
+.TP
+\fBEsc\fR
+Exit the current screen/mode
+.TP
+\fBAlt+Enter\fR
+Switch between full screen and windowed modes
+.TP
+\fBPause\fR or \fBCtrl+P\fR
+Pause audio/game
+.TP
+\fBCtrl+Up/Down\fR
+Change audio volume
+
+.SS "Song selection:"
+.TP
+\fBUp\fR/\fBDown\fR
+Switch the sort order (song name, artist, edition, genre or song folder path)
+.TP
+\fBAny text\fR
+Search for songs (write the text to find, uses regexp format)
+.TP
+\fBTab\fR
+Randomize songs (sort them again)
+.TP
+\fBCtrl+R\fR
+Refresh song list (reload from disk)
+.TP
+\fBF4\fR
+Enter jukebox mode (play songs entirely, hide song browser, allow seeking with Up/Down)
+
+.SS "Singing screen:"
+.TP
+\fBCtrl+Left/Right\fR/\fBHome\fR
+Fast forward or rewind the song
+.TP
+\fBEnter\fR
+Skip long instrumental breaks, or get the grading instantly at the end of song.
+.TP
+\fBCtrl+S\fR
+Toggle synth mode (synthesized tone for notes)
+.TP
+\fBCtrl+F1/F2\fR
+Adjust audio/video sync. Use if the notes pass the black line at incorrect time.
+.TP
+\fBCtrl+F3/F4\fR
+Adjust audio roundtrip latency. Use if the pitch wave does not match the notes, when you match your timing to what you hear.
+.TP
+\fBCtrl+F5/F6\fR
+The total of USB controller latency combined with audio output latency. Adjust so that you can hit the notes best when playing by ear (not looking on screen).
+.TP
+\fBCtrl+K\fR
+Toggle karaoke mode (hide notes and scores)
+.TP
+\fBCtrl+W\fR
+Toggle pitch wave rendering (only when karaoke mode is disabled)
+.TP
+\fBCtrl+R\fR
+Hot reload song from disk (useful for making or repairing songs)
+
+[audio device configuration]
+Performous normally autodetects microphones and playback devices correctly, but if this fails on your machine, you will need to configure them in the Audio Devices -screen. Advanced configuration is possible through the command line, just remember to enter the configuration menu and press \fBCtrl+S\fR to save them to your config file so that they don't need to be specified every time the program starts.
+
+The list of available PortAudio devices is printed to the console, but it can also be seen from the GUI.
+
+[see also]
+You can find more information at http://performous.org/ or
+http://wiki.performous.org or
+http://sourceforge.net/projects/performous/
+
diff --git a/docs/man/ss_adpcm_decode.1 b/docs/man/ss_adpcm_decode.1
new file mode 100644 (file)
index 0000000..aaf64eb
--- /dev/null
@@ -0,0 +1,18 @@
+.TH "ss_adpcm_decode" "1" "" "" ""
+.SH "NAME"
+ss_adpcm_decode \- Tool for converting ADPCM Singstar audio format to WAV
+.SH "SYNOPSIS"
+\fBss_adpcm_decode\fR [archive.pak] input.mib output.wav
+.TP
+[ \fBarchive.pak\fR ]
+Optional Singstar archive name to look in
+.TP
+\fBinput.mib\fR
+ADPCM source file
+.TP
+\fBoutput.wav\fR
+WAV destination file
+.SH "DESCRIPTION"
+Tool for converting ADPCM Singstar audio format to WAV
+.SH "SEE ALSO"
+\fIperformous\fR(6)
diff --git a/docs/man/ss_chc_decode.1 b/docs/man/ss_chc_decode.1
new file mode 100644 (file)
index 0000000..8e4c154
--- /dev/null
@@ -0,0 +1,18 @@
+.TH "ss_chc_decode" "1" "" "" ""
+.SH "NAME"
+ss_chc_decode \- Tool for decoding Singstar CHC (melody cache) files
+.SH "SYNOPSIS"
+\fBss_chc_decode\fR chc_file key1 key2 key3 key4 track_id
+.TP
+\fBchc_file\fR
+Singstar melody cache file
+.TP
+\fBkey1 to key4\fR
+keys to decode the cache file
+.TP
+\fBtrack_id\fR
+Singstar track id to extract
+.SH "DESCRIPTION"
+Tool for decrypting Singstar CHC files.
+.SH "SEE ALSO"
+\fIperformous\fR(6)
diff --git a/docs/man/ss_cover_conv.1 b/docs/man/ss_cover_conv.1
new file mode 100644 (file)
index 0000000..a2f69b6
--- /dev/null
@@ -0,0 +1,21 @@
+.TH "ss_cover_conv" "1" "" "" ""
+.SH "NAME"
+ss_cover_conv \- Tool for converting Singstar song cover
+.SH "SYNOPSIS"
+\fBss_cover_conv\fR [\-h|\-\-help] pak_file track_id output_image
+.TP
+\fB\-h\fR [ \fB\-\-help\fR ]
+you are viewing it
+.TP
+\fBpak_file\fR
+Singstar Pak file to look in
+.TP
+\fBtrack_id\fR
+Singstar track id to extract
+.TP
+\fBoutput_image\fR
+Output image (format will be automatically detected)
+.SH "DESCRIPTION"
+Tool for converting internal Singstar song cover (TX2 format) into a standard format
+.SH "SEE ALSO"
+\fIperformous\fR(6)
diff --git a/docs/man/ss_extract.1 b/docs/man/ss_extract.1
new file mode 100644 (file)
index 0000000..5395e09
--- /dev/null
@@ -0,0 +1,27 @@
+.TH ss_extract "1" "" "" ""
+.SH "NAME"
+ss_extract \- Tool for converting Singstar DVDs to Ultrastar format
+.SH "SYNOPSIS"
+\fBss_extract\fR [\-h|\-\-help] [\-\-dvd arg] [\-l|\-\-list] [\-\-song arg] [\-\-video arg] [\-\-audio arg]
+.TP
+\fB\-h\fR [ \fB\-\-help\fR ]
+you are viewing it
+.TP
+\fB\-\-dvd\fR arg
+path to Singstar DVD root
+.TP
+\fB\-l\fR [ \fB\-\-list\fR ]
+list tracks only
+.TP
+\fB\-\-song\fR arg
+only extract the given track (ID or partial name)
+.TP
+\fB\-\-video\fR arg (=mkv)
+specify video format (none, mkv, mpeg2)
+.TP
+\fB\-\-audio\fR arg (=ogg)
+specify audio format (none, ogg, wav)
+.SH "DESCRIPTION"
+Tool for converting original Singstar DVDs to the format used by Performous.
+.SH "SEE ALSO"
+\fIperformous\fR(6)
diff --git a/docs/man/ss_ipu_conv.1 b/docs/man/ss_ipu_conv.1
new file mode 100644 (file)
index 0000000..32eee37
--- /dev/null
@@ -0,0 +1,15 @@
+.TH "ss_ipu_conv" "1" "" "" ""
+.SH "NAME"
+ss_ipu_conv \- Tool for converting Singstar videos
+.SH "SYNOPSIS"
+\fBss_ipu_conv\fR infile.ipu outfile.m2v
+.TP
+\fBinfile.ipu\fR
+Singstar ipu video file
+.TP
+\fBoutfile.m2v\fR
+Video output file (MPEG2-Video)
+.SH "DESCRIPTION"
+Tool for converting Singstar videos
+.SH "SEE ALSO"
+\fIperformous\fR(6)
diff --git a/docs/man/ss_pak_extract.1 b/docs/man/ss_pak_extract.1
new file mode 100644 (file)
index 0000000..fa60bfb
--- /dev/null
@@ -0,0 +1,17 @@
+.TH "ss_pak_extract" "1" "" "" ""
+.SH "NAME"
+ss_pak_extract \- Tool for reading general PAK files (used by Singstar)
+.SH "SYNOPSIS"
+.TP
+\fBss_pak_extract\fR [\-h|\-\-help] file.pak \-\-extract [files]
+Extract \fBfiles\fR from \fBfile.pak\fR pak file.
+.TP
+\fBss_pak_extract\fR file.pak \-\-dump file
+Dump \fBfile\fR content from \fBfile.pak\fR pak file to stdout.
+.TP
+\fBss_pak_extract\fR file.pak \-\-list
+List files from \fBfile.pak\fR pak file to stdout.
+.SH "DESCRIPTION"
+Tool for reading general PAK files (used by Singstar)
+.SH "SEE ALSO"
+\fIperformous\fR(6)
diff --git a/game/3dobject.cc b/game/3dobject.cc
new file mode 100644 (file)
index 0000000..4faed54
--- /dev/null
@@ -0,0 +1,123 @@
+#include "3dobject.hh"
+
+#include "surface.hh"
+#include <boost/filesystem/fstream.hpp>
+#include <boost/lexical_cast.hpp>
+#include <sstream>
+#include <stdexcept>
+
+// TODO: test & fix faces that doesn't have texcoords in the file
+// TODO: group handling for loader
+
+namespace {
+       static const int HAS_TEXCOORDS = 1;
+       static const int HAS_NORMALS = 2;
+
+       /// Returns a word (delimited by delim) in a string st at position pos (1-based)
+       std::string getWord(std::string& st, size_t pos, char delim) {
+               std::istringstream iss(st);
+               std::string ret;
+               for (size_t i = 1; i <= pos; i++)
+                       getline(iss, ret, delim);
+               return ret;
+       }
+}
+
+/// A polygon containing links to required point data
+struct Face {
+       std::vector<int> vertices;
+       std::vector<int> texcoords;
+       std::vector<int> normals;
+};
+
+/// Load a Wavefront .obj file and possibly scale it also
+void Object3d::loadWavefrontObj(fs::path const& filepath, float scale) {
+       int linenumber = 0;
+       std::string row;
+       fs::ifstream file(filepath, std::ios::binary);
+       if (!file) throw std::runtime_error("Couldn't open object file "+filepath.string());
+       std::vector<glmath::vec3> vertices;
+       std::vector<glmath::vec3> normals;
+       std::vector<glmath::vec2> texcoords;
+       std::vector<Face> m_faces;
+       while (getline(file, row)) {
+               ++linenumber;
+               std::istringstream srow(row);
+               float x,y,z;
+               std::string tempst;
+               if (row.substr(0,2) == "v ") {  // Vertices
+                       srow >> tempst >> x >> y >> z;
+                       vertices.push_back(glmath::vec3(x*scale, y*scale, z*scale));
+               } else if (row.substr(0,2) == "vt") {  // Texture Coordinates
+                       srow >> tempst >> x >> y;
+                       texcoords.push_back(glmath::vec2(x, y));
+               } else if (row.substr(0,2) == "vn") {  // Normals
+                       srow >> tempst >> x >> y >> z;
+                       double sum = std::abs(x)+std::abs(y)+std::abs(z);
+                       if (sum == 0) throw std::runtime_error("Invalid normal in "+filepath.string()+":"+boost::lexical_cast<std::string>(linenumber));
+                       x /= sum; y /= sum; z /= sum; // Normalize components
+                       normals.push_back(glmath::vec3(x, y, z));
+               } else if (row.substr(0,2) == "f ") {  // Faces
+                       Face f;
+                       srow >> tempst; // Eat away prefix
+                       // Parse face point's coordinate references
+                       for (std::string fpoint; srow >> fpoint; ) {
+                               for (size_t i = 1; i <= 3; ++i) {
+                                       std::string st_id(getWord(fpoint,i,'/'));
+                                       if (!st_id.empty()) {
+                                               // Vertex indices are 1-based in the file
+                                               int v_id = boost::lexical_cast<int>(st_id) - 1;
+                                               switch (i) {
+                                                       case 1: f.vertices.push_back(v_id); break;
+                                                       case 2: f.texcoords.push_back(v_id); break;
+                                                       case 3: f.normals.push_back(v_id); break;
+                                               }
+                                       }
+                               }
+                       }
+                       if (!f.vertices.empty() && f.vertices.size() != 3)
+                               throw std::runtime_error("Only triangle faces allowed in "+filepath.string()+":"+boost::lexical_cast<std::string>(linenumber));
+                       // Face must have equal number of v, vt, vn or none of a kind
+                       if (!f.vertices.empty()
+                         && (f.texcoords.empty() || (f.texcoords.size() == f.vertices.size()))
+                         && (f.normals.empty()   || (f.normals.size() == f.vertices.size()))) {
+                               m_faces.push_back(f);
+                       } else {
+                               throw std::runtime_error("Invalid face in "+filepath.string()+":"+boost::lexical_cast<std::string>(linenumber));
+                       }
+               }
+       }
+       // Construct a vertex array
+       for (std::vector<Face>::const_iterator i = m_faces.begin(); i != m_faces.end(); ++i) {
+               bool hasNormals = !i->normals.empty();
+               bool hasTexCoords = !i->texcoords.empty();
+               for (size_t j = 0; j < i->vertices.size(); ++j) {
+                       if (hasNormals) m_va.normal(normals[i->normals[j]]);
+                       if (hasTexCoords) m_va.texCoord(texcoords[i->texcoords[j]]);
+                       m_va.vertex(vertices[i->vertices[j]]);
+               }
+       }
+       // Models loaded from disk are assumed static, so optimized with a VBO
+       m_va.generateVBO();
+}
+
+void Object3d::load(fs::path const& filepath, fs::path const& texturepath, float scale) {
+       if (!texturepath.empty()) m_texture.reset(new Texture(texturepath));
+       loadWavefrontObj(filepath, scale);
+}
+
+void Object3d::draw() {
+       UseShader us(getShader("3dobject"));
+       if (m_texture) {
+               UseTexture tex(*m_texture);
+               m_va.draw(GL_TRIANGLES);
+       } else {
+               m_va.draw(GL_TRIANGLES);
+       }
+}
+
+void Object3d::draw(float x, float y, float z, float s) {
+       using namespace glmath;
+       Transform trans(translate(vec3(x, y, z)) * scale(s));  // Move to position and scale
+       draw();
+}
diff --git a/game/3dobject.hh b/game/3dobject.hh
new file mode 100644 (file)
index 0000000..c75636d
--- /dev/null
@@ -0,0 +1,32 @@
+#pragma once
+
+#include <string>
+#include <boost/scoped_ptr.hpp>
+#include <boost/noncopyable.hpp>
+#include "glshader.hh"
+
+// TODO: Exception handling
+// TODO: Texture loading
+
+class Surface;
+
+/// A class representing 3d object
+/// Non-copyable because of display lists getting messed up
+class Object3d: boost::noncopyable {
+  private:
+       glutil::VertexArray m_va;
+       boost::scoped_ptr<Surface> m_texture; /// texture
+       /// load a Wavefront .obj 3d object file
+       void loadWavefrontObj(fs::path const& filepath, float scale = 1.0);
+  public:
+       Object3d() {}
+       Object3d(fs::path const& filepath, fs::path const& texturepath = fs::path(), float scale = 1.0) {
+               load(filepath, texturepath, scale);
+       }
+       /// load a new object file
+       void load(fs::path const& filepath, fs::path const& texturepath = fs::path(), float scale = 1.0);
+       /// draws the object (with texture if given)
+       void draw();
+       /// draws the object with a transform
+       void draw(float x, float y, float z = 0, float s = 1.0);
+};
diff --git a/game/CMakeLists.txt b/game/CMakeLists.txt
new file mode 100644 (file)
index 0000000..9b43b14
--- /dev/null
@@ -0,0 +1,163 @@
+cmake_minimum_required(VERSION 2.6)
+
+file(GLOB SOURCE_FILES "*.cc")
+file(GLOB HEADER_FILES "*.hh" "libda/*.hpp")
+
+if(WIN32)
+       if(ENABLE_VERSIONING)
+               set(COMMENTS)
+               string(REGEX MATCHALL "([^\\.,^$]+)(\\.|,|$)"  VERSIONING ${PROJECT_VERSION})
+               set(VERSIONS "MAJOR" "MINOR" "PATCH" "TWEAK")
+               foreach(s ${VERSIONING})
+                       # We get the most-right number
+                       string(REGEX REPLACE "[^0-9]+$" "" s ${s})#removes most right part non-numeric (like .)
+                       # Now we have a string in format <numbers-letters..........numbers>
+                       # Take last numbers (if there are)
+                       # If string not empty, there are some numbers in right of string
+                       # otherwise, set a 0, to be sure that there's a number
+                       if(s STREQUAL "")
+                               set(s "0")
+                       endif()
+                       string(REGEX MATCH "[0-9]*$" s ${s})
+
+                       foreach(v ${VERSIONS})
+                               if(NOT VERSION_${v}_DONE)
+                                       set(VERSION_${v}_DONE 1)
+                                       set(VERSION_${v} "${s}")
+                                       break()
+                               endif()
+                       endforeach()
+               endforeach()
+
+               foreach(v ${VERSIONS})
+                       if(NOT VERSION_${v}_DONE OR VERSION_${v} STREQUAL "") #For the substitution did before, in VERSION_${v} we have or a empty string (if all letters) or a number
+                               set(VERSION_${v} "0")
+                       endif()
+               endforeach()
+               message(STATUS "Setting .exe version: ${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_PATCH}.${VERSION_TWEAK}")
+       else(ENABLE_VERSIONING)
+               set(COMMENTS "//")
+       endif(ENABLE_VERSIONING)
+       set(RESOURCE_FILES "${CMAKE_BINARY_DIR}/performous.rc")
+
+       configure_file("../win32/performous.cmake.rc" "${RESOURCE_FILES}")
+       if(MINGW)
+               # According to MinGW tools, we need to compile the rc file, and then link it into projects:
+               # windres foo.rc foores.o
+               # gcc -o foo.exe foo.o foores.o
+               if(NOT CMAKE_RC_COMPILER)
+                       find_program(CMAKE_RC_COMPILER windres)
+               endif()
+               if(NOT CMAKE_RC_COMPILER)
+                       message(STATUS "Cannot find windres. Will not create a versioned exe.")
+                       set(RESOURCE_FILES)
+               else()
+                       set(CMAKE_RC_COMPILE_OBJECT "<CMAKE_RC_COMPILER> <FLAGS> -O coff <DEFINES> -i <SOURCE> -o <OBJECT>")
+               endif()
+       endif()
+else()
+       set(RESOURCE_FILES) #nothing
+endif()
+
+set(SOURCES ${SOURCE_FILES} ${HEADER_FILES} ${RESOURCE_FILES})
+
+# Libraries
+
+find_package(Boost 1.36 REQUIRED COMPONENTS thread date_time program_options regex filesystem system)
+include_directories(${Boost_INCLUDE_DIRS})
+list(APPEND LIBS ${Boost_LIBRARIES})
+
+# Find all the libs that don't require extra parameters
+foreach(lib ${OUR_LIBS} SDL2 PangoCairo LibRSVG LibXML++ GLEW AVFormat AVResample SWScale OpenGL Z Jpeg Png PortAudio Fontconfig)
+       find_package(${lib} REQUIRED)
+       message(STATUS "${lib} includes: ${${lib}_INCLUDE_DIRS}")
+       include_directories(${${lib}_INCLUDE_DIRS})
+       list(APPEND LIBS ${${lib}_LIBRARIES})
+       add_definitions(${${lib}_DEFINITIONS})
+endforeach(lib)
+
+find_package(Gettext)
+if(Gettext_FOUND)
+       include_directories(${Gettext_INCLUDE_DIRS})
+       list(APPEND LIBS ${Gettext_LIBRARIES})
+       add_definitions("-DUSE_GETTEXT")
+       message(STATUS "Internationalization: Enabled")
+else()
+       message(STATUS "Internationalization: Disabled (libintl not found)")
+endif()
+
+option(ENABLE_MIDI "Enable support for MIDI hardware (e-drums with USB/MIDI connection)." ON)
+if(ENABLE_MIDI)
+       find_package(PortMidi)
+       if(PortMidi_FOUND)
+               include_directories(${PortMidi_INCLUDE_DIRS})
+               list(APPEND LIBS ${PortMidi_LIBRARIES})
+               add_definitions("-DUSE_PORTMIDI")
+               message(STATUS "MIDI I/O: Enabled")
+       else()
+               message(STATUS "MIDI I/O: Disabled (libportmidi not found)")
+       endif()
+else()
+       message(STATUS "MIDI I/O: Disabled (explicitly disabled)")
+endif()
+
+option(ENABLE_WEBCAM "Enable webcam support (OpenCV)." ON)
+if(ENABLE_WEBCAM)
+       find_package(OpenCV)
+       if(OpenCV_FOUND)
+               include_directories(${OpenCV_INCLUDE_DIRS})
+               list(APPEND LIBS ${OpenCV_LIBS})
+               add_definitions("-DUSE_OPENCV")
+               message(STATUS "Webcam support: Enabled")
+       else()
+               message(STATUS "Webcam support: Disabled (libcv/libhighgui not found)")
+       endif()
+else()
+       message(STATUS "Webcam support: Disabled (explicitly disabled)")
+endif()
+
+
+if(APPLE)
+       # Needed for ffmpeg.cc to compile cleanly on OSX (it's a (unsigned long) long story)
+       add_definitions("-D__STDC_CONSTANT_MACROS")
+endif(APPLE)
+
+if(UNIX)
+       # Note: cannot use list APPEND here because it inserts semicolons instead of spaces
+       set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -pthread")
+       set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -pthread")
+endif(UNIX)
+
+if(WIN32)
+       option(MXE_HACK "Features horrible hacks, but is able to compile a static performous.exe (that may not work)." OFF)
+       mark_as_advanced(MXE_HACK)
+       if(MXE_HACK)
+               execute_process(COMMAND "${CMAKE_SOURCE_DIR}/win32/mxe/libs.sh"
+                       OUTPUT_VARIABLE MXE_HACK_STRING
+               )
+               set(CMAKE_CXX_LINK_EXECUTABLE ${CMAKE_CXX_LINK_EXECUTABLE}${MXE_HACK_STRING})
+               add_definitions(-DBOOST_THREAD_USE_LIB -DGLEW_STATIC)
+       endif()
+       set(BIN_INSTALL .)  # Straight to Program Files/Performous with no bin subfolder.
+       set(SUBSYSTEM_WIN32 WIN32)
+else()
+       set(BIN_INSTALL bin)
+endif()
+
+# Build main executable
+add_executable(performous ${SUBSYSTEM_WIN32} ${SOURCES} ${SDL2_SOURCES})
+target_link_libraries(performous ${LIBS})
+install(TARGETS performous DESTINATION ${BIN_INSTALL})
+
+set_target_properties(performous PROPERTIES INSTALL_RPATH_USE_LINK_PATH TRUE)  # Store library paths in executable
+set_target_properties(performous PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR})  # Produce executable in build/, not build/game/
+
+# Capitalized Performous.exe on Windows (this is considered more beautiful).
+if(WIN32)
+       set_target_properties(performous PROPERTIES OUTPUT_NAME "Performous")
+endif()
+
+# Generate config.hh
+configure_file("${CMAKE_CURRENT_SOURCE_DIR}/config.cmake.hh" "${CMAKE_CURRENT_BINARY_DIR}/config.hh" @ONLY)
+include_directories("${CMAKE_CURRENT_BINARY_DIR}")
+
diff --git a/game/animvalue.hh b/game/animvalue.hh
new file mode 100644 (file)
index 0000000..c925e92
--- /dev/null
@@ -0,0 +1,117 @@
+#pragma once
+
+#include "util.hh"
+#include "xtime.hh"
+#include <cmath>
+#include <stdexcept>
+
+/// class for simple/linear animation/transition of values
+class AnimValue {
+  public:
+       /// constructor
+       AnimValue(double value = 0.0, double rate = 1.0): m_value(value), m_target(value), m_rate(rate), m_time(now()) {}
+       /// move animation forward by diff
+       void move(double diff) { m_value += diff; }
+       /// gets animition target
+       double getTarget() const { return m_target; }
+       /// sets animation target (end point)
+       void setTarget(double target, bool step = false) { m_target = target; if (step) m_value = target; }
+       /// sets animation range
+       void setRange(double tmin, double tmax) {
+               if (tmin > tmax) throw std::logic_error("AnimValue range is reversed");
+               m_target = clamp(m_target, tmin, tmax);
+       }
+       /// hard-sets anim value
+       void setValue(double value) { m_value = value; }
+       /// set the adjustment rate
+       void setRate(double value) { m_rate = value; }
+       /// get current anim value
+       double get() const {
+               double maxadj = m_rate * duration();
+               double diff = m_value - m_target;
+               double adj = std::min(maxadj, std::fabs(diff));
+               if (diff > 0.0) m_value -= adj; else m_value += adj;
+               return m_value;
+       }
+
+  private:
+       double duration() const {
+               boost::xtime newtime = now();
+               double t = newtime - m_time;
+               m_time = newtime;
+               return clamp(t, 0.0, 1.0);
+       }
+       mutable double m_value;
+       double m_target;
+       double m_rate;
+       mutable boost::xtime m_time;
+};
+
+/// easing animations
+class AnimAcceleration {
+  public:
+       /// constructor
+       AnimAcceleration(): m_target(), m_songs(), m_position(), m_velocity(), m_marginLeft(), m_marginRight(), m_time() {}
+       /// set margins
+       void setMargins(double left, double right) { m_marginLeft = left; m_marginRight = right; }
+       /// get current value
+       double getValue() {
+               const double acceleration = 50.0; // the coefficient of velocity changes (animation speed)
+               const double overshoot = 0.95; // Over 1.0 decelerates too late, less than 1.0 decelerates too early
+               if (m_songs == 0) return m_target;
+               double num = m_marginLeft + m_songs + m_marginRight;
+               boost::xtime curtime = now();
+               double duration = seconds(curtime) - seconds(m_time);
+               m_time = curtime;
+               if (!(duration > 0.0)) return m_position; // Negative value or NaN, or no songs - skip processing
+               if (duration > 1.0) {
+                       // More than one second has elapsed, assume that we have stopped on target already
+                       m_velocity = 0.0;
+                       return m_position = m_target;
+               }
+               std::size_t rounds = 1.0 + 1000.0 * duration; // 1 ms or shorter timesteps
+               double t = duration / rounds;
+               for (std::size_t i = 0; i < rounds; ++i) {
+                       double d = remainder(m_target - m_position, num); // Distance (via shortest way)
+                       // Allow it to stop nicely, without jitter
+                       if (std::abs(m_velocity) < 0.1 && std::abs(d) < 0.001) {
+                               m_velocity = 0.0;
+                               m_position = m_target;
+                               break;
+                       }
+                       double a = d > 0.0 ? acceleration : -acceleration; // Acceleration vector
+                       // Are we going to right direction && can we stop in time if we start decelerating now?
+                       if (d * m_velocity > 0.0 && std::abs(m_velocity) > 2.0 * overshoot * acceleration * d / m_velocity) a *= -1.0;
+                       // Apply Newtonian mechanics
+                       m_velocity += t * a;
+                       m_position += t * m_velocity;
+               }
+               if ((m_position = fmod(m_position, num)) < 0.0) m_position += num; // Normalize to [0, num]
+               if (m_position > m_marginLeft + m_songs) m_position -= num; // Normalize to [-m_marginLeft, songs + m_marginRight]
+               return m_position;
+       }
+       /// get target
+       unsigned int getTarget() const { return m_target; };
+       /// set target
+       void setTarget(unsigned int target, unsigned int songs) {
+               m_target = target;
+               if (m_songs == songs) return;
+               // Number of songs has changed => reset animation
+               m_songs = songs;
+               m_position = target;
+               m_velocity = 0.0;
+       };
+       /// resets animation target to 0
+       void reset() { setTarget(0, 0); }
+       /// get current velocity
+       double getVelocity() const { return m_velocity; }
+
+  private:
+       unsigned int m_target;
+       unsigned int m_songs;
+       double m_position;
+       double m_velocity;
+       double m_marginLeft;
+       double m_marginRight;
+       boost::xtime m_time;
+};
diff --git a/game/audio.cc b/game/audio.cc
new file mode 100644 (file)
index 0000000..acf93d3
--- /dev/null
@@ -0,0 +1,633 @@
+#include "audio.hh"
+
+#include "configuration.hh"
+#include "util.hh"
+#include "libda/fft.hpp"  // For M_PI
+#include "libda/portaudio.hpp"
+#include <boost/ptr_container/ptr_map.hpp>
+#include <boost/ptr_container/ptr_vector.hpp>
+#include <boost/range/iterator_range.hpp>
+#include <boost/thread/mutex.hpp>
+#include <boost/lexical_cast.hpp>
+#include <cmath>
+#include <iostream>
+#include <map>
+
+using namespace boost::posix_time;
+
+namespace {
+       /**
+        * A function to parse key=value pairs with quoting capabilites.
+        */
+       std::map<std::string, std::string> parseKeyValuePairs(const std::string& st) {
+               std::map<std::string, std::string> ret;
+               bool inside_quotes = false;
+               int parsing_key = true;
+               std::string key = "", value = "";
+               for (size_t i = 0; i < st.size(); ++i) {
+                       // Quotes
+                       if (st[i] == '"') { inside_quotes = !inside_quotes; continue; }
+                       // Value end
+                       if (st[i] == ' ' && !inside_quotes && !parsing_key) {
+                               if (value.empty()) continue; // Skip whitespace after equals sign
+                               ret[key] = value;
+                               key = ""; value = "";
+                               parsing_key = true;
+                               continue;
+                       }
+                       // Space in key (bad)
+                       if (st[i] == ' ' && parsing_key && !key.empty())
+                               throw std::logic_error("Space in key in string: " + st);
+                       // Value start
+                       if (st[i] == '=' && !inside_quotes) {
+                               if (key.empty()) throw std::logic_error("Empty key in string: " + st);
+                               parsing_key = false;
+                               continue;
+                       }
+                       // Key start
+                       if (st[i] != ' ' && parsing_key) { key += st[i]; continue; }
+                       // If we got here, it is value
+                       value += st[i];
+               }
+               // Handle last key
+               if (!key.empty()) ret[key] = value;
+               return ret;
+       }
+
+       /**
+        * Pitch shifter.
+        * @param begin start of the buffer
+        * @param end end of the buffer
+        * @param factor shift factor from 0 (no shift) to 1 (maximum)
+        */
+       template <typename It> void PitchShift(It begin, It end, double factor) {
+               //FIXME: Dummy volume bender
+               for (It i = begin; i != end; ++i)
+                       *i *= factor * factor; // Decrease music volume
+       }
+}
+/**
+* Advanced audio sync code.
+* Produces precise monotonic clock synced to audio output callback (which may suffer of major jitter).
+* Uses system clock as timebase but the clock is skewed (made slower or faster) depending on whether
+* it is late or early. The clock is also stopped if audio output pauses.
+**/
+class AudioClock {
+       static ptime getTime() { return microsec_clock::universal_time(); }
+       // Conversion helpers
+       static double getSeconds(time_duration t) { return 1e-6 * t.total_microseconds(); }
+       static time_duration getDuration(double seconds) { return microseconds(1e6 * seconds); }
+
+       mutable boost::mutex m_mutex;
+       ptime m_baseTime; ///< A reference time (corresponds to m_basePos)
+       double m_basePos; ///< A reference position in song
+       double m_skew; ///< The skew ratio applied to system time (since baseTime)
+       volatile float m_max; ///< Maximum output value for the clock (end of the current audio block)
+       /// Get the current position (current time via parameter, no locking)
+       double pos_internal(ptime now) const {
+               double t = m_basePos + (1.0 + m_skew) * getSeconds(now - m_baseTime);
+               return std::min<double>(t, m_max);
+       }
+public:
+       AudioClock(): m_baseTime(), m_basePos(), m_skew(), m_max() {}
+       /**
+       * Called from audio callback to keep the clock synced.
+       * @param audioPos the current position in the song
+       * @param length the duration of the current audio block
+       */
+       void timeSync(time_duration audioPos, time_duration length) {
+               constexpr double maxError = 0.1;  // Step the clock instead of skewing if over 100 ms off
+               // Full correction requires locking, but we can update max without lock too
+               boost::mutex::scoped_try_lock l(m_mutex, boost::defer_lock);
+               double max = getSeconds(audioPos + length);
+               if (!l.try_lock()) {
+                       if (max > m_max) m_max = max; // Allow increasing m_max
+                       return;
+               }
+               // Mutex locked - do a full update
+               ptime now = getTime();
+               const double sys = pos_internal(now);  // Current position (based on system clock + corrections)
+               const double audio = getSeconds(audioPos);  // Audio time
+               const double diff = audio - sys;
+               // Skew-based correction only if going forward and relatively well synced
+               if (max > m_max && std::abs(diff) < maxError) {
+                       constexpr double fudgeFactor = 0.001;  // Adjustment ratio
+                       // Update base position (this should not affect the clock)
+                       m_baseTime = now;
+                       m_basePos = sys;
+                       // Apply a VERY ARTIFICIAL correction for clock!
+                       const double valadj = getSeconds(length) * 0.1 * rand() / RAND_MAX;  // Dither
+                       m_skew += (diff < valadj ? -1.0 : 1.0) * fudgeFactor;
+                       // Limits to keep things sane in abnormal situations
+                       m_skew = clamp(m_skew, -0.01, 0.01);
+               } else {
+                       // Off too much, step to correct time
+                       m_baseTime = now;
+                       m_basePos = audio;
+                       m_skew = 0.0;
+               }
+               m_max = max;
+       }
+       /// Get the current position in seconds
+       double pos() const {
+               boost::mutex::scoped_lock l(m_mutex);
+               return pos_internal(getTime());
+       }
+};
+
+class Music {
+       struct Track {
+               FFmpeg mpeg;
+               float fadeLevel;
+               float pitchFactor;
+               Track(fs::path const& filename, unsigned int sr): mpeg(filename, sr), fadeLevel(1.0f), pitchFactor(0.0f) {}
+       };
+       typedef boost::ptr_map<std::string, Track> Tracks;
+       Tracks tracks; ///< Audio decoders
+       double srate; ///< Sample rate
+       int64_t m_pos; ///< Current sample position
+       bool m_preview;
+       AudioClock m_clock;
+       time_duration durationOf(int64_t samples) const { return microseconds(1e6 * samples / srate / 2.0); }
+public:
+       double fadeLevel;
+       double fadeRate;
+       typedef std::vector<float> Buffer;
+       Music(Audio::Files const& files, unsigned int sr, bool preview):
+         srate(sr), m_pos(), m_preview(preview), fadeLevel(), fadeRate()
+       {
+               for (auto const& tf /* trackname-filename pair */: files) {
+                       if (tf.second.empty()) continue; // Skip tracks with no filenames; FIXME: Why do we even have those here, shouldn't they be eliminated earlier?
+                       tracks.insert(tf.first, std::auto_ptr<Track>(new Track(tf.second, sr)));
+               }
+       }
+       /// Sums the stream to output sample range, returns true if the stream still has audio left afterwards.
+       bool operator()(float* begin, float* end) {
+               size_t samples = end - begin;
+               m_clock.timeSync(durationOf(m_pos), durationOf(samples)); // Keep the clock synced
+               bool eof = true;
+               Buffer mixbuf(end - begin);
+               for (Tracks::iterator it = tracks.begin(), itend = tracks.end(); it != itend; ++it) {
+                       Track& t = *it->second;
+// FIXME: Include this code bit once there is a sane pitch shifting algorithm
+#if 0
+//                     if (it->first == "guitar") std::cout << t.pitchFactor << std::endl;
+                       if (t.pitchFactor != 0) { // Pitch shift
+                               Buffer tempbuf(end - begin);
+                               // Get audio to temp buffer
+                               if (t.mpeg.audioQueue(&*tempbuf.begin(), &*tempbuf.end(), m_pos, t.fadeLevel)) eof = false;
+                               // Do the magic
+                               PitchShift(&*tempbuf.begin(), &*tempbuf.end(), t.pitchFactor);
+                               // Mix with other tracks
+                               Buffer::iterator m = mixbuf.begin();
+                               Buffer::iterator b = tempbuf.begin();
+                               while (b != tempbuf.end())
+                                       *m++ += (*b++);
+                       // Otherwise just get the audio and mix it straight away
+                       } else
+#endif
+                       if (t.mpeg.audioQueue(&*mixbuf.begin(), &*mixbuf.end(), m_pos, t.fadeLevel)) eof = false;
+               }
+               m_pos += samples;
+               for (size_t i = 0, iend = mixbuf.size(); i != iend; ++i) {
+                       if (i % 2 == 0) {
+                               fadeLevel += fadeRate;
+                               if (fadeLevel <= 0.0) return false;
+                               if (fadeLevel > 1.0) { fadeLevel = 1.0; fadeRate = 0.0; }
+                       }
+                       begin[i] += mixbuf[i] * fadeLevel * static_cast<float>(m_preview ? config["audio/preview_volume"].i() : config["audio/music_volume"].i())/100.0;
+               }
+               return !eof;
+       }
+       void seek(double time) { m_pos = time * srate * 2.0; }
+       /// Get the current position in seconds
+       double pos() const { return m_clock.pos(); }
+       double duration() const {
+               double dur = 0.0;
+               for (Tracks::const_iterator it = tracks.begin(), itend = tracks.end(); it != itend; ++it) {
+                       dur = std::max(dur, it->second->mpeg.audioQueue.duration());
+               }
+               return dur;
+       }
+       /// Prepare (seek) all tracks to current position, return true when done (nonblocking)
+       bool prepare() {
+               bool ready = true;
+               for (Tracks::iterator it = tracks.begin(), itend = tracks.end(); it != itend; ++it) {
+                       FFmpeg& mpeg = it->second->mpeg;
+                       if (mpeg.terminating()) continue;  // Song loading failed or other error, won't ever get ready
+                       if (mpeg.audioQueue.prepare(m_pos)) continue;  // Buffering done
+                       ready = false;  // Need to wait for buffering
+                       break;
+               }
+               return ready;
+       }
+       void trackFade(std::string const& name, double fadeLevel) {
+               Tracks::iterator it = tracks.find(name);
+               if (it == tracks.end()) return;
+               it->second->fadeLevel = fadeLevel;
+       }
+       void trackPitchBend(std::string const& name, double pitchFactor) {
+               Tracks::iterator it = tracks.find(name);
+               if (it == tracks.end()) return;
+               it->second->pitchFactor = pitchFactor;
+       }
+};
+
+struct Sample {
+  private:
+       double m_pos;
+       FFmpeg mpeg;
+       bool eof;
+  public:
+       Sample(fs::path const& filename, unsigned sr) : m_pos(), mpeg(filename, sr), eof(true) { }
+       void operator()(float* begin, float* end) {
+               if(eof) {
+                       // No more data to play in this sample
+                       return;
+               }
+               std::vector<float> mixbuf(end - begin);
+               if(!mpeg.audioQueue(&*mixbuf.begin(), &*mixbuf.end(), m_pos, 1.0)) {
+                       eof = true;
+               }
+               for (size_t i = 0, iend = end - begin; i != iend; ++i) {
+                       begin[i] += mixbuf[i] * static_cast<float>(config["audio/fail_volume"].i())/100.0;
+               }
+               m_pos += end - begin;
+       }
+       void reset() {
+               eof = false;
+               m_pos = 0;
+       }
+};
+
+struct Synth {
+  private:
+       Notes m_notes;
+       double srate; ///< Sample rate
+  public:
+       Synth(Notes const& notes, unsigned int sr) : m_notes(notes), srate(sr) {}
+       void operator()(float* begin, float* end, double position) {
+               static double phase = 0.0;
+               for (float *i = begin; i < end; ++i) *i *= 0.3; // Decrease music volume
+
+               std::vector<float> mixbuf(end - begin);
+               Notes::const_iterator it = m_notes.begin();
+
+               while (it != m_notes.end() && it->end < position) ++it;
+               if (it == m_notes.end() || it->type == Note::SLEEP || it->begin > position) { phase = 0.0; return; }
+               int note = it->note % 12;
+               double d = (note + 1) / 13.0;
+               double freq = MusicalScale().setNote(note + 4 * 12).getFreq();
+               double value = 0.0;
+               // Synthesize tones
+               for (size_t i = 0, iend = mixbuf.size(); i != iend; ++i) {
+                       if (i % 2 == 0) {
+                               value = d * 0.2 * std::sin(phase) + 0.2 * std::sin(2 * phase) + (1.0 - d) * 0.2 * std::sin(4 * phase);
+                               phase += 2.0 * M_PI * freq / srate;
+                       }
+                       begin[i] += value;
+               }
+       }
+};
+
+struct Command {
+       enum { TRACK_FADE, TRACK_PITCHBEND, SAMPLE_RESET } type;
+       std::string track;
+       double factor;
+};
+
+/// Audio output callback wrapper. The playback Device calls this when it needs samples.
+struct Output {
+       boost::mutex mutex;
+       boost::mutex samples_mutex;
+       boost::mutex synth_mutex;
+       std::auto_ptr<Synth> synth;
+       std::auto_ptr<Music> preloading;
+       boost::ptr_vector<Music> playing, disposing;
+       std::vector<Analyzer*> mics;  // Used for audio pass-through
+       boost::ptr_map<std::string, Sample> samples;
+       std::vector<Command> commands;
+       volatile bool paused;
+       Output(): paused(false) {}
+
+       void callbackUpdate() {
+               boost::mutex::scoped_try_lock l(mutex);
+               if (!l.owns_lock()) return;  // No update now, try again later (cannot stop and wait for mutex to be released)
+               // Move from preloading to playing, if ready
+               if (preloading.get() && preloading->prepare()) {
+                       if (!playing.empty()) playing[0].fadeRate = -preloading->fadeRate;  // Fade out the old music
+                       playing.insert(playing.begin(), preloading);
+               }
+               // Process commands
+               for (auto const& cmd: commands) {
+                       switch (cmd.type) {
+                       case Command::TRACK_FADE:
+                               if (!playing.empty()) playing[0].trackFade(cmd.track, cmd.factor);
+                               break;
+                       case Command::TRACK_PITCHBEND:
+                               if (!playing.empty()) playing[0].trackPitchBend(cmd.track, cmd.factor);
+                               break;
+                       case Command::SAMPLE_RESET:
+                               boost::ptr_map<std::string, Sample>::iterator it = samples.find(cmd.track);
+                               if (it != samples.end())
+                                       it->second->reset();
+                               break;
+                       }
+               }
+               commands.clear();
+       }
+
+       void callback(float* begin, float* end, double rate) {
+               callbackUpdate();
+               std::fill(begin, end, 0.0f);
+               if (paused) return;
+               // Mix in from the streams currently playing
+               for (size_t i = 0; i < playing.size();) {
+                       bool keep = playing[i](begin, end);  // Do the actual mixing
+                       boost::mutex::scoped_try_lock l(mutex, boost::defer_lock);
+                       if (!keep && l.try_lock()) {
+                               // Dispose streams no longer needed by moving them to another container (that will be cleared by another thread).
+                               disposing.transfer(disposing.end(), playing.begin() + i, playing);
+                               continue;
+                       }
+                       ++i;
+               }
+               // Mix in microphones (if pass-through is enabled)
+               if (mics.size() > 0 && config["audio/pass-through"].b()) {
+                       // Decrease music volume
+                       float amp = 1.0f / config["audio/pass-through_ratio"].f();
+                       if (amp != 1.0f) for (auto& s: boost::make_iterator_range(begin, end)) s *= amp;
+                       // Do the mixing
+                       for (auto& m: mics) if (m) m->output(begin, end, rate);
+               }
+               // Mix in the samples currently playing
+               {
+                       // samples should not be created/destroyed on the fly
+                       boost::mutex::scoped_try_lock l(samples_mutex, boost::defer_lock);
+                       if(l.try_lock()) {
+                               for(boost::ptr_map<std::string, Sample>::iterator it = samples.begin() ; it != samples.end() ; ++it) {
+                                       (*it->second)(begin, end);
+                               }
+                       }
+               }
+               // Mix synth if available (should be done at the end)
+               {
+                       boost::mutex::scoped_try_lock l(synth_mutex, boost::defer_lock);
+                       if(l.try_lock() && synth.get() && !playing.empty()) {
+                               (*synth.get())(begin, end, playing[0].pos());
+                       }
+               }
+       }
+};
+
+
+Device::Device(unsigned int in, unsigned int out, double rate, unsigned int dev):
+  in(in), out(out), rate(rate), dev(dev),
+  stream(
+    *this,
+    portaudio::Params().channelCount(in).device(dev).suggestedLatency(config["audio/latency"].f()),
+       portaudio::Params().channelCount(out).device(dev).suggestedLatency(config["audio/latency"].f()),
+       rate),
+  mics(in, nullptr),
+  outptr()
+{}
+
+void Device::start() {
+       PaError err = Pa_StartStream(stream);
+       if (err != paNoError) throw std::runtime_error(std::string("Pa_StartStream: ") + Pa_GetErrorText(err));
+}
+
+int Device::operator()(void const* input, void* output, unsigned long frames, const PaStreamCallbackTimeInfo*, PaStreamCallbackFlags) try {
+       float const* inbuf = static_cast<float const*>(input);
+       float* outbuf = static_cast<float*>(output);
+       for (std::size_t i = 0; i < mics.size(); ++i) {
+               if (!mics[i]) continue;  // No analyzer? -> Channel not used
+               da::sample_const_iterator it = da::sample_const_iterator(inbuf + i, in);
+               mics[i]->input(it, it + frames);
+       }
+       if (outptr) outptr->callback(outbuf, outbuf + 2 * frames, rate);
+       return paContinue;
+} catch (std::exception& e) {
+       std::cerr << "Exception in audio callback: " << e.what() << std::endl;
+       return paAbort;
+}
+
+
+
+struct Audio::Impl {
+       Output output;
+       portaudio::Init init;
+       boost::ptr_vector<Analyzer> analyzers;
+       boost::ptr_vector<Device> devices;
+       bool playback;
+       Impl(): init(), playback() {
+               std::clog << "audio/info: " << portaudio::AudioDevices().dump() << std::flush;
+               // Parse audio devices from config
+               ConfigItem::StringList devs = config["audio/devices"].sl();
+               for (ConfigItem::StringList::const_iterator it = devs.begin(), end = devs.end(); it != end; ++it) {
+                       try {
+                               struct Params {
+                                       unsigned out, in;
+                                       unsigned int rate;
+                                       std::string dev;
+                                       std::vector<std::string> mics;
+                               } params = Params();
+                               params.out = 0;
+                               params.in = 0;
+                               params.rate = 48000;
+                               // Break into tokens:
+                               std::map<std::string, std::string> keyvalues = parseKeyValuePairs(*it);
+                               for (std::map<std::string, std::string>::const_iterator it2 = keyvalues.begin();
+                                 it2 != keyvalues.end(); ++it2) {
+                                       // Handle keys
+                                       std::string key = it2->first;
+                                       std::istringstream iss(it2->second);
+                                       if (key == "out") iss >> params.out;
+                                       else if (key == "in") iss >> params.in;
+                                       else if (key == "rate") iss >> params.rate;
+                                       else if (key == "dev") std::getline(iss, params.dev);
+                                       else if (key == "mics") {
+                                               // Parse a comma-separated list of mics
+                                               for (std::string mic; std::getline(iss, mic, ','); params.mics.push_back(mic)) {}
+                                       }
+                                       else throw std::runtime_error("Unknown device parameter " + key);
+                                       if (!iss.eof()) throw std::runtime_error("Syntax error parsing device parameter " + key);
+                               }
+                               // Sync mics/in settings together
+                               if (params.in == 0) params.in = params.mics.size();
+                               else params.mics.resize(params.in);
+                               portaudio::AudioDevices ad;
+                               auto const& info = ad.find(params.dev);
+                               std::clog << "audio/info: Trying audio device \"" << params.dev << "\", idx: " << info.idx
+                                       << ", in: " << params.in << ", out: " << params.out << std::endl;
+                               if (info.in < int(params.mics.size())) throw std::runtime_error("Device doesn't have enough input channels");
+                               if (info.out < int(params.out)) throw std::runtime_error("Device doesn't have enough output channels");
+                               // Match found if we got here, construct a device
+                               auto d = new Device(params.in, params.out, params.rate, info.idx);
+                               devices.push_back(d);
+                               // Start capture/playback on this device (likely to throw due to audio system errors)
+                               // NOTE: When it throws we want to keep the device in devices to avoid calling ~Device
+                               // which often would hit the Pa_CloseStream hang bug and terminate the application.
+                               d->start();
+                               // Assign mics for all channels of the device
+                               int assigned_mics = 0;
+                               for (unsigned int j = 0; j < params.in; ++j) {
+                                       if (analyzers.size() >= AUDIO_MAX_ANALYZERS) break; // Too many mics
+                                       std::string const& m = params.mics[j];
+                                       if (m.empty()) continue; // Input channel not used
+                                       // Check that the color is not already taken
+                                       bool mic_used = false;
+                                       for (size_t mi = 0; mi < analyzers.size(); ++mi) {
+                                               if (analyzers[mi].getId() == m) { mic_used = true; break; }
+                                       }
+                                       if (mic_used) continue;
+                                       // Add the new analyzer
+                                       Analyzer* a = new Analyzer(d->rate, m);
+                                       analyzers.push_back(a);
+                                       d->mics[j] = a;
+                                       ++assigned_mics;
+                               }
+                               // Assign playback output for the first available stereo output
+                               if (!playback && d->out == 2) { d->outptr = &output; playback = true; }
+                               std::clog << "audio/info: Using audio device: " << info.desc();
+                               if (assigned_mics) std::clog << ", input channels: " << assigned_mics;
+                               if (params.out) std::clog << ", output channels: " << params.out;
+                               std::clog << std::endl;
+                       } catch(std::runtime_error& e) {
+                               std::clog << "audio/error: Audio device '" << *it << "': " << e.what() << std::endl;
+                       }
+               }
+               // Assign mic buffers to the output for pass-through
+               for (size_t i = 0; i < analyzers.size(); ++i)
+                       output.mics.push_back(&analyzers[i]);
+       }
+};
+
+Audio::Audio(): self(new Impl) {}
+Audio::~Audio() {}
+
+void Audio::restart() { self.reset(new Impl); }
+void Audio::close() { self.reset(); }
+
+bool Audio::isOpen() const {
+       return !self->devices.empty();
+}
+
+bool Audio::hasPlayback() const {
+       for (size_t i = 0; i < self->devices.size(); ++i)
+               if (self->devices[i].isOutput()) return true;
+       return false;
+}
+
+void Audio::loadSample(std::string const& streamId, fs::path const& filename) {
+       boost::mutex::scoped_lock l(self->output.samples_mutex);
+       self->output.samples.insert(streamId, std::auto_ptr<Sample>(new Sample(filename, getSR())));
+}
+
+void Audio::playSample(std::string const& streamId) {
+       Output& o = self->output;
+       boost::mutex::scoped_lock l(o.mutex);
+       Command cmd = { Command::SAMPLE_RESET, streamId, 0.0 };
+       o.commands.push_back(cmd);
+}
+
+void Audio::unloadSample(std::string const& streamId) {
+       boost::mutex::scoped_lock l(self->output.samples_mutex);
+       self->output.samples.erase(streamId);
+}
+
+void Audio::playMusic(Audio::Files const& filenames, bool preview, double fadeTime, double startPos) {
+       Output& o = self->output;
+       boost::mutex::scoped_lock l(o.mutex);
+       o.disposing.clear();  // Delete disposed streams
+       o.preloading.reset(new Music(filenames, getSR(), preview));
+       Music& m = *o.preloading.get();
+       m.seek(startPos);
+       m.fadeRate = 1.0 / getSR() / fadeTime;
+       o.commands.clear();  // Remove old unprocessed commands (they should not apply to the new music)
+}
+
+void Audio::playMusic(fs::path const& filename, bool preview, double fadeTime, double startPos) {
+       Audio::Files m;
+       m["MAIN"] = filename;
+       playMusic(m, preview, fadeTime, startPos);
+}
+
+void Audio::stopMusic() {
+       playMusic(Audio::Files(), false, 0.0);
+       {
+               Output& o = self->output;
+               // stop synth when music is stopped
+               boost::mutex::scoped_lock l(o.synth_mutex);
+               o.synth.reset();
+       }
+}
+
+void Audio::fadeout(double fadeTime) {
+       playMusic(Audio::Files(), false, fadeTime);
+       {
+               Output& o = self->output;
+               // stop synth when music is stopped
+               boost::mutex::scoped_lock l(o.synth_mutex);
+               o.synth.reset();
+       }
+}
+
+double Audio::getPosition() const {
+       Output& o = self->output;
+       boost::mutex::scoped_lock l(o.mutex);
+       return (o.playing.empty() || o.preloading.get()) ? getNaN() : o.playing[0].pos();
+}
+
+double Audio::getLength() const {
+       Output& o = self->output;
+       boost::mutex::scoped_lock l(o.mutex);
+       return (o.playing.empty() || o.preloading.get()) ? getNaN() : o.playing[0].duration();
+}
+
+bool Audio::isPlaying() const {
+       Output& o = self->output;
+       boost::mutex::scoped_lock l(o.mutex);
+       return o.preloading.get() || !o.playing.empty();
+}
+
+void Audio::seek(double offset) {
+       Output& o = self->output;
+       boost::mutex::scoped_lock l(o.mutex);
+       for (auto& trk: o.playing) trk.seek(clamp(trk.pos() + offset, 0.0, trk.duration()));
+       pause(false);
+}
+
+void Audio::seekPos(double pos) {
+       Output& o = self->output;
+       boost::mutex::scoped_lock l(o.mutex);
+       for (auto& trk: o.playing) trk.seek(pos);
+       pause(false);
+}
+
+void Audio::pause(bool state) { self->output.paused = state; }
+bool Audio::isPaused() const { return self->output.paused; }
+
+void Audio::streamFade(std::string track, double fadeLevel) {
+       Output& o = self->output;
+       boost::mutex::scoped_lock l(o.mutex);
+       Command cmd = { Command::TRACK_FADE, track, fadeLevel };
+       o.commands.push_back(cmd);
+}
+
+void Audio::streamBend(std::string track, double pitchFactor) {
+       Output& o = self->output;
+       boost::mutex::scoped_lock l(o.mutex);
+       Command cmd = { Command::TRACK_PITCHBEND, track, pitchFactor };
+       o.commands.push_back(cmd);
+}
+
+void Audio::toggleSynth(Notes const& notes) {
+       Output& o = self->output;
+       boost::mutex::scoped_lock l(o.synth_mutex);
+       o.synth.get() ?  o.synth.reset() : o.synth.reset(new Synth(notes, getSR()));
+}
+
+boost::ptr_vector<Analyzer>& Audio::analyzers() { return self->analyzers; }
+
+boost::ptr_vector<Device>& Audio::devices() { return self->devices; }
diff --git a/game/audio.hh b/game/audio.hh
new file mode 100644 (file)
index 0000000..03ded04
--- /dev/null
@@ -0,0 +1,102 @@
+#pragma once
+
+#include <string>
+#include <vector>
+#include <map>
+
+#include "ffmpeg.hh"
+#include "notes.hh"
+#include "pitch.hh"
+#include "util.hh"
+#include <boost/date_time.hpp>
+#include <boost/ptr_container/ptr_vector.hpp>
+#include <boost/scoped_ptr.hpp>
+#include "libda/portaudio.hpp"
+
+const unsigned AUDIO_MAX_ANALYZERS = 4;
+
+struct Output;
+
+struct Device {
+       // Init
+       const unsigned int in, out;
+       const double rate;
+       const unsigned int dev;
+       portaudio::Stream stream;
+       std::vector<Analyzer*> mics;
+       Output* outptr;
+
+       Device(unsigned int in, unsigned int out, double rate, unsigned int dev);
+       /// Start
+       void start();
+       /// Callback
+       int operator()(void const* input, void* output, unsigned long frames, const PaStreamCallbackTimeInfo*, PaStreamCallbackFlags);
+       /// Returns true if this device is opened for output
+       bool isOutput() const { return outptr != NULL; }
+       /// Returns true if this device is assigned to the named channel (mic color or "OUT")
+       bool isChannel(std::string const& name) const {
+               if (name == "OUT") return isOutput();
+               for (auto const& m: mics) if (m && m->getId() == name) return true;
+               return false;
+       }
+};
+
+
+/** @short High level audio playback API **/
+class Audio {
+       struct Impl;
+       boost::scoped_ptr<Impl> self;
+public:
+       typedef std::map<std::string, fs::path> Files;
+       Audio();
+       ~Audio();
+       void restart();
+       void close();
+       boost::ptr_vector<Analyzer>& analyzers();
+       boost::ptr_vector<Device>& devices();
+       bool isOpen() const;
+       bool hasPlayback() const;
+       /** Play a song beginning at startPos (defaults to 0)
+        * @param filename the track filename
+        * @param preview if the song preview is to play
+        * @param fadeTime time to fade
+        * @param startPos starting position
+        */
+       void playMusic(fs::path const& filename, bool preview = false, double fadeTime = 0.5, double startPos = 0.0);
+       /** Plays a list of songs **/
+       void playMusic(Files const& filenames, bool preview = false, double fadeTime = 0.5, double startPos = 0.0);
+       /** Loads/plays/unloads a sample **/
+       void loadSample(std::string const& streamId, fs::path const& filename);
+       void playSample(std::string const& streamId);
+       void unloadSample(std::string const& streamId);
+       /** Stops music **/
+       void stopMusic();
+       /** Fades music out **/
+       void fadeout(double time = 1.0);
+       /** Get the length of the currently playing song, in seconds. **/
+       double getLength() const;
+       /**
+        * This methods seek forward in the stream (backwards if
+        * argument is negative), and continues playing.
+        * @param seek_dist number of seconds to seek from current position
+        */
+       void seek(double seek_dist);
+       /** Seek to specific time **/
+       void seekPos(double pos);
+       /** Is the music playing (loaded and not at EOF yet, pause doesn't matter) **/
+       bool isPlaying() const;
+       /** Get the current position. If not known or nothing is playing, NaN is returned. **/
+       double getPosition() const;
+       void togglePause() { pause(!isPaused()); }
+       void pause(bool state = true);
+       bool isPaused() const;
+       /** Toggle synth playback **/
+       void toggleSynth(Notes const&);
+       /** Adjust volume level of a single track (used for muting incorrectly played instruments). Range 0.0 to 1.0. **/
+       void streamFade(std::string track, double volume);
+       /** Do a pitch shift - used for guitar whammy bar */
+       void streamBend(std::string track, double pitchFactor);
+       /** Get sample rate */
+       double getSR() const { return 48000.0; }
+};
+
diff --git a/game/backgrounds.cc b/game/backgrounds.cc
new file mode 100644 (file)
index 0000000..2140d19
--- /dev/null
@@ -0,0 +1,78 @@
+#include "backgrounds.hh"
+
+#include "configuration.hh"
+#include <boost/bind.hpp>
+#include <boost/filesystem.hpp>
+#include <boost/format.hpp>
+#include <boost/lexical_cast.hpp>
+#include <boost/regex.hpp>
+#include <algorithm>
+#include <cstdlib>
+#include <iostream>
+#include <sstream>
+#include <stdexcept>
+
+void Backgrounds::reload() {
+       if (m_loading) return;
+       // Run loading thread
+       m_loading = true;
+       m_thread.reset(new boost::thread(boost::bind(&Backgrounds::reload_internal, boost::ref(*this))));
+}
+
+void Backgrounds::reload_internal() {
+       {       // Remove old ones
+               boost::mutex::scoped_lock l(m_mutex);
+               m_bgs.clear();
+               m_dirty = true;
+       }
+       // Go through the background paths
+       Paths paths = getPaths();
+       for (auto it = paths.begin(); m_loading && it != paths.end(); ++it) {
+               if (!m_loading) break;
+               *it /= "backgrounds";
+               if (!fs::is_directory(*it)) { std::clog << "backgrounds/info: >>> Not scanning for backgrounds: " << *it << " (no such directory)" << std::endl; continue; }
+               std::clog << "backgrounds/info: >>> Scanning " << *it << " (for backgrounds)" << std::endl;
+               size_t count = m_bgs.size();
+               reload_internal(*it); // Scan the found folder
+               size_t diff = m_bgs.size() - count;
+               if (diff > 0 && m_loading) std::clog << "backgrounds/info: " << diff << " backgrounds loaded" << std::endl;
+       }
+       m_loading = false;
+       {       // Randomize the order
+               boost::mutex::scoped_lock l(m_mutex);
+               random_shuffle(m_bgs.begin(), m_bgs.end());
+               m_dirty = false;
+               m_bgiter = 0;
+       }
+}
+
+void Backgrounds::reload_internal(fs::path const& parent) {
+       if (std::distance(parent.begin(), parent.end()) > 20) { std::clog << "backgrounds/info: >>> Not scanning: " << parent.string() << " (maximum depth reached, possibly due to cyclic symlinks)" << std::endl; return; }
+       try {
+               // Find suitable file formats
+               boost::regex expression(R"(\.(png|jpeg|jpg|svg)$)", boost::regex_constants::icase);
+               for (fs::directory_iterator dirIt(parent), dirEnd; m_loading && dirIt != dirEnd; ++dirIt) {
+                       fs::path p = dirIt->path();
+                       if (fs::is_directory(p)) { reload_internal(p); continue; }
+                       std::string name = p.filename().string(); // File basename
+                       std::string path = p.string(); // Path without filename
+                       path.erase(path.size() - name.size());
+                       if (!regex_search(name, expression)) continue;
+                       {
+                               boost::mutex::scoped_lock l(m_mutex);
+                               m_bgs.push_back(path + name); // Add the background
+                               m_dirty = true;
+                       }
+               }
+       } catch (std::exception const& e) {
+               std::cout << "Error accessing " << parent << std::endl;
+       }
+}
+
+/// Get a random background
+std::string Backgrounds::getRandom() {
+       if (m_bgs.empty()) throw std::runtime_error("No random backgrounds available");
+       // This relies on that the bgs are in random order
+       return m_bgs.at((++m_bgiter) % m_bgs.size());
+}
+
diff --git a/game/backgrounds.hh b/game/backgrounds.hh
new file mode 100644 (file)
index 0000000..f4894eb
--- /dev/null
@@ -0,0 +1,46 @@
+#pragma once
+
+//#include "animvalue.hh"
+#include "fs.hh"
+//#include "song.hh"
+#include <boost/shared_ptr.hpp>
+#include <boost/scoped_ptr.hpp>
+#include <boost/thread/mutex.hpp>
+#include <boost/thread/thread.hpp>
+#include <vector>
+
+/// songs class for songs screen
+class Backgrounds: boost::noncopyable {
+  public:
+       /// constructor
+       Backgrounds(): m_bgiter(0), m_dirty(false), m_loading(false)
+       {
+               reload();
+       }
+       ~Backgrounds() {
+               m_loading = false; // Terminate loading if currently in progress
+               m_thread->join();
+       }
+       /// reloads backgrounds list
+       void reload();
+       /// array access
+       std::string& operator[](std::size_t pos) { return m_bgs.at(pos); }
+       /// number of backgrounds
+       int size() const { return m_bgs.size(); };
+       /// true if empty
+       int empty() const { return m_bgs.empty(); };
+       /// returns random background
+       std::string getRandom();
+
+  private:
+       typedef std::vector<std::string> BGVector;
+       BGVector m_bgs;
+       int m_bgiter;
+       void reload_internal();
+       void reload_internal(fs::path const& p);
+       volatile bool m_dirty;
+       volatile bool m_loading;
+       boost::scoped_ptr<boost::thread> m_thread;
+       mutable boost::mutex m_mutex;
+};
+
diff --git a/game/cache.cc b/game/cache.cc
new file mode 100644 (file)
index 0000000..7592660
--- /dev/null
@@ -0,0 +1,20 @@
+#include "cache.hh"
+#include "fs.hh"
+
+#include <boost/format.hpp>
+#include <algorithm>
+#include <boost/algorithm/string/classification.hpp>
+
+namespace cache {
+       fs::path constructSVGCacheFileName(fs::path const& svgfilename, double factor){
+               fs::path cache_filename;
+               std::string const lod = (boost::format("%.2f") % factor).str();
+               std::string const cache_basename = svgfilename.filename().string() + ".cache_" + lod + ".premul.png";
+               std::string fullpath = svgfilename.parent_path().string();
+               // Windows drive name handling
+               std::replace_if(fullpath.begin(), fullpath.end(), boost::is_any_of(":"), '_');
+               cache_filename = getCacheDir() / "misc" / fullpath / cache_basename;
+               return cache_filename;
+       }
+
+}
diff --git a/game/cache.hh b/game/cache.hh
new file mode 100644 (file)
index 0000000..1cd1bbf
--- /dev/null
@@ -0,0 +1,25 @@
+#pragma once
+
+#include "configuration.hh"
+#include "fs.hh"
+#include <boost/filesystem.hpp>
+#include <cstring>
+#include <stdexcept>
+
+namespace cache {
+
+       /** Builds the full path and file name for the SVG cache resource **/
+       fs::path constructSVGCacheFileName(fs::path const& svgfilename, double factor);
+
+       /** Load an SVG from the cache, if loading fails invalid_cache_error is thrown **/
+       template <typename T> bool loadSVG(T& target, fs::path const& source_filename, double factor) {
+               fs::path const cache_filename = cache::constructSVGCacheFileName(source_filename, factor);
+               // Verify that a cached file exists and that it is more recent than the original SVG
+               if (!fs::is_regular_file(cache_filename)) return false;
+               if (fs::last_write_time(source_filename) > fs::last_write_time(cache_filename)) return false;
+               // Try to load the cached file          
+               try { loadPNG(target, cache_filename.string()); } catch( ... ) { return false; }
+               return true;
+       }
+}
+
diff --git a/game/cachemap.hh b/game/cachemap.hh
new file mode 100644 (file)
index 0000000..6e42b3a
--- /dev/null
@@ -0,0 +1,41 @@
+#pragma once
+#include <boost/ptr_container/ptr_map.hpp>
+#include <list>
+
+/// caching template
+template <typename Key, typename Value> class Cachemap {
+       typedef boost::ptr_map<Key, Value> Map;
+       Map m_map;
+       std::list<Key> m_history;
+       std::size_t m_size;
+       void access(Key const& key) {
+               m_history.remove(key);
+               while (m_history.size() >= m_size) { m_map.erase(m_history.front()); m_history.pop_front(); }
+               m_history.push_back(key);
+       }
+
+  public:
+       /// constructor
+       Cachemap(std::size_t size): m_size(size) {}
+       /// inserts key:value pairs
+       typename Map::iterator insert(Key key, Value* value) {
+               access(key);
+               return m_map.insert(key, value).first;
+       }
+       /// array access
+       Value& operator[](Key const& key) {
+               typename Map::iterator it = m_map.find(key);
+               if (it == m_map.end()) it = insert(key, new Value(key)); else access(key);
+               return *it->second;
+       }
+       /// does it have a certain key
+       bool contains(Key const& key) const {
+               return m_map.find(key) != m_map.end();
+       }
+       /// clears history and cachemap
+       void clear() {
+               m_history.clear();
+               m_map.clear();
+       }
+};
+
diff --git a/game/color.cc b/game/color.cc
new file mode 100644 (file)
index 0000000..fc11eae
--- /dev/null
@@ -0,0 +1,69 @@
+#include "color.hh"
+#include <cstdio>
+#include <iostream>
+#include <map>
+#include <string>
+
+std::istream& operator>>(std::istream& is, Color& color) {
+       std::string str;
+       is >> str;
+       color = Color(str);
+       return is;
+}
+
+namespace {
+       struct ColorNames {
+               typedef std::map<std::string, Color> Map;
+               Map m;
+               ColorNames() {
+                       m["none"] = Color("#00000000");
+                       m["black"] = Color("#000000");
+                       m["gray"] = Color("#808080");
+                       m["silver"] = Color("#C0C0C0");
+                       m["white"] = Color("#FFFFFF");
+                       m["maroon"] = Color("#800000");
+                       m["red"] = Color("#FF0000");
+                       m["green"] = Color("#008000");
+                       m["lime"] = Color("#00FF00");
+                       m["navy"] = Color("#000080");
+                       m["blue"] = Color("#0000FF");
+                       m["purple"] = Color("#800080");
+                       m["fuchsia"] = Color("#FF00FF");
+                       m["olive"] = Color("#808000");
+                       m["yellow"] = Color("#FFFF00");
+                       m["teal"] = Color("#008080");
+                       m["aqua"] = Color("#00FFFF");
+               }
+       } colors;
+
+       // Convert sRGB color component into linear as per OpenGL specs
+       double lin(double sRGB) {
+               if (sRGB <= 0.04045) return sRGB / 12.92;
+               return std::pow((sRGB + 0.055)/1.055, 2.4);
+       }
+}
+
+Color::Color(std::string const& str) {
+       unsigned int r = 0, g = 0, b = 0, a = 255;
+       if (str.size() > 0 && str[0] == '#' && sscanf(str.c_str() + 1, "%02x %02x %02x %02x", &r, &g, &b, &a) >= 3) {
+               *this = Color(lin(r / 255.0), lin(g / 255.0), lin(b / 255.0), a / 255.0);
+               return;
+       }
+       ColorNames::Map::const_iterator it = colors.m.find(str);
+       if (it != colors.m.end()) { *this = it->second; return; }
+       std::clog << "Color/warning: Unknown color: " << str << " (using magenta to hilight)" << std::endl;
+       *this = Color(1.0, 0.0, 1.0);
+}
+
+glmath::vec4 Color::linear() const {
+       return a * glmath::vec4(r, g, b, 1.0);
+}
+
+Color MicrophoneColor::get(std::string name) {
+       if (name == "blue") return Color(0.2, 0.5, 0.7);
+       else if (name == "red") return Color(0.8, 0.3, 0.3);
+       else if (name == "green") return Color(0.2, 0.9, 0.2);
+       else if (name == "orange") return Color(1.0, 0.6, 0.0);
+       else return Color(0.5, 0.5, 0.5);
+}
+
diff --git a/game/color.hh b/game/color.hh
new file mode 100644 (file)
index 0000000..40c69a1
--- /dev/null
@@ -0,0 +1,28 @@
+#pragma once
+
+#include "glmath.hh"
+#include <istream>
+
+/// A struct for holding RGBA color in non-premultiplied linear RGB format (and conversions)
+struct Color {
+       double r;
+       double g;
+       double b;
+       double a;
+       /// Default-construct white
+       Color(): r(1.0), g(1.0), b(1.0), a(1.0) {}
+       /// Construct using RGB(A)
+       Color(double red, double grn, double blu, double alp = 1.0): r(red), g(grn), b(blu), a(alp) {}
+       /// Construct white color with alpha
+       static Color alpha(double alp) { return Color(1.0, 1.0, 1.0, alp); }
+       /// Parse CSS color string (sRGB)
+       explicit Color(std::string const& str);
+       /// Return premultiplied linear color suitable for use with OpenGL
+       glmath::vec4 linear() const;
+};
+
+std::istream& operator>>(std::istream& is, Color& color);
+
+namespace MicrophoneColor {
+       Color get(std::string name);
+}
diff --git a/game/config.cmake.hh b/game/config.cmake.hh
new file mode 100644 (file)
index 0000000..118c5e7
--- /dev/null
@@ -0,0 +1,25 @@
+#pragma once
+
+// CMake uses config.cmake.hh to generate config.hh within the build folder.
+#ifndef PERFORMOUS_CONFIG_HH
+#define PERFORMOUS_CONFIG_HH
+
+#define LOCALEDIR "@LOCALE_DIR@"
+
+#define PACKAGE "@CMAKE_PROJECT_NAME@"
+#define VERSION "@PROJECT_VERSION@"
+
+#define SHARED_DATA_DIR "@SHARE_INSTALL@"
+
+// FFMPEG/libav libraries use changing include file names... Get them from CMake.
+#define AVCODEC_INCLUDE <@AVCodec_INCLUDE@>
+#define AVFORMAT_INCLUDE <@AVFormat_INCLUDE@>
+#define SWSCALE_INCLUDE <@SWScale_INCLUDE@>
+//libav 0.9 fix
+#define AVRESAMPLE_INCLUDE <@AVResample_INCLUDE@>
+#define AVUTIL_INCLUDE <@AVUtil_INCLUDE@>
+#define AVUTIL_OPT_INCLUDE <@AVUtil_INCLUDE_DIRS@/libavutil/opt.h> //HACK to get AVOption class!
+#define AVUTIL_MATH_INCLUDE <@AVUtil_INCLUDE_DIRS@/libavutil/mathematics.h>
+
+#endif
+
diff --git a/game/configuration.cc b/game/configuration.cc
new file mode 100644 (file)
index 0000000..6b4722c
--- /dev/null
@@ -0,0 +1,369 @@
+#include "configuration.hh"
+
+#include "fs.hh"
+#include "util.hh"
+#include "i18n.hh"
+#include <boost/filesystem.hpp>
+#include <boost/format.hpp>
+#include <boost/lexical_cast.hpp>
+#include <libxml++/libxml++.h>
+#include <algorithm>
+#include <iomanip>
+#include <stdexcept>
+#include <iostream>
+#include <cmath>
+
+Config config;
+
+
+ConfigItem::ConfigItem(bool bval): m_type("bool"), m_value(bval), m_sel() { }
+
+ConfigItem::ConfigItem(int ival): m_type("int"), m_value(ival), m_sel() { }
+
+ConfigItem::ConfigItem(float fval): m_type("float"), m_value(fval), m_sel() { }
+
+ConfigItem::ConfigItem(std::string sval): m_type("string"), m_value(sval), m_sel() { }
+
+ConfigItem::ConfigItem(OptionList opts): m_type("option_list"), m_value(opts), m_sel() { }
+
+
+ConfigItem& ConfigItem::incdec(int dir) {
+       if (m_type == "int") {
+               int& val = boost::get<int>(m_value);
+               int step = boost::get<int>(m_step);
+               val = clamp(((val + dir * step)/ step) * step, boost::get<int>(m_min), boost::get<int>(m_max));
+       } else if (m_type == "float") {
+               double& val = boost::get<double>(m_value);
+               double step = boost::get<double>(m_step);
+               val = clamp(round((val + dir * step) / step) * step, boost::get<double>(m_min), boost::get<double>(m_max));
+       } else if (m_type == "bool") {
+               bool& val = boost::get<bool>(m_value);
+               val = !val;
+       } else if (m_type == "option_list") {
+               size_t s = boost::get<OptionList>(m_value).size();
+               m_sel = (m_sel + dir + s) % s;
+       }
+       return *this;
+}
+
+bool ConfigItem::isDefaultImpl(ConfigItem::Value const& defaultValue) const {
+       if (m_type == "bool") return boost::get<bool>(m_value) == boost::get<bool>(defaultValue);
+       if (m_type == "int") return boost::get<int>(m_value) == boost::get<int>(defaultValue);
+       if (m_type == "float") return boost::get<double>(m_value) == boost::get<double>(defaultValue);
+       if (m_type == "string") return boost::get<std::string>(m_value) == boost::get<std::string>(defaultValue);
+       if (m_type == "string_list") return boost::get<StringList>(m_value) == boost::get<StringList>(defaultValue);
+       if (m_type == "option_list") return boost::get<OptionList>(m_value) == boost::get<OptionList>(defaultValue);
+       throw std::logic_error("ConfigItem::is_default doesn't know type '" + m_type + "'");
+}
+
+void ConfigItem::verifyType(std::string const& type) const {
+       if (type == m_type) return;
+       std::string name = "unknown";
+       // Try to find this item in the config map
+       for (Config::const_iterator it = config.begin(); it != config.end(); ++it) {
+               if (&it->second == this) { name = it->first; break; }
+       }
+       if (m_type.empty()) throw std::logic_error("Config item " + name + ", requested_type=" + type + " used in C++ but missing from config schema");
+       throw std::logic_error("Config item type mismatch: item=" + name + ", type=" + m_type + ", requested=" + type);
+}
+
+int& ConfigItem::i() { verifyType("int"); return boost::get<int>(m_value); }
+bool& ConfigItem::b() { verifyType("bool"); return boost::get<bool>(m_value); }
+double& ConfigItem::f() { verifyType("float"); return boost::get<double>(m_value); }
+std::string& ConfigItem::s() { verifyType("string"); return boost::get<std::string>(m_value); }
+ConfigItem::StringList& ConfigItem::sl() { verifyType("string_list"); return boost::get<StringList>(m_value); }
+ConfigItem::OptionList& ConfigItem::ol() { verifyType("option_list"); return boost::get<OptionList>(m_value); }
+std::string& ConfigItem::so() { verifyType("option_list"); return boost::get<OptionList>(m_value).at(m_sel); }
+
+void ConfigItem::select(int i) { verifyType("option_list"); m_sel = clamp<int>(i, 0, boost::get<OptionList>(m_value).size()-1); }
+
+namespace {
+       template <typename T, typename VariantAll, typename VariantNum> std::string numericFormat(VariantAll const& value, VariantNum const& multiplier, VariantNum const& step) {
+               T m = boost::get<T>(multiplier);
+               // Find suitable precision (not very useful for integers, but this code is generic...)
+               T s = std::abs(m * boost::get<T>(step));
+               unsigned precision = 0;
+               while (s > 0.0 && (s *= 10) < 10) ++precision;
+               // Format the output
+               boost::format fmter("%f");
+               fmter % boost::io::group(std::setprecision(precision), double(m) * boost::get<T>(value));
+               return fmter.str();
+       }
+
+       std::string getText(xmlpp::Element const& elem) {
+               xmlpp::TextNode const* n = elem.get_child_text();  // Returns NULL if there is no text
+               return n ? std::string(n->get_content()) : std::string();
+       }
+       
+       std::string getText(xmlpp::Element const& elem, std::string const& path) {
+               xmlpp::NodeSet ns = elem.find(path);
+               if (ns.empty()) return std::string();
+               return getText(dynamic_cast<xmlpp::Element const&>(*ns[0]));
+       }
+}
+
+std::string ConfigItem::getValue() const {
+       if (m_type == "int") {
+               int val = boost::get<int>(m_value);
+               if (val >= 0 && val < int(m_enums.size())) return m_enums[val];
+               return numericFormat<int>(m_value, m_multiplier, m_step) + m_unit;
+       }
+       if (m_type == "float") return numericFormat<double>(m_value, m_multiplier, m_step) + m_unit;
+       if (m_type == "bool") return boost::get<bool>(m_value) ? _("Enabled") : _("Disabled");
+       if (m_type == "string") return boost::get<std::string>(m_value);
+       if (m_type == "string_list") {
+               StringList const& sl = boost::get<StringList>(m_value);
+               return sl.size() == 1 ? "{" + sl[0] + "}" : (boost::format(_("%d items")) % sl.size()).str();
+       }
+       if (m_type == "option_list") return boost::get<OptionList>(m_value).at(m_sel);
+       throw std::logic_error("ConfigItem::getValue doesn't know type '" + m_type + "'");
+}
+
+namespace {
+       struct XMLError {
+               XMLError(xmlpp::Element& e, std::string msg): elem(e), message(msg) {}
+               xmlpp::Element& elem;
+               std::string message;
+       };
+       std::string getAttribute(xmlpp::Element& elem, std::string const& attr) {
+               xmlpp::Attribute* a = elem.get_attribute(attr);
+               if (!a) throw XMLError(elem, "attribute " + attr + " not found");
+               return a->get_value();
+       }
+       template <typename T, typename V> void setLimits(xmlpp::Element& e, V& min, V& max, V& step) {
+               xmlpp::Attribute* a = e.get_attribute("min");
+               if (a) min = boost::lexical_cast<T>(a->get_value());
+               a = e.get_attribute("max");
+               if (a) max = boost::lexical_cast<T>(a->get_value());
+               a = e.get_attribute("step");
+               if (a) step = boost::lexical_cast<T>(a->get_value());
+       }
+}
+
+void ConfigItem::addEnum(std::string name) {
+       verifyType("int");
+       m_enums.push_back(name);
+       m_min = 0;
+       m_max = int(m_enums.size() - 1);
+       m_step = 1;
+}
+
+void ConfigItem::selectEnum(std::string const& name) {
+       auto it = std::find(m_enums.begin(), m_enums.end(), name);
+       if (it == m_enums.end()) throw std::runtime_error("Enum value " + name + " not found in " + m_shortDesc);
+       i() = it - m_enums.begin();
+}
+
+
+std::string ConfigItem::getEnumName() {
+       int val = i();
+       if (val >= 0 && val < int(m_enums.size())) return m_enums[val];
+       return "";
+}
+
+template <typename T> void ConfigItem::updateNumeric(xmlpp::Element& elem, int mode) {
+       xmlpp::NodeSet ns = elem.find("limits");
+       if (!ns.empty()) setLimits<T>(dynamic_cast<xmlpp::Element&>(*ns[0]), m_min, m_max, m_step);
+       else if (mode == 0) throw XMLError(elem, "child element limits missing");
+       ns = elem.find("ui");
+       // Default values
+       if (mode == 0) {
+               m_unit.clear();
+               m_multiplier = static_cast<T>(1);
+       }
+       if (!ns.empty()) {
+               xmlpp::Element& e = dynamic_cast<xmlpp::Element&>(*ns[0]);
+               try { m_unit = getAttribute(e, "unit"); } catch (...) {}
+               std::string m;
+               try {
+                       m = getAttribute(e, "multiplier");
+                       m_multiplier = boost::lexical_cast<T>(m);
+               } catch (XMLError&) {}
+               catch (boost::bad_lexical_cast&) { throw XMLError(e, "attribute multiplier='" + m + "' value invalid"); }
+       }
+}
+
+
+void ConfigItem::update(xmlpp::Element& elem, int mode) try {
+       if (mode == 0) {
+               m_type = getAttribute(elem, "type");
+               if (m_type.empty()) throw std::runtime_error("Entry type attribute is missing");
+               // Menu text
+               m_shortDesc = getText(elem, "short");
+               m_longDesc = getText(elem, "long");
+       } else {
+               std::string type = getAttribute(elem, "type");
+               if (!type.empty() && type != m_type) throw std::runtime_error("Entry type mismatch: " + getAttribute(elem, "name") + ": schema type = " + m_type + ", config type = " + type);
+       }
+       if (m_type == "bool") {
+               std::string value_string = getAttribute(elem, "value");
+               bool value;
+               if (value_string == "true") value = true;
+               else if (value_string == "false") value = false;
+               else throw std::runtime_error("Invalid boolean value '" + value_string + "'");
+               m_value = value;
+       } else if (m_type == "int") {
+               std::string value_string = getAttribute(elem, "value");
+               if (!value_string.empty()) m_value = boost::lexical_cast<int>(value_string);
+               // Enum handling
+               if (mode == 0) {
+                       xmlpp::NodeSet n2 = elem.find("limits/enum");
+                       if (!n2.empty()) {
+                               for (xmlpp::NodeSet::const_iterator it2 = n2.begin(), end2 = n2.end(); it2 != end2; ++it2) {
+                                       xmlpp::Element& elem2 = dynamic_cast<xmlpp::Element&>(**it2);
+                                       m_enums.push_back(getText(elem2));
+                               }
+                               m_min = 0;
+                               m_max = int(m_enums.size() - 1);
+                               m_step = 1;
+                       }
+               }
+               updateNumeric<int>(elem, mode);
+       } else if (m_type == "float") {
+               std::string value_string = getAttribute(elem, "value");
+               if (!value_string.empty()) m_value = boost::lexical_cast<double>(value_string);
+               updateNumeric<double>(elem, mode);
+       } else if (m_type == "string") {
+               m_value = getText(elem, "stringvalue");
+       } else if (m_type == "string_list" || m_type == "option_list") {
+               //TODO: Option list should also update selection (from attribute?)
+               std::vector<std::string> value;
+               xmlpp::NodeSet n2 = elem.find("stringvalue");
+               for (xmlpp::NodeSet::const_iterator it2 = n2.begin(), end2 = n2.end(); it2 != end2; ++it2) {
+                       value.push_back(getText(dynamic_cast<xmlpp::Element const&>(**it2)));
+               }
+               m_value = value;
+       } else if (!m_type.empty()) throw std::runtime_error("Invalid value type in config schema: " + m_type);
+       // Schema sets all defaults, system config sets the system default
+       if (mode < 1) m_factoryDefaultValue = m_defaultValue = m_value;
+       if (mode < 2) m_defaultValue = m_value;
+} catch (std::exception& e) {
+       int line = elem.get_line();
+       throw std::runtime_error(boost::lexical_cast<std::string>(line) + ": Error while reading entry: " + e.what());
+}
+
+// These are set in readConfig, once the paths have been bootstrapped.
+fs::path systemConfFile;
+fs::path userConfFile;
+
+void writeConfig(bool system) {
+       xmlpp::Document doc;
+       xmlpp::Node* nodeRoot = doc.create_root_node("performous");
+       bool dirty = false;
+       for (auto& elem: config) {
+               ConfigItem& item = elem.second;
+               std::string name = elem.first;
+               if (item.isDefault(system)) continue; // No need to save settings with default values
+               dirty = true;
+               xmlpp::Element* entryNode = nodeRoot->add_child("entry");
+               entryNode->set_attribute("name", name);
+               std::string type = item.get_type();
+               entryNode->set_attribute("type", type);
+               if (type == "int") entryNode->set_attribute("value",boost::lexical_cast<std::string>(item.i()));
+               else if (type == "bool") entryNode->set_attribute("value", item.b() ? "true" : "false");
+               else if (type == "float") entryNode->set_attribute("value",boost::lexical_cast<std::string>(item.f()));
+               else if (item.get_type() == "string") entryNode->add_child("stringvalue")->add_child_text(item.s());
+               else if (item.get_type() == "string_list") {
+                       for (auto const& str: item.sl()) entryNode->add_child("stringvalue")->add_child_text(str);
+               }
+               else if (item.get_type() == "option_list") {
+                       //TODO: Write selected also (as attribute?)
+                       for (auto const& str: item.ol()) entryNode->add_child("stringvalue")->add_child_text(str);
+               }
+       }
+       fs::path const& conf = system ? systemConfFile : userConfFile;
+       std::string tmp = conf.string() + "tmp";
+       try {
+               create_directories(conf.parent_path());
+               if (dirty) doc.write_to_file_formatted(tmp, "UTF-8");
+               if (exists(conf)) remove(conf);
+               if (dirty) {
+                       rename(tmp, conf);
+                       std::cerr << "Saved configuration to " << conf << std::endl;
+               } else {
+                       std::cerr << "Using default settings, no configuration file needed." << std::endl;
+               }
+       } catch (...) {
+               throw std::runtime_error("Unable to save " + conf.string());
+       }
+       if (!system) return;
+       // Tell the items that we have changed the system default
+       for (auto& elem: config) elem.second.makeSystem();
+       // User config is no longer needed
+       if (exists(userConfFile)) remove(userConfFile);
+}
+
+ConfigMenu configMenu;
+
+void readMenuXML(xmlpp::Node* node) {
+       xmlpp::Element& elem = dynamic_cast<xmlpp::Element&>(*node);
+       MenuEntry me;
+       me.name = getAttribute(elem, "name");
+       me.shortDesc = getText(elem, "short");
+       me.longDesc = getText(elem, "long");
+       configMenu.push_back(me);
+}
+
+void readConfigXML(fs::path const& file, int mode) {
+       if (!fs::exists(file)) {
+               std::clog << "config/info: Skipping " << file << " (not found)" << std::endl;
+               return;
+       }
+       std::clog << "config/info: Parsing " << file << std::endl;
+       xmlpp::DomParser domParser(file.string());
+       try {
+               xmlpp::NodeSet n = domParser.get_document()->get_root_node()->find("/performous/menu/entry");
+               if (!n.empty()) {
+                       configMenu.clear();
+                       std::for_each(n.begin(), n.end(), readMenuXML);
+               }
+               n = domParser.get_document()->get_root_node()->find("/performous/entry");
+               for (xmlpp::NodeSet::const_iterator nodeit = n.begin(), end = n.end(); nodeit != end; ++nodeit) {
+                       xmlpp::Element& elem = dynamic_cast<xmlpp::Element&>(**nodeit);
+                       std::string name = getAttribute(elem, "name");
+                       if (name.empty()) throw std::runtime_error(file.string() + " element Entry missing name attribute");
+                       auto it = config.find(name);
+                       if (mode == 0) { // Schema
+                               if (it != config.end()) throw std::runtime_error("Configuration schema contains the same value twice: " + name);
+                               config[name].update(elem, 0);
+                               // Add the item to menu, if not hidden
+                               bool hidden = false;
+                               try { if (getAttribute(elem, "hidden") == "true") hidden = true; } catch (XMLError&) {}
+                               if (!hidden) {
+                                       for (auto& elem: configMenu) {
+                                               std::string prefix = elem.name + '/';
+                                               if (name.substr(0, prefix.size()) == prefix) { elem.items.push_back(name); break; }
+                                       }
+                               }
+                       } else {
+                               if (it == config.end()) {
+                                       std::clog << "config/warning:   Entry " << name << " ignored (does not exist in config schema)." << std::endl;
+                                       continue;
+                               }
+                               it->second.update(elem, mode);
+                       }
+               }
+       } catch (XMLError& e) {
+               int line = e.elem.get_line();
+               std::string name = e.elem.get_name();
+               throw std::runtime_error(file.string() + ":" + boost::lexical_cast<std::string>(line) + " element " + name + " " + e.message);
+       } catch (std::exception& e) {
+               throw std::runtime_error(file.string() + ":" + e.what());
+       }
+}
+
+void readConfig() {
+       // Find config schema
+       fs::path schemaFile = getSchemaFilename();
+       systemConfFile = getSysConfigDir() / "config.xml";
+       userConfFile = getConfigDir() / "config.xml";
+       readConfigXML(schemaFile, 0);  // Read schema and defaults
+       readConfigXML(systemConfFile, 1);  // Update defaults with system config
+       readConfigXML(userConfFile, 2);  // Read user settings
+       pathInit();
+       // Populate themes
+       ConfigItem& ci = config["game/theme"];
+       for (std::string const& theme: getThemes()) ci.addEnum(theme);
+       if (ci.i() == -1) ci.selectEnum("default");  // Select the default theme if nothing is selected
+}
+
diff --git a/game/configuration.hh b/game/configuration.hh
new file mode 100644 (file)
index 0000000..de9ec18
--- /dev/null
@@ -0,0 +1,82 @@
+#pragma once
+
+#include <boost/variant.hpp>
+#include <map>
+#include <string>
+#include <vector>
+
+namespace xmlpp { class Element; }  // Forward declaration for libxml++ stuff
+
+/// configuration option
+class ConfigItem {
+  public:
+       typedef std::vector<std::string> StringList; ///< a list of strings
+       typedef std::vector<std::string> OptionList; ///< a list of string options
+       ConfigItem() : m_sel() {}
+       ConfigItem(bool bval);
+       ConfigItem(int ival);
+       ConfigItem(float fval);
+       ConfigItem(std::string sval);
+       ConfigItem(OptionList opts);
+       void update(xmlpp::Element& elem, int mode); ///< Load XML config file, elem = Entry, mode = 0 for schema, 1 for system config and 2 for user config
+       ConfigItem& operator++() { return incdec(1); } ///< increments config value
+       ConfigItem& operator--() { return incdec(-1); } ///< decrements config value
+       /// Is the current value the same as the default value (factory setting or system setting)
+       bool isDefault(bool factory = false) const { return isDefaultImpl(factory ? m_factoryDefaultValue : m_defaultValue); }
+       std::string get_type() const { return m_type; } ///< get the field type
+       int& i(); ///< Access integer item
+       bool& b(); ///< Access boolean item
+       double& f(); ///< Access floating-point item
+       std::string& s(); ///< Access string item
+       StringList& sl(); ///< Access stringlist item
+       OptionList& ol(); ///< Access optionlist item
+       std::string& so(); ///< Access currently selected string option
+       void select(int i); ///< Set optionlist selected item index
+       void reset(bool factory = false) { m_value = factory ? m_factoryDefaultValue : m_defaultValue; } ///< Reset to default
+       void makeSystem() { m_defaultValue = m_value; } ///< Make current value the system default (used when saving system config)
+       std::string getValue() const; ///< Get a human-readable representation of the current value
+       std::string const& getShortDesc() const { return m_shortDesc; } ///< get the short description for this ConfigItem
+       std::string const& getLongDesc() const { return m_longDesc; } ///< get the long description for this ConfigItem
+       void addEnum(std::string name); ///< Dynamically adds an enum to all values
+       void selectEnum(std::string const& name); ///< Set integer value by enum name
+       std::string getEnumName(); ///< Returns the selected enum option's text
+
+  private:
+       template <typename T> void updateNumeric(xmlpp::Element& elem, int mode); ///< Used internally for loading XML
+       void verifyType(std::string const& t) const; ///< throws std::logic_error if t != type
+       ConfigItem& incdec(int dir); ///< Increment/decrement by dir steps (must be -1 or 1)
+       std::string m_type;
+       std::string m_shortDesc;
+       std::string m_longDesc;
+
+       typedef boost::variant<bool, int, double, std::string, StringList> Value;
+       bool isDefaultImpl(Value const& defaultValue) const;
+       Value m_value; ///< The current value
+       Value m_factoryDefaultValue; ///< The value from config schema
+       Value m_defaultValue; ///< The value from config schema or system config
+       std::vector<std::string> m_enums; ///< Enum value titles
+       boost::variant<int, double> m_step, m_min, m_max;
+       boost::variant<int, double> m_multiplier;
+       std::string m_unit;
+       int m_sel;
+};
+
+typedef std::map<std::string, ConfigItem> Config;
+extern Config config; ///< A global variable that contains all config items
+
+/** Read config schema and configuration from XML files **/
+void readConfig();
+
+/** Write modified config options to user's or system-wide config XML **/
+void writeConfig(bool system = false);
+
+/// struct for entries in menu
+struct MenuEntry {
+       std::string name; ///< name of the menu entry
+       std::string shortDesc; ///< a short description
+       std::string longDesc; ///< a longer description
+       std::vector<std::string> items; ///< selectable options
+};
+
+typedef std::vector<MenuEntry> ConfigMenu;
+extern ConfigMenu configMenu;
diff --git a/game/controllers-buttons.ii b/game/controllers-buttons.ii
new file mode 100644 (file)
index 0000000..f551461
--- /dev/null
@@ -0,0 +1,63 @@
+// This header should be used for generating input button definitions and code:
+// #define DEFINE_BUTTON(devtype, button, num, nav) do something with devtype##_##button etc.
+// #include "controllers-buttons.ii"
+
+// Numeric values have special meanings tied to them
+// 0x000xxxyy where xxx = plane, yy = num (e.g. fret keys), planes >= 0x100 are reserved for GENERIC keys
+// 0x00100000 and greater are not used
+
+// Guitar buttons
+DEFINE_BUTTON(GUITAR, GREEN, 0, NAV_SOME)
+DEFINE_BUTTON(GUITAR, RED, 1, NAV_SOME)
+DEFINE_BUTTON(GUITAR, YELLOW, 2, NAV_SOME)
+DEFINE_BUTTON(GUITAR, BLUE, 3, NAV_SOME)
+DEFINE_BUTTON(GUITAR, ORANGE, 4, NAV_SOME)
+DEFINE_BUTTON(GUITAR, PICK_DOWN,11, NAV_DOWN)
+DEFINE_BUTTON(GUITAR, PICK_UP, 10, NAV_UP)
+DEFINE_BUTTON(GUITAR, GODMODE, 0xF00, NAV_NONE)
+DEFINE_BUTTON(GUITAR, WHAMMY, 0xF01, NAV_NONE)
+// Drums buttons
+DEFINE_BUTTON(DRUMS, KICK, 0x000, NAV_START)
+DEFINE_BUTTON(DRUMS, RED, 0x001, NAV_LEFT)  // Snare
+DEFINE_BUTTON(DRUMS, YELLOW, 0x002, NAV_UP)
+DEFINE_BUTTON(DRUMS, BLUE, 0x003, NAV_DOWN)
+DEFINE_BUTTON(DRUMS, GREEN, 0x004, NAV_RIGHT)
+DEFINE_BUTTON(DRUMS, YELLOW_TOM, 0x102, NAV_UP)  // Tom 1
+DEFINE_BUTTON(DRUMS, BLUE_TOM, 0x103, NAV_DOWN)  // Tom 2
+DEFINE_BUTTON(DRUMS, GREEN_TOM, 0x104, NAV_RIGHT)  // Tom 3
+DEFINE_BUTTON(DRUMS, YELLOW_CYMBAL, 0x202, NAV_SOME)  // Hi-Hat
+DEFINE_BUTTON(DRUMS, BLUE_CYMBAL, 0x203, NAV_SOME)  // Ride
+DEFINE_BUTTON(DRUMS, GREEN_CYMBAL, 0x204, NAV_SOME)  // Crash
+// Keytar buttons
+DEFINE_BUTTON(KEYTAR, C, 0, NAV_SOME)
+DEFINE_BUTTON(KEYTAR, D, 1, NAV_SOME)
+DEFINE_BUTTON(KEYTAR, E, 2, NAV_SOME)
+DEFINE_BUTTON(KEYTAR, F, 3, NAV_SOME)
+DEFINE_BUTTON(KEYTAR, G, 4, NAV_SOME)
+DEFINE_BUTTON(KEYTAR, GODMODE, 5, NAV_NONE)
+DEFINE_BUTTON(KEYTAR, WHAMMY, 6, NAV_NONE)
+// DANCEPAD buttons
+DEFINE_BUTTON(DANCEPAD, LEFT, 0, NAV_LEFT)
+DEFINE_BUTTON(DANCEPAD, DOWN, 1, NAV_DOWN)
+DEFINE_BUTTON(DANCEPAD, UP, 2, NAV_UP)
+DEFINE_BUTTON(DANCEPAD, RIGHT, 3, NAV_RIGHT)
+DEFINE_BUTTON(DANCEPAD, DOWN_LEFT, 4, NAV_SOME)
+DEFINE_BUTTON(DANCEPAD, DOWN_RIGHT, 5, NAV_MOREUP)
+DEFINE_BUTTON(DANCEPAD, UP_LEFT, 6, NAV_MOREDOWN)
+DEFINE_BUTTON(DANCEPAD, UP_RIGHT, 7, NAV_SOME)
+// Generic controls
+DEFINE_BUTTON(GENERIC, UNASSIGNED, 0x10000, NAV_NONE)
+DEFINE_BUTTON(GENERIC, START, 0x10001, NAV_START)
+DEFINE_BUTTON(GENERIC, CANCEL, 0x10002, NAV_CANCEL)
+DEFINE_BUTTON(GENERIC, UP, 0x10010, NAV_UP)
+DEFINE_BUTTON(GENERIC, DOWN, 0x10011, NAV_DOWN)
+DEFINE_BUTTON(GENERIC, LEFT, 0x10012, NAV_LEFT)
+DEFINE_BUTTON(GENERIC, RIGHT, 0x10013, NAV_RIGHT)
+DEFINE_BUTTON(GENERIC, MOREUP, 0x10020, NAV_MOREUP)
+DEFINE_BUTTON(GENERIC, MOREDOWN, 0x10021, NAV_MOREDOWN)
+DEFINE_BUTTON(GENERIC, VOLUME_UP, 0x10022, NAV_VOLUME_UP)
+DEFINE_BUTTON(GENERIC, VOLUME_DOWN, 0x10023, NAV_VOLUME_DOWN)
+DEFINE_BUTTON(GENERIC, PAUSE, 0x10024, NAV_PAUSE)
+
+#undef DEFINE_BUTTON
+
diff --git a/game/controllers-joystick.cc b/game/controllers-joystick.cc
new file mode 100644 (file)
index 0000000..722b9cb
--- /dev/null
@@ -0,0 +1,102 @@
+#include "controllers.hh"
+
+#include <boost/smart_ptr/shared_ptr.hpp>
+#include <vector>
+
+namespace input {
+       struct Joysticks: public Hardware {
+               Joysticks() {
+                       for (int id = 0; id < SDL_NumJoysticks(); ++id) {
+                               JoyPtr joy(SDL_JoystickOpen(id), SDL_JoystickClose);
+                               std::ostringstream oss;
+                               oss << "controller-joystick/info: Opened joystick " << id << ": " << getName(id) << " ("
+                                 << SDL_JoystickNumButtons(joy.get()) << " buttons, "
+                                 << SDL_JoystickNumAxes(joy.get()) << " axes, "
+                                 << SDL_JoystickNumHats(joy.get()) << " hats, "
+                                 << SDL_JoystickNumBalls(joy.get()) << " balls)";
+                               std::clog << oss.str() << std::endl;  // Logging system barks if this is not one atomic write (thus the ostringstream).
+                               m_joysticks.push_back(joy);
+                       }
+               }
+               std::string getName(unsigned device) const override {
+                       return SDL_JoystickNameForIndex(device);
+               }
+               bool process(Event& event, SDL_Event const& sdlEv) override {
+                       if (sdlEv.type == SDL_JOYBUTTONDOWN || sdlEv.type == SDL_JOYBUTTONUP) {
+                               event.hw = sdlEv.jbutton.button;
+                               event.value = (sdlEv.type == SDL_JOYBUTTONDOWN ? 1.0 : 0.0);
+                       }
+                       else if (sdlEv.type == SDL_JOYAXISMOTION) {
+                               event.hw = hwIsAxis.min + sdlEv.jaxis.axis;
+                               event.value = (sdlEv.jaxis.value + 0.5) / 32767.5;  // Convert to -1.0 .. 1.0 range
+                               if (std::abs(event.value) < 0.001) event.value = 0.0;  // Some dead zone around zero
+                       }
+                       else if (sdlEv.type == SDL_JOYHATMOTION) {
+                               event.hw = hwIsHat.min + sdlEv.jhat.hat;
+                               event.value = sdlEv.jhat.value;
+                       }
+                       else return false;
+                       event.source = SourceId(SOURCETYPE_JOYSTICK, sdlEv.jbutton.which);  // All j* structures have .which at the same position as jbutton
+                       return true;
+               }
+               typedef boost::shared_ptr<SDL_Joystick> JoyPtr;
+               std::vector<JoyPtr> m_joysticks;
+
+       };
+
+       Hardware::ptr constructJoysticks() { return Hardware::ptr(new Joysticks()); }
+}
+
+
+#if 0
+
+// Forcing menu
+
+void init() {
+       std::map<unsigned int, Instrument> forced_type;
+       ConfigItem::StringList instruments = config["game/instruments"].sl();
+
+       // Populate controller forcing config items
+       ConfigItem& ci0 = config["game/instrument0"];
+       ConfigItem& ci1 = config["game/instrument1"];
+       ConfigItem& ci2 = config["game/instrument2"];
+       ConfigItem& ci3 = config["game/instrument3"];
+       int i = 0;
+       for (ControllerDefs::const_iterator it = m_controllerDefs.begin(); it != m_controllerDefs.end(); ++it, ++i) {
+               // Add the enum
+               std::string title = it->second.description;
+               ci0.addEnum(title);
+               ci1.addEnum(title);
+               ci2.addEnum(title);
+               ci3.addEnum(title);
+               // Check for active items
+               if (i == ci0.i()-1) instruments.push_back("0:" + it->first);
+               if (i == ci1.i()-1) instruments.push_back("1:" + it->first);
+               if (i == ci2.i()-1) instruments.push_back("2:" + it->first);
+               if (i == ci3.i()-1) instruments.push_back("3:" + it->first);
+       }
+
+       // Check all forced instruments
+       for (ConfigItem::StringList::const_iterator it = instruments.begin(); it != instruments.end(); ++it) {
+               std::istringstream iss(*it);
+               unsigned sdl_id;
+               char ch;
+               std::string type;
+               if (!(iss >> sdl_id >> ch >> type) || ch != ':') {
+                       std::clog << "controllers/error: \"" << *it << "\" invalid syntax, should be SDL_ID:CONTROLLER_TYPE" << std::endl;
+                       continue;
+               } else {
+                       bool found = false;
+                       for (Instruments::const_iterator it2 = g_instruments.begin(); it2 != g_instruments.end(); ++it2) {
+                               if (type == it2->first) {
+                                       forced_type.insert(std::pair<unsigned int,Instrument>(sdl_id, Instrument(it2->second)));
+                                       found = true;
+                                       break;
+                               }
+                       }
+                       if (!found) std::clog << "controllers/error: Controller type \"" << type << "\" unknown" << std::endl;
+               }
+       }
+
+#endif
+
diff --git a/game/controllers-keyboard.cc b/game/controllers-keyboard.cc
new file mode 100644 (file)
index 0000000..f23de3c
--- /dev/null
@@ -0,0 +1,142 @@
+#include "controllers.hh"
+
+#include <set>
+
+namespace {
+       bool g_enableInstruments = false;
+}
+
+namespace input {
+       class Keyboard: public Hardware {
+               std::set<unsigned> m_pressed;
+               bool m_guitar, m_keytar, m_drumkit, m_dancepad;
+               /// Set the value of an instrument bool from a config variable and return a log message snippet if value was changed.
+               static std::string setMode(bool& var, std::string const& name) {
+                       bool value = config["game/keyboard_" + name].b();
+                       if (var == value) return std::string();
+                       var = value;
+                       return " " + name + (value ? " enabled." : " disabled.");
+               }
+       public:
+               Keyboard(): m_guitar(), m_keytar(), m_drumkit(), m_dancepad() {}
+               bool process(Event& event, SDL_Event const& sdlEv) override {
+                       if (sdlEv.type != SDL_KEYDOWN && sdlEv.type != SDL_KEYUP) return false;
+                       // Switch modes only when no keys are pressed (avoids buttons getting stuck on mode change)
+                       if (m_pressed.empty()) {
+                               std::string msg;
+                               if (g_enableInstruments) {
+                                       msg += setMode(m_guitar, "guitar");
+                                       msg += setMode(m_keytar, "keytar");
+                                       msg += setMode(m_drumkit, "drumkit");
+                                       msg += setMode(m_dancepad, "dancepad");
+                               } else if (m_guitar || m_keytar || m_drumkit || m_dancepad) {
+                                       msg = " all instruments disabled.";
+                                       m_guitar = m_keytar = m_drumkit = m_dancepad = false;
+                               }
+                               if (!msg.empty()) std::clog << "controller-keyboard/info: Mode change:" + msg << std::endl;
+                       }
+                       // Keep track of pressed keys
+                       {
+                               unsigned pressedId = sdlEv.key.keysym.sym << 16 | sdlEv.key.keysym.sym;
+                               if (sdlEv.type == SDL_KEYDOWN) m_pressed.insert(pressedId);
+                               else m_pressed.erase(pressedId);
+                       }
+                       // Convert SDL event into controller Event
+                       event.source = SourceId(SOURCETYPE_KEYBOARD, 0);  // FIXME! cmake the device ID zero because in SDL2 it ain't zero!!
+                       event.hw = sdlEv.key.keysym.sym;
+                       event.value = (sdlEv.type == SDL_KEYDOWN ? 1.0 : 0.0);
+                       // Get the modifier keys that we actually use as modifiers
+                       unsigned mod = sdlEv.key.keysym.mod & (KMOD_LCTRL | KMOD_LALT);
+                       // Map to keyboard instruments (sets event.button if matching)
+                       if (!mod) mapping(event);
+                       // Map to menu navigation
+                       if (event.button == GENERIC_UNASSIGNED) event.button = navigation(event.hw, mod);
+                       return event.button != GENERIC_UNASSIGNED;
+               }
+               void mapping(Event& event) {
+                       unsigned button = 0;
+                       switch (event.hw) {
+                               // Guitar on keyboard
+                               case SDLK_BACKSPACE: button = GUITAR_WHAMMY; goto guitar_process;
+                               case SDLK_RCTRL: button = GUITAR_GODMODE; goto guitar_process;
+                               case SDLK_RSHIFT: button = GUITAR_PICK_UP; goto guitar_process;
+                               case SDLK_RETURN: case SDLK_KP_ENTER: button = GUITAR_PICK_DOWN; goto guitar_process;
+                               case SDLK_F5: case SDLK_5: case SDLK_b: button++;
+                               case SDLK_F4: case SDLK_4: case SDLK_v: button++;
+                               case SDLK_F3: case SDLK_3: case SDLK_c: button++;
+                               case SDLK_F2: case SDLK_2: case SDLK_x: button++;
+                               case SDLK_F1: case SDLK_1: case SDLK_z: case SDLK_w: case SDLK_y:  // Support also French and German layouts
+                               guitar_process:
+                                       if (!m_guitar) return;
+                                       event.devType = DEVTYPE_GUITAR;
+                                       break;
+
+                               // Keytar on keyboard
+                               case SDLK_F12: button++;
+                               case SDLK_F11: button++;
+                               case SDLK_F10: button++;
+                               case SDLK_F9: button++;
+                               case SDLK_F8: button++;
+                               case SDLK_F7:
+                                       if (!m_keytar) return;
+                                       event.devType = DEVTYPE_KEYTAR;
+                                       break;
+
+                               // Drums on keyboard
+                               case SDLK_8: button = DRUMS_YELLOW_CYMBAL; goto drum_process;
+                               case SDLK_9: button = DRUMS_GREEN_CYMBAL; goto drum_process;
+                               case SDLK_0: button = DRUMS_BLUE_CYMBAL; goto drum_process;
+                               case SDLK_u: button = DRUMS_RED; goto drum_process;
+                               case SDLK_i: button = DRUMS_YELLOW_TOM; goto drum_process;
+                               case SDLK_o: button = DRUMS_BLUE_TOM; goto drum_process;
+                               case SDLK_p: button = DRUMS_GREEN_TOM; goto drum_process;
+                               case SDLK_SPACE:
+                                       drum_process:
+                                       if (!m_drumkit) return;
+                                       event.devType = DEVTYPE_DRUMS;
+                                       break;
+
+                               // Dance on keypad
+                               case SDLK_KP_9: button++;
+                               case SDLK_KP_7: button++;
+                               case SDLK_KP_3: button++;
+                               case SDLK_KP_1: button++;
+                               case SDLK_KP_6: case SDLK_RIGHT: button++;
+                               case SDLK_KP_8: case SDLK_UP: button++;
+                               case SDLK_KP_2: case SDLK_DOWN: case SDLK_KP_5: button++;
+                               case SDLK_KP_4: case SDLK_LEFT:
+                                       if (!m_dancepad) return;
+                                       event.devType = DEVTYPE_DANCEPAD;
+                                       break;
+
+                               default: return;
+                       }
+                       event.button = ButtonId(button);
+                       event.source.channel = event.devType;  // Each type gets its own unique SourceId channel
+               }
+               Button navigation(unsigned k, unsigned mod) {
+                       if (!mod) {
+                               if (k == SDLK_UP) return GENERIC_UP;
+                               if (k == SDLK_DOWN) return GENERIC_DOWN;
+                               if (k == SDLK_LEFT) return GENERIC_LEFT;
+                               if (k == SDLK_RIGHT) return GENERIC_RIGHT;
+                               if (k == SDLK_RETURN || k == SDLK_KP_ENTER) return GENERIC_START;
+                               if (k == SDLK_ESCAPE) return GENERIC_CANCEL;
+                               if (k == SDLK_PAGEUP) return GENERIC_MOREUP;
+                               if (k == SDLK_PAGEDOWN) return GENERIC_MOREDOWN;
+                               if (k == SDLK_PAUSE) return GENERIC_PAUSE;
+                       }
+                       else if (mod == KMOD_LCTRL) {
+                               if (k == SDLK_UP) return GENERIC_VOLUME_UP;
+                               if (k == SDLK_DOWN) return GENERIC_VOLUME_DOWN;
+                               if (k == SDLK_p) return GENERIC_PAUSE;
+                       }
+                       return GENERIC_UNASSIGNED;
+               }
+       };
+
+       void Hardware::enableKeyboardInstruments(bool state) { g_enableInstruments = state; }
+       Hardware::ptr constructKeyboard() { return Hardware::ptr(new Keyboard()); }
+       
+}
+
diff --git a/game/controllers-midi.cc b/game/controllers-midi.cc
new file mode 100644 (file)
index 0000000..f388cc5
--- /dev/null
@@ -0,0 +1,75 @@
+#ifdef USE_PORTMIDI
+
+#include "controllers.hh"
+#include "portmidi.hh"
+#include "fs.hh"
+#include <boost/lexical_cast.hpp>
+#include <boost/ptr_container/ptr_map.hpp>
+#include <boost/regex.hpp>
+
+namespace input {
+
+       class Midi: public Hardware {
+       public:
+               Midi() {
+                       boost::regex re(config["game/midi_input"].s());
+                       for (int dev = 0; dev < Pm_CountDevices(); ++dev) {
+                               try {
+                                       PmDeviceInfo const* info = Pm_GetDeviceInfo(dev);
+                                       if (!info->input) continue;  // Not an input device
+                                       if (info->opened) continue;  // Already opened
+                                       std::string name = getName(dev);
+                                       if (!re.empty() && !regex_search(name, re)) continue;
+                                       // Now actually open the device
+                                       m_streams.insert(dev, std::auto_ptr<pm::Input>(new pm::Input(dev)));
+                                       std::clog << "controller-midi/info: Opened MIDI device " << name << std::endl;
+                               } catch (std::runtime_error& e) {
+                                       std::clog << "controller-midi/warning: " << e.what() << std::endl;
+                               }
+                       }
+               }
+               std::string getName(unsigned dev) const override {
+                       PmDeviceInfo const* info = Pm_GetDeviceInfo(dev);
+                       if (!info) throw std::logic_error("Invalid MIDI device requested in Midi::getName");
+                       std::ostringstream name;
+                       name << dev << ": " << info->name;
+                       return name.str();
+               }
+               bool process(Event& event) override {
+                       PmEvent ev;
+                       for (auto kv: m_streams) {
+                               if (Pm_Read(*kv.second, &ev, 1) != 1) continue;
+                               unsigned char evnt = ev.message & 0xF0;
+                               unsigned char note = ev.message >> 8;
+                               unsigned char vel  = ev.message >> 16;
+                               unsigned chan = (ev.message & 0x0F) + 1;  // It is conventional to use one-based indexing
+                               if (evnt == 0x80 /* NOTE OFF */) { evnt = 0x90; vel = 0; }  // Translate NOTE OFF into NOTE ON with zero-velocity
+                               if (evnt != 0x90 /* NOTE ON */) continue;  // Ignore anything that isn't NOTE ON/OFF
+                               std::clog << "controller-midi/info: MIDI NOTE ON/OFF event: ch=" << unsigned(chan) << " note=" << unsigned(note) << " vel=" << unsigned(vel) << std::endl;
+                               event.source = SourceId(SOURCETYPE_MIDI, kv.first, chan);
+                               event.hw = note;
+                               event.value = vel / 127.0;
+                               return true;
+                       }
+                       return false;
+               }
+       private:
+               pm::Initialize m_init;
+               boost::ptr_map<unsigned, pm::Input> m_streams;
+       };
+
+       Hardware::ptr constructMidi() { return Hardware::ptr(new Midi()); }
+       bool Hardware::midiEnabled() { return true; }
+}
+
+#else
+
+#include "controllers.hh"
+
+namespace input {
+       Hardware::ptr constructMidi() { return Hardware::ptr(); }
+       bool Hardware::midiEnabled() { return false; }
+}
+
+#endif
+
diff --git a/game/controllers.cc b/game/controllers.cc
new file mode 100644 (file)
index 0000000..fbb8e34
--- /dev/null
@@ -0,0 +1,420 @@
+#include "controllers.hh"
+
+#include "fs.hh"
+#include <boost/algorithm/string.hpp>
+#include <boost/filesystem.hpp>
+#include <boost/lexical_cast.hpp>
+#include <boost/regex.hpp>
+#include <boost/smart_ptr/weak_ptr.hpp>
+#include <libxml++/libxml++.h>
+#include <SDL2/SDL_joystick.h>
+#include <deque>
+#include <stdexcept>
+
+using namespace input;
+
+namespace {
+       struct XMLError {
+               XMLError(xmlpp::Element const& e, std::string const& msg): elem(e), message(msg) {}
+               xmlpp::Element const& elem;
+               std::string message;
+       };
+       std::string getAttribute(xmlpp::Element const& elem, std::string const& attr) {
+               xmlpp::Attribute const* a = elem.get_attribute(attr);
+               if (!a) throw XMLError(elem, "attribute " + attr + " not found");
+               return a->get_value();
+       }
+       template <typename T> bool tryGetAttribute(xmlpp::Element const& elem, std::string const& attr, T& var) {
+               xmlpp::Attribute const* a = elem.get_attribute(attr);
+               if (!a) return false;
+               try {
+                       var = boost::lexical_cast<T>(a->get_value());
+               } catch (std::exception&) {
+                       throw XMLError(elem, "attribute " + attr + " value invalid: " + a->get_value());
+               }
+               return true;
+       }
+       template <typename Numeric> void parse(MinMax<Numeric>& range, xmlpp::Element const& elem) {
+               tryGetAttribute(elem, "min", range.min);
+               tryGetAttribute(elem, "max", range.max);
+       }
+       // Return a NavButton corresponding to an Event
+       NavButton navigation(Event const& ev) {
+               #define DEFINE_BUTTON(dt, btn, num, nav) if ((DEVTYPE_##dt == DEVTYPE_GENERIC || ev.devType == DEVTYPE_##dt) && ev.button == dt##_##btn) return nav;
+               #include "controllers-buttons.ii"
+               return NAV_NONE;
+       }
+
+       std::ostream& operator<<(std::ostream& os, SourceId const& source) {
+               switch (source.type) {
+                       case SOURCETYPE_NONE: return os << "(none)";
+                       case SOURCETYPE_KEYBOARD: return os << "(keyboard " << source.device << " instrument " << source.channel << ")";
+                       case SOURCETYPE_JOYSTICK: return os << "(joystick " << source.device << ")";
+                       case SOURCETYPE_MIDI: return os << "(midi " << source.device << " channel " << source.channel << ")";
+                       case SOURCETYPE_N: break;
+               }
+               throw std::logic_error("Unknown SOURCETYPE in controllers.cc SourceId operator<<");
+       }
+       std::string buttonDebug(DevType type, Button b) {
+               #define DEFINE_BUTTON(dt, btn, num, nav) if ((DEVTYPE_##dt == DEVTYPE_GENERIC || type == DEVTYPE_##dt) && b == dt##_##btn) \
+                 return #dt " " #btn " (" #nav ")";
+               #include "controllers-buttons.ii"
+               throw std::logic_error("Invalid Button value in controllers.cc buttonDebug");
+       }
+       std::ostream& operator<<(std::ostream& os, Event const& ev) {
+               os << ev.source << ' ';
+               // Print hw button info if the event is not assigned to a function, otherwise print assignments
+               if (ev.button == GENERIC_UNASSIGNED) {
+                       if (hwIsAxis.matches(ev.hw)) {
+                               os << "axis hw=" << ev.hw - hwIsAxis.min << " value=" << ev.value;
+                       } else if (hwIsHat.matches(ev.hw)) {
+                               os << "hat hw=" << ev.hw - hwIsHat.min << ' ';
+                               std::string dir;
+                               unsigned val = ev.value;
+                               if (val & SDL_HAT_UP) dir += "up";
+                               if (val & SDL_HAT_DOWN) dir += "down";
+                               if (val & SDL_HAT_LEFT) dir += "left";
+                               if (val & SDL_HAT_RIGHT) dir += "right";
+                               os << (dir.empty() ? "centered" : dir);
+                       }
+                       else os << "button hw=" << ev.hw << " value=" << ev.value;
+               } else {
+                       os << buttonDebug(ev.devType, ev.button) << " value=" << ev.value;
+               }
+               return os;
+       }
+}
+
+struct ButtonMap {
+       Button map;  // Generic action
+       Button negative, positive;  // Half-axis movement
+       Button up, down, left, right;  // Hat direction
+       ButtonMap() { std::memset(this, 0, sizeof(*this)); }
+};
+
+typedef std::map<HWButton, ButtonMap> ButtonMapping;
+
+/// A controller definition from controllers.xml
+struct ControllerDef {
+       std::string name;
+       std::string description;
+       SourceType sourceType;
+       DevType devType;
+       double latency;
+       boost::regex deviceRegex;
+       MinMax<unsigned> deviceMinMax;
+       MinMax<unsigned> channelMinMax;
+       ButtonMapping mapping;
+       ControllerDef(): sourceType(), devType(), latency() {}
+       bool matches(Event const& ev, std::string const& devName) const {
+               if (ev.source.type != sourceType) return false;
+               if (!deviceMinMax.matches(ev.source.device)) return false;
+               if (!channelMinMax.matches(ev.source.channel)) return false;
+               if (!deviceRegex.empty() && !regex_search(devName, deviceRegex)) return false;
+               return true;
+       }
+};
+
+struct Controllers::Impl {
+       typedef std::map<std::string, ControllerDef> ControllerDefs;
+       ControllerDefs m_controllerDefs;
+
+       typedef std::map<std::string, Button> NameToButton;
+       NameToButton m_buttons[DEVTYPE_N];
+
+       typedef std::map<SourceId, ControllerDef const*> Assignments;
+       Assignments m_assignments;
+       
+       typedef std::map<SourceType, Hardware::ptr> HW;
+       HW m_hw;
+
+       std::deque<NavEvent> m_navEvents;
+       std::map<SourceId, DevicePtr> m_orphans;
+       std::map<SourceId, boost::weak_ptr<Device> > m_devices;
+       bool m_eventsEnabled;
+       
+       typedef std::pair<SourceId, ButtonId> UniqueButton;
+       std::map<UniqueButton, double> m_values;
+
+       std::map<NavButton, NavEvent> m_navRepeat;
+       
+       Impl(): m_eventsEnabled() {
+               #define DEFINE_BUTTON(devtype, button, num, nav) m_buttons[DEVTYPE_##devtype][#button] = devtype##_##button;
+               #include "controllers-buttons.ii"
+               readControllers(getShareDir() / "config/controllers.xml");
+               readControllers(getConfigDir() / "controllers.xml");
+               m_hw[SOURCETYPE_KEYBOARD] = constructKeyboard();
+               m_hw[SOURCETYPE_JOYSTICK] = constructJoysticks();
+               if (Hardware::midiEnabled()) m_hw[SOURCETYPE_MIDI] = constructMidi();
+       }
+       
+       void readControllers(fs::path const& file) {
+               if (!fs::is_regular_file(file)) {
+                       std::clog << "controllers/info: Skipping " << file << " (not found)" << std::endl;
+                       return;
+               }
+               std::clog << "controllers/info: Parsing " << file << std::endl;
+               xmlpp::DomParser domParser(file.string());
+               try {
+                       parseControllers(domParser, "/controllers/joystick/controller", SOURCETYPE_JOYSTICK);
+                       parseControllers(domParser, "/controllers/midi/controller", SOURCETYPE_MIDI);
+               } catch (XMLError& e) {
+                       int line = e.elem.get_line();
+                       std::string name = e.elem.get_name();
+                       throw std::runtime_error(file.string() + ":" + boost::lexical_cast<std::string>(line) + " element " + name + " " + e.message);
+               }
+       }
+
+       void parseControllers(xmlpp::DomParser const& dom, std::string const& path, SourceType sourceType) {
+               xmlpp::NodeSet n = dom.get_document()->get_root_node()->find(path);
+               for (xmlpp::NodeSet::const_iterator nodeit = n.begin(), end = n.end(); nodeit != end; ++nodeit) {
+                       xmlpp::Element& elem = dynamic_cast<xmlpp::Element&>(**nodeit);
+                       ControllerDef def;
+                       def.name = getAttribute(elem, "name");
+                       def.sourceType = sourceType;
+                       // Device type
+                       {
+                               std::string type = getAttribute(elem, "type");
+                               if (type == "guitar") def.devType = DEVTYPE_GUITAR;
+                               else if (type == "drumkit") def.devType = DEVTYPE_DRUMS;
+                               else if (type == "keytar") def.devType = DEVTYPE_KEYTAR;
+                               else if (type == "piano") def.devType = DEVTYPE_PIANO;
+                               else if (type == "dancepad") def.devType = DEVTYPE_DANCEPAD;
+                               else {
+                                       std::clog << "controllers/warning: " << type << ": Unknown controller type in controllers.xml (skipped)" << std::endl;
+                                       continue;
+                               }
+                       }
+                       xmlpp::NodeSet ns;
+                       // Device description
+                       ns = elem.find("description/text()");
+                       if (ns.size() == 1) def.description = dynamic_cast<xmlpp::TextNode&>(*ns[0]).get_content();
+                       // Read filtering rules
+                       ns = elem.find("device");
+                       if (ns.size() == 1) {
+                               xmlpp::Element& elem = dynamic_cast<xmlpp::Element&>(*ns[0]);
+                               std::string regex;
+                               if (tryGetAttribute(elem, "regex", regex)) def.deviceRegex = regex;
+                               parse(def.deviceMinMax, elem);
+                               double latency;
+                               if (tryGetAttribute(elem, "latency", latency)) def.latency = latency;
+                       }
+                       ns = elem.find("channel");
+                       if (ns.size() == 1) parse(def.channelMinMax, dynamic_cast<xmlpp::Element&>(*ns[0]));
+                       // Read button mapping
+                       ns = elem.find("mapping/*");
+                       for (xmlpp::NodeSet::const_iterator nodeit2 = ns.begin(), end = ns.end(); nodeit2 != end; ++nodeit2) {
+                               xmlpp::Element& elem = dynamic_cast<xmlpp::Element&>(**nodeit2);
+                               HWButton hw;
+                               if (!tryGetAttribute(elem, "hw", hw)) throw XMLError(elem, "Mandatory attribute hw is missing or invalid");
+                               // Axes and hats use different HWButton ranges internally
+                               if (elem.get_name() == "axis") hw = HWButton(hw + hwIsAxis.min);
+                               else if (elem.get_name() == "hat") hw = HWButton(hw + hwIsHat.min);
+                               // Parse the mapping for this HWButton
+                               ButtonMap& m = def.mapping[hw];
+                               m.map = parseButton(elem, "map", def);
+                               m.negative = parseButton(elem, "negative", def);
+                               m.positive = parseButton(elem, "positive", def);
+                               m.up = parseButton(elem, "up", def);
+                               m.down = parseButton(elem, "down", def);
+                               m.left = parseButton(elem, "left", def);
+                               m.right = parseButton(elem, "right", def);
+                       }
+                       // Add/replace the controller definition
+                       std::clog << "controllers/info: " << (m_controllerDefs.find(def.name) == m_controllerDefs.end() ? "Controller" : "Overriding")
+                         << " definition: " << def.name << ": " << def.description << std::endl;
+                       m_controllerDefs[def.name] = def;
+               }
+       }
+       /// Read a button attribute from XML element
+       Button parseButton(xmlpp::Element const& elem, std::string const& attr, ControllerDef const& def) {
+               std::string action;
+               tryGetAttribute(elem, attr, action);
+               return findButton(def.devType, action);
+       }
+       /// Find button by name, either of given type or of generic type
+       Button findButton(DevType type, std::string name) {
+               Button button = GENERIC_UNASSIGNED;
+               if (name.empty()) return button;
+               boost::algorithm::to_upper(name);
+               boost::algorithm::replace_all(name, "-", "_");
+               // Try getting button first from devtype-specific, then generic names
+               buttonByName(type, name, button) || buttonByName(DEVTYPE_GENERIC, name, button) ||
+                 std::clog << "controllers/warning: " << name << ": Unknown button name in controllers.xml." << std::endl;
+               return button;
+       }
+       /// Try to find button of specific type
+       bool buttonByName(DevType type, std::string const& name, Button& button) {
+               NameToButton const& n2b = m_buttons[type];
+               auto it = n2b.find(name);
+               if (it == n2b.end()) return false;
+               button = it->second;
+               return true;
+       }
+       /// Return the next available navigation event from queue, if available
+       bool getNav(NavEvent& ev) {
+               if (m_navEvents.empty()) return false;
+               ev = m_navEvents.front();
+               m_navEvents.pop_front();
+               return true;
+       }
+       /// Register an orphan device
+       DevicePtr registerDevice(SourceId const& source) {
+               auto it = m_orphans.find(source);
+               if (it == m_orphans.end()) return DevicePtr();
+               DevicePtr ret = it->second;
+               m_orphans.erase(it);
+               return ret;
+       }
+       void enableEvents(bool state) {
+               m_eventsEnabled = state;
+               Hardware::enableKeyboardInstruments(state);
+               if (!state) {
+                       m_orphans.clear();
+                       m_devices.clear();
+               }
+       }
+       /// Do internal event processing (poll for MIDI events etc)
+       void process(boost::xtime const& now) {
+               for (auto& typehw: m_hw) {
+                       while (true) {
+                               Event event;
+                               event.time = now;
+                               if (!typehw.second->process(event)) break;
+                               pushHWEvent(event);
+                       }
+               }
+               for (auto& kv: m_navRepeat) {
+                       NavEvent& ne = kv.second;
+                       double delay = 2.0 / (10 + ne.repeat);
+                       if (now - ne.time < delay) continue;  // Not yet time to repeat
+                       // Emit auto-repeated event
+                       // Note: We intentionally only emit one per frame (call to process) to avoid surprises when latency spikes occur.
+                       ++ne.repeat;
+                       ne.time += delay;  // Increment rather than set to now, so that repeating is smoother.
+                       std::clog << "controllers/debug: NavEvent auto repeat " << ne.repeat << " next=" << now - ne.time << " delay=" << delay << std::endl;
+                       m_navEvents.push_back(ne);
+               }
+       }
+       /// Handle an incoming SDL event
+       bool pushEvent(SDL_Event const& sdlEv, boost::xtime const& t) {
+               for (auto& typehw: m_hw) {
+                       Event event;
+                       event.time = t;
+                       if (typehw.second->process(event, sdlEv)) { pushHWEvent(event); return true; }
+               }
+               return false;
+       }
+       /// Assign event's source a ControllerDef (if not already assigned) and return it
+       ControllerDef const* assign(Event const& event) {
+               // Attempt insertion (does not override existing values)
+               std::pair<Assignments::iterator, bool> ret = m_assignments.insert(Assignments::value_type(event.source, nullptr));
+               ControllerDef const*& def = ret.first->second;  // A reference to the value inside the map
+               if (!ret.second) return def;  // Source already assigned, just return it.
+               std::string devName = m_hw[event.source.type]->getName(event.source.device);
+               // Find a matching ControllerDef
+               for (ControllerDefs::const_iterator it = m_controllerDefs.begin(); it != m_controllerDefs.end() && !def; ++it) {
+                       if (it->second.matches(event, devName)) def = &it->second;
+               }
+               if (def) std::clog << "controllers/info: Assigned " << event.source << " as " << def->name << std::endl;
+               else if (!event.source.isKeyboard()) std::clog << "controllers/warning: \"" << devName << " " << event.source << "\" not found from controllers.xml. Please report a bug if this is a game controller." << std::endl;
+               return def;
+       }
+       /// Handle an incoming hardware event
+       void pushHWEvent(Event event) {
+               ControllerDef const* def = assign(event);
+               if (!def) {
+                       pushMappedEvent(event);  // This is for keyboard events mainly (they have no ControllerDefs)
+                       return;
+               }
+               event.time += -def->latency;
+               event.devType = def->devType;
+               // Mapping from controllers.xml
+               auto it = def->mapping.find(event.hw);
+               if (it != def->mapping.end()) {
+                       Event ev = event;  // Make a copy for fiddling
+                       bool handled = false;
+                       ButtonMap const& m = it->second;
+                       double value = ev.value;
+                       unsigned val = value;
+                       ev.button = m.map; if (pushMappedEvent(ev)) handled = true;
+                       ev.button = m.positive; ev.value = clamp(value); if (pushMappedEvent(ev)) handled = true;
+                       ev.button = m.negative; ev.value = clamp(-value); if (pushMappedEvent(ev)) handled = true;
+                       if (hwIsHat.matches(ev.hw)) {
+                               ev.button = m.up; ev.value = !!(val & SDL_HAT_UP); if (pushMappedEvent(ev)) handled = true;
+                               ev.button = m.down; ev.value = !!(val & SDL_HAT_DOWN); if (pushMappedEvent(ev)) handled = true;
+                               ev.button = m.left; ev.value = !!(val & SDL_HAT_LEFT); if (pushMappedEvent(ev)) handled = true;
+                               ev.button = m.right; ev.value = !!(val & SDL_HAT_RIGHT); if (pushMappedEvent(ev)) handled = true;
+                       }
+                       if (!handled) std::clog << "controllers/info: ignored " << event << std::endl;  // No matching attribute in controllers.xml
+               } else {
+                       std::clog << "controllers/warning: not mapped " << event << std::endl;  // No matching button/axis/hat element in controllers.xml
+               }
+       }
+       bool pushMappedEvent(Event& ev) {
+               if (ev.button == GENERIC_UNASSIGNED) return false;
+               if (!valueChanged(ev)) return false;  // Avoid repeated or other useless events
+               std::clog << "controllers/debug: processing " << ev << std::endl;
+               ev.nav = navigation(ev);
+               // Emit nav event (except if device is currently registered for events)
+               if (ev.nav != NAV_NONE) {
+                       NavEvent ne(ev);
+                       // Menu navigation mapping
+                       {
+                               bool vertical = (ev.devType == DEVTYPE_GUITAR);
+                               if (ne.button == NAV_UP) ne.menu = (vertical ? NAVMENU_A_PREV : NAVMENU_B_PREV);
+                               else if (ne.button == NAV_DOWN) ne.menu = (vertical ? NAVMENU_A_NEXT : NAVMENU_B_NEXT);
+                               else if (ne.button == NAV_LEFT) ne.menu = (vertical ? NAVMENU_B_PREV : NAVMENU_A_PREV);
+                               else if (ne.button == NAV_RIGHT) ne.menu = (vertical ? NAVMENU_B_NEXT : NAVMENU_A_NEXT);
+                       }
+                       if (ev.value != 0.0) {
+                               m_navEvents.push_back(ne);
+                               if (ne.button >= NAV_REPEAT) m_navRepeat.insert(std::make_pair(ne.button, ne));
+                       } else {
+                               if (ne.button >= NAV_REPEAT) m_navRepeat.erase(ne.button);
+                       }
+               }
+               if (m_eventsEnabled) {
+                       // Emit Event and construct a new Device first if needed
+                       DevicePtr ptr = m_devices[ev.source].lock();
+                       if (!ptr) {
+                               ptr.reset(new Device(ev.source, ev.devType));
+                               m_orphans[ev.source] = ptr;
+                               m_devices[ev.source] = ptr;
+                       }
+                       ptr->pushEvent(ev);
+               }
+               return true;
+       }
+       /// Test if button's value has changed since the last call to this function
+       bool valueChanged(Event const& ev) {
+               // Find the matching UniqueButton or add a new one with NaN value
+               auto res = m_values.insert(std::make_pair(UniqueButton(ev.source, ev.button), getNaN()));
+               double& value = res.first->second;
+               // Check and update value
+               if (value == ev.value) return false;
+               value = ev.value;
+               return true;
+       }
+};
+
+// External API simply wraps self (pImpl)
+Controllers::Controllers(): self(new Controllers::Impl()) {}
+Controllers::~Controllers() {}
+bool Controllers::getNav(NavEvent& ev) { return self->getNav(ev); }
+DevicePtr Controllers::registerDevice(SourceId const& source) { return self->registerDevice(source); }
+void Controllers::enableEvents(bool state) { self->enableEvents(state); }
+void Controllers::process(boost::xtime const& now) { self->process(now); }
+bool Controllers::pushEvent(SDL_Event const& ev, boost::xtime const& t) { return self->pushEvent(ev, t); }
+
+bool Device::getEvent(Event& ev) {
+       if (m_events.empty()) return false;
+       ev = m_events.front();
+       m_events.pop_front();
+       return true;
+}
+
+void Device::pushEvent(Event const& ev) {
+       m_events.push_back(ev);
+}
+
diff --git a/game/controllers.hh b/game/controllers.hh
new file mode 100644 (file)
index 0000000..c4aa294
--- /dev/null
@@ -0,0 +1,139 @@
+#pragma once
+
+#include <climits>
+#include <deque>
+#include <vector>
+#include <iostream>
+#include <stdexcept>
+#include <boost/noncopyable.hpp>
+#include <boost/smart_ptr/scoped_ptr.hpp>
+
+#include "SDL_events.h"
+
+#include "util.hh"
+#include "xtime.hh"
+#include "configuration.hh"
+
+namespace input {
+       enum SourceType { SOURCETYPE_NONE, SOURCETYPE_JOYSTICK, SOURCETYPE_MIDI, SOURCETYPE_KEYBOARD, SOURCETYPE_N };
+       enum DevType { DEVTYPE_GENERIC, DEVTYPE_VOCALS, DEVTYPE_GUITAR, DEVTYPE_DRUMS, DEVTYPE_KEYTAR, DEVTYPE_PIANO, DEVTYPE_DANCEPAD, DEVTYPE_N };
+       /// Generalized mapping of navigation actions
+       enum NavButton {
+               NAV_NONE /* No NavEvent emitted */, NAV_SOME /* Major gameplay button with no direct nav function, used for joining instruments */,
+               NAV_START, NAV_CANCEL, NAV_PAUSE,
+               NAV_REPEAT = 0x80 /* Anything after this is auto-repeating */,
+               NAV_UP, NAV_DOWN, NAV_LEFT, NAV_RIGHT, NAV_MOREUP, NAV_MOREDOWN, NAV_VOLUME_UP, NAV_VOLUME_DOWN
+       };
+       /// Alternative orientation-agnostic mapping where A axis is the one that is easiest to access (e.g. guitar pick) and B might not be available on all devices
+       enum NavMenu { NAVMENU_NONE, NAVMENU_A_PREV, NAVMENU_A_NEXT, NAVMENU_B_PREV, NAVMENU_B_NEXT };
+
+       enum ButtonId: unsigned {
+               // Button constants for each DevType
+               #define DEFINE_BUTTON(devtype, button, num, nav) devtype##_##button = num,
+               #include "controllers-buttons.ii"
+       };
+
+       struct Button {
+               ButtonId id;
+               Button(ButtonId id = GENERIC_UNASSIGNED): id(id) {}
+               Button(unsigned layer, unsigned num): id(ButtonId(layer << 8 | num)) {}
+               operator ButtonId() const { return id; }
+               unsigned layer() const { return id >> 8; }
+               unsigned num() const { return id & 0xFF; }
+               bool generic() const { return layer() == 0x100; }
+       };
+
+       typedef unsigned HWButton;
+       static const MinMax<HWButton> hwIsAxis(0x10000000u, 0x1000FFFFu);
+       static const MinMax<HWButton> hwIsHat(0x11000000u, 0x1100FFFFu);
+       
+       /// Each controller has unique SourceId that can be used for telling players apart etc.
+       struct SourceId {
+               SourceId(SourceType type = SOURCETYPE_NONE, unsigned device = 0, unsigned channel = 0): type(type), device(device), channel(channel) {
+               }
+               SourceType type;
+               unsigned device, channel;  ///< Device number and channel (0..1023)
+               /// Provide numeric conversion for comparison and ordered containers
+               operator unsigned() const { return unsigned(type)<<20 | device<<10 | channel; }
+               bool isKeyboard() const { return type == SOURCETYPE_KEYBOARD; }  ///< This is so common test that a helper is provided
+       };
+       
+       struct Event {
+               SourceId source; ///< Where did it originate from
+               HWButton hw; ///< Hardware button number (for internal use and debugging only)
+               Button button; ///< Mapped button id
+               NavButton nav; ///< Navigational button interpretation
+               double value; ///< Zero for button release, up to 1.0 for press (e.g. velocity value), or axis value (-1.0 .. 1.0)
+               boost::xtime time; ///< When did the event occur
+               DevType devType; ///< Device type
+               Event(): source(), hw(), nav(NAV_NONE), value(), time(), devType() {}
+               bool pressed() const { return value != 0.0; }
+       };
+
+       /// NavEvent is a menu navigation event, generalized for all controller type so that the user doesn't need to know about controllers.
+       struct NavEvent {
+               SourceId source;
+               DevType devType;
+               NavButton button;
+               NavMenu menu;
+               boost::xtime time;
+               unsigned repeat;  ///< Zero for hardware event, increased by one for each auto-repeat
+               NavEvent(): source(), devType(), button(), menu(), time(), repeat() {}
+               explicit NavEvent(Event const& ev): source(ev.source), devType(ev.devType), button(ev.nav), menu(), time(ev.time), repeat() {}
+       };
+       
+       /// A handle for receiving device events
+       class Device: boost::noncopyable {
+               typedef std::deque<Event> Events;
+               Events m_events;
+       public:
+               const SourceId source;
+               const DevType type;
+               Device(SourceId const& source, DevType type): source(source), type(type) {}
+               bool getEvent(Event&);
+               void pushEvent(Event const&);
+       };
+       typedef boost::shared_ptr<Device> DevicePtr;
+
+       /// The main controller class that contains everything
+       class Controllers: boost::noncopyable {
+       public:
+               Controllers();
+               ~Controllers();
+               /// Return true and a nav event if there are any in queue. Otherwise return false.
+               bool getNav(NavEvent& ev);
+               /// Enable or disable event processing (pending events will be cleared).
+               void enableEvents(bool state);
+               /// Adopt a specific orphan device (for receiving Events).
+               DevicePtr registerDevice(SourceId const& source);
+               /// Internally poll for new events. The current time is passed for reference.
+               void process(boost::xtime const& now);
+               /// Push an SDL event for processing. Returns true if the event was taken (recognized and accepted).
+               bool pushEvent(SDL_Event const& sdlEv, boost::xtime const& now);
+       private:
+               struct Impl;
+               boost::scoped_ptr<Impl> self;
+       };
+
+       /// Base class for different types of hardware backends.
+       class Hardware: boost::noncopyable {
+       public:
+               static bool midiEnabled();
+               static void enableKeyboardInstruments(bool state);
+               virtual ~Hardware() {}
+               /// Get the name of a specific device of this type
+               virtual std::string getName(unsigned) const { return std::string(); }
+               /// Return an Event and true if any are available. The Event is pre-initialized with current time.
+               virtual bool process(Event&) { return false; }
+               /// Convert an SDL event into Event. The Event is pre-initialized with event's time. Returns false if SDL_Event was not handled.
+               virtual bool process(Event&, SDL_Event const&) { return false; }
+               // Note: process functions are expected to return Event with source, hw and value set and possibly with time adjusted.
+               typedef boost::shared_ptr<Hardware> ptr;
+       };
+       
+       Hardware::ptr constructKeyboard();
+       Hardware::ptr constructJoysticks();
+       Hardware::ptr constructMidi();
+}
+
+
diff --git a/game/dancegraph.cc b/game/dancegraph.cc
new file mode 100644 (file)
index 0000000..82b4d8d
--- /dev/null
@@ -0,0 +1,544 @@
+#include "dancegraph.hh"
+#include "song.hh"
+#include "i18n.hh"
+
+#include <boost/lexical_cast.hpp>
+#include <stdexcept>
+#include <algorithm>
+
+namespace {
+       // Position mappings for panels
+       static const int mapping4[max_panels] = {0, 1, 2, 3,-1,-1,-1,-1,-1,-1};
+       static const int mapping5[max_panels] = {0, 1, 3, 4, 2,-1,-1,-1,-1,-1};
+       static const int mapping6[max_panels] = {0, 2, 3, 5, 1, 4,-1,-1,-1,-1};
+       static const int mapping7[max_panels] = {0, 2, 4, 6, 1, 5, 3,-1,-1,-1};
+       static const int mapping8[max_panels] = {0, 3, 4, 7, 1, 6, 2, 5,-1,-1};
+       static const int mapping10[max_panels]= {0, 3, 4, 7, 1, 6, 2, 5,-1,-1};
+       #if 0 // Here is some dummy gettext calls to populate the dictionary
+       _("Beginner") _("Easy") _("Medium") _("Hard") _("Challenge")
+       #endif
+       const std::string diffv[] = { "Beginner", "Easy", "Medium", "Hard", "Challenge" };
+       const float past = -0.3f; // Relative time from cursor that is considered past (out of screen)
+       const float future = 2.0f; // Relative time from cursor that is considered future (out of screen)
+       const float timescale = 12.0f; // Multiplier to get graphics units from time
+       const float texCoordStep = -0.25f; // Four beat lines per beat texture
+       // Note: t is difference from playback time so it must be in range [past, future]
+       float time2y(float t) { return timescale * (t - past) / (future - past); }
+       float time2a(float t) {
+               float a = clamp(1.0 - t / future); // Note: we want 1.0 alpha already at zero t.
+               return std::pow(a, 0.8f); // Nicer curve
+       }
+       const double maxTolerance = 0.15; // Maximum error in seconds
+       int getNextBigStreak(int prev) { return prev + 10; }
+
+       /// Get an accuracy value [0, 1] for the error offset (in seconds)
+       double accuracy(double error) { return 1.0 - (std::abs(error) / maxTolerance); };
+
+       /// Gives points based on error from a perfect hit
+       double points(double error) {
+               double ac = accuracy(error);
+               if (ac > .90) return 50.0;  // Perfect
+               if (ac > .80) return 40.0;  // Excellent
+               if (ac > .70) return 30.0;  // Great
+               if (ac > .60) return 20.0;  // Good
+               if (ac > .40) return 15.0;  // OK
+               if (ac > .20) return 10.0;  // Late/Early
+               return 5.0;  // Way off
+       }
+
+       std::string getRank(double error) {
+               double ac = accuracy(error);
+               if (error < 0.0) {
+                       if (ac > .90) return "Perfect!";
+                       if (ac > .80) return "Excellent!-";
+                       if (ac > .70) return "Great!-";
+                       if (ac > .60) return " Good!- ";
+                       if (ac > .40) return "  OK!-  ";
+                       if (ac > .20) return "Late!-";
+                       return "Way off!";
+               } else {
+                       if (ac > .90) return "Perfect!";
+                       if (ac > .80) return "-Excellent!";
+                       if (ac > .70) return "-Great!";
+                       if (ac > .60) return " -Good! ";
+                       if (ac > .40) return "  -OK!  ";
+                       if (ac > .20) return "-Early!";
+                       return "Way off!";
+               }
+       }
+
+       struct lessEnd {
+               bool operator()(const DanceNote& left, const DanceNote& right) {
+                       return left.note.end < right.note.end;
+               }
+       };
+}
+
+
+/// Constructor
+DanceGraph::DanceGraph(Audio& audio, Song const& song, input::DevicePtr dev):
+  InstrumentGraph(audio, song, dev),
+  m_level(BEGINNER),
+  m_beat(findFile("dancebeat.svg")),
+  m_arrows(findFile("arrows.svg")),
+  m_arrows_cursor(findFile("arrows_cursor.svg")),
+  m_arrows_hold(findFile("arrows_hold.svg")),
+  m_mine(findFile("mine.svg")),
+  m_insideStop()
+{
+       // Initialize some arrays
+       for (size_t i = 0; i < max_panels; i++) {
+               m_activeNotes[i] = m_notes.end();
+               m_pressed_anim[i] = AnimValue(0.0, 4.0);
+               m_arrow_map[i] = -1;
+       }
+
+       if(m_song.danceTracks.empty())
+               throw std::runtime_error("Could not find any dance tracks.");
+       changeTrack(0); // Get an initial game mode and notes for it
+       setupJoinMenu(); // Finally setup the menu
+}
+
+
+void DanceGraph::setupJoinMenu() {
+       m_menu.clear();
+       updateJoinMenu();
+       // Populate root menu
+       m_menu.add(MenuOption(_("Ready!"), _("Start performing!")));
+       { // Create track selector
+               ConfigItem::OptionList ol;
+               int i = 0, cur = 0;
+               // Add tracks to option list
+               for (auto it = m_song.danceTracks.begin(); it != m_song.danceTracks.end(); ++it, ++i) {
+                       ol.push_back(it->first);
+                       if (m_gamingMode == it->first) cur = i; // Find the index of current track
+               }
+               m_selectedTrack = ConfigItem(ol); // Create a ConfigItem from the option list
+               m_selectedTrack.select(cur); // Set the selection to current level
+               m_menu.add(MenuOption("", _("Select track")).changer(m_selectedTrack)); // MenuOption that cycles the options
+               m_menu.back().setDynamicName(m_trackOpt); // Set the title to be dynamic
+       }
+       { // Create difficulty opt
+               ConfigItem::OptionList ol;
+               int i = 0, cur = 0;
+               // Add difficulties to the option list
+               for (int level = 0; level < DIFFICULTYCOUNT; ++level) {
+                       if (difficulty(DanceDifficulty(level), true)) {
+                               ol.push_back(boost::lexical_cast<std::string>(level));
+                               if (DanceDifficulty(level) == m_level) cur = i;
+                               ++i;
+                       }
+               }
+               m_selectedDifficulty = ConfigItem(ol); // Create a ConfigItem from the option list
+               m_selectedDifficulty.select(cur); // Set the selection to current level
+               m_menu.add(MenuOption("", _("Select difficulty")).changer(m_selectedDifficulty)); // MenuOption that cycles the options
+               m_menu.back().setDynamicName(m_difficultyOpt); // Set the title to be dynamic
+       }
+       m_menu.add(MenuOption(_("Quit"), _("Exit to song browser")).screen("Songs"));
+}
+
+void DanceGraph::updateJoinMenu() {
+       m_trackOpt = getTrack();
+       m_difficultyOpt = getDifficultyString();
+}
+
+/// Attempt to select next/previous game mode
+void DanceGraph::changeTrack(int direction) {
+       // Cycling
+       if (direction == 0) {
+               m_curTrackIt = m_song.danceTracks.find("dance-single");
+               if (m_curTrackIt == m_song.danceTracks.end())
+                       m_curTrackIt = m_song.danceTracks.begin();
+       } else if (direction > 0) {
+               ++m_curTrackIt;
+               if (m_curTrackIt == m_song.danceTracks.end()) m_curTrackIt = m_song.danceTracks.begin();
+       } else if (direction < 0) {
+               if (m_curTrackIt == m_song.danceTracks.begin()) m_curTrackIt = (--m_song.danceTracks.end());
+               else --m_curTrackIt;
+       }
+       finalizeTrackChange();
+}
+
+/// Attempt to select a specific game mode
+void DanceGraph::setTrack(const std::string& track) {
+       auto it = m_song.danceTracks.find(track);
+       if (it == m_song.danceTracks.end()) return;
+       m_curTrackIt = it;
+       finalizeTrackChange();
+}
+
+void DanceGraph::finalizeTrackChange() {
+       // Determine how many arrow lines are needed
+       m_gamingMode = m_curTrackIt->first;
+       std::string gm = m_gamingMode;
+       if (gm == "dance-single") { m_pads = 4; std::copy(mapping4, mapping4+max_panels, m_arrow_map); }
+       else if (gm == "dance-double") { m_pads = 8; std::copy(mapping8, mapping8+max_panels, m_arrow_map); }
+       else if (gm == "dance-couple") { m_pads = 8; std::copy(mapping8, mapping8+max_panels, m_arrow_map); }
+       else if (gm == "dance-solo") { m_pads = 6; std::copy(mapping6, mapping6+max_panels, m_arrow_map); }
+       else if (gm == "pump-single") { m_pads = 5 ; std::copy(mapping5, mapping5+max_panels, m_arrow_map); }
+       else if (gm == "pump-double") { m_pads = 10; std::copy(mapping10, mapping10+max_panels, m_arrow_map); }
+       else if (gm == "pump-couple") { m_pads = 10; std::copy(mapping10, mapping10+max_panels, m_arrow_map); }
+       else if (gm == "ez2-single") { m_pads = 5; std::copy(mapping5, mapping5+max_panels, m_arrow_map); }
+       else if (gm == "ez2-double") { m_pads = 10; std::copy(mapping10, mapping10+max_panels, m_arrow_map); }
+       else if (gm == "ez2-real") { m_pads = 7; std::copy(mapping7, mapping7+max_panels, m_arrow_map); }
+       else if (gm == "para-single") { m_pads = 5; std::copy(mapping5, mapping5+max_panels, m_arrow_map); }
+       else throw std::runtime_error("Unknown track " + gm);
+
+       changeDifficulty(0); // Construct new notes
+       setupJoinMenu();
+       m_menu.select(1); // Restore selection to the track item
+}
+
+/// Get the track string
+std::string DanceGraph::getTrack() const {
+       return _(m_gamingMode.c_str());
+}
+
+/// Get the difficulty as displayable string
+std::string DanceGraph::getDifficultyString() const {
+       return _(diffv[m_level].c_str());
+}
+
+/// Get a string id for track and difficulty
+std::string DanceGraph::getModeId() const {
+       return m_gamingMode + " - " + diffv[m_level] + (isKeyboard() ? " (kbd)" : "");
+}
+
+/// Attempt to change the difficulty by a step
+void DanceGraph::changeDifficulty(int delta) {
+       int newLevel = m_level + delta;
+       if(newLevel >= DIFFICULTYCOUNT || newLevel < 0) return; // Out of bounds
+       auto it = m_song.danceTracks.find(m_gamingMode);
+       if(it->second.find((DanceDifficulty)newLevel) != it->second.end())
+               difficulty((DanceDifficulty)newLevel);
+       else
+               changeDifficulty(delta + (delta < 0 ? -1 : 1));
+}
+
+/// Select a difficulty and construct DanceNotes and score normalizer for it
+bool DanceGraph::difficulty(DanceDifficulty level, bool check_only) {
+       // TODO: error handling
+       DanceDifficultyMap const& ddm = m_song.danceTracks.find(m_gamingMode)->second;
+       if (ddm.find(level) == ddm.end()) return false; else if (check_only) return true;
+       m_notes.clear();
+       DanceTrack const& track = ddm.find(level)->second;
+       for (auto const& n: track.notes) m_notes.push_back(DanceNote(n));
+       std::sort(m_notes.begin(), m_notes.end(), lessEnd()); // for engine's iterators
+       m_notesIt = m_notes.begin();
+       m_level = level;
+       for (auto& noteIt: m_activeNotes) noteIt = m_notes.end();
+       m_scoreFactor = 1;
+       if (!m_notes.empty()) m_scoreFactor = 10000.0 / (50 * m_notes.size()); // maxpoints / (notepoint * notes)
+       updateJoinMenu();
+       return true;
+}
+
+/// Handles input and some logic
+void DanceGraph::engine() {
+       double time = m_audio.getPosition();
+       time -= config["audio/controller_delay"].f();
+       doUpdates();
+       // Handle stops
+       bool outsideStop = true;
+       for (auto const& stop: m_song.stops) {
+               if (stop.first >= time) break;
+               if (time < stop.first + stop.second) {  // Inside stop
+                       time = stop.first;
+                       if (!m_insideStop) {
+                               m_popups.push_back(Popup(_("STOP!"),  Color(1.0, 0.8, 0.0), 2.0, m_popupText.get()));
+                               m_insideStop = true;
+                       }
+                       outsideStop = false;
+                       break;
+               }
+               time -= stop.second;
+       }
+       if (outsideStop && m_insideStop) m_insideStop = false;
+       bool difficulty_changed = false;
+       // Handle all events
+       for (input::Event ev; m_dev->getEvent(ev); ) {
+               m_dead = 0; // Keep alive
+               // Menu keys
+               if (menuOpen() && ev.value != 0.0) {
+                       if (ev.nav == input::NAV_START || ev.nav == input::NAV_CANCEL) m_menu.close();
+                       else if (ev.nav == input::NAV_RIGHT) m_menu.action(1);
+                       else if (ev.nav == input::NAV_LEFT) m_menu.action(-1);
+                       else if (ev.nav == input::NAV_UP) m_menu.move(-1);
+                       else if (ev.nav == input::NAV_DOWN) m_menu.move(1);
+                       difficulty_changed = true;
+                       // See if anything changed
+                       if (m_selectedTrack.so() != m_gamingMode) setTrack(m_selectedTrack.so());
+                       else if (boost::lexical_cast<int>(m_selectedDifficulty.so()) != m_level)
+                               difficulty(DanceDifficulty(boost::lexical_cast<int>(m_selectedDifficulty.so())));
+                       else if (m_rejoin.b()) { unjoin(); setupJoinMenu(); m_dev->pushEvent(input::Event()); /* FIXME: HACK? */ }
+                       // Sync dynamic stuff
+                       updateJoinMenu();
+               // Open Menu
+               } else if (!menuOpen() && ev.value != 0.0) {
+                       if (ev.nav == input::NAV_CANCEL || ev.nav == input::NAV_START) m_menu.open();
+               }
+               if (ev.button < max_panels) {
+                       // Gaming controls
+                       if (ev.value == 0.0) {
+                               m_pressed[ev.button] = false;
+                               dance(time, ev);
+                               m_pressed_anim[ev.button].setTarget(0.0);
+                       } else if (ev.value != 0.0) {
+                               m_pressed[ev.button] = true;
+                               dance(time, ev);
+                               m_pressed_anim[ev.button].setValue(1.0);
+                       }
+               }
+       }
+
+       // Countdown to start
+       handleCountdown(time, time < getNotesBeginTime() ? getNotesBeginTime() : m_jointime+1);
+
+       // Notes gone by
+       for (DanceNotes::iterator& it = m_notesIt; it != m_notes.end() && time > it->note.end + maxTolerance; it++) {
+               if(!it->isHit) { // Missed
+                       if (it->note.type != Note::MINE) m_streak = 0;
+               } else { // Hit, add score
+                       if(it->note.type != Note::MINE) m_score += it->score;
+                       if(!it->releaseTime) it->releaseTime = time;
+               }
+               if (!joining(time)) ++m_dead;  // Increment dead counter (but not while joining)
+       }
+       if (difficulty_changed) m_dead = 0; // if difficulty is changed, m_dead would get incorrect
+
+       // Holding button when mine comes?
+       for (auto it = m_notesIt; it != m_notes.end() && time <= it->note.begin + maxTolerance; ++it) {
+               if(!it->isHit && it->note.type == Note::MINE && m_pressed[it->note.note] &&
+                 it->note.begin >= time - maxTolerance && it->note.end <= time + maxTolerance) {
+                       it->isHit = true;
+                       m_score -= points(0);
+               }
+       }
+
+       // Check if a long streak goal has been reached
+       if (m_streak >= getNextBigStreak(m_bigStreak)) {
+               m_bigStreak = getNextBigStreak(m_bigStreak);
+               m_popups.push_back(Popup(boost::lexical_cast<std::string>(unsigned(m_bigStreak)) + "\n" + _("Streak!"),
+                 Color(1.0, 0.0, 0.0), 1.0, m_popupText.get()));
+       }
+}
+
+/// Handles scoring and such
+void DanceGraph::dance(double time, input::Event const& ev) {
+       // Handle release events
+       if (ev.value == 0.0) {
+               auto it = m_activeNotes[ev.button];
+               if(it != m_notes.end()) {
+                       if(!it->releaseTime && it->note.end > time + maxTolerance) {
+                               it->releaseTime = time;
+                               it->score = 0;
+                               m_streak = 0;
+                       }
+               }
+               return;
+       }
+
+       // So it was a PRESS event
+       for (auto it = m_notesIt; it != m_notes.end() && time <= it->note.end + maxTolerance; ++it) {
+               if(!it->isHit && std::abs(time - it->note.begin) <= maxTolerance && ev.button == unsigned(it->note.note)) {
+                       it->isHit = true;
+                       if (it->note.type != Note::MINE) {
+                               it->score = points(it->note.begin - time);
+                               it->error = it->note.begin - time;
+                               m_streak++;
+                               if (m_streak > m_longestStreak) m_longestStreak = m_streak;
+                       } else { // Mine!
+                               m_score -= points(0);
+                               m_streak = 0;
+                       }
+                       m_activeNotes[ev.button] = it;
+                       break;
+               }
+       }
+}
+
+
+namespace {
+       const float arrowSize = 0.4f; // Half width of an arrow
+       const float one_arrow_tex_w = 1.0 / 8.0; // Width of a single arrow in texture coordinates
+
+       /// Create a symmetric vertex pair for arrow drawing
+       void vertexPair(glutil::VertexArray& va, int arrow_i, float y, float ty) {
+               if (arrow_i < 0) {
+                       // Single thing in a texture (e.g. mine)
+                       va.texCoord(0.0f, ty).vertex(-arrowSize, y);
+                       va.texCoord(1.0f, ty).vertex(arrowSize, y);
+               } else {
+                       // Arrow from a texture atlas
+                       va.texCoord(arrow_i * one_arrow_tex_w, ty).vertex(-arrowSize, y);
+                       va.texCoord((arrow_i+1) * one_arrow_tex_w, ty).vertex(arrowSize, y);
+               }
+       }
+}
+
+/// Draw a dance pad icon using the given texture
+void DanceGraph::drawArrow(int arrow_i, Texture& tex, float ty1, float ty2) {
+       glActiveTexture(GL_TEXTURE0);
+       glBindTexture(tex.type(), tex.id());
+       glutil::VertexArray va;
+       vertexPair(va, arrow_i, -arrowSize, ty1);
+       vertexPair(va, arrow_i,  arrowSize, ty2);
+       va.draw();
+}
+
+/// Draws the dance graph
+void DanceGraph::draw(double time) {
+       for (auto const& stop: m_song.stops) {
+               if (stop.first >= time) break;
+               if (time < stop.first + stop.second) { time = stop.first; break; } // Inside stop
+               time -= stop.second;
+       }
+
+       Dimensions dimensions(1.0); // FIXME: bogus aspect ratio (is this fixable?)
+       dimensions.screenTop().middle(m_cx.get()).stretch(m_width.get(), 1.0);
+       ViewTrans view(0.5 * (dimensions.x1() + dimensions.x2()), 0.0, 0.75);  // Apply a per-player local perspective
+       {
+               using namespace glmath;
+               // Some matrix magic to get the viewport right
+               float temp_s = dimensions.w() / 8.0f; // Allow for 8 pads to fit on a track
+               Transform trans(translate(vec3(0.0f, dimensions.y1(), 0.0)) * scale(temp_s));
+
+               // Draw the "neck" graph (beat lines)
+               drawBeats(time);
+
+               // Arrows on cursor
+               {
+                       UseShader us(getShader("dancenote"));
+                       us()["clock"].set(float(time));
+                       us()["noteType"].set(0);
+                       us()["scale"].set(getScale());
+                       for (unsigned arrow_i = 0; arrow_i < m_pads; ++arrow_i) {
+                               float l = m_pressed_anim[arrow_i].get();
+                               us()["hitAnim"].set(l);
+                               us()["position"].set(panel2x(arrow_i), time2y(0.0));
+                               drawArrow(arrow_i, m_arrows_cursor);
+                       }
+               }
+
+               // Draw the notes
+               if (time == time) { // Check that time is not NaN
+                       for (auto& n: m_notes) {
+                               if (n.note.end - time < past) continue;
+                               if (n.note.begin - time > future) continue;
+                               drawNote(n, time); // Let's just do all the calculating in the sub, instead of passing them as a long list
+                       }
+               }
+       }
+       drawInfo(time, dimensions); // Go draw some texts and other interface stuff
+}
+
+void DanceGraph::drawBeats(double time) {
+       UseTexture tex(m_beat);
+       glutil::VertexArray va;
+       float texCoord = 0.0f;
+       float tBeg = 0.0f, tEnd;
+       float w = 0.5 * m_pads * getScale();
+       for (auto it = m_song.beats.begin(); it != m_song.beats.end() && tBeg < future; ++it, texCoord += texCoordStep, tBeg = tEnd) {
+               tEnd = *it - time;
+               //if (tEnd < past) continue;
+               /*if (tEnd > future) {
+                       // Crop the end off
+                       texCoord -= texCoordStep * (tEnd - future) / (tEnd - tBeg);
+                       tEnd = future;
+               }*/
+               glmath::vec4 c(1.0f, 1.0f, 1.0f, time2a(tEnd));
+               va.color(c).normal(0.0f, 1.0f, 0.0f).texCoord(0.0f, texCoord).vertex(-w, time2y(tEnd));
+               va.color(c).normal(0.0f, 1.0f, 0.0f).texCoord(1.0f, texCoord).vertex(w, time2y(tEnd));
+       }
+       va.draw();
+}
+
+/// Draws a single note (or hold)
+void DanceGraph::drawNote(DanceNote& note, double time) {
+       float tBeg = note.note.begin - time;
+       float tEnd = note.note.end - time;
+       int arrow_i = note.note.note;
+       bool mine = note.note.type == Note::MINE;
+       float x = panel2x(arrow_i);
+       float yBeg = time2y(tBeg);
+       float yEnd = time2y(tEnd);
+
+       // Did we hit it?
+       if (note.isHit && (note.releaseTime > 0.0 || std::abs(tEnd) < maxTolerance) && note.hitAnim.getTarget() == 0.0) {
+               if (mine) note.hitAnim.setRate(1.0);
+               note.hitAnim.setTarget(1.0, false);
+       }
+       double glow = note.hitAnim.get();
+
+       {
+               UseShader us(getShader("dancenote"));
+               us()["hitAnim"].set(float(glow));
+               us()["clock"].set(float(time));
+               us()["scale"].set(getScale());
+
+               if (yEnd - yBeg > arrowSize) {
+                       // Draw holds
+                       if (note.isHit && note.releaseTime <= 0) { // The note is being held down
+                               yBeg = std::max(time2y(0.0), yBeg);
+                               yEnd = std::max(time2y(0.0), yEnd);
+                       }
+                       if (note.releaseTime > 0) yBeg = time2y(note.releaseTime - time); // Oh noes, it got released!
+                       us()["noteType"].set(2);
+                       us()["position"].set(x, yBeg);
+                       // Draw begin
+                       drawArrow(arrow_i, m_arrows_hold, 0.0f, 1.0f/3.0f);
+                       if (yEnd - yBeg > 0) {
+                               glActiveTexture(GL_TEXTURE0);
+                               glBindTexture(m_arrows_hold.type(), m_arrows_hold.id());
+                               glutil::VertexArray va;
+                               // Middle
+                               vertexPair(va, arrow_i, arrowSize, 1.0f/3.0f);
+                               float l = (yEnd - yBeg) / getScale();
+                               float yMid = std::max(l-arrowSize, arrowSize);
+                               vertexPair(va, arrow_i, yMid, 2.0f/3.0f);
+                               // End
+                               vertexPair(va, arrow_i, l, 1.0f);
+                               va.draw();
+                       }
+               } else {
+                       // Draw short note
+                       if (mine && note.isHit) yBeg = time2y(0.0);
+                       us()["noteType"].set(mine ? 3 : 1);
+                       us()["position"].set(x, yBeg);
+                       drawArrow((mine ? -1 : arrow_i), (mine ? m_mine : m_arrows));
+               }
+       }
+
+       // Draw a text telling how well we hit
+       double alpha = 1.0 - glow;
+       if (!mine && note.isHit) {
+               std::string text;
+               if (note.releaseTime <= 0.0 && tBeg < tEnd) { // Is being held down and is a hold note
+                       text = "HOLD";
+                       alpha = glow = 1.0;
+               } else if (glow > 0.0) { // Released already, display rank
+                       text = note.score ? getRank(note.error) : "FAIL!";
+               }
+               if (!text.empty()) {
+                       double sc = getScale() * 0.6 * arrowSize * (3.0 + glow);
+                       Transform trans(glmath::translate(glmath::vec3(0.0, 0.0, 0.5 * glow))); // Slightly elevated
+                       ColorTrans c(Color::alpha(std::sqrt(alpha)));
+                       m_popupText->render(text);
+                       m_popupText->dimensions().middle(x).center(time2y(0.0)).stretch(sc, sc/2.0);
+                       m_popupText->draw();
+               }
+       }
+}
+
+/// Draw popups and other info texts
+void DanceGraph::drawInfo(double /*time*/, Dimensions dimensions) {
+       if (!menuOpen()) {
+               // Draw scores
+               m_text.dimensions.screenBottom(-0.35).middle(0.32 * dimensions.w());
+               m_text.draw(boost::lexical_cast<std::string>(unsigned(getScore())));
+               m_text.dimensions.screenBottom(-0.32).middle(0.32 * dimensions.w());
+               m_text.draw(boost::lexical_cast<std::string>(unsigned(m_streak)) + "/"
+                 + boost::lexical_cast<std::string>(unsigned(m_longestStreak)));
+       }
+       drawPopups();
+}
diff --git a/game/dancegraph.hh b/game/dancegraph.hh
new file mode 100644 (file)
index 0000000..fa1d042
--- /dev/null
@@ -0,0 +1,79 @@
+#pragma once
+
+#include <boost/ptr_container/ptr_map.hpp>
+
+#include "instrumentgraph.hh"
+
+class Song;
+
+struct DanceNote {
+       DanceNote(Note note) :
+               note(note), hitAnim(0.0, 5.0), releaseTime(0), error(getNaN()), score(0), isHit(false) {}
+       Note note;
+       AnimValue hitAnim; /// for animating hits
+       double releaseTime; /// tells when a hold was ended
+       double error; /// time difference between hit and correct time (negative = late)
+       int score;
+       bool isHit;
+};
+
+
+typedef std::vector<DanceNote> DanceNotes;
+
+/// handles drawing of notes
+class DanceGraph: public InstrumentGraph {
+  public:
+       /// constructor
+       DanceGraph(Audio& audio, Song const& song, input::DevicePtr dev);
+       /** draws DanceGraph
+        * @param time at which time to draw
+        */
+       void draw(double time);
+       void engine();
+       std::string getTrack() const;
+       std::string getDifficultyString() const;
+       std::string getModeId() const;
+       void changeTrack(int dir = 1);
+       void changeDifficulty(int dir = 1);
+
+  private:
+       // Difficulty & mode selection
+       enum DanceStep { STEP_LEFT, STEP_DOWN, STEP_UP, STEP_RIGHT };
+       void setupJoinMenu();
+       void updateJoinMenu();
+       void setTrack(const std::string& track);
+       void finalizeTrackChange();
+       bool difficulty(DanceDifficulty level, bool check_only = false);
+       DanceDifficulty m_level;
+       std::string m_gamingMode; /// current game mode
+       DanceTracks::const_iterator m_curTrackIt; /// iterator to the currently selected game mode
+
+       // Scoring & drawing
+       void dance(double time, input::Event const& ev);
+       void drawBeats(double time);
+       void drawNote(DanceNote& note, double time);
+       void drawInfo(double time, Dimensions dimensions);
+       void drawArrow(int arrow_i, Texture& tex, float ty1 = 0.0, float ty2 = 1.0);
+
+       // Helpers
+       float panel2x(int i) const { return getScale() * (-(m_pads * 0.5f) + m_arrow_map[i] + 0.5f); } /// Get x for an arrow line
+       float getScale() const { return 1.0f / m_pads * 8.0f; }
+       double getNotesBeginTime() const { return m_notes.front().note.begin; }
+
+       // Note stuff
+       DanceNotes m_notes; /// contains the dancing notes for current game mode and difficulty
+       DanceNotes::iterator m_notesIt; /// the first note that hasn't gone away yet
+       DanceNotes::iterator m_activeNotes[max_panels]; /// hold notes that are currently pressed down
+
+       // Textures
+       Texture m_beat;
+       Texture m_arrows;
+       Texture m_arrows_cursor;
+       Texture m_arrows_hold;
+       Texture m_mine;
+
+       // Misc
+       int m_arrow_map[max_panels]; /// game mode dependant mapping of arrows' ordering at cursor
+       bool m_insideStop;
+};
+
diff --git a/game/database.cc b/game/database.cc
new file mode 100644 (file)
index 0000000..7e7abbb
--- /dev/null
@@ -0,0 +1,117 @@
+#include "database.hh"
+
+#include "i18n.hh"
+#include <boost/filesystem.hpp>
+#include <libxml++/libxml++.h>
+#include <iostream>
+
+Database::Database(fs::path const& filename): m_filename(filename) {
+       load();
+}
+
+Database::~Database() {
+       save();
+}
+
+void Database::load() {
+       if (!exists(m_filename)) return;
+       try {
+               xmlpp::DomParser domParser(m_filename.string());
+               xmlpp::Node* nodeRoot = domParser.get_document()->get_root_node();
+               m_players.load(nodeRoot->find("/performous/players/player"));
+               m_songs.load(nodeRoot->find("/performous/songs/song"));
+               m_hiscores.load(nodeRoot->find("/performous/hiscores/hiscore"));
+               std::clog << "database/info: Loaded " << m_players.size() << " players, " << m_songs.size() << " songs and " << m_hiscores.size() << " hiscores from " << m_filename.string() << std::endl;
+       } catch (std::exception& e) {
+               std::clog << "database/error: Error loading " + m_filename.string() + ": " + e.what() << std::endl;
+       }
+}
+
+void Database::save() {
+       try {
+               create_directories(m_filename.parent_path());
+               fs::path tmp = m_filename.string() + ".tmp";
+               {
+                       xmlpp::Document doc;
+                       xmlpp::Node* nodeRoot = doc.create_root_node("performous");
+                       m_players.save(nodeRoot->add_child("players"));
+                       m_songs.save(nodeRoot->add_child("songs"));
+                       m_hiscores.save(nodeRoot->add_child("hiscores"));
+                       doc.write_to_file_formatted(tmp.string(), "UTF-8");
+               }
+               rename(tmp, m_filename);
+               std::clog << "database/info: Saved " << m_players.size() << " players, " << m_songs.size() << " songs and " << m_hiscores.size() << " hiscores to " << m_filename.string() << std::endl;
+       } catch (std::exception const& e) {
+               std::clog << "database/error: Could not save " + m_filename.string() + ": " + e.what() << std::endl;
+               return;
+       }
+}
+
+void Database::addPlayer(std::string const& name, std::string const& picture, int id) {
+       m_players.addPlayer(name, picture, id);
+}
+
+void Database::addSong(boost::shared_ptr<Song> s) {
+       m_songs.addSong(s);
+}
+
+void Database::addHiscore(boost::shared_ptr<Song> s) {
+       int playerid = m_players.lookup(m_players.current().name);
+       int score = scores.front().score;
+       std::string track = scores.front().track;
+       int songid = m_songs.lookup(s);
+
+       m_hiscores.addHiscore(score, playerid, songid, track);
+       std::clog << "database/info: Added new hiscore " << score << " points on track " << track << " of songid " << songid << std::endl;
+}
+
+bool Database::reachedHiscore(boost::shared_ptr<Song> s) const {
+       int score = scores.front().score;
+       std::string track = scores.front().track;
+       int songid = m_songs.lookup(s);
+
+       return m_hiscores.reachedHiscore(score, songid, track);
+}
+
+void Database::queryOverallHiscore(std::ostream & os, std::string const& track) const {
+       std::vector<HiscoreItem> hi = m_hiscores.queryHiscore (10, -1, -1, track);
+       for (size_t i=0; i<hi.size(); ++i) {
+               os << i+1 << ".\t"
+                  << m_players.lookup(hi[i].playerid) << "\t"
+                  << m_songs.lookup(hi[i].songid) << "\t"
+               // << hi[i].track << "\t"
+                  << hi[i].score << "\n";
+       }
+}
+
+void Database::queryPerSongHiscore(std::ostream & os, boost::shared_ptr<Song> s, std::string const& track) const {
+       int songid = m_songs.lookup(s);
+       if (songid == -1) return;  // Song not included in database (yet)
+       // Reorder hiscores by track / score
+       std::map<std::string, std::multiset<HiscoreItem>> scoresByTrack;
+       for (HiscoreItem const& hi: m_hiscores.queryHiscore(-1, -1, songid, track)) scoresByTrack[hi.track].insert(hi);
+       for (auto const& hiv: scoresByTrack) {
+               os << hiv.first << ":\n";
+               for (auto const& hi: hiv.second) {
+                       os << "\t" << hi.score << "\t" << m_players.lookup(hi.playerid) << "\n";
+               }
+               os << "\n";
+       }
+}
+
+void Database::queryPerPlayerHiscore(std::ostream & os, std::string const& track) const {
+       int playerid = m_players.lookup(m_players.current().name);
+       std::vector<HiscoreItem> hi = m_hiscores.queryHiscore(3, playerid, -1, track);
+       for (size_t i=0; i<hi.size(); ++i) {
+               os << i+1 << ".\t"
+                  << m_songs.lookup(hi[i].songid) << "\t"
+                  << hi[i].score << "\t"
+                  << "(" << hi[i].track << ")\n";
+       }
+}
+
+bool Database::hasHiscore(Song& s) const {
+       int songid = m_songs.lookup(s);
+       return m_hiscores.hasHiscore(songid);
+}
+
diff --git a/game/database.hh b/game/database.hh
new file mode 100644 (file)
index 0000000..cac6e17
--- /dev/null
@@ -0,0 +1,107 @@
+#pragma once
+
+#include "color.hh"
+#include "controllers.hh"
+#include "fs.hh"
+#include "hiscore.hh"
+#include "players.hh"
+#include "songitems.hh"
+#include <string>
+#include <ostream>
+
+struct ScoreItem {
+       int score;
+       input::DevType type;
+       std::string track;  ///< includes difficulty
+       std::string track_simple; ///< no difficulty
+       Color color;
+       bool operator<(ScoreItem const& other) const { return score < other.score; }
+};
+
+/**Access to a database for performous which holds
+  Player-, Hiscore-, Song-, Track- and (in future)
+  Partydata.
+
+  This is a facade for Players, Hiscore and SongItems.
+
+  Will be initialized at the very beginning of
+  the program.
+
+  The current lists (Players and scores) are used
+  to pass the information which players have won
+  to the ScoreScreen and then to the players window.
+ */
+class Database {
+public:
+       /**Will try to load the database.
+         If it does not succeed the error will be ignored.
+         Only some information will be printed on stderr.
+         */
+       Database(fs::path const& filename);
+       /**Will try to save the database.
+         This will even be done if the loading failed.
+         It tries to create the directory above the file.
+         */
+       ~Database();
+
+       /**Loads the whole database from xml.
+         @exception bad_cast may be thrown if xml element is not of correct type
+         @exception xmlpp exceptions may be thrown on any parse errors
+         @exception PlayersException if some conditions of players fail (e.g. no id)
+         @exception HiscoreException if some hiscore conditions fail (e.g. score too high)
+         @exception SongItemsExceptions if some songs conditions fail (e.g. no id)
+         @post filled database
+         */
+       void load();
+       /**Saves the whole database to xml.
+         Will write out everything to the file given in the constructor, @see file()
+       */
+       void save();
+
+       friend class ScreenHiscore;
+       friend class ScreenPlayers;
+       friend class ScreenSing;
+       friend class ScoreWindow;
+       friend class LayoutSinger;
+       friend class NoteGraph;
+       friend class Engine;
+private: // will be bypassed by above friend declaration
+       typedef std::list<Player> cur_players_t;
+       typedef std::list<ScoreItem> cur_scores_t;
+
+       //This fields are misused as additional parameters
+       cur_players_t cur;
+       cur_scores_t scores;
+
+public: // methods for database management
+
+       /**A facade for Players::addPlayer.*/
+       void addPlayer(std::string const& name, std::string const& picture = "", int id = -1);
+       /**A facade for SongItems::addSong.*/
+       void addSong(boost::shared_ptr<Song> s);
+       /**A facade for Hiscore::addHiscore.
+        The ids will be looked up first by using the songs and current players data.
+        */
+       void addHiscore(boost::shared_ptr<Song> s);
+
+public: // methods for database queries
+       /**A facade for Hiscore::reachedHiscore.
+         Queries if the current player with current score has reached a new hiscore
+         for the song s.
+        */
+       bool reachedHiscore(boost::shared_ptr<Song> s) const;
+
+       void queryOverallHiscore(std::ostream & os, std::string const& track = std::string()) const;
+       void queryPerSongHiscore(std::ostream & os, boost::shared_ptr<Song> s, std::string const& track = std::string()) const;
+       void queryPerPlayerHiscore(std::ostream & os, std::string const& track = std::string()) const;
+
+       bool hasHiscore(Song& s) const;
+       bool noPlayers() const;
+
+private:
+       fs::path m_filename;
+
+       Players m_players;
+       Hiscore m_hiscores;
+       SongItems m_songs;
+};
diff --git a/game/dialog.hh b/game/dialog.hh
new file mode 100644 (file)
index 0000000..7e58046
--- /dev/null
@@ -0,0 +1,31 @@
+#pragma once
+
+#include "configuration.hh"
+#include "fs.hh"
+#include "opengl_text.hh"
+#include "surface.hh"
+
+/// class for printing dialogues
+class Dialog {
+  public:
+       /// constructor
+       Dialog(std::string const& text):
+         m_text(text),
+         m_dialog(findFile("warning.svg")),
+         m_svgText(findFile("dialog_txt.svg"), config["graphic/text_lod"].f())
+       {
+               m_dialog.dimensions.fixedWidth(0.8);
+       }
+       /// draws dialogue
+       void draw() {
+               using namespace glmath;
+               Transform(translate(vec3(0.0f, 0.0f, 0.1f)));  // Raise a bit in 3D
+               m_dialog.draw();
+               m_svgText.draw(m_text);
+       }
+
+  private:
+       std::string m_text;
+       Surface m_dialog;
+       SvgTxtTheme m_svgText;
+};
diff --git a/game/engine.cc b/game/engine.cc
new file mode 100644 (file)
index 0000000..9f0f7ef
--- /dev/null
@@ -0,0 +1,41 @@
+#include "engine.hh"
+
+#include "audio.hh"
+#include "song.hh"
+#include "database.hh"
+#include "configuration.hh"
+#include <boost/bind.hpp>
+#include <iostream>
+#include <list>
+
+const double Engine::TIMESTEP = 0.01;
+
+Engine::Engine(Audio& audio, VocalTrackPtrs vocals, Database& database):
+  m_audio(audio), m_time(), m_quit(), m_database(database)
+{
+       boost::ptr_vector<Analyzer>& analyzers = m_audio.analyzers();
+       if (analyzers.size() != vocals.size()) throw std::logic_error("Engine requires the same number of vocal tracks as there are analyzers.");
+       // Clear old player information
+       m_database.cur.clear();
+       m_database.scores.clear();
+       unsigned i = 0;
+       for (Analyzer& a: analyzers) {
+               // Calculate the space required for pitch frames
+               size_t frames = vocals[i]->endTime / Engine::TIMESTEP;
+               m_database.cur.push_back(Player(*vocals[i], a, frames));
+               ++i;
+       }
+       m_thread.reset(new boost::thread(boost::ref(*this)));
+}
+
+void Engine::operator()() {
+       while (!m_quit) {
+               std::for_each(m_database.cur.begin(), m_database.cur.end(), boost::bind(&Player::prepare, _1));
+               double t = m_audio.getPosition() - config["audio/round-trip"].f();
+               double timeLeft = m_time - t;
+               if (timeLeft != timeLeft || timeLeft > 1.0) timeLeft = 1.0;  // FIXME: Workaround for NaN values and other weirdness (should fix the weirdness instead)
+               if (timeLeft > 0.0) { boost::thread::sleep(now() + std::min(TIMESTEP, timeLeft)); continue; }
+               std::for_each(m_database.cur.begin(), m_database.cur.end(), boost::bind(&Player::update, _1));
+               m_time += TIMESTEP;
+       }
+}
diff --git a/game/engine.hh b/game/engine.hh
new file mode 100644 (file)
index 0000000..3c0c046
--- /dev/null
@@ -0,0 +1,28 @@
+#pragma once
+
+#include <boost/scoped_ptr.hpp>
+#include <boost/thread/thread.hpp>
+
+class Audio;
+class Database;
+class VocalTrack;
+
+/// performous engine
+class Engine {
+       Audio& m_audio;
+       double m_time;
+       volatile bool m_quit;
+       Database& m_database;
+       boost::scoped_ptr<boost::thread> m_thread;
+
+  public:
+       typedef std::vector<VocalTrack*> VocalTrackPtrs;
+       static const double TIMESTEP;  ///< The duration of one engine time step in seconds
+       /// Construct an engine thread with vocal tracks and players specified by parameters
+       Engine(Audio& audio, VocalTrackPtrs vocals, Database& database);
+       ~Engine() { kill(); }
+       /// Terminates processing
+       void kill() { m_quit = true; m_thread->join(); }
+       /** Used internally for boost::thread. Do not call this yourself. (boost::thread requires this to be public). **/
+       void operator()();
+};
diff --git a/game/execname.cc b/game/execname.cc
new file mode 100644 (file)
index 0000000..e5ac89f
--- /dev/null
@@ -0,0 +1,56 @@
+#include "execname.hh"
+
+#if defined(_WIN32)
+#include <windows.h>
+fs::path execname() {
+       char buf[1024];
+       DWORD ret = GetModuleFileName(NULL, buf, sizeof(buf));
+       if (ret == 0 || ret == sizeof(buf)) return std::string();
+       return buf;
+}
+#elif defined(__APPLE__)
+#include <mach-o/dyld.h>
+fs::path execname() {
+       char buf[1024];
+       uint32_t size = sizeof(buf);
+       int ret = _NSGetExecutablePath(buf, &size);
+       if (ret != 0) return fs::path();
+       return buf;
+}
+#elif defined(sun) || defined(__sun)
+#include <stdlib.h>
+fs::path execname() {
+       return getexecname();
+}
+#elif defined(__FreeBSD__)
+#include <sys/sysctl.h>
+fs::path execname() {
+       int mib[4];
+       mib[0] = CTL_KERN;
+       mib[1] = KERN_PROC;
+       mib[2] = KERN_PROC_PATHNAME;
+       mib[3] = -1;
+       char buf[1024];
+       size_t maxchars = sizeof(buf) - 1;
+       size_t size = maxchars;
+       sysctl(mib, 4, buf, &size, NULL, 0);
+       if (size == 0 || size >= maxchars) return fs::path();
+       buf[size] = '\0';
+       return buf;
+}
+#elif defined(__linux__)
+#include <unistd.h>
+fs::path execname() {
+       char buf[1024];
+       ssize_t maxchars = sizeof(buf) - 1;
+       ssize_t size = readlink("/proc/self/exe", buf, sizeof(buf));
+       if (size <= 0 || size >= maxchars) return fs::path();
+       buf[size] = '\0';
+       return buf;
+}
+#else
+fs::path execname() {
+       return fs::path();
+}
+#endif
+
diff --git a/game/execname.hh b/game/execname.hh
new file mode 100644 (file)
index 0000000..df0618f
--- /dev/null
@@ -0,0 +1,8 @@
+#pragma once
+
+#include "fs.hh"
+
+/// Get the current executable name with path. Returns empty path if the name
+/// cannot be found. May return absolute or relative paths.
+fs::path execname();
+
diff --git a/game/fbo.hh b/game/fbo.hh
new file mode 100644 (file)
index 0000000..856695a
--- /dev/null
@@ -0,0 +1,55 @@
+#pragma once
+
+#include <boost/noncopyable.hpp>
+#include "surface.hh"
+#include "video_driver.hh"
+
+/// Frame Buffer Object class
+class FBO: boost::noncopyable {
+  public:
+       /// Generate the FBO and attach a fresh texture to it
+       FBO(unsigned w, unsigned h) {
+               {
+                       UseTexture tex(m_texture);
+                       glTexImage2D(GL_TEXTURE_RECTANGLE, 0, GL_RGBA, w, h, 0, GL_RGBA, GL_FLOAT, NULL);
+               }
+               {
+                       UseTexture tex(m_depth);
+                       glTexImage2D(GL_TEXTURE_RECTANGLE, 0, GL_DEPTH_COMPONENT, w, h, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, NULL);
+               }
+               // Create FBO
+               glGenFramebuffersEXT(1, &m_fbo);
+               // Bind texture as COLOR_ATTACHMENT0
+               bind();
+               glFramebufferTexture2DEXT(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_RECTANGLE, m_texture.id(), 0);
+               glFramebufferTexture2DEXT(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_RECTANGLE, m_depth.id(), 0);
+               unbind();
+       }
+       /// Handle clean-up
+       ~FBO() {
+               if (m_fbo) glDeleteFramebuffersEXT(1, &m_fbo);
+       }
+       /// Returns a reference to the attached texture
+       OpenGLTexture<GL_TEXTURE_RECTANGLE>& getTexture() {
+               return m_texture;
+       }
+       /// Bind the FBO into use
+       void bind() {
+               glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_fbo);
+       }
+       /// Unbind any FBO
+       static void unbind() {
+               glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
+       }
+
+  private:
+       GLuint m_fbo;
+       OpenGLTexture<GL_TEXTURE_RECTANGLE> m_texture;
+       OpenGLTexture<GL_TEXTURE_RECTANGLE> m_depth;
+};
+
+/// RAII FBO binder
+struct UseFBO {
+       UseFBO(FBO& fbo) { fbo.bind(); }
+       ~UseFBO() { FBO::unbind(); }
+};
diff --git a/game/ffmpeg.cc b/game/ffmpeg.cc
new file mode 100644 (file)
index 0000000..7c106e3
--- /dev/null
@@ -0,0 +1,240 @@
+#include "ffmpeg.hh"
+
+#include "config.hh"
+#include "util.hh"
+#include "xtime.hh"
+#include <boost/smart_ptr/shared_ptr.hpp>
+#include <iostream>
+#include <sstream>
+#include <stdexcept>
+
+extern "C" {
+#include AVCODEC_INCLUDE
+#include AVFORMAT_INCLUDE
+#include SWSCALE_INCLUDE
+#include AVRESAMPLE_INCLUDE
+#include AVUTIL_INCLUDE
+#include AVUTIL_OPT_INCLUDE
+#include AVUTIL_MATH_INCLUDE
+}
+
+#if (LIBAVCODEC_VERSION_INT) < (AV_VERSION_INT(52,94,3))
+#      define AV_SAMPLE_FMT_S16 SAMPLE_FMT_S16
+#endif
+
+#define AUDIO_CHANNELS 2
+
+/*static*/ boost::mutex FFmpeg::s_avcodec_mutex;
+
+namespace {
+       std::string ffversion(unsigned ver) {
+               unsigned major = ver >> 16;
+               unsigned minor = (ver >> 8) & 0xFF;
+               unsigned micro = ver & 0xFF;
+               std::ostringstream oss;
+               oss << major << "." << minor << "." << micro << (micro >= 100 ? "(ff)" : "(lav)");
+               return oss.str();
+       }
+}
+
+
+FFmpeg::FFmpeg(fs::path const& _filename, unsigned int rate):
+  width(), height(), m_filename(_filename), m_rate(rate), m_quit(),
+  m_seekTarget(getNaN()), m_position(), m_duration(), m_streamId(-1),
+  m_mediaType(rate ? AVMEDIA_TYPE_AUDIO : AVMEDIA_TYPE_VIDEO),
+  m_formatContext(), m_codecContext(), m_resampleContext(), m_swsContext(),
+  m_thread(new boost::thread(boost::ref(*this)))
+{
+       static bool versionChecked = false;
+       if (!versionChecked) {
+               versionChecked = true;
+               bool matches =
+                 LIBAVUTIL_VERSION_INT == avutil_version() &&
+                 LIBAVCODEC_VERSION_INT == avcodec_version() &&
+                 LIBAVFORMAT_VERSION_INT == avformat_version() &&
+                 LIBSWSCALE_VERSION_INT == swscale_version();
+               if (matches) {
+                       std::clog << "ffmpeg/info: "
+                         " avutil:" + ffversion(LIBAVUTIL_VERSION_INT) +
+                         " avcodec:" + ffversion(LIBAVCODEC_VERSION_INT) +
+                         " avformat:" + ffversion(LIBAVFORMAT_VERSION_INT) +
+                         " avresample:" + ffversion(LIBAVRESAMPLE_VERSION_INT) +
+                         " swscale:" + ffversion(LIBSWSCALE_VERSION_INT)
+                         << std::endl;
+               } else {
+                       std::clog << "ffmpeg/error: header/lib version mismatch:"
+                         " avutil:" + ffversion(LIBAVUTIL_VERSION_INT) + "/" + ffversion(avutil_version()) +
+                         " avcodec:" + ffversion(LIBAVCODEC_VERSION_INT) + "/" + ffversion(avcodec_version()) +
+                         " avformat:" + ffversion(LIBAVFORMAT_VERSION_INT) + "/" + ffversion(avformat_version()) +
+                         " avresample:" + ffversion(LIBAVRESAMPLE_VERSION_INT) + "/" + ffversion(avresample_version()) +
+                         " swscale:" + ffversion(LIBSWSCALE_VERSION_INT) + "/" + ffversion(swscale_version())
+                         << std::endl;
+               }
+       }
+}
+
+FFmpeg::~FFmpeg() {
+       m_quit = true;
+       videoQueue.reset();
+       audioQueue.quit();
+       m_thread->join();
+}
+
+void FFmpeg::open() {
+       boost::mutex::scoped_lock l(s_avcodec_mutex);
+       av_register_all();
+       av_log_set_level(AV_LOG_ERROR);
+       if (avformat_open_input(&m_formatContext, m_filename.string().c_str(), nullptr, nullptr)) throw std::runtime_error("Cannot open input file");
+       if (avformat_find_stream_info(m_formatContext, nullptr) < 0) throw std::runtime_error("Cannot find stream information");
+       m_formatContext->flags |= AVFMT_FLAG_GENPTS;
+       // Find a track and open the codec
+       AVCodec* codec = nullptr;
+       m_streamId = av_find_best_stream(m_formatContext, (AVMediaType)m_mediaType, -1, -1, &codec, 0);
+       if (m_streamId < 0) throw std::runtime_error("No suitable track found");
+
+       AVCodecContext* cc = m_formatContext->streams[m_streamId]->codec;
+       if (avcodec_open2(cc, codec, nullptr) < 0) throw std::runtime_error("Cannot open codec");
+       cc->workaround_bugs = FF_BUG_AUTODETECT;
+       m_codecContext = cc;
+
+       switch (m_mediaType) {
+       case AVMEDIA_TYPE_AUDIO:
+               m_resampleContext = avresample_alloc_context();
+               av_opt_set_int(m_resampleContext, "in_channel_layout", m_codecContext->channel_layout ? m_codecContext->channel_layout : av_get_default_channel_layout(m_codecContext->channels), 0);
+               av_opt_set_int(m_resampleContext, "out_channel_layout", av_get_default_channel_layout(AUDIO_CHANNELS), 0);
+               av_opt_set_int(m_resampleContext, "in_sample_rate", m_codecContext->sample_rate, 0);
+               av_opt_set_int(m_resampleContext, "out_sample_rate", m_rate, 0);
+               av_opt_set_int(m_resampleContext, "in_sample_fmt", m_codecContext->sample_fmt, 0);
+               av_opt_set_int(m_resampleContext, "out_sample_fmt", AV_SAMPLE_FMT_S16, 0);
+               avresample_open(m_resampleContext);
+               if (!m_resampleContext) throw std::runtime_error("Cannot create resampling context");
+               audioQueue.setSamplesPerSecond(AUDIO_CHANNELS * m_rate);
+               break;
+       case AVMEDIA_TYPE_VIDEO:
+               // Setup software scaling context for YUV to RGB conversion
+               width = cc->width;
+               height = cc->height;
+               m_swsContext = sws_getContext(
+                 cc->width, cc->height, cc->pix_fmt,
+                 width, height, PIX_FMT_RGB24,
+                 SWS_POINT, nullptr, nullptr, nullptr);
+               break;
+       default:  // Should never be reached but avoids compile warnings
+               abort();
+       }
+}
+
+void FFmpeg::operator()() {
+       try { open(); } catch (std::exception const& e) { std::clog << "ffmpeg/error: Failed to open " << m_filename << ": " << e.what() << std::endl; m_quit = true; return; }
+       m_duration = m_formatContext->duration / double(AV_TIME_BASE);
+       audioQueue.setDuration(m_duration);
+       int errors = 0;
+       while (!m_quit) {
+               try {
+                       if (audioQueue.wantSeek()) m_seekTarget = 0.0;
+                       if (m_seekTarget == m_seekTarget) seek_internal();
+                       decodePacket();
+                       errors = 0;
+               } catch (eof_error&) {
+                       videoQueue.push(new Bitmap()); // EOF marker
+                       boost::thread::sleep(now() + 0.1);
+               } catch (std::exception& e) {
+                       std::clog << "ffmpeg/error: " << m_filename << ": " << e.what() << std::endl;
+                       if (++errors > 2) { std::clog << "ffmpeg/error: FFMPEG terminating due to multiple errors" << std::endl; m_quit = true; }
+               }
+       }
+       audioQueue.reset();
+       videoQueue.reset();
+       // TODO: use RAII for freeing resources (to prevent memory leaks)
+       boost::mutex::scoped_lock l(s_avcodec_mutex); // avcodec_close is not thread-safe
+       if (m_resampleContext) avresample_close(m_resampleContext);
+       if (m_codecContext) avcodec_close(m_codecContext);
+#if LIBAVFORMAT_VERSION_INT >= AV_VERSION_INT(53, 17, 0)
+       if (m_formatContext) avformat_close_input(&m_formatContext);
+#else
+       if (m_formatContext) av_close_input_file(m_formatContext);
+#endif
+}
+
+void FFmpeg::seek(double time, bool wait) {
+       m_seekTarget = time;
+       videoQueue.reset(); audioQueue.reset(); // Empty these to unblock the internals in case buffers were full
+       if (wait) while (!m_quit && m_seekTarget == m_seekTarget) boost::thread::sleep(now() + 0.01);
+}
+
+void FFmpeg::seek_internal() {
+       videoQueue.reset();
+       audioQueue.reset();
+       int flags = 0;
+       if (m_seekTarget < m_position) flags |= AVSEEK_FLAG_BACKWARD;
+       av_seek_frame(m_formatContext, -1, m_seekTarget * AV_TIME_BASE, flags);
+       m_seekTarget = getNaN(); // Signal that seeking is done
+}
+
+void FFmpeg::decodePacket() {
+       struct ReadFramePacket: public AVPacket {
+               AVFormatContext* m_s;
+               ReadFramePacket(AVFormatContext* s): m_s(s) {
+                       if (av_read_frame(s, this) < 0) throw FFmpeg::eof_error();
+               }
+               ~ReadFramePacket() { av_free_packet(this); }
+       };
+
+       // Read an AVPacket and decode it into AVFrames
+       ReadFramePacket packet(m_formatContext);
+       int packetSize = packet.size;
+       while (packetSize) {
+               if (packetSize < 0) throw std::logic_error("negative packet size?!");
+               if (m_quit || m_seekTarget == m_seekTarget) return;
+               if (packet.stream_index != m_streamId) return;
+               boost::shared_ptr<AVFrame> frame(avcodec_alloc_frame(), &av_free);
+               int frameFinished = 0;
+               int decodeSize = (m_mediaType == AVMEDIA_TYPE_VIDEO ?
+                 avcodec_decode_video2(m_codecContext, frame.get(), &frameFinished, &packet) :
+                 avcodec_decode_audio4(m_codecContext, frame.get(), &frameFinished, &packet));
+               if (decodeSize < 0) return; // Packet didn't produce any output (could be waiting for B frames or something)
+               packetSize -= decodeSize; // Move forward within the packet
+               if (!frameFinished) continue;
+               // Update current position if timecode is available
+               if (int64_t(frame->pkt_pts) != int64_t(AV_NOPTS_VALUE)) {
+                       m_position = double(frame->pkt_pts) * av_q2d(m_formatContext->streams[m_streamId]->time_base)
+                         - double(m_formatContext->start_time) / AV_TIME_BASE;
+               }
+               if (m_mediaType == AVMEDIA_TYPE_VIDEO) processVideo(frame.get()); else processAudio(frame.get());
+       }
+}
+
+void FFmpeg::processVideo(AVFrame* frame) {
+       // Convert into RGB and scale the data
+       int w = (m_codecContext->width+15)&~15;
+       int h = m_codecContext->height;
+       auto bitmap = new Bitmap();
+       bitmap->timestamp = m_position;
+       bitmap->fmt = pix::RGB;
+       bitmap->resize(w, h);
+       {
+               uint8_t* data = bitmap->data();
+               int linesize = w * 3;
+               sws_scale(m_swsContext, frame->data, frame->linesize, 0, h, &data, &linesize);
+       }
+       videoQueue.push(bitmap);  // Takes ownership and may block until there is space
+}
+
+void FFmpeg::processAudio(AVFrame* frame) {
+       // resample to output
+               int16_t *output;
+               int out_linesize;
+               int out_samples = avresample_available(m_resampleContext) +
+                       av_rescale_rnd(avresample_get_delay(m_resampleContext) +
+                                               frame->nb_samples, frame->sample_rate, m_rate, AV_ROUND_UP);
+               av_samples_alloc((uint8_t**)&output, &out_linesize, AUDIO_CHANNELS, out_samples,
+                                        AV_SAMPLE_FMT_S16, 0);
+               out_samples = avresample_convert(m_resampleContext, (uint8_t**)&output, 0, out_samples,
+                                                                        &frame->data[0], 0, frame->nb_samples);
+               // The output is now an interleaved array of 16-bit samples
+               std::vector<int16_t> m_output(output, output+out_samples*AUDIO_CHANNELS);
+               audioQueue.push(m_output,m_position);
+               av_freep(&output);
+               m_position += double(out_samples)/m_rate;
+}
+
diff --git a/game/ffmpeg.hh b/game/ffmpeg.hh
new file mode 100644 (file)
index 0000000..708123d
--- /dev/null
@@ -0,0 +1,212 @@
+#pragma once
+
+#include "surface.hh"
+#include "util.hh"
+#include "libda/sample.hpp"
+#include <boost/circular_buffer.hpp>
+#include <boost/ptr_container/ptr_deque.hpp>
+#include <boost/scoped_ptr.hpp>
+#include <boost/thread/condition.hpp>
+#include <boost/thread/mutex.hpp>
+#include <boost/thread/recursive_mutex.hpp>
+#include <boost/thread/thread.hpp>
+#include <vector>
+#include <iostream>
+
+using boost::uint8_t;
+using boost::int16_t;
+using boost::int64_t;
+
+/// single audio frame
+struct AudioFrame {
+       /// timestamp of audio frame
+       double timestamp;
+       /// audio data
+       std::vector<int16_t> data;
+       /// constructor
+       template <typename InIt> AudioFrame(double ts, InIt begin, InIt end): timestamp(ts), data(begin, end) {}
+       AudioFrame(): timestamp(getInf()) {} // EOF marker
+};
+
+/// Video queue
+class VideoFifo {
+  public:
+       VideoFifo(): m_timestamp(), m_eof() {}
+       /// trys to pop a video frame from queue
+       bool tryPop(Bitmap& f) {
+               boost::mutex::scoped_lock l(m_mutex);
+               if (m_queue.empty()) return false; // Nothing to deliver
+               if (m_queue.begin()->buf.empty()) { m_eof = true; return false; }
+               f.swap(*m_queue.begin());
+               m_queue.pop_front();
+               m_cond.notify_all();
+               m_timestamp = f.timestamp;
+               return true;
+       }
+       /// Add frame to queue
+       void push(Bitmap* f) {
+               boost::mutex::scoped_lock l(m_mutex);
+               while (m_queue.size() > m_max) m_cond.wait(l);
+               if (m_queue.empty()) m_timestamp = f->timestamp;
+               m_queue.push_back(f);
+       }
+       /// Clear and unlock the queue
+       void reset() {
+               boost::mutex::scoped_lock l(m_mutex);
+               m_queue.clear();
+               m_cond.notify_all();
+               m_eof = false;
+       }
+       /// Returns the current position (seconds)
+       double position() const { return m_timestamp; }
+       /// Tests if EOF has already been reached
+       double eof() const { return m_eof; }
+
+  private:
+       boost::ptr_deque<Bitmap> m_queue;
+       mutable boost::mutex m_mutex;
+       boost::condition m_cond;
+       double m_timestamp;
+       bool m_eof;
+       static const unsigned m_max = 20;
+};
+
+class AudioBuffer {
+       typedef boost::recursive_mutex mutex;
+  public:
+       AudioBuffer(size_t size = 1000000): m_data(size), m_pos(), m_posReq(), m_sps(), m_duration(getNaN()), m_quit() {}
+       /// Reset from FFMPEG side (seeking to beginning or terminate stream)
+       void reset() {
+               mutex::scoped_lock l(m_mutex);
+               m_data.clear();
+               m_pos = 0;
+               l.unlock();
+               m_cond.notify_one();
+       }
+       void quit() {
+               mutex::scoped_lock l(m_mutex);
+               m_quit = true;
+               l.unlock();
+               m_cond.notify_one();
+       }
+       /// set samples per second
+       void setSamplesPerSecond(unsigned sps) { m_sps = sps; }
+       /// get samples per second
+       unsigned getSamplesPerSecond() const { return m_sps; }
+       void push(std::vector<int16_t> const& data, double timestamp) {
+                       mutex::scoped_lock l(m_mutex);
+                       while (!condition()) m_cond.wait(l);
+                       if (m_quit) return;
+                       if (timestamp < 0.0) {
+                               std::clog << "ffmpeg/warning: Negative audio timestamp " << timestamp << " seconds, frame ignored." << std::endl;
+                               return;
+                       }
+                       // Insert silence at the beginning if the stream starts later than 0.0
+                       if (m_pos == 0 && timestamp > 0.0) {
+                               m_pos = timestamp * m_sps;
+                               m_data.resize(m_pos, 0);
+                       }
+                       m_data.insert(m_data.end(), data.begin(), data.end());
+                       m_pos += data.size();
+               }
+       bool prepare(int64_t pos) {
+               mutex::scoped_try_lock l(m_mutex);
+               if (!l.owns_lock()) return false;  // Didn't get lock, give up for now
+               if (eof(pos)) return true;
+               if (pos < 0) pos = 0;
+               m_posReq = pos;
+               wakeups();
+               // Has enough been prebuffered already and is the requested position still within buffer
+               return m_pos > m_posReq + m_data.capacity() / 16 && m_pos <= m_posReq + m_data.size();
+       }
+       bool operator()(float* begin, float* end, int64_t pos, float volume = 1.0f) {
+               mutex::scoped_lock l(m_mutex);
+               size_t idx = pos + m_data.size() - m_pos;
+               size_t samples = end - begin;
+               for (size_t s = 0; s < samples; ++s, ++idx) {
+                       if (idx < m_data.size()) begin[s] += volume * da::conv_from_s16(m_data[idx]);
+               }
+               m_posReq = std::max<int64_t>(0, pos + samples);
+               wakeups();
+               return !eof(pos);
+       }
+       bool eof(int64_t pos) const { return double(pos) / m_sps >= m_duration; }
+       void setEof() { m_duration = double(m_pos) / m_sps; }
+       double duration() const { return m_duration; }
+       void setDuration(double seconds) { m_duration = seconds; }
+       bool wantSeek() {
+               // Are we already past the requested position? (need to seek backward or back to beginning)
+               return m_posReq > 0 && m_posReq + m_sps * 2 /* seconds tolerance */ + m_data.size() < m_pos;
+       }
+  private:
+       /// Handle waking up of input thread etc. whenever m_posReq is changed.
+       void wakeups() {
+               if (wantSeek()) reset();
+               else if (condition()) m_cond.notify_one();
+       }
+       bool wantMore() { return m_pos < m_posReq + m_data.capacity() / 2; }
+       /// Should the input stop waiting?
+       bool condition() { return m_quit || wantMore() || wantSeek(); }
+       mutable mutex m_mutex;
+       boost::condition m_cond;
+       boost::circular_buffer<int16_t> m_data;
+       size_t m_pos;
+       int64_t m_posReq;
+       unsigned m_sps;
+       double m_duration;
+       bool m_quit;
+};
+
+// ffmpeg forward declarations
+extern "C" {
+  struct AVCodecContext;
+  struct AVFormatContext;
+  struct AVFrame;
+  struct AVAudioResampleContext;
+  struct SwsContext;
+}
+
+/// ffmpeg class
+class FFmpeg {
+  public:
+       /// Decode file; if no rate is specified, decode video, otherwise decode audio.
+       FFmpeg(fs::path const& file, unsigned int rate = 0);
+       ~FFmpeg();
+       void operator()(); ///< Thread runs here, don't call directly
+       unsigned width, ///< width of video
+                height; ///< height of video
+       /// queue for video
+       VideoFifo  videoQueue;
+       /// queue for audio
+       AudioBuffer  audioQueue;
+       /** Seek to the chosen time. Will block until the seek is done, if wait is true. **/
+       void seek(double time, bool wait = true);
+       /// duration
+       double duration() const;
+       bool terminating() const { return m_quit; }
+
+       class eof_error: public std::exception {};
+  private:
+       void seek_internal();
+       void open();
+       void decodePacket();
+       void processVideo(AVFrame* frame);
+       void processAudio(AVFrame* frame);
+       fs::path m_filename;
+       unsigned int m_rate;
+       volatile bool m_quit;
+       volatile double m_seekTarget;
+       double m_position;
+       double m_duration;
+       // libav-specific variables
+       int m_streamId;
+       int m_mediaType;  // enum AVMediaType
+       AVFormatContext* m_formatContext;
+       AVCodecContext* m_codecContext;
+       AVAudioResampleContext* m_resampleContext;
+       SwsContext* m_swsContext;
+       // Make sure the thread starts only after initializing everything else
+       boost::scoped_ptr<boost::thread> m_thread;
+       static boost::mutex s_avcodec_mutex; // Used for avcodec_open/close (which use some static crap and are thus not thread-safe)
+};
+
diff --git a/game/fs.cc b/game/fs.cc
new file mode 100644 (file)
index 0000000..459e538
--- /dev/null
@@ -0,0 +1,275 @@
+#include "fs.hh"
+
+#include "config.hh"
+#include "configuration.hh"
+#include "execname.hh"
+#include <boost/filesystem/fstream.hpp>
+#include <boost/filesystem/operations.hpp>
+#include <cstdlib>
+#include <iostream>
+#include <boost/thread.hpp>
+#include <set>
+#include <sstream>
+#include <algorithm>
+
+#ifdef _WIN32
+#include <windows.h>
+#include <shlobj.h>
+#endif
+
+namespace {
+       /// Test if a path begins with name and if so, remove that element and return true
+       /// Mostly a workaround for fs::path's crippled API that makes this operation difficult
+       bool pathRootHack(fs::path& p, std::string const& name) {
+               if (p.empty() || p.begin()->string() != name) return false;
+               fs::path ret;
+               // Add all but first element
+               for (auto dir = ++p.begin(); dir != p.end(); ++dir)
+                       ret /= *dir;
+               p = ret;
+               return true;
+       }
+
+       const fs::path performous = "performous";
+       const fs::path configSchema = "config/schema.xml";
+
+       struct PathCache {
+               /// Expand a path specifier as a list of actual paths. Expands ~ (home) and DATADIR (Performous search path).
+               Paths pathExpand(fs::path p) {
+                       Paths ret;
+                       if (pathRootHack(p, "~")) ret.push_back(home / p);
+                       else if (pathRootHack(p, "DATADIR")) {
+                               // Add all data paths with p appended to them
+                               for (auto const& path: paths) ret.push_back(path / p);
+                       }
+                       else ret.push_back(p);
+                       return ret;
+               }
+
+               fs::path base, share, locale, sysConf, home, conf, data, cache;
+               Paths paths;
+               // Note: three-phase init:
+               // 1. Default constructor runs in static context (before main) and cannot do much
+               // 2. pathBootstrap is called to find out static system paths (critical for logging and for loading config files)
+               // 3. pathInit is called to process the full search path, using config settings
+               void pathBootstrap() {
+                       if (!base.empty()) return;  // Only bootstrap once
+                       // Base (e.g. /usr/local), share (src or installed data files) and locale (built or installed .mo files)
+                       {
+                               char const* root = getenv("PERFORMOUS_ROOT");
+                               base = fs::absolute(root ? root : execname().parent_path());
+                               do {
+                                       if (base.empty()) throw std::runtime_error("Unable to find Performous data files. Install properly or set environment variable PERFORMOUS_ROOT.");
+                                       for (fs::path const& infix: { fs::path(SHARED_DATA_DIR), fs::path("data"), fs::path() }) {
+                                               if (!fs::exists(base / infix / configSchema)) continue;
+                                               share = base / infix;
+                                               goto found;
+                                       }
+                                       // Use locale .mo files from build folder?
+                                       if (base.filename() == "build" && fs::exists(base / "lang")) {
+                                               locale = base / "lang";
+                                       }
+                                       base = base.parent_path();
+                               } while (true);
+                       found:;
+                               if (locale.empty() && fs::exists(base / LOCALEDIR)) locale = base / LOCALEDIR;
+                       }
+                       // System-wide config files
+                       {
+                       #ifdef _WIN32
+                               sysConf = execname().parent_path() / "config";  // I.e. Program Files/Performous/config or build/config/
+                       #else
+                               sysConf = "/etc/xdg/performous";
+                       #endif
+                       }
+                       // Home
+                       {
+                       #ifdef _WIN32
+                               char const* p = getenv("USERPROFILE");
+                       #else
+                               char const* p = getenv("HOME");
+                       #endif
+                               if (p) home = p;
+                       }
+                       // Config
+                       {
+                       #ifdef _WIN32
+                               ITEMIDLIST* pidl;
+                               HRESULT hRes = SHGetSpecialFolderLocation(nullptr, CSIDL_APPDATA|CSIDL_FLAG_CREATE, &pidl);
+                               if (hRes != NOERROR) throw std::runtime_error("Unable to determine where Application Data is stored");
+                               char p[MAX_PATH];
+                               SHGetPathFromIDList(pidl, p);
+                               conf = p;
+                       #else
+                               char const* p = getenv("XDG_CONFIG_HOME");
+                               conf = (p ? p : home / ".config");
+                       #endif
+                               conf /= performous;
+                       }
+                       // Data
+                       {
+                       #ifdef _WIN32
+                               data = conf;
+                       #else
+                               char const* p = getenv("XDG_DATA_HOME");
+                               data = (p ? p / performous : home / ".local" / SHARED_DATA_DIR);
+                       #endif
+                       }
+                       // Cache
+                       {
+                       #ifdef _WIN32
+                               cache = data / "cache";  // FIXME: Should we use GetTempPath?
+                       #else
+                               char const* p = getenv("XDG_CACHE_HOME");
+                               cache = (p ? p / performous : home / ".cache" / performous);
+                       #endif
+                       }
+                       pathInit();
+               }
+               /// Initialize/reset data dirs (search path).
+               void pathInit() {
+                       bool bootstrapping = paths.empty();  // The first run (during bootstrap)
+                       if (!bootstrapping) {
+                               std::string logmsg = "fs/info: Found system paths:\n";
+                               logmsg += "  base:     " + base.string() + '\n';
+                               logmsg += "  share:    " + share.string() + '\n';
+                               logmsg += "  locale:   " + locale.string() + '\n';
+                               logmsg += "  sysConf:  " + sysConf.string() + '\n';
+                               logmsg += "  home:     " + home.string() + '\n';
+                               logmsg += "  config:   " + conf.string() + '\n';
+                               logmsg += "  data:     " + data.string() + '\n';
+                               logmsg += "  cache:    " + cache.string() + '\n';
+                               std::clog << logmsg << std::flush;
+                       }
+                       // Data dirs
+                       std::string logmsg = "fs/info: Determining data dirs (search path):\n";
+                       {
+                               Paths dirs;
+                               dirs.push_back(data);  // Adding user's data dir
+                               dirs.push_back(share);  // Adding system data dir (relative to performous executable or PERFORMOUS_ROOT)
+                       #ifndef _WIN32
+                               // Adding XDG_DATA_DIRS
+                               {
+                                       char const* xdg_data_dirs = getenv("XDG_DATA_DIRS");
+                                       std::istringstream iss(xdg_data_dirs ? xdg_data_dirs : "/usr/local/share/:/usr/share/");
+                                       for (std::string p; std::getline(iss, p, ':'); dirs.push_back(p / performous)) {}
+                               }
+                       #endif
+                               // Adding paths from config file (during bootstrap config options are not yet available)
+                               if (!bootstrapping) {
+                                       auto const& conf = config["paths/system"].sl();
+                                       for (std::string const& dir: conf) dirs.splice(dirs.end(), pathExpand(dir));
+                               }
+                               // Check if they actually exist and print debug
+                               paths.clear();
+                               std::set<fs::path> used;
+                               for (auto dir: dirs) {
+                                       dir = fs::absolute(dir);
+                                       if (used.find(dir) != used.end()) continue;
+                                       logmsg += "  " + dir.string() + '\n';
+                                       paths.push_back(dir);
+                                       used.insert(dir);
+                               }
+                       }
+                       if (!bootstrapping) std::clog << logmsg << std::flush;
+               }
+       } cache;
+       boost::mutex mutex;
+       typedef boost::lock_guard<boost::mutex> Lock;
+}
+
+void pathBootstrap() { Lock l(mutex); cache.pathBootstrap(); }
+void pathInit() { Lock l(mutex); cache.pathInit(); }
+fs::path getLogFilename() { Lock l(mutex); return cache.cache / "infolog.txt"; }
+fs::path getSchemaFilename() { Lock l(mutex); return cache.share / configSchema; }
+fs::path getHomeDir() { Lock l(mutex); return cache.home; }
+fs::path getShareDir() { Lock l(mutex); return cache.share; }
+fs::path getLocaleDir() { Lock l(mutex); return cache.locale; }
+fs::path getConfigDir() { Lock l(mutex); return cache.conf; }
+fs::path getSysConfigDir() { Lock l(mutex); return cache.sysConf; }
+fs::path getDataDir() { Lock l(mutex); return cache.data; }
+fs::path getCacheDir() { Lock l(mutex); return cache.cache; }
+Paths const& getPaths() { Lock l(mutex); return cache.paths; }
+
+Paths getThemePaths() {
+       const fs::path themes = "themes";
+       const fs::path def = "default";
+       std::string theme = config["game/theme"].getEnumName();
+       Paths paths = getPaths();
+       Paths infixes = { themes / theme, themes / def, fs::path() };
+       if (!theme.empty() && theme != def) infixes.push_front(themes / theme);
+       // Build combinations of paths and infixes
+       Paths themePaths;
+       for (fs::path const& infix: infixes) {
+               for (fs::path p: paths) {
+                       p /= infix;
+                       if (fs::is_directory(p)) themePaths.push_back(p);
+               }
+       }
+       return themePaths;
+}
+
+fs::path findFile(fs::path const& filename) {
+       if (filename.empty()) throw std::logic_error("findFile expects a filename.");
+       if (filename.is_absolute()) throw std::logic_error("findFile expects a filename without path.");
+       Paths list;
+       for (fs::path p: getThemePaths()) {
+               p /= filename;
+               list.push_back(p);
+               if (fs::exists(p)) return p.string();
+       }
+       std::string logmsg = "fs/error: Unable to locate data file, tried:\n";
+       for (auto const& p: list) logmsg += "  " + p.string() + '\n';
+       std::clog << logmsg << std::flush;
+       throw std::runtime_error("Cannot find file \"" + filename.string() + "\" in Performous theme or data folders");
+}
+
+Paths listFiles(fs::path const& dir) {
+       if (dir.is_absolute()) throw std::logic_error("findFile expects a folder name without path.");
+       std::set<fs::path> found;  // Filenames already found
+       Paths files;  // Full paths of files found
+       for (fs::path path: getThemePaths()) {
+               for (fs::recursive_directory_iterator dirIt(path), dirEnd; dirIt != dirEnd; ++dirIt) {
+                       fs::path name = dirIt->path().filename();  // FIXME: Extract full path from current folder, not just the filename
+                       // If successfully inserted to "found", it wasn't found before, so add to paths.
+                       if (found.insert(name).second) files.push_back(*dirIt);
+               }
+       }
+       return files;
+}
+
+std::list<std::string> getThemes() {
+       std::set<std::string> themes;
+       // Search all paths for themes folders and add them
+       for (auto p: getPaths()) {
+               p /= "themes";
+               if (!fs::is_directory(p)) continue;
+               // Gather the themes in this folder
+               for (fs::directory_iterator dirIt(p), dirEnd; dirIt != dirEnd; ++dirIt) {
+                       fs::path p2 = dirIt->path();
+                       if (fs::is_directory(p2)) themes.insert(p2.filename().string());
+               }
+       }
+       return std::list<std::string>(themes.begin(), themes.end());
+}
+
+Paths getPathsConfig(std::string const& confOption) {
+       Lock l(mutex);
+       Paths ret;
+       for (auto const& str: config[confOption].sl()) {
+               ret.splice(ret.end(), cache.pathExpand(str));  // Add expanded paths to ret.
+       }
+       return ret;
+}
+
+BinaryBuffer readFile(fs::path const& path) {
+       BinaryBuffer ret;
+       fs::ifstream f(path, std::ios::binary);
+       f.seekg(0, std::ios::end);
+       ret.resize(f.tellg());
+       f.seekg(0);
+       f.read(reinterpret_cast<char*>(ret.data()), ret.size());
+       if (!f) throw std::runtime_error("File cannot be read: " + path.string());
+       return ret;
+}
+
diff --git a/game/fs.hh b/game/fs.hh
new file mode 100644 (file)
index 0000000..1a94ad6
--- /dev/null
@@ -0,0 +1,41 @@
+#pragma once
+
+#include <boost/filesystem/path.hpp>
+#include <list>
+
+namespace fs = boost::filesystem;
+
+typedef std::vector<std::uint8_t> BinaryBuffer;
+
+/// Read an entire file into a buffer
+BinaryBuffer readFile(fs::path const& path);
+
+/// Determine where the important system paths and most importantly the config schema are. Must be run before any of the functions below.
+void pathBootstrap();
+
+/// Do full data dir (search path) init or re-init after config options have been modified.
+/// - Full search path and themes will only be available after this.
+/// - Logging and config must be running before pathInit (pathInit is first called from configuration.cc).
+void pathInit();
+
+std::list<std::string> getThemes();  ///< Find all theme folders and return theme names.
+
+fs::path getLogFilename();  ///< Get the log filename.
+fs::path getSchemaFilename();  ///< Get the config schema filename.
+fs::path getHomeDir();  ///< Get user's home folder.
+fs::path getConfigDir();  ///< Get user-writable Performous config folder.
+fs::path getSysConfigDir();  ///< Get root-writable Performous config folder.
+fs::path getDataDir();  ///< Get user-writable Performous data folder.
+fs::path getCacheDir();  ///< Get user-writable temporary folder.
+fs::path getShareDir();  ///< Get Performous system-level data folder.
+fs::path getLocaleDir();  ///< Get the system local folder.
+
+typedef std::list<fs::path> Paths;
+
+fs::path findFile(fs::path const& filename);  ///< Look for the specified file in theme and data folders.
+Paths listFiles(fs::path const& dir);  ///< List contents of specified folder in theme and data folders (omit duplicates).
+
+Paths const& getPaths();  ///< Get the data file search path
+Paths getThemePaths();  ///< Get the data/theme file search path (includes current and default themes in addition to data folders)
+Paths getPathsConfig(std::string const& confOption);  ///< Return expanded list of paths specified by a path config option
+
diff --git a/game/game.cc b/game/game.cc
new file mode 100644 (file)
index 0000000..7686792
--- /dev/null
@@ -0,0 +1,143 @@
+#include "screen.hh"
+#include "fs.hh"
+#include "configuration.hh"
+#include "glutil.hh"
+#include "glmath.hh"
+#include "util.hh"
+
+#include <boost/thread.hpp>
+#include <boost/lexical_cast.hpp>
+#include <stdexcept>
+#include <cstdlib>
+
+template<> Game* Singleton<Game>::ms_Singleton = nullptr;
+
+Game::Game(Window& _window):
+  m_window(_window), m_finished(false), newScreen(), currentScreen(), currentPlaylist(),
+  m_timeToFadeIn(), m_timeToFadeOut(), m_timeToShow(), m_message(),
+  m_messagePopup(0.0, 1.0), m_textMessage(findFile("message_text.svg"), config["graphic/text_lod"].f()),
+  m_loadingProgress(0.0f), m_logo(findFile("logo.svg")), m_logoAnim(0.0, 0.5)
+{
+       m_textMessage.dimensions.middle().center(-0.05);
+}
+
+void Game::activateScreen(std::string const& name) {
+       newScreen = getScreen(name);
+}
+
+void Game::updateScreen() {
+       if (!newScreen) return;
+       Screen* s = newScreen;  // A local copy in case exit() or enter() want to change screens again
+       newScreen = nullptr;
+       if (currentScreen) currentScreen->exit();
+       currentScreen = nullptr;  // Exception safety, do not remove
+       s->enter();
+       currentScreen = s;
+}
+
+Screen* Game::getScreen(std::string const& name) {
+       try {
+               return &screens.at(name);
+       } catch (boost::bad_ptr_container_operation&) {
+               throw std::invalid_argument("Screen " + name + " does not exist");
+       }
+}
+
+void Game::prepareScreen() {
+       getCurrentScreen()->prepare();
+}
+
+void Game::drawScreen() {
+       getCurrentScreen()->draw();
+       drawLogo();
+       drawNotifications();
+}
+
+void Game::loading(std::string const& message, float progress) {
+       // TODO: Create a better one, this is quite ugly
+       flashMessage(message + " " + boost::lexical_cast<std::string>(int(round(progress*100))) + "%", 0.0f, 0.5f, 0.2f);
+       m_loadingProgress = progress;
+       m_window.blank();
+       m_window.render(boost::bind(&Game::drawLoading, this));
+       m_window.swap();
+}
+
+void Game::drawLoading() {
+       drawLogo();
+       drawNotifications();
+       const int maxi = 20;
+       const double x = 0.3;
+       const double spacing = 0.01;
+       const double sq_size = (2*x - (maxi-1)*spacing) / maxi;
+       for (int i = 0; i <= m_loadingProgress * maxi; ++i) {
+               ColorTrans c(Color(0.2, 0.7, 0.7, (m_loadingProgress + 1.0)*0.5));
+               UseShader shader(getShader("color"));
+               float cx = -x + i * (sq_size + spacing);
+               float cy = 0;
+               float r = sq_size/2;
+               glutil::VertexArray va;
+               va.vertex(cx - r, cy + r);
+               va.vertex(cx + r, cy + r);
+               va.vertex(cx - r, cy - r);
+               va.vertex(cx + r, cy - r);
+               va.draw(GL_TRIANGLE_STRIP);
+       }
+}
+
+void Game::fatalError(std::string const& message) {
+       dialog("FATAL ERROR\n\n" + message);
+       m_window.blank();
+       m_window.render(boost::bind(&Game::drawNotifications, this));
+       m_window.swap();
+       boost::thread::sleep(now() + 4.0);
+}
+
+void Game::flashMessage(std::string const& message, float fadeIn, float hold, float fadeOut) {
+       m_message = message;
+       m_timeToFadeIn = fadeIn;
+       m_timeToShow = hold;
+       m_timeToFadeOut = fadeOut;
+       m_messagePopup.setTarget(fadeIn + hold + fadeOut);
+       m_messagePopup.setValue(0.0);
+}
+
+void Game::dialog(std::string const& text) {
+       m_dialogTimeOut.setValue(10);
+       m_dialog.reset(new Dialog(text));
+}
+
+bool Game::closeDialog() {
+       bool ret = !!m_dialog;
+       m_dialog.reset();
+       return ret;
+}
+
+void Game::drawLogo() {
+       double v = 0.5 - 0.5 * std::cos(M_PI * m_logoAnim.get());
+       m_logo.dimensions.fixedHeight(0.1).left(-0.45).screenTop(-0.1 + 0.11 * v);
+       m_logo.draw();
+}
+
+void Game::drawNotifications() {
+       double time = m_messagePopup.get();
+       if (time != 0.0) {
+               bool haveToFadeIn = time <= (m_timeToFadeIn); // Is this fade in?
+               bool haveToFadeOut = time >= (m_messagePopup.getTarget() - m_timeToFadeOut); // Is this fade out?
+               float fadeValue = 1.0f;
+
+               if (haveToFadeIn) { // Fade in
+                       fadeValue = float(time / m_timeToFadeIn); // Calculate animation value
+               } else if (haveToFadeOut) { // Fade out
+                       fadeValue = float((m_messagePopup.getTarget() - time) / m_timeToFadeOut); // Calculate animation value
+                       if (time >= m_messagePopup.getTarget()) m_messagePopup.setTarget(0.0, true); // Reset if fade out finished
+               }
+
+               ColorTrans c(Color::alpha(fadeValue));
+               m_textMessage.draw(m_message); // Draw the message
+       }
+       // Dialog
+       if (m_dialog) {
+               m_dialog->draw();
+               if(m_dialogTimeOut.get() == 0) closeDialog();
+       }
+}
diff --git a/game/glmath.hh b/game/glmath.hh
new file mode 100644 (file)
index 0000000..b7e3a7d
--- /dev/null
@@ -0,0 +1,184 @@
+#pragma once
+
+#include <GL/glew.h>
+#include <algorithm>
+#include <cmath>
+#include <iomanip>
+#include <iostream>
+#include <sstream>
+
+// FIXME: Temporary MinGW fix
+#ifndef M_PI
+#define M_PI 3.1415926535
+#endif
+
+namespace glmath {
+
+       template <typename T> T mix(T const& a, T const& b, double blend) {
+               return (1.0-blend) * a + blend * b;
+       }
+
+       struct vec4;
+
+       struct vec2 {
+               GLfloat x, y;
+               explicit vec2(GLfloat const* arr) { std::copy(arr, arr + 2, &x); }
+               explicit vec2(float x = 0.0, float y = 0.0): x(x), y(y) {}
+               GLfloat& operator[](unsigned j) { return (&x)[j]; }
+               GLfloat const& operator[](unsigned j) const { return (&x)[j]; }
+       };
+
+       struct vec3 {
+               GLfloat x, y, z;
+               explicit vec3(GLfloat const* arr) { std::copy(arr, arr + 3, &x); }
+               explicit vec3(float x = 0.0, float y = 0.0, float z = 0.0): x(x), y(y), z(z) {}
+               explicit vec3(vec4 const& v);
+               GLfloat& operator[](unsigned j) { return (&x)[j]; }
+               GLfloat const& operator[](unsigned j) const { return (&x)[j]; }
+       };
+
+       struct vec4 {
+               GLfloat x, y, z, w;
+               explicit vec4(GLfloat const* arr) { std::copy(arr, arr + 4, &x); }
+               explicit vec4(float x = 0.0, float y = 0.0, float z = 0.0, float w = 0.0): x(x), y(y), z(z), w(w) {}
+               explicit vec4(vec3 const& v, float w = 0.0): x(v.x), y(v.y), z(v.z), w(w) {}
+               GLfloat& operator[](unsigned j) { return (&x)[j]; }
+               GLfloat const& operator[](unsigned j) const { return (&x)[j]; }
+       };
+
+       inline vec3::vec3(vec4 const& v): x(v.x), y(v.y), z(v.z) {}
+
+       // Template functions to allow them to work with different types of floating-point values
+
+       template <typename Scalar> static inline vec2 operator*(Scalar k, vec2 const& v) { return vec2(k * v.x, k * v.y); }
+       template <typename Scalar> static inline vec3 operator*(Scalar k, vec3 const& v) { return vec3(k * v.x, k * v.y, k * v.z); }
+       template <typename Scalar> static inline vec4 operator*(Scalar k, vec4 const& v) { return vec4(k * v.x, k * v.y, k * v.z, k * v.w); }
+
+       static inline vec3 operator+(vec3 const& a, vec4 const& b) { return vec3(a.x + b.x, a.y + b.y, a.z + b.z); }
+       static inline vec4 operator+(vec4 const& a, vec4 const& b) { return vec4(a.x + b.x, a.y + b.y, a.z + b.z, a.w + b.w); }
+
+       static inline float dot(vec2 const& a, vec2 const& b) {
+               return a.x * b.x + a.y * b.y;
+       }
+       static inline float dot(vec3 const& a, vec3 const& b) {
+               return a.x * b.x + a.y * b.y + a.z * b.z;
+       }
+
+       static inline float len(vec2 const& v) { return std::sqrt(dot(v, v)); }
+       static inline float len(vec3 const& v) { return std::sqrt(dot(v, v)); }
+       static inline vec2 normalize(vec2 const& v) { return (1 / len(v)) * v; }
+       static inline vec3 normalize(vec3 const& v) { return (1 / len(v)) * v; }
+
+       template <typename Vector> struct mat {
+               typedef Vector vector_type;
+               static const unsigned dimension = sizeof(Vector) / sizeof(GLfloat);
+               static mat zero() { return mat(); }
+               static mat identity() {
+                       mat ret;
+                       for (unsigned i = 0; i < dimension; ++i) ret(i,i) = 1.0;
+                       return ret;
+               }
+               static mat diagonal(Vector const& v) {
+                       mat ret;
+                       for (unsigned i = 0; i < dimension; ++i) ret(i,i) = v[i];
+                       return ret;
+               }
+               template <typename AnyVec> explicit mat(mat<AnyVec> const& m) {
+                       for (unsigned i = 0; i < dimension && i < m.dimension; ++i) cols[i] = Vector(m.cols[i]);
+               }
+               Vector cols[dimension];
+               operator GLfloat*() { return &cols[0][0]; }
+               operator GLfloat const*() const { return &cols[0][0]; }
+               GLfloat& operator()(unsigned i, unsigned j) { return cols[j][i]; }
+               GLfloat const& operator()(unsigned i, unsigned j) const { return cols[j][i]; }
+       private:
+               mat() {}
+       };
+       
+       template <typename Vec> static inline std::ostream& operator<<(std::ostream& os, mat<Vec> const& m) {
+               std::ostringstream oss;
+               oss << std::setprecision(3) << std::fixed;
+               for (int i = 0; i < m.dimension; ++i) {
+                       for (int j = 0; j < m.dimension; ++j) {
+                               oss.width(7);
+                               oss << m(i,j);
+                       }
+                       oss << '\n';
+               }
+               return os << oss.str() << std::endl;
+       }
+
+       template <typename Vec> static inline mat<Vec> operator*(mat<Vec> const& a, mat<Vec> const& b) {
+               mat<Vec> ret = mat<Vec>::zero();
+               for (unsigned i = 0; i < ret.dimension; ++i) {
+                       for (unsigned j = 0; j < ret.dimension; ++j) {
+                               GLfloat sum = 0.0;
+                               for (unsigned k = 0; k < ret.dimension; ++k) {
+                                       sum += a(i, k) * b(k, j);
+                               }
+                               ret(i, j) = sum;
+                       }
+               }
+               return ret;
+       }
+
+       typedef mat<vec3> mat3;
+       typedef mat<vec4> mat4;
+
+       static inline mat4 translate(vec3 const& v) {
+               mat4 ret = mat4::identity();
+               ret(0,3) = v.x;
+               ret(1,3) = v.y;
+               ret(2,3) = v.z;
+               return ret;
+       }
+
+       static inline mat4 scale(vec3 const& v) {
+               mat4 ret = mat4::identity();
+               ret(0,0) = v.x;
+               ret(1,1) = v.y;
+               ret(2,2) = v.z;
+               return ret;
+       }
+
+       static inline mat4 scale(float k) { return scale(vec3(k, k, k)); }
+
+       static inline mat4 rotate(float rad, vec3 axis) {
+               mat4 ret = mat4::identity();
+               vec3 u = normalize(axis);
+               // Based on http://en.wikipedia.org/wiki/Rotation_mat4#Rotation_mat4_from_axis_and_angle
+               float s = std::sin(rad);
+               float c = std::cos(rad);
+               float nc = 1 - c;
+               // Column 0
+               ret(0,0) = c + u.x * u.x * nc;
+               ret(1,0) = u.y * u.x * nc + u.z * s;
+               ret(2,0) = u.z * u.x * nc - u.y * s;
+               // Column 1
+               ret(0,1) = u.x * u.y * nc - u.z * s;
+               ret(1,1) = c + u.y * u.y * nc;
+               ret(2,1) = u.z * u.y * nc + u.x * s;
+               // Column 2
+               ret(0,2) = u.x * u.z * nc + u.y * s;
+               ret(1,2) = u.y * u.z * nc - u.x * s;
+               ret(2,2) = c + u.z * u.z * nc;
+               return ret;
+       }
+
+       static inline mat4 frustum(float l, float r, float b, float t, float n, float f) {
+               float w = r - l;
+               float h = t - b;
+               float d = n - f;
+               mat4 ret = mat4::identity();
+               ret(0,0) = 2 * n / w;
+               ret(1,1) = 2 * n / h;
+               ret(0,2) = (r + l) / w;
+               ret(1,2) = (t + b) / h;
+               ret(2,2) = (f + n) / d;
+               ret(3,2) = -1.0;
+               ret(2,3) = 2 * f * n / d;
+               ret(3,3) = 0.0;
+               return ret;
+       }
+}
+
diff --git a/game/glshader.cc b/game/glshader.cc
new file mode 100644 (file)
index 0000000..b8d3a1f
--- /dev/null
@@ -0,0 +1,135 @@
+#include "glshader.hh"
+
+#include "glutil.hh"
+#include <boost/filesystem/fstream.hpp>
+#include <algorithm>
+#include <stdexcept>
+
+using namespace glutil;
+
+namespace {
+       /// Loads a file into memory
+       std::string loadFile(fs::path const& filepath) {
+               fs::ifstream f(filepath, std::ios::binary);
+               if (!f) throw std::runtime_error(std::string("Couldn't open ") + filepath.string());
+               f.seekg(0, std::ios::end);
+               size_t size = f.tellg();
+               f.seekg(0);
+               std::vector<char> data(size+1); // +1 for terminating null
+               if (!f.read(&data[0], size)) throw std::runtime_error(std::string("Unexpected I/O error in ") + filepath.string());
+               data.back() = '\0';
+               return std::string(&data[0]);
+       }
+}
+
+/// Dumps Shader/Program InfoLog
+void Shader::dumpInfoLog(GLuint id) {
+       int maxLength;
+
+       if (glIsShader(id)) glGetShaderiv(id, GL_INFO_LOG_LENGTH, &maxLength);
+       else glGetProgramiv(id, GL_INFO_LOG_LENGTH, &maxLength);
+
+       char infoLog[maxLength];
+       int infoLogLength = 0;
+
+       if (glIsShader(id)) glGetShaderInfoLog(id, maxLength, &infoLogLength, infoLog);
+       else glGetProgramInfoLog(id, maxLength, &infoLogLength, infoLog);
+
+       // Ignore success messages that the Radeon driver always seems to give
+       if (std::equal(infoLog, infoLog + infoLogLength, "Vertex shader(s) linked, fragment shader(s) linked, geometry shader(s) linked.")) return;
+
+       // FIXME: The logging facility probably won't handle this right, especially when infoLog contains many lines.
+       std::clog << "opengl/error: Shader " << name << ": " << infoLog << std::endl;
+}
+
+Shader::Shader(std::string const& name): name(name), program(0) {}
+
+Shader::~Shader() {
+       glDeleteProgram(program);
+       std::for_each(shader_ids.begin(), shader_ids.end(), glDeleteShader);
+       //std::clog << "shader/info: Shader program " << (unsigned)program << " deleted." << std::endl;
+}
+
+Shader& Shader::compileFile(fs::path const& filename) {
+       fs::path ext = filename.extension();
+       GLenum type;
+       if (ext == ".vert") type = GL_VERTEX_SHADER;
+       else if (ext == ".geom") type = GL_GEOMETRY_SHADER;
+       else if (ext == ".frag") type = GL_FRAGMENT_SHADER;
+       else throw std::logic_error("Unknown file extension on shader " + filename.string());
+       std::string srccode = loadFile(filename);
+       // Replace "//DEFINES" with defs
+       if (!defs.empty()) {
+               std::string::size_type pos = srccode.find("//DEFINES");
+               if (pos != std::string::npos) srccode = srccode.substr(0, pos) + defs + srccode.substr(pos + 9);
+       }
+       try {
+               return compileCode(srccode, type);
+       } catch (std::runtime_error& e) {
+               throw std::runtime_error(filename.string() + ": " + e.what());
+       }
+}
+
+
+Shader& Shader::compileCode(std::string const& srccode, GLenum type) {
+       glutil::GLErrorChecker ec("Shader::compile");
+       GLenum new_shader = glCreateShader(type);
+       ec.check("glCreateShader");
+       char const* source = srccode.c_str();
+       glShaderSource(new_shader, 1, &source, nullptr);
+       ec.check("glShaderSource");
+
+       glCompileShader(new_shader);
+       ec.check("glCompileShader");
+       glGetShaderiv(new_shader, GL_COMPILE_STATUS, &gl_response);
+       dumpInfoLog(new_shader);
+       if (gl_response != GL_TRUE) {
+               throw std::runtime_error("Shader compile error");
+       }
+
+       shader_ids.push_back(new_shader);
+       return *this;
+}
+
+
+Shader& Shader::link() {
+       glutil::GLErrorChecker ec("Shader::link");
+       if (program) throw std::runtime_error("Shader already linked.");
+       // Create the program id
+       program = glCreateProgram();
+       ec.check("glCreateProgram");
+       // Attach all compiled shaders to it
+       for (ShaderObjects::const_iterator it = shader_ids.begin(); it != shader_ids.end(); ++it)
+               glAttachShader(program, *it);
+       ec.check("glAttachShader");
+
+       // Link and check status
+       glLinkProgram(program);
+       glGetProgramiv(program, GL_LINK_STATUS, &gl_response);
+       dumpInfoLog(program);
+       if (gl_response != GL_TRUE) {
+               throw std::runtime_error("Something went wrong linking the shader program.");
+       }
+       ec.check("glLinkProgram");
+
+       return *this;
+}
+
+
+Shader& Shader::bind() {
+       glutil::GLErrorChecker ec("Shader::bind");
+       glUseProgram(program);
+       return *this;
+}
+
+
+Uniform Shader::operator[](const std::string& uniform) {
+       bind();
+       // Try to use a cached value
+       auto it = uniforms.find(uniform);
+       if (it != uniforms.end()) return Uniform(it->second);
+       // Get the value and cache it
+       GLint var = glGetUniformLocation(program, uniform.c_str());
+       if (var == -1) throw std::logic_error("GLSL shader '" + name + "' uniform variable '" + uniform + "' not found.");
+       return Uniform(uniforms[uniform] = var);
+}
diff --git a/game/glshader.hh b/game/glshader.hh
new file mode 100644 (file)
index 0000000..a5886fe
--- /dev/null
@@ -0,0 +1,85 @@
+#pragma once
+
+#include "fs.hh"
+#include "glmath.hh"
+#include "glutil.hh"
+#include <string>
+#include <map>
+#include <vector>
+#include <GL/glew.h>
+#include <boost/noncopyable.hpp>
+
+struct Uniform {
+       GLint id;
+       explicit Uniform(GLint id): id(id) {}
+       void set(int value) { glUniform1i(id, value); }
+       void set(float value) { glUniform1f(id, value); }
+       void set(int x, int y) { glUniform2i(id, x, y); }
+       void set(float x, float y) { glUniform2f(id, x, y); }
+       void set(int x, int y, int z) { glUniform3i(id, x, y, z); }
+       void set(float x, float y, float z) { glUniform3f(id, x, y, z); }
+       void set(int x, int y, int z, int w) { glUniform4i(id, x, y, z, w); }
+       void set(float x, float y, float z, float w) { glUniform4f(id, x, y, z, w); }
+       void setMat3(GLfloat const* m) { glUniformMatrix3fv(id, 1, GL_FALSE, m); }
+       void setMat4(GLfloat const* m) { glUniformMatrix4fv(id, 1, GL_FALSE, m); }
+};
+
+struct Shader: public boost::noncopyable {
+       /// Print compile errors and such
+       /// @param id of shader or program
+       void dumpInfoLog(GLuint id);
+
+       Shader(std::string const& name);
+       ~Shader();
+       /// Set a string that will replace "//DEFINES" in anything loaded by compileFile
+       Shader& addDefines(std::string const& defines) { defs += defines; return *this; }
+       /// Load shader from file
+       Shader& compileFile(fs::path const& filename);
+       /** Compiles a shader of a given type. */
+       Shader& compileCode(std::string const& srccode, GLenum type);
+       /** Links all compiled shaders to a shader program. */
+       Shader& link();
+
+       /** Binds the shader into use. */
+       Shader& bind();
+
+       /** Allow setting uniforms in a chain. Shader needs to be in use.*/
+
+
+       /** Get uniform location. Uses caching internally. */
+       Uniform operator[](const std::string& uniform);
+
+       // Some operators
+       bool operator==(const Shader& rhs) const { return program == rhs.program; }
+       bool operator!=(const Shader& rhs) const { return program != rhs.program; }
+
+private:
+       std::string name; ///< for debugging purposes only
+       GLuint program; ///< shader program object id
+       int gl_response; ///< save last return state
+
+       std::string defs;
+
+       typedef std::vector<GLuint> ShaderObjects;
+       ShaderObjects shader_ids;
+
+       typedef std::map<std::string, GLint> UniformMap;
+       UniformMap uniforms; ///< Cached uniform locations, use operator[] to access
+
+};
+
+
+/** Temporarily switch shader in a RAII manner. */
+struct UseShader {
+       UseShader(Shader& new_shader): m_shader(new_shader) {
+               glGetIntegerv(GL_CURRENT_PROGRAM, &m_old);
+               m_shader.bind();
+       }
+       ~UseShader() { glUseProgram(m_old); }
+       /// Access the bound shader
+       Shader& operator()() { return m_shader; }
+
+  private:
+       Shader& m_shader;
+       GLint m_old;
+};
diff --git a/game/glutil.cc b/game/glutil.cc
new file mode 100644 (file)
index 0000000..7cd895a
--- /dev/null
@@ -0,0 +1,52 @@
+#include "glutil.hh"
+
+namespace glutil {
+
+void VertexArray::generateVBO() {
+       if (m_vbo != 0) glDeleteBuffers(1, &m_vbo);
+       glGenBuffers(1, &m_vbo);
+       glBindBuffer(GL_ARRAY_BUFFER, m_vbo);
+       glBufferData(GL_ARRAY_BUFFER, sizeof(VertexInfo) * size(), &m_vertices.front(), GL_STATIC_DRAW);
+       glBindBuffer(GL_ARRAY_BUFFER, 0);
+}
+
+void VertexArray::draw(GLint mode) {
+       if (empty()) return;
+       unsigned stride = sizeof(VertexInfo);
+       GLint program;
+       glGetIntegerv(GL_CURRENT_PROGRAM, &program);
+       GLint vertPos = glGetAttribLocation(program, "vertPos");
+       GLint vertTexCoord = glGetAttribLocation(program, "vertTexCoord");
+       GLint vertNormal = glGetAttribLocation(program, "vertNormal");
+       GLint vertColor = glGetAttribLocation(program, "vertColor");
+       if (m_vbo) glBindBuffer(GL_ARRAY_BUFFER, m_vbo);
+       if (vertPos != -1) {
+               const GLvoid* ptr = m_vbo ? (GLvoid*)offsetof(VertexInfo, position) : &m_vertices[0].position;
+               glEnableVertexAttribArray(vertPos);
+               glVertexAttribPointer(vertPos, 3, GL_FLOAT, GL_FALSE, stride, ptr);
+       }
+       if (vertTexCoord != -1) {
+               const GLvoid* ptr = m_vbo ? (GLvoid*)offsetof(VertexInfo, texCoord) : &m_vertices[0].texCoord;
+               glEnableVertexAttribArray(vertTexCoord);
+               glVertexAttribPointer(vertTexCoord, 2, GL_FLOAT, GL_FALSE, stride, ptr);
+       }
+       if (vertNormal != -1) {
+               const GLvoid* ptr = m_vbo ? (GLvoid*)offsetof(VertexInfo, normal) : &m_vertices[0].normal;
+               glEnableVertexAttribArray(vertNormal);
+               glVertexAttribPointer(vertNormal, 3, GL_FLOAT, GL_FALSE, stride, ptr);
+       }
+       if (vertColor != -1) {
+               const GLvoid* ptr = m_vbo ? (GLvoid*)offsetof(VertexInfo, color) : &m_vertices[0].color;
+               glEnableVertexAttribArray(vertColor);
+               glVertexAttribPointer(vertColor, 4, GL_FLOAT, GL_FALSE, stride, ptr);
+       }
+       glDrawArrays(mode, 0, size());
+
+       if (vertPos != -1) glDisableVertexAttribArray(vertPos);
+       if (vertTexCoord != -1) glDisableVertexAttribArray(vertTexCoord);
+       if (vertNormal != -1) glDisableVertexAttribArray(vertNormal);
+       if (vertColor != -1) glDisableVertexAttribArray(vertColor);
+       if (m_vbo) glBindBuffer(GL_ARRAY_BUFFER, 0);
+}
+
+}
diff --git a/game/glutil.hh b/game/glutil.hh
new file mode 100644 (file)
index 0000000..473106b
--- /dev/null
@@ -0,0 +1,133 @@
+#pragma once
+
+
+#include "color.hh"
+#include "glmath.hh"
+#include <GL/glew.h>
+#include <string>
+#include <iostream>
+#include <vector>
+
+namespace glutil {
+
+       // Note: if you reorder or otherwise change the contents of this, VertexArray::Draw() must be modified accordingly
+       struct VertexInfo {
+               glmath::vec3 position;
+               glmath::vec2 texCoord;
+               glmath::vec3 normal;
+               glmath::vec4 color;
+               VertexInfo():
+                 position(0.0, 0.0, 0.0),
+                 texCoord(0.0, 0.0),
+                 normal(0.0, 0.0, 0.0),
+                 color(1.0, 1.0, 1.0, 1.0)
+               {}
+       };
+
+       /// Handy vertex array capable of drawing itself
+       class VertexArray {
+         private:
+               std::vector<VertexInfo> m_vertices;
+               VertexInfo m_vert;
+               GLuint m_vbo = 0;
+         public:
+               VertexArray() {}
+
+               ~VertexArray() { clear(); }
+
+               void generateVBO();
+
+               VertexArray& vertex(float x, float y, float z = 0.0f) {
+                       return vertex(glmath::vec3(x, y, z));
+               }
+
+               VertexArray& vertex(glmath::vec3 const& v) {
+                       m_vert.position = v;
+                       m_vertices.push_back(m_vert);
+                       m_vert = VertexInfo();
+                       return *this;
+               }
+
+               VertexArray& normal(float x, float y, float z) {
+                       return normal(glmath::vec3(x, y, z));
+               }
+
+               VertexArray& normal(glmath::vec3 const& v) {
+                       m_vert.normal = v;
+                       return *this;
+               }
+
+               VertexArray& texCoord(float s, float t) {
+                       return texCoord(glmath::vec2(s, t));
+               }
+
+               VertexArray& texCoord(glmath::vec2 const& v) {
+                       m_vert.texCoord = v;
+                       return *this;
+               }
+
+               VertexArray& color(glmath::vec4 const& v) {
+                       m_vert.color = v;
+                       return *this;
+               }
+
+               void draw(GLint mode = GL_TRIANGLE_STRIP);
+
+               bool empty() const {
+                       return m_vertices.empty();
+               }
+
+               unsigned size() const {
+                       return m_vertices.size();
+               }
+
+               void clear() {
+                       m_vertices.clear();
+                       if (m_vbo) {
+                               glDeleteBuffers(1, &m_vbo);
+                               m_vbo = 0;
+                       }
+               }
+
+       };
+
+       /// Wrapper struct for RAII
+       struct UseDepthTest {
+               /// enable depth test (for 3d objects)
+               UseDepthTest() {
+                       glClear(GL_DEPTH_BUFFER_BIT);
+                       glEnable(GL_DEPTH_TEST);
+               }
+               ~UseDepthTest() {
+                       glDisable(GL_DEPTH_TEST);
+               }
+       };
+
+       /// Checks for OpenGL error and displays it with given location info
+       struct GLErrorChecker {
+               std::string info;
+               GLErrorChecker(std::string const& info): info(info) { check("precondition"); }
+               ~GLErrorChecker() { check("postcondition"); }
+               void check(std::string const& what = "check()") {
+                       GLenum err = glGetError();
+                       if (err == GL_NO_ERROR) return;
+                       std::clog << "opengl/error: " << msg(err) << " in " << info << " " << what << std::endl;
+               }
+               static void reset() { glGetError(); }
+               static std::string msg(GLenum err) {
+                       switch(err) {
+                               case GL_NO_ERROR: return std::string();
+                               case GL_INVALID_ENUM: return "Invalid enum";
+                               case GL_INVALID_VALUE: return "Invalid value";
+                               case GL_INVALID_OPERATION: return "Invalid operation";
+                               case GL_INVALID_FRAMEBUFFER_OPERATION: return "FBO is not complete";
+                               case GL_STACK_OVERFLOW: return "Stack overflow";
+                               case GL_STACK_UNDERFLOW: return "Stack underflow";
+                               case GL_OUT_OF_MEMORY: return "Out of memory";
+                               default: return "Unknown error";
+                       }
+               }
+       };
+}
+
+
diff --git a/game/guitargraph.cc b/game/guitargraph.cc
new file mode 100644 (file)
index 0000000..e8525d3
--- /dev/null
@@ -0,0 +1,1228 @@
+#include "guitargraph.hh"
+#include "fs.hh"
+#include "song.hh"
+#include "i18n.hh"
+
+#include <cmath>
+#include <cstdlib>
+#include <stdexcept>
+#include <boost/lexical_cast.hpp>
+#include <boost/format.hpp>
+
+namespace {
+       #if 0 // Here is some dummy gettext calls to populate the dictionary
+       _("Kids") _("Easy") _("Medium") _("Hard") _("Expert")
+       #endif
+       struct Diff { std::string name; int basepitch; } diffv[] = {
+               { "Kids", 0x3C },
+               { "Easy", 0x3C },
+               { "Medium", 0x48 },
+               { "Hard", 0x54 },
+               { "Expert", 0x60 }
+       };
+       const size_t diffsz = sizeof(diffv) / sizeof(*diffv);
+       const float g_angle = 1.4f; // How many radians to rotate the fretboards
+       const float past = -0.2f; // Relative time from cursor that is considered past (out of screen)
+       const float future = 1.5f; // Relative time from cursor that is considered future (out of screen)
+       const float timescale = 25.0f; // Multiplier to get graphics units from time
+       const float texCoordStep = -0.5f; // Two beat lines per neck texture => 0.5 tex units per beat
+       const float flameSpd = 6.0f; // Multiplier for flame growth
+       // Note: t is difference from playback time so it must be in range [past, future]
+       float time2y(float t) { return -timescale * (t - past) / (future - past); }
+       float time2a(float t) {
+               float a = clamp(1.0 - t / future); // Note: we want 1.0 alpha already at zero t.
+               return std::pow(a, 0.8f); // Nicer curve
+       }
+       float y2a(float y) { return time2a(past - y / timescale * (future - past)); }
+       float tc(float y) { return y * 0.1; } // Get texture coordinates for animating hold notes
+       const double maxTolerance = 0.15; // Maximum error in seconds
+
+       const float drumfill_min_rate = 6.0; // The rate of hits per second required to complete a drum fill
+       double points(double error) {
+               // error    points
+               // 150ms      15
+               // 100ms      30
+               //  50ms      45
+               //  30ms      50
+               double score = 0.0;
+               if (error < maxTolerance) score += 15;
+               if (error < 0.1) score += 15;
+               if (error < 0.05) score += 15;
+               if (error < 0.03) score += 5;
+               return score;
+       }
+
+       const int streakStarBonus = 500;
+       int getNextBigStreak(int prev) { return prev + 50; }
+       inline float blend(float a, float b, float f) { return a*f + b*(1.0f-f); }
+}
+
+void GuitarGraph::initGuitar() {
+       // Copy all tracks of guitar types (not DRUMS and not KEYBOARD) to m_instrumentTracks
+       for (auto const& elem: m_song.instrumentTracks) {
+               std::string index = elem.first;
+               if (index != TrackName::DRUMS && index != TrackName::KEYBOARD) m_instrumentTracks[index] = &elem.second;
+       }
+       if (m_instrumentTracks.empty()) throw std::logic_error("No guitar tracks found");
+
+       // Adding fail samples
+       m_samples.push_back("guitar fail1");
+       m_samples.push_back("guitar fail2");
+       m_samples.push_back("guitar fail3");
+       m_samples.push_back("guitar fail4");
+       m_samples.push_back("guitar fail5");
+       m_samples.push_back("guitar fail6");
+}
+
+void GuitarGraph::initDrums() {
+       // Copy all tracks of drum type  to m_instrumentTracks
+       for (auto const& elem: m_song.instrumentTracks) {
+               std::string index = elem.first;
+               if (index == TrackName::DRUMS) m_instrumentTracks[index] = &elem.second;
+       }
+       if (m_instrumentTracks.empty()) throw std::logic_error("No drum tracks found");
+
+       // Adding fail samples
+       m_samples.push_back("drum bass");
+       m_samples.push_back("drum snare");
+       m_samples.push_back("drum hi-hat");
+       m_samples.push_back("drum tom1");
+       m_samples.push_back("drum cymbal");
+       //m_samples.push_back("drum tom2");
+}
+
+GuitarGraph::GuitarGraph(Audio& audio, Song const& song, input::DevicePtr dev, int number):
+  InstrumentGraph(audio, song, dev),
+  m_tail(findFile("tail.svg")),
+  m_tail_glow(findFile("tail_glow.svg")),
+  m_tail_drumfill(findFile("tail_drumfill.svg")),
+  m_flame(findFile("flame.svg")),
+  m_flame_godmode(findFile("flame_godmode.svg")),
+  m_tap(findFile("tap.svg")),
+  m_neckglow(findFile("neck_glow.svg")),
+  m_neckglowColor(),
+  m_drums(dev->type == input::DEVTYPE_DRUMS),
+  m_level(),
+  m_track_index(m_instrumentTracks.end()),
+  m_dfIt(m_drumfills.end()),
+  m_errorMeter(0.0, 2.0),
+  m_errorMeterFlash(0.0, 4.0),
+  m_errorMeterFade(0.0, 0.333),
+  m_drumJump(0.0, 12.0),
+  m_starpower(0.0, 0.1),
+  m_starmeter(),
+  m_drumfillHits(),
+  m_drumfillScore(),
+  m_soloTotal(),
+  m_soloScore(),
+  m_solo(),
+  m_hasTomTrack(false),
+  m_whammy(0)
+{
+       if(m_drums) {
+               initDrums();
+       } else {
+               initGuitar();
+       }
+       // Load 3D fret objects
+       m_fretObj.load(findFile("fret.obj"));
+       m_tappableObj.load(findFile("fret_tap.obj"));
+       // Score calculator (TODO a better one)
+       m_scoreText.reset(new SvgTxtThemeSimple(findFile("sing_score_text.svg"), config["graphic/text_lod"].f()));
+       m_streakText.reset(new SvgTxtThemeSimple(findFile("sing_score_text.svg"), config["graphic/text_lod"].f()));
+       for (size_t i = 0; i < max_panels; ++i) {
+               m_pressed_anim[i].setRate(5.0);
+               m_holds[i] = 0;
+       }
+       m_pads = 5;
+       m_track_index = m_instrumentTracks.begin();
+       while (number--)
+               if (++m_track_index == m_instrumentTracks.end()) m_track_index = m_instrumentTracks.begin();
+       // Pick a nice default difficulty (note: the execution of || stops when true is returned)
+       difficulty(DIFFICULTY_EASY) ||
+       difficulty(DIFFICULTY_SUPAEASY) ||
+       difficulty(DIFFICULTY_MEDIUM) ||
+       difficulty(DIFFICULTY_AMAZING) ||
+       (difficultyAuto(), true);
+       updateNeck();
+       setupJoinMenu();
+}
+
+void GuitarGraph::setupJoinMenuDifficulty() {
+       ConfigItem::OptionList ol;
+       int cur = 0;
+       // Add difficulties to the option list
+       for (int level = 0; level < DIFFICULTYCOUNT; ++level) {
+               if (difficulty(Difficulty(level), true)) {
+                       ol.push_back(boost::lexical_cast<std::string>(level));
+                       if (Difficulty(level) == m_level) cur = ol.size()-1;
+               }
+       }
+       m_selectedDifficulty = ConfigItem(ol); // Create a ConfigItem from the option list
+       m_selectedDifficulty.select(cur); // Set the selection to current level
+       m_menu.add(MenuOption("", _("Select difficulty")).changer(m_selectedDifficulty)); // MenuOption that cycles the options
+       m_menu.back().setDynamicName(m_difficultyOpt); // Set the title to be dynamic
+}
+
+void GuitarGraph::setupJoinMenuDrums() {
+       setupJoinMenuDifficulty();
+       m_menu.add(MenuOption(_("Lefty-mode"), "").changer(m_leftymode));
+       m_menu.back().setDynamicComment(m_leftyOpt);
+}
+
+void GuitarGraph::setupJoinMenuGuitar() {
+       ConfigItem::OptionList ol;
+       int cur = 0;
+       // Add tracks to option list
+       for (InstrumentTracksConstPtr::const_iterator it = m_instrumentTracks.begin(); it != m_instrumentTracks.end(); ++it) {
+               ol.push_back(it->first);
+               if (m_track_index->first == it->first) cur = ol.size()-1; // Find the index of current track
+       }
+       m_selectedTrack = ConfigItem(ol); // Create a ConfigItem from the option list
+       m_selectedTrack.select(cur); // Set the selection to current track
+       m_menu.add(MenuOption("", _("Select track")).changer(m_selectedTrack)); // MenuOption that cycles the options
+       m_menu.back().setDynamicName(m_trackOpt); // Set the title to be dynamic
+       setupJoinMenuDifficulty();
+       m_menu.add(MenuOption(_("Lefty-mode"), "").changer(m_leftymode));
+       m_menu.back().setDynamicComment(m_leftyOpt);
+}
+
+void GuitarGraph::setupJoinMenu() {
+       m_menu.clear();
+       updateJoinMenu();
+       // Populate root menu
+       m_menu.add(MenuOption(_("Ready!"), _("Start performing!")));
+       if(m_drums) {
+               setupJoinMenuDrums();
+       } else {
+               setupJoinMenuGuitar();
+       }
+       m_menu.add(MenuOption(_("Quit"), _("Exit to song browser")).screen("Songs"));
+}
+
+void GuitarGraph::updateJoinMenu() {
+       m_trackOpt = getTrack();
+       m_difficultyOpt =  getDifficultyString();
+       std::string s("\n (");
+       std::string le = m_leftymode.b() ? _("ON") : _("OFF");
+       m_leftyOpt = _("Toggle lefty-mode") + s + le + ")";
+}
+
+/// Load the appropriate neck texture
+void GuitarGraph::updateNeck() {
+       // TODO: Optimize with texture cache
+       std::string index = m_track_index->first;
+       if (index == TrackName::DRUMS) m_neck.reset(new Texture(findFile("drumneck.svg")));
+       else if (index == TrackName::KEYBOARD) m_neck.reset(new Texture(findFile("guitarneck.svg")));
+       else if (index == TrackName::BASS) m_neck.reset(new Texture(findFile("bassneck.svg")));
+       else m_neck.reset(new Texture(findFile("guitarneck.svg")));
+}
+
+/// Cycle through the different tracks
+void GuitarGraph::changeTrack(int dir) {
+       if (dir >= 0) ++m_track_index; else --m_track_index;
+       if (m_track_index == m_instrumentTracks.end()) m_track_index = m_instrumentTracks.begin();
+       else if (m_track_index == (--m_instrumentTracks.end())) m_track_index = (--m_instrumentTracks.end());
+       difficultyAuto(true);
+       updateNeck();
+       setupJoinMenu();  // Reset menu as difficulties might have changed
+       m_menu.select(1); // Restore selection to the track item
+}
+
+/// Set specific track
+void GuitarGraph::setTrack(const std::string& track) {
+       InstrumentTracksConstPtr::const_iterator it = m_instrumentTracks.find(track);
+       if (it != m_instrumentTracks.end()) m_track_index = it;
+       difficultyAuto(true);
+       updateNeck();
+       setupJoinMenu();  // Reset menu as difficulties might have changed
+       m_menu.select(1); // Restore selection to the track item
+}
+
+/// Get the trackname string
+std::string GuitarGraph::getTrack() const {
+       return _(m_track_index->first.c_str());
+}
+
+/// Get the difficulty as displayable string
+std::string GuitarGraph::getDifficultyString() const {
+       return _(diffv[m_level].name.c_str());
+}
+
+/// Get a string id for track and difficulty
+std::string GuitarGraph::getModeId() const {
+       return m_track_index->first + " - " + diffv[m_level].name;
+}
+
+/// Cycle through difficulties
+void GuitarGraph::changeDifficulty(int dir) {
+       for (int level = ((int)m_level + dir) % DIFFICULTYCOUNT; level != m_level;
+         level = (level+dir) % DIFFICULTYCOUNT)
+               if (difficulty(Difficulty(level))) return;
+}
+
+/// Find an initial difficulty level to use
+void GuitarGraph::difficultyAuto(bool tryKeep) {
+       if (tryKeep && difficulty(Difficulty(m_level))) return;
+       for (int level = 0; level < DIFFICULTYCOUNT; ++level) if (difficulty(Difficulty(level))) return;
+       throw std::runtime_error("No difficulty levels found for track " + m_track_index->first);
+}
+
+/// Attempt to use a given difficulty level
+bool GuitarGraph::difficulty(Difficulty level, bool check_only) {
+       InstrumentTrack const& track = *m_track_index->second;
+       // Find the stream number
+       for (auto const& elem: m_song.instrumentTracks) {
+               if (&track == &elem.second) break;
+       }
+       // Check if the difficulty level is available
+       uint8_t basepitch = diffv[level].basepitch;
+       NoteMap const& nm = track.nm;
+       unsigned fail = 0;
+       for (unsigned fret = 0; fret < m_pads; ++fret) if (nm.find(basepitch + fret) == nm.end()) ++fail;
+       if (fail == m_pads) return false;
+       if (check_only) return true;
+       Difficulty prevLevel = m_level;
+       m_level = level;
+       updateChords();
+       if (m_chords.size() <= 1) { // If there is only one chord, it's probably b0rked
+               m_level = prevLevel;
+               updateChords();
+               return false;
+       }
+       return true;
+}
+
+/// Core engine
+void GuitarGraph::engine() {
+       double time = m_audio.getPosition();
+       time -= config["audio/controller_delay"].f();
+       doUpdates();
+       if (!m_drumfills.empty()) updateDrumFill(time); // Drum Fills / BREs
+       m_whammy = 0;
+       // Countdown to start
+       handleCountdown(time, time < getNotesBeginTime() ? getNotesBeginTime() : m_jointime+1);
+       // Handle all events
+       for (input::Event ev; m_dev->getEvent(ev); ) {
+               // Lefty mode flip of buttons
+               if (m_leftymode.b() && m_drums && ev.source.type != input::SOURCETYPE_MIDI) {
+                       unsigned layer = ev.button.layer(), num = ev.button.num();
+                       // Layers 0-1: reverse all but kick; layer 2: swap yellow and blue cymbals
+                       if ((layer < 2 && num >= 1 && num <= 4) || (layer == 2 && num >= 2 && num <= 3)) ev.button = input::Button(layer, 5 - num);
+               }
+               // Keypress anims
+               {
+                       unsigned layer = ev.button.layer(), num = ev.button.num();
+                       // Guitar numbering hack
+                       if (!m_drums) {
+                               if (ev.button == input::GUITAR_PICK_DOWN || ev.button == input::GUITAR_PICK_UP) { layer = 0; num = 0; }
+                               else ++num;
+                       }
+                       // Update key pressed status
+                       if (layer < 8 && num < max_panels) {
+                               if (!m_drums && num > 0) m_pressed[num] = ev.value; // Only guitar frets can be held
+                               if (ev.pressed()) m_pressed_anim[num].setValue(1.0); // Hit flash
+                       }
+               }
+               m_dead = 0; // Keep alive
+               // Menu keys
+               if (menuOpen()) {
+                       // Check first regular keys
+                       if (ev.pressed()) {
+                               if (ev.nav == input::NAV_START) m_menu.action();
+                               else if (ev.nav == input::NAV_LEFT) m_menu.action(-1);
+                               else if (ev.nav == input::NAV_UP) m_menu.move(-1);
+                               else if (ev.nav == input::NAV_DOWN) m_menu.move(1);
+                               else if (ev.nav == input::NAV_RIGHT) m_menu.action(1);
+                               else if (ev.nav == input::NAV_CANCEL) m_menu.close();
+                               if (!m_drums) {
+                                       if (ev.button == input::GUITAR_GREEN) m_menu.action(-1);
+                                       else if (ev.button == input::GUITAR_RED) m_menu.action(1);
+                               }
+                       }
+                       // See if anything changed
+                       if (!m_drums && m_selectedTrack.so() != m_track_index->first) setTrack(m_selectedTrack.so());
+                       else if (boost::lexical_cast<int>(m_selectedDifficulty.so()) != m_level)
+                               difficulty(Difficulty(boost::lexical_cast<int>(m_selectedDifficulty.so())));
+                       else if (m_rejoin.b()) { unjoin(); setupJoinMenu(); m_dev->pushEvent(input::Event()); /* FIXME: HACK! */ }
+                       // Sync menu items & captions
+                       updateJoinMenu();
+                       break;
+
+               // If the songs hasn't yet started, we want key presses to bring join menu back (not pause menu)
+               } else if (time < -2 && ev.pressed() && ev.button != input::GUITAR_WHAMMY && ev.button != input::GUITAR_GODMODE) {
+                       setupJoinMenu();
+                       m_menu.open();
+                       break;
+               // Handle Start/Select keypresses
+               } else if (!isKeyboard()) {
+                       if (ev.button == input::GENERIC_CANCEL) ev.button = input::GUITAR_GODMODE; // Select = GodMode
+                       if (ev.button == input::GENERIC_START) { m_menu.open(); continue; }
+               }
+
+               // Disable gameplay when game is paused
+               if (m_audio.isPaused()) continue;
+
+               // Guitar specific actions
+               if (!m_drums) {
+                       if (ev.button == input::GUITAR_GODMODE && ev.pressed()) activateStarpower();
+                       if (ev.button == input::GUITAR_WHAMMY) m_whammy = (1.0 + ev.value + 2.0*(rand()/double(RAND_MAX))) / 4.0;
+                       if (ev.button <= m_pads && !ev.pressed()) endHold(ev.button, time);
+               }
+
+               // Playing
+               if (m_drums) {
+                       if (ev.pressed() && ev.button.layer() < 8 && ev.button.num() < m_pads) drumHit(time, ev.button.num());
+               } else {
+                       guitarPlay(time, ev);
+               }
+               if (m_score < 0) m_score = 0;
+       }
+       // Handle fret hold markers
+       if (!m_drums) for (unsigned num = 0; num < max_panels; ++num) m_pressed_anim[num].setTarget(m_pressed[num] ? 1.0 : 0.0);
+
+       // Skip missed chords
+       // - Only after we are so much past them that they can no longer be played (maxTolerance)
+       // - For chords played or skipped by playing (i.e. play another chord that quickly follows), ++m_chordIt is done elsewhere
+       while (m_chordIt != m_chords.end() && m_chordIt->begin + maxTolerance < time) {
+               if (m_chordIt->status < m_chordIt->polyphony) endStreak();
+               // Calculate solo total score
+               if (m_solo) { m_soloScore += m_chordIt->score; m_soloTotal += m_chordIt->polyphony * points(0);
+               // Solo just ended?
+               } else if (m_soloTotal > 0) {
+                       m_popups.push_back(Popup(boost::lexical_cast<std::string>(unsigned(m_soloScore / m_soloTotal * 100)) + " %",
+                         Color(0.0, 0.8, 0.0), 1.0, m_popupText.get()));
+                       m_soloScore = 0;
+                       m_soloTotal = 0;
+               }
+               if (!joining(time)) ++m_dead;  // Increment dead counter (but not while joining)
+               ++m_chordIt;
+       }
+       // Start decreasing correctness instantly if the current note is being played late (don't wait until maxTolerance)
+       if (m_chordIt != m_chords.end() && m_chordIt->begin < time && m_chordIt->status == 0) m_correctness.setTarget(0.0);
+       // Process holds
+       if (!m_drums) {
+               // FIXME: Why do we have per-fret hold handling, why not just as a part of the current chord?
+               // FIXME: Use polyphony from proper chord (which isn't always m_chordIt); now it only counts frets currently held
+               unsigned count = 0, polyphony = 0;
+               bool holds = false;
+               for (unsigned fret = 0; fret < m_pads; ++fret) {
+                       if (!m_holds[fret]) continue;
+                       holds = true;
+                       ++polyphony;
+                       Event& ev = m_events[m_holds[fret] - 1];
+                       ev.glow.setTarget(1.0, true);
+                       // Whammy animvalue mangling
+                       ev.whammy.setTarget(m_whammy);
+                       if (m_whammy > 0) {
+                               ev.whammy.move(0.5);
+                               if (ev.whammy.get() > 1.0) ev.whammy.setValue(1.0);
+                       }
+                       // Calculate how long the note was held this cycle and score it
+                       double last = std::min(time, ev.dur->end);
+                       double t = last - ev.holdTime;
+                       if (t < 0) continue;  // FIXME: What is this for, rewinding?
+                       // Is the hold being played correctly?
+                       bool early = time - ev.dur->begin < 1.5;  // At the beginning we don't require whammy
+                       bool whammy = ev.whammy.get() > 0.01;
+                       bool godmode = m_starpower.get() > 0.01;
+                       if (early || whammy || godmode) ++count;
+                       // Score for holding
+                       m_score += t * 50.0 * m_correctness.get();
+                       // Whammy fills starmeter much faster
+                       m_starmeter += t * 50 * ( (ev.whammy.get() > 0.01) ? 2.0 : 1.0 );
+                       ev.holdTime = time;
+                       // If end reached, handle it
+                       if (last == ev.dur->end) endHold(fret, time);
+               }
+               // Set correctness as a percentage of chord being held
+               if (holds) m_correctness.setTarget(clamp(double(count) / m_chordIt->polyphony));  // FIXME: polyphony doesn't seem to be set correctly for guitar tracks (workaround by clamping)
+       }
+       // Update solo status
+       m_solo = false;
+       for (Durations::const_iterator it = m_solos.begin(); it != m_solos.end(); ++it) {
+               if (time >= it->begin && time <= it->end) { m_solo = true; break; }
+       }
+       // Check if a long streak goal has been reached (display a nasty combo breaker popup)
+       if (m_streak >= getNextBigStreak(m_bigStreak)) {
+               m_bigStreak = getNextBigStreak(m_bigStreak);
+               m_starmeter += streakStarBonus;
+               m_popups.push_back(Popup(boost::lexical_cast<std::string>(unsigned(m_bigStreak)) + "\n" + _("Streak!"),
+                 Color(1.0, 0.0, 0.0), 1.0, m_popupText.get()));
+       }
+       // During GodMode, correctness is full, no matter what
+       if (m_starpower.get() > 0.01) m_correctness.setTarget(1.0, true);
+}
+
+/// Attempt to activate GodMode
+void GuitarGraph::activateStarpower() {
+       if (canActivateStarpower()) {
+               m_starmeter = 0;
+               m_starpower.setValue(1.0);
+               m_popups.push_back(Popup(_("God Mode\nActivated!"),
+                 Color(0.3, 0.0, 1.0), 0.666, m_popupText.get(), _("Mistakes ignored!"), &m_text));
+       }
+}
+
+/// New hit for the error indicator
+void GuitarGraph::errorMeter(float error) {
+       error /=  maxTolerance;
+       m_errorMeter.setTarget(error, true);
+       m_errorMeterFade.setValue(1.0);
+       if (std::abs(error) < 0.10) m_errorMeterFlash.setValue(1.0);
+}
+
+/// Mark the holding of a note as ended
+void GuitarGraph::endHold(unsigned fret, double time) {
+       if (fret >= m_pads || !m_holds[fret]) return;
+       m_events[m_holds[fret] - 1].glow.setTarget(0.0);
+       m_events[m_holds[fret] - 1].whammy.setTarget(0.0, true);
+       m_holds[fret] = 0;
+       if (time > 0) { // Do we set the releaseTime?
+               // Search for the Chord this hold belongs to
+               for (auto& chord: m_chords) {
+                       if (time > chord.begin + maxTolerance && time < chord.end - maxTolerance) {
+                               chord.releaseTimes[fret] = time;
+                               if (time >= chord.end - maxTolerance) chord.passed = true; // Mark as past note for rewinding
+                               else m_correctness.setValue(0.0);  // Note: if still holding some frets, proper percentage will be set in hold handling
+                               break;
+                       }
+               }
+       }
+}
+
+/// Do stuff when a note is played incorrectly
+void GuitarGraph::fail(double time, int fret) {
+       if (fret == -2) return; // Tapped note
+       if (fret == -1) {
+               for (unsigned i = 0; i < m_pads; ++i) endHold(i, time);
+       }
+       if (m_starpower.get() < 0.01) {
+               // Reduce points and play fail sample only when GodMode is deactivated
+               m_events.push_back(Event(time, 0, fret));
+               if (fret < 0) fret = std::rand();
+               m_audio.playSample(m_samples[unsigned(fret) % m_samples.size()]);
+               // remove equivalent of 1 perfect hit for every note
+               // kids tend to play a lot of extra notes just for the fun of it.
+               // need to make sure they don't end up with a score of zero
+               m_score -= (m_level == DIFFICULTY_KIDS) ? points(0)/2.0 : points(0);
+               m_correctness.setTarget(0.0, true);  // Instantly fail correctness
+       }
+       endStreak();
+}
+
+/// Ends the Big Rock Ending and gives score if appropriate
+void GuitarGraph::endBRE() {
+       float l = m_dfIt->end - m_dfIt->begin;
+       // Completion requires ~ 6 hits per second
+       if (m_drumfillHits / l >= 6.0) {
+               m_score += m_drumfillScore; // Add score from overlapped notes if there were any
+               m_score += 50.0 * l; // Add score as if it were a single long hold
+       }
+       m_drumfillHits = 0;
+       m_drumfillScore = 0;
+       m_dfIt = m_drumfills.end();
+}
+
+/// Calculates the start and end times for the next/current drum fill
+/// Also activates GodMode if fill went well
+void GuitarGraph::updateDrumFill(double time) {
+       // Check if fill is over
+       if (m_dfIt != m_drumfills.end()) {
+               // Reset stuff for drum fills but not for BREs (handled elsewhere)
+               if (time > m_dfIt->end - past && (m_dfIt != (--m_drumfills.end()) || (m_drums && !m_song.hasBRE))) {
+                       m_drumfillHits = 0;
+                       m_drumfillScore = 0;
+                       m_dfIt = m_drumfills.end();
+               }
+               return;
+       } else if (m_drums && canActivateStarpower()) {
+               // Search for the next drum fill
+               for (Durations::const_iterator it = m_drumfills.begin(); it != m_drumfills.end(); ++it) {
+                       if (it->begin >= time + future) { m_dfIt = it; return; }
+               }
+       } else if (!m_drums && m_drumfills.back().begin >= time + future) {
+               m_dfIt = (--m_drumfills.end()); return; // Guitar Big Rock Ending
+       } else if (m_drums && m_song.hasBRE && m_drumfills.back().begin <= time + future) {
+               m_dfIt = (--m_drumfills.end()); return; // Drum Big Rock Ending
+       }
+       m_dfIt = m_drumfills.end(); // Reset iterator
+}
+
+/// Handle drum hit scoring
+void GuitarGraph::drumHit(double time, unsigned fret) {
+       // Handle drum fills
+       if (m_dfIt != m_drumfills.end() && time >= m_dfIt->begin - maxTolerance
+         && time <= m_dfIt->end + maxTolerance) {
+               m_drumfillHits += 1;
+               // Check if we hit the final note in drum fill to activate starpower and get the points
+               if (fret == 4 && time >= m_dfIt->end - maxTolerance
+                 && (!m_song.hasBRE || m_dfIt != (--m_drumfills.end()))) {
+                       // GodMode and scores require ~ 6 hits per second
+                       if (m_drumfillHits >= drumfill_min_rate * (m_dfIt->end - m_dfIt->begin)) {
+                               activateStarpower();
+                               m_score += m_drumfillScore;
+                       }
+                       m_drumfillScore = 0;
+                       m_drumfillHits = 0;
+               }
+               m_flames[fret].push_back(AnimValue(0.0, flameSpd));
+               m_flames[fret].back().setTarget(1.0);
+               return;
+       }
+       // Find any suitable note within the tolerance
+       double tolerance = maxTolerance;
+       double signed_error = maxTolerance;
+       auto best = m_chords.end();
+       // when we get here m_chordIt points to the last best fit chord
+       for (auto it = m_chordIt; it != m_chords.end() && it->begin <= time + tolerance; ++it) {
+               // it->dur[fret]          == NULL for a chord that doesn't include the fret played (pad hit)
+               // m_notes[it->dur[fret]] != 0    when the fret played (pad hit) was already played
+               if (m_level == DIFFICULTY_KIDS) {
+                       // in kiddy mode we don't care about the correct pad
+                       // all that matters is that there is still a missing note in that chord
+                       if (m_chordIt->status == m_chordIt->polyphony) continue;
+               } else if (m_notes[it->dur[fret]]) continue;  // invalid fret/hit or already played
+
+               double error = std::abs(it->begin - time);
+               if (error < tolerance) {
+                       best = it;
+                       tolerance = error;
+                       signed_error = it->begin - time;
+               }
+       }
+       if (best == m_chords.end()) fail(time, fret);  // None found
+       else {
+               // Skip all chords earlier than the best fit chord
+               for (; best != m_chordIt; ++m_chordIt) {
+                       // End streak if skipped chords had not been played properly
+                       if (m_chordIt->status < m_chordIt->polyphony) endStreak();
+               }
+               ++m_chordIt->status;  // One more drum belonging to the chord hit
+               double percentage = clamp(double(m_chordIt->status) / m_chordIt->polyphony); // FIXME: clamping should not be necessary but polyphony seems incorrect
+               m_correctness.setTarget(1.0, true);  // Instantly correct
+               m_correctness.setTarget(percentage);  // ... but keep fading if chord is incomplete
+               Duration const* dur = m_chordIt->dur[fret];
+               // Record the hit event
+               m_events.push_back(Event(time, 1, fret, dur));
+               m_notes[dur] = m_events.size();
+               // Scoring - be a little more generous for kids
+               double score = (m_level == DIFFICULTY_KIDS) ? points(tolerance/2.0) : points(tolerance);
+               m_chordIt->score += score;
+               m_score += score;
+               if (!m_drumfills.empty()) m_starmeter += score; // Only add starmeter if it's possible to activate GodMode
+               // Graphical effects
+               m_flames[fret].push_back(AnimValue(0.0, flameSpd));
+               m_flames[fret].back().setTarget(1.0);
+               if (fret == input::DRUMS_KICK) m_drumJump.setTarget(1.0); // Do a jump for bass drum
+               // All drums of the chord hit already?
+               if (m_chordIt->status == m_chordIt->polyphony) {
+                       //m_score -= m_chordIt->score;
+                       //m_chordIt->score *= m_chordIt->polyphony;
+                       //m_score += m_chordIt->score;
+                       m_streak += 1;
+                       if (m_streak > m_longestStreak) m_longestStreak = m_streak;
+                       // Handle Big Rock Ending scoring
+                       if (m_drumfillHits > 0 && *best == m_chords.back()) endBRE();
+                       // ErrorMeter
+                       errorMeter(signed_error);
+               }
+       }
+}
+
+/// Handle guitar events and scoring
+void GuitarGraph::guitarPlay(double time, input::Event const& ev) {
+       bool picked = (ev.button == input::GUITAR_PICK_UP || ev.button == input::GUITAR_PICK_DOWN) && ev.pressed();
+       // Handle Big Rock Ending
+       if (m_dfIt != m_drumfills.end() && time >= m_dfIt->begin - maxTolerance
+         && time <= m_dfIt->end + maxTolerance) {
+               if (!ev.pressed() || ev.button >= m_pads) return;  // No processing for release events or non-fret buttons
+               m_drumfillHits += 1;
+               m_flames[ev.button].push_back(AnimValue(0.0, flameSpd));
+               m_flames[ev.button].back().setTarget(1.0);
+               return;
+       }
+       bool frets[max_panels];  // The combination about to be played
+       if (picked) {
+               for (unsigned fret = 0; fret < m_pads; ++fret) {
+                       frets[fret] = m_pressed[fret + 1];
+               }
+       } else { // Attempt to tap
+               if (ev.button >= m_pads) return;
+               if (m_correctness.get() < 0.5 && m_starpower.get() < 0.001) return; // Hammering not possible at the moment
+               for (unsigned fret = 0; fret < m_pads; ++fret) frets[fret] = false;
+               for (unsigned fret = ev.button + 1; fret < m_pads; ++fret) {
+                       if (frets[fret]) return; // Extra buttons on right side
+               }
+               if (ev.pressed()) {
+                       // Hammer-on, the fret pressed is played
+                       frets[ev.button] = true;
+               } else {
+                       // Pull off, find the note to played that way
+                       int fret = ev.button;
+                       do {
+                               if (--fret < 0) return; // No frets pressed -> not a pull off
+                       } while (!frets[fret]);
+                       frets[fret] = true;
+               }
+       }
+       // Find any suitable note within the tolerance
+       double tolerance = maxTolerance;
+       double signed_error = maxTolerance;
+       auto best = m_chords.end();
+       for (auto it = m_chordIt; it != m_chords.end() && it->begin <= time + tolerance; ++it) {
+               if (it->status > 1) continue; // Already picked, can't play again
+               if (!picked) { // Tapping rules
+                       if (it->status > 0) continue; // Already tapped, can't tap again
+                       if (!it->tappable) continue; // Cannot tap
+                       auto tmp = it;
+                       if ( (tmp == m_chords.begin() || (--tmp)->status == 0) &&
+                         m_starpower.get() < 0.001) continue; // The previous note not played
+               }
+               if (!it->matches(frets)) continue;
+               double error = std::abs(it->begin - time);
+               if (error < tolerance) {
+                       best = it;
+                       tolerance = error;
+                       signed_error = it->begin - time;
+               }
+       }
+       if (best == m_chords.end()) fail(time, picked ? -1 : -2);
+       else { // Correctly hit
+               m_chordIt = best;
+               int& score = m_chordIt->score;
+               m_score -= score;
+               m_starmeter -= score;
+               bool first_time = (score == 0 ? true : false);
+               if (first_time) m_streak++;
+               if (m_streak > m_longestStreak) m_longestStreak = m_streak;
+               score = points(tolerance);
+               score *= m_chordIt->polyphony;
+               m_chordIt->status = 1 + picked;
+               m_score += score;
+               m_starmeter += score;
+               m_correctness.setTarget(1.0, true); // Instantly go to one
+               errorMeter(signed_error);
+               for (unsigned fret = 0; fret < m_pads; ++fret) {
+                       if (!m_chordIt->fret[fret]) continue;
+                       Duration const* dur = m_chordIt->dur[fret];
+                       m_events.push_back(Event(time, 1 + picked, fret, dur));
+                       m_notes[dur] = m_events.size();
+                       m_holds[fret] = m_events.size();
+                       if (first_time) {
+                               m_flames[fret].push_back(AnimValue(0.0, flameSpd));
+                               m_flames[fret].back().setTarget(1.0);
+                       }
+               }
+               // Handle Big Rock Ending scoring
+               if (m_drumfillHits > 0 && *best == m_chords.back()) endBRE();
+       }
+}
+
+/// Modify color based on things like GodMode and solos
+Color const GuitarGraph::colorize(Color c, double time) const {
+       const static Color godmodeC(0.5f, 0.5f, 1.0f); // Color for full GodMode
+       const static Color soloC(0.2f, 0.9f, 0.2f); // Color for solo notes
+       // Solo? (cannot use m_solo, as time can be in future)
+       for (auto const& solo: m_solos) {
+               if (time >= solo.begin && time <= solo.end) { c = soloC; break; }
+       }
+       double f = m_starpower.get();
+       if (f < 0.001) return c;
+       f = std::sqrt(std::sqrt(f));
+       c.r = blend(godmodeC.r, c.r, f);
+       c.g = blend(godmodeC.g, c.g, f);
+       c.b = blend(godmodeC.b, c.b, f);
+       return c;
+}
+
+namespace {
+       const float fretWid = 0.5f; // The actual width is two times this
+
+       /// Create a symmetric vertex pair of given data
+       void vertexPair(glutil::VertexArray& va, float x, float y, Color color, float ty, float fretW = fretWid, float zn = 0.0) {
+               color.a = y2a(y);
+               {
+                       glmath::vec4 c(color.r, color.g, color.b, color.a);
+                       va.color(c).texCoord(0.0f, ty).vertex(x - fretW, y, 0.1 + zn);
+                       va.color(c).texCoord(1.0f, ty).vertex(x + fretW, y, 0.1 - zn);
+               }
+       }
+
+}
+
+void GuitarGraph::drawNotes(double time) {
+       glutil::UseDepthTest depthtest;
+       // Draw drum fills / Big Rock Endings
+       bool drumfill = m_dfIt != m_drumfills.end() && m_dfIt->begin - time <= future;
+       if (drumfill) {
+               drawDrumfill(m_dfIt->begin - time, m_dfIt->end - time);
+               // If it is a drum fill (not BRE), draw the final note
+               if (m_drums && (!m_song.hasBRE || (m_dfIt != (--m_drumfills.end())))) {
+                       Color c(0.7f, 0.7f, 0.7f);
+                       if (m_drumfillHits >= drumfill_min_rate * (m_dfIt->end - m_dfIt->begin))
+                               c = colorize(color(4), m_dfIt->end);
+                       drawNote(4, c, m_dfIt->end - time, m_dfIt->end - time, 0, false, false, 0, 0);
+               }
+       }
+       if (time != time) return;  // Check that time is not NaN
+       
+       glmath::vec4 neckglow;  // Used for calculating the average neck color
+       
+       // Iterate chords
+       for (auto& chord: m_chords) {
+               float tBeg = chord.begin - time;
+               float tEnd = m_drums ? tBeg : chord.end - time;
+               if (tBeg > future) break;
+               if (tEnd < past) {
+                       chord.passed = true; // Mark as past note for rewinding
+                       continue;
+               }
+               // Don't show past chords when rewinding
+               if (chord.passed || (tBeg > maxTolerance && chord.status > 0)) continue;
+               // Handle notes during drum fills / BREs
+               if (drumfill && chord.begin >= m_dfIt->begin - maxTolerance
+                 && chord.begin <= m_dfIt->end + maxTolerance) {
+                       if (chord.status == 0) {
+                               chord.status = chord.polyphony; // Mark as hit so that streak doesn't reset
+                               m_drumfillScore += chord.polyphony * 50.0; // Count points from notes under drum fill
+                       }
+                       continue;
+               }
+               // Loop through the frets
+               for (unsigned fret = 0; fret < m_pads; ++fret) {
+                       if (!chord.fret[fret] || (tBeg > maxTolerance && chord.releaseTimes[fret] > 0)) continue;
+                       if (tEnd > future) tEnd = future;
+                       unsigned event = m_notes[chord.dur[fret]];
+                       float glow = 0.0f;
+                       float whammy = 0.0f;
+                       if (event > 0) {
+                               glow = m_events[event - 1].glow.get();
+                               whammy = m_events[event - 1].whammy.get();
+                       }
+                       // Set the default color (disabled state)
+                       Color c(0.5f, 0.5f, 0.5f);
+                       if (!joining(time)) {
+                               // Get a color for the fret and adjust it if GodMode is on
+                               c = colorize(color(fret), chord.begin);
+                               if (glow > 0.1f) { neckglow = neckglow + glmath::vec4(c.r, c.g, c.b, 1.0); } // neck glow tracking
+                               // Further adjust the color if the note is hit
+                               c.r += glow * 0.2f;
+                               c.g += glow * 0.2f;
+                               c.b += glow * 0.2f;
+                       }
+                       if (glow > 0.5f && tEnd < 0.1f && chord.hitAnim[fret].get() == 0.0) chord.hitAnim[fret].setTarget(1.0);
+                       // Call the actual note drawing function
+                       bool tap = m_drums ? chord.fret_cymbal[fret] : chord.tappable;
+                       drawNote(fret, c, tBeg, tEnd, whammy, tap, glow > 0.5f, chord.hitAnim[fret].get(),
+                         chord.releaseTimes[fret] > 0.0 ? chord.releaseTimes[fret] - time : getNaN());
+               }
+       }
+       // Mangle neck glow color as needed
+       // Convert sum into average and apply correctness as premultiplied alpha
+       if (neckglow.w > 0.0) neckglow = (correctness() / neckglow.w) * neckglow;
+       // Blend into use slowly
+       m_neckglowColor = glmath::mix(m_neckglowColor, neckglow, 0.05);
+}
+
+double GuitarGraph::neckWidth() const { return std::min(0.5, m_width.get()); }
+
+void GuitarGraph::drawNeckStuff(double time) {
+       using namespace glmath;
+       mat4 m = translate(vec3(0.0f, 0.5 * virtH(), 0.0f)) * rotate(g_angle, vec3(1.0f, 0.0f, 0.0f)) * scale(neckWidth() / 5.0f);
+       // Do some jumping for drums
+       if (m_drums) {
+               float jumpanim = m_drumJump.get();
+               if (jumpanim == 1.0) m_drumJump.setTarget(0.0);
+               if (jumpanim > 0) m = translate(vec3(0.0f, -m_drumJump.get() * 0.01, 0.0f)) * m;
+       }
+       //Transform trans(m);
+       ViewTrans trans(m);
+
+       // Draw the neck
+       {
+               UseTexture tex(*m_neck);
+               glutil::VertexArray va;
+               float w = (m_drums ? 2.0f : 2.5f);
+               float texCoord = 0.0f;
+               float tBeg = 0.0f, tEnd;
+               for (auto it = m_song.beats.begin(); it != m_song.beats.end() && tBeg < future; ++it, texCoord += texCoordStep, tBeg = tEnd) {
+                       tEnd = *it - time;
+                       //if (tEnd < past) continue;
+                       if (tEnd > future) {
+                               // Crop the end off
+                               texCoord -= texCoordStep * (tEnd - future) / (tEnd - tBeg);
+                               tEnd = future;
+                       }
+                       glmath::vec4 c = colorize(Color::alpha(time2a(tEnd)), time + tBeg).linear();
+                       va.normal(0.0f, 1.0f, 0.0f).color(c).texCoord(0.0f, texCoord).vertex(-w, time2y(tEnd));
+                       va.normal(0.0f, 1.0f, 0.0f).color(c).texCoord(1.0f, texCoord).vertex(w, time2y(tEnd));
+               }
+               va.draw();
+       }
+
+       if (!menuOpen()) {
+               // Draw the cursor
+               {
+                       float level = m_pressed_anim[0].get();
+                       ColorTrans c(Color(level, level, level));
+                       drawBar(0.0, 0.01f);
+               }
+               // Fret buttons on cursor
+               for (unsigned fret = m_drums; fret < m_pads; ++fret) {
+                       float x = getFretX(fret);
+                       float l = m_pressed_anim[fret + !m_drums].get();
+                       // The note head
+                       {
+                               ColorTrans c(colorize(color(fret), time)); // Get a color for the fret and adjust it if GodMode is on
+                               m_button.dimensions.center(time2y(0.0)).middle(x);
+                               m_button.draw();
+                       }
+                       // Tap note indicator
+                       {
+                               ColorTrans c(Color(l, l, l));
+                               m_tap.dimensions = m_button.dimensions;
+                               m_tap.draw();
+                       }
+               }
+       }
+
+       drawNotes(time);
+
+       // Draw flames
+       for (unsigned fret = 0; fret < m_pads; ++fret) { // Loop through the frets
+               if (m_drums && fret == input::DRUMS_KICK) { // Skip bass drum
+                       m_flames[fret].clear(); continue;
+               }
+               Texture* ftex = &m_flame;
+               if (m_starpower.get() > 0.01) ftex = &m_flame_godmode;
+               float x = getFretX(fret);
+               for (auto it = m_flames[fret].begin(); it != m_flames[fret].end();) {
+                       float flameAnim = it->get();
+                       if (flameAnim == 1.0) {
+                               it = m_flames[fret].erase(it);
+                               continue;
+                       }
+                       float h = flameAnim * 4.0f * fretWid;
+                       UseTexture tblock(*ftex);
+                       glutil::VertexArray va;
+                       glmath::vec4 c(1.0, 1.0, 1.0, 1.0 - flameAnim);
+                       va.texCoord(0.0f, 1.0f).color(c).vertex(x - fretWid, time2y(0.0f), 0.0f);
+                       va.texCoord(1.0f, 1.0f).color(c).vertex(x + fretWid, time2y(0.0f), 0.0f);
+                       va.texCoord(0.0f, 0.0f).color(c).vertex(x - fretWid, time2y(0.0f), h);
+                       va.texCoord(1.0f, 0.0f).color(c).vertex(x + fretWid, time2y(0.0f), h);
+                       va.draw();
+                       ++it;
+               }
+       }
+       // Accuracy indicator
+       UseShader us(getShader("color"));
+       float maxsize = 1.5f;
+       float thickness = 0.12f;
+       float x = -2.5 - thickness;
+       float y = time2y(0.0);
+       float alpha = m_errorMeterFade.get();
+       float bgcol = m_errorMeterFlash.get();
+       // Indicator background
+       {
+               glmath::vec4 c(bgcol, bgcol, bgcol, 0.6f * alpha);
+               glutil::VertexArray va;
+               va.color(c).texCoord(0,0).vertex(x - thickness, y + maxsize);
+               va.color(c).texCoord(0,0).vertex(x, y + maxsize);
+               va.color(c).texCoord(0,0).vertex(x - thickness, y - maxsize);
+               va.color(c).texCoord(0,0).vertex(x, y - maxsize);
+               va.draw();
+       }
+       // Indicator bar
+       float error = m_errorMeter.get();
+       if (error != 0) {
+               if (m_errorMeter.get() == m_errorMeter.getTarget()) m_errorMeter.setTarget(0.0);
+               float y1 = 0, y2 = 0;
+               glmath::vec4 c;
+               if (error > 0) { c = glmath::vec4(0.0f, 1.0f, 0.0f, alpha); y2 = -maxsize * error; }
+               else { c = glmath::vec4(1.0f, 0.0f, 0.0f, alpha); y1 = -maxsize * error; }
+               glutil::VertexArray va;
+               va.color(c).texCoord(0,0).vertex(x - thickness, y1 + y);
+               va.color(c).texCoord(0,0).vertex(x, y1 + y);
+               va.color(c).texCoord(0,0).vertex(x - thickness, y2 + y);
+               va.color(c).texCoord(0,0).vertex(x, y2 + y);
+               va.draw();
+       }
+}
+
+/// Main drawing function (projection, neck, cursor...)
+void GuitarGraph::draw(double time) {
+       glutil::GLErrorChecker ec("GuitarGraph::draw");
+       ViewTrans view(m_cx.get(), 0.0, 0.75);  // Apply a per-player local perspective
+
+       drawNeckStuff(time);
+
+       if (m_neckglowColor.w > 0.0) {
+               // Neck glow drawing
+               using namespace glmath;
+               ColorTrans c(glmath::mat4::diagonal(m_neckglowColor));
+               m_neckglow.dimensions.screenBottom(0.0).middle().fixedWidth(neckWidth());
+               m_neckglow.draw();
+       }
+
+       drawInfo(time); // Go draw some texts and other interface stuff
+}
+
+/// Draws a single note
+/// The times passed are normalized to [past, future]
+void GuitarGraph::drawNote(int fret, Color color, float tBeg, float tEnd, float whammy, bool tappable, bool hit, double hitAnim, double releaseTime) {
+       float x = getFretX(fret);
+       if (m_drums && fret == input::DRUMS_KICK) { // Bass drum? That's easy
+               if (hit || hitAnim > 0) return; // Hide it if it's hit
+               color.a = time2a(tBeg);
+               {
+                       ColorTrans c(color);
+                       drawBar(tBeg, 0.015f);
+               }
+               return;
+       }
+       // If the note is hit, limit it to cursor position
+       float yBeg = (hit || hitAnim > 0) ? std::min(time2y(0.0), time2y(tBeg)): time2y(tBeg);
+       float yEnd = time2y(tEnd);
+       // Long notes
+       if (yBeg - 2 * fretWid >= yEnd) {
+               // A hold is released? Let it go...
+               if (releaseTime == releaseTime && tEnd - releaseTime > 0.1) yBeg = time2y(releaseTime);
+               // Short note? Render minimum renderable length
+               if (yEnd > yBeg - 3 * fretWid) yEnd = yBeg - 3 * fretWid;
+               // Skip the fret head
+               float y = yBeg + fretWid;
+               y -= fretWid;
+               float fretY = y;
+               color.a = clamp(time2a(tBeg)*2.0f,0.0f,1.0f);
+               y -= fretWid;
+               // Render the middle
+               bool doanim = hit || hitAnim > 0; // Enable glow?
+               Texture const& tex(doanim ? m_tail_glow : m_tail); // Select texture
+               UseTexture tblock(tex);
+               glutil::VertexArray va;
+               double t = m_audio.getPosition() * 10.0; // Get adjusted time value for animation
+               vertexPair(va, x, y, color, doanim ? tc(y + t) : 1.0f); // First vertex pair
+               while ((y -= fretWid) > yEnd + fretWid) {
+                       if (whammy > 0.1) {
+                               // FIXME: Should use Boost/C++11 random, and use the same seed for both eyes in stereo3d.
+                               float r1 = rand() / double(RAND_MAX) - 0.5;
+                               float r2 = rand() / double(RAND_MAX) - 0.5;
+                               vertexPair(va, x+0.2*(cos(y*whammy)+r1), y, color, tc(y + t), fretWid, 0.1*(sin(y*whammy)+r2));
+                       } else vertexPair(va, x, y, color, doanim ? tc(y + t) : 0.5f);
+               }
+               // Render the end
+               y = yEnd + fretWid;
+               vertexPair(va, x, y, color, doanim ? tc(y + t) : 0.20f);
+               vertexPair(va, x, yEnd, color, doanim ? tc(yEnd + t) : 0.0f);
+               glDisable(GL_DEPTH_TEST);
+               va.draw();
+               glEnable(GL_DEPTH_TEST);
+               // Render the fret object
+               {
+                       ColorTrans c(color);
+                       m_fretObj.draw(x, fretY, 0.0f);
+               }
+       } else {
+               // Too short note: only render the ring
+               if (hitAnim > 0.0 && tEnd <= maxTolerance) {
+                       float s = 1.0 - hitAnim;
+                       color.a = s;
+                       {
+                               ColorTrans c(color);
+                               m_fretObj.draw(x, yBeg, 0.0f, s);
+                       }
+               } else {
+                       color.a = clamp(time2a(tBeg)*2.0f,0.0f,1.0f);
+                       {
+                               ColorTrans c(color);
+                               m_fretObj.draw(x, yBeg, 0.0f);
+                       }
+               }
+       }
+       // Hammer note caps
+       if (tappable) {
+               float l = std::max(0.3, m_correctness.get());
+               float s = 1.0 - hitAnim;
+               ColorTrans c(Color(l, l, l, s));
+               m_tappableObj.draw(x, yBeg, 0.0f, s);
+       }
+}
+
+/// Draws a drum fill
+void GuitarGraph::drawDrumfill(float tBeg, float tEnd) {
+       for (unsigned fret = m_drums; fret < m_pads; ++fret) { // Loop through the frets
+               float x = -2.0f + fret - 0.5f * m_drums;
+               float yBeg = time2y(tBeg);
+               float yEnd = time2y(tEnd <= future ? tEnd : future);
+               float tcEnd = tEnd <= future ? 0.0f : 0.25f;
+               Color c = color(fret);
+               UseTexture tblock(m_tail_drumfill);
+               glutil::VertexArray va;
+               vertexPair(va, x, yBeg, c, 1.0f); // First vertex pair
+               if (std::abs(yEnd - yBeg) > 4.0 * fretWid) {
+                       float y = yBeg - 2.0 * fretWid;
+                       vertexPair(va, x, y, c, 0.75f);
+                       while ((y -= 10.0 * fretWid) > yEnd + 2.0 * fretWid)
+                               vertexPair(va, x, y, c, 0.5f);
+                       vertexPair(va, x, yEnd + 2.0 * fretWid, c, 0.25f);
+               }
+               vertexPair(va, x, yEnd, c, tcEnd); // Last vertex pair
+               va.draw();
+       }
+}
+
+/// Draw popups and other info texts
+void GuitarGraph::drawInfo(double time) {
+       // Draw score/streak counters
+       if (!menuOpen()) {
+               using namespace glmath;
+               Transform trans(translate(vec3(0.0f, 0.0f, -0.5f)));  // Add some depth
+               double w = neckWidth();
+               double xcor = 0.53 * w;
+               double h = 0.15 * w;
+               // Draw scores
+               {
+                       ColorTrans c(Color(0.1, 0.3, 1.0, 0.9));
+                       m_scoreText->render((boost::format("%04d") % getScore()).str());
+                       m_scoreText->dimensions().middle(-xcor).fixedHeight(h).screenBottom(-0.22);
+                       m_scoreText->draw();
+               }
+               // Draw streak counter
+               {
+                       ColorTrans c(Color(0.6, 0.6, 0.7, 0.95));
+                       m_streakText->render(boost::lexical_cast<std::string>(unsigned(m_streak)) + "/"
+                         + boost::lexical_cast<std::string>(unsigned(m_longestStreak)));
+                       m_streakText->dimensions().middle(-xcor).fixedHeight(h*0.75).screenBottom(-0.18);
+                       m_streakText->draw();
+               }
+       }
+       // Status text at the bottom
+       {
+               ColorTrans c(Color::alpha(std::abs(std::fmod(time, 1.0) - 0.5f) * 2.0f));
+               if (canActivateStarpower()) {
+                       m_text.dimensions.screenBottom(-0.02).middle(-0.12);
+                       if (!m_drums) m_text.draw(_("God Mode Ready!"));
+                       else if (m_dfIt != m_drumfills.end() && time >= m_dfIt->begin && time <= m_dfIt->end) m_text.draw(_("Drum Fill!"));
+               } else if (m_solo) {
+                       m_text.dimensions.screenBottom(-0.02).middle(-0.03);
+                       m_text.draw(_("Solo!"));
+               }
+       }
+       drawPopups();
+}
+
+/// Draw a bar for drum bass pedal/note
+void GuitarGraph::drawBar(double time, float h) {
+       UseShader shader(getShader("color"));
+       glutil::VertexArray va;
+
+       va.normal(0.0f, 1.0f, 0.0f).texCoord(0,0).vertex(-2.5f, time2y(time + h));
+       va.normal(0.0f, 1.0f, 0.0f).texCoord(0,0).vertex(2.5f, time2y(time + h));
+       va.normal(0.0f, 1.0f, 0.0f).texCoord(0,0).vertex(-2.5f, time2y(time - h));
+       va.normal(0.0f, 1.0f, 0.0f).texCoord(0,0).vertex(2.5f, time2y(time - h));
+
+       va.draw();
+}
+
+bool GuitarGraph::updateTom(unsigned int tomTrack, unsigned int fretId) {
+       auto tomTrackIt = m_track_index->second->nm.find(tomTrack);
+       if (tomTrackIt == m_track_index->second->nm.end()) return false;  // Track not found
+       auto chordIt = m_chords.begin();
+       for (Duration const& tom: tomTrackIt->second) {
+               // Iterate over chords of the song
+               for (; chordIt != m_chords.end() && chordIt->begin < tom.end; ++chordIt) {
+                       if (!chordIt->fret[fretId]) continue;  // Chord doesn't contain the fret we are looking for
+                       chordIt->fret_cymbal[fretId] = (chordIt->begin < tom.begin);  // If not within tom, it is a cymbal
+               }
+       }
+       return true;
+}
+
+/// Create the Chord structures for the current track/difficulty level
+void GuitarGraph::updateChords() {
+       m_chords.clear(); m_solos.clear(); m_drumfills.clear();
+       m_scoreFactor = 0;
+       NoteMap const& nm = m_track_index->second->nm;
+
+       Durations::size_type pos[5] = {}, size[5] = {};
+       Durations const* durations[5] = {};
+       for (unsigned fret = 0; fret < m_pads; ++fret) {
+               int basepitch = diffv[m_level].basepitch;
+               auto it = nm.find(basepitch + fret);
+               if (it == nm.end()) continue;
+               durations[fret] = &it->second;
+               size[fret] = durations[fret]->size();
+       }
+       double lastEnd = 0.0;
+       const double tapMaxDelay = 0.15;  // Delay from the end of the previous note
+       while (true) {
+               // Find the earliest
+               double t = getInf();
+               for (unsigned fret = 0; fret < m_pads; ++fret) {
+                       if (pos[fret] == size[fret]) continue;
+                       Durations const& dur = *durations[fret];
+                       t = std::min(t, dur[pos[fret]].begin);
+               }
+               // Quit processing if none were left
+               if (t == getInf()) break;
+               // Construct a chord
+               Chord c;
+               c.begin = t;
+               int tapfret = -1;
+               for (unsigned fret = 0; fret < m_pads; ++fret) {
+                       if (pos[fret] == size[fret]) continue;
+                       Durations const& dur = *durations[fret];
+                       Duration const& d = dur[pos[fret]];
+                       if (d.begin > t) continue;
+                       c.end = std::max(c.end, d.end);
+                       c.fret[fret] = true;
+                       c.dur[fret] = &d;
+                       tapfret = fret;
+                       ++c.polyphony;
+                       ++pos[fret];
+                       m_scoreFactor += 50;
+                       if (d.end - d.begin > 0.0) m_scoreFactor += 50.0 * (d.end - d.begin);
+               }
+               // Check if the chord is tappable
+               if (!m_drums && c.polyphony == 1) {
+                       c.tappable = true;
+                       if (m_chords.empty() || m_chords.back().fret[tapfret]) c.tappable = false;
+                       if (lastEnd + tapMaxDelay < t) c.tappable = false;
+               }
+               lastEnd = c.end;
+               m_chords.push_back(c);
+       }
+       m_chordIt = m_chords.begin();
+
+       m_hasTomTrack = false;
+       if(m_drums) {
+               // HiHat/Rack Tom 1 detection
+               m_hasTomTrack = updateTom(110, input::DRUMS_YELLOW) || m_hasTomTrack;
+               // Ride Cymbal/Rack Tom 2 detection
+               m_hasTomTrack = updateTom(111, input::DRUMS_BLUE) || m_hasTomTrack;
+               // Crash Cymbal/Floor Tom detection
+               m_hasTomTrack = updateTom(112, input::DRUMS_GREEN) || m_hasTomTrack;
+       }
+
+       // Solos
+       auto solotrack = nm.find(103); // 103 = Expert Solo - used for every difficulty
+       if (solotrack != nm.end()) {
+               for (auto const& solo: solotrack->second) {
+                       // Require at least 6s length in order to avoid starpower sections
+                       if (solo.end - solo.begin >= 6.0) m_solos.push_back(solo);
+               }
+       }
+       // Drum fills
+       auto dfTrack = nm.find(124); // 124 = drum fills (actually 120-124, but one is enough)
+       if (dfTrack != nm.end()) {
+               m_drumfills = dfTrack->second;
+               // Big Rock Ending scoring (single hold note)
+               if (!m_drums || m_song.hasBRE)
+                       m_scoreFactor += 50.0 * (m_drumfills.back().end - m_drumfills.back().begin);
+       }
+       m_dfIt = m_drumfills.end();
+
+       // Normalize maximum score factor
+       m_scoreFactor = 10000.0 / m_scoreFactor;
+}
diff --git a/game/guitargraph.hh b/game/guitargraph.hh
new file mode 100644 (file)
index 0000000..686f58f
--- /dev/null
@@ -0,0 +1,160 @@
+#pragma once
+
+#include <boost/ptr_container/ptr_map.hpp>
+
+#include "instrumentgraph.hh"
+#include "3dobject.hh"
+
+class Song;
+
+struct Chord {
+       double begin, end;
+       bool fret[5];
+       bool fret_cymbal[5];
+       Duration const* dur[5];
+       int polyphony;
+       bool tappable;
+       bool passed; // Set to true for notes that should not re-appear when rewinding
+       int status; // Guitar: 0 = not played, 1 = tapped, 2 = picked, drums: number of pads hit
+       int score;
+       AnimValue hitAnim[5];
+       double releaseTimes[5];
+       Chord(): begin(), end(), polyphony(), tappable(), passed(), status(), score() {
+               std::fill(fret, fret + 5, false);
+               std::fill(fret_cymbal, fret_cymbal + 5, false);
+               std::fill(dur, dur + 5, static_cast<Duration const*>(NULL));
+               std::fill(hitAnim, hitAnim + 5, AnimValue(0.0, 1.5));
+               std::fill(releaseTimes, releaseTimes + 5, 0.0);
+       }
+       bool matches(bool const* fretPressed) {
+               if (polyphony == 1) {
+                       bool shadowed = true;
+                       for (int i = 0; i < 5; ++i) {
+                               if (fret[i]) shadowed = false;
+                               if (!shadowed && fret[i] != fretPressed[i]) return false;
+                       }
+                       return true;
+               }
+               return std::equal(fret, fret + 5, fretPressed);
+       }
+};
+
+static inline bool operator==(Chord const& a, Chord const& b) {
+       return std::equal(a.fret, a.fret + 5, b.fret);
+}
+
+/// handles drawing of notes and waves
+class GuitarGraph: public InstrumentGraph {
+  public:
+       /// constructor
+       GuitarGraph(Audio& audio, Song const& song, input::DevicePtr dev, int number);
+       /** draws GuitarGraph
+        * @param time at which time to draw
+        */
+       void draw(double time);
+       void engine();
+       std::string getTrack() const;
+       std::string getDifficultyString() const;
+       std::string getModeId() const;
+       void changeTrack(int dir = 1);
+       void changeDifficulty(int dir = 1);
+       double getWhammy() const { return m_whammy; }
+
+  private:
+       // refactoring methods
+       void initDrums();
+       void initGuitar();
+       void setupJoinMenuDifficulty();
+       void setupJoinMenuDrums();
+       void setupJoinMenuGuitar();
+       // Engine / scoring utils
+       void updateNeck();
+       bool canActivateStarpower() { return (m_starmeter > 6000); }
+       void activateStarpower();
+       void errorMeter(float error);
+       void fail(double time, int fret);
+       void endHold(unsigned fret, double time = 0.0);
+       void endBRE();
+       void endStreak() { m_streak = 0; m_bigStreak = 0; }
+       void updateDrumFill(double time);
+       void drumHit(double time, unsigned pad);
+       void guitarPlay(double time, input::Event const& ev);
+
+       // Media
+       Texture m_tail;
+       Texture m_tail_glow;
+       Texture m_tail_drumfill;
+       Texture m_flame;
+       Texture m_flame_godmode;
+       Surface m_tap; /// image for 2d HOPO note cap
+       Surface m_neckglow; /// image for the glow from the bottom of the neck
+       glmath::vec4 m_neckglowColor;
+       Object3d m_fretObj; /// 3d object for regular note
+       Object3d m_tappableObj; /// 3d object for the HOPO note cap
+       std::vector<std::string> m_samples; /// sound effects
+       boost::scoped_ptr<Texture> m_neck; /// necks
+       boost::scoped_ptr<SvgTxtThemeSimple> m_scoreText;
+       boost::scoped_ptr<SvgTxtThemeSimple> m_streakText;
+
+       // Flags
+       bool m_drums; /// are we using drums?
+
+       // Track stuff
+       enum Difficulty {
+               DIFFICULTY_KIDS,     // Kids
+               DIFFICULTY_SUPAEASY, // Easy
+               DIFFICULTY_EASY,     // Medium
+               DIFFICULTY_MEDIUM,   // Hard
+               DIFFICULTY_AMAZING,  // Expert
+               DIFFICULTYCOUNT
+       } m_level;
+       void setupJoinMenu();
+       void updateJoinMenu();
+       void nextTrack(bool fast = false);
+       void setTrack(const std::string& track);
+       void difficultyAuto(bool tryKeepCurrent = false);
+       bool difficulty(Difficulty level, bool check_only = false);
+       InstrumentTracksConstPtr m_instrumentTracks; /// tracks
+       InstrumentTracksConstPtr::const_iterator m_track_index;
+       unsigned m_holds[max_panels]; /// active hold notes
+
+       // Graphics functions
+       Color const colorize(Color c, double time) const;
+       void drawNeckStuff(double time);  ///< Anything in neck coordinates
+       void drawNotes(double time);  ///< Frets etc.
+       void drawBar(double time, float h);
+       void drawNote(int fret, Color, float tBeg, float tEnd, float whammy = 0, bool tappable = false, bool hit = false, double hitAnim = 0.0, double releaseTime = 0.0);
+       void drawDrumfill(float tBeg, float tEnd);
+       void drawInfo(double time);
+       float getFretX(int fret) { return (-2.0f + fret- (m_drums ? 0.5 : 0)) * (m_leftymode.b() ? -1 : 1); }
+       double neckWidth() const; ///< Get the currently effective neck width (0.5 or less)
+       // Chords & notes
+       void updateChords();
+       bool updateTom(unsigned int tomTrack, unsigned int fretId); // returns true if this tom track exists
+       double getNotesBeginTime() const { return m_chords.front().begin; }
+       typedef std::vector<Chord> Chords;
+       Chords m_chords;
+       Chords::iterator m_chordIt;
+       typedef std::map<Duration const*, unsigned> NoteStatus; // Note in song to m_events[unsigned - 1] or 0 for not played
+       NoteStatus m_notes;
+       std::vector<Duration> m_solos; /// holds guitar solos
+       std::vector<Duration> m_drumfills; /// holds drum fills (used for activating GodMode)
+       Durations::const_iterator m_dfIt; /// current drum fill
+
+       // Animation & misc score keeping
+       std::vector<AnimValue> m_flames[max_panels]; /// flame effect queues for each fret
+       AnimValue m_errorMeter;
+       AnimValue m_errorMeterFlash;
+       AnimValue m_errorMeterFade;
+       AnimValue m_drumJump;
+       AnimValue m_starpower; /// how long the GodMode lasts (also used in fading the effect)
+       double m_starmeter; /// when this is high enough, GodMode becomes available
+       double m_drumfillHits; /// keeps track that enough hits are scored
+       double m_drumfillScore; /// max score for the notes under drum fill
+       double m_soloTotal; /// maximum solo score
+       double m_soloScore; /// score during solo
+       bool m_solo; /// are we currently playing a solo
+       bool m_hasTomTrack; /// true if the track has at least one tom track
+       double m_whammy; /// whammy value for pitch shift
+};
+
diff --git a/game/hiscore.cc b/game/hiscore.cc
new file mode 100644 (file)
index 0000000..a82af35
--- /dev/null
@@ -0,0 +1,74 @@
+#include "hiscore.hh"
+
+#include <algorithm>
+#include <sstream>
+#include <stdexcept>
+#include <boost/lexical_cast.hpp>
+#include <libxml++/libxml++.h>
+
+bool Hiscore::reachedHiscore(unsigned score, unsigned songid, std::string const& track) const {
+       if (score > 10000) throw std::logic_error("Invalid score value");
+       if (score < 2000) return false; // come on, did you even try to sing?
+
+       unsigned position = 0;
+       for (auto const& elem: m_hiscore) {
+               if (elem.songid != songid) continue;
+               if (elem.track != track) continue;
+               if (score > elem.score) return true; // seems like you are in top 3!
+               if (++position == 3) return false; // not in top 3 -> leave
+       }
+       return true; // nothing found for that song -> true
+}
+
+void Hiscore::addHiscore(unsigned score, unsigned playerid, unsigned songid, std::string const& track) {
+       if (track.empty()) throw std::runtime_error("No track given");
+       if (!reachedHiscore(score, songid, track)) return;
+       m_hiscore.insert(HiscoreItem(score, playerid, songid, track));
+}
+
+Hiscore::HiscoreVector Hiscore::queryHiscore(unsigned max, unsigned playerid, unsigned songid, std::string const& track) const {
+       HiscoreVector hv;
+       for (auto const& h: m_hiscore) {
+               if (playerid != unsigned(-1) && playerid != h.playerid) continue;
+               if (songid != unsigned(-1) && songid != h.songid) continue;
+               if (!track.empty() && track != h.track) continue;
+               if (--max == 0) break;
+               hv.push_back(h);
+       }
+       return hv;
+}
+
+bool Hiscore::hasHiscore(unsigned songid) const {
+       for (auto const& h: m_hiscore) if (songid == h.songid) return true;
+       return false;
+}
+
+void Hiscore::load(xmlpp::NodeSet const& nodes) {
+       for (auto const& n: nodes) {
+               xmlpp::Element& element = dynamic_cast<xmlpp::Element&>(*n);
+               xmlpp::Attribute* a_playerid = element.get_attribute("playerid");
+               if (!a_playerid) throw std::runtime_error("Attribute playerid not found");
+               xmlpp::Attribute* a_songid = element.get_attribute("songid");
+               if (!a_songid) throw std::runtime_error("Attribute songid not found");
+               xmlpp::Attribute* a_track = element.get_attribute("track");
+
+               int playerid = boost::lexical_cast<int>(a_playerid->get_value());
+               int songid = boost::lexical_cast<int>(a_songid->get_value());
+
+               xmlpp::TextNode* tn = element.get_child_text();
+               if (!tn) throw std::runtime_error("Score not found");
+               int score = boost::lexical_cast<int>(tn->get_content());
+
+               addHiscore(score, playerid, songid, a_track ? a_track->get_value() : "vocals");
+       }
+}
+
+void Hiscore::save(xmlpp::Element *hiscores) {
+       for (auto const& h: m_hiscore) {
+               xmlpp::Element* hiscore = hiscores->add_child("hiscore");
+               hiscore->set_attribute("playerid", boost::lexical_cast<std::string>(h.playerid));
+               hiscore->set_attribute("songid", boost::lexical_cast<std::string>(h.songid));
+               hiscore->set_attribute("track", h.track);
+               hiscore->add_child_text(boost::lexical_cast<std::string>(h.score));
+       }
+}
diff --git a/game/hiscore.hh b/game/hiscore.hh
new file mode 100644 (file)
index 0000000..4bda353
--- /dev/null
@@ -0,0 +1,59 @@
+#pragma once
+
+#include <set>
+#include <string>
+#include <vector>
+
+namespace xmlpp { class Node; class Element; typedef std::vector<Node*> NodeSet; }
+
+/// This struct holds together information for a single item of a highscore.
+struct HiscoreItem {
+       unsigned score, playerid, songid;
+       std::string track;
+       HiscoreItem(unsigned score, unsigned playerid, unsigned songid, std::string const& track):
+         score(score), playerid(playerid), songid(songid), track(track) {}
+       /// Operator for sorting by score. Reverse order, so that highest is first!
+       bool operator<(HiscoreItem const& other) const { return other.score < score; }
+};
+
+class Hiscore {
+public:
+       void load(xmlpp::NodeSet const& n);
+       void save(xmlpp::Element *players);
+
+       /**Check if you reached a new highscore.
+
+         You must be in TOP 3 of a specific song to enter the highscore list.
+         This is because it will take forever to fill more.
+         And people refuse to enter their names if they are not close to the top.
+
+         @param score is a value between 0 and 10000. values below 2000 will lead to instant disqualification.
+         @return true if the score make it into the list
+         @return false if addNewHiscore does not make sense
+           for that score.*/
+       bool reachedHiscore(unsigned score, unsigned songid, std::string const& track) const;
+
+       /**Add a specific highscore into the list.
+
+         @pre Hiscore is added.
+
+         There is no check regarding if it is useful to add this hiscore.
+         To check this, use reachedHiscore() first.
+
+         The method will check if all ids are non-negative and the score
+         in its valid interval. If one of this conditions is not net a
+         HiscoreException will be raised.
+         */
+       void addHiscore(unsigned score, unsigned playerid, unsigned songid, std::string const& track);
+
+       typedef std::vector<HiscoreItem> HiscoreVector;
+
+       /// This queries the database for a sorted vector of highscores. The defaults mean to query everything.
+       /// @param max limits the number of elements returned.
+       HiscoreVector queryHiscore(unsigned max, unsigned playerid, unsigned songid, std::string const& track) const;
+       bool hasHiscore(unsigned songid) const;
+       std::size_t size() const { return m_hiscore.size(); }
+private:
+       typedef std::multiset<HiscoreItem> hiscore_t;
+       hiscore_t m_hiscore;
+};
diff --git a/game/i18n.hh b/game/i18n.hh
new file mode 100644 (file)
index 0000000..d2a1856
--- /dev/null
@@ -0,0 +1,42 @@
+#pragma once
+
+#ifdef USE_GETTEXT
+/* Internationalization Dependances */
+    #ifdef __APPLE__ // Using system gettext can choke portability of an app-bundle. 
+        #include "libintl.h"
+        #include "locale.h"
+    #else
+        #include <libintl.h>
+        #include <locale.h>
+    #endif
+#include "fs.hh"
+#define _(x) gettext(x)
+#else
+#define _(x) (x)
+#endif
+
+class Gettext {
+  public:
+       Gettext(const char *package) {
+#ifdef USE_GETTEXT
+               // initialize gettext
+#ifdef _MSC_VER
+               setlocale(LC_ALL, "");//only untill we don't have a better solution. This because LC_MESSAGES cause crash under Visual Studio
+#else
+               setlocale (LC_MESSAGES, "");
+#endif
+               bindtextdomain (package, getLocaleDir().string().c_str());
+               textdomain (package);
+               bind_textdomain_codeset (package, "UTF-8");
+#else
+               (void)package;
+#endif
+       };
+       static bool enabled() {
+               #ifdef USE_GETTEXT
+               return true;
+               #else
+               return false;
+               #endif
+       }
+};
diff --git a/game/image.cc b/game/image.cc
new file mode 100644 (file)
index 0000000..3e44fd2
--- /dev/null
@@ -0,0 +1,228 @@
+#include "image.hh"
+
+#include "cache.hh"
+#include "configuration.hh"
+#include <boost/filesystem/fstream.hpp>
+#include <jpeglib.h>
+#include <librsvg/rsvg.h>
+#include <png.h>
+
+using fs::ofstream;
+using fs::ifstream;
+
+// Avoid deprecation messages with new versions since Ubuntu 12.10.
+#if LIBRSVG_MAJOR_VERSION * 10000 + LIBRSVG_MINOR_VERSION * 100 + LIBRSVG_MICRO_VERSION < 23602
+#include <librsvg/rsvg-cairo.h>
+#endif
+
+namespace {
+       void writePngHelper(png_structp pngPtr, png_bytep data, png_size_t length) {
+               static_cast<std::ostream*>(png_get_io_ptr(pngPtr))->write((char*)data, length);
+       }
+
+       void readPngHelper(png_structp pngPtr, png_bytep data, png_size_t length) {
+               static_cast<std::istream*>(png_get_io_ptr(pngPtr))->read((char*)data, length);
+       }
+       void loadPNG_internal(png_structp pngPtr, png_infop infoPtr, ifstream& file, Bitmap& bitmap, std::vector<png_bytep>& rows) {
+               if (setjmp(png_jmpbuf(pngPtr))) throw std::runtime_error("Reading PNG failed");
+               png_set_read_fn(pngPtr,(png_voidp)&file, readPngHelper);
+               png_read_info(pngPtr, infoPtr);
+               png_set_expand(pngPtr);  // Expand everything to RGB(A)
+               png_set_strip_16(pngPtr);  // Strip everything down to 8 bit/component
+               png_set_gray_to_rgb(pngPtr);  // Convert even grayscale to RGB(A)
+               png_set_filler(pngPtr, 0xFF, PNG_FILLER_AFTER); // Add alpha channel if it is missing
+               bitmap.resize(png_get_image_width(pngPtr, infoPtr), png_get_image_height(pngPtr, infoPtr));
+               rows.resize(bitmap.height);
+               for (unsigned y = 0; y < bitmap.height; ++y) rows[y] = reinterpret_cast<png_bytep>(&bitmap.buf[y * bitmap.width * 4]);
+               png_read_image(pngPtr, &rows[0]);
+       }
+
+       static void writePNG_internal(png_structp pngPtr, png_infop infoPtr, ofstream& file, unsigned w, unsigned h, int colorType, std::vector<png_bytep>& rows) {
+               // There must be no objects initialized within this function because longjmp will mess them up
+               if (setjmp(png_jmpbuf(pngPtr))) throw std::runtime_error("Writing PNG failed");
+               png_set_write_fn(pngPtr, &file, writePngHelper, NULL);
+               png_set_IHDR(pngPtr, infoPtr, w, h, 8, colorType, PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE);
+               png_write_info(pngPtr, infoPtr);
+               png_write_image(pngPtr, &rows[0]);
+               png_write_end(pngPtr, NULL);
+       }
+
+       struct my_jpeg_error_mgr {
+               struct jpeg_error_mgr pub;      /* "public" fields */
+               jmp_buf setjmp_buffer;  /* for return to caller */
+       };
+
+       typedef struct my_jpeg_error_mgr * my_jpeg_error_mgr_ptr;
+
+       static inline void my_jpeg_error_exit(j_common_ptr cinfo) {
+               my_jpeg_error_mgr_ptr myerr = (my_jpeg_error_mgr_ptr) cinfo->err;
+               (*cinfo->err->output_message) (cinfo);
+               longjmp(myerr->setjmp_buffer, 1);
+       }
+
+       #if JPEG_LIB_VERSION < 80
+       // Implementation of jpeg_mem_src from
+       // http://stackoverflow.com/questions/5280756/libjpeg-ver-6b-jpeg-stdio-src-vs-jpeg-mem-src 
+
+       /* Read JPEG image from a memory segment */
+       static void init_source(j_decompress_ptr /*cinfo*/) {}
+       static boolean fill_input_buffer(j_decompress_ptr /*cinfo*/) {
+               //ERREXIT(cinfo, JERR_INPUT_EMPTY);
+               return true;
+       }
+       static void skip_input_data(j_decompress_ptr cinfo, long num_bytes) {
+               auto src = static_cast<jpeg_source_mgr*>(cinfo->src);
+               if (num_bytes > 0) {
+                       src->next_input_byte += num_bytes;
+                       src->bytes_in_buffer -= num_bytes;
+               }
+       }
+       static void term_source(j_decompress_ptr /*cinfo*/) {}
+       static void jpeg_mem_src(j_decompress_ptr cinfo, void* buffer, long nbytes) {
+               if (!cinfo->src) {   /* first time for this JPEG object? */
+                       cinfo->src = static_cast<jpeg_source_mgr*>(
+                         (*cinfo->mem->alloc_small) ((j_common_ptr)cinfo, JPOOL_PERMANENT, sizeof(jpeg_source_mgr))
+                       );
+               }
+               auto src = static_cast<jpeg_source_mgr*>(cinfo->src);
+               src->init_source = init_source;
+               src->fill_input_buffer = fill_input_buffer;
+               src->skip_input_data = skip_input_data;
+               src->resync_to_restart = jpeg_resync_to_restart; /* use default method */
+               src->term_source = term_source;
+               src->bytes_in_buffer = nbytes;
+               src->next_input_byte = static_cast<JOCTET*>(buffer);
+       }
+       #endif
+
+}
+
+void writePNG(fs::path const& filename, Bitmap const& img, unsigned stride) {
+       fs::path name = filename;
+       // We use PNG in a non-standard way, with premultiplied alpha, signified by .premul.png extension.
+       std::clog << "image/debug: Saving PNG: " + name.string() << std::endl;
+       std::vector<png_bytep> rows(img.height);
+       // Determine color type and bytes per pixel
+       unsigned char bpp;
+       int colorType;
+       switch (img.fmt) {
+               case pix::RGB: bpp = 3; colorType = PNG_COLOR_TYPE_RGB; break;
+               case pix::CHAR_RGBA: bpp = 4; colorType = PNG_COLOR_TYPE_RGBA; break;
+               default:
+                       // Byte order would need to be changed for other formats and we don't currently need them...
+                       throw std::logic_error("Unsupported pixel format in writePNG_internal");
+       }
+       // Construct row pointers
+       bool reverse = img.bottomFirst;
+       if (stride == 0) stride = img.width * bpp;
+       unsigned pos = reverse ? img.height * stride : -stride;
+       for (unsigned y = 0; y < img.height; ++y) {
+               pos += (reverse ? -stride : stride);
+               rows[y] = (png_bytep)(&img.data()[pos]);
+       }
+       // Initialize libpng structures
+       png_structp pngPtr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
+       if (!pngPtr) throw std::runtime_error("png_create_read_struct failed");
+       png_infop infoPtr = NULL;
+       struct Cleanup {
+               png_structpp pngPP;
+               png_infopp infoPP;
+               Cleanup(png_structp& pngP, png_infop& infoP): pngPP(&pngP), infoPP(&infoP) {}
+               ~Cleanup() { png_destroy_write_struct(pngPP, infoPP); }
+       } cleanup(pngPtr, infoPtr);
+       infoPtr = png_create_info_struct(pngPtr);
+       if (!infoPtr) throw std::runtime_error("png_create_info_struct failed");
+       png_set_gAMA(pngPtr, infoPtr, img.linearPremul ? 1.0 : 2.2);
+       // Write file
+       ofstream file(name, std::ios::binary);
+       writePNG_internal(pngPtr, infoPtr, file, img.width, img.height, colorType, rows);
+}
+
+void loadSVG(Bitmap& bitmap, fs::path const& filename) {
+       double factor = config["graphic/svg_lod"].f();
+       // Try to load a cached PNG instead
+       if (cache::loadSVG(bitmap, filename, factor)) return;
+       std::clog << "image/debug: Loading SVG: " + filename.string() << std::endl;
+       // Open the SVG file in librsvg
+#if !GLIB_CHECK_VERSION(2, 36, 0)   // Avoid deprecation warnings
+       g_type_init();
+#endif
+       GError* pError = NULL;
+       boost::shared_ptr<RsvgHandle> svgHandle(rsvg_handle_new_from_file(filename.string().c_str(), &pError), g_object_unref);
+       if (pError) {
+               g_error_free(pError);
+               throw std::runtime_error("Unable to load " + filename.string());
+       }
+       // Get SVG dimensions
+       RsvgDimensionData svgDimension;
+       rsvg_handle_get_dimensions(svgHandle.get(), &svgDimension);
+       // Prepare the pixel buffer
+       bitmap.resize(svgDimension.width*factor, svgDimension.height*factor);
+       bitmap.fmt = pix::INT_ARGB;
+       bitmap.linearPremul = true;
+       // Raster with Cairo
+       boost::shared_ptr<cairo_surface_t> surface(
+         cairo_image_surface_create_for_data(&bitmap.buf[0], CAIRO_FORMAT_ARGB32, bitmap.width, bitmap.height, bitmap.width * 4),
+         cairo_surface_destroy);
+       boost::shared_ptr<cairo_t> dc(cairo_create(surface.get()), cairo_destroy);
+       cairo_scale(dc.get(), factor, factor);
+       rsvg_handle_render_cairo(svgHandle.get(), dc.get());
+       // Change byte order from BGRA to RGBA
+       for (uint32_t *ptr = reinterpret_cast<uint32_t*>(&*bitmap.buf.begin()), *end = ptr + bitmap.buf.size() / 4; ptr < end; ++ptr) {
+               uint8_t* pixel = reinterpret_cast<uint8_t*>(ptr);
+               uint8_t r = pixel[2], g = pixel[1], b = pixel[0], a = pixel[3];
+               pixel[0] = r; pixel[1] = g; pixel[2] = b; pixel[3] = a;
+       }
+       bitmap.fmt = pix::CHAR_RGBA;
+       // Write to cache so that it can be loaded faster the next time
+       fs::path cache_filename = cache::constructSVGCacheFileName(filename, factor);
+       fs::create_directories(cache_filename.parent_path());
+       writePNG(cache_filename, bitmap);
+}
+
+void loadPNG(Bitmap& bitmap, fs::path const& filename) {
+       std::clog << "image/debug: Loading PNG: " + filename.string() << std::endl;
+       // A hack to assume linear premultiplied data if file extension is .premul.png (used for cached SVGs)
+       if (filename.stem().extension() == "premul") bitmap.linearPremul = true;
+       ifstream file(filename, std::ios::binary);
+       png_structp pngPtr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
+       if (!pngPtr) throw std::runtime_error("png_create_read_struct failed");
+       png_infop infoPtr = NULL;
+       struct Cleanup {
+               png_structpp pngPP;
+               png_infopp infoPP;
+               Cleanup(png_structp& pngP, png_infop& infoP): pngPP(&pngP), infoPP(&infoP) {}
+               ~Cleanup() { png_destroy_read_struct(pngPP, infoPP, (png_infopp)NULL); }
+       } cleanup(pngPtr, infoPtr);
+       infoPtr = png_create_info_struct(pngPtr);
+       if (!infoPtr) throw std::runtime_error("png_create_info_struct failed");
+       std::vector<png_bytep> rows;
+       loadPNG_internal(pngPtr, infoPtr, file, bitmap, rows);
+}
+
+void loadJPEG(Bitmap& bitmap, fs::path const& filename) {
+       std::clog << "image/debug: Loading JPEG: " + filename.string() << std::endl;
+       bitmap.fmt = pix::RGB;
+       struct my_jpeg_error_mgr jerr;
+       BinaryBuffer data = readFile(filename);
+       jpeg_decompress_struct cinfo;
+       cinfo.err = jpeg_std_error(&jerr.pub);
+       jerr.pub.error_exit = my_jpeg_error_exit;
+       if (setjmp(jerr.setjmp_buffer)) {
+               jpeg_destroy_decompress(&cinfo);
+               throw std::runtime_error("Error in libjpeg when decoding " + filename.string());
+       }
+       jpeg_create_decompress(&cinfo);
+       jpeg_mem_src(&cinfo, data.data(), data.size());
+       if (jpeg_read_header(&cinfo, true) != JPEG_HEADER_OK) throw std::runtime_error("Cannot read header of " + filename.string());
+       jpeg_start_decompress(&cinfo);
+       bitmap.resize(cinfo.output_width, cinfo.output_height);
+       unsigned stride = (bitmap.width * 3 + 3) & ~3;  // Number of bytes per row (word-aligned)
+       unsigned char* ptr = &bitmap.buf[0];
+       while (cinfo.output_scanline < bitmap.height) {
+               jpeg_read_scanlines(&cinfo, &ptr, 1);
+               ptr += stride;
+       }
+       jpeg_destroy_decompress(&cinfo);
+}
+
diff --git a/game/image.hh b/game/image.hh
new file mode 100644 (file)
index 0000000..cc55bd0
--- /dev/null
@@ -0,0 +1,11 @@
+#pragma once
+
+#include "surface.hh"
+#include "util.hh"
+
+// The total number of bytes per line (stride) may be specified. By default no padding at end of line is assumed.
+void writePNG(fs::path const& filename, Bitmap const& bitmap, unsigned stride = 0);
+void loadSVG(Bitmap& bitmap, fs::path const& filename);
+void loadPNG(Bitmap& bitmap, fs::path const& filename);
+void loadJPEG(Bitmap& bitmap, fs::path const& filename);
+
diff --git a/game/instrumentgraph.cc b/game/instrumentgraph.cc
new file mode 100644 (file)
index 0000000..2ab2739
--- /dev/null
@@ -0,0 +1,240 @@
+#include "instrumentgraph.hh"
+#include "i18n.hh"
+#include "glutil.hh"
+#include "theme.hh"
+
+namespace {
+       const double join_delay = 3.0; // Time after join menu before playing when joining mid-game
+       const unsigned death_delay = 20; // Delay in notes after which the player is hidden
+}
+
+//const unsigned InstrumentGraph::max_panels = 10; // Maximum number of arrow lines / guitar frets
+
+
+InstrumentGraph::InstrumentGraph(Audio& audio, Song const& song, input::DevicePtr dev):
+  m_audio(audio), m_song(song),
+  m_stream(),
+  m_dev(dev),
+  m_cx(0.0, 0.2), m_width(0.5, 0.4),
+  m_menu(),
+  m_button(findFile("button.svg")),
+  m_arrow_up(findFile("arrow_button_up.svg")),
+  m_arrow_down(findFile("arrow_button_down.svg")),
+  m_arrow_left(findFile("arrow_button_left.svg")),
+  m_arrow_right(findFile("arrow_button_right.svg")),
+  m_text(findFile("sing_timetxt.svg"), config["graphic/text_lod"].f()),
+  m_selectedTrack(""),
+  m_selectedDifficulty(0),
+  m_rejoin(false),
+  m_leftymode(false),
+  m_pads(),
+  m_correctness(1.0, 5.0),
+  m_score(),
+  m_scoreFactor(),
+  m_starmeter(),
+  m_streak(),
+  m_longestStreak(),
+  m_bigStreak(),
+  m_countdown(3), // Display countdown 3 secs before note start
+  m_dead(),
+  m_ready()
+{
+       double time = m_audio.getPosition();
+       m_jointime = time < 0.0 ? -1.0 : time + join_delay;
+
+       m_popupText.reset(new SvgTxtThemeSimple(findFile("sing_popup_text.svg"), config["graphic/text_lod"].f()));
+       m_menuTheme.reset(new ThemeInstrumentMenu());
+       for (auto& elem: m_pressed) elem = false;
+}
+
+InstrumentGraph::~InstrumentGraph() {}  // For destruction of scoped_ptrs (only forward-declared in header)
+
+bool InstrumentGraph::dead() const { return m_jointime != m_jointime || m_dead >= death_delay; }
+
+void InstrumentGraph::setupPauseMenu() {
+       m_menu.clear();
+       m_menu.add(MenuOption(_("Resume"), _("Back to performing!")));
+       m_menu.add(MenuOption(_("Rejoin"), _("Change selections")).changer(m_rejoin));
+       m_menu.add(MenuOption(_("Restart"), _("Start the song\nfrom the beginning")).screen("Sing"));
+       m_menu.add(MenuOption(_("Quit"), _("Exit to song browser")).screen("Songs"));
+}
+
+
+void InstrumentGraph::doUpdates() {
+       if (!menuOpen() && !m_ready) {
+               m_ready = true;
+               setupPauseMenu();
+       }
+}
+
+void InstrumentGraph::togglePause(int) {
+       m_audio.togglePause();
+}
+
+void InstrumentGraph::toggleMenu(int forcestate) {
+       if (forcestate == 1) { m_menu.open(); return; }
+       else if (forcestate == 0) { m_menu.close(); return; }
+       m_menu.toggle();
+}
+
+
+void InstrumentGraph::drawMenu() {
+       ViewTrans view(m_cx.get(), 0.0, 0.75);  // Apply a per-player local perspective
+       if (m_menu.empty()) return;
+       Dimensions dimensions(1.0); // FIXME: bogus aspect ratio (is this fixable?)
+       if (getGraphType() == input::DEVTYPE_DANCEPAD) dimensions.screenTop().middle().stretch(m_width.get(), 1.0);
+       else dimensions.screenBottom().middle().fixedWidth(std::min(m_width.get(), 0.5));
+       ThemeInstrumentMenu& th = *m_menuTheme;
+       th.back_h.dimensions.fixedHeight(0.08f);
+       m_arrow_up.dimensions.stretch(0.05, 0.05);
+       m_arrow_down.dimensions.stretch(0.05, 0.05);
+       m_arrow_left.dimensions.stretch(0.05, 0.05);
+       m_arrow_right.dimensions.stretch(0.05, 0.05);
+       auto cur = static_cast<MenuOptions::const_iterator>(&m_menu.current());
+       double w = m_menu.dimensions.w();
+       const float s = std::min(m_width.get(), 0.5) / w;
+       Transform trans(glmath::scale(s));  // Fit better menu on screen
+       // We need to multiply offset by inverse scale factor to keep it always constant
+       // All these vars are ultimately affected by the scaling matrix
+       const float txth = th.option_selected.h();
+       const float button_margin = m_arrow_up.dimensions.w()
+               * (isKeyboard() && getGraphType() != input::DEVTYPE_DANCEPAD ? 2.0f : 1.0f);
+       const float step = txth * 0.7f;
+       const float h = m_menu.getOptions().size() * step + step;
+       float y = -h * .5f + step;
+       float x = -w*.5f + step + button_margin;
+       float xx = w*.5f - step - button_margin;
+       // Background
+       th.bg.dimensions.middle().center().stretch(w, h);
+       th.bg.draw();
+       // Loop through menu items
+       w = 0;
+       unsigned i = 0;
+       for (MenuOptions::const_iterator it = m_menu.begin(); it != m_menu.end(); ++it, ++i) {
+               std::string menutext = it->getName();
+               SvgTxtTheme* txt = &th.option_selected; // Default: font for selected menu item
+
+               if (cur != it) { // Unselected menuoption
+                       txt = &(th.getCachedOption(menutext));
+
+               // Selected item
+               } else {
+                       // Left/right Icons
+                       if (getGraphType() == input::DEVTYPE_DRUMS) {
+                               // Drum colors are mirrored
+                               m_arrow_left.dimensions.middle(xx + button_margin).center(y);
+                               m_arrow_right.dimensions.middle(x - button_margin).center(y);
+                       } else {
+                               m_arrow_left.dimensions.middle(x - button_margin).center(y);
+                               m_arrow_right.dimensions.middle(xx + button_margin).center(y);
+                       }
+                       m_arrow_left.draw();
+                       m_arrow_right.draw();
+
+                       // Up/down icons
+                       if (getGraphType() != input::DEVTYPE_GUITAR) {
+                               if (i > 0) { // Up
+                                       m_arrow_up.dimensions.middle(x - button_margin).center(y - step);
+                                       m_arrow_up.draw();
+                               }
+                               if (i < m_menu.getOptions().size()-1) { // Down
+                                       m_arrow_down.dimensions.middle(x - button_margin).center(y + step);
+                                       m_arrow_down.draw();
+                               }
+                       }
+
+                       // Draw the key letters for keyboard (not for dancepad)
+                       if (isKeyboard() && getGraphType() != input::DEVTYPE_DANCEPAD) {
+                               float leftx = x - button_margin*0.75f;
+                               float rightx = xx + button_margin*0.25f;
+                               {
+                                       std::string hintletter = (getGraphType() == input::DEVTYPE_GUITAR ? (m_leftymode.b() ? "Z" : "1") : "U");
+                                       SvgTxtTheme& hintfont = th.getCachedOption(hintletter);
+                                       hintfont.dimensions.left(leftx).center(y);
+                                       hintfont.draw(hintletter);
+                               }{
+                                       std::string hintletter = (getGraphType() == input::DEVTYPE_GUITAR ? (m_leftymode.b() ? "X" : "2") : "P");
+                                       SvgTxtTheme& hintfont = th.getCachedOption(hintletter);
+                                       hintfont.dimensions.right(rightx).center(y);
+                                       hintfont.draw(hintletter);
+                               }
+                               // Only drums has up/down
+                               if (getGraphType() == input::DEVTYPE_DRUMS) {
+                                       if (i > 0) {  // Up
+                                               SvgTxtTheme& hintfont = th.getCachedOption("I");
+                                               hintfont.dimensions.left(leftx).center(y - step);
+                                               hintfont.draw("I");
+                                       }
+                                       if (i < m_menu.getOptions().size()-1) {  // Down
+                                               SvgTxtTheme& hintfont = th.getCachedOption("O");
+                                               hintfont.dimensions.left(leftx).center(y + step);
+                                               hintfont.draw("O");
+                                       }
+                               }
+                       }
+               }
+               // Finally we are at the actual menu item text drawing
+               ColorTrans c(Color::alpha(it->isActive() ? 1.0 : 0.5));
+               txt->dimensions.middle(x).center(y);
+               txt->draw(menutext);
+               w = std::max(w, txt->w() + 2 * step + button_margin * 2); // Calculate the widest entry
+               y += step; // Move draw position down for the next option
+       }
+       // Draw comment text
+       if (cur->getComment() != "") {
+               //th.comment_bg.dimensions.middle().screenBottom(-0.2);
+               //th.comment_bg.draw();
+               th.comment.dimensions.middle().screenBottom(-0.12);
+               th.comment.draw(cur->getComment());
+       }
+       // Save the calculated menu dimensions
+       m_menu.dimensions.stretch(w, h);
+}
+
+
+void InstrumentGraph::drawPopups() {
+       for (auto it = m_popups.begin(); it != m_popups.end(); ) {
+               if (!it->draw()) { it = m_popups.erase(it); continue; }
+               ++it;
+       }
+}
+
+
+void InstrumentGraph::handleCountdown(double time, double beginTime) {
+       if (!dead() && time < beginTime && time >= beginTime - m_countdown - 1) {
+               m_popups.push_back(Popup(m_countdown > 0 ?
+                 std::string("- ") +boost::lexical_cast<std::string>(unsigned(m_countdown))+" -" : "Rock On!",
+                 Color(0.0, 0.0, 1.0), 2.0, m_popupText.get()));
+                 --m_countdown;
+       }
+}
+
+
+Color const& InstrumentGraph::color(unsigned fret) const {
+       static Color fretColors[5] = {
+               Color(0.0, 0.9, 0.0),
+               Color(0.9, 0.0, 0.0),
+               Color(0.9, 0.9, 0.0),
+               Color(0.0, 0.0, 1.0),
+               Color(0.9, 0.4, 0.0)
+       };
+       if (fret >= m_pads) throw std::logic_error("Invalid fret number in InstrumentGraph::color");
+       if (getGraphType() == input::DEVTYPE_DRUMS) {
+               if (fret == 0) fret = 4;
+               else if (fret == 4) fret = 0;
+       }
+       return fretColors[fret];
+}
+
+
+void InstrumentGraph::unjoin() {
+       m_jointime = getNaN();
+       m_rejoin = false;
+       m_score = 0;
+       m_starmeter = 0;
+       m_streak = 0;
+       m_longestStreak = 0;
+       m_bigStreak = 0;
+       m_countdown = 3;
+       m_ready = false;
+}
diff --git a/game/instrumentgraph.hh b/game/instrumentgraph.hh
new file mode 100644 (file)
index 0000000..cd7363f
--- /dev/null
@@ -0,0 +1,167 @@
+#pragma once
+
+#include <vector>
+
+#include "audio.hh"
+#include "animvalue.hh"
+#include "notes.hh"
+#include "controllers.hh"
+#include "surface.hh"
+#include "opengl_text.hh"
+#include "glutil.hh"
+#include "menu.hh"
+#include "screen.hh"
+#include "fs.hh"
+
+/// Represents popup messages
+class Popup {
+  public:
+       /// Constructor
+       Popup(std::string msg, Color c, double speed, SvgTxtThemeSimple* popupText, std::string info = "", SvgTxtTheme* infoText = NULL):
+         m_msg(msg), m_color(c), m_anim(AnimValue(0.0, speed)), m_popupText(popupText), m_info(info), m_infoText(infoText)
+       {
+               m_anim.setTarget(1.0, false);
+       }
+       /// Draw the popup
+       /// Returns false if it is expired
+       bool draw() {
+               double anim = m_anim.get();
+               if (anim <= 0.0 || !m_popupText) return false;
+               float a = 1.0 - anim;
+               m_color.a = a;
+               ColorTrans color(m_color);
+               m_popupText->render(m_msg);
+               {
+                       using namespace glmath;
+                       Transform trans(translate(vec3(0.0f, 0.0f, 0.5f * anim)));
+                       m_popupText->dimensions().center(0.1 - 0.03 * anim).middle().stretch(0.2f, 0.2f);
+                       m_popupText->draw();
+               }
+               if (m_info != "" && m_infoText) {
+                       m_infoText->dimensions.screenBottom(-0.02).middle(-0.12);
+                       m_infoText->draw(m_info);
+               }
+               if (anim > 0.999) m_anim.setTarget(0.0, true);
+               return true;
+       }
+  private:
+       std::string m_msg;  /// Popup text
+       Color m_color;  /// Color
+       AnimValue m_anim;  /// Animation timer
+       SvgTxtThemeSimple* m_popupText;  /// Font for popup
+       std::string m_info;  /// Text to show in the bottom
+       SvgTxtTheme* m_infoText;  /// Font for the additional text
+};
+
+
+const unsigned max_panels = 10; // Maximum number of arrow lines / guitar frets
+
+class Audio;
+class Song;
+class ThemeInstrumentMenu;
+
+class InstrumentGraph {
+public:
+       /// Constructor
+       InstrumentGraph(Audio& audio, Song const& song, input::DevicePtr dev);
+       /// Virtual destructor
+       virtual ~InstrumentGraph();
+
+       // Interface functions
+       virtual void draw(double time) = 0;
+       virtual void engine() = 0;
+       virtual void process(input::Event const&) {}
+       virtual std::string getTrack() const = 0;
+       virtual std::string getDifficultyString() const = 0;
+       virtual std::string getModeId() const = 0;
+       virtual void changeTrack(int dir = 1) = 0;
+       virtual void changeDifficulty(int dir = 1) = 0;
+
+       // General shared functions
+       bool dead() const;
+       void setupPauseMenu();
+       void doUpdates();
+       void drawMenu();
+       void toggleMenu(int forcestate = -1); // 0 = close, 1 = open, -1 = auto/toggle
+       void togglePause(int);
+       void quit(int) { Game::getSingletonPtr()->activateScreen("Songs"); }
+       void unjoin();
+
+       // General getters
+       bool joining(double time) const { return time < m_jointime; }
+       bool ready() const { return m_ready; };
+       bool menuOpen() const { return m_menu.isOpen(); }
+       void position(double cx, double width) { m_cx.setTarget(cx); m_width.setTarget(width); }
+       unsigned stream() const { return m_stream; }
+       double correctness() const { return m_correctness.get(); }
+       int getScore() const { return (m_score > 0 ? m_score : 0) * m_scoreFactor; }
+       input::DevType getGraphType() const { return m_dev->type; }
+       virtual double getWhammy() const { return 0; }
+       bool isKeyboard() const { return m_dev->source.isKeyboard(); }
+
+  protected:
+       // Core stuff
+       Audio& m_audio;
+       Song const& m_song;
+       std::size_t m_stream; /// audio stream number
+       input::DevicePtr m_dev;
+       AnimValue m_cx, m_width; /// controls horizontal position and width smoothly
+       struct Event {
+               double time;
+               AnimValue glow;
+               AnimValue whammy;
+               int type; // 0 = miss (pick), 1 = tap, 2 = pick
+               int fret;
+               Duration const* dur;
+               double holdTime;
+               Event(double t, int ty, int f = -1, Duration const* d = NULL): time(t), glow(0.0, 5.0), whammy(0.0, 0.5), type(ty), fret(f), dur(d), holdTime(d ? d->begin : getNaN()) { if (type > 0) glow.setValue(1.0); }
+       };
+       typedef std::vector<Event> Events;
+       Events m_events;
+       typedef std::vector<Popup> Popups;
+       Popups m_popups;
+       Menu m_menu;
+
+       // Shared functions for derived classes
+       void drawPopups();
+       void handleCountdown(double time, double beginTime);
+
+       // Functions not really shared, but needed here
+       Color const& color(unsigned fret) const;
+
+       // Media
+       Surface m_button;
+       Surface m_arrow_up;
+       Surface m_arrow_down;
+       Surface m_arrow_left;
+       Surface m_arrow_right;
+       SvgTxtTheme m_text;
+       boost::scoped_ptr<SvgTxtThemeSimple> m_popupText;
+       boost::scoped_ptr<ThemeInstrumentMenu> m_menuTheme;
+
+       // Dynamic stuff for join menu
+       ConfigItem m_selectedTrack; /// menu modifies this to select track
+       ConfigItem m_selectedDifficulty; /// menu modifies this to select difficulty
+       ConfigItem m_rejoin; /// menu sets this if we want to re-join
+       ConfigItem m_leftymode; /// switch guitar notes to right-to-left direction
+       std::string m_trackOpt;
+       std::string m_difficultyOpt;
+       std::string m_leftyOpt;
+
+       // Misc counters etc.
+       unsigned m_pads; /// how many panels the current gaming mode uses
+       bool m_pressed[max_panels]; /// is certain panel pressed currently
+       AnimValue m_pressed_anim[max_panels]; /// animation for panel pressing
+       AnimValue m_correctness;
+       double m_score; /// unnormalized scores
+       double m_scoreFactor; /// normalization factor
+       double m_starmeter; /// when this is high enough, GodMode becomes available
+       int m_streak; /// player's current streak/combo
+       int m_longestStreak; /// player's longest streak/combo
+       int m_bigStreak; /// next limit when a popup appears
+       int m_countdown; /// countdown counter
+       double m_jointime; /// when the player joined
+       unsigned m_dead; /// how many notes has been passed without hitting buttons
+       bool m_ready;
+};
+
diff --git a/game/layout_singer.cc b/game/layout_singer.cc
new file mode 100644 (file)
index 0000000..eb1b15a
--- /dev/null
@@ -0,0 +1,174 @@
+#include "layout_singer.hh"
+
+#include "configuration.hh"
+#include "fs.hh"
+#include "song.hh"
+#include "database.hh"
+
+#include <list>
+#include <boost/format.hpp>
+
+LayoutSinger::LayoutSinger(VocalTrack& vocal, Database& database, boost::shared_ptr<ThemeSing> theme):
+  m_vocal(vocal), m_noteGraph(vocal),m_lyricit(vocal.notes.begin()), m_lyrics(), m_database(database), m_theme(theme), m_hideLyrics() {
+       m_score_text[0].reset(new SvgTxtThemeSimple(findFile("sing_score_text.svg"), config["graphic/text_lod"].f()));
+       m_score_text[1].reset(new SvgTxtThemeSimple(findFile("sing_score_text.svg"), config["graphic/text_lod"].f()));
+       m_score_text[2].reset(new SvgTxtThemeSimple(findFile("sing_score_text.svg"), config["graphic/text_lod"].f()));
+       m_score_text[3].reset(new SvgTxtThemeSimple(findFile("sing_score_text.svg"), config["graphic/text_lod"].f()));
+       m_line_rank_text[0].reset(new SvgTxtThemeSimple(findFile("sing_score_text.svg"), config["graphic/text_lod"].f()));
+       m_line_rank_text[1].reset(new SvgTxtThemeSimple(findFile("sing_score_text.svg"), config["graphic/text_lod"].f()));
+       m_line_rank_text[2].reset(new SvgTxtThemeSimple(findFile("sing_score_text.svg"), config["graphic/text_lod"].f()));
+       m_line_rank_text[3].reset(new SvgTxtThemeSimple(findFile("sing_score_text.svg"), config["graphic/text_lod"].f()));
+       m_player_icon.reset(new Surface(findFile("sing_pbox.svg")));
+}
+
+LayoutSinger::~LayoutSinger() {}
+
+void LayoutSinger::reset() {
+       m_lyricit = m_vocal.notes.begin();
+       m_lyrics.clear();
+}
+
+void LayoutSinger::drawScore(PositionMode position) {
+       unsigned int i = 0, j = 0;
+       for (std::list<Player>::const_iterator p = m_database.cur.begin(); p != m_database.cur.end(); ++p, ++i) {
+               if (p->m_vocal.name != m_vocal.name) continue;
+               Color color(p->m_color.r, p->m_color.g, p->m_color.b, p->activity());
+               if (color.a == 0.0) continue;
+               m_score_text[i%4]->render((boost::format("%04d") % p->getScore()).str());
+               switch(position) {
+                       case LayoutSinger::FULL:
+                               m_player_icon->dimensions.left(-0.5 + 0.01 + 0.25 * j).fixedWidth(0.075).screenTop(0.055);
+                               m_score_text[i%4]->dimensions().middle(-0.350 + 0.01 + 0.25 * j).fixedHeight(0.075).screenTop(0.055);
+                               break;
+                       case LayoutSinger::TOP:
+                               m_player_icon->dimensions.right(0.35).fixedHeight(0.050).screenTop(0.025 + 0.050 * j);
+                               m_score_text[i%4]->dimensions().right(0.45).fixedHeight(0.050).screenTop(0.025 + 0.050 * j);
+                               break;
+                       case LayoutSinger::BOTTOM:
+                               m_player_icon->dimensions.right(0.35).fixedHeight(0.050).center(0.025 + 0.050 * j);
+                               m_score_text[i%4]->dimensions().right(0.45).fixedHeight(0.050).center(0.025 + 0.050 * j);
+                               break;
+                       case LayoutSinger::LEFT:
+                       case LayoutSinger::RIGHT:
+                               m_player_icon->dimensions.left(-0.5 + 0.01 + 0.25 * j).fixedWidth(0.075).screenTop(0.055);
+                               m_score_text[i%4]->dimensions().middle(-0.350 + 0.01 + 0.25 * j).fixedHeight(0.075).screenTop(0.055);
+                               break;
+               }
+               {
+                       ColorTrans c(color);
+                       m_player_icon->draw();
+                       m_score_text[i%4]->draw();
+               }
+               // Give some feedback on how well the last lyrics row went
+               double fact = p->m_feedbackFader.get();
+               if (p->m_prevLineScore > 0.5 && fact > 0) {
+                       std::string prevLineRank;
+                       double fzoom = 3.0 / (2.0 + fact);
+                       if (p->m_prevLineScore > 0.95) prevLineRank = "Perfect";
+                       else if (p->m_prevLineScore > 0.9) prevLineRank = "Excellent";
+                       else if (p->m_prevLineScore > 0.8) prevLineRank = "Great";
+                       else if (p->m_prevLineScore > 0.6) prevLineRank = "Good";
+                       else if (p->m_prevLineScore > 0.4) prevLineRank = "OK";
+                       m_line_rank_text[i%4]->render(prevLineRank);
+                       switch(position) {
+                               case LayoutSinger::FULL:
+                                       m_line_rank_text[i%4]->dimensions().middle(-0.350 + 0.01 + 0.25 * j).fixedHeight(0.055*fzoom).screenTop(0.11);
+                                       break;
+                               case LayoutSinger::TOP:
+                                       m_line_rank_text[i%4]->dimensions().right(0.30).fixedHeight(0.05*fzoom).screenTop(0.025 + 0.050 * j);
+                                       break;
+                               case LayoutSinger::BOTTOM:
+                                       m_line_rank_text[i%4]->dimensions().right(0.30).fixedHeight(0.05*fzoom).center(0.025 + 0.050 * j);
+                                       break;
+                               case LayoutSinger::LEFT:
+                               case LayoutSinger::RIGHT:
+                                       m_line_rank_text[i%4]->dimensions().middle(-0.350 + 0.01 + 0.25 * j).fixedHeight(0.055*fzoom).screenTop(0.11);
+                                       break;
+                       }
+                       {
+                               color.a = clamp(fact*2.0);
+                               ColorTrans c(color);
+                               m_line_rank_text[i%4]->draw();
+                       }
+               }
+               ++j;
+       }
+}
+
+void LayoutSinger::draw(double time, PositionMode position) {
+       // Draw notes and pitch waves (only when not in karaoke mode)
+       if (!config["game/karaoke_mode"].i()) {
+               switch(position) {
+                       case LayoutSinger::FULL:
+                               m_noteGraph.draw(time, m_database, NoteGraph::FULLSCREEN);
+                               break;
+                       case LayoutSinger::TOP:
+                               m_noteGraph.draw(time, m_database, NoteGraph::TOP);
+                               break;
+                       case LayoutSinger::BOTTOM:
+                               m_noteGraph.draw(time, m_database, NoteGraph::BOTTOM);
+                               break;
+                       case LayoutSinger::LEFT:
+                       case LayoutSinger::RIGHT:
+                               m_noteGraph.draw(time, m_database, NoteGraph::LEFT);
+                               break;
+               }
+       }
+
+       // Draw the lyrics
+       if (!m_hideLyrics) {
+               double linespacing = 0.0;
+               Dimensions pos;
+               switch(position) {
+                       case LayoutSinger::FULL:
+                               if(config["game/karaoke_mode"].i() >= 2) {
+                                       pos.center(0);
+                               } else {
+                                       pos.screenBottom(-0.1);
+                               }
+                               linespacing = 0.06;
+                               break;
+                       case LayoutSinger::TOP:
+                               pos.center(-0.06);
+                               linespacing = 0.04;
+                               break;
+                       case LayoutSinger::BOTTOM:
+                               pos.screenBottom(-0.07);
+                               linespacing = 0.04;
+                               break;
+                       case LayoutSinger::LEFT:
+                       case LayoutSinger::RIGHT:
+                               pos.screenBottom(-0.1);
+                               linespacing = 0.06;
+                               break;
+               }
+               bool dirty;
+               do {
+                       dirty = false;
+                       if (!m_lyrics.empty() && m_lyrics[0].expired(time)) {
+                               // Add extra spacing to replace the removed row
+                               if (m_lyrics.size() > 1) m_lyrics[1].extraspacing.move(m_lyrics[0].extraspacing.get() + 1.0);
+                               m_lyrics.pop_front();
+                               dirty = true;
+                       }
+                       if (!dirty && m_lyricit != m_vocal.notes.end() && m_lyricit->begin < time + 4.0) {
+                               m_lyrics.push_back(LyricRow(m_lyricit, m_vocal.notes.end()));
+                               dirty = true;
+                       }
+               } while (dirty);
+               if (m_theme.get()) // if there is a theme, draw the lyrics with it
+               {
+                       for (size_t i = 0; i < m_lyrics.size(); ++i, pos.move(0.0, linespacing)) {
+                               pos.move(0.0, m_lyrics[i].extraspacing.get() * linespacing);
+                               if (i == 0) m_lyrics[0].draw(m_theme->lyrics_now, time, pos);
+                               else if (i == 1) m_lyrics[1].draw(m_theme->lyrics_next, time, pos);
+                       }
+               }
+       }
+
+       if (!config["game/karaoke_mode"].i() ) drawScore(position); // draw score if not in karaoke mode
+}
+
+double LayoutSinger::lyrics_begin() const {
+       return m_lyricit->begin;
+}
diff --git a/game/layout_singer.hh b/game/layout_singer.hh
new file mode 100644 (file)
index 0000000..584c5a8
--- /dev/null
@@ -0,0 +1,82 @@
+#pragma once
+
+#include "theme.hh"
+#include "opengl_text.hh"
+#include "notegraph.hh"
+#include "configuration.hh"
+
+#include <deque>
+
+class Database;
+
+/// handles songlyrics
+class LyricRow {
+  public:
+       AnimValue extraspacing; ///< extraspacing for lyrics (used when the previous line is removed)
+       AnimValue fade; ///< fade
+       /// iterator
+       typedef Notes::const_iterator Iterator;
+       /// constructor
+       LyricRow(Iterator& it, Iterator const& eof): extraspacing(0.0, 2.0), fade(0.0, 0.6) {
+               fade.setTarget(1.0);
+               m_begin = it;
+               while (it != eof && it->type != Note::SLEEP) ++it;
+               m_end = it;
+               if (it != eof) ++it;
+               if (m_begin == m_end) throw std::logic_error("Empty sentence");
+       }
+       /// lyric expired?
+       bool expired(double time) const {
+               double lastTime = 0.0;
+               for (Iterator it = m_begin; it != m_end; ++it) lastTime = it->end;
+               return time > lastTime;
+       }
+       /// draw/print lyrics
+       void draw(SvgTxtTheme& txt, double time, Dimensions &dim) const {
+               std::vector<TZoomText> sentence;
+               for (Iterator it = m_begin; it != m_end; ++it) {
+                       sentence.push_back(TZoomText(it->syllable));
+                       if(!config["game/Textstyle"].i()) {
+                       bool current = (time >= it->begin && time < it->end);
+                       sentence.back().factor = current ? 1.2 - 0.2 * (time - it->begin) / (it->end - it->begin) : 1.0; ///what the hell is the logic behind this?
+                       } else {
+                       bool current = time >=it->begin;
+                               if(current)
+                               sentence.back().factor = 1.1;
+                               else
+                               sentence.back().factor = 1.0;
+                       }
+               }
+               ColorTrans c(Color::alpha(fade.get()));
+               txt.dimensions = dim;
+               txt.draw(sentence);
+       }
+
+  private:
+       Iterator m_begin, m_end;
+};
+
+class LayoutSinger {
+  public:
+       enum PositionMode {FULL, TOP, BOTTOM, LEFT, RIGHT};
+       /// ThemeSing is optional if you want to use drawScore only
+       LayoutSinger(VocalTrack& vocal, Database& database, boost::shared_ptr<ThemeSing> theme = boost::shared_ptr<ThemeSing>());
+       ~LayoutSinger();
+       void reset();
+       void draw(double time, PositionMode position = LayoutSinger::FULL);
+       void drawScore(PositionMode position);
+       double lyrics_begin() const;
+       void hideLyrics(bool hide = true) { m_hideLyrics = hide; }
+  private:
+       VocalTrack& m_vocal;
+       NoteGraph m_noteGraph;
+       Notes::const_iterator m_lyricit;
+       std::deque<LyricRow> m_lyrics;
+       boost::scoped_ptr<Surface> m_player_icon;
+       boost::scoped_ptr<SvgTxtThemeSimple> m_score_text[4];
+       boost::scoped_ptr<SvgTxtThemeSimple> m_line_rank_text[4];
+       Database& m_database;
+       boost::shared_ptr<ThemeSing> m_theme;
+       AnimValue m_feedbackFader;
+       bool m_hideLyrics;
+};
diff --git a/game/libda/fft.hpp b/game/libda/fft.hpp
new file mode 100644 (file)
index 0000000..3b85705
--- /dev/null
@@ -0,0 +1,84 @@
+#pragma once
+
+/**
+ * @file fft.hpp FFT and related facilities.
+ */
+
+#include "sample.hpp"
+#include <complex>
+#include <cstddef>
+#include <vector>
+
+#ifndef M_PI
+#define M_PI 3.141592653589793
+#endif
+
+#define M_TAU (2.0 * M_PI)
+
+namespace da {
+
+       // With g++ optimization -fcx-limited-range should be used for 5x performance boost.
+       
+       // Based on the description of Volodymyr Myrnyy in
+       // http://www.dspdesignline.com/showArticle.jhtml?printableArticle=true&articleId=199903272
+       template<unsigned P, typename T> struct DanielsonLanczos {
+               static void apply(std::complex<T>* data) {
+                       constexpr std::size_t N = 1 << P;
+                       constexpr std::size_t M = N / 2;
+                       // Compute even and odd halves
+                       DanielsonLanczos<P - 1, T>().apply(data);
+                       DanielsonLanczos<P - 1, T>().apply(data + M);
+                       // Combine the results
+                       std::complex<T> w(1.0);
+                       for (std::size_t i = 0; i < M; ++i) {
+                               const std::complex<T> temp = data[i + M] * w;
+                               data[M + i] = data[i] - temp;
+                               data[i] += temp;
+                               w *= std::polar<T>(1.0, -M_TAU / N);
+                       }
+               }
+       };
+
+       template<typename T> struct DanielsonLanczos<0, T> { static void apply(std::complex<T>*) {} };
+
+       /** Perform FFT on data. **/
+       template<unsigned P, typename T> void fft(std::complex<T>* data) {
+               // Perform bit-reversal sorting of sample data.
+               constexpr std::size_t N = 1 << P;
+               std::size_t j = 0;
+               for (std::size_t i = 0; i < N; ++i) {
+                       if (i < j) std::swap(data[i], data[j]);
+                       std::size_t m = N / 2;
+                       while (m > 1 && m <= j) { j -= m; m >>= 1; }
+                       j += m;
+               }
+               // Do the actual calculation
+               DanielsonLanczos<P, T>::apply(data);
+       }
+
+       /** Perform FFT on data from floating point iterator, windowing the input. **/
+       template<unsigned P, typename InIt, typename Window> std::vector<std::complex<float> > fft(InIt begin, Window window) {
+               std::vector<std::complex<float> > data(1 << P);
+               // Perform bit-reversal sorting of sample data.
+               constexpr std::size_t N = 1 << P;
+               std::size_t j = 0;
+               for (std::size_t i = 0; i < N; ++i) {
+                       data[j] = *begin++ * window[i];
+                       std::size_t m = N / 2;
+                       while (m > 1 && m <= j) { j -= m; m >>= 1; }
+                       j += m;
+               }
+               // Do the actual calculation
+               DanielsonLanczos<P, float>::apply(&data[0]);
+               return data;
+       }
+
+       template<unsigned P, typename T> void ifft(std::complex<T>* data) {
+               constexpr std::size_t N = 1 << P;
+               for (std::size_t i = 0; i < N; ++i) data[i] = std::conj(data[i]);  // Invert phase so that we can use FFT to do IFFT
+               fft<P>(data);
+               constexpr std::complex<T> scale(1.0/N, 0.0);
+               for (std::size_t i = 0; i < N; ++i) data[i] = scale * std::conj(data[i]);  // Invert back, and apply IFFT scaling
+       }
+       
+}
diff --git a/game/libda/mixer.hpp b/game/libda/mixer.hpp
new file mode 100644 (file)
index 0000000..cfc820a
--- /dev/null
@@ -0,0 +1,303 @@
+#pragma once
+
+/**
+ * @file mixer.hpp LibDA mixer interface, version 1.
+ *
+ * This appears to be too complex and will probably be removed in later release in
+ * favor of something easier and faster. Actually it is not even used currently.
+ */
+
+#include "audio.hpp"
+#include <boost/scoped_ptr.hpp>
+#include <boost/thread/recursive_mutex.hpp>
+//#include <boost/thread/mutex.hpp>
+#include <algorithm>
+#include <memory>
+
+namespace da {
+
+       template <typename T> class shared_reference_wrapper {
+         public:
+               typedef T type;
+               explicit shared_reference_wrapper(boost::shared_ptr<T> const& ptr): m_ptr(ptr) {}
+               bool operator()(pcm_data data) { return get()(data); }
+               operator T&() const { return *m_ptr; }
+               T& get() const { return *m_ptr; }
+               //T* get_pointer() const { return m_ptr; }
+         private:
+               boost::shared_ptr<T> m_ptr;
+       };
+
+       template <typename T> shared_reference_wrapper<T> shared_ref(T* ptr) {
+               return shared_reference_wrapper<T>(boost::shared_ptr<T>(ptr));
+       }
+
+       template <typename T> shared_reference_wrapper<T> shared_ref(boost::shared_ptr<T> const& ptr) {
+               return shared_reference_wrapper<T>(ptr);
+       }
+
+
+       class chain: boost::noncopyable {
+         public:
+               typedef std::vector<callback_t> streams_t;
+               void add(callback_t const& cb) { streams.push_back(cb); }
+               void clear() { streams.clear(); }
+               /** Calls every stream in the chain and removes those that return false. **/
+               bool operator()(pcm_data& data) {
+                       streams_t::iterator wr = streams.begin();
+                       for (streams_t::iterator it = wr; it != streams.end(); ++it) {
+                               if ((*it)(data)) *wr++ = *it;
+                       }
+                       if (wr != streams.end()) streams.erase(wr, streams.end());
+                       return !streams.empty();
+               }
+               streams_t streams;
+         private:
+       };
+
+       namespace {
+               bool voidOp(pcm_data const&) { return true; }
+               bool zero(pcm_data& data) {
+                       std::fill(data.rawbuf, data.rawbuf + (data.channels * data.frames), 0.0f);
+                       return true;
+               }
+       }
+
+       class accumulate: boost::noncopyable {
+         public:
+               typedef std::vector<callback_t> streams_t;
+               void add(callback_t const& cb) { streams.push_back(cb); }
+               void clear() { streams.clear(); }
+               /** Calls every stream in the chain and removes those that return false, summing the results. **/
+               bool operator()(pcm_data& data) {
+                       std::vector<sample_t> buffer(data.samples());
+                       pcm_data accumbuf(&buffer[0], data.frames, data.channels, data.rate);
+                       streams_t::iterator wr = streams.begin();
+                       for (streams_t::iterator it = wr; it != streams.end(); ++it) {
+                               if ((*it)(accumbuf)) *wr++ = *it;
+                               for (std::size_t i = 0; i < buffer.size(); ++i) {
+                                       data.rawbuf[i] += buffer[i];
+                                       buffer[i] = 0.0f;
+                               }
+                       }
+                       if (wr != streams.end()) streams.erase(wr, streams.end());
+                       return !streams.empty();
+               }
+               streams_t streams;
+         private:
+       };
+
+       class buffer: boost::noncopyable {
+         public:
+               explicit buffer(std::size_t s): m_data(s) {}
+               sample_t* begin() { return &m_data[0]; }
+               sample_t* end() { return begin() + m_data.size(); }
+         private:
+               std::vector<sample_t> m_data;
+       };
+
+       class stream: boost::noncopyable {
+         public:
+               stream(): m_pos() {}
+               bool operator()(pcm_data& data) {
+                       sample_t* b = m_buffer->begin();
+                       sample_t* e = m_buffer->end();
+                       size_t size = std::min<size_t>(data.frames * data.channels, e - b - m_pos);
+                       for (size_t i = 0; i < size; ++i, ++m_pos) {
+                               if (m_pos < 0) continue;
+                               data.rawbuf[i] += b[m_pos];
+                       }
+                       return true;
+               }
+         private:
+               boost::shared_ptr<buffer> m_buffer;
+               int64_t m_pos;
+       };
+
+       class fadeinOp: boost::noncopyable {
+         public:
+               fadeinOp(double time = 1.0, int64_t pos = 0): m_pos(pos), m_time(time) {}
+               bool operator()(pcm_data& data) {
+                       size_t end = m_time * data.rate;
+                       size_t size = data.frames * data.channels;
+                       if (m_pos > int64_t(end)) return 1.0f;
+                       for (size_t i = 0; i < size; ++i, ++m_pos) {
+                               if (m_pos < 0) data.rawbuf[i] = 0.0f;
+                               sample_t level = size_t(m_pos) < end ? sample_t(m_pos) / end : 1.0f;
+                               data.rawbuf[i] *= level;
+                       }
+                       return m_pos < int64_t(end);
+               }
+         private:
+               int64_t m_pos;
+               double m_time;
+       };
+
+       class fadeoutOp: boost::noncopyable {
+         public:
+               fadeoutOp(callback_t cb, double time = 1.0, int64_t pos = 0): m_stream(cb), m_pos(pos), m_time(time) {}
+               bool operator()(pcm_data& data) {
+                       bool ret = m_stream(data);
+                       size_t end = m_time * data.rate;
+                       size_t size = data.frames * data.channels;
+                       for (size_t i = 0; i < size; ++i, ++m_pos) {
+                               if (m_pos < 0) continue;
+                               sample_t level = size_t(m_pos) < end ? 1.0f - sample_t(m_pos) / end : 0.0f;
+                               data.rawbuf[i] *= level;
+                       }
+                       return ret && m_pos < int64_t(end);
+               }
+         private:
+               callback_t m_stream;
+               int64_t m_pos;
+               double m_time;
+       };
+
+       class volume {
+         public:
+               volume(sample_t level = 1.0f): m_level(level) {}
+               void level(sample_t level) { m_level = level; }
+               bool operator()(pcm_data& data) {
+                       if (m_level == 1.0f) return true;
+                       for (size_t i = 0, s = data.samples(); i < s; ++i) data.rawbuf[i] *= m_level;
+                       return true;
+               }
+         private:
+               sample_t m_level;
+       };
+
+       class scoped_lock: public boost::recursive_mutex::scoped_lock {
+         public:
+               template <typename T> scoped_lock(T& obj): boost::recursive_mutex::scoped_lock(obj.m_mutex) {}
+       };
+
+       class mutex_stream: boost::noncopyable {
+         public:
+               mutex_stream(callback_t const& stream): m_stream(stream) {}
+               bool operator()(pcm_data& data) {
+                       scoped_lock l(*this);
+                       if (!m_stream) return false;
+                       return m_stream(data);
+               }
+               void clear() {
+                       scoped_lock l(*this);
+                       m_stream.clear();
+               }
+         private:
+               callback_t m_stream;
+               mutable boost::recursive_mutex m_mutex;
+               friend class scoped_lock;
+       };
+
+       typedef std::auto_ptr<scoped_lock> lock_holder;
+
+       template <typename Key> class select {
+               typedef std::map<Key, callback_t> streams;
+         public:
+               void choose(Key const& k) {
+                       typename streams::iterator it = m_streams.find(k);
+                       if (it == m_streams.end()) throw std::logic_error("da::select::key: Invalid key");
+                       m_key = k;
+                       m_stream = it->second;
+               }
+               void insert(Key const& k, callback_t const& cb) {
+                       m_streams[k] = cb;
+               }
+               bool operator()(pcm_data& data) {
+                       if (!m_stream) return false;
+                       return m_stream(data);
+               }
+         private:
+               streams m_streams;
+               Key m_key;
+               callback_t m_stream;
+       };
+
+       class mixer {
+         public:
+               mixer(): m_mutex(boost::ref(m_select)) { init(); }
+               mixer(settings& s): m_mutex(boost::ref(m_select)) { init(); start(s); }
+               ~mixer() {
+                       // Make sure that all processing has stopped before exiting
+                       scoped_lock l(m_mutex);
+                       m_mutex.clear();
+                       m_playback.reset();
+               }
+               void start(settings& s) { m_settings = s; start(); s = m_settings; }
+               void start() {
+                       stop();
+                       m_settings.set_callback(boost::ref(m_mutex));
+                       m_playback.reset(new playback(m_settings));
+               }
+               void stop() { m_playback.reset(); }
+               bool started() const { return m_playback; }
+               void add(callback_t const& cb) {
+                       scoped_lock l(m_mutex);
+                       m_user.add(cb);
+               }
+               void fadein(callback_t const& cb, double time, double startpos = 0.0) {
+                       scoped_lock l(m_mutex);
+                       if (m_user.streams.size() <= 1) {
+                               // The simple case
+                               m_user.add(cb);
+                               m_user.add(shared_ref(new fadeinOp(time)));
+                               return;
+                       }
+                       // Make a new chain that produces the same output as the old one
+                       boost::shared_ptr<chain> origch(new chain());
+                       origch->streams.insert(origch->streams.end(), m_user.streams.begin() + 1, m_user.streams.end());
+                       // Make a new chain for cb + fade
+                       boost::shared_ptr<chain> fadech(new chain());
+                       fadech->add(cb);
+                       fadech->add(shared_ref(new fadeinOp(time, startpos * m_settings.rate() * m_settings.channels())));
+                       // Replace the output with accumulate of both chains
+                       clear();
+                       boost::shared_ptr<accumulate> accu(new accumulate());
+                       accu->add(shared_ref(origch));
+                       accu->add(shared_ref(fadech));
+                       add(shared_ref(accu));
+               }
+               void fadeout(double time, double startpos = 0.0) {
+                       scoped_lock l(m_mutex);
+                       if (m_user.streams.size() <= 1) return;
+                       // Make a new chain that produces the same output as the old one
+                       boost::shared_ptr<chain> ch(new chain());
+                       ch->streams.insert(ch->streams.end(), m_user.streams.begin() + 1, m_user.streams.end());
+                       // Replace the output with our new stream (with fade)
+                       clear();
+                       add(shared_ref(new fadeoutOp(shared_ref(ch), time, startpos * m_settings.rate() * m_settings.channels())));
+               }
+               void clear() {
+                       scoped_lock l(m_mutex);
+                       m_user.clear();
+                       m_user.add(voidOp);
+               }
+               void set_volume(sample_t level) {
+                       scoped_lock l(m_mutex);
+                       m_volume.level(level);
+               }
+               void pause(bool p) {
+                       scoped_lock l(m_mutex);
+                       m_select.choose(p ? "paused" : "normal");
+               }
+               settings get_settings() { return m_settings; }
+               lock_holder lock() const { return lock_holder(new scoped_lock(m_mutex)); }
+         private:
+               void init() {
+                       m_master.add(zero);
+                       m_master.add(boost::ref(m_user));
+                       m_master.add(boost::ref(m_volume));
+                       m_select.insert("paused", zero);
+                       m_select.insert("normal", boost::ref(m_master));
+                       pause(false);
+                       clear();
+               }
+               volume m_volume;
+               chain m_user;
+               chain m_master;
+               select<std::string> m_select;
+               mutex_stream m_mutex;
+               settings m_settings;
+               boost::scoped_ptr<playback> m_playback;
+       };
+}
diff --git a/game/libda/portaudio.hpp b/game/libda/portaudio.hpp
new file mode 100644 (file)
index 0000000..01fad16
--- /dev/null
@@ -0,0 +1,180 @@
+#pragma once
+
+/**
+ * @file portaudio.hpp OOP / RAII wrappers & utilities for PortAudio library.
+ */
+
+#include <boost/thread.hpp>
+#include <boost/regex.hpp>
+#include <portaudio.h>
+#include <cstdlib>
+#include <stdexcept>
+#include <stdint.h>
+
+#include "../unicode.hh"
+
+#define PORTAUDIO_CHECKED(func, args) portaudio::internal::check(func args, #func)
+
+namespace portaudio {
+       class Error: public std::runtime_error {
+       public:
+               Error(PaError code_, char const* func_):
+                 runtime_error(std::string(func_) + " failed: " + Pa_GetErrorText(code_)),
+                 m_code(code_),
+                 m_func(func_)
+               {}
+               PaError code() const { return m_code; }
+               std::string func() const { return m_func; }
+       private:
+               PaError m_code;
+               char const* m_func;
+       };
+
+       namespace internal {
+               void inline check(PaError code, char const* func) { if (code != paNoError) throw Error(code, func); }
+       }
+
+       struct DeviceInfo {
+               DeviceInfo(int id, std::string n = std::string(), int i = 0, int o = 0): name(n), flex(n), idx(id), in(i), out(o) {}
+               std::string desc() const {
+                       std::ostringstream oss;
+                       oss << name << " (";
+                       if (in) oss << in << " in";
+                       if (in && out) oss << ", ";
+                       if (out) oss << out << " out";
+                       oss << ")";
+                       return oss.str();
+               }
+               std::string name;  ///< Full device name in UTF-8
+               std::string flex;  ///< Modified name that is less specific but still unique (allow device numbers to change)
+               int idx;
+               int in, out;
+       };
+
+       typedef std::vector<DeviceInfo> DeviceInfos;
+
+       struct AudioDevices {
+               static int count() { return Pa_GetDeviceCount(); }
+               /// Constructor gets the PA devices into a vector
+               AudioDevices() {
+                       for (unsigned i = 0, end = Pa_GetDeviceCount(); i != end; ++i) {
+                               PaDeviceInfo const* info = Pa_GetDeviceInfo(i);
+                               if (!info) continue;
+                               std::string name = convertToUTF8(info->name);
+                               /// Omit some useless legacy devices of PortAudio/ALSA from our list
+                               for (auto const& dev: { "front", "surround40", "surround41", "surround50", "surround51", "surround71", "iec958", "spdif", "dmix" }) {
+                                       if (name.find(dev) != std::string::npos) name.clear();
+                               }
+                               if (name.empty()) continue;  // No acceptable device found
+                               // Verify that the name is unique (haven't seen duplicate names occur though)
+                               std::string n = name;
+                               while (true) {
+                                       int num = 1;
+                                       for (auto& dev: devices) if (dev.name == n) goto rename;
+                                       break;
+                               rename:
+                                       std::ostringstream oss;
+                                       oss << name << " #" << ++num;
+                                       n = oss.str();
+                               };
+                               devices.push_back(DeviceInfo(i, name, info->maxInputChannels, info->maxOutputChannels));
+                       }
+                       for (auto& dev: devices) {
+                               // Array of regex - replacement pairs
+                               static char const* const replacements[][2] = {
+                                       { "\\(hw:\\d+,", "(hw:," },  // Remove ALSA device numbers
+                                       { " \\(.*\\)", "" },  // Remove the parenthesis part entirely
+                               };
+                               for (auto const& rep: replacements) {
+                                       std::string flex = boost::regex_replace(dev.flex, boost::regex(rep[0]), rep[1]);
+                                       if (flex == dev.flex) continue;  // Nothing changed
+                                       // Verify that flex doesn't find any wrong devices
+                                       bool fail = false;
+                                       try {
+                                               if (find(flex).idx != dev.idx) fail = true;
+                                       } catch (...) {}  // Failure to find anything is success
+                                       if (!fail) dev.flex = flex;
+                               }
+                       }
+               }
+               /// Get a printable dump of the devices
+               std::string dump() const {
+                       std::ostringstream oss;
+                       oss << "PortAudio devices:" << std::endl;
+                       for (auto const& d: devices) oss << "  #" << d.idx << " " << d.desc() << std::endl;
+                       oss << std::endl;
+                       return oss.str();
+               }
+               DeviceInfo const& find(std::string const& name) {
+                       // Try name search with full match
+                       for (auto const& dev: devices) if (dev.name == name) return dev;
+                       // Try name search with partial/flexible match
+                       for (auto const& dev: devices) {
+                               if (dev.name.find(name) != std::string::npos) return dev;
+                               if (dev.flex.find(name) != std::string::npos) return dev;
+                       }
+                       throw std::runtime_error("No such device.");
+               }
+               DeviceInfos devices;
+       };
+
+       struct Init {
+               Init() { PORTAUDIO_CHECKED(Pa_Initialize, ()); }
+               ~Init() { Pa_Terminate(); }
+       };
+
+       struct Params {
+               PaStreamParameters params;
+               Params(PaStreamParameters const& init = PaStreamParameters()): params(init) {
+                       // Some useful defaults so that things just work (channel count must be set by user anyway)
+                       if (params.channelCount == 0) sampleFormat(paFloat32).suggestedLatency(0.05);
+               }
+               Params& channelCount(int val) { params.channelCount = val; return *this; }
+               Params& device(PaDeviceIndex val) { params.device = val; return *this; }
+               Params& sampleFormat(PaSampleFormat val) { params.sampleFormat = val; return *this; }
+               Params& suggestedLatency(PaTime val) { params.suggestedLatency = val; return *this; }
+               Params& hostApiSpecificStreamInfo(void* val) { params.hostApiSpecificStreamInfo = val; return *this; }
+               operator PaStreamParameters const*() const { return params.channelCount > 0 ? &params : nullptr; }
+       };
+
+       template <typename Functor> int functorCallback(void const* input, void* output, unsigned long frameCount, const PaStreamCallbackTimeInfo* timeInfo, PaStreamCallbackFlags statusFlags, void* userData) {
+               Functor* ptr = *reinterpret_cast<Functor**>(&userData);
+               return (*ptr)(input, output, frameCount, timeInfo, statusFlags);
+       }
+
+       class Stream {
+               PaStream* m_handle;
+       public:
+               /// Construct a stream as with Pa_OpenStream
+               Stream(
+                 PaStreamParameters const* input,
+                 PaStreamParameters const* output,
+                 double sampleRate,
+                 unsigned long framesPerBuffer = paFramesPerBufferUnspecified,
+                 PaStreamFlags flags = paNoFlag,
+                 PaStreamCallback* callback = NULL,
+                 void* userData = NULL)
+               {
+                       PORTAUDIO_CHECKED(Pa_OpenStream, (&m_handle, input, output, sampleRate, framesPerBuffer, flags, callback, userData));
+               }
+               /// Construct stream using a C++ functor as callback
+               template <typename Functor> Stream(
+                 Functor& functor,
+                 PaStreamParameters const* input,
+                 PaStreamParameters const* output,
+                 double sampleRate,
+                 unsigned long framesPerBuffer = paFramesPerBufferUnspecified,
+                 PaStreamFlags flags = paNoFlag
+               ): Stream(input, output, sampleRate, framesPerBuffer, flags, functorCallback<Functor>, (void*)(intptr_t)&functor) {}
+               ~Stream() {
+                       // Give audio a little time to shutdown but then just quit
+                       boost::thread audiokiller(Pa_CloseStream, m_handle);
+                       if (!audiokiller.timed_join(boost::posix_time::milliseconds(5000))) {
+                               std::cout << "PortAudio BUG: Pa_CloseStream hung for more than five seconds. Aborting." << std::endl;
+                               std::abort();  // Crash. Calling exit() is prone to hang.
+                       }
+               }
+               operator PaStream*() { return m_handle; }
+       };
+
+}
diff --git a/game/libda/sample.hpp b/game/libda/sample.hpp
new file mode 100644 (file)
index 0000000..a6d0bc6
--- /dev/null
@@ -0,0 +1,81 @@
+#pragma once
+
+#include <cmath>
+
+/**
+ * @file sample.hpp Sample format definition and format conversions.
+ */
+
+namespace da {
+
+       using namespace std;  // For std::round which apparently is not in std namespace on mingw and thus cannot be directly used
+       
+       // Should be a floating-point type
+       typedef float sample_t;
+
+       // A helper function for clamping a value to a certain range
+       template <typename T> T clamp(T val, T min, T max) {
+               if (val < min) val = min;
+               if (val > max) val = max;
+               return val;
+       }
+
+       constexpr sample_t max_s16(32767), min_s16 = -max_s16 - sample_t(1);
+       constexpr sample_t max_s24(8388607), min_s24 = -max_s24 - sample_t(1);
+       constexpr sample_t max_s32(2147483647), min_s32= -max_s32 - sample_t(1);
+       constexpr double tau(6.2831853071795864769252867665590057683943387987502116);  ///< One full circle
+       constexpr double pi = tau / sample_t(2);  ///< Half circle
+       constexpr double eps(1e-10);  ///< Tiny positive value
+       
+       /// Mathematical sinc function
+       template<typename Float> static inline Float msinc(Float x) { return std::abs(x) < Float(eps) ? Float(1) : std::sin(x) / x; }
+       
+       /// Normalized (signal processing) sinc function
+       template<typename Float> static inline Float sinc(Float x) { return msinc(Float(pi) * x); }
+       
+       /// Lanczos kernel of size A
+       template<unsigned A, typename Float> static inline Float lanc(Float x) {
+               return std::abs(x) < A ? sinc(x) * sinc(x / A) : Float();
+       }
+
+       // The following conversions provide lossless conversions between floats
+       // and integers. Be sure to use only these conversions or otherwise the
+       // conversions may not be lossless, due to different scaling factors being
+       // used by different libraries.
+
+       // The negative minimum integer value produces sample_t value slightly
+       // more negative than -1.0 but this is necessary in order to prevent
+       // clipping in the float-to-int conversions. Now amplitude 1.0 in floating
+       // point produces -32767 .. 32767 symmetrical non-clipping range in s16.
+
+       static inline sample_t conv_from_s16(int s) { return s / max_s16; }
+       static inline sample_t conv_from_s24(int s) { return s / max_s24; }
+       static inline sample_t conv_from_s32(int s) { return s / max_s32; }
+       // The rounding is strictly not necessary, but it greatly improves
+       // the error tolerance if any floating point calculations are done.
+       // The ugly static_casts are required to avoid warnings in MSVC.
+       static inline int conv_to_s16(sample_t s) { return clamp(static_cast<int>(round(s * max_s16)), static_cast<int>(min_s16), static_cast<int>(max_s16)); }
+       static inline int conv_to_s24(sample_t s) { return clamp(static_cast<int>(round(s * max_s24)), static_cast<int>(min_s24), static_cast<int>(max_s24)); }
+       static inline int conv_to_s32(sample_t s) { return static_cast<int>(clamp(static_cast<sample_t>(round(s * max_s32)), min_s32, max_s32 )); }
+       // Non-rounding non-clamping versions are provided for very low end devices (still lossless)
+       static inline int conv_to_s16_fast(sample_t s) { return static_cast<int>(s * max_s16); }
+       static inline int conv_to_s24_fast(sample_t s) { return static_cast<int>(s * max_s24); }
+       static inline int conv_to_s32_fast(sample_t s) { return static_cast<int>(s * max_s32); }
+
+       template <typename ValueType> class step_iterator: public std::iterator<std::random_access_iterator_tag, ValueType> {
+               ValueType* m_pos;
+               std::ptrdiff_t m_step;
+         public:
+               step_iterator(ValueType* pos, std::ptrdiff_t step): m_pos(pos), m_step(step) {}
+               ValueType& operator*() { return *m_pos; }
+               step_iterator operator+(std::ptrdiff_t rhs) { return step_iterator(m_pos + m_step * rhs, m_step); }
+               step_iterator& operator++() { m_pos += m_step; return *this; }
+               step_iterator operator++(int) { step_iterator ret = *this; ++*this; return ret; }
+               bool operator!=(step_iterator const& rhs) const { return m_pos != rhs.m_pos; }
+               std::ptrdiff_t operator-(step_iterator const& rhs) const { return (m_pos - rhs.m_pos) / m_step; }
+               // TODO: more operators
+       };
+
+       typedef step_iterator<sample_t> sample_iterator;
+       typedef step_iterator<sample_t const> sample_const_iterator;
+}
diff --git a/game/log.cc b/game/log.cc
new file mode 100644 (file)
index 0000000..16a0ebc
--- /dev/null
@@ -0,0 +1,148 @@
+#include "log.hh"
+
+#include "fs.hh"
+#include <boost/filesystem/fstream.hpp>
+#include <boost/iostreams/stream_buffer.hpp>
+#include <boost/thread/mutex.hpp>
+#include <iostream>
+#include <stdexcept>
+
+/** \file
+ * \brief The std::clog logger.
+ *
+ * General message format: <tt>subsystem/level: message</tt>
+ *
+ * Example:
+ * \code
+ * std::clog << "foo/info: Here's an info message from subsystem foo" << std::endl;
+ * \endcode
+ *
+ * Each message may contain newlines and flushing the stream (i.e. by std::endl or std::flush) must be done
+ * when and only when the message is complete.
+ *
+ * Any lower-case subsystem name including hyphens may be used. The levels, in descending order of priority
+ * are as follows:
+ *
+ * error    A serious and rare message that usually means that a function requested by user cannot be completed.
+ * warning  Less critical errors that should still be emitted sparingly (consider using "debug" for repeated warnings).
+ * notice   A non-error situation that might still require user attention (the lowest level displayed by default).
+ * info     Any information that might be of interest but that does not appear too often and glog the log output.
+ * debug    Any information that is flooded so much that it should normally be suppressed.
+ *
+ * The user may either choose a desired level of messages to emit, or he may choose a specific subsystem (by
+ * substring search) to be monitored all the way down to debug level, in which case only errors from any other
+ * subsystems will be printed.
+ *
+ **/
+
+/** \internal
+ * Guard to ensure we're atomically printing to cerr.
+ * \attention This only guards from multiple clog interleaving, not other console I/O.
+ */
+boost::mutex log_lock;
+
+/** \internal The implementation of the stream filter that handles the message filtering. **/
+class VerboseMessageSink : public boost::iostreams::sink {
+  public:
+       std::streamsize write(const char* s, std::streamsize n);
+};
+
+// defining them in main() causes segfault at exit as they apparently got free'd before we're done using them
+static boost::iostreams::stream_buffer<VerboseMessageSink> sb; //!< \internal
+static VerboseMessageSink vsm; //!< \internal
+
+//! \internal used to store the default/original clog buffer.
+static std::streambuf* default_ClogBuf = nullptr;
+
+fs::ofstream file;
+
+std::string target;
+int minLevel;
+
+void writeLog(std::string const& msg) {
+       boost::mutex::scoped_lock l(log_lock);
+       std::cerr << msg << std::flush;
+       file << msg << std::flush;
+}
+
+int numeric(std::string const& level) {
+       if (level == "debug") return 0;
+       if (level == "info") return 1;
+       if (level == "notice") return 2;
+       if (level == "warning") return 3;
+       if (level == "error") return 4;
+       return -1;
+}
+
+std::streamsize VerboseMessageSink::write(const char* s, std::streamsize n) {
+       std::string line(s, n);  // Note: s is *not* a c-string, thus we must stop after n chars.
+       // Parse prefix as subsystem/level:...
+       size_t slash = line.find('/');
+       size_t colon = line.find(": ", slash);
+       if (slash == std::string::npos || colon == std::string::npos) {
+               std::string msg = "logger/error: Invalid log prefix on line [[[\n" + line + "]]]\n";
+               write(msg.data(), msg.size());
+               return n;
+       }
+       std::string subsystem(line, 0, slash);
+       std::string level(line, slash + 1, colon - slash - 1);
+       int lev = numeric(level);
+       if (lev == -1) {
+               std::string msg = "logger/error: Invalid level '" + level + "' line [[[\n" + line + "]]]\n";
+               write(msg.data(), msg.size());
+               return n;
+       }
+       if (lev >= minLevel || (!target.empty() && subsystem.find(target) != std::string::npos)) {
+               writeLog(line);
+       }
+       return n;
+}
+
+Logger::Logger(std::string const& level) {
+       if (default_ClogBuf) throw std::logic_error("Multiple loggers constructed. There can only be one.");
+       if (level.find_first_of(":/_* ") != std::string::npos) throw std::runtime_error("Invalid logging level specified. Specify either a subsystem name or a level (debug, info, notice, warning, error).");
+       pathBootstrap();  // So that log filename is known...
+       std::string msg = "logger/notice: Logging ";
+       {
+               boost::mutex::scoped_lock l(log_lock);
+               if (level.empty()) {
+                       minLevel = 2;  // Display all notices, warnings and errors
+                       msg += "all notices, warnings and errors.";
+               } else if (level == "none") {
+                       minLevel = 100;
+                       msg += "disabled.";  // No-one will see this, so what's the point? :)
+               } else {
+                       minLevel = numeric(level);
+                       if (minLevel == -1 /* Not a valid level name */) {
+                               minLevel = 4;  // Display errors from any subsystem
+                               target = level;  // All messages from the given subsystem
+                               msg += "everything from subsystem " + target + " and all errors.";
+                       } else {
+                               msg += "any events of " + level + " or higher level.";
+                       }
+               }
+               if (minLevel < 100) {
+                       fs::path name = getLogFilename();
+                       file.open(name);
+                       msg += " Log file: " + name.string();
+               }
+               sb.open(vsm);
+               default_ClogBuf = std::clog.rdbuf();
+               std::clog.rdbuf(&sb);
+               atexit(Logger::teardown);
+       }
+       std::clog << msg << std::endl;
+}
+
+Logger::~Logger() { teardown(); }
+
+void Logger::teardown() {
+       if (default_ClogBuf) std::clog << "logger/info: Exiting normally." << std::endl;
+       boost::mutex::scoped_lock l(log_lock);
+       if (!default_ClogBuf) return;
+       std::clog.rdbuf(default_ClogBuf);
+       sb.close();
+       file.close();
+       default_ClogBuf = nullptr;
+}
+
diff --git a/game/log.hh b/game/log.hh
new file mode 100644 (file)
index 0000000..c86f4b3
--- /dev/null
@@ -0,0 +1,11 @@
+#pragma once
+
+#include <string>
+
+class Logger {
+public:
+       Logger(std::string const& level);
+       ~Logger();
+       static void teardown();
+};
+
diff --git a/game/main.cc b/game/main.cc
new file mode 100644 (file)
index 0000000..531f7f4
--- /dev/null
@@ -0,0 +1,389 @@
+
+#include "backgrounds.hh"
+#include "config.hh"
+#include "controllers.hh"
+#include "database.hh"
+#include "fs.hh"
+#include "glutil.hh"
+#include "i18n.hh"
+#include "log.hh"
+#include "profiler.hh"
+#include "screen.hh"
+#include "songs.hh"
+#include "video_driver.hh"
+#include "webcam.hh"
+#include "xtime.hh"
+
+// Screens
+#include "screen_intro.hh"
+#include "screen_songs.hh"
+#include "screen_sing.hh"
+#include "screen_practice.hh"
+#include "screen_audiodevices.hh"
+#include "screen_paths.hh"
+#include "screen_players.hh"
+#include "screen_playlist.hh"
+
+#include <boost/bind.hpp>
+#include <boost/format.hpp>
+#include <boost/program_options.hpp>
+#include <boost/thread.hpp>
+#include <csignal>
+#include <string>
+#include <vector>
+#include <cstdlib>
+
+// Disable main level exception handling for debug builds (because gdb cannot properly catch throwing otherwise)
+#ifdef NDEBUG
+#define RUNTIME_ERROR std::runtime_error
+#define EXCEPTION std::exception
+#else
+namespace { struct Nothing { char const* what() const { return NULL; } }; }
+#define RUNTIME_ERROR Nothing
+#define EXCEPTION Nothing
+#endif
+
+volatile bool g_quit = false;
+
+bool g_take_screenshot = false;
+
+// Signal handling for Ctrl-C
+
+static void signalSetup();
+
+extern "C" void quit(int) {
+       using namespace std; // Apparently some implementations put quick_exit in std:: and others in ::
+       if (g_quit) abort();  // Instant exit if Ctrl+C is pressed again
+       g_quit = true;
+       signalSetup();
+}
+
+static void signalSetup() {
+       std::signal(SIGINT, quit);
+       std::signal(SIGTERM, quit);
+}
+
+/// can be thrown as an exception to quit the game
+struct QuitNow {};
+
+static void checkEvents(Game& gm) {
+       if (g_quit) {
+               std::cerr << "Terminating, please wait... (or kill the process)" << std::endl;
+               throw QuitNow();
+       }
+       SDL_Event event;
+       while(SDL_PollEvent(&event) == 1) {
+               // Let the navigation system grab any and all SDL events
+               boost::xtime eventTime = now();
+               gm.controllers.pushEvent(event, eventTime);
+               switch(event.type) {
+                 case SDL_QUIT:
+                       gm.finished();
+                       break;
+                 case SDL_KEYDOWN:
+                       int keypressed  = event.key.keysym.sym;
+                       uint16_t modifier = event.key.keysym.mod;
+                       if (((keypressed == SDLK_RETURN || keypressed == SDLK_KP_ENTER) && modifier & KMOD_ALT) || keypressed == SDLK_F11) {
+                               config["graphic/fullscreen"].b() = !config["graphic/fullscreen"].b();
+                               continue; // Already handled here...
+                       }
+                       if (keypressed == SDLK_PRINTSCREEN || (keypressed == SDLK_F12 && (modifier & KMOD_CTRL))) {
+                               g_take_screenshot = true;
+                               continue; // Already handled here...
+                       }
+                       if (keypressed == SDLK_F4 && modifier & KMOD_ALT) {
+                               gm.finished();
+                               continue; // Already handled here...
+                       }
+                       break;
+               }
+               // Screens always receive SDL events that were not already handled here
+               gm.window().resize();
+               gm.getCurrentScreen()->manageEvent(event);
+       }
+       for (input::NavEvent event; gm.controllers.getNav(event); ) {
+               input::NavButton nav = event.button;
+               // Volume control
+               if (nav == input::NAV_VOLUME_UP || nav == input::NAV_VOLUME_DOWN) {
+                       std::string curS = gm.getCurrentScreen()->getName();
+                       // Pick proper setting
+                       std::string which_vol = (curS == "Sing" || curS == "Practice")
+                         ? "audio/music_volume" : "audio/preview_volume";
+                       // Adjust value
+                       if (nav == input::NAV_VOLUME_UP) ++config[which_vol]; else --config[which_vol];
+                       // Show message
+                       gm.flashMessage(config[which_vol].getShortDesc() + ": " + config[which_vol].getValue());
+                       continue; // Already handled here...
+               }
+               // If a dialog is open, any nav event will close it
+               if (gm.isDialogOpen()) { gm.closeDialog(); continue; }
+               // Let the current screen handle other events
+               gm.getCurrentScreen()->manageEvent(event);
+       }
+
+       // Need to toggle full screen mode?
+       if (config["graphic/fullscreen"].b() != gm.window().getFullscreen()) {
+               gm.window().setFullscreen(config["graphic/fullscreen"].b());
+               gm.reloadGL();
+       }
+}
+
+void mainLoop(std::string const& songlist) {
+       std::clog << "core/notice: Starting the audio subsystem (errors printed on console may be ignored)." << std::endl;
+       Audio audio;
+       std::clog << "core/info: Loading assets." << std::endl;
+       Gettext localization(PACKAGE);
+       Window window(config["graphic/window_width"].i(), config["graphic/window_height"].i(), config["graphic/fullscreen"].b());
+       SurfaceLoader m_loader;
+       Backgrounds backgrounds;
+       Database database(getConfigDir() / "database.xml");
+       Songs songs(database, songlist);
+       loadFonts();
+       Game gm(window);
+       try {
+               // Load audio samples
+               gm.loading(_("Loading audio samples..."), 0.5);
+               audio.loadSample("drum bass", findFile("sounds/drum_bass.ogg"));
+               audio.loadSample("drum snare", findFile("sounds/drum_snare.ogg"));
+               audio.loadSample("drum hi-hat", findFile("sounds/drum_hi-hat.ogg"));
+               audio.loadSample("drum tom1", findFile("sounds/drum_tom1.ogg"));
+               audio.loadSample("drum cymbal", findFile("sounds/drum_cymbal.ogg"));
+               //audio.loadSample("drum tom2", findFile("sounds/drum_tom2.ogg"));
+               audio.loadSample("guitar fail1", findFile("sounds/guitar_fail1.ogg"));
+               audio.loadSample("guitar fail2", findFile("sounds/guitar_fail2.ogg"));
+               audio.loadSample("guitar fail3", findFile("sounds/guitar_fail3.ogg"));
+               audio.loadSample("guitar fail4", findFile("sounds/guitar_fail4.ogg"));
+               audio.loadSample("guitar fail5", findFile("sounds/guitar_fail5.ogg"));
+               audio.loadSample("guitar fail6", findFile("sounds/guitar_fail6.ogg"));
+               // Load screens
+               gm.loading(_("Creating screens..."), 0.7);
+               gm.addScreen(new ScreenIntro("Intro", audio));
+               gm.addScreen(new ScreenSongs("Songs", audio, songs, database));
+               gm.addScreen(new ScreenSing("Sing", audio, database, backgrounds));
+               gm.addScreen(new ScreenPractice("Practice", audio));
+               gm.addScreen(new ScreenAudioDevices("AudioDevices", audio));
+               gm.addScreen(new ScreenPaths("Paths", audio));
+               gm.addScreen(new ScreenPlayers("Players", audio, database));
+               gm.addScreen(new ScreenPlaylist("Playlist", audio, songs, backgrounds));
+               gm.activateScreen("Intro");
+               gm.loading(_("Entering main menu"), 0.8);
+               gm.updateScreen();  // exit/enter, any exception is fatal error
+               gm.loading(_("Loading complete"), 1.0);
+               // Main loop
+               boost::xtime time = now();
+               unsigned frames = 0;
+               std::clog << "core/info: Assets loaded, entering main loop." << std::endl;
+               while (!gm.isFinished()) {
+                       Profiler prof("mainloop");
+                       bool benchmarking = config["graphic/fps"].b();
+                       if( g_take_screenshot ) {
+                               try {
+                                       window.screenshot();
+                                       gm.flashMessage(_("Screenshot taken!"));
+                               } catch (EXCEPTION& e) {
+                                       std::cerr << "ERROR: " << e.what() << std::endl;
+                                       gm.flashMessage(_("Screenshot failed!"));
+                               }
+                               g_take_screenshot = false;
+                       }
+                       gm.updateScreen();  // exit/enter, any exception is fatal error
+                       if (benchmarking) prof("misc");
+                       try {
+                               window.blank();
+                               // Draw
+                               window.render(boost::bind(&Game::drawScreen, &gm));
+                               if (benchmarking) { glFinish(); prof("draw"); }
+                               // Display (and wait until next frame)
+                               window.swap();
+                               if (benchmarking) { glFinish(); prof("swap"); }
+                               updateSurfaces();
+                               gm.prepareScreen();
+                               if (benchmarking) { glFinish(); prof("surfaces"); }
+                               if (benchmarking) {
+                                       ++frames;
+                                       if (now() - time > 1.0) {
+                                               std::ostringstream oss;
+                                               oss << frames << " FPS";
+                                               gm.flashMessage(oss.str());
+                                               time += 1.0;
+                                               frames = 0;
+                                       }
+                               } else {
+                                       boost::thread::sleep(time + 0.01); // Max 100 FPS
+                                       time = now();
+                                       frames = 0;
+                               }
+                               if (benchmarking) prof("fpsctrl");
+                               // Process events for the next frame
+                               gm.controllers.process(now());
+                               checkEvents(gm);
+                               if (benchmarking) prof("events");
+                       } catch (RUNTIME_ERROR& e) {
+                               std::cerr << "ERROR: " << e.what() << std::endl;
+                               gm.flashMessage(std::string("ERROR: ") + e.what());
+                       }
+               }
+       } catch (EXCEPTION& e) {
+               std::clog << "core/error: Exiting due to fatal error: " << e.what() << std::endl;
+               gm.fatalError(e.what());  // Notify the user
+               throw;
+       } catch (QuitNow&) {
+               std::cerr << "Terminated." << std::endl;
+       }
+}
+
+/// Simple test utility to make mapping of joystick buttons/axes easier
+void jstestLoop() {
+       try {
+               Window window(config["graphic/window_width"].i(), config["graphic/window_height"].i(), false);
+               // Main loop
+               boost::xtime time = now();
+               int oldjoy = -1, oldaxis = -1, oldvalue = -1;
+               while (true) {
+                       SDL_Event e;
+                       while(SDL_PollEvent(&e) == 1) {
+                               if (e.type == SDL_QUIT || (e.type == SDL_KEYDOWN && e.key.keysym.sym == SDLK_ESCAPE)) {
+                                       return;
+                               } else if (e.type == SDL_KEYDOWN) {
+                                       std::cout << "Keyboard key: " << int(e.key.keysym.sym) << ", mod: " << int(e.key.keysym.mod) << std::endl;
+                               } else if (e.type == SDL_JOYBUTTONDOWN) {
+                                       std::cout << "JoyID: " << int(e.jbutton.which) << ", button: " << int(e.jbutton.button) << ", state: " << int(e.jbutton.state) << std::endl;
+                               } else if (e.type == SDL_JOYAXISMOTION) {
+                                       if ((oldjoy != int(e.jaxis.which)) || (oldaxis != int(e.jaxis.axis)) || (oldvalue != int(e.jaxis.value))) {
+                                               std::cout << "JoyID: " << int(e.jaxis.which) << ", axis: " << int(e.jaxis.axis) << ", value: " << int(e.jaxis.value) << std::endl;
+                                               oldjoy = int(e.jaxis.which);
+                                               oldaxis = int(e.jaxis.axis);
+                                               oldvalue = int(e.jaxis.value);
+                                       }
+                               } else if (e.type == SDL_JOYHATMOTION) {
+                                       std::cout << "JoyID: " << int(e.jhat.which) << ", hat: " << int(e.jhat.hat) << ", value: " << int(e.jhat.value) << std::endl;
+                               }
+                       }
+                       window.blank(); window.swap();
+                       boost::thread::sleep(time + 0.01); // Max 100 FPS
+                       time = now();
+               }
+       } catch (EXCEPTION& e) {
+               std::cerr << "ERROR: " << e.what() << std::endl;
+       } catch (QuitNow&) {
+               std::cerr << "Terminated." << std::endl;
+       }
+       return;
+}
+
+template <typename Container> void confOverride(Container const& c, std::string const& name) {
+       if (c.empty()) return;  // Don't override if no options specified
+       ConfigItem::StringList& sl = config[name].sl();
+       sl.clear();
+       std::copy(c.begin(), c.end(), std::back_inserter(sl));
+}
+
+void outputOptionalFeatureStatus();
+
+int main(int argc, char** argv) try {
+       signalSetup();
+       std::ios::sync_with_stdio(false);  // We do not use C stdio
+       std::srand(std::time(nullptr));
+       // Parse commandline options
+       std::vector<std::string> devices;
+       std::vector<std::string> songdirs;
+       namespace po = boost::program_options;
+       po::options_description opt1("Generic options");
+       std::string songlist;
+       std::string loglevel;
+       opt1.add_options()
+         ("help,h", "you are viewing it")
+         ("log,l", po::value<std::string>(&loglevel), "subsystem name or minimum level to log")
+         ("version,v", "display version number")
+         ("songlist", po::value<std::string>(&songlist), "save a list of songs in the specified folder");
+       po::options_description opt2("Configuration options");
+       opt2.add_options()
+         ("audio", po::value<std::vector<std::string> >(&devices)->composing(), "specify an audio device to use")
+         ("audiohelp", "print audio related information")
+         ("jstest", "utility to get joystick button mappings");
+       po::options_description opt3("Hidden options");
+       opt3.add_options()
+         ("songdir", po::value<std::vector<std::string> >(&songdirs)->composing(), "");
+       // Process flagless options as songdirs
+       po::positional_options_description p;
+       p.add("songdir", -1);
+       po::options_description cmdline;
+       cmdline.add(opt1).add(opt2);
+       po::variables_map vm;
+       // Load the arguments
+       try {
+               po::options_description allopts(cmdline);
+               allopts.add(opt3);
+               po::store(po::command_line_parser(argc, argv).options(allopts).positional(p).run(), vm);
+       } catch (EXCEPTION& e) {
+               std::cerr << cmdline << std::endl;
+               std::cerr << "ERROR: " << e.what() << std::endl;
+               return EXIT_FAILURE;
+       }
+       po::notify(vm);
+
+       if (vm.count("version")) {
+               std::cout << PACKAGE " " VERSION << std::endl;
+               return EXIT_SUCCESS;
+       }
+       if (vm.count("help")) {
+               std::cout << cmdline << "  any arguments without a switch are interpreted as song folders.\n" << std::endl;
+               return EXIT_SUCCESS;
+       }
+
+       Logger logger(loglevel);
+       outputOptionalFeatureStatus();
+
+       // Read config files
+       try {
+               readConfig();
+       } catch (EXCEPTION& e) {
+               std::clog << "core/error: Error loading configuration: " << e.what() << std::endl;
+               return EXIT_FAILURE;
+       }
+       if (vm.count("audiohelp")) {
+               std::clog << "core/notice: Starting audio subsystem for audiohelp (errors printed on console may be ignored)." << std::endl;
+               Audio audio;
+               // Print the devices
+               portaudio::AudioDevices ads;
+               std::cout << ads.dump();
+               // Some examples
+               std::cout << "Example --audio parameters" << std::endl;
+               std::cout << "  --audio \"out=2\"         # Pick first working two-channel playback device" << std::endl;
+               std::cout << "  --audio \"dev=1 out=2\"   # Pick device id 1 and assign stereo playback" << std::endl;
+               std::cout << "  --audio 'dev=\"HDA Intel\" mics=blue,red'   # HDA Intel with two mics" << std::endl;
+               std::cout << "  --audio 'dev=pulse out=2 mics=blue'       # PulseAudio with input and output" << std::endl;
+               // Give audio a little time to shutdown but then just quit
+               boost::thread audiokiller(boost::bind(&Audio::close, boost::ref(audio)));
+               if (!audiokiller.timed_join(boost::posix_time::milliseconds(2000)))
+                 std::clog << "core/warning: Closing audio hung for over two seconds." << std::endl;
+               return EXIT_SUCCESS;
+       }
+       // Override XML config for options that were specified from commandline or performous.conf
+       confOverride(songdirs, "paths/songs");
+       confOverride(devices, "audio/devices");
+       getPaths(); // Initialize paths before other threads start
+       if (vm.count("jstest")) { // Joystick test program
+               std::clog << "core/notice: Starting jstest input test utility." << std::endl;
+               std::cout << std::endl << "Joystick utility - Touch your joystick to see buttons here" << std::endl
+               << "Hit ESC (window focused) to quit" << std::endl << std::endl;
+               jstestLoop();
+               return EXIT_SUCCESS;
+       }
+       // Run the game init and main loop
+       mainLoop(songlist);
+
+       return EXIT_SUCCESS; // Do not remove. SDL_Main (which this function is called on some platforms) needs return statement.
+} catch (EXCEPTION& e) {
+       std::cerr << "FATAL ERROR: " << e.what() << std::endl;
+       return EXIT_FAILURE;
+}
+
+void outputOptionalFeatureStatus() {
+       std::clog << "core/notice: " PACKAGE " " VERSION " starting..."
+         << "\n  Build date:           " __DATE__
+         << "\n  Internationalization: " << (Gettext::enabled() ? "Enabled" : "Disabled")
+         << "\n  MIDI Hardware I/O:    " << (input::Hardware::midiEnabled() ? "Enabled" : "Disabled")
+         << "\n  Webcam support:       " << (Webcam::enabled() ? "Enabled" : "Disabled")
+         << std::endl;
+}
diff --git a/game/menu.cc b/game/menu.cc
new file mode 100644 (file)
index 0000000..fc7c263
--- /dev/null
@@ -0,0 +1,97 @@
+#include "menu.hh"
+#include "screen.hh"
+#include "surface.hh"
+#include "fs.hh"
+
+
+MenuOption::MenuOption(std::string const& nm, std::string const& comm, MenuImage img):
+  type(), value(), newValue(), callback(), image(img), name(nm), comment(comm), namePtr(), commentPtr()
+{}
+
+std::string MenuOption::getName() const {
+       if (namePtr) return *namePtr;
+       if (!name.empty()) return name;
+       if (value) return value->getValue();
+       return "";
+}
+
+const std::string& MenuOption::getComment() const { return commentPtr ? *commentPtr : comment; }
+
+bool MenuOption::isActive() const {
+       if (type == OPEN_SUBMENU && options.empty()) return false;
+       if (type == CHANGE_VALUE) {
+               if (!value) return false;
+               if (value->get_type() == "option_list" && value->ol().size() <= 1) return false;
+       }
+       return true;
+}
+
+
+Menu::Menu(): dimensions(), m_open(true) { clear(); }
+
+void Menu::add(MenuOption opt) {
+       root_options.push_back(opt);
+       clear(true); // Adding resets menu stack
+}
+
+void Menu::move(int dir) {
+       if (dir > 0 && selection_stack.back() < menu_stack.back()->size() - 1) ++selection_stack.back();
+       else if (dir < 0 && selection_stack.back() > 0) --selection_stack.back();
+}
+
+void Menu::select(unsigned sel) {
+       if (sel < menu_stack.back()->size()) selection_stack.back() = sel;
+}
+
+void Menu::action(int dir) {
+       switch (current().type) {
+               case MenuOption::OPEN_SUBMENU: {
+                       if (current().options.empty()) break;
+                       menu_stack.push_back(&current().options);
+                       selection_stack.push_back(0);
+                       break;
+               }
+               case MenuOption::CHANGE_VALUE: {
+                       if (current().value) {
+                               if (dir > 0) ++(*(current().value));
+                               else if (dir < 0) --(*(current().value));
+                       }
+                       break;
+               }
+               case MenuOption::SET_AND_CLOSE: {
+                       if (current().value) *(current().value) = current().newValue;
+                       // Fall-through to closing
+               }
+               case MenuOption::CLOSE_SUBMENU: {
+                       closeSubmenu();
+                       break;
+               }
+               case MenuOption::ACTIVATE_SCREEN: {
+                       Game* gm = Game::getSingletonPtr();
+                       std::string screen = current().newValue.s();
+                       clear();
+                       if (screen.empty()) gm->finished();
+                       else gm->activateScreen(screen);
+                       break;
+               }
+               case MenuOption::CALLBACK: {
+                       if (current().callback) current().callback();
+                       break;
+               }
+       }
+}
+
+void Menu::clear(bool save_root) {
+       if (!save_root) root_options.clear();
+       menu_stack.clear();
+       selection_stack.clear();
+       menu_stack.push_back(&root_options);
+       selection_stack.push_back(0);
+}
+
+void Menu::closeSubmenu() {
+       if (menu_stack.size() > 1) {
+               menu_stack.pop_back();
+               selection_stack.pop_back();
+       } else close();
+}
diff --git a/game/menu.hh b/game/menu.hh
new file mode 100644 (file)
index 0000000..1bfcfd5
--- /dev/null
@@ -0,0 +1,105 @@
+#pragma once
+
+#include "opengl_text.hh"
+#include "configuration.hh"
+#include <boost/noncopyable.hpp>
+#include <boost/shared_ptr.hpp>
+#include <functional>
+#include <string>
+#include <vector>
+
+class Surface;
+class MenuOption;
+class Menu;
+
+typedef std::vector<MenuOption> MenuOptions;
+typedef std::vector<MenuOptions*> SubmenuStack;
+typedef std::function<void ()> MenuOptionCallback;
+typedef boost::shared_ptr<Surface> MenuImage;
+
+/// Struct for menu options
+class MenuOption {
+public:
+       enum Type { CLOSE_SUBMENU, OPEN_SUBMENU, CHANGE_VALUE, SET_AND_CLOSE, ACTIVATE_SCREEN, CALLBACK } type;
+
+       /// Construct a menu option. Default function is to close the menu.
+       /// @param nm Name (menu item title)
+       /// @param comm Comment
+       /// @param img Image filename
+       MenuOption(const std::string& nm, const std::string& comm, MenuImage img = MenuImage());
+
+       /// Make the option change values of a ConfigItem.
+       MenuOption& changer(ConfigItem& val) { type = CHANGE_VALUE; value = &val; return *this; }
+       /// Make the option set a given value for ConfigItem and close the menu.
+       MenuOption& setter(ConfigItem& val, ConfigItem newval) { type = SET_AND_CLOSE; value = &val; newValue = newval; return *this; }
+       /// Make the option open a submenu
+       MenuOption& submenu(MenuOptions opts) { type = OPEN_SUBMENU; options = opts; return *this; }
+       /// Make the option activate a screeen
+       MenuOption& screen(std::string const& scrn) { type = ACTIVATE_SCREEN; newValue = scrn; return *this; }
+       /// Make the option call a callback
+       MenuOption& call(MenuOptionCallback f) { type = CALLBACK; callback = f; return *this; }
+       /// Sets name to follow a reference
+       MenuOption& setDynamicName(std::string& nm) { namePtr = &nm; return *this; }
+       /// Sets comment to follow a reference
+       MenuOption& setDynamicComment(std::string& comm) { commentPtr = &comm; return *this; }
+       /// Return name
+       std::string getName() const;
+       /// Return comment
+       const std::string& getComment() const;
+       /// Check if this option can be selected
+       bool isActive() const;
+       ConfigItem* value;  ///< Setting to be adjusted
+       ConfigItem newValue;  ///< Value to be set or screen name
+       MenuOptions options;  ///< Submenu
+       MenuOptionCallback callback;  ///< Callback function
+       MenuImage image;  ///< Image to use with option
+private:
+       std::string name;        ///< Option name (it will be displayed as this)
+       std::string comment;     ///< Extended information about the option displayed usually when selected
+       std::string* namePtr;    ///< Optional pointer to dynamically changing name
+       std::string* commentPtr; ///< Optional pointer to dynamically changing comment
+};
+
+
+/// Menu for selecting difficulty etc.
+class Menu {
+public:
+       /// constructor
+       Menu();
+       /// add a menu option
+       void add(MenuOption opt);
+       /// move the selection
+       void move(int dir = 1);
+       /// set selection
+       void select(unsigned sel);
+       /// adjust the selected value
+       void action(int dir = 1);
+       /// clear items
+       void clear(bool save_root = false);
+       /// closes submenu or if in root menu, closes the whole menu
+       void closeSubmenu();
+
+       bool empty() const { return (menu_stack.empty() || (menu_stack.size() == 1 && menu_stack.back()->empty())); }
+       bool isOpen() const { return m_open; }
+       size_t getSubmenuLevel() const { return menu_stack.size() - 1; }
+       void open() { m_open = true; }
+       void close() { m_open = false; }
+       void toggle() { m_open = !m_open; }
+       void moveToLast() { selection_stack.back() = menu_stack.back()->size() - 1; }
+
+       size_t curIndex() { return selection_stack.back(); }
+       MenuOption& current() { return menu_stack.back()->at(selection_stack.back()); }
+       MenuOption& back() { return root_options.back(); }
+       const MenuOptions::const_iterator begin() const { return menu_stack.back()->begin(); }
+       const MenuOptions::const_iterator end() const { return menu_stack.back()->end(); }
+       const MenuOptions getOptions() const { return *menu_stack.back(); }
+
+       Dimensions dimensions;
+
+private:
+       MenuOptions root_options;
+       SubmenuStack menu_stack;
+       std::vector<size_t> selection_stack;
+
+       bool m_open;
+};
diff --git a/game/midifile.cc b/game/midifile.cc
new file mode 100644 (file)
index 0000000..0a86e25
--- /dev/null
@@ -0,0 +1,344 @@
+#include "midifile.hh"
+
+#include <boost/filesystem/fstream.hpp>
+#include <algorithm>
+#include <iomanip>
+#include <iostream>
+#include <stdexcept>
+#include <sstream>
+#include <string>
+
+#define MIDI_DEBUG_LEVEL 0
+
+
+/**
+ * @short The MidiStream class reads midifile for MidiFileParser.
+ */
+
+class MidiStream {
+  public:
+
+       /** Constructor.
+        *
+        * Creates MidiStream object that reads given midiFile.
+        *
+        * @param file MidiFile to be read
+        */
+       MidiStream(fs::path const& file) {
+               fs::ifstream ifs(file, std::ios::binary);
+#if MIDI_DEBUG_LEVEL > 1
+               std::cout << "Opening file: " << file << std::endl;
+#endif
+               f << ifs.rdbuf();
+               f.exceptions(std::ios::failbit);
+       }
+
+       /// read bytes
+       std::string read_bytes(size_t bytes);
+
+       class Riff {
+         public:
+               MidiStream& ms;
+               std::string name;
+               size_t pos;
+               size_t size;
+               size_t offset;
+               Riff(MidiStream& ms);
+               ~Riff();
+               bool has_more_data() const { return offset < size; }
+               uint8_t read_uint8() { consume(1); return ms.f.get(); }
+               uint16_t read_uint16() { consume(2); return ms.read_uint16(); }
+               uint32_t read_uint32() { consume(4); return ms.read_uint32(); }
+               uint32_t read_varlen();
+               template <typename T> T read(T& value) {
+                       consume(sizeof(T));
+                       value = 0;
+                       for (int i = sizeof(T) - 1; i >= 0; --i) value |= ms.f.get() << (8 * i);
+                       return value;
+               }
+               std::string read_bytes(size_t size) { consume(size); return ms.read_bytes(size); }
+               void ignore(size_t size) { consume(size); ms.f.ignore(size); }
+               void seek_back(size_t offset = 1);
+         private:
+               void consume(size_t bytes);
+       };
+
+private:
+
+       std::stringstream f;
+       uint16_t read_uint16() { return f.get() << 8 | f.get(); }
+       uint32_t read_uint32() { return f.get() << 24 | f.get() << 16 | f.get() << 8 | f.get(); }
+
+};
+
+namespace { bool is_not_alpha(char c) { return (c < 'A' || c > 'Z') && (c < 'a' || c > 'z'); } }
+
+MidiStream::Riff::Riff(MidiStream& ms): ms(ms), name(ms.read_bytes(4)), size(ms.read_uint32()), offset(0) {
+       if (std::find_if(name.begin(), name.end(), is_not_alpha) != name.end()) throw std::runtime_error("Invalid RIFF chunk name");
+       pos = ms.f.tellg();
+}
+
+MidiStream::Riff::~Riff() {
+#if MIDI_DEBUG_LEVEL > 0
+       if (has_more_data()) std::clog << "MidiStream/warning: Only " << offset << " of " << size << " bytes read of RIFF chunk " << name << std::endl;
+#endif
+       ms.f.seekg(pos + size);
+}
+
+uint32_t MidiStream::Riff::read_varlen() {
+       unsigned long value = 0;
+       size_t a = 0;
+       unsigned char c;
+       do {
+               if (++a > 4) throw std::runtime_error("Too long varlen sequence");
+               consume(1);
+               c = ms.f.get();
+               value = (value << 7) | (c & 0x7F);
+       } while (c & 0x80);
+       return value;
+}
+
+std::string MidiStream::read_bytes(size_t bytes) {
+       std::string data;
+       for(size_t i=0; i < bytes; ++i) data += f.get();
+       return data;
+}
+
+void MidiStream::Riff::consume(size_t bytes) {
+       if (size - offset < bytes) throw std::runtime_error("Read past the end of RIFF chunk " + name);
+       ms.f.seekg(pos + offset);
+       offset += bytes;
+}
+
+void MidiStream::Riff::seek_back(size_t o) {
+       if (offset < o) throw std::runtime_error("Seek past the beginning of RIFF chunk " + name);
+       offset -= o;
+       ms.f.seekg(pos + offset);
+}
+
+
+MidiFileParser::MidiFileParser(fs::path const& name):
+  format(0), division(0), ts_last(0)
+{
+       MidiStream stream(name);
+       size_t ntracks = parse_header(stream);
+       if (format > 0) {
+               // First track is a control track
+               read_track(stream);
+               --ntracks;
+       }
+       for (size_t i = 0; i < ntracks; ++i) tracks.push_back(read_track(stream));
+}
+
+uint16_t MidiFileParser::parse_header(MidiStream& stream) {
+       MidiStream::Riff riff(stream);
+       if (riff.name != "MThd") throw std::runtime_error("Header not found");
+       if (riff.read(format) > 1) throw std::runtime_error("Unsupported MIDI format (only 0 and 1 are supported)");
+       uint16_t ntracks = riff.read_uint16();
+       if ((format == 0 && ntracks != 1) || (format == 1 && ntracks < 2)) throw std::runtime_error("Invalid number of tracks");
+       riff.read(division);
+       if (division & 0x8000) throw std::runtime_error("SMPTE type divisions not supported");
+#if MIDI_DEBUG_LEVEL > 1
+       std::cout << "Division: " << division << std::endl;
+#endif
+       return ntracks;
+}
+
+MidiFileParser::Track MidiFileParser::read_track(MidiStream& stream) {
+       MidiStream::Riff riff(stream);
+       if (riff.name != "MTrk") throw std::runtime_error("Chunk MTrk not found");
+       Track track;
+       uint32_t miditime = 0;
+       uint8_t runningstatus = 0;
+       bool end = false;
+       while (!end) {
+               miditime += riff.read_varlen();
+               uint8_t event = riff.read_uint8();
+
+               if (event & 0x80) {
+                       // Store current status, with exceptions:
+                       // * Not stored for RealTime Category messages (0xF8..0xFF)
+                       // * Running status cleared for System Common Category (0xF0..0xF7)
+                       if (event < 0xF8) runningstatus = (event < 0xF0 ? event : 0);
+               } else {
+                       riff.seek_back();
+                       if (!runningstatus) throw std::runtime_error("Invalid MIDI file (first MIDI Event of a track wants running status)");
+                       event = runningstatus;
+               }
+
+               if (event == 0xFF) {
+                       // Meta event
+                       uint8_t type = riff.read_uint8();
+                       std::string data = riff.read_bytes(riff.read_varlen());
+                       switch (type) {
+                         // 0x00: Sequence Number
+                         case 0x01: { // Text Event
+                               const std::string sect_pfx = "[section ";
+                               // Lyrics are hidden here, only [text] are orders
+                               if (data[0] != '[') m_lyric = data;
+                               else if (!data.compare(0, sect_pfx.length(), sect_pfx)) {// [section verse_1]
+                                       std::string sect_name = data.substr(sect_pfx.length(), data.length()-sect_pfx.length()-1);
+                                       if (sect_name != "big_rock_ending") {
+                                               bool space = true;
+                                               for (auto& ch: sect_name) {
+                                                       if (space) ch = toupper(static_cast<unsigned char>(ch));  // Capitalize first letter of each word
+                                                       if (ch == '_') { ch = ' '; space = true; }  // underscores to spaces
+                                                       else space = false;
+                                               }
+                                               // replace gtr => guitar
+#if MIDI_DEBUG_LEVEL > 2
+                                               std::cout << "Section: " << sect_name << " at " << get_seconds(miditime) << std::endl;
+#endif
+                                               midisections.push_back(MidiSection(sect_name, get_seconds(miditime)));
+                                       } else cmdevents.push_back(std::string(data)); // see songparser-ini.cc: we need to keep the BRE in cmdevents
+                               }
+                               else cmdevents.push_back(std::string(data));
+#if MIDI_DEBUG_LEVEL > 2
+                               std::cout << "Text: " << data << std::endl;
+#endif
+                         } break;
+                         // 0x02: Copyright Notice
+                         case 0x03: // Sequence or Track Name
+                               track.name = data;
+#if MIDI_DEBUG_LEVEL > 1
+                               std::cout << "Track name: " << data << std::endl;
+#endif
+                               break;
+                         // 0x04: Instrument Name
+                         case 0x05: // Lyric Text
+                               m_lyric = data;
+#if MIDI_DEBUG_LEVEL > 2
+                               std::cout << "Lyric: " << data << std::endl;
+#endif
+                               break;
+                         // 0x06: Marker Text
+                         // 0x07: Cue point
+                         // 0x20: MIDI Channel Prefix Assignment
+                         case 0x2F: // End of Track
+                               end = true;
+                               break;
+                         case 0x51: // Tempo Setting
+                               if (data.size() != 3) throw std::runtime_error("Invalid tempo change event");
+                               add_tempo_change(miditime, static_cast<unsigned char>(data[0]) << 16 | static_cast<unsigned char>(data[1]) << 8 | static_cast<unsigned char>(data[2])); break;
+                         // 0x54: SMPTE Offset
+                         case 0x58: // Time Signature
+                               if (data.size() != 4) throw std::runtime_error("Invalid time signature event");
+#if MIDI_DEBUG_LEVEL > 3
+                               // if none is found "4/4, 24,8" should be assume
+                               std::cout << "Time signature: " << int(data[0]) << "/" << int(data[1]) << ", " << int(data[2]) << ", " << int(data[3]) << std::endl;
+#endif
+                               break;
+                         // 0x59: Key Signature
+                         // 0x7f: Sequencer Specific Event
+                         default:
+#if MIDI_DEBUG_LEVEL > 1
+                               std::cout << "Unhandled meta event  type=" << int(type) << " (" << data.size() << " bytes)" << std::endl;
+#endif
+                               break;
+                       }
+               } else if (event==0xF0 || event==0xF7) {
+                       // System exclusive event
+                       uint32_t size = riff.read_varlen();
+                       riff.ignore(size);
+#if MIDI_DEBUG_LEVEL > 1
+                       std::cout << "System exclusive event ignored (" << size << " bytes)" << std::endl;
+#endif
+               } else {
+                       // Midi event
+                       uint8_t arg1 = riff.read_uint8();
+                       uint8_t arg2 = 0;
+                       uint8_t ev = event >> 4;
+                       switch (ev) {
+                       case 0x8: case 0x9: case 0xA: case 0xB: case 0xE: arg2 = riff.read_uint8(); break;
+                       case 0xC: case 0xD: break;  // These only take one argument
+                       default: throw std::runtime_error("Unknown MIDI event");  // Quite possibly this is impossible, but I am too tired to prove it.
+                       }
+                       process_midi_event(track, ev, arg1, arg2, miditime);
+               }
+       }
+       if (miditime > ts_last) ts_last = miditime;
+       return track;
+}
+
+void MidiFileParser::add_tempo_change(uint32_t miditime, uint32_t tempo) {
+       if (tempo == 0) throw std::runtime_error("Invalid MIDI file (tempo is zero)");
+       if (tempochanges.empty()) {
+               if (miditime > 0) throw std::runtime_error("Invalid MIDI file (tempo not set at the beginning)");
+       } else {
+               if (tempochanges.back().miditime >= miditime) throw std::runtime_error("Invalid MIDI file (unexpected tempo change)");
+       }
+#if MIDI_DEBUG_LEVEL > 2
+       std::cout << "Tempo change at miditime=" << miditime << ":  " << tempo << " us/QN  " << 6e7 / tempo << " BPM" << std::endl;
+#endif
+       tempochanges.push_back(TempoChange(miditime, tempo));
+}
+
+void MidiFileParser::cout_midi_event(uint8_t t, uint8_t arg1, uint8_t arg2, uint32_t miditime) {
+       std::cout << "Midi event:" << std::setw(12) << miditime << std::fixed << std::setprecision(2) << std::setw(12) << get_seconds(miditime) << "  ";
+       switch (t) {
+         case 0x8: std::cout << "note off   pitch=" << int(arg1) << " velocity=" << int(arg2); break;
+         case 0x9: std::cout << "note on   pitch=" << int(arg1) << " velocity=" << int(arg2); break;
+         case 0xA: std::cout << "aftertouch pitch=" << int(arg1) << " value=" << int(arg2); break;
+         case 0xB: std::cout << "controller num=" << int(arg1) << " value=" << int(arg2); break;
+         case 0xC: std::cout << "program change num=" << int(arg1); break;
+         case 0xD: std::cout << "channel value =" << int(arg1); break;
+         case 0xE: std::cout << "pitch bend value=" << (arg2 << 8 | arg1); break;
+         default: std::cout << "UNKNOWN EVENT=0x" << std::hex << int(t) << std::dec << ")"; break;
+       }
+       std::cout << std::endl;
+}
+
+uint64_t MidiFileParser::get_us(uint32_t miditime) {
+       if (tempochanges.empty()) throw std::runtime_error("Unable to calculate note duration without tempo");
+       uint64_t time = 0;
+       auto i = tempochanges.begin();
+       // TODO: cache previous
+       for (; i + 1 != tempochanges.end() && (i + 1)->miditime < miditime; ++i) {
+               time += static_cast<uint64_t>(i->value) * ((i + 1)->miditime - i->miditime);
+       }
+       time += static_cast<uint64_t>(i->value) * (miditime - i->miditime);
+       return time / division;
+}
+
+void MidiFileParser::process_midi_event(Track& track, uint8_t t, uint8_t arg1, uint8_t arg2, uint32_t miditime) {
+#if MIDI_DEBUG_LEVEL > 3
+       cout_midi_event(t, arg1, arg2, miditime);
+#endif
+
+       std::vector<Note>& pitch(track.notes[arg1]);
+       // common track management
+       if (t == 8 || (t == 9 && arg2 == 0)) {
+               if (pitch.empty() || pitch.back().end != 0) {
+                       // Note end event with no corresponding beginning
+               } else {
+                       pitch.back().end = miditime;
+               }
+       } else {
+               pitch.push_back(Note(miditime));
+       }
+       // special management for lyrics
+       if (track.name == "PART VOCALS" || track.name == "PART HARM1" || track.name == "PART HARM2" || track.name == "PART HARM3") {
+               // Discard note effects
+               if( arg1 < 20 ) return;
+               if (t == 8 || (t == 9 && arg2 == 0)) {
+                       // end of note (note off or note on with zero velocity)
+                       if( !m_lyric.empty()  ) {
+                               // here we should update the last note lyric with the current m_lyric
+                               track.lyrics.back().lyric = m_lyric;
+                               // here we should update the last note end time with the miditime
+                               track.lyrics.back().end = miditime;
+                       } else {
+                               if( track.lyrics.back().lyric.empty() ) {
+                                       // bad notes, removing it
+                                       track.lyrics.pop_back();
+                               }
+                       }
+                       m_lyric.clear();
+               } else {
+                       // beginning of note then
+                       // here we should add a lyric with the start time at miditime
+                       track.lyrics.push_back(LyricNote("", arg1, miditime, miditime));
+               }
+       }
+}
+
diff --git a/game/midifile.hh b/game/midifile.hh
new file mode 100644 (file)
index 0000000..d32f7d3
--- /dev/null
@@ -0,0 +1,102 @@
+#pragma once
+#include "fs.hh"
+#include <map>
+#include <string>
+#include <vector>
+
+using std::uint8_t;
+using std::uint16_t;
+using std::uint32_t;
+using std::uint64_t;
+
+#if 0
+
+class MidiEvent {
+  public:
+       /** Constructs new MidiEvent
+       * @param fret Fret(1,2,3,4,5) in which the event is connected.
+       * @param evt Tells the type of midievent Noteon or Noteoff.
+       * @param time Time, absolute time in seconds. Tells when the event should happen.
+       */
+       MidiEvent(int f, unsigned char e, double t): fret(f), event(e), time(t) {}
+
+       int fret; ///< Tells the quitar fret where the event is linked.
+       unsigned char event; ///< MIDI event type
+       double time; ///< Time in seconds
+};
+
+#endif
+
+class MidiStream;
+
+/**
+ * The Parser class, that contains needed information of given midi-file
+ */
+
+class MidiFileParser {
+public:
+
+       /** Constructor
+        *
+        * Creates a MidiFileParser which contains      information of given midifile.
+        *
+        * @param name Name of midifile, which want to be read
+        */
+       MidiFileParser(fs::path const& name);
+
+       struct TempoChange {
+               uint32_t miditime;
+               uint32_t value;
+               TempoChange(uint32_t miditime, uint32_t value): miditime(miditime), value(value) {}
+       };
+       typedef std::vector<TempoChange> TempoChanges;
+       TempoChanges tempochanges;
+       typedef uint8_t Pitch;
+       struct Note {
+               uint32_t begin;
+               uint32_t end;
+               Note(uint32_t begin, uint32_t end = 0): begin(begin), end(end) {}
+       };
+       typedef std::vector<Note> Notes;
+       typedef std::map<Pitch, Notes> NoteMap;
+       struct LyricNote {
+               std::string lyric;
+               int note;
+               uint32_t begin;
+               uint32_t end;
+               LyricNote(std::string const& lyric, int note, uint32_t begin, uint32_t end = 0): lyric(lyric), note(note), begin(begin), end(end) {}
+       };
+       typedef std::vector<LyricNote> Lyrics;
+       struct Track {
+               std::string name;
+               NoteMap notes;
+               Lyrics lyrics;
+               Track(std::string const& name = "default"): name(name) {}
+       };
+       typedef std::vector<Track> Tracks;
+       Tracks tracks;
+       struct MidiSection {
+               std::string name;
+               double begin;
+               MidiSection(std::string const& name, const double begin): name(name), begin(begin) {}
+       };
+       typedef std::vector<MidiSection> MidiSections;
+       MidiSections midisections; ///< vector of song sections
+       uint16_t parse_header(MidiStream&);
+       Track read_track(MidiStream&);
+       void cout_midi_event(uint8_t type, uint8_t arg1, uint8_t arg2, uint32_t miditime);
+       void process_midi_event(Track& track, uint8_t type, uint8_t arg1, uint8_t arg2, uint32_t miditime);
+       uint64_t get_us(uint32_t miditime);
+       double get_seconds(uint32_t miditime) { return 1e-6 * get_us(miditime); }
+       void add_tempo_change(uint32_t miditime, uint32_t tempo);
+       uint16_t format;
+       typedef std::vector<std::string> CommandEvents;
+       CommandEvents cmdevents;
+
+       /** Ticks per beat == number of divisions per every quarter note **/
+       uint16_t division;
+       uint32_t ts_last;
+private:
+       std::string m_lyric;
+};
+
diff --git a/game/musicalscale.cc b/game/musicalscale.cc
new file mode 100644 (file)
index 0000000..ee02dcf
--- /dev/null
@@ -0,0 +1,47 @@
+#include "musicalscale.hh"
+
+#include "util.hh"
+#include <cmath>
+#include <sstream>
+#include <stdexcept>
+
+MusicalScale& MusicalScale::clear() { m_freq = m_note = getNaN(); return *this; }
+
+MusicalScale& MusicalScale::setFreq(double freq) {
+       m_freq = freq;
+       m_note = m_baseId + 12.0 * std::log(freq / m_baseFreq) / std::log(2.0);
+       if (!isValid()) m_note = getNaN();
+       return *this;
+}
+
+MusicalScale& MusicalScale::setNote(double note) {
+       m_note = note;
+       m_freq = m_baseFreq * std::pow(2.0, (m_note - m_baseId) / 12.0);
+       return *this;
+}
+
+unsigned MusicalScale::getNoteId() const {
+       if (!isValid()) throw std::logic_error("MusicalScale::getNoteId must only be called on valid notes.");
+       return round(m_note);
+}
+
+// NOTE: Only C major scale is currently implemented.
+
+static const char* const noteNames[12] = {"C ","C#","D ","D#","E ","F ","F#","G ","G#","A ","A#","B "};
+static const int noteLines[12] = { 0, 0, 1, 1, 2, 3, 3, 4, 4, 5, 5, 6 };
+
+std::string MusicalScale::getStr() const {
+       if (!isValid()) return std::string();
+       std::ostringstream oss;
+       oss << noteNames[getNum()] << " " << round(m_freq) << " Hz";
+       return oss.str();
+}
+
+int MusicalScale::getNoteLine() const {
+       return (getOctave() - 4) * 7 + noteLines[getNum()];
+}
+
+bool MusicalScale::isSharp() const {
+       return noteNames[getNum()][1] == '#';  // Uses the second character of noteNames!
+}
+
diff --git a/game/musicalscale.hh b/game/musicalscale.hh
new file mode 100644 (file)
index 0000000..5f9e339
--- /dev/null
@@ -0,0 +1,28 @@
+#pragma once
+
+#include <string>
+
+/// Conversions for the C major musical scale
+class MusicalScale {
+  private:
+       double m_baseFreq;
+       static const int m_baseId = 69;  ///< MIDI note that corresponds to baseFreq
+       double m_freq;
+       double m_note;
+  public:
+       MusicalScale(double baseFreq = 440.0): m_baseFreq(baseFreq) { clear(); }  ///< Construct a C major scale (no others are currently implemented)
+       MusicalScale& clear();  ///< Clear current note/freq values
+       MusicalScale& setFreq(double freq);  ///< Set note by frequency
+       MusicalScale& setNote(double note);  ///< Set note by note value
+       double getFreq() const { return m_freq; }  ///< Get the note frequency
+       double getNote() const { return m_note; }  ///< Get the precise (non-rounded) note id for a the frequency
+       unsigned getNoteId() const;   ///< Get the nearest note for the frequency
+       double getNoteOffset() const { return m_note - getNoteId(); }  ///< Get the note offset (-0.5 to 0.5)
+       std::string getStr() const;  ///< Get a human-readable string representation for the note
+       unsigned getNum() const { return getNoteId() % 12; }  ///< Get note number within an octave (0 to 11, begins at key, e.g. C)
+       int getOctave() const { return int(getNoteId() / 12) - 1; }   ///< Get the octave number (-1 to 9, A4 ~ baseFreq)
+       int getNoteLine() const;  ///< Get a note line number in traditional notation (0 ~ key base e.g. C4, odd values are between lines, negative for lower octaves)
+       bool isSharp() const;  ///< Check if the note is sharp (#)
+       bool isValid() const { return m_note >= 0.0 && m_note <= 127.0; }  ///< Test if a valid note value is stored
+};
+
diff --git a/game/notegraph.cc b/game/notegraph.cc
new file mode 100644 (file)
index 0000000..396c502
--- /dev/null
@@ -0,0 +1,254 @@
+#include "notegraph.hh"
+
+#include "configuration.hh"
+#include "database.hh"
+#include "engine.hh"
+#include "player.hh"
+
+Dimensions dimensions; // Make a public member variable
+
+NoteGraph::NoteGraph(VocalTrack const& vocal):
+  m_vocal(vocal),
+  m_notelines(findFile("notelines.svg")), m_wave(findFile("wave.png")),
+  m_star(findFile("star.svg")), m_star_hl(findFile("star_glow.svg")),
+  m_notebar(findFile("notebar.svg")), m_notebar_hl(findFile("notebar.png")),
+  m_notebarfs(findFile("notebarfs.svg")), m_notebarfs_hl(findFile("notebarfs-hl.png")),
+  m_notebargold(findFile("notebargold.svg")), m_notebargold_hl(findFile("notebargold.png")),
+  m_notealpha(0.0f), m_nlTop(0.0, 4.0), m_nlBottom(0.0, 4.0), m_time()
+{
+       dimensions.stretch(1.0, 0.5); // Initial dimensions, probably overridden from somewhere
+       m_nlTop.setTarget(m_vocal.noteMax, true);
+       m_nlBottom.setTarget(m_vocal.noteMin, true);
+       for (auto const& n: m_vocal.notes) n.stars.clear(); // Reset stars
+       reset();
+}
+
+void NoteGraph::reset() {
+       m_songit = m_vocal.notes.begin();
+}
+
+namespace {
+       void drawNotebar(Texture const& texture, double x, double ybeg, double yend, double w, double h) {
+               glutil::VertexArray va;
+               UseTexture tblock(texture);
+
+               // The front cap begins
+               va.texCoord(0.0f, 0.0f).vertex(x, ybeg);
+               va.texCoord(0.0f, 1.0f).vertex(x, ybeg + h);
+               if (w >= 2.0 * h) {
+                       // Calculate the y coordinates of the middle part
+                       double tmp = h / w;  // h = cap size (because it is a h by h square)
+                       double y1 = (1.0 - tmp) * ybeg + tmp * yend;
+                       double y2 = tmp * ybeg + (1.0 - tmp) * yend;
+                       // The middle part between caps
+                       va.texCoord(0.5f, 0.0f).vertex(x + h, y1);
+                       va.texCoord(0.5f, 1.0f).vertex(x + h, y1 + h);
+                       va.texCoord(0.5f, 0.0f).vertex(x + w - h, y2);
+                       va.texCoord(0.5f, 1.0f).vertex(x + w - h, y2 + h);
+               } else {
+                       // Note is too short to even fit caps, crop to fit.
+                       double ymid = 0.5 * (ybeg + yend);
+                       float crop = 0.25f * w / h;
+                       va.texCoord(crop, 0.0f).vertex(x + 0.5 * w, ymid);
+                       va.texCoord(crop, 1.0f).vertex(x + 0.5 * w, ymid + h);
+                       va.texCoord(1.0f - crop, 0.0f).vertex(x + 0.5 * w, ymid);
+                       va.texCoord(1.0f - crop, 1.0f).vertex(x + 0.5 * w, ymid + h);
+               }
+               // The rear cap ends
+               va.texCoord(1.0f, 0.0f).vertex(x + w, yend);
+               va.texCoord(1.0f, 1.0f).vertex(x + w, yend + h);
+
+               va.draw();
+       }
+}
+
+const double baseLine = -0.2;
+const double pixUnit = 0.2;
+
+void NoteGraph::draw(double time, Database const& database, Position position) {
+       if (time < m_time) reset();
+       m_time = time;
+       // Update m_songit (which note to start the rendering from)
+       while (m_songit != m_vocal.notes.end() && (m_songit->type == Note::SLEEP || m_songit->end < time - (baseLine + 0.5) / pixUnit)) ++m_songit;
+
+       // Automatically zooming notelines
+       {
+               int low = m_vocal.noteMax;
+               int high = m_vocal.noteMin;
+               int low2 = m_vocal.noteMax;
+               int high2 = m_vocal.noteMin;
+               for (auto it = m_songit; it != m_vocal.notes.end() && it->begin < time + 15.0; ++it) {
+                       if (it->type == Note::SLEEP) continue;
+                       if (it->note < low) low = it->note;
+                       if (it->note > high) high = it->note;
+                       if (it->begin > time + 8.0) continue;
+                       if (it->note < low2) low2 = it->note;
+                       if (it->note > high2) high2 = it->note;
+               }
+               if (low2 <= high2) {
+                       m_nlTop.setRange(high2, high);
+                       m_nlBottom.setRange(low, low2);
+               }
+       }
+       switch(position) {
+               case NoteGraph::FULLSCREEN:
+                       dimensions.stretch(1.0, 0.50).center();
+                       break;
+               case NoteGraph::TOP:
+                       dimensions.stretch(1.0, 0.32).bottom(0.0);
+                       break;
+               case NoteGraph::BOTTOM:
+                       dimensions.stretch(1.0, 0.32).top(0.0);
+                       break;
+               case NoteGraph::LEFT:
+                       dimensions.stretch(0.50, 0.50).center().left(-0.5);
+                       break;
+               case NoteGraph::RIGHT:
+                       dimensions.stretch(0.50, 0.50).center().right();
+                       break;
+       }
+       m_max = m_nlTop.get() + 7.0;
+       m_min = m_nlBottom.get() - 7.0;
+       m_noteUnit = -dimensions.h() / std::max(48.0 * dimensions.h(), m_max - m_min);
+       m_baseY = -0.5 * (m_min + m_max) * m_noteUnit + dimensions.yc();
+       m_baseX = baseLine - m_time * pixUnit + dimensions.xc();  // FIXME: Moving in X direction requires additional love (is b0rked now, keep it centered at zero)
+
+       // Fading notelines handing
+       if (m_songit == m_vocal.notes.end() || m_songit->begin > m_time + 3.0) m_notealpha -= 0.02f;
+       else if (m_notealpha < 1.0f) m_notealpha += 0.02f;
+       if (m_notealpha <= 0.0f) { m_notealpha = 0.0f; return; }
+
+       ColorTrans c(Color::alpha(m_notealpha));
+
+       drawNotes();
+       if (config["game/pitch"].b()) drawWaves(database);
+
+       // Draw a star for well sung notes
+       for (auto it = m_songit; it != m_vocal.notes.end() && it->begin < m_time - (baseLine - 0.5) / pixUnit; ++it) {
+               float player_star_offset = 0;
+               for (std::vector<Color>::const_iterator it_col = it->stars.begin(); it_col != it->stars.end(); ++it_col) {
+                       double x = m_baseX + it->begin * pixUnit + m_noteUnit; // left x coordinate: begin minus border (side borders -noteUnit wide)
+                       double w = (it->end - it->begin) * pixUnit - m_noteUnit * 2.0; // width: including borders on both sides
+                       float hh = -m_noteUnit;
+                       float centery = m_baseY + (it->note + 0.4) * m_noteUnit; // Star is 0.4 notes higher than current note
+                       float centerx = x + w - (player_star_offset + 1.2) * hh; // Star is 1.2 units from end
+                       float rot = fmod(time * 5.0, 2.0 * M_PI); // They rotate!
+                       bool smallerNoteGraph = ((position == NoteGraph::TOP) || (position == NoteGraph::BOTTOM));
+                       float zoom = (std::abs((rot-180) / 360.0f) * 0.8f + 0.6f) * (smallerNoteGraph ? 2.3 : 2.0) * hh;
+                       using namespace glmath;
+                       Transform trans(translate(vec3(centerx, centery, 0.0f)) * rotate(rot, vec3(0.0f, 0.0f, 1.0f)));
+                       {
+                               ColorTrans c(Color(it_col->r, it_col->g, it_col->b, it_col->a));
+                               m_star_hl.draw(Dimensions().stretch(zoom*1.2, zoom*1.2).center().middle(), TexCoords());
+                       }
+                       m_star.draw(Dimensions().stretch(zoom, zoom).center().middle(), TexCoords());
+                       player_star_offset += 0.8;
+               }
+       }
+}
+
+void NoteGraph::drawNotes() {
+       // Draw note lines
+       m_notelines.draw(Dimensions().stretch(dimensions.w(), (m_max - m_min - 13) * m_noteUnit).middle(dimensions.xc()).center(dimensions.yc()), TexCoords(0.0, (-m_min - 7.0) / 12.0f, 1.0, (-m_max + 6.0) / 12.0f));
+
+       // Draw notes
+       for (auto it = m_songit; it != m_vocal.notes.end() && it->begin < m_time - (baseLine - 0.5) / pixUnit; ++it) {
+               if (it->type == Note::SLEEP) continue;
+               double alpha = it->power;
+               Texture* t1;
+               Texture* t2;
+               switch (it->type) {
+                 case Note::NORMAL: case Note::SLIDE: t1 = &m_notebar; t2 = &m_notebar_hl; break;
+                 case Note::GOLDEN: t1 = &m_notebargold; t2 = &m_notebargold_hl; break;
+                 case Note::FREESTYLE:  // Freestyle notes use custom handling
+                       {
+                               Dimensions dim;
+                               dim.middle(m_baseX + 0.5 * (it->begin + it->end) * pixUnit).center(m_baseY + it->note * m_noteUnit).stretch((it->end - it->begin) * pixUnit, -m_noteUnit * 12.0);
+                               float xoffset = 0.1 * m_time / m_notebarfs.dimensions.ar();
+                               m_notebarfs.draw(dim, TexCoords(xoffset, 0.0, xoffset + dim.ar() / m_notebarfs.dimensions.ar(), 1.0));
+                               if (alpha > 0.0) {
+                                       float xoffset = rand() / double(RAND_MAX);
+                                       m_notebarfs_hl.draw(dim, TexCoords(xoffset, 0.0, xoffset + dim.ar() / m_notebarfs_hl.dimensions.ar(), 1.0));
+                               }
+                       }
+                       continue;
+                 default: throw std::logic_error("Unknown note type: don't know how to render");
+               }
+               double x = m_baseX + it->begin * pixUnit + m_noteUnit; // left x coordinate: begin minus border (side borders -noteUnit wide)
+               double ybeg = m_baseY + (it->notePrev + 1) * m_noteUnit; // top y coordinate (on the one higher note line)
+               double yend = m_baseY + (it->note + 1) * m_noteUnit; // top y coordinate (on the one higher note line)
+               double w = (it->end - it->begin) * pixUnit - m_noteUnit * 2.0; // width: including borders on both sides
+               double h = -m_noteUnit * 2.0; // height: 0.5 border + 1.0 bar + 0.5 border = 2.0
+               drawNotebar(*t1, x, ybeg, yend, w, h);
+               if (alpha > 0.0) {
+                       ColorTrans c(Color::alpha(alpha));
+                       drawNotebar(*t2, x, ybeg, yend, w, h);
+               }
+       }
+}
+
+namespace {
+       void strip(glutil::VertexArray& va) {
+               if (va.size() > 3) va.draw();
+               va.clear();
+       }
+}
+
+void NoteGraph::drawWaves(Database const& database) {
+       if (m_vocal.notes.empty()) return; // Cannot draw without notes
+       UseTexture tblock(m_wave);
+       for (auto const& player: database.cur) {
+               if (player.m_vocal.name != m_vocal.name)
+                       continue;
+               float const texOffset = 2.0 * m_time; // Offset for animating the wave texture
+               Player::pitch_t const& pitch = player.m_pitch;
+               size_t const beginIdx = std::max(0.0, m_time - 0.5 / pixUnit) / Engine::TIMESTEP; // At which pitch idx to start displaying the wave
+               size_t const endIdx = player.m_pos;
+               size_t idx = beginIdx;
+               // Go back until silence (NaN freq) to allow proper wave phase to be calculated
+               if (beginIdx < endIdx) while (idx > 0 && pitch[idx].first == pitch[idx].first) --idx;
+               // Start processing
+               float tex = texOffset;
+               double t = idx * Engine::TIMESTEP;
+               double oldval = getNaN();
+               glutil::VertexArray va;
+               auto noteIt = m_vocal.notes.begin();
+               glmath::vec4 c(player.m_color.r, player.m_color.g, player.m_color.b, 1.0);
+               for (; idx < endIdx; ++idx, t += Engine::TIMESTEP) {
+                       double const freq = pitch[idx].first;
+                       // If freq is NaN, we have nothing to process
+                       if (freq != freq) { oldval = getNaN(); tex = texOffset; continue; }
+                       tex += freq * 0.001; // Wave phase (texture coordinate)
+                       if (idx < beginIdx) continue; // Skip graphics rendering if out of screen
+                       double x = -0.2 + (t - m_time) * pixUnit;
+                       // Find the currently active note(s)
+                       while (noteIt != m_vocal.notes.end() && (noteIt->type == Note::SLEEP || t > noteIt->end)) ++noteIt;
+                       auto notePrev = noteIt;
+                       while (notePrev != m_vocal.notes.begin() && (notePrev->type == Note::SLEEP || t < notePrev->begin)) --notePrev;
+                       bool hasNote = (noteIt != m_vocal.notes.end());
+                       bool hasPrev = notePrev->type != Note::SLEEP && t >= notePrev->begin;
+                       double val;
+                       if (hasNote && hasPrev) val = 0.5 * (noteIt->note + notePrev->note);
+                       else if (hasNote) val = noteIt->note;
+                       else val = notePrev->note;
+                       // Now val contains the active note value. The following calculates note value for current freq:
+                       val += Note::diff(val, MusicalScale(m_vocal.scale).setFreq(freq).getNote());
+                       // Graphics positioning & animation:
+                       double y = m_baseY + val * m_noteUnit;
+                       double thickness = clamp(1.0 + pitch[idx].second / 60.0) + 0.5;
+                       thickness *= 1.0 + 0.2 * std::sin(tex - 2.0 * texOffset); // Further animation :)
+                       thickness *= -m_noteUnit;
+                       // If there has been a break or if the pitch change is too fast, terminate and begin a new one
+                       if (oldval != oldval || std::abs(oldval - val) > 1) strip(va);
+                       // Add a point or a pair of points
+                       if (!va.size()) va.texCoord(tex, 0.5f).color(c).vertex(x, y);
+                       else {
+                               va.texCoord(tex, 0.0f).color(c).vertex(x, y - thickness);
+                               va.texCoord(tex, 1.0f).color(c).vertex(x, y + thickness);
+                       }
+                       oldval = val;
+               }
+               strip(va);
+       }
+}
+
diff --git a/game/notegraph.hh b/game/notegraph.hh
new file mode 100644 (file)
index 0000000..f92db1c
--- /dev/null
@@ -0,0 +1,46 @@
+#pragma once
+
+#include "animvalue.hh"
+#include "surface.hh"
+#include "notes.hh"
+
+class Song;
+class Database;
+
+/// handles drawing of notes and waves
+class NoteGraph {
+  public:
+       enum Position {FULLSCREEN, TOP, BOTTOM, LEFT, RIGHT};
+       /// constructor
+       NoteGraph(VocalTrack const& vocal);
+       /// resets NoteGraph and Notes
+       void reset();
+       /** draws NoteGraph (notelines, notes, waves)
+        * @param time at which time to draw
+        * @param players reference to the list of singing Players
+        */
+       void draw(double time, Database const& database, Position position = NoteGraph::FULLSCREEN);
+  private:
+       /// draw notebars
+       void drawNotes();
+       /// draw waves (what players are singing)
+       void drawWaves(Database const& database);
+       VocalTrack const& m_vocal;
+       Texture m_notelines;
+       Texture m_wave;
+       Texture m_star;
+       Texture m_star_hl;
+       Texture m_notebar;
+       Texture m_notebar_hl;
+       Texture m_notebarfs;
+       Texture m_notebarfs_hl;
+       Texture m_notebargold;
+       Texture m_notebargold_hl;
+       float m_notealpha;
+       AnimValue m_nlTop, m_nlBottom;
+       Notes::const_iterator m_songit;
+       double m_time;
+       double m_max, m_min, m_noteUnit, m_baseY, m_baseX;
+
+};
+
diff --git a/game/notes.cc b/game/notes.cc
new file mode 100644 (file)
index 0000000..0e365f7
--- /dev/null
@@ -0,0 +1,60 @@
+#include "notes.hh"
+
+#include "util.hh"
+#include <cmath>
+#include <sstream>
+#include <stdexcept>
+
+Note::Note(): begin(getNaN()), end(getNaN()), phase(getNaN()), power(getNaN()), type(NORMAL), note(), notePrev() {}
+
+double Note::diff(double note, double n) { return remainder(n - note, 12.0); }
+double Note::maxScore() const { return scoreMultiplier() * (end - begin); }
+
+double Note::clampDuration(double b, double e) const {
+       double len = std::min(e, end) - std::max(b, begin);
+       return len > 0.0 ? len : 0.0;
+}
+
+double Note::score(double n, double b, double e) const {
+       return scoreMultiplier() * powerFactor(n) * clampDuration(b, e);
+}
+
+double Note::scoreMultiplier() const {
+       switch(type) {
+               case GOLDEN:
+                       return 2.0;
+               case SLEEP:
+                       return 0.0;
+               case FREESTYLE:
+               case NORMAL:
+               case SLIDE:
+               case TAP:
+               case HOLDBEGIN:
+               case HOLDEND:
+               case ROLL:
+               case MINE:
+               case LIFT:
+                       return 1.0;
+       }
+       return 0.0;
+}
+
+double Note::powerFactor(double note) const {
+       if (type == FREESTYLE) return 1.0;
+       double error = std::abs(diff(note));
+       return clamp(1.5 - error, 0.0, 1.0);
+}
+
+Duration::Duration(): begin(getNaN()), end(getNaN()) {}
+
+DanceTrack::DanceTrack(std::string& description, Notes& notes) : description(description), notes(notes) {}
+
+VocalTrack::VocalTrack(std::string name) : name(name) {reload();}
+
+void VocalTrack::reload() {
+       notes.clear();
+       m_scoreFactor = 0.0;
+       noteMin = std::numeric_limits<int>::max();
+       noteMax = std::numeric_limits<int>::min();
+       beginTime = endTime = getNaN();
+}
diff --git a/game/notes.hh b/game/notes.hh
new file mode 100644 (file)
index 0000000..17804ea
--- /dev/null
@@ -0,0 +1,123 @@
+#pragma once
+
+#include <map>
+#include <string>
+#include <vector>
+
+#include "color.hh"
+#include "musicalscale.hh"
+
+/// stores duration of a note
+struct Duration {
+       double begin, ///< beginning timestamp in seconds
+              end;   ///< ending timestamp in seconds
+       Duration();
+       /// create a new Duration object and initialize begin and end
+       Duration(double b, double e): begin(b), end(e) {}
+       /// compares begin timestamps of two Duration structs
+       static bool ltBegin(Duration const& a, Duration const& b) { return a.begin < b.begin; }
+       /// compares end timestamps of two Duration structs
+       static bool ltEnd(Duration const& a, Duration const& b) { return a.end < b.end; }
+};
+
+typedef std::vector<Duration> Durations;
+typedef std::map<int, Durations> NoteMap;
+
+/// Sort by instrument track name
+struct CompInstrumentTrack {
+       bool operator()(std::string const& l, std::string const& r) const {
+               // TODO: Sort other guitar tracks (coop / rhythm) properly
+               return l > r;
+       }
+};
+
+struct InstrumentTrack {
+       // TODO: name should not be needed here (contained into the map)
+       InstrumentTrack(std::string n): name(n) {}
+       std::string name;
+       NoteMap nm;
+};
+
+// keep these ones
+typedef std::map<std::string, InstrumentTrack, CompInstrumentTrack> InstrumentTracks;
+typedef std::map<std::string, InstrumentTrack const*, CompInstrumentTrack> InstrumentTracksConstPtr; // this one really needed ? can't we save only the map key for comparison ?
+
+static inline bool isTrackInside(InstrumentTracks const& track_map, std::string const& name) {
+       return track_map.find(name) != track_map.end();
+}
+
+// TODO: Make Note use Duration
+
+/// note read from songfile
+struct Note {
+       Note();
+       double begin, ///< begin time
+              end; ///< end time
+       double phase; /// Position within a measure, [0, 1)
+       // FIXME: Remove gameplay variables from here (Note should be immutable).
+       /// power of note (how well it is being hit right now)
+       mutable double power;
+       /// which players sung well
+       mutable std::vector<Color> stars;
+       /// note type
+       enum Type { FREESTYLE = 'F', NORMAL = ':', GOLDEN = '*', SLIDE = '+', SLEEP = '-',
+         TAP = '1', HOLDBEGIN = '2', HOLDEND = '3', ROLL = '4', MINE = 'M', LIFT = 'L'} type;
+       int note; ///< MIDI pitch of the note (at the end for slide notes)
+       int notePrev; ///< MIDI pitch of the previous note (should be same as note for everything but SLIDE)
+       /// lyrics syllable for that note
+       std::string syllable;
+       /// Difference of n from note
+       double diff(double n) const { return diff(note, n); }
+       /// Difference of n from note, so that note + diff(note, n) is n (mod 12)
+       static double diff(double note, double n);
+       /// Maximum score
+       double maxScore() const;
+       /// The length of the time period [a,b] that falls within the note in seconds
+       double clampDuration(double b, double e) const;
+       /// Score when singing over time period (a, b), which needs not to be entirely within the note
+       double score(double freq, double b, double e) const;
+       /// How precisely the note is hit (always 1.0 for freestyle, 0..1 for others)
+       double powerFactor(double note) const;
+       /// Compares begin of two notes
+       static bool ltBegin(Note const& a, Note const& b) { return a.begin < b.begin; }
+       /// Compares end of two notes
+       static bool ltEnd(Note const& a, Note const& b) { return a.end < b.end; }
+  private:
+       double scoreMultiplier() const;
+};
+
+typedef std::vector<Note> Notes;
+
+class VocalTrack {
+public:
+       VocalTrack(std::string name);
+       void reload();
+       std::string name;
+       Notes notes;
+       int noteMin, noteMax; ///< lowest and highest note
+       double beginTime, endTime; ///< the period where there are notes
+       double m_scoreFactor; ///< normalization factor for the scoring system
+       MusicalScale scale; ///< scale in which song is sung
+};
+
+typedef std::map<std::string, VocalTrack> VocalTracks;
+
+struct DanceTrack {
+       DanceTrack(std::string& description, Notes& notes);
+       //track description
+       std::string description;
+       //container for the actual note data
+       Notes notes;
+};
+
+enum DanceDifficulty {
+       BEGINNER,
+       EASY,
+       MEDIUM,
+       HARD,
+       CHALLENGE,
+       DIFFICULTYCOUNT
+};
+
+typedef std::map<DanceDifficulty, DanceTrack> DanceDifficultyMap;
+typedef std::map<std::string, DanceDifficultyMap> DanceTracks;
diff --git a/game/opengl_text.cc b/game/opengl_text.cc
new file mode 100644 (file)
index 0000000..01d1724
--- /dev/null
@@ -0,0 +1,277 @@
+#include "opengl_text.hh"
+
+#include <boost/lexical_cast.hpp>
+#include "fontconfig/fontconfig.h"
+#include <libxml++/libxml++.h>
+#include <pango/pangocairo.h>
+#include <cmath>
+#include <iostream>
+#include <sstream>
+#include "fs.hh"
+
+void loadFonts() {
+       /* Disabled on Windows due to not working and producing weird cache directory in the wrong place
+#ifndef _WIN32
+       FcConfig *config = FcInitLoadConfigAndFonts();
+       for (fs::path const& font: listFiles("fonts")) {
+               FcConfigAppFontAddFile(config, reinterpret_cast<const FcChar8*>(font.string().c_str()));
+       }
+       FcConfigSetCurrent(config);
+#endif
+*/
+}
+
+namespace {
+       PangoAlignment parseAlignment(std::string const& fontalign) {
+               if (fontalign == "start") return PANGO_ALIGN_LEFT;
+               if (fontalign == "center" || fontalign == "middle") return PANGO_ALIGN_CENTER;
+               if (fontalign == "end") return PANGO_ALIGN_RIGHT;
+               throw std::logic_error(fontalign + ": Unknown font alignment (opengl_text.cc)");
+       }
+
+       PangoWeight parseWeight(std::string const& fontweight) {
+               if (fontweight == "normal") return PANGO_WEIGHT_NORMAL;
+               if (fontweight == "bold") return PANGO_WEIGHT_BOLD;
+               if (fontweight == "bolder") return PANGO_WEIGHT_ULTRABOLD;
+               throw std::logic_error(fontweight + ": Unknown font weight (opengl_text.cc)");
+       }
+
+       PangoStyle parseStyle(std::string const& fontstyle) {
+               if (fontstyle == "normal") return PANGO_STYLE_NORMAL;
+               if (fontstyle == "italic") return PANGO_STYLE_ITALIC;
+               if (fontstyle == "oblique") return PANGO_STYLE_OBLIQUE;
+               throw std::logic_error(fontstyle + ": Unknown font style (opengl_text.cc)");
+       }
+}
+
+OpenGLText::OpenGLText(TextStyle& _text, double m) {
+       m *= 2.0;  // HACK to improve text quality without affecting compatibility with old versions
+       // Setup font settings
+       PangoAlignment alignment = parseAlignment(_text.fontalign);
+       boost::shared_ptr<PangoFontDescription> desc(
+         pango_font_description_new(),
+         pango_font_description_free);
+       pango_font_description_set_weight(desc.get(), parseWeight(_text.fontweight));
+       pango_font_description_set_style(desc.get(), parseStyle(_text.fontstyle));
+       pango_font_description_set_family(desc.get(), _text.fontfamily.c_str());
+       pango_font_description_set_absolute_size(desc.get(), _text.fontsize * PANGO_SCALE * m);
+       double border = _text.stroke_width * m;
+       // Setup Pango context and layout
+       boost::shared_ptr<PangoContext> ctx(
+         pango_font_map_create_context(pango_cairo_font_map_get_default()),
+         g_object_unref);
+       boost::shared_ptr<PangoLayout> layout(
+         pango_layout_new(ctx.get()),
+         g_object_unref);
+       pango_layout_set_alignment(layout.get(), alignment);
+       pango_layout_set_font_description(layout.get(), desc.get());
+       pango_layout_set_text(layout.get(), _text.text.c_str(), -1);
+       // Compute text extents
+       {
+               PangoRectangle rec1, rec2;
+               pango_layout_get_pixel_extents(layout.get(), &rec1, &rec2);
+               m_x = rec2.width + border;  // Add twice half a border for margins
+               m_y = rec2.height + border;
+               m_x_advance = rec1.x;
+               m_y_advance = rec1.y;
+       }
+       // Create Cairo surface and drawing context
+       boost::shared_ptr<cairo_surface_t> surface(
+         cairo_image_surface_create(CAIRO_FORMAT_ARGB32, m_x, m_y),
+         cairo_surface_destroy);
+       boost::shared_ptr<cairo_t> dc(
+         cairo_create(surface.get()),
+         cairo_destroy);
+       // Keep things sharp and fast, we scale with OpenGL anyway...
+       cairo_set_antialias(dc.get(), CAIRO_ANTIALIAS_NONE);
+       // Add Pango line and path to proper position on the DC
+       cairo_move_to(dc.get(), 0.5 * border, 0.5 * border);  // Margins needed for border stroke to fit in
+       pango_cairo_update_layout(dc.get(), layout.get());
+       pango_cairo_layout_path(dc.get(), layout.get());
+       // Render text
+       if (_text.fill_col.a > 0.0) {
+               cairo_set_source_rgba(dc.get(), _text.fill_col.r, _text.fill_col.g, _text.fill_col.b, _text.fill_col.a);
+               cairo_fill_preserve(dc.get());
+       }
+       // Render text border
+       if (_text.stroke_col.a > 0.0) {
+               cairo_set_line_width(dc.get(), border);
+               cairo_set_source_rgba(dc.get(), _text.stroke_col.r, _text.stroke_col.g, _text.stroke_col.b, _text.stroke_col.a);
+               cairo_stroke(dc.get());
+       }
+       // Load into m_surface (OpenGL texture)
+       Bitmap bitmap(cairo_image_surface_get_data(surface.get()));
+       bitmap.fmt = pix::INT_ARGB;
+       bitmap.linearPremul = true;
+       bitmap.resize(cairo_image_surface_get_width(surface.get()), cairo_image_surface_get_height(surface.get()));
+       m_surface.load(bitmap);
+       // We don't want text quality multiplier m to affect rendering size...
+       m_x /= m;
+       m_y /= m;
+       m_x_advance /= m;
+       m_y_advance /= m;
+}
+
+void OpenGLText::draw() {
+       m_surface.draw();
+}
+
+void OpenGLText::draw(Dimensions &_dim, TexCoords &_tex) {
+       m_surface.dimensions = _dim;
+       m_surface.tex = _tex;
+       m_surface.draw();
+}
+
+namespace {
+       void parseTheme(fs::path const& themeFile, TextStyle &_theme, double &_width, double &_height, double &_x, double &_y, SvgTxtTheme::Align& _align) {
+               xmlpp::Node::PrefixNsMap nsmap;
+               nsmap["svg"] = "http://www.w3.org/2000/svg";
+               xmlpp::DomParser dom(themeFile.string());
+               xmlpp::NodeSet n;
+               // Parse width attribute
+               n = dom.get_document()->get_root_node()->find("/svg:svg/@width",nsmap);
+               if (n.empty()) throw std::runtime_error("Unable to find text theme info width in "+themeFile.string());
+               xmlpp::Attribute& width = dynamic_cast<xmlpp::Attribute&>(*n[0]);
+               _width = boost::lexical_cast<double>(width.get_value());
+               // Parse height attribute
+               n = dom.get_document()->get_root_node()->find("/svg:svg/@height",nsmap);
+               if (n.empty()) throw std::runtime_error("Unable to find text theme info height in "+themeFile.string());
+               xmlpp::Attribute& height = dynamic_cast<xmlpp::Attribute&>(*n[0]);
+               _height = boost::lexical_cast<double>(height.get_value());
+               // Parse text style attribute (CSS rules)
+               n = dom.get_document()->get_root_node()->find("/svg:svg//svg:text/@style",nsmap);
+               if (n.empty()) throw std::runtime_error("Unable to find text theme info style in "+themeFile.string());
+               xmlpp::Attribute& style = dynamic_cast<xmlpp::Attribute&>(*n[0]);
+               std::istringstream iss(style.get_value());
+               std::string token;
+               while (std::getline(iss, token, ';')) {
+                       std::istringstream iss2(token);
+                       std::getline(iss2, token, ':');
+                       if (token == "font-size") iss2 >> _theme.fontsize;
+                       else if (token == "font-family") std::getline(iss2, _theme.fontfamily);
+                       else if (token == "font-style") std::getline(iss2, _theme.fontstyle);
+                       else if (token == "font-weight") std::getline(iss2, _theme.fontweight);
+                       else if (token == "stroke-width") iss2 >> _theme.stroke_width;
+                       else if (token == "stroke-opacity") iss2 >> _theme.stroke_col.a;
+                       else if (token == "fill-opacity") iss2 >> _theme.fill_col.a;
+                       else if (token == "fill") iss2 >> _theme.fill_col;
+                       else if (token == "stroke") iss2 >> _theme.stroke_col;
+                       else if (token == "text-anchor") {
+                               std::string value;
+                               std::getline(iss2, value);
+                               _theme.fontalign = value;
+                               if (value == "start") _align = SvgTxtTheme::LEFT;
+                               else if (value == "middle") _align = SvgTxtTheme::CENTER;
+                               else if (value == "end") _align = SvgTxtTheme::RIGHT;
+                       }
+               }
+               // Parse x and y attributes
+               n = dom.get_document()->get_root_node()->find("/svg:svg//svg:text/@x",nsmap);
+               if (n.empty()) throw std::runtime_error("Unable to find text theme info x in "+themeFile.string());
+               xmlpp::Attribute& x = dynamic_cast<xmlpp::Attribute&>(*n[0]);
+               _x = boost::lexical_cast<double>(x.get_value());
+               n = dom.get_document()->get_root_node()->find("/svg:svg//svg:text/@y",nsmap);
+               if (n.empty()) throw std::runtime_error("Unable to find text theme info y in "+themeFile.string());
+               xmlpp::Attribute& y = dynamic_cast<xmlpp::Attribute&>(*n[0]);
+               _y = boost::lexical_cast<double>(y.get_value());
+       }
+}
+
+SvgTxtThemeSimple::SvgTxtThemeSimple(fs::path const& themeFile, double factor) : m_factor(factor) {
+       SvgTxtTheme::Align a;
+       double tmp;
+       parseTheme(themeFile, m_text, tmp, tmp, tmp, tmp, a);
+}
+
+void SvgTxtThemeSimple::render(std::string _text) {
+       if (!m_opengl_text.get() || m_cache_text != _text) {
+               m_cache_text = _text;
+               m_text.text = _text;
+               m_opengl_text.reset(new OpenGLText(m_text, m_factor));
+       }
+}
+
+void SvgTxtThemeSimple::draw() {
+       m_opengl_text->draw();
+}
+
+SvgTxtTheme::SvgTxtTheme(fs::path const& themeFile, double factor): m_align(),m_factor(factor) {
+       parseTheme(themeFile, m_text, m_width, m_height, m_x, m_y, m_align);
+       dimensions.stretch(0.0, 0.0).middle(-0.5 + m_x / m_width).center((m_y - 0.5 * m_height) / m_width);
+}
+
+void SvgTxtTheme::setHighlight(fs::path const& themeFile) {
+       double a,b,c,d;
+       Align e;
+       parseTheme(themeFile, m_text_highlight, a, b, c, d, e);
+}
+
+void SvgTxtTheme::draw(std::vector<std::string> const& _text) {
+       std::vector<TZoomText> tmp;
+
+       for (auto const& str: _text) {
+               TZoomText t;
+               t.string = str;
+               t.factor = 1.0;
+               tmp.push_back(t);
+       }
+
+       draw(tmp);
+}
+
+void SvgTxtTheme::draw(std::string _text) {
+       std::vector<TZoomText> tmp;
+       TZoomText t;
+       t.string = _text;
+       t.factor = 1.0;
+       tmp.push_back(t);
+       draw(tmp);
+}
+
+void SvgTxtTheme::draw(std::vector<TZoomText> const& _text) {
+       std::string tmp;
+       for (auto& zt: _text) tmp += zt.string;
+
+       if (m_opengl_text.size() != _text.size() || m_cache_text != tmp) {
+               m_cache_text = tmp;
+               m_opengl_text.clear();
+               for (auto& zt: _text) {
+                       m_text.text = zt.string;
+                       m_opengl_text.push_back(new OpenGLText(m_text, m_factor));
+               }
+       }
+       double text_x = 0.0;
+       double text_y = 0.0;
+       // First compute maximum height and whole length
+       for (unsigned int i = 0; i < _text.size(); i++ ) {
+               text_x += m_opengl_text[i].x();
+               text_y = std::max(text_y, m_opengl_text[i].y());
+       }
+
+       double texture_ar = text_x / text_y;
+       m_texture_width = std::min(0.96, text_x/800.);
+       m_texture_height = m_texture_width / texture_ar;
+
+       double position_x = dimensions.x1();
+       if (m_align == CENTER) position_x -= 0.5 * m_texture_width;
+       if (m_align == RIGHT) position_x -= m_texture_width;
+
+       for (unsigned int i = 0; i < _text.size(); i++ ) {
+               double syllable_x = m_opengl_text[i].x();
+               double syllable_width = syllable_x *  m_texture_width / text_x;
+               double syllable_height = m_texture_height;
+               double syllable_ar = syllable_width / syllable_height;
+               Dimensions dim(syllable_ar);
+               dim.fixedHeight(m_texture_height).center(dimensions.y1());
+               dim.middle(position_x + 0.5 * dim.w());
+               TexCoords tex;
+               double factor = _text[i].factor;
+               if (factor > 1.0) {
+                       ColorTrans c(Color(m_text_highlight.fill_col.r, m_text_highlight.fill_col.g, m_text_highlight.fill_col.b));
+                       dim.fixedWidth(dim.w() * factor);
+                       m_opengl_text[i].draw(dim, tex);
+               } else m_opengl_text[i].draw(dim, tex);
+               position_x += syllable_width;
+       }
+}
+
diff --git a/game/opengl_text.hh b/game/opengl_text.hh
new file mode 100644 (file)
index 0000000..99ceaef
--- /dev/null
@@ -0,0 +1,172 @@
+#pragma once
+
+#include "color.hh"
+#include "surface.hh"
+#include <boost/scoped_ptr.hpp>
+#include <boost/ptr_container/ptr_vector.hpp>
+#include <vector>
+
+/// Load custom fonts from current theme and data folders
+void loadFonts();
+
+/// zoomed text
+struct TZoomText {
+       /// text
+       std::string string;
+       /// zoomfactor
+       double factor;
+       /// constructor
+       TZoomText(std::string const& str = std::string()): string(str), factor(1.0) {}
+};
+
+/// Special theme for creating opengl themed surfaces
+/** this structure does not include:
+ *  - library specific field
+ *  - global positionning
+ * the font{family,style,weight,align} are the one found into SVGs
+ */
+struct TextStyle {
+       Color fill_col; ///< fill color
+       Color stroke_col; ///< stroke color
+       double stroke_width; ///< stroke thickness
+       double fontsize; ///< fontsize
+       std::string fontfamily; ///< fontfamily
+       std::string fontstyle; ///< fontstyle
+       std::string fontweight; ///< fontweight
+       std::string fontalign; ///< alignment
+       std::string text; ///< text
+       TextStyle(): stroke_width(), fontsize() {}
+};
+
+/// this class will enable to create a texture from a themed text structure
+/** it will not cache any data (class using this class should)
+ * it provides size of the texture are drawn (x,y)
+ * it provides size of the texture created (x_power_of_two, y_power_of_two)
+ */
+class OpenGLText {
+public:
+       /// constructor
+       OpenGLText(TextStyle &_text, double m);
+       /// draws area
+       void draw(Dimensions &_dim, TexCoords &_tex);
+       /// draws full texture
+       void draw();
+       /// @return x
+       double x() const { return m_x; }
+       /// @return y
+       double y() const { return m_y; }
+       /// @return x_advance
+       double x_advance() const { return m_x_advance; }
+       /// @return y_advance
+       double y_advance() const { return m_y_advance; }
+       /// @returns dimension of texture
+       Dimensions& dimensions() { return m_surface.dimensions; }
+
+private:
+       double m_x;
+       double m_y;
+       double m_x_advance;
+       double m_y_advance;
+       Surface m_surface;
+};
+
+/// themed svg texts (simple)
+class SvgTxtThemeSimple {
+public:
+       /// constructor
+       SvgTxtThemeSimple(fs::path const& themeFile, double factor = 1.0);
+       /// renders text
+       void render(std::string _text);
+       /// draws texture
+       void draw();
+       /// gets dimensions
+       Dimensions& dimensions() { return m_opengl_text->dimensions(); }
+
+private:
+       boost::scoped_ptr<OpenGLText> m_opengl_text;
+       std::string m_cache_text;
+       TextStyle m_text;
+       double m_factor;
+};
+
+/// themed svg texts
+class SvgTxtTheme {
+public:
+       /// enum declaration Gravity:
+       /** <pre>
+        * +----+---+----+
+        * | NW | N | NE |
+        * +----+---+----+
+        * | W  | C |  E |
+        * +----+---+----+
+        * | SW | S | SE |
+        * +----+---+----+ (and ASIS)
+        *
+        * Coord:
+        * (x0,y0)        (x1,y0)
+        *    +--------------+
+        *    |              |
+        *    |              |
+        *    +--------------+
+        * (x0,y1)        (x1,y1)
+        *
+        * gravity will affect how fit-inside/fit-outside will work
+        * fitting will always keep aspect ratio
+        * fit-inside: will fit inside if texture is too big
+        * force-fit-inside: will always stretch to fill at least one of the axis
+        * fit-outside: will fit outside if texture is too small
+        * force-fit-outside: will always stretch to fill both axis
+        * gravity does not mean position, it is only an anchor
+        * Fixed points:
+        *   NW: (x0,y0)
+        *   N:  ((x0+x1)/2,y0)
+        *   NE: (x1,y0)
+        *   W:  (x0,(y0+y1)/2)
+        *   C:  ((x0+x1)/2,(y0+y1)/2)
+        *   E:  (x1,(y0+y1)/2)
+        *   SW: (x0,y1)
+        *   S:  ((x0+x1)/2,y1)
+        *   SE: (x1,y1)</pre>
+        */
+       /// TODO anchors
+       enum Gravity {NW,N,NE,W,C,E,SW,S,SE};
+       /// where to position when space is too small
+       enum Fitting {F_ASIS, INSIDE, OUTSIDE, FORCE_INSIDE, FORCE_OUTSIDE};
+       /// vertical align
+       enum VAlign {V_ASIS, TOP, MIDDLE, BOTTOM};
+       /// horizontal align
+       enum Align {A_ASIS, LEFT, CENTER, RIGHT};
+       /// dimensions, what else
+       Dimensions dimensions;
+       /// constructor
+       SvgTxtTheme(fs::path const& themeFile, double factor = 1.0);
+       /// draws text with alpha
+       void draw(std::vector<TZoomText> const& _text);
+       /// draw texts
+       void draw(std::vector<std::string> const& _text);
+       /// draw text with alpha
+       void draw(std::string _text);
+       /// sets highlight
+       void setHighlight(fs::path const& themeFile);
+       /// width
+       double w() const { return m_texture_width; }
+       /// height
+       double h() const { return m_texture_height; }
+       /// set align
+       void setAlign(Align align) { m_align = align; }
+
+private:
+       boost::ptr_vector<OpenGLText> m_opengl_text;
+       Align m_align;
+       double m_x;
+       double m_y;
+       double m_width;
+       double m_height;
+       double m_factor;
+       double m_texture_width;
+       double m_texture_height;
+       std::string m_cache_text;
+       TextStyle m_text;
+       TextStyle m_text_highlight;
+};
+
diff --git a/game/osx/SDLMain.h b/game/osx/SDLMain.h
new file mode 100644 (file)
index 0000000..4683df5
--- /dev/null
@@ -0,0 +1,11 @@
+/*   SDLMain.m - main entry point for our Cocoa-ized SDL app
+       Initial Version: Darrell Walisser <dwaliss1@purdue.edu>
+       Non-NIB-Code & other changes: Max Horn <max@quendi.de>
+
+    Feel free to customize this file to suit your needs
+*/
+
+#import <Cocoa/Cocoa.h>
+
+@interface SDLMain : NSObject
+@end
diff --git a/game/osx/SDLMain.m b/game/osx/SDLMain.m
new file mode 100644 (file)
index 0000000..2eaa1c1
--- /dev/null
@@ -0,0 +1,384 @@
+/*   SDLMain.m - main entry point for our Cocoa-ized SDL app
+       Initial Version: Darrell Walisser <dwaliss1@purdue.edu>
+       Non-NIB-Code & other changes: Max Horn <max@quendi.de>
+
+    Feel free to customize this file to suit your needs
+*/
+
+#import "SDL.h"
+#import "SDLMain.h"
+#import <sys/param.h> /* for MAXPATHLEN */
+#import <unistd.h>
+
+/* For some reaon, Apple removed setAppleMenu from the headers in 10.4,
+ but the method still is there and works. To avoid warnings, we declare
+ it ourselves here. */
+@interface NSApplication(SDL_Missing_Methods)
+- (void)setAppleMenu:(NSMenu *)menu;
+@end
+
+/* Use this flag to determine whether we use SDLMain.nib or not */
+#define                SDL_USE_NIB_FILE        0
+
+/* Use this flag to determine whether we use CPS (docking) or not */
+#define                SDL_USE_CPS             1
+#ifdef SDL_USE_CPS
+/* Portions of CPS.h */
+typedef struct CPSProcessSerNum
+{
+       UInt32          lo;
+       UInt32          hi;
+} CPSProcessSerNum;
+
+extern OSErr   CPSGetCurrentProcess( CPSProcessSerNum *psn);
+extern OSErr   CPSEnableForegroundOperation( CPSProcessSerNum *psn, UInt32 _arg2, UInt32 _arg3, UInt32 _arg4, UInt32 _arg5);
+extern OSErr   CPSSetFrontProcess( CPSProcessSerNum *psn);
+
+#endif /* SDL_USE_CPS */
+
+static int    gArgc;
+static char  **gArgv;
+static BOOL   gFinderLaunch;
+static BOOL   gCalledAppMainline = FALSE;
+
+static NSString *getApplicationName(void)
+{
+    NSDictionary *dict;
+    NSString *appName = 0;
+
+    /* Determine the application name */
+    dict = (NSDictionary *)CFBundleGetInfoDictionary(CFBundleGetMainBundle());
+    if (dict)
+        appName = [dict objectForKey: @"CFBundleName"];
+    
+    if (![appName length])
+        appName = [[NSProcessInfo processInfo] processName];
+
+    return appName;
+}
+
+#if SDL_USE_NIB_FILE
+/* A helper category for NSString */
+@interface NSString (ReplaceSubString)
+- (NSString *)stringByReplacingRange:(NSRange)aRange with:(NSString *)aString;
+@end
+#endif
+
+@interface SDLApplication : NSApplication
+@end
+
+@implementation SDLApplication
+/* Invoked from the Quit menu item */
+- (void)terminate:(id)sender
+{
+    /* Post a SDL_QUIT event */
+    SDL_Event event;
+    event.type = SDL_QUIT;
+    SDL_PushEvent(&event);
+}
+@end
+
+/* The main class of the application, the application's delegate */
+@implementation SDLMain
+
+/* Set the working directory to the .app's parent directory */
+- (void) setupWorkingDirectory:(BOOL)shouldChdir
+{
+    if (shouldChdir)
+    {
+        char parentdir[MAXPATHLEN];
+               CFURLRef url = CFBundleCopyBundleURL(CFBundleGetMainBundle());
+               CFURLRef url2 = CFURLCreateCopyDeletingLastPathComponent(0, url);
+               if (CFURLGetFileSystemRepresentation(url2, true, (UInt8 *)parentdir, MAXPATHLEN)) {
+               assert ( chdir (parentdir) == 0 );   /* chdir to the binary app's parent */
+               }
+               CFRelease(url);
+               CFRelease(url2);
+       }
+
+}
+
+#if SDL_USE_NIB_FILE
+
+/* Fix menu to contain the real app name instead of "SDL App" */
+- (void)fixMenu:(NSMenu *)aMenu withAppName:(NSString *)appName
+{
+    NSRange aRange;
+    NSEnumerator *enumerator;
+    NSMenuItem *menuItem;
+
+    aRange = [[aMenu title] rangeOfString:@"SDL App"];
+    if (aRange.length != 0)
+        [aMenu setTitle: [[aMenu title] stringByReplacingRange:aRange with:appName]];
+
+    enumerator = [[aMenu itemArray] objectEnumerator];
+    while ((menuItem = [enumerator nextObject]))
+    {
+        aRange = [[menuItem title] rangeOfString:@"SDL App"];
+        if (aRange.length != 0)
+            [menuItem setTitle: [[menuItem title] stringByReplacingRange:aRange with:appName]];
+        if ([menuItem hasSubmenu])
+            [self fixMenu:[menuItem submenu] withAppName:appName];
+    }
+    [ aMenu sizeToFit ];
+}
+
+#else
+
+static void setApplicationMenu(void)
+{
+    /* warning: this code is very odd */
+    NSMenu *appleMenu;
+    NSMenuItem *menuItem;
+    NSString *title;
+    NSString *appName;
+    
+    appName = getApplicationName();
+    appleMenu = [[NSMenu alloc] initWithTitle:@""];
+    
+    /* Add menu items */
+    title = [@"About " stringByAppendingString:appName];
+    [appleMenu addItemWithTitle:title action:@selector(orderFrontStandardAboutPanel:) keyEquivalent:@""];
+
+    [appleMenu addItem:[NSMenuItem separatorItem]];
+
+    title = [@"Hide " stringByAppendingString:appName];
+    [appleMenu addItemWithTitle:title action:@selector(hide:) keyEquivalent:@"h"];
+
+    menuItem = (NSMenuItem *)[appleMenu addItemWithTitle:@"Hide Others" action:@selector(hideOtherApplications:) keyEquivalent:@"h"];
+    [menuItem setKeyEquivalentModifierMask:(NSAlternateKeyMask|NSCommandKeyMask)];
+
+    [appleMenu addItemWithTitle:@"Show All" action:@selector(unhideAllApplications:) keyEquivalent:@""];
+
+    [appleMenu addItem:[NSMenuItem separatorItem]];
+
+    title = [@"Quit " stringByAppendingString:appName];
+    [appleMenu addItemWithTitle:title action:@selector(terminate:) keyEquivalent:@"q"];
+
+    
+    /* Put menu into the menubar */
+    menuItem = [[NSMenuItem alloc] initWithTitle:@"" action:nil keyEquivalent:@""];
+    [menuItem setSubmenu:appleMenu];
+    [[NSApp mainMenu] addItem:menuItem];
+
+    /* Tell the application object that this is now the application menu */
+    [NSApp setAppleMenu:appleMenu];
+
+    /* Finally give up our references to the objects */
+    [appleMenu release];
+    [menuItem release];
+}
+
+/* Create a window menu */
+static void setupWindowMenu(void)
+{
+    NSMenu      *windowMenu;
+    NSMenuItem  *windowMenuItem;
+    NSMenuItem  *menuItem;
+
+    windowMenu = [[NSMenu alloc] initWithTitle:@"Window"];
+    
+    /* "Minimize" item */
+    menuItem = [[NSMenuItem alloc] initWithTitle:@"Minimize" action:@selector(performMiniaturize:) keyEquivalent:@"m"];
+    [windowMenu addItem:menuItem];
+    [menuItem release];
+    
+    /* Put menu into the menubar */
+    windowMenuItem = [[NSMenuItem alloc] initWithTitle:@"Window" action:nil keyEquivalent:@""];
+    [windowMenuItem setSubmenu:windowMenu];
+    [[NSApp mainMenu] addItem:windowMenuItem];
+    
+    /* Tell the application object that this is now the window menu */
+    [NSApp setWindowsMenu:windowMenu];
+
+    /* Finally give up our references to the objects */
+    [windowMenu release];
+    [windowMenuItem release];
+}
+
+/* Replacement for NSApplicationMain */
+static void CustomApplicationMain (int argc, char **argv)
+{
+    NSAutoreleasePool  *pool = [[NSAutoreleasePool alloc] init];
+    SDLMain                            *sdlMain;
+
+    /* Ensure the application object is initialised */
+    [SDLApplication sharedApplication];
+    
+#ifdef SDL_USE_CPS
+    {
+        CPSProcessSerNum PSN;
+        /* Tell the dock about us */
+        if (!CPSGetCurrentProcess(&PSN))
+            if (!CPSEnableForegroundOperation(&PSN,0x03,0x3C,0x2C,0x1103))
+                if (!CPSSetFrontProcess(&PSN))
+                    [SDLApplication sharedApplication];
+    }
+#endif /* SDL_USE_CPS */
+
+    /* Set up the menubar */
+    [NSApp setMainMenu:[[NSMenu alloc] init]];
+    setApplicationMenu();
+    setupWindowMenu();
+
+    /* Create SDLMain and make it the app delegate */
+    sdlMain = [[SDLMain alloc] init];
+    [NSApp setDelegate:sdlMain];
+    
+    /* Start the main event loop */
+    [NSApp run];
+    
+    [sdlMain release];
+    [pool release];
+}
+
+#endif
+
+
+/*
+ * Catch document open requests...this lets us notice files when the app
+ *  was launched by double-clicking a document, or when a document was
+ *  dragged/dropped on the app's icon. You need to have a
+ *  CFBundleDocumentsType section in your Info.plist to get this message,
+ *  apparently.
+ *
+ * Files are added to gArgv, so to the app, they'll look like command line
+ *  arguments. Previously, apps launched from the finder had nothing but
+ *  an argv[0].
+ *
+ * This message may be received multiple times to open several docs on launch.
+ *
+ * This message is ignored once the app's mainline has been called.
+ */
+- (BOOL)application:(NSApplication *)theApplication openFile:(NSString *)filename
+{
+    const char *temparg;
+    size_t arglen;
+    char *arg;
+    char **newargv;
+
+    if (!gFinderLaunch)  /* MacOS is passing command line args. */
+        return FALSE;
+
+    if (gCalledAppMainline)  /* app has started, ignore this document. */
+        return FALSE;
+
+    temparg = [filename UTF8String];
+    arglen = SDL_strlen(temparg) + 1;
+    arg = (char *) SDL_malloc(arglen);
+    if (arg == NULL)
+        return FALSE;
+
+    newargv = (char **) realloc(gArgv, sizeof (char *) * (gArgc + 2));
+    if (newargv == NULL)
+    {
+        SDL_free(arg);
+        return FALSE;
+    }
+    gArgv = newargv;
+
+    SDL_strlcpy(arg, temparg, arglen);
+    gArgv[gArgc++] = arg;
+    gArgv[gArgc] = NULL;
+    return TRUE;
+}
+
+
+/* Called when the internal event loop has just started running */
+- (void) applicationDidFinishLaunching: (NSNotification *) note
+{
+    int status;
+
+    /* Set the working directory to the .app's parent directory */
+    [self setupWorkingDirectory:gFinderLaunch];
+
+#if SDL_USE_NIB_FILE
+    /* Set the main menu to contain the real app name instead of "SDL App" */
+    [self fixMenu:[NSApp mainMenu] withAppName:getApplicationName()];
+#endif
+
+    /* Hand off to main application code */
+    gCalledAppMainline = TRUE;
+    status = SDL_main (gArgc, gArgv);
+
+    /* We're done, thank you for playing */
+    exit(status);
+}
+@end
+
+
+@implementation NSString (ReplaceSubString)
+
+- (NSString *)stringByReplacingRange:(NSRange)aRange with:(NSString *)aString
+{
+    unsigned int bufferSize;
+    unsigned int selfLen = [self length];
+    unsigned int aStringLen = [aString length];
+    unichar *buffer;
+    NSRange localRange;
+    NSString *result;
+
+    bufferSize = selfLen + aStringLen - aRange.length;
+    buffer = NSAllocateMemoryPages(bufferSize*sizeof(unichar));
+    
+    /* Get first part into buffer */
+    localRange.location = 0;
+    localRange.length = aRange.location;
+    [self getCharacters:buffer range:localRange];
+    
+    /* Get middle part into buffer */
+    localRange.location = 0;
+    localRange.length = aStringLen;
+    [aString getCharacters:(buffer+aRange.location) range:localRange];
+     
+    /* Get last part into buffer */
+    localRange.location = aRange.location + aRange.length;
+    localRange.length = selfLen - localRange.location;
+    [self getCharacters:(buffer+aRange.location+aStringLen) range:localRange];
+    
+    /* Build output string */
+    result = [NSString stringWithCharacters:buffer length:bufferSize];
+    
+    NSDeallocateMemoryPages(buffer, bufferSize);
+    
+    return result;
+}
+
+@end
+
+
+
+#ifdef main
+#  undef main
+#endif
+
+
+/* Main entry point to executable - should *not* be SDL_main! */
+int main (int argc, char **argv)
+{
+    /* Copy the arguments into a global variable */
+    /* This is passed if we are launched by double-clicking */
+    if ( argc >= 2 && strncmp (argv[1], "-psn", 4) == 0 ) {
+        gArgv = (char **) SDL_malloc(sizeof (char *) * 2);
+        gArgv[0] = argv[0];
+        gArgv[1] = NULL;
+        gArgc = 1;
+        gFinderLaunch = YES;
+    } else {
+        int i;
+        gArgc = argc;
+        gArgv = (char **) SDL_malloc(sizeof (char *) * (argc+1));
+        for (i = 0; i <= argc; i++)
+            gArgv[i] = argv[i];
+        gFinderLaunch = NO;
+    }
+
+#if SDL_USE_NIB_FILE
+    [SDLApplication poseAsClass:[NSApplication class]];
+    NSApplicationMain (argc, argv);
+#else
+    CustomApplicationMain (argc, argv);
+#endif
+    return 0;
+}
+
diff --git a/game/pitch.cc b/game/pitch.cc
new file mode 100644 (file)
index 0000000..a64a5ce
--- /dev/null
@@ -0,0 +1,233 @@
+#include "pitch.hh"
+
+#include "util.hh"
+#include "libda/fft.hpp"
+#include <cmath>
+#include <iostream>
+#include <iomanip>
+
+// Limit the range to avoid noise and useless computation
+static const double FFT_MINFREQ = 45.0;
+static const double FFT_MAXFREQ = 5000.0;
+
+Tone::Tone():
+  freq(0.0),
+  db(-getInf()),
+  stabledb(-getInf()),
+  age()
+{
+       for (auto& h: harmonics) h = -getInf();
+}
+
+void Tone::print() const {
+       if (age < Tone::MINAGE) return;
+       std::cout << std::fixed << std::setprecision(1) << freq << " Hz, age " << age << ", " << db << " dB:";
+       for (std::size_t i = 0; i < 8; ++i) std::cout << " " << harmonics[i];
+       std::cout << std::endl;
+}
+
+bool Tone::operator==(double f) const {
+       return std::abs(freq / f - 1.0) < 0.05;
+}
+
+Analyzer::Analyzer(double rate, std::string id, std::size_t step):
+  m_step(step),
+  m_resampleFactor(1.0),
+  m_resamplePos(),
+  m_rate(rate),
+  m_id(id),
+  m_window(FFT_N),
+  m_fftLastPhase(FFT_N / 2),
+  m_peak(0.0),
+  m_oldfreq(0.0)
+{
+       if (m_step > FFT_N) throw std::logic_error("Analyzer step is larger that FFT_N (ideally it should be less than a fourth of FFT_N).");
+       // Hamming window
+       for (size_t i=0; i < FFT_N; i++) {
+               m_window[i] = 0.53836 - 0.46164 * std::cos(2.0 * M_PI * i / (FFT_N - 1));
+       }
+}
+
+void Analyzer::output(float* begin, float* end, double rate) {
+       constexpr unsigned a = 2;
+       const unsigned size = m_passthrough.size();
+       const unsigned out = (end - begin) / 2 /* stereo */;
+       if (out == 0) return;
+       const unsigned in = m_resampleFactor * (m_rate / rate) * out + 2 * a /* lanczos kernel */ + 5 /* safety margin for rounding errors */;
+       float pcm[m_passthrough.capacity];
+       m_passthrough.read(pcm, pcm + in + 4);
+       for (unsigned i = 0; i < out; ++i) {
+               double s = 0.0;
+               unsigned k = m_resamplePos;
+               double x = m_resamplePos - k;
+               // Lanczos sampling of input at m_resamplePos
+               for (unsigned j = 0; j <= 2 * a; ++j) s += pcm[k + j] * da::lanc<a>(x - j + a);
+               s *= 5.0;
+               begin[i * 2] += s;
+               begin[i * 2 + 1] += s;
+               m_resamplePos += m_resampleFactor;
+       }
+       unsigned num = m_resamplePos;
+       m_resamplePos -= num;
+       if (size > 3000) {
+               // Reset
+               m_passthrough.pop(m_passthrough.size() - 700);
+               m_resampleFactor = 1.0;
+       } else {
+               m_passthrough.pop(num);
+               m_resampleFactor = 0.99 * m_resampleFactor + 0.01 * (size > 700 ? 1.02 : 0.98);
+       }
+}
+
+
+namespace {
+       struct Peak {
+               double freq;
+               double db;
+               bool harm[Tone::MAXHARM];
+               Peak(double _freq = 0.0, double _db = -getInf()):
+                 freq(_freq), db(_db)
+               {
+                       for (auto& h: harm) h = false;
+               }
+               void clear() {
+                       freq = 0.0;
+                       db = -getInf();
+               }
+       };
+
+       Peak& match(std::vector<Peak>& peaks, std::size_t pos) {
+               std::size_t best = pos;
+               if (peaks[pos - 1].db > peaks[best].db) best = pos - 1;
+               if (peaks[pos + 1].db > peaks[best].db) best = pos + 1;
+               return peaks[best];
+       }
+}
+
+bool Analyzer::calcFFT() {
+       float pcm[FFT_N];
+       // Read FFT_N samples, move forward by m_step samples
+       if (!m_buf.read(pcm, pcm + FFT_N)) return false;
+       m_buf.pop(m_step);
+       // Peak level calculation of the most recent m_step samples (the rest is overlap)
+       for (float const* ptr = pcm + FFT_N - m_step; ptr != pcm + FFT_N; ++ptr) {
+               float s = *ptr;
+               float p = s * s;
+               if (p > m_peak) m_peak = p; else m_peak *= 0.999;
+       }
+       // Calculate FFT
+       m_fft = da::fft<FFT_P>(pcm, m_window);
+       return true;
+}
+
+void Analyzer::calcTones() {
+       // Precalculated constants
+       const double freqPerBin = m_rate / FFT_N;
+       const double phaseStep = 2.0 * M_PI * m_step / FFT_N;
+       const double normCoeff = 1.0 / FFT_N;
+       const double minMagnitude = pow(10, -100.0 / 20.0) / normCoeff; // -100 dB
+       // Limit frequency range of processing
+       const size_t kMin = std::max(size_t(1), size_t(FFT_MINFREQ / freqPerBin));
+       const size_t kMax = std::min(FFT_N / 2, size_t(FFT_MAXFREQ / freqPerBin));
+       std::vector<Peak> peaks(kMax + 1); // One extra to simplify loops
+       for (size_t k = 1; k <= kMax; ++k) {
+               double magnitude = std::abs(m_fft[k]);
+               double phase = std::arg(m_fft[k]);
+               // process phase difference
+               double delta = phase - m_fftLastPhase[k];
+               m_fftLastPhase[k] = phase;
+               delta -= k * phaseStep;  // subtract expected phase difference
+               delta = remainder(delta, 2.0 * M_PI);  // map delta phase into +/- M_PI interval
+               delta /= phaseStep;  // calculate diff from bin center frequency
+               double freq = (k + delta) * freqPerBin;  // calculate the true frequency
+               if (freq > 1.0 && magnitude > minMagnitude) {
+                       peaks[k].freq = freq;
+                       peaks[k].db = 20.0 * log10(normCoeff * magnitude);
+               }
+       }
+       // Prefilter peaks
+       double prevdb = peaks[0].db;
+       for (size_t k = 1; k < kMax; ++k) {
+               double db = peaks[k].db;
+               if (db > prevdb) peaks[k - 1].clear();
+               if (db < prevdb) peaks[k].clear();
+               prevdb = db;
+       }
+       // Find the tones (collections of harmonics) from the array of peaks
+       tones_t tones;
+       for (size_t k = kMax - 1; k >= kMin; --k) {
+               if (peaks[k].db < -70.0) continue;
+               // Find the best divider for getting the fundamental from peaks[k]
+               std::size_t bestDiv = 1;
+               int bestScore = 0;
+               for (std::size_t div = 2; div <= Tone::MAXHARM && k / div > 1; ++div) {
+                       double freq = peaks[k].freq / div; // Fundamental
+                       int score = 0;
+                       for (std::size_t n = 1; n < div && n < 8; ++n) {
+                               Peak& p = match(peaks, k * n / div);
+                               --score;
+                               if (p.db < -90.0 || std::abs(p.freq / n / freq - 1.0) > .03) continue;
+                               if (n == 1) score += 4; // Extra for fundamental
+                               score += 2;
+                       }
+                       if (score > bestScore) {
+                               bestScore = score;
+                               bestDiv = div;
+                       }
+               }
+               // Construct a Tone by combining the fundamental frequency (freq) and all harmonics
+               Tone t;
+               std::size_t count = 0;
+               double freq = peaks[k].freq / bestDiv;
+               t.db = peaks[k].db;
+               for (std::size_t n = 1; n <= bestDiv; ++n) {
+                       // Find the peak for n'th harmonic
+                       Peak& p = match(peaks, k * n / bestDiv);
+                       if (std::abs(p.freq / n / freq - 1.0) > .03) continue; // Does it match the fundamental freq?
+                       if (p.db > t.db - 10.0) {
+                               t.db = std::max(t.db, p.db);
+                               ++count;
+                               t.freq += p.freq / n;
+                       }
+                       t.harmonics[n - 1] = p.db;
+                       p.clear();
+               }
+               t.freq /= count;
+               // If the tone seems strong enough, add it (-3 dB compensation for each harmonic)
+               if (t.db > -50.0 - 3.0 * count) {
+                       t.stabledb = t.db;
+                       tones.push_back(t);
+               }
+       }
+       mergeWithOld(tones);
+       m_tones.swap(tones);
+}
+
+void Analyzer::mergeWithOld(tones_t& tones) const {
+       tones.sort();
+       auto it = tones.begin();
+       // Iterate over old tones
+       for (auto const& old: m_tones) {
+               // Try to find a matching new tone
+               while (it != tones.end() && *it < old) ++it;
+               // If match found
+               if (it != tones.end() && *it == old) {
+                       // Merge the old tone into the new tone
+                       it->age = old.age + 1;
+                       it->stabledb = 0.8 * old.stabledb + 0.2 * it->db;
+                       it->freq = 0.5 * old.freq + 0.5 * it->freq;
+               } else if (old.db > -80.0) {
+                       // Insert a decayed version of the old tone into new tones
+                       Tone& t = *tones.insert(it, old);
+                       t.db -= 5.0;
+                       t.stabledb -= 0.1;
+               }
+       }
+}
+
+void Analyzer::process() {
+       // Try calculating FFT and calculate tones until no more data in input buffer
+       while (calcFFT()) calcTones();
+}
+
+
diff --git a/game/pitch.hh b/game/pitch.hh
new file mode 100644 (file)
index 0000000..497e54f
--- /dev/null
@@ -0,0 +1,131 @@
+#pragma once
+
+#include <complex>
+#include <vector>
+#include <list>
+#include <algorithm>
+#include <cmath>
+
+/// struct to represent tones
+struct Tone {
+       static const std::size_t MAXHARM = 48; ///< The maximum number of harmonics tracked
+       static const std::size_t MINAGE = 2; ///< The minimum age required for a tone to be output
+       double freq; ///< Frequency (Hz)
+       double db; ///< Level (dB)
+       double stabledb; ///< Stable level, useful for graphics rendering
+       double harmonics[MAXHARM]; ///< Harmonics' levels
+       std::size_t age; ///< How many times the tone has been detected in row
+       Tone(); 
+       void print() const; ///< Prints Tone to std::cout
+       bool operator==(double f) const; ///< Compare for rough frequency match
+       /// Less-than compare by levels (instead of frequencies like operator< does)
+       static bool dbCompare(Tone const& l, Tone const& r) { return l.db < r.db; }
+};
+
+static inline bool operator==(Tone const& lhs, Tone const& rhs) { return lhs == rhs.freq; }
+static inline bool operator!=(Tone const& lhs, Tone const& rhs) { return !(lhs == rhs); }
+static inline bool operator<=(Tone const& lhs, Tone const& rhs) { return lhs.freq < rhs.freq || lhs == rhs; }
+static inline bool operator>=(Tone const& lhs, Tone const& rhs) { return lhs.freq > rhs.freq || lhs == rhs; }
+static inline bool operator<(Tone const& lhs, Tone const& rhs) { return lhs.freq < rhs.freq && lhs != rhs; }
+static inline bool operator>(Tone const& lhs, Tone const& rhs) { return lhs.freq > rhs.freq && lhs != rhs; }
+
+static const unsigned FFT_P = 10;
+static const std::size_t FFT_N = 1 << FFT_P;
+
+/// Lock-free ring buffer. Discards oldest data on overflow (not strictly thread-safe).
+template <size_t SIZE> class RingBuffer {
+public:
+       constexpr static size_t capacity = SIZE;
+       RingBuffer(): m_read(), m_write() {}  ///< Initialize empty buffer
+       template <typename InIt> void insert(InIt begin, InIt end) {
+               unsigned r = m_read;  // The read position
+               unsigned w = m_write;  // The write position
+               bool overflow = false;
+               while (begin != end) {
+                       m_buf[w] = *begin++;  // Copy sample
+                       w = modulo(w + 1);  // Update cursor
+                       if (w == r) overflow = true;
+               }
+               m_write = w;
+               if (overflow) m_read = modulo(w + 1);  // Reset read pointer on overflow
+       }
+       /// Read data from current position if there is enough data to fill the range (otherwise return false). Does not move read pointer.
+       template <typename OutIt> bool read(OutIt begin, OutIt end) {
+               unsigned r = m_read;
+               if (modulo(m_write - r) <= end - begin) return false;  // Not enough audio available
+               while (begin != end) *begin++ = m_buf[r++ % SIZE];  // Copy audio to output iterator
+               return true;
+       }
+       void pop(unsigned n) { m_read = modulo(m_read + n); } ///< Move reading pointer forward.
+       unsigned size() const { return modulo(m_write - m_read); }
+private:
+       static unsigned modulo(unsigned idx) { return (SIZE + idx) % SIZE; }  ///< Modulo operation with proper rounding (handles slightly "negative" idx as well)
+       float m_buf[SIZE];
+       volatile size_t m_read, m_write;  ///< The indices of the next read/write operations. read == write implies that buffer is empty.
+};
+
+/// analyzer class
+ /** class to analyze input audio and transform it into useable data
+ */
+class Analyzer {
+public:
+       /// fast fourier transform vector
+       typedef std::vector<std::complex<float> > fft_t;
+       /// list of tones
+       typedef std::list<Tone> tones_t;
+       /// constructor
+       Analyzer(double rate, std::string id, std::size_t step = 200);
+       /** Add input data to buffer. This is thread-safe (against other functions). **/
+       template <typename InIt> void input(InIt begin, InIt end) {
+               m_buf.insert(begin, end);
+               m_passthrough.insert(begin, end);
+       }
+       /** Call this to process all data input so far. **/
+       void process();
+       /** Get the raw FFT. **/
+       fft_t const& getFFT() const { return m_fft; }
+       /** Get the peak level in dB (negative value, 0.0 = clipping). **/
+       double getPeak() const { return 10.0 * log10(m_peak); }
+       /** Get a list of all tones detected. **/
+       tones_t const& getTones() const { return m_tones; }
+       /** Find a tone within the singing range; prefers strong tones around 200-400 Hz. **/
+       Tone const* findTone(double minfreq = 65.0, double maxfreq = 1000.0) const {
+               if (m_tones.empty()) { m_oldfreq = 0.0; return NULL; }
+               double db = std::max_element(m_tones.begin(), m_tones.end(), Tone::dbCompare)->db;
+               Tone const* best = NULL;
+               double bestscore = 0;
+               for (tones_t::const_iterator it = m_tones.begin(); it != m_tones.end(); ++it) {
+                       if (it->db < db - 20.0 || it->freq < minfreq || it->age < Tone::MINAGE) continue;
+                       if (it->freq > maxfreq) break;
+                       double score = it->db - std::max(180.0, std::abs(it->freq - 300.0)) / 10.0;
+                       if (m_oldfreq != 0.0 && std::fabs(it->freq/m_oldfreq - 1.0) < 0.05) score += 10.0;
+                       if (best && bestscore > score) break;
+                       best = &*it;
+                       bestscore = score;
+               }
+               m_oldfreq = (best ? best->freq : 0.0);
+               return best;
+       }
+       /** Give data away for mic pass-through */
+       void output(float* begin, float* end, double rate);
+       /** Returns the id (color name) of the mic */
+       std::string const& getId() const { return m_id; }
+
+private:
+       const std::size_t m_step;
+       RingBuffer<2 * FFT_N> m_buf;  // Twice the FFT size should give enough room for sliding window and for engine delays
+       RingBuffer<4096> m_passthrough;
+       double m_resampleFactor;
+       double m_resamplePos;
+       double m_rate;
+       std::string m_id;
+       std::vector<float> m_window;
+       fft_t m_fft;
+       std::vector<float> m_fftLastPhase;
+       double m_peak;
+       tones_t m_tones;
+       mutable double m_oldfreq;
+       bool calcFFT();
+       void calcTones();
+       void mergeWithOld(tones_t& tones) const;
+};
diff --git a/game/player.cc b/game/player.cc
new file mode 100644 (file)
index 0000000..69aff10
--- /dev/null
@@ -0,0 +1,85 @@
+#include "player.hh"
+#include "song.hh"
+#include "engine.hh" // just for Engine::TIMESTEP
+
+
+Player::Player(VocalTrack& vocal, Analyzer& analyzer, size_t frames):
+         m_vocal(vocal), m_analyzer(analyzer), m_pitch(frames, std::make_pair(getNaN(),
+         -getInf())), m_pos(), m_score(), m_noteScore(), m_lineScore(), m_maxLineScore(),
+         m_prevLineScore(-1), m_feedbackFader(0.0, 2.0), m_activitytimer(),
+         m_scoreIt(m_vocal.notes.begin())
+{
+       // Initialize note powers
+       for (Notes::const_iterator it = m_vocal.notes.begin(); it != m_vocal.notes.end(); ++it) it->power = 0.0f;
+       // Assign colors
+       m_color = MicrophoneColor::get(m_analyzer.getId());
+}
+
+void Player::update() {
+       if (m_pos == m_pitch.size()) return; // End of song already
+       double beginTime = Engine::TIMESTEP * m_pos;
+       // Get the currently sung tone and store it in player's pitch data (also control inactivity timer)
+       Tone const* t = m_analyzer.findTone();
+       if (t) {
+               m_activitytimer = 1000;
+               m_pitch[m_pos++] = std::make_pair(t->freq, t->stabledb);
+       } else {
+               if (m_activitytimer > 0) --m_activitytimer;
+               m_pitch[m_pos++] = std::make_pair(getNaN(), -getInf());
+       }
+       double endTime = Engine::TIMESTEP * m_pos;
+       // Iterate over all the notes that are considered for this timestep
+       while (m_scoreIt != m_vocal.notes.end()) {
+               if (endTime < m_scoreIt->begin) break;  // The note begins later than on this timestep
+               // If tone was detected, calculate score
+               m_scoreIt->power *= std::pow(0.05, m_scoreIt->clampDuration(beginTime, endTime));  // Fade glow
+               if (t) {
+                       double note = MusicalScale(m_vocal.scale).setFreq(t->freq).getNote();
+                       // Add score
+                       double score_addition = m_vocal.m_scoreFactor * m_scoreIt->score(note, beginTime, endTime);
+                       m_score += score_addition;
+                       m_noteScore += score_addition;
+                       m_lineScore += score_addition;
+                       // Add power if already on the note
+                       m_scoreIt->power = std::max(m_scoreIt->power, m_scoreIt->powerFactor(note));
+               }
+               // If a row of lyrics ends, calculate how well it went
+               if (m_scoreIt->type == Note::SLEEP) {
+                       calcRowRank();
+               } else {
+                       m_maxLineScore = 0; // Not in SLEEP note anymore, so reset maximum
+               }
+               if (endTime < m_scoreIt->end) break;  // The note continues past this timestep
+               // Check if we got a star
+               if ((m_scoreIt->type == Note::NORMAL || m_scoreIt->type == Note::SLIDE || m_scoreIt->type == Note::GOLDEN)
+                 && (m_noteScore / m_vocal.m_scoreFactor / m_scoreIt->maxScore() > 0.8)) {
+                       m_scoreIt->stars.push_back(m_color);
+               }
+               m_noteScore = 0; // Reset noteScore as we are moving on to the next one
+               m_scoreIt->power = 0.0; // Remove glow
+               ++m_scoreIt;
+       }
+       if (m_scoreIt == m_vocal.notes.end()) calcRowRank();
+       m_score = clamp(m_score, 0.0, 1.0);
+}
+
+void Player::calcRowRank() {
+       if (m_maxLineScore == 0) { // Has the maximum already been calculated for this SLEEP?
+               m_prevLineScore = m_lineScore;
+               // Calculate max score of the completed row
+               Notes::const_reverse_iterator maxScoreIt(m_scoreIt);
+               // NOTE: MacOSX needs the following cast to compile correctly
+               // it is related to the fact that OSX default compiler is 4.0.1 that is buggy when not casting
+               while ((maxScoreIt != static_cast<Notes::const_reverse_iterator>(m_vocal.notes.rend())) && (maxScoreIt->type != Note::SLEEP)) {
+                       m_maxLineScore += m_vocal.m_scoreFactor * maxScoreIt->maxScore();
+                       maxScoreIt++;
+               }
+               if (m_maxLineScore > 0) {
+                       m_prevLineScore /= m_maxLineScore;
+                       m_feedbackFader.setValue(1.0);
+               } else {
+                       m_prevLineScore = -1;
+               }
+               m_lineScore = 0;
+       }
+}
diff --git a/game/player.hh b/game/player.hh
new file mode 100644 (file)
index 0000000..8a6a41d
--- /dev/null
@@ -0,0 +1,94 @@
+#pragma once
+#include "color.hh"
+#include "fs.hh"
+#include "pitch.hh"
+#include "notes.hh"
+#include "animvalue.hh"
+
+#include <string>
+#include <vector>
+#include <utility>
+
+class Song;
+
+/// player class
+struct Player {
+       /// currently played vocal track
+       VocalTrack& m_vocal;
+       /// sound analyzer
+       Analyzer& m_analyzer;
+       /// player color for bars, waves, scores
+       Color m_color;
+       /// typedef for pitch
+       typedef std::vector<std::pair<double, double> > pitch_t;
+       /// player's pitch
+       pitch_t m_pitch;
+       /// current position in pitch vector (first unused spot)
+       size_t m_pos;
+       /// score for current song
+       double m_score;
+       /// score for current note
+       double m_noteScore;
+       /// score for current line
+       double m_lineScore;
+       /// maximum score for the previous line
+       double m_maxLineScore;
+       /// score for the previous line (normalized [0,1])
+       double m_prevLineScore;
+       /// fader for text feedback display
+       AnimValue m_feedbackFader;
+       /// activity timer
+       unsigned m_activitytimer;
+       /// score iterator
+       Notes::const_iterator m_scoreIt;
+       /// constructor
+       Player(VocalTrack& vocal, Analyzer& analyzer, size_t frames);
+       /// prepares analyzer
+       void prepare() { m_analyzer.process(); }
+       /// updates player stats
+       void update();
+       /// calculate how well last lyrics row went
+       void calcRowRank();
+       /// player activity singing
+       float activity() const { return m_activitytimer / 300.0; }
+       /// get player's score
+       int getScore() const {
+               return 10000.0 * m_score;
+       }
+       /**Operator for sorting by score.*/
+       bool operator < (Player const& other) const
+       {
+               return other.m_score < m_score;
+       }
+};
+
+/** Static Information of a player, not
+  dependent from current song.
+
+  Used for Players Management.
+  */
+struct PlayerItem {
+       int id; ///< unique identifier for this PlayerItem, Link to hiscore
+
+       std::string name; ///< name displayed and used for searching the player
+       fs::path picture; ///< the filename which was passed from xml (and is written back)
+       fs::path path; ///< a full path to a picture shown, generated from picture above
+/* Future ideas
+       std::string displayedName; /// artist name, short name, nick (can be changed)
+       std::map<std::string, int> scores; /// map between a Song and the highest score the Player achieved
+*/
+
+       /**For insertion in set.
+        Provides ordering and ensures id is unique.*/
+       bool operator< (PlayerItem const& pi) const
+       {
+               return id < pi.id;
+       }
+
+       /**Checks if a player has the same name.
+         Used to find a PlayerItem with the same name.*/
+       bool operator== (PlayerItem const& pi) const
+       {
+               return name == pi.name;
+       }
+};
diff --git a/game/players.cc b/game/players.cc
new file mode 100644 (file)
index 0000000..c419b1c
--- /dev/null
@@ -0,0 +1,138 @@
+#include "players.hh"
+
+#include "configuration.hh"
+#include "fs.hh"
+#include <boost/regex.hpp>
+#include <boost/lexical_cast.hpp>
+#include <libxml++/libxml++.h>
+
+Players::Players():
+       m_players(),
+       m_filtered(),
+       m_filter(),
+       math_cover(),
+       m_dirty(false)
+{}
+
+Players::~Players() {}
+
+void Players::load(xmlpp::NodeSet const& n) {
+       for (auto const& elem: n) {
+               xmlpp::Element& element = dynamic_cast<xmlpp::Element&>(*elem);
+               xmlpp::Attribute* a_name = element.get_attribute("name");
+               if (!a_name) throw PlayersException("Attribute name not found");
+               xmlpp::Attribute* a_id = element.get_attribute("id");
+               if (!a_id) throw PlayersException("Attribute id not found");
+               int id = -1;
+               try {id = boost::lexical_cast<int>(a_id->get_value());} catch (boost::bad_lexical_cast const&) { }
+               xmlpp::NodeSet n2 = element.find("picture");
+               std::string picture;
+               if (!n2.empty()) // optional picture element
+               {
+                       xmlpp::Element& element2 =dynamic_cast<xmlpp::Element&>(**n2.begin());
+                       xmlpp::TextNode* tn = element2.get_child_text();
+                       picture = tn->get_content();
+               }
+               addPlayer(a_name->get_value(), picture, id);
+       }
+       filter_internal();
+}
+
+void Players::save(xmlpp::Element *players) {
+       for (auto const& p: m_players) {
+               xmlpp::Element* player = players->add_child("player");
+               player->set_attribute("name", p.name);
+               player->set_attribute("id", boost::lexical_cast<std::string>(p.id));
+               if (p.picture != "")
+               {
+                       xmlpp::Element* picture = player->add_child("picture");
+                       picture->add_child_text(p.picture.string());
+               }
+       }
+}
+
+void Players::update() {
+       if (m_dirty) filter_internal();
+}
+
+int Players::lookup(std::string const& name) const {
+       for (auto const& p: m_players) {
+               if (p.name == name) return p.id;
+       }
+
+       return -1;
+}
+
+std::string Players::lookup(int id) const {
+       PlayerItem pi;
+       pi.id = id;
+       auto it = m_players.find(pi);
+       if (it == m_players.end()) return "Unkown Player";
+       else return it->name;
+}
+
+void Players::addPlayer (std::string const& name, std::string const& picture, int id) {
+       PlayerItem pi;
+       pi.id = id;
+       pi.name = name;
+       pi.picture = picture;
+       pi.path = "";
+
+
+       if (pi.id == -1) pi.id = assign_id_internal();
+
+       if (pi.picture != "") // no picture, so don't search path
+       {
+               try {
+                       pi.path =  findFile(fs::path("pictures") / pi.picture);
+               } catch (std::runtime_error const& e)
+               {
+                       std::cerr << e.what() << std::endl;
+               }
+       }
+
+       m_dirty = true;
+       std::pair<players_t::iterator, bool> ret = m_players.insert(pi);
+       if (!ret.second)
+       {
+               pi.id = assign_id_internal();
+               m_players.insert(pi); // now do the insert with the fresh id
+       }
+}
+
+void Players::setFilter(std::string const& val) {
+       if (m_filter == val) return;
+       m_filter = val;
+       filter_internal();
+}
+
+int Players::assign_id_internal() {
+       auto it = m_players.rbegin();
+       if (it != m_players.rend()) return it->id+1;
+       else return 1; // empty set
+}
+
+void Players::filter_internal() {
+       m_dirty = false;
+       PlayerItem selection = current();
+
+       try {
+               fplayers_t filtered;
+               for (auto const& p: m_players) {
+                       if (regex_search(p.name, boost::regex(m_filter, boost::regex_constants::icase))) filtered.push_back(p);
+               }
+               m_filtered.swap(filtered);
+       } catch (...) {
+               fplayers_t(m_players.begin(), m_players.end()).swap(m_filtered);  // Invalid regex => copy everything
+       }
+       math_cover.reset();
+
+       // Restore old selection
+       int pos = 0;
+       if (selection.name != "") {
+               auto it = std::find(m_filtered.begin(), m_filtered.end(), selection);
+               math_cover.setTarget(0, 0);
+               if (it != m_filtered.end()) pos = it - m_filtered.begin();
+       }
+       math_cover.setTarget(pos, size());
+}
diff --git a/game/players.hh b/game/players.hh
new file mode 100644 (file)
index 0000000..2dbb366
--- /dev/null
@@ -0,0 +1,106 @@
+#pragma once
+
+#include <set>
+#include <list>
+#include <vector>
+#include <string>
+#include <stdexcept>
+
+#include <boost/noncopyable.hpp>
+
+//#include "fs.hh"
+#include "player.hh"
+#include "animvalue.hh"
+
+namespace xmlpp { class Node; class Element; typedef std::vector<Node*>NodeSet; }
+
+/**Exception which will be thrown when loading or
+  saving Players fails.*/
+struct PlayersException: public std::runtime_error {
+       PlayersException (std::string const& msg) :
+               runtime_error(msg)
+       {}
+};
+
+/**A collection of all Players.
+
+ The current players plugged in a song can
+ be retrieved with Engine::getPlayers().
+
+ There are 3 different views united in that collection.
+ There is a full players list which are used by the
+ database, but also for the filtering.
+
+ The filtered list is used to show players in
+ the screen_players.
+ */
+class Players: boost::noncopyable {
+  private:
+       typedef std::set<PlayerItem> players_t;
+       typedef std::vector<PlayerItem> fplayers_t;
+
+  private:
+       players_t m_players;
+       fplayers_t m_filtered;
+
+       std::string m_filter;
+       AnimAcceleration math_cover;
+
+       bool m_dirty;
+
+  public:
+       Players();
+       ~Players();
+
+       void load(xmlpp::NodeSet const& n);
+       void save(xmlpp::Element *players);
+
+       void update();
+
+       /// lookup a playerid using the players name
+       int lookup(std::string const& name) const;
+
+       /** lookup a players name using the playerid.
+         @return the players name or "Unkown Player"
+         */
+       std::string lookup(int id) const;
+
+       /// add a player with a displayed name and an optional picture; if no id is given one will be assigned
+       void addPlayer (std::string const& name, std::string const& picture = "", int id = -1);
+
+       /// const array access
+       PlayerItem operator[](std::size_t pos) const {
+               if (pos < m_filtered.size()) return m_filtered[pos];
+               else return PlayerItem();
+       }
+       /// number of songs
+       size_t size() const { return m_filtered.size(); };
+       /// true if empty
+       int empty() const { return m_filtered.empty(); };
+       /// advances to next player
+       void advance(int diff) {
+               int size = m_filtered.size();
+               if (size == 0) return;  // Do nothing if no songs are available
+               int _current = size ? (int(math_cover.getTarget()) + diff) % size : 0;
+               if (_current < 0) _current += m_filtered.size();
+               math_cover.setTarget(_current,this->size());
+       }
+       /// get current id
+       int currentId() const { return math_cover.getTarget(); }
+       /// gets current position
+       double currentPosition() { return math_cover.getValue(); }
+       /// gets current velocity
+       double currentVelocity() const { return math_cover.getVelocity(); }
+       /// sets margins for animation
+       void setAnimMargins(double left, double right) { math_cover.setMargins(left, right); }
+       /// @return current PlayerItem (the copy is very cheap at the moment)
+       PlayerItem current() const {
+               if (math_cover.getTarget() < m_filtered.size()) return m_filtered[math_cover.getTarget()];
+               else return PlayerItem();
+       }
+       /// filters playerlist by regular expression
+       void setFilter(std::string const& regex);
+  private:
+       int assign_id_internal(); /// returns the next available id
+       void filter_internal();
+};
diff --git a/game/playlist.cc b/game/playlist.cc
new file mode 100644 (file)
index 0000000..0cdd96b
--- /dev/null
@@ -0,0 +1,50 @@
+#include "playlist.hh"
+#include "song.hh"
+#include <algorithm>
+
+void PlayList::addSong(boost::shared_ptr<Song> song) {
+       m_list.push_back(song);
+}
+
+boost::shared_ptr<Song> PlayList::getNext() {
+       if (isEmpty()) return boost::shared_ptr<Song>();
+       boost::shared_ptr<Song> nextSong;
+       nextSong = m_list[0];
+       m_list.erase(m_list.begin());
+       return nextSong;
+}
+
+PlayList::SongList& PlayList::getList() {
+       return m_list;
+}
+
+
+bool PlayList::isEmpty() {
+       return m_list.empty();
+}
+
+void PlayList::shuffle() {
+       std::random_shuffle(m_list.begin(), m_list.end());
+}
+
+void PlayList::clear() {
+       m_list.clear();
+}
+
+void PlayList::removeSong(int index) {
+       m_list.erase(m_list.begin() + index);
+}
+void PlayList::swap(int index1, int index2) {
+       boost::shared_ptr<Song> song1 = m_list[index1];
+       m_list[index1] = m_list[index2];
+       m_list[index2] = song1;
+}
+
+
+boost::shared_ptr<Song> PlayList::getSong(int index) {
+       if (isEmpty()) return boost::shared_ptr<Song>();
+       boost::shared_ptr<Song> nextSong;
+       nextSong = m_list[index];
+       m_list.erase(m_list.begin() + index);
+       return nextSong;
+}
diff --git a/game/playlist.hh b/game/playlist.hh
new file mode 100644 (file)
index 0000000..3c12f7e
--- /dev/null
@@ -0,0 +1,36 @@
+#pragma once
+
+#include <vector>
+#include "song.hh"
+#include <boost/shared_ptr.hpp>
+#include <sstream>
+
+class PlayList
+{
+public:
+    //needs function that returns the song properties in a list for display on screen
+
+       typedef std::vector< boost::shared_ptr<Song> > SongList;
+
+       /// Adds a new song to the queue
+       void addSong(boost::shared_ptr<Song> song);
+       /// Returns the next song and removes it from the queue
+       boost::shared_ptr<Song> getNext();
+       /// Returns all currently queued songs
+       SongList& getList();
+       /// Returns true if the queue is empty
+       bool isEmpty();
+       /// Randomizes the order of the playlist
+       void shuffle();
+       ///clears list
+       void clear();
+       ///removes a song
+       void removeSong(int index);
+       /// swaps two songs
+       void swap (int index1, int index2);
+       /// gets a specific song and removes it from the queue
+       boost::shared_ptr<Song> getSong(int index);
+private:
+       SongList m_list;
+};
+
diff --git a/game/portmidi.hh b/game/portmidi.hh
new file mode 100644 (file)
index 0000000..65e816a
--- /dev/null
@@ -0,0 +1,36 @@
+#pragma once
+
+#include <portmidi.h>
+#include <stdexcept>
+#include <iostream>
+
+namespace pm {
+       struct Initialize {
+               Initialize() { Pm_Initialize(); }
+               ~Initialize() { Pm_Terminate(); }
+       };
+       class Stream {
+       public:
+               operator PortMidiStream*() { return m_handle; }
+               Stream(Stream const&) = delete;
+       protected:
+               PortMidiStream* m_handle;
+               Stream(): m_handle() {}
+               void abort() { Pm_Abort(m_handle); m_handle = NULL; }
+               ~Stream() { if (m_handle) Pm_Close(m_handle); }
+       };
+
+       class Input: public Stream {
+       public:
+               Input(int devId) {
+                       // Errors must be handled here because otherwise PortMidi will just exit() the program...
+                       if (devId < 0 || devId >= Pm_CountDevices()) throw std::runtime_error("Invalid PortMidi device ID");
+                       PmDeviceInfo const* info = Pm_GetDeviceInfo(devId);
+                       if (!info->input) throw std::runtime_error(std::string(info->name) + ": The PortMidi device is an output device (input device needed)");
+                       if (info->opened) throw std::runtime_error(std::string(info->name) + ": The PortMidi device is already open");
+                       PmError err = Pm_OpenInput(&m_handle, devId, 0, 1024, 0, 0);
+                       if (err) throw std::runtime_error(std::string(info->name) + ": Pm_OpenInput failed");
+               }
+       };
+}
+
diff --git a/game/profiler.hh b/game/profiler.hh
new file mode 100644 (file)
index 0000000..08f46e2
--- /dev/null
@@ -0,0 +1,70 @@
+#pragma once
+
+#include "xtime.hh"
+#include <iomanip>
+#include <iostream>
+#include <map>
+#include <sstream>
+#include <string>
+#include <vector>
+
+struct ProfCP {
+       unsigned long samples;
+       double total;
+       double peak;
+       double avg;
+       ProfCP(): samples(), total(), peak(), avg() {}
+       void add(double t) {
+               ++samples;
+               total += t;
+               avg = total / samples;
+               if (peak < t) peak = t;
+       }
+};
+
+static inline std::ostream& operator<<(std::ostream& os, ProfCP const& cp) {
+       os << std::fixed << std::setprecision(1);
+       if (cp.samples == 0) return os << "no data";
+       if (cp.samples > 1) os << cp.samples << "x ";
+       os << cp.avg * 1000.0 << " ms";
+       if (cp.peak > 2.0 * cp.avg) os << " peak " << cp.peak * 1000.0 << " ms";
+       return os;
+}
+
+/// @short A simple performance profiling tool
+class Profiler {
+       typedef std::map<std::string, ProfCP> Checkpoints;
+       typedef std::pair<std::string, ProfCP> Pair;
+       Checkpoints m_checkpoints;
+       std::string m_name;
+       boost::xtime m_time;
+       static bool cmpFunc(Pair const& a, Pair const& b) { return a.second.total > b.second.total; }
+  public:
+       /// Start a profiler with the given name
+       Profiler(std::string const& name): m_name(name), m_time(now()) {}
+       ~Profiler() { dump(); }
+       /// Profiling checkpoint: record the duration since construction or previous checkpoint.
+       /// If no tag is specified, no recording is done.
+       void operator()(std::string const& tag = std::string()) {
+               boost::xtime n = now();
+               std::swap(n, m_time);
+               double t = m_time - n;
+               m_checkpoints[tag].add(t);
+       }
+       /// Dump current stats to log and reset
+       void dump(std::string const& level = "debug") {
+               if (m_checkpoints.empty()) return;
+               if (level.empty()) { m_checkpoints.clear(); return; }
+               std::vector<Pair> cps(m_checkpoints.begin(), m_checkpoints.end());
+               m_checkpoints.clear();
+               std::sort(cps.begin(), cps.end(), cmpFunc);
+               std::ostringstream oss;
+               oss << "profiler-" << m_name << "/" << level << ":";
+               for (std::vector<Pair>::const_iterator it = cps.begin(); it != cps.end(); ++it) {
+                       oss << "  " << it->first << " (" << it->second << ")";
+               }
+               std::clog << oss.str() << std::endl;
+       }
+};
+
+
diff --git a/game/progressbar.cc b/game/progressbar.cc
new file mode 100644 (file)
index 0000000..2597583
--- /dev/null
@@ -0,0 +1,45 @@
+#include "progressbar.hh"
+
+#include "util.hh"
+
+#include <stdexcept>
+
+ProgressBar::ProgressBar(fs::path const& bg, fs::path const& bar, Mode mode, float begin, float end, bool sliding):
+  m_bg(bg), m_bar(bar), m_mode(mode), m_begin(begin), m_end(end), m_sliding(sliding), dimensions(m_bg.dimensions)
+{}
+
+void ProgressBar::draw(float value) {
+       value = clamp(value);
+       float scale = 1.0f - m_begin - m_end;
+       float off = (1.0f - value) * scale;  // Offset for sliding mode
+       m_bg.draw(dimensions);
+       switch (m_mode) {
+         case HORIZONTAL:
+               {
+                       Dimensions dim = dimensions;
+                       TexCoords tex;
+                       if (m_sliding) { dim.move(-off * dim.w(), 0.0f); tex.x1 = m_begin + off; }
+                       else { tex.x1 = m_begin; tex.x2 = tex.x1 + value * scale; }
+                       m_bar.drawCropped(dim, tex);
+               }
+               break;
+         case VERTICAL:
+               {
+                       Dimensions dim = dimensions;
+                       TexCoords tex;
+                       if (m_sliding) { dim.move(0.0f, off * dim.h()); tex.y2 = 1.0f - m_begin - off; }
+                       else { tex.y2 = 1.0f - m_begin; tex.y1 = tex.y2 - value * scale; }
+                       m_bar.drawCropped(dim, tex);
+               }
+               break;
+         case CIRCULAR:
+               {
+                       UseTexture texblock(m_bar);
+                       throw std::logic_error("ProgressBar::draw(): CIRCULAR not implemented yet");  // TODO: Implement
+               }
+               break;
+         default: throw std::logic_error("ProgressBar::draw(): unknown m_mode value");
+       }
+       // Reset dimensions due to async image loading
+       dimensions = m_bg.dimensions;
+}
diff --git a/game/progressbar.hh b/game/progressbar.hh
new file mode 100644 (file)
index 0000000..5ccfa9f
--- /dev/null
@@ -0,0 +1,31 @@
+#pragma once
+
+#include "surface.hh"
+
+/// simple progressbar class
+class ProgressBar {
+  public:
+       /// type of progressbar
+       enum Mode { HORIZONTAL, VERTICAL, CIRCULAR };
+       /**
+       * Construct a new progress bar.
+       * @param bg filename of background image
+       * @param bar filename of the bar image
+       * @param mode specifies bar appearance
+       * @param begin margin before the bar begins [0, 1]
+       * @param end margin after the bar ends [0, 1]
+       * @param sliding makes the bar move; the texture is anchored at bar end rather than at bar beginning
+       **/
+       ProgressBar(fs::path const& bg, fs::path const& bar, Mode mode = HORIZONTAL, float begin = 0.0f, float end = 0.0f, bool sliding = false);
+       /** Draw a progress bar with the given percentage [0, 1] **/
+       void draw(float value);
+  private:
+       Texture m_bg, m_bar;
+       Mode m_mode;
+       float m_begin, m_end;
+       bool m_sliding;
+  public:
+       /// dimensions of progressbar
+       Dimensions dimensions;
+};
+
diff --git a/game/screen.hh b/game/screen.hh
new file mode 100644 (file)
index 0000000..9749cfd
--- /dev/null
@@ -0,0 +1,121 @@
+#pragma once
+
+#include "controllers.hh"
+#include "singleton.hh"
+#include "animvalue.hh"
+#include "opengl_text.hh"
+#include "video_driver.hh"
+#include "dialog.hh"
+#include "playlist.hh"
+#include "fbo.hh"
+#include <boost/ptr_container/ptr_map.hpp>
+#include <boost/scoped_ptr.hpp>
+#include <SDL2/SDL.h>
+#include <string>
+
+/// Abstract Class for screens
+class Screen {
+  public:
+       /// counstructor
+       Screen(std::string const& name): m_name(name) {}
+       virtual ~Screen() {}
+       /// Event handler for navigation events
+       virtual void manageEvent(input::NavEvent const& event) = 0;
+       /// Event handler for SDL events
+       virtual void manageEvent(SDL_Event) {}
+       /// prepare screen for drawing
+       virtual void prepare() {}
+       /// draws screen
+       virtual void draw() = 0;
+       /// enters screen
+       virtual void enter() = 0;
+       /// exits screen
+       virtual void exit() = 0;
+       /// reloads OpenGL textures but avoids restarting music etc.
+       virtual void reloadGL() { exit(); enter(); }
+       /// returns screen name
+       std::string getName() const { return m_name; }
+  private:
+       std::string m_name;
+};
+
+/// Manager for screens and Playlist
+/** manages screens
+ * @see Singleton
+ */
+class Game: public Singleton <Game> {
+  public:
+       /// constructor
+    Game(Window& window);
+    ~Game() { if (currentScreen) currentScreen->exit(); }
+       /// Adds a screen to the manager
+       void addScreen(Screen* s) { std::string tmp = s->getName(); screens.insert(tmp, s); }
+       /// Switches active screen
+       void activateScreen(std::string const& name);
+       /// Does actual switching of screens (if necessary)
+       void updateScreen();
+       /// Prepare (slow loading operations) of the current screen for rendering
+       void prepareScreen();
+       /// Draws the current screen and possible transition effects
+       void drawScreen();
+       /// Reload OpenGL resources (after fullscreen toggle etc)
+       void reloadGL() { if (currentScreen) currentScreen->reloadGL(); }
+       /// Returns pointer to current Screen
+       Screen* getCurrentScreen() { return currentScreen; }
+       /// Returns pointer to Screen for given name
+       Screen* getScreen(std::string const& name);
+       /// Returns a reference to the window
+       Window& window() { return m_window; }
+
+       /// Draw a loading progress indication
+       void loading(std::string const& message, float progress);
+       /// Internal rendering function for loading indicator
+       void drawLoading();
+       /// Draw an error notification and quit
+       void fatalError(std::string const& message);
+       /// Set a message to flash in current screen
+       void flashMessage(std::string const& message, float fadeIn=0.5f, float hold=1.5f, float fadeOut=1.0f);
+       /// Create a new dialog message
+       void dialog(std::string const& text);
+       /// Close dialog and return true if it was opened in the first place
+       bool closeDialog();
+       /// Returns true if dialog is open
+       bool isDialogOpen() { return !!m_dialog; }
+       /// Draw dialogs & flash messages, called automatically by drawScreen
+       void drawNotifications();
+
+       /// Sets finished to true
+       void finished() { m_finished = true; }
+       /// Returns finished state
+       bool isFinished() { return m_finished; }
+
+       void showLogo(bool show = true) { m_logoAnim.setTarget(show ? 1.0 : 0.0); }
+       void drawLogo();
+
+private:
+       Window& m_window;
+public:
+       input::Controllers controllers;
+    PlayList& getCurrentPlayList() { return currentPlaylist; }
+private:
+       bool m_finished;
+       typedef boost::ptr_map<std::string, Screen> screenmap_t;
+       screenmap_t screens;
+       Screen* newScreen;
+       Screen* currentScreen;
+    PlayList currentPlaylist;
+       // Flash messages members
+       float m_timeToFadeIn;
+       float m_timeToFadeOut;
+       float m_timeToShow;
+       std::string m_message;
+       AnimValue m_messagePopup;
+       SvgTxtTheme m_textMessage;
+       float m_loadingProgress;
+       Surface m_logo;
+       AnimValue m_logoAnim;
+       AnimValue m_dialogTimeOut;
+       // Dialog members
+       boost::scoped_ptr<Dialog> m_dialog;
+};
+
diff --git a/game/screen_audiodevices.cc b/game/screen_audiodevices.cc
new file mode 100644 (file)
index 0000000..bb4bc5f
--- /dev/null
@@ -0,0 +1,198 @@
+#include "screen_audiodevices.hh"
+
+#include "configuration.hh"
+#include "controllers.hh"
+#include "theme.hh"
+#include "audio.hh"
+#include "i18n.hh"
+#include <boost/thread.hpp>
+#include <boost/bind.hpp>
+
+namespace {
+       static const int unassigned_id = -1;  // mic.dev value for unassigned
+       static const float yoff = 0.18; // Offset from center where to place top row
+       static const float xoff = 0.45; // Offset from middle where to place first column
+
+       bool countRow(std::string needle, std::string const& haystack, int& count) {
+               if (haystack.find(needle) != std::string::npos) ++count;
+               if (count > 1) return false;
+               return true;
+       }
+}
+
+ScreenAudioDevices::ScreenAudioDevices(std::string const& name, Audio& audio): Screen(name), m_audio(audio) {
+       m_selector.reset(new Surface(findFile("device_selector.svg")));
+       m_mic_icon.reset(new Surface(findFile("sing_pbox.svg")));
+       m_pdev_icon.reset(new Surface(findFile("icon_pdev.svg")));
+}
+
+void ScreenAudioDevices::enter() {
+       m_theme.reset(new ThemeAudioDevices());
+       portaudio::AudioDevices ads;
+       m_devs = ads.devices;
+       // FIXME: Something more elegant, like a warning box
+       if (m_devs.empty()) throw std::runtime_error("No audio devices found!");
+       m_selected_column = 0;
+       // Detect if there is existing advanced configuration and warn that this will override
+       if (!config["audio/devices"].isDefault()) {
+               ConfigItem::StringList devconf = config["audio/devices"].sl();
+               std::map<std::string, int> countmap;
+               bool ok = true;
+               for (ConfigItem::StringList::const_iterator it = devconf.begin(); it != devconf.end(); ++it) {
+                       if (!countRow("blue", *it, countmap["blue"])) { ok = false; break; }
+                       if (!countRow("red", *it, countmap["red"])) { ok = false; break; }
+                       if (!countRow("green", *it, countmap["green"])) { ok = false; break; }
+                       if (!countRow("orange", *it, countmap["orange"])) { ok = false; break; }
+                       if (!countRow("out=", *it, countmap["out="])) { ok = false; break; }
+               }
+               if (!ok)
+                       Game::getSingletonPtr()->dialog(
+                               _("It seems you have some manual configurations\nincompatible with this user interface.\nSaving these settings will override\nall existing audio device configuration.\nYour other options changes will be saved too."));
+       }
+       // Populate the mics vector and check open devices
+       load();
+       // TODO: Scrolling would be nicer than just zooming out infinitely
+       float s = std::min(xoff / m_channels.size() / 1.2, yoff*2 / m_devs.size() / 1.1);
+       m_mic_icon->dimensions.fixedWidth(s);
+       m_pdev_icon->dimensions.fixedWidth(s);
+}
+
+void ScreenAudioDevices::exit() { m_theme.reset(); }
+
+void ScreenAudioDevices::manageEvent(input::NavEvent const& event) {
+       Game* gm = Game::getSingletonPtr();
+       input::NavButton nav = event.button;
+       auto& chpos = m_channels[m_selected_column].pos;
+       const unsigned posN = m_devs.size() + 1;
+       if (nav == input::NAV_CANCEL) gm->activateScreen("Intro");
+       else if (nav == input::NAV_PAUSE) m_audio.togglePause();
+       else if (m_devs.empty()) return; // The rest work if there are any devices
+       else if (nav == input::NAV_START) { if (save()) gm->activateScreen("Intro"); }
+       else if (nav == input::NAV_LEFT && m_selected_column > 0) --m_selected_column;
+       else if (nav == input::NAV_RIGHT && m_selected_column < m_channels.size()-1) ++m_selected_column;
+       else if (nav == input::NAV_UP) chpos = (chpos + posN) % posN - 1;
+       else if (nav == input::NAV_DOWN) chpos = (chpos + posN + 2) % posN - 1;
+}
+
+void ScreenAudioDevices::manageEvent(SDL_Event event) {
+       if (event.type == SDL_KEYDOWN) {
+               int key = event.key.keysym.sym;
+               uint16_t modifier = event.key.keysym.mod;
+               if (m_devs.empty()) return; // The rest work if there are any config options
+               // Reset to defaults
+               else if (key == SDLK_r && modifier & KMOD_CTRL) {
+                       config["audio/devices"].reset(modifier & KMOD_ALT);
+                       save(true); // Save to disk, reload audio & reload UI to keep stuff consistent
+               }
+       }
+}
+
+void ScreenAudioDevices::draw() {
+       m_theme->bg.draw();
+       if (m_devs.empty()) return;
+       // Calculate spacing between columns/rows
+       const float xstep = (xoff - 0.5 + xoff) / m_channels.size();
+       const float ystep = yoff*2 / m_devs.size();
+       // Device text & bg
+       m_theme->device_bg.dimensions.stretch(std::abs(xoff*2), m_mic_icon->dimensions.h()*0.9).middle();
+       m_selector->dimensions.stretch(m_mic_icon->dimensions.w() * 1.75, m_mic_icon->dimensions.h() * 1.75);
+       for (size_t i = 0; i <= m_devs.size(); ++i) {
+               const float y = -yoff + i*ystep;
+               float alpha = 1.0f;
+               // "Grey out" devices that doesn't fit the selection
+               if (m_channels[m_selected_column].name == "OUT" && !m_devs[i].out) alpha = 0.5f;
+               else if (m_channels[m_selected_column].name != "OUT" && !m_devs[i].in) alpha = 0.5f;
+               m_theme->device_bg.dimensions.center(y);
+               m_theme->device_bg.draw();
+               ColorTrans c(Color::alpha(alpha));
+               m_theme->device.dimensions.middle(-xstep*0.5).center(y);
+               m_theme->device.draw(i < m_devs.size() ? m_devs[i].desc() : _("- Unassigned -"));
+       }
+       // Icons
+       for (size_t i = 0; i < m_channels.size(); ++i) {
+               Surface& srf = (i < m_channels.size()-1) ? *m_mic_icon : *m_pdev_icon;
+               {
+                       ColorTrans c(MicrophoneColor::get(m_channels[i].name));
+                       int pos = m_channels[i].pos;
+                       if (pos == unassigned_id) pos = m_devs.size();  // Transform -1 to the bottom of the list
+                       srf.dimensions.middle(-xoff + xstep*0.5 + i*xstep).center(-yoff+pos*ystep);
+                       srf.draw();
+               }
+               // Selection indicator
+               if (m_selected_column == i)
+                       m_selector->dimensions.middle(srf.dimensions.xc()).center(srf.dimensions.yc());
+       }
+       m_selector->draw(); // Position already set in the loop
+       // Key help
+       m_theme->comment_bg.dimensions.stretch(1.0, 0.025).middle().screenBottom(-0.054);
+       m_theme->comment_bg.draw();
+       m_theme->comment.dimensions.left(-0.48).screenBottom(-0.067);
+       m_theme->comment.draw(_("Use arrow keys to configure. Hit Enter/Start to save and test or Esc/Select to cancel. Ctrl + R to reset defaults"));
+       // Additional info
+       m_theme->comment_bg.dimensions.middle().screenBottom(-0.01);
+       m_theme->comment_bg.draw();
+       m_theme->comment.dimensions.left(-0.48).screenBottom(-0.023);
+       m_theme->comment.draw(_("For advanced device configuration, use command line parameter --audio (use --audiohelp for details)."));
+}
+
+void ScreenAudioDevices::load() {
+       std::string names[] = { "blue", "red", "green", "orange", "OUT" };
+       m_channels.assign(std::begin(names), std::end(names));
+       // Get the currently assigned devices for each channel (FIXME: this is a really stupid algorithm)
+       for (auto const& d: m_audio.devices()) {
+               for (auto& c: m_channels) {
+                       if (!d.isChannel(c.name)) continue;
+                       for (size_t i = 0; i < m_devs.size(); ++i) {
+                               if (unsigned(m_devs[i].idx) == d.dev) c.pos = i;
+                       }
+               }
+       }
+}
+
+bool ScreenAudioDevices::save(bool skip_ui_config) {
+       if (!skip_ui_config) {
+               ConfigItem::StringList devconf;
+               // Loop through the devices and if there is mics/pdev assigned, form a config line
+               for (auto const& d: m_devs) {  // PortAudio devices
+                       std::string mics = "", pdev = "";
+                       for (auto const& c: m_channels) {  // blue, red, ..., OUT
+                               if (c.pos == unassigned_id || m_devs[c.pos].idx != d.idx) continue;
+                               if (c.name == "OUT") pdev = "out=2"; // Pdev, only stereo supported
+                               else { // Mic
+                                       if (!mics.empty()) mics += ","; // Add separator if needed
+                                       mics += c.name; // Append mic color
+                               }
+                       }
+                       if (mics.empty() && pdev.empty()) continue; // Continue looping if device is not used
+                       std::string dev = "dev=\"" + d.flex + "\""; // Use flexible name for more robustness
+                       // Use half duplex I/O even if the same device is used for capture and playback (works better)
+                       if (!mics.empty()) devconf.push_back(dev + " mics=" + mics);
+                       if (!pdev.empty()) devconf.push_back(dev + " " + pdev);
+               }
+               config["audio/devices"].sl() = devconf;
+       }
+       writeConfig(); // Save the new config
+       // Give audio a little time to shutdown but then just quit
+       boost::thread audiokiller(boost::bind(&Audio::close, boost::ref(m_audio)));
+       if (!audiokiller.timed_join(boost::posix_time::milliseconds(2500)))
+               Game::getSingletonPtr()->fatalError("Audio hung for some reason.\nPlease restart Performous.");
+       m_audio.restart(); // Reload audio to take the new settings into use
+       m_audio.playMusic(findFile("menu.ogg"), true); // Start music again
+       // Check that all went well
+       bool ret = verify();
+       if (!ret) Game::getSingletonPtr()->dialog(_("Some devices failed to open!"));
+       // Load the new config back for UI
+       load();
+       return ret;
+}
+
+bool ScreenAudioDevices::verify() {
+       for (auto const& c: m_channels) {
+               if (c.pos == unassigned_id) continue;  // No checking needed of unassigned channels
+               // Find the device
+               for (auto const& d: m_audio.devices()) if (d.isChannel(c.name)) goto found;
+               return false;
+               found:;
+       }
+       return true;
+}
diff --git a/game/screen_audiodevices.hh b/game/screen_audiodevices.hh
new file mode 100644 (file)
index 0000000..6b6dfeb
--- /dev/null
@@ -0,0 +1,42 @@
+#pragma once
+
+#include <map>
+#include <boost/scoped_ptr.hpp>
+#include "screen.hh"
+#include "glutil.hh"
+#include "libda/portaudio.hpp"
+
+class Audio;
+class ThemeAudioDevices;
+
+/// options dialogue
+class ScreenAudioDevices: public Screen {
+  public:
+       /// constructor
+       ScreenAudioDevices(std::string const& name, Audio& m_audio);
+       void enter();
+       void exit();
+       void manageEvent(SDL_Event event);
+       void manageEvent(input::NavEvent const& event);
+       void draw();
+
+  private:
+       struct Channel {
+               Channel(std::string const& name): name(name), pos(-1) {}
+               std::string name;
+               int pos;
+       };
+       void load(); ///< Check what devices are open
+       bool save(bool skip_ui_config = false); ///< Save the config to disk xml and then reload
+       bool verify(); ///< Check that all were opened after audio reset
+
+       Audio& m_audio;
+       boost::scoped_ptr<ThemeAudioDevices> m_theme;
+       unsigned int m_selected_column;
+       portaudio::DeviceInfos m_devs;
+       std::vector<Channel> m_channels;
+       boost::scoped_ptr<Surface> m_selector;
+       boost::scoped_ptr<Surface> m_mic_icon;
+       boost::scoped_ptr<Surface> m_pdev_icon;
+};
+
diff --git a/game/screen_intro.cc b/game/screen_intro.cc
new file mode 100644 (file)
index 0000000..d8f9157
--- /dev/null
@@ -0,0 +1,185 @@
+#include "screen_intro.hh"
+
+#include "fs.hh"
+#include "glmath.hh"
+#include "audio.hh"
+#include "i18n.hh"
+#include "controllers.hh"
+#include "theme.hh"
+#include "menu.hh"
+#include "xtime.hh"
+
+
+ScreenIntro::ScreenIntro(std::string const& name, Audio& audio): Screen(name), m_audio(audio), m_first(true) {
+}
+
+void ScreenIntro::enter() {
+       Game::getSingletonPtr()->showLogo();
+       m_audio.playMusic(findFile("menu.ogg"), true);
+       m_selAnim = AnimValue(0.0, 10.0);
+       m_submenuAnim = AnimValue(0.0, 3.0);
+       populateMenu();
+       if( m_first ) {
+               std::string msg;
+               if (!m_audio.hasPlayback()) msg = _("No playback devices could be used.\n");
+               if (!msg.empty()) Game::getSingletonPtr()->dialog(msg + _("\nPlease configure some before playing."));
+               m_first = false;
+       }
+       reloadGL();
+}
+
+void ScreenIntro::reloadGL() {
+       theme.reset(new ThemeIntro());
+}
+
+void ScreenIntro::exit() {
+       m_menu.clear();
+       theme.reset();
+}
+
+void ScreenIntro::manageEvent(input::NavEvent const& event) {
+       input::NavButton nav = event.button;
+       if (nav == input::NAV_CANCEL) {
+               if (m_menu.getSubmenuLevel() == 0) m_menu.moveToLast();  // Move cursor to quit in main menu
+               else m_menu.closeSubmenu(); // One menu level up
+       }
+       else if (nav == input::NAV_DOWN || nav == input::NAV_MOREDOWN) m_menu.move(1);
+       else if (nav == input::NAV_UP || nav == input::NAV_MOREUP) m_menu.move(-1);
+       else if (nav == input::NAV_RIGHT && m_menu.getSubmenuLevel() >= 2) m_menu.action(1); // Config menu
+       else if (nav == input::NAV_LEFT && m_menu.getSubmenuLevel() >= 2) m_menu.action(-1); // Config menu
+       else if (nav == input::NAV_RIGHT && m_menu.getSubmenuLevel() < 2) m_menu.move(1); // Instrument nav hack
+       else if (nav == input::NAV_LEFT && m_menu.getSubmenuLevel() < 2) m_menu.move(-1); // Instrument nav hack
+       else if (nav == input::NAV_START) m_menu.action();
+       else if (nav == input::NAV_PAUSE) m_audio.togglePause();
+       // Animation targets
+       m_selAnim.setTarget(m_menu.curIndex());
+       m_submenuAnim.setTarget(m_menu.getSubmenuLevel());
+}
+
+void ScreenIntro::manageEvent(SDL_Event event) {
+       if (event.type == SDL_KEYDOWN && m_menu.getSubmenuLevel() > 0) {
+               // These are only available in config menu
+               int key = event.key.keysym.sym;
+               uint16_t modifier = event.key.keysym.mod;
+               if (key == SDLK_r && modifier & KMOD_CTRL && m_menu.current().value) {
+                       m_menu.current().value->reset(modifier & KMOD_ALT);
+               } else if (key == SDLK_s && modifier & KMOD_CTRL) {
+                       writeConfig(modifier & KMOD_ALT);
+                       Game::getSingletonPtr()->flashMessage((modifier & KMOD_ALT)
+                               ? _("Settings saved as system defaults.") : _("Settings saved."));
+               }
+       }
+}
+
+void ScreenIntro::draw_menu_options() {
+       // Variables used for positioning and other stuff
+       double wcounter = 0;
+       const size_t showopts = 4; // Show at most 4 options simultaneously
+       const float x = -0.35;
+       const float start_y = -0.1;
+       const float sel_margin = 0.03;
+       const MenuOptions opts = m_menu.getOptions();
+       double submenuanim = 1.0 - std::min(1.0, std::abs(m_submenuAnim.get()-m_menu.getSubmenuLevel()));
+       theme->back_h.dimensions.fixedHeight(0.065f);
+       theme->back_h.dimensions.stretch(m_menu.dimensions.w(), theme->back_h.dimensions.h());
+       // Determine from which item to start
+       int start_i = std::min((int)m_menu.curIndex() - 1, (int)opts.size() - (int)showopts
+               + (m_menu.getSubmenuLevel() == 2 ? 1 : 0)); // Hack to counter side-effects from displaying the value inside the menu
+       if (start_i < 0 || opts.size() == showopts) start_i = 0;
+
+       // Loop the currently visible options
+       for (size_t i = start_i, ii = 0; ii < showopts && i < opts.size(); ++i, ++ii) {
+               MenuOption const& opt = opts[i];
+               ColorTrans c(Color::alpha(submenuanim));
+
+               // Selection
+               if (i == m_menu.curIndex()) {
+                       // Animate selection higlight moving
+                       double selanim = m_selAnim.get() - start_i;
+                       if (selanim < 0) selanim = 0;
+                       theme->back_h.dimensions.left(x - sel_margin).center(start_y + selanim*0.08);
+                       theme->back_h.draw();
+                       // Draw the text, dim if option not available
+                       {
+                               ColorTrans c(Color::alpha(opt.isActive() ? 1.0 : 0.5));
+                               theme->option_selected.dimensions.left(x).center(start_y + ii*0.08);
+                               theme->option_selected.draw(opt.getName());
+                       }
+                       wcounter = std::max(wcounter, theme->option_selected.w() + 2 * sel_margin); // Calculate the widest entry
+                       // If this is a config item, show the value below
+                       if (opt.type == MenuOption::CHANGE_VALUE) {
+                               ++ii; // Use a slot for the value
+                               theme->option_selected.dimensions.left(x + sel_margin).center(-0.1 + (selanim+1)*0.08);
+                               theme->option_selected.draw("<  " + opt.value->getValue() + "  >");
+                       }
+
+               // Regular option (not selected)
+               } else {
+                       std::string title = opt.getName();
+                       SvgTxtTheme& txt = getTextObject(title);
+                       ColorTrans c(Color::alpha(opt.isActive() ? 1.0 : 0.5));
+                       txt.dimensions.left(x).center(start_y + ii*0.08);
+                       txt.draw(title);
+                       wcounter = std::max(wcounter, txt.w() + 2 * sel_margin); // Calculate the widest entry
+               }
+       }
+       m_menu.dimensions.stretch(wcounter, 1);
+}
+
+void ScreenIntro::draw() {
+       glutil::GLErrorChecker glerror("ScreenIntro::draw()");
+       {
+               float anim = SDL_GetTicks() % 20000 / 20000.0;
+               ColorTrans c(glmath::rotate(2.0 * M_PI * anim, glmath::vec3(1.0, 1.0, 1.0)));
+               theme->bg.draw();
+       }
+       glerror.check("bg");
+       if (m_menu.current().image) m_menu.current().image->draw();
+       // Comment
+       theme->comment_bg.dimensions.center().screenBottom(-0.01);
+       theme->comment_bg.draw();
+       theme->comment.dimensions.left(-0.48).screenBottom(-0.028);
+       theme->comment.draw(m_menu.current().getComment());
+       // Key help for config
+       if (m_menu.getSubmenuLevel() > 0) {
+               theme->short_comment_bg.dimensions.stretch(theme->short_comment.w() + 0.08, 0.025);
+               theme->short_comment_bg.dimensions.left(-0.54).screenBottom(-0.054);
+               theme->short_comment_bg.draw();
+               theme->short_comment.dimensions.left(-0.48).screenBottom(-0.067);
+               theme->short_comment.draw(_("Ctrl + S to save, Ctrl + R to reset defaults"));
+       }
+       // Menu
+       draw_menu_options();
+}
+
+SvgTxtTheme& ScreenIntro::getTextObject(std::string const& txt) {
+       if (theme->options.contains(txt)) return theme->options[txt];
+       return *theme->options.insert(txt, new SvgTxtTheme(findFile("mainmenu_option.svg"), config["graphic/text_lod"].f()))->second;
+}
+
+void ScreenIntro::populateMenu() {
+       MenuImage imgSing(new Surface(findFile("intro_sing.svg")));
+       MenuImage imgPractice(new Surface(findFile("intro_practice.svg")));
+       MenuImage imgConfig(new Surface(findFile("intro_configure.svg")));
+       MenuImage imgQuit(new Surface(findFile("intro_quit.svg")));
+       m_menu.clear();
+       m_menu.add(MenuOption(_("Perform"), _("Start performing!"), imgSing).screen("Songs"));
+       m_menu.add(MenuOption(_("Practice"), _("Check your skills or test the microphones"), imgPractice).screen("Practice"));
+       // Configure menu + submenu options
+       MenuOptions configmain;
+       for (MenuEntry const& submenu: configMenu) {
+               if (!submenu.items.empty()) {
+                       MenuOptions opts;
+                       // Process items that belong to that submenu
+                       for (std::string const& item: submenu.items) {
+                               ConfigItem& c = config[item];
+                               opts.push_back(MenuOption(_(c.getShortDesc().c_str()), _(c.getLongDesc().c_str())).changer(c));
+                       }
+                       configmain.push_back(MenuOption(_(submenu.shortDesc.c_str()), _(submenu.longDesc.c_str()), imgConfig).submenu(opts));
+               } else {
+                       configmain.push_back(MenuOption(_(submenu.shortDesc.c_str()), _(submenu.longDesc.c_str()), imgConfig).screen(submenu.name));
+               }
+       }
+       m_menu.add(MenuOption(_("Configure"), _("Configure audio and game options"), imgConfig).submenu(configmain));
+       m_menu.add(MenuOption(_("Quit"), _("Leave the game"), imgQuit).screen(""));
+}
diff --git a/game/screen_intro.hh b/game/screen_intro.hh
new file mode 100644 (file)
index 0000000..3d7fb61
--- /dev/null
@@ -0,0 +1,39 @@
+#pragma once
+
+#include "screen.hh"
+#include "menu.hh"
+#include "animvalue.hh"
+
+#include <boost/scoped_ptr.hpp>
+
+class Audio;
+class ThemeIntro;
+class SvgTxtTheme;
+class MenuOption;
+
+/// intro screen
+class ScreenIntro : public Screen {
+  public:
+       /// constructor
+       ScreenIntro(std::string const& name, Audio& audio);
+       void enter();
+       void exit();
+       void reloadGL();
+       void manageEvent(SDL_Event event);
+       void manageEvent(input::NavEvent const& event);
+       void draw();
+
+       /// draw menu
+       void draw_menu_options();
+
+  private:
+       void populateMenu();
+       SvgTxtTheme& getTextObject(std::string const& txt);
+
+       Audio& m_audio;
+       boost::scoped_ptr<ThemeIntro> theme;
+       Menu m_menu;
+       bool m_first;
+       AnimValue m_selAnim;
+       AnimValue m_submenuAnim;
+};
diff --git a/game/screen_paths.cc b/game/screen_paths.cc
new file mode 100644 (file)
index 0000000..c040ce2
--- /dev/null
@@ -0,0 +1,78 @@
+#include "screen_paths.hh"
+
+#include "configuration.hh"
+#include "controllers.hh"
+#include "theme.hh"
+#include "audio.hh"
+#include "i18n.hh"
+#include <boost/thread.hpp>
+#include <boost/bind.hpp>
+
+namespace {
+       const float yoff = 0.18; // Offset from center where to place top row
+       const float xoff = 0.45; // Offset from middle where to place first column
+}
+
+ScreenPaths::ScreenPaths(std::string const& name, Audio& audio): Screen(name), m_audio(audio) {}
+
+void ScreenPaths::enter() {
+       m_theme.reset(new ThemeAudioDevices());
+       m_txtinp.text.clear();
+
+       // FIXME: Temp error message
+       Game::getSingletonPtr()->dialog(
+               _("This tool is not yet available.\n"
+                 "Configure paths by adding them\n"
+                 "as command line parameters and\n"
+                 "then save them in configuration menu."));
+}
+
+void ScreenPaths::exit() { m_theme.reset(); }
+
+void ScreenPaths::manageEvent(SDL_Event event) {
+       if (event.type == SDL_KEYDOWN) {
+               return; // FIXME: Remove
+               SDL_Keycode key = event.key.keysym.sym;
+               uint16_t modifier = event.key.keysym.mod;
+               if (m_txtinp.process(event.key.keysym)) /* Nop */ ;
+               // Reset to defaults
+               else if (key == SDLK_r && modifier & KMOD_CTRL) {
+                       config["paths/songs"].reset(modifier & KMOD_ALT);
+                       config["paths/system"].reset(modifier & KMOD_ALT);
+                       // TODO: Save
+               }
+       }
+}
+
+void ScreenPaths::manageEvent(input::NavEvent const& ev) {
+       Game* gm = Game::getSingletonPtr();
+       if (ev.button == input::NAV_CANCEL) {
+               if (m_txtinp.text.empty()) gm->activateScreen("Intro");
+               else m_txtinp.text.clear();
+       }
+       else if (ev.button == input::NAV_PAUSE) m_audio.togglePause();
+       else if (ev.button == input::NAV_START) { 
+               // TODO: Save config
+               gm->activateScreen("Intro");
+       }
+}
+
+void ScreenPaths::draw() {
+       if (!Game::getSingletonPtr()->isDialogOpen())
+               Game::getSingletonPtr()->activateScreen("Intro"); // FIXME: Remove
+
+       m_theme->bg.draw();
+
+       // Key help
+       m_theme->comment_bg.dimensions.stretch(1.0, 0.025).middle().screenBottom(-0.054);
+       m_theme->comment_bg.draw();
+       m_theme->comment.dimensions.left(-0.48).screenBottom(-0.067);
+       m_theme->comment.draw(_("Press any key to exit."));
+       // Additional info
+       #ifdef _WIN32
+       m_theme->comment_bg.dimensions.middle().screenBottom(-0.01);
+       m_theme->comment_bg.draw();
+       m_theme->comment.dimensions.left(-0.48).screenBottom(-0.023);
+       m_theme->comment.draw(_("Windows users can also use ConfigureSongDirectory.bat script."));
+       #endif
+}
diff --git a/game/screen_paths.hh b/game/screen_paths.hh
new file mode 100644 (file)
index 0000000..323eff9
--- /dev/null
@@ -0,0 +1,27 @@
+#pragma once
+
+#include <map>
+#include <boost/scoped_ptr.hpp>
+#include "screen.hh"
+#include "textinput.hh"
+
+class Audio;
+class ThemeAudioDevices;
+
+/// options dialogue
+class ScreenPaths: public Screen {
+  public:
+       /// constructor
+       ScreenPaths(std::string const& name, Audio& m_audio);
+       void enter();
+       void exit();
+       void manageEvent(SDL_Event event);
+       void manageEvent(input::NavEvent const& event);
+       void draw();
+
+  private:
+       Audio& m_audio;
+       boost::scoped_ptr<ThemeAudioDevices> m_theme;
+       TextInput m_txtinp;
+};
+
diff --git a/game/screen_players.cc b/game/screen_players.cc
new file mode 100644 (file)
index 0000000..60901d4
--- /dev/null
@@ -0,0 +1,186 @@
+#include "screen_players.hh"
+#include "screen_songs.hh"
+
+#include "configuration.hh"
+#include "audio.hh"
+#include "database.hh"
+#include "fs.hh"
+#include "util.hh"
+#include "layout_singer.hh"
+#include "theme.hh"
+#include "video.hh"
+#include "i18n.hh"
+#include "controllers.hh"
+
+#include <iostream>
+#include <sstream>
+#include <boost/format.hpp>
+
+ScreenPlayers::ScreenPlayers(std::string const& name, Audio& audio, Database& database):
+  Screen(name), m_audio(audio), m_database(database), m_players(database.m_players), m_covers(20)
+{
+       m_players.setAnimMargins(5.0, 5.0);
+       m_playTimer.setTarget(getInf()); // Using this as a simple timer counting seconds
+}
+
+void ScreenPlayers::enter() {
+       m_layout_singer.reset(new LayoutSinger(m_song->getVocalTrack(), m_database));
+
+       theme.reset(new ThemeSongs());
+       m_emptyCover.reset(new Surface(findFile("no_player_image.svg")));
+       m_search.text.clear();
+       m_players.setFilter(m_search.text);
+       m_audio.fadeout();
+       if (m_database.scores.empty() || !m_database.reachedHiscore(m_song)) {
+               Game::getSingletonPtr()->activateScreen("Playlist");
+       }
+}
+
+void ScreenPlayers::exit() {
+       m_layout_singer.reset();
+
+       m_covers.clear();
+       m_emptyCover.reset();
+       theme.reset();
+       m_video.reset();
+       m_songbg.reset();
+       m_playing.clear();
+       m_playReq.clear();
+
+       m_database.save();
+}
+
+void ScreenPlayers::manageEvent(input::NavEvent const& event) {
+       Game* gm = Game::getSingletonPtr();
+       input::NavButton nav = event.button;
+       if (nav == input::NAV_CANCEL) {
+               if (m_search.text.empty()) { gm->activateScreen("Songs"); return; }
+               else { m_search.text.clear(); m_players.setFilter(m_search.text); }
+       } else if (nav == input::NAV_START) {
+               if (m_players.empty()) {
+                       m_players.addPlayer(m_search.text);
+                       m_players.setFilter(m_search.text);
+                       m_players.update();
+                       // the current player is the new created one
+               }
+               m_database.addHiscore(m_song);
+               m_database.scores.pop_front();
+
+               if (m_database.scores.empty() || !m_database.reachedHiscore(m_song)) {
+                       // no more highscore, we are now finished
+                       gm->activateScreen("Playlist");
+               } else {
+                       m_search.text.clear();
+                       m_players.setFilter("");
+                       // add all players which reach highscore because if score is very near or same it might be
+                       // frustrating for second one that he cannot enter, so better go for next one...
+               }
+       }
+       else if (m_players.empty()) return;
+       else if (nav == input::NAV_PAUSE) m_audio.togglePause();
+       else if (nav == input::NAV_LEFT) m_players.advance(-1);
+       else if (nav == input::NAV_RIGHT) m_players.advance(1);
+       else if (nav == input::NAV_UP) m_players.advance(-1);
+       else if (nav == input::NAV_DOWN) m_players.advance(1);
+       else if (nav == input::NAV_MOREUP) m_players.advance(-10);
+       else if (nav == input::NAV_MOREDOWN) m_players.advance(10);
+}
+
+void ScreenPlayers::manageEvent(SDL_Event event) {
+       if (event.type == SDL_KEYDOWN) { // Process keyboard-only keys
+               SDL_Keysym keysym = event.key.keysym;
+               //int key = keysym.sym;
+               //SDLMod mod = event.key.keysym.mod;
+
+               //TODO: reload -- needs database reload
+               // if (key == SDLK_r && mod & KMOD_CTRL) { m_players.reload(); m_players.setFilter(m_search.text); }
+               if (m_search.process(keysym)) m_players.setFilter(m_search.text);
+       }
+}
+
+void ScreenPlayers::draw() {
+       m_players.update(); // Poll for new players
+       double length = m_audio.getLength();
+       double time = clamp(m_audio.getPosition() - config["audio/video_delay"].f(), 0.0, length);
+       if (m_songbg.get()) m_songbg->draw();
+       if (m_video.get()) m_video->render(time);
+       theme->bg.draw();
+       std::string music, songbg, video;
+       double videoGap = 0.0;
+       std::ostringstream oss_song, oss_order;
+       // Test if there are no players currently selected
+       if (m_players.empty()) {
+               // Format the song information text
+               if (m_search.text.empty()) {
+                       oss_song << _("No players found!");
+                       oss_order << _("Enter a name to create a new player.");
+               } else {
+                       oss_song << _("Press enter to create player!");
+                       oss_order << m_search.text << '\n';
+               }
+       } else if (m_database.scores.empty()) {
+               oss_song << _("No players worth mentioning!");
+       } else {
+               // Format the player information text
+               oss_song << m_database.scores.front().track << '\n';
+               // TODO: use boost::format
+               oss_song << boost::format(_("You reached %1% points!")) % m_database.scores.front().score;
+               oss_order << _("Change player with arrow keys.") << '\n'
+                       << _("Name:") << ' ' << m_players.current().name << '\n';
+               //m_database.queryPerPlayerHiscore(oss_order);
+               oss_order << '\n'
+                       << (m_search.text.empty() ? _("Type text to filter or create a new player.") : std::string(_("Search Text:")) + " " + m_search.text)
+                       << '\n';
+               double spos = m_players.currentPosition(); // This needs to be polled to run the animation
+
+               // Draw the covers
+               std::size_t ss = m_players.size();
+               int baseidx = spos + 1.5; --baseidx; // Round correctly
+               double shift = spos - baseidx;
+               // FIXME: 3D browser
+               for (int i = -2; i < 5; ++i) {
+                       PlayerItem player_display = m_players[baseidx + i];
+                       if (baseidx + i < 0 || baseidx + i >= int(ss)) continue;
+                       Surface* cover = nullptr;
+                       if (player_display.path != "")
+                       {
+                               try { cover = &m_covers[player_display.path]; }
+                               catch (std::exception const&) {}
+                       }
+                       Surface& s = (cover ? *cover : *m_emptyCover);
+                       double diff = (i == 0 ? (0.5 - fabs(shift)) * 0.07 : 0.0);
+                       double y = 0.27 + 0.5 * diff;
+                       // Draw the cover
+                       s.dimensions.middle(-0.2 + 0.17 * (i - shift)).bottom(y - 0.2 * diff).fitInside(0.14 + diff, 0.14 + diff); s.draw();
+                       // Draw the reflection
+                       s.dimensions.top(y + 0.2 * diff); s.tex = TexCoords(0, 1, 1, 0);
+                       {
+                               ColorTrans c(Color::alpha(0.4));
+                               s.draw();
+                       }
+                       s.tex = TexCoords();
+               }
+               /*
+               if (!song.music.empty()) music = song.music[0]; // FIXME: support multiple tracks
+               if (!song.background.empty()) songbg = song.path + song.background;
+               if (!song.video.empty()) { video = song.path + song.video; videoGap = song.videoGap; }
+               */
+       }
+
+       // Draw song and order texts
+       theme->song.draw(oss_song.str());
+       theme->order.draw(oss_order.str());
+
+       // Schedule playback change if the chosen song has changed
+       if (music != m_playReq) { m_playReq = music; m_playTimer.setValue(0.0); }
+       // Play/stop preview playback (if it is the time)
+       if (music != m_playing && m_playTimer.get() > 0.4) {
+               m_songbg.reset(); m_video.reset();
+               if (music.empty()) m_audio.fadeout(1.0); else m_audio.playMusic(music, true, 2.0);
+               if (!songbg.empty()) try { m_songbg.reset(new Surface(songbg)); } catch (std::exception const&) {}
+               if (!video.empty() && config["graphic/video"].b()) m_video.reset(new Video(video, videoGap));
+               m_playing = music;
+       }
+       m_layout_singer->drawScore(LayoutSinger::TOP);
+}
+
diff --git a/game/screen_players.hh b/game/screen_players.hh
new file mode 100644 (file)
index 0000000..07a760a
--- /dev/null
@@ -0,0 +1,53 @@
+#pragma once
+
+#include "animvalue.hh"
+#include "cachemap.hh"
+#include "screen.hh"
+#include "textinput.hh"
+
+#include <boost/scoped_ptr.hpp>
+
+class Song;
+class Audio;
+class Video;
+class Players;
+class Surface;
+class Database;
+class ThemeSongs;
+class LayoutSinger;
+
+/** Player hiscore addition screen.
+  Database is passed as argument, but only the players is stored
+  and used everywhere.
+ */
+class ScreenPlayers : public Screen {
+  public:
+       /// constructor
+       ScreenPlayers(std::string const& name, Audio& audio, Database& database);
+       void enter();
+       void exit();
+       void manageEvent(SDL_Event event);
+       void manageEvent(input::NavEvent const& event);
+       void draw();
+
+       void setSong (boost::shared_ptr<Song> song_)
+       {
+               m_song = song_;
+       }
+
+  private:
+       Audio& m_audio;
+       Database& m_database;
+       Players& m_players;
+       boost::shared_ptr<Song> m_song; /// Pointer to the current song
+       boost::scoped_ptr<Surface> m_songbg;
+       boost::scoped_ptr<Video> m_video;
+       boost::scoped_ptr<ThemeSongs> theme;
+       std::string m_playing;
+       std::string m_playReq;
+       AnimValue m_playTimer;
+       TextInput m_search;
+       boost::scoped_ptr<Surface> m_emptyCover;
+       Cachemap<fs::path, Surface> m_covers;
+       boost::scoped_ptr<LayoutSinger> m_layout_singer;
+};
diff --git a/game/screen_playlist.cc b/game/screen_playlist.cc
new file mode 100644 (file)
index 0000000..a630d56
--- /dev/null
@@ -0,0 +1,352 @@
+#include "screen_playlist.hh"
+#include "menu.hh"
+#include "screen_sing.hh"
+#include "playlist.hh"
+#include "theme.hh"
+#include "util.hh"
+#include "i18n.hh"
+
+#include <iostream>
+#include <sstream>
+#include <boost/format.hpp>
+
+namespace {
+       static const double NEXT_TIMEOUT = 15.0; // go to next song in 15 seconds
+}
+
+ScreenPlaylist::ScreenPlaylist(std::string const& name,Audio& audio, Songs& songs, Backgrounds& bgs):
+       Screen(name), m_audio(audio), m_songs(songs), m_backgrounds(bgs), m_covers(20), keyPressed()
+{}
+
+void ScreenPlaylist::enter() {
+       Game* gm = Game::getSingletonPtr();
+       // Initialize webcam
+       gm->loading(_("Initializing webcam..."), 0.1);
+       if (config["graphic/webcam"].b() && Webcam::enabled()) {
+               try {
+                       m_cam.reset(new Webcam(config["graphic/webcamid"].i()));
+               } catch (std::exception& e) { std::cout << e.what() << std::endl; };
+       }
+       m_audio.togglePause();
+       if (gm->getCurrentPlayList().isEmpty()) {
+               if(config["game/autoplay"].b()) {
+                       m_songs.setFilter("");
+                       Screen* s = gm->getScreen("Sing");
+                       ScreenSing* ss = dynamic_cast<ScreenSing*> (s);
+                       assert(ss);
+                       int randomsong = std::rand() % m_songs.size();
+                       ss->setSong(m_songs[randomsong]);
+                       gm->activateScreen("Sing");
+               } else {
+                       gm->activateScreen("Songs");
+               }
+       }
+       keyPressed = false;
+       m_nextTimer.setValue(NEXT_TIMEOUT);
+       overlay_menu.close();
+       createSongListMenu();
+       songlist_menu.open();
+       reloadGL();
+}
+
+void ScreenPlaylist::prepare() {
+       return;
+}
+
+void ScreenPlaylist::reloadGL() {
+       theme.reset(new ThemePlaylistScreen());
+       m_menuTheme.reset(new ThemeInstrumentMenu());
+       m_singCover.reset(new Surface(findFile("no_cover.svg")));
+       m_instrumentCover.reset(new Surface(findFile("instrument_cover.svg")));
+       m_bandCover.reset(new Surface(findFile("band_cover.svg")));
+       m_danceCover.reset(new Surface(findFile("dance_cover.svg")));
+}
+
+void ScreenPlaylist::exit() {
+       overlay_menu.clear();
+       songlist_menu.clear();
+       m_menuTheme.reset();
+       theme.reset();
+       m_audio.togglePause();
+       m_background.reset();
+       m_cam.reset();
+}
+
+
+void ScreenPlaylist::manageEvent(input::NavEvent const& event) {
+       input::NavButton nav = event.button;
+       Menu& menu = overlay_menu.isOpen() ? overlay_menu : songlist_menu;
+
+       if (keyPressed == false)
+               keyPressed = true;
+
+       if (nav == input::NAV_CANCEL) {
+               if(overlay_menu.isOpen()) {
+                       overlay_menu.close();
+               } else {
+                       createEscMenu();
+                       overlay_menu.open();
+               }
+       } else {
+               if (nav == input::NAV_PAUSE) {
+                       m_audio.togglePause();
+               } else if (nav == input::NAV_START) {
+                       menu.action();
+               } else if (event.menu == input::NAVMENU_A_PREV) {
+                       menu.move(-1);
+               } else if (event.menu == input::NAVMENU_A_NEXT) {
+                       menu.move(1);
+               } else if (event.menu == input::NAVMENU_B_PREV) {
+                       menu.move(-1);
+               } else if (event.menu == input::NAVMENU_B_NEXT) {
+                       menu.move(1);
+               }
+       }
+}
+
+void ScreenPlaylist::manageEvent(SDL_Event) {
+       return;
+}
+
+void ScreenPlaylist::draw() {
+       Game* gm = Game::getSingletonPtr();
+       if (!m_background || m_background->empty()) m_background.reset(new Surface(m_backgrounds.getRandom()));
+       m_background->draw();
+       if (m_nextTimer.get() == 0.0 && keyPressed == false) {
+               Screen* s = gm->getScreen("Sing");
+               ScreenSing* ss = dynamic_cast<ScreenSing*> (s);
+               assert(ss);
+               ss->setSong(gm->getCurrentPlayList().getNext());
+               gm->activateScreen("Sing");
+       }
+       if (m_cam && config["graphic/webcam"].b()) m_cam->render();
+       draw_menu_options();
+       //menu on top of everything
+       if (overlay_menu.isOpen()) {
+               drawMenu();
+       }
+       auto const& playlist = gm->getCurrentPlayList().getList();
+       for (unsigned i = playlist.size() - 1; i < playlist.size(); --i) {
+               if(i < 9) { //only draw the first 9 covers
+                       Surface& s = getCover(*playlist[i]);
+                       double pos =  i / std::max<double>(9, 9);
+                       using namespace glmath;
+                       Transform trans(
+                         translate(vec3(-0.4 + 0.9 * pos, 0.045)) //vec3(horizontal-offset-from-center, vertical offset from screen_bottom)
+                         * rotate(-0.0, vec3(0.0, 1.0, 0.0))
+                       );
+                       s.dimensions.middle().screenBottom(-0.06).fitInside(0.08, 0.08);
+                       s.draw();
+               }
+       }
+}
+Surface& ScreenPlaylist::getCover(Song const& song) {
+       Surface* cover = nullptr;
+       // Fetch cover image from cache or try loading it
+       if (!song.cover.empty()) try { cover = &m_covers[song.cover]; } catch (std::exception const&) {}
+       // Fallback to background image as cover if needed
+       if (!cover && !song.background.empty()) try { cover = &m_covers[song.background]; } catch (std::exception const&) {}
+       // Use empty cover
+       if (!cover) {
+               if(song.hasDance()) {
+                       cover = m_danceCover.get();
+               } else if(song.hasDrums()) {
+                       cover = m_bandCover.get();
+               } else {
+                       size_t tracks = song.instrumentTracks.size();
+                       if (tracks == 0) cover = m_singCover.get();
+                       else cover = m_instrumentCover.get();
+               }
+       }
+       return *cover;
+}
+
+void ScreenPlaylist::createEscMenu() {
+       overlay_menu.clear();
+       overlay_menu.add(MenuOption(_("Continue"), _("Continue playing")).call([this]() {
+               Game* gm = Game::getSingletonPtr();
+               Screen* s = gm->getScreen("Sing");
+               ScreenSing* ss = dynamic_cast<ScreenSing*> (s);
+               assert(ss);
+               ss->setSong(gm->getCurrentPlayList().getNext());
+               gm->activateScreen("Sing");
+       }));
+       overlay_menu.add(MenuOption(_("Add songs"), _("Open the song browser to add more songs")).screen("Songs"));
+       overlay_menu.add(MenuOption(_("Shuffle"), _("Randomize the order of the playlist")).call([this]() {
+               Game* tm = Game::getSingletonPtr();
+               tm->getCurrentPlayList().shuffle();
+               overlay_menu.close();
+               createSongListMenu();
+       }));
+       overlay_menu.add(MenuOption(_("Clear and exit"), _("Remove all the songs from the list")).call([this]() {
+               Game* tm = Game::getSingletonPtr();
+               tm->getCurrentPlayList().clear();
+               overlay_menu.close();
+               tm->activateScreen("Songs");
+       }));
+       overlay_menu.add(MenuOption(_("Back"), _("Back to playlist viewer")).call([this]() {
+               overlay_menu.close();
+       }));
+}
+
+void ScreenPlaylist::drawMenu() {
+       if (overlay_menu.empty()) return;
+       // Some helper vars
+       ThemeInstrumentMenu& th = *m_menuTheme;
+       auto cur = static_cast<MenuOptions::const_iterator>(&overlay_menu.current());
+       double w = overlay_menu.dimensions.w();
+       const float txth = th.option_selected.h();
+       const float step = txth * 0.85f;
+       const float h = overlay_menu.getOptions().size() * step + step;
+       float y = -h * .5f + step;
+       float x = -w * .5f + step;
+       // Background
+       th.bg.dimensions.middle(0).center(0).stretch(w, h);
+       th.bg.draw();
+       // Loop through menu items
+       w = 0;
+       for (MenuOptions::const_iterator it = overlay_menu.begin(); it != overlay_menu.end(); ++it) {
+               // Pick the font object
+               SvgTxtTheme* txt = &th.option_selected;
+               if (cur != it) txt = &(th.getCachedOption(it->getName()));
+               // Set dimensions and draw
+               txt->dimensions.middle(x).center(y);
+               txt->draw(it->getName());
+               w = std::max(w, txt->w() + 2 * step); // Calculate the widest entry
+               y += step;
+       }
+       if (cur->getComment() != "") {
+               th.comment.dimensions.middle(0).screenBottom(-0.12);
+               th.comment.draw(cur->getComment());
+       }
+       overlay_menu.dimensions.stretch(w, h);
+}
+
+void ScreenPlaylist::draw_menu_options() {
+       // Variables used for positioning and other stuff
+       double wcounter = 0;
+       const size_t showopts = 7; // Show at most 8 options simultaneously
+       const float x = -0.35; // x xcoordinate from screen center, the menu should be aligned left of the center therefore it´s negative.n
+       const float start_y = -0.15;
+       const float sel_margin = 0.04;
+       const MenuOptions opts = songlist_menu.getOptions();
+       double submenuanim = 1.0 - std::min(1.0, std::abs(m_submenuAnim.get()-songlist_menu.getSubmenuLevel()));
+       // Determine from which item to start
+       int start_i = std::min((int)songlist_menu.curIndex() - 1, (int)opts.size() - (int)showopts
+               + (songlist_menu.getSubmenuLevel() == 2 ? 1 : 0)); // Hack to counter side-effects from displaying the value inside the menu
+       if (start_i < 0 || opts.size() == showopts) start_i = 0;
+
+       // Loop the currently visible options
+       for (size_t i = start_i, ii = 0; ii < showopts && i < opts.size(); ++i, ++ii) {
+               MenuOption const& opt = opts[i];
+               ColorTrans c(Color::alpha(submenuanim));
+
+               // Selection
+               if (i == songlist_menu.curIndex()) {
+                       // Animate selection higlight moving
+                       double selanim = m_selAnim.get() - start_i;
+                       if (selanim < 0) selanim = 0;
+                       // Draw the text, dim if option not available
+                       {
+                               ColorTrans c(Color::alpha(opt.isActive() ? 1.0 : 0.5));
+                               theme->option_selected.dimensions.left(x).center(start_y + ii*0.049);
+                               theme->option_selected.draw(opt.getName());
+                       }
+                       wcounter = std::max(wcounter, theme->option_selected.w() + 2 * sel_margin); // Calculate the widest entry
+                       // If this is a config item, show the value below
+                       if (opt.type == MenuOption::CHANGE_VALUE) {
+                               ++ii; // Use a slot for the value
+                               theme->option_selected.dimensions.left(x + sel_margin).center(-0.1 + (selanim+1)*0.08);
+                               theme->option_selected.draw("<  " + opt.value->getValue() + "  >");
+                       }
+
+               // Regular option (not selected)
+               } else {
+                       std::string title = opt.getName();
+                       SvgTxtTheme& txt = getTextObject(title);
+                       ColorTrans c(Color::alpha(opt.isActive() ? 1.0 : 0.5));
+                       txt.dimensions.left(x).center(start_y + ii*0.05);
+                       txt.draw(title);
+                       wcounter = std::max(wcounter, txt.w() + 2 * sel_margin); // Calculate the widest entry
+               }
+       }
+       songlist_menu.dimensions.stretch(wcounter, 1);
+}
+
+SvgTxtTheme& ScreenPlaylist::getTextObject(std::string const& txt) {
+       if (theme->options.contains(txt)) return theme->options[txt];
+       return *theme->options.insert(txt, new SvgTxtTheme(findFile("mainmenu_option.svg"), config["graphic/text_lod"].f()))->second;
+}
+
+void ScreenPlaylist::createSongListMenu() {
+       Game* gm = Game::getSingletonPtr();
+       std::ostringstream oss_playlist;
+       int count = 1;
+       songlist_menu.clear();
+       SongList& currentList = gm->getCurrentPlayList().getList();
+       for (auto const& song: currentList) {
+               oss_playlist << "#" << count << " : " << song->artist << " - " << song->title;
+               std::string songinfo = oss_playlist.str();
+               if (songinfo.length() > 20) {
+                       songinfo = songinfo + "                          >"; //FIXME: ugly hack to make the text scale so it fits on screen!
+               }
+               songlist_menu.add(MenuOption(_(songinfo.c_str()),_("Press enter to view song options")).call([this, count]() {
+                       createSongMenu(count);
+                       overlay_menu.open();
+               }));
+               oss_playlist.str("");
+               count++;
+       }
+       songlist_menu.add(MenuOption(_("View more options"),_("View general playlist settings")).call([this]() {
+               createEscMenu();
+               overlay_menu.open();
+       }));
+}
+
+void ScreenPlaylist::createSongMenu(int songNumber) {
+       overlay_menu.clear();
+       std::string firstOption = songNumber >= 2 ? _("Play first") : _("Continue");
+       std::string firstDesc = songNumber >= 2 ?
+               _("Ignore the playlist's order and play this song first") :
+               _("Start the song already!");
+       overlay_menu.add(MenuOption(firstOption, firstDesc).call([this, songNumber]() {
+               Game* gm = Game::getSingletonPtr();
+               Screen* s = gm->getScreen("Sing");
+               ScreenSing* ss = dynamic_cast<ScreenSing*>(s);
+               assert(ss);
+               ss->setSong(gm->getCurrentPlayList().getSong(songNumber - 1));
+               gm->activateScreen("Sing");
+       }));
+       overlay_menu.add(MenuOption(_("Remove"), _("Remove this song from the list")).call([this, songNumber]() {
+               Game* gm = Game::getSingletonPtr();
+               // Minus 1 so it doesn´t remove #2 when you´ve selected #1
+               gm->getCurrentPlayList().removeSong(songNumber - 1);
+               overlay_menu.close();
+               if (gm->getCurrentPlayList().isEmpty()) {
+                       gm->activateScreen("Songs");
+               } else {
+                       createSongListMenu();
+               }
+       }));
+       if (songNumber >= 2) { //can't move up first song
+               overlay_menu.add(MenuOption(_("Move up"), _("Move this song up the list")).call([this, songNumber]() {
+                       Game* gm = Game::getSingletonPtr();
+                       gm->getCurrentPlayList().swap(songNumber -1, songNumber -2);
+                       createSongListMenu();
+                       overlay_menu.close();
+               }));
+       }
+       Game* gm = Game::getSingletonPtr();
+       int size = gm->getCurrentPlayList().getList().size();
+       if (songNumber < size) { //can't move down the last song
+               overlay_menu.add(MenuOption(_("Move Down"), _("Move this song up the list")).call([this, songNumber]() {
+                       Game* gm = Game::getSingletonPtr();
+                       gm->getCurrentPlayList().swap(songNumber -1, songNumber);
+                       createSongListMenu();
+                       overlay_menu.close();
+               }));
+       }
+       overlay_menu.add(MenuOption(_("Back"), _("Back to playlist viewer")).call([this]() {
+               overlay_menu.close();
+       }));
+}
diff --git a/game/screen_playlist.hh b/game/screen_playlist.hh
new file mode 100644 (file)
index 0000000..027599e
--- /dev/null
@@ -0,0 +1,68 @@
+#pragma once
+
+#include "backgrounds.hh"
+#include "screen.hh"
+#include "cachemap.hh"
+#include "menu.hh"
+#include "song.hh"
+#include "animvalue.hh"
+#include "playlist.hh"
+#include "controllers.hh"
+#include "songs.hh"
+#include "surface.hh"
+#include "webcam.hh"
+#include <vector>
+#include <boost/scoped_ptr.hpp>
+
+
+class Audio;
+class Database;
+class Song;
+class Surface;
+class ThemePlaylistScreen;
+class Backgrounds;
+class ThemeInstrumentMenu;
+
+class ScreenPlaylist : public Screen
+{
+public:
+       typedef std::vector< boost::shared_ptr<Song> > SongList;
+       ScreenPlaylist(std::string const& name, Audio& audio, Songs& songs, Backgrounds& bgs);
+       void manageEvent(input::NavEvent const& event);
+       void manageEvent(SDL_Event);
+       void prepare();
+       void draw();
+       void enter();
+       void exit();
+       void reloadGL();
+private:
+       Menu overlay_menu;
+       Menu songlist_menu;
+       bool m_first;
+       AnimValue m_selAnim;
+       AnimValue m_submenuAnim;
+       Audio& m_audio;
+       Songs& m_songs;
+       void createSongListMenu();
+       void createEscMenu();
+       void createSongMenu(int songNumber);
+       void drawMenu();
+       void createMenuFromPlaylist();
+       Backgrounds& m_backgrounds;
+       Cachemap<fs::path, Surface> m_covers;
+       boost::scoped_ptr<ThemeInstrumentMenu> m_menuTheme;
+       boost::scoped_ptr<ThemePlaylistScreen> theme;
+       boost::scoped_ptr<Surface> m_background;
+       SvgTxtTheme& getTextObject(std::string const& txt);
+       AnimValue m_nextTimer;
+       void draw_menu_options();
+       bool keyPressed;
+       Surface& getCover(Song const& song);
+       boost::scoped_ptr<Surface> m_singCover;
+       boost::scoped_ptr<Surface> m_instrumentCover;
+       boost::scoped_ptr<Surface> m_bandCover;
+       boost::scoped_ptr<Surface> m_danceCover;
+       boost::scoped_ptr<Webcam> m_cam;
+};
+
+
diff --git a/game/screen_practice.cc b/game/screen_practice.cc
new file mode 100644 (file)
index 0000000..b38b27f
--- /dev/null
@@ -0,0 +1,110 @@
+#include "screen_practice.hh"
+
+#include "audio.hh"
+#include "util.hh"
+#include "fs.hh"
+#include "controllers.hh"
+#include "theme.hh"
+#include "progressbar.hh"
+
+ScreenPractice::ScreenPractice(std::string const& name, Audio& audio):
+  Screen(name), m_audio(audio)
+{}
+
+void ScreenPractice::enter() {
+       m_audio.playMusic(findFile("practice.ogg"));
+       // draw vu meters
+       for (unsigned int i = 0, mics = m_audio.analyzers().size(); i < mics; ++i) {
+               m_vumeters.push_back(new ProgressBar(findFile("vumeter_bg.svg"), findFile("vumeter_fg.svg"), ProgressBar::VERTICAL, 0.136, 0.023));
+       }
+       m_samples.push_back("drum bass");
+       m_samples.push_back("drum snare");
+       m_samples.push_back("drum hi-hat");
+       m_samples.push_back("drum tom1");
+       m_samples.push_back("drum cymbal");
+       //m_samples.push_back("drum tom2");
+       reloadGL();
+       Game::getSingletonPtr()->controllers.enableEvents(true);
+}
+
+void ScreenPractice::reloadGL() {
+       theme.reset(new ThemePractice());
+}
+
+void ScreenPractice::exit() {
+       Game::getSingletonPtr()->controllers.enableEvents(false);
+       m_vumeters.clear();
+       m_samples.clear();
+       theme.reset();
+}
+
+void ScreenPractice::manageEvent(input::NavEvent const& event) {
+       Game* gm = Game::getSingletonPtr();
+       input::NavButton nav = event.button;
+       if (nav == input::NAV_CANCEL || nav == input::NAV_START) gm->activateScreen("Intro");
+       else if (nav == input::NAV_PAUSE) m_audio.togglePause();
+       // Process all instrument events that are available, then throw away the instruments...
+       input::DevicePtr dev = gm->controllers.registerDevice(event.source);
+       if (dev) {
+               for (input::Event ev; dev->getEvent(ev);) {
+                       if (ev.value == 0.0) continue;
+                       if (dev->type == input::DEVTYPE_DANCEPAD) {}
+                       else if (dev->type == input::DEVTYPE_GUITAR) {}
+                       else if (dev->type == input::DEVTYPE_DRUMS) m_audio.playSample(m_samples[ev.button.num() % m_samples.size()]);
+               }
+       }
+       // TODO: We could store the DevicePtrs and display the instruments on screen in a meaningful way
+       // Note: Alternatively this could be done via listening to NavEvents and not even registering the devices, simplifying the above processing.
+}
+
+void ScreenPractice::draw() {
+       theme->bg.draw();
+       this->draw_analyzers();
+}
+
+void ScreenPractice::draw_analyzers() {
+       theme->note.dimensions.fixedHeight(0.03f);
+       theme->sharp.dimensions.fixedHeight(0.09f);
+       boost::ptr_vector<Analyzer>& analyzers = m_audio.analyzers();
+       if (analyzers.empty()) return;
+       MusicalScale scale;
+       double textPower = -getInf();
+       double textFreq = 0.0;
+
+       for (unsigned int i = 0; i < analyzers.size(); ++i) {
+               Analyzer& analyzer = analyzers[i];
+               analyzer.process();
+               Tone const* tone = analyzer.findTone();
+               double freq = (tone ? tone->freq : 0.0);
+               if (tone && tone->db > textPower) {
+                       textPower = tone->db;
+                       textFreq = freq;
+               }
+               // getPeak returns 0.0 when clipping, negative values when not that loud.
+               // Normalizing to [0,1], where 0 is -43 dB or less (to match the vumeter graphic)
+               m_vumeters[i].dimensions.screenBottom().left(-0.4 + i * 0.2).fixedWidth(0.04);
+               m_vumeters[i].draw(analyzer.getPeak() / 43.0 + 1.0);
+
+               if (freq != 0.0) {
+                       Analyzer::tones_t tones = analyzer.getTones();
+
+                       for (Analyzer::tones_t::const_iterator t = tones.begin(); t != tones.end(); ++t) {
+                               if (t->age < Tone::MINAGE) continue;
+                               if (!scale.setFreq(t->freq).isValid()) continue;
+                               double line = scale.getNoteLine() + 0.4 * scale.getNoteOffset();
+                               float posXnote = -0.25 + 0.2 * i + 0.002 * t->stabledb;  // Wiggle horizontally based on volume
+                               float posYnote = -0.03 - line * 0.015;  // On treble key (C4), plus offset (lines)
+
+                               theme->note.dimensions.left(posXnote).center(posYnote);
+                               theme->note.draw();
+                               // Draw # for sharp notes
+                               if (scale.isSharp()) {
+                                       theme->sharp.dimensions.right(posXnote).center(posYnote);
+                                       theme->sharp.draw();
+                               }
+                       }
+               }
+       }
+       // Display note and frequency
+       if (textFreq > 0.0) theme->note_txt.draw(scale.setFreq(textFreq).getStr());
+}
diff --git a/game/screen_practice.hh b/game/screen_practice.hh
new file mode 100644 (file)
index 0000000..7911aa6
--- /dev/null
@@ -0,0 +1,31 @@
+#pragma once
+
+#include <boost/scoped_ptr.hpp>
+#include "screen.hh"
+#include "controllers.hh"
+
+class Audio;
+class Sample;
+class ProgressBar;
+class ThemePractice;
+
+/// screen for practice mode
+class ScreenPractice : public Screen {
+  public:
+       /// constructor
+       ScreenPractice(std::string const& name, Audio& audio);
+       void enter();
+       void exit();
+       void reloadGL();
+       void manageEvent(input::NavEvent const& event);
+       void draw();
+
+       /// draw analyzers
+       void draw_analyzers();
+
+  private:
+       Audio& m_audio;
+       std::vector<std::string> m_samples;
+       boost::ptr_vector<ProgressBar> m_vumeters;
+       boost::scoped_ptr<ThemePractice> theme;
+};
diff --git a/game/screen_sing.cc b/game/screen_sing.cc
new file mode 100644 (file)
index 0000000..6f03581
--- /dev/null
@@ -0,0 +1,702 @@
+#include "screen_sing.hh"
+
+#include "backgrounds.hh"
+#include "dancegraph.hh"
+#include "database.hh"
+#include "engine.hh"
+#include "fs.hh"
+#include "glutil.hh"
+#include "guitargraph.hh"
+#include "i18n.hh"
+#include "layout_singer.hh"
+#include "menu.hh"
+#include "screen_players.hh"
+#include "songparser.hh"
+#include "util.hh"
+#include "video.hh"
+#include "webcam.hh"
+#include "screen_songs.hh"
+
+#include <boost/format.hpp>
+#include <boost/lexical_cast.hpp>
+#include <iostream>
+#include <stdexcept>
+#include <cmath>
+#include <utility>
+
+namespace {
+       static const double QUIT_TIMEOUT = 20.0; // Return to songs screen after 20 seconds in score screen
+
+       /// Add a flash message about the state of a config item
+       void dispInFlash(ConfigItem& ci) {
+               Game* gm = Game::getSingletonPtr();
+               gm->flashMessage(ci.getShortDesc() + ": " + ci.getValue());
+       }
+}
+
+ScreenSing::ScreenSing(std::string const& name, Audio& audio, Database& database, Backgrounds& bgs):
+       Screen(name), m_audio(audio), m_database(database), m_backgrounds(bgs),
+       m_selectedTrack(TrackName::LEAD_VOCAL)
+{}
+
+void ScreenSing::enter() {
+       keyPressed = false;
+       m_DuetTimeout.setValue(10);
+       Game* gm = Game::getSingletonPtr();
+       // Initialize webcam
+       gm->loading(_("Initializing webcam..."), 0.1);
+       if (config["graphic/webcam"].b() && Webcam::enabled()) {
+               try {
+                       m_cam.reset(new Webcam(config["graphic/webcamid"].i()));
+               } catch (std::exception& e) { std::cout << e.what() << std::endl; };
+       }
+       // Load video
+       gm->loading(_("Loading video..."), 0.2);
+       if (!m_song->video.empty() && config["graphic/video"].b()) {
+               m_video.reset(new Video(m_song->video, m_song->videoGap));
+       }
+       boost::ptr_vector<Analyzer>& analyzers = m_audio.analyzers();
+       reloadGL();
+       // Load song notes
+       gm->loading(_("Loading song..."), 0.4);
+       try { m_song->loadNotes(false /* don't ignore errors */); }
+       catch (SongParserException& e) {
+               std::clog << e;
+               gm->activateScreen("Songs");
+       }
+       // Notify about broken tracks
+       if (!m_song->b0rked.empty()) gm->dialog(_("Song contains broken tracks!") + std::string("\n\n") + m_song->b0rked);
+       // Startup delay for instruments is longer than for singing only
+       double setup_delay = (!m_song->hasControllers() ? -1.0 : -5.0);
+       m_audio.pause();
+       m_audio.playMusic(m_song->music, false, 0.0, setup_delay);
+       gm->loading(_("Loading menu..."), 0.7);
+       {
+               VocalTracks const& tracks = m_song->vocalTracks;
+               unsigned players = analyzers.size();
+               m_menu.clear();
+               m_menu.add(MenuOption(_("Start"), _("Start performing")).call(std::bind(&ScreenSing::setupVocals, this)));
+               m_duet = ConfigItem(0);
+               if (players == 0) players = 1;  // No mic? We display lyrics anyway
+               if (players > 1) { // Duet toggle
+                       m_duet.addEnum(_("Duet mode"));
+                       m_duet.addEnum(_("Normal mode"));
+                       m_menu.add(MenuOption("", _("Switch between duet and regular singing mode")).changer(m_duet));
+               }
+               // Add vocal track selector for each player
+               for (unsigned player = 0; player < players; ++player) {
+                       ConfigItem& vocalTrack = m_vocalTracks[player];
+                       vocalTrack = ConfigItem(0);
+                       for (auto const& track: tracks) vocalTrack.addEnum(track.second.name);
+                       if (tracks.size() > 1 && player % 2) ++vocalTrack;  // Every other player gets the second track
+                       m_menu.add(MenuOption("", _("Change vocal track")).changer(vocalTrack));
+               }
+               m_menu.add(MenuOption(_("Quit"), _("Exit to song browser")).screen("Songs"));
+               m_menu.open();
+               if (tracks.size() <= 1) setupVocals();  // No duet menu
+       }
+       gm->showLogo(false);
+       gm->loading(_("Loading complete"), 1.0);
+}
+
+void ScreenSing::setupVocals() {
+       if (!m_song->vocalTracks.empty()) {
+               m_layout_singer.clear();
+               Engine::VocalTrackPtrs selectedTracks;
+               boost::ptr_vector<Analyzer>& analyzers = m_audio.analyzers();
+               unsigned players = (analyzers.empty() ? 1 : analyzers.size());  // Always at least 1; should be number of mics
+               std::set<VocalTrack*> shownTracks;  // Tracks to be included in layout_singer (stored by name for proper sorting and merging duplicates)
+               for (unsigned player = 0; player < players; ++player) {
+                       VocalTrack* vocal = &m_song->getVocalTrack(m_vocalTracks[(m_duet.i() == 0 ? player : 0)].i());
+                       selectedTracks.push_back(vocal);
+                       shownTracks.insert(vocal);
+               }
+               if (shownTracks.size() > 2) throw std::runtime_error("Too many tracks chosen. Only two vocal tracks can be used simultaneously.");
+               for (auto const& trk: shownTracks) m_layout_singer.push_back(new LayoutSinger(*trk, m_database, theme));
+               // Note: Engine maps tracks with analyzers 1:1. If user doesn't have mics, we still want to have singer layout enabled but without engine...
+               if (!analyzers.empty()) m_engine.reset(new Engine(m_audio, selectedTracks, m_database));
+       }
+       createPauseMenu();
+       m_audio.pause(false);
+}
+
+void ScreenSing::createPauseMenu() {
+       m_menu.clear();
+       m_menu.add(MenuOption(_("Resume"), _("Back to performing!")));
+       m_menu.add(MenuOption(_("Restart"), _("Start the song\nfrom the beginning")).screen("Sing"));
+       m_menu.add(MenuOption(_("Skip"), _("Skip current song")).screen("Playlist"));
+       m_menu.add(MenuOption(_("Quit"), _("Exit to song browser")).call([]() {
+               Game* gm = Game::getSingletonPtr();
+               gm->activateScreen("Songs");
+       }));
+       m_menu.close();
+}
+
+void ScreenSing::reloadGL() {
+       // Load UI graphics
+       theme.reset(new ThemeSing());
+       m_menuTheme.reset(new ThemeInstrumentMenu());
+       m_pause_icon.reset(new Surface(findFile("sing_pause.svg")));
+       m_player_icon.reset(new Surface(findFile("sing_pbox.svg"))); // For duet menu
+       m_help.reset(new Surface(findFile("instrumenthelp.svg")));
+       m_progress.reset(new ProgressBar(findFile("sing_progressbg.svg"), findFile("sing_progressfg.svg"), ProgressBar::HORIZONTAL, 0.01f, 0.01f, true));
+       // Load background
+       if (!m_song->background.empty()) m_background.reset(new Surface(m_song->background));
+}
+
+void ScreenSing::exit() {
+    Game::getSingletonPtr()->controllers.enableEvents(false);
+       m_engine.reset();
+       m_score_window.reset();
+       m_menu.clear();
+       m_instruments.clear();
+       m_layout_singer.clear();
+       m_help.reset();
+       m_pause_icon.reset();
+       m_player_icon.reset();
+       m_cam.reset();
+       m_video.reset();
+       m_background.reset();
+       m_song->dropNotes();
+       m_menuTheme.reset();
+       theme.reset();
+       if (m_audio.isPaused()) m_audio.togglePause();
+       Game::getSingletonPtr()->showLogo();
+}
+
+
+
+/// Manages the instrument drawing
+void ScreenSing::instrumentLayout(double time) {
+       if (!m_song->hasControllers()) return;
+       int count_alive = 0, count_menu = 0, i = 0;
+       // Remove dead instruments and do the counting
+       for (Instruments::iterator it = m_instruments.begin(); it != m_instruments.end(); ) {
+               if (it->dead()) {
+                       it = m_instruments.erase(it);
+                       continue;
+               }
+               ++count_alive;
+               if (it->menuOpen()) ++count_menu;
+               ++it;
+       }
+       if (count_alive > 0) {
+               // Handle pause
+               bool shouldPause = count_menu > 0 || m_menu.isOpen();
+               if (shouldPause != m_audio.isPaused()) m_audio.togglePause();
+       } else if (time < -0.5) {
+               // Display help if no-one has joined yet
+               ColorTrans c(Color::alpha(clamp(-1.0 - 2.0 * time)));
+               m_help->draw();
+       }
+       double iw = std::min(0.5, 1.0 / count_alive);
+       typedef std::pair<unsigned, double> CountSum;
+       std::map<std::string, CountSum> volume; // Stream id to (count, sum)
+       std::map<std::string, CountSum> pitchbend; // Stream id to (count, sum)
+       for (Instruments::iterator it = m_instruments.begin(); it != m_instruments.end(); ++it, ++i) {
+               it->engine();
+               it->position((0.5 + i - 0.5 * count_alive) * iw, iw); // Do layout stuff
+               it->draw(time);
+               {
+                       CountSum& cs = volume[it->getTrack()];
+                       cs.first++;
+                       cs.second += it->correctness();
+               }{
+                       CountSum& cs = pitchbend[it->getTrack()];
+                       cs.first++;
+                       cs.second += it->getWhammy();
+               }
+       }
+       // Set volume levels (averages of all instruments playing that track)
+       for (auto const& track: m_song->music) {
+               std::string const& name = track.first;
+               std::string locName = _(name.c_str());  // FIXME: There should NOT be gettext calls here!
+               double level = 1.0;
+               if (volume.find(locName) != volume.end()) {
+                       CountSum cs = volume[locName];
+                       if (cs.first > 0) level = cs.second / cs.first;
+                       if (m_song->music.size() <= 1) level = std::max(0.333, level);
+               }
+               m_audio.streamFade(name, level);
+               if (pitchbend.find(locName) != pitchbend.end()) {
+                       CountSum cs = pitchbend[locName];
+                       level = cs.second;
+                       m_audio.streamBend(name, level);
+               }
+       }
+}
+
+void ScreenSing::activateNextScreen()
+{
+       Game* gm = Game::getSingletonPtr();
+
+       m_database.addSong(m_song);
+       if (m_database.scores.empty() || !m_database.reachedHiscore(m_song)) {
+               // if no highscore reached..
+           gm->activateScreen("Playlist");
+       }
+
+       // Score window visible -> Enter quits to Players Screen
+       Screen* s = gm->getScreen("Players");
+       ScreenPlayers* ss = dynamic_cast<ScreenPlayers*> (s);
+       assert(ss);
+       ss->setSong(m_song);
+       gm->activateScreen("Players");
+}
+
+void ScreenSing::manageEvent(input::NavEvent const& event) {
+       keyPressed = true;
+       input::NavButton nav = event.button;
+       m_quitTimer.setValue(QUIT_TIMEOUT);
+       double time = m_audio.getPosition();
+       Song::Status status = m_song->status(time);
+       // When score window is displayed
+       if (m_score_window.get()) {
+               if (nav == input::NAV_START || nav == input::NAV_CANCEL) activateNextScreen();
+               return;  // The rest are only available when score window is not displayed
+       }
+       // Instant quit with CANCEL at the very beginning
+       if (nav == input::NAV_CANCEL && time < 1.0) {
+               Game::getSingletonPtr()->activateScreen("Playlist");
+               return;
+       }
+
+       if (event.repeat == 0 && devCanParticipate(event.devType)) {
+               Game* gm = Game::getSingletonPtr();
+               input::DevicePtr dev = gm->controllers.registerDevice(event.source);
+               if (dev) {
+                       // Eat all events and see if any are valid for joining
+                       input::DevType type = input::DEVTYPE_GENERIC;
+                       std::string msg;
+                       for (input::Event ev; dev->getEvent(ev);) {
+                               if (ev.value == 0.0) continue;
+                               if (dev->type == input::DEVTYPE_DANCEPAD && m_song->hasDance()) {
+                                       if (ev.button == input::DANCEPAD_UP) type = dev->type;
+                                       else msg = dev->source.isKeyboard() ? _("Press UP to join dance!") : _("Step UP to join!");
+                               }
+                               else if (dev->type == input::DEVTYPE_GUITAR && m_song->hasGuitars()) {
+                                       if (ev.button == input::GUITAR_GREEN) type = dev->type;
+                                       else if (ev.button != input::GUITAR_WHAMMY && ev.button != input::GUITAR_GODMODE) {
+                                               msg = dev->source.isKeyboard() ? _("Press 1 to join guitar!") : _("Press GREEN to join!");
+                                       }
+                               }
+                               else if (dev->type == input::DEVTYPE_DRUMS && m_song->hasDrums()) {
+                                       if (ev.button == input::DRUMS_KICK) type = dev->type;
+                                       else msg = dev->source.isKeyboard() ? _("Press SPACE to join drums!") : _("KICK to join!");
+                               }
+                       }
+                       if (!msg.empty()) gm->flashMessage(msg, 0.0, 0.1, 0.1);
+                       else if (type == input::DEVTYPE_DANCEPAD) m_instruments.push_back(new DanceGraph(m_audio, *m_song, dev));
+                       else if (type != input::DEVTYPE_GENERIC) m_instruments.push_back(new GuitarGraph(m_audio, *m_song, dev, m_instruments.size()));
+               }
+       }
+
+       // Only pause or esc opens the global menu (instruments have their own menus)
+       // TODO: This should probably check if the source is participating as an instrument or not rather than check for its type
+       if (!devCanParticipate(event.devType) && (nav == input::NAV_PAUSE || nav == input::NAV_CANCEL) && !m_audio.isPaused() && !m_menu.isOpen()) {
+               m_menu.open();
+               m_audio.togglePause();
+       }
+       // Global/singer pause menu navigation
+       if (m_menu.isOpen()) {
+               int do_action = 0;
+               if (nav == input::NAV_START) { do_action = 1; }
+               else if (nav == input::NAV_LEFT) { do_action = -1; }
+               else if (nav == input::NAV_RIGHT) { do_action = 1; }
+               else if (nav == input::NAV_DOWN) { m_menu.move(1); return; }
+               else if (nav == input::NAV_UP) { m_menu.move(-1); return; }
+
+               if (do_action != 0) {
+                       m_menu.action(do_action);
+                       // Did the action close the menu?
+                       if (!m_menu.isOpen() && m_audio.isPaused()) {
+                               m_audio.togglePause();
+                       }
+                       return;
+               }
+       }
+       // Start button has special functions for skipping things (only in singing for now)
+       if (nav == input::NAV_START && m_instruments.empty() && !m_layout_singer.empty() && !m_audio.isPaused()) {
+               // Open score dialog early
+               if (status == Song::FINISHED) {
+                       if (m_engine) m_engine->kill(); // Kill the engine thread
+                       m_score_window.reset(new ScoreWindow(m_instruments, m_database)); // Song finished, but no score window -> show it
+               }
+               // Skip instrumental breaks
+               else if (status == Song::INSTRUMENTAL_BREAK) {
+                       if (time < 0) m_audio.seek(0.0);
+                       else {
+                               // TODO: Instead of calculating here, calculate instrumental breaks right after song loading and store in Song data structures
+                               double diff = getNaN();
+                               for (size_t i = 0; i < m_layout_singer.size(); ++i) {
+                                       double d = m_layout_singer[i].lyrics_begin() - 3.0 - time;
+                                       if (!(d > diff)) diff = d;  // Store smallest d in diff (notice NaN handling)
+                               }
+                               if (diff > 0.0) m_audio.seek(diff);
+                       }
+               }
+       }
+}
+
+
+void ScreenSing::manageEvent(SDL_Event event) {
+       keyPressed = true;
+       double time = m_audio.getPosition();
+       int key = event.key.keysym.sym;
+       // Ctrl combinations that can be used while performing (not when score dialog is displayed)
+       if (event.type == SDL_KEYDOWN && (event.key.keysym.mod & KMOD_CTRL) && !m_score_window.get()) {
+               if (key == SDLK_s) m_audio.toggleSynth(m_song->getVocalTrack(m_selectedTrack).notes);
+               if (key == SDLK_v) m_audio.streamFade("vocals", event.key.keysym.mod & KMOD_SHIFT ? 1.0 : 0.0);
+               if (key == SDLK_k)  { // Toggle karaoke mode
+                       if(config["game/karaoke_mode"].i() >=2) config["game/karaoke_mode"].i() = 0;
+                       else ++config["game/karaoke_mode"];
+                       dispInFlash(config["game/karaoke_mode"]);
+               }
+               if (key == SDLK_w) dispInFlash(++config["game/pitch"]); // Toggle pitch wave
+               // Toggle webcam
+               if (key == SDLK_a && Webcam::enabled()) {
+                       // Initialize if we haven't done that already
+                       if (!m_cam) { try { m_cam.reset(new Webcam(config["graphic/webcamid"].i())); } catch (...) { }; }
+                       if (m_cam) { dispInFlash(++config["graphic/webcam"]); m_cam->pause(!config["graphic/webcam"].b()); }
+               }
+               // Latency settings
+               if (key == SDLK_F1) dispInFlash(--config["audio/video_delay"]);
+               if (key == SDLK_F2) dispInFlash(++config["audio/video_delay"]);
+               if (key == SDLK_F3) dispInFlash(--config["audio/round-trip"]);
+               if (key == SDLK_F4) dispInFlash(++config["audio/round-trip"]);
+               if (key == SDLK_F5) dispInFlash(--config["audio/controller_delay"]);
+               if (key == SDLK_F6) dispInFlash(++config["audio/controller_delay"]);
+               bool seekback = false;
+
+               if (m_song->danceTracks.empty()) { // Seeking backwards is currently not permitted for dance songs
+                       if (key == SDLK_HOME) { m_audio.seekPos(0.0); seekback = true; }
+                       if (key == SDLK_LEFT) {
+                               Song::SongSection section("error", 0);
+                               if (m_song->getPrevSection(m_audio.getPosition(), section)) {
+                                       m_audio.seekPos(section.begin);
+                                       // TODO: display popup with section.name here
+                                       std::cout << section.name << std::endl;
+                               } else m_audio.seek(-5.0);
+                               seekback = true;
+                       }
+               }
+               if (key == SDLK_RIGHT) {
+                       Song::SongSection section("error", 0);
+                       if (m_song->getNextSection(m_audio.getPosition(), section)) {
+                               m_audio.seekPos(section.begin);
+                               // TODO: display popup with section.name here
+                               std::cout << section.name << std::endl;
+                       } else m_audio.seek(5.0);
+               }
+
+               // Some things must be reset after seeking backwards
+               if (seekback)
+                       for (unsigned i = 0; i < m_layout_singer.size(); ++i)
+                               m_layout_singer[i].reset();
+               // Reload current song
+               if (key == SDLK_r) {
+                       exit(); m_song->reload(); enter();
+                       m_audio.seek(time);
+               }
+       }
+}
+
+namespace {
+       const double arMin = 1.33;
+       const double arMax = 2.35;
+
+       void fillBG() {
+               Dimensions dim(arMin);
+               dim.fixedWidth(1.0);
+               glutil::VertexArray va;
+               va.texCoord(0,0).vertex(dim.x1(), dim.y1());
+               va.texCoord(0,0).vertex(dim.x2(), dim.y1());
+               va.texCoord(0,0).vertex(dim.x1(), dim.y2());
+               va.texCoord(0,0).vertex(dim.x2(), dim.y2());
+               getShader("texture").bind();
+               va.draw();
+       }
+}
+
+void ScreenSing::prepare() {
+       Game* gm = Game::getSingletonPtr();
+       // Enable/disable controllers as needed (mostly so that keyboard navigation will not be obstructed).
+       gm->controllers.enableEvents(m_song->hasControllers() && !m_menu.isOpen() && !m_score_window.get());
+       double time = m_audio.getPosition();
+       if (m_video) m_video->prepare(time);
+       // Menu mangling
+       // We don't allow instrument menus during global menu
+       // except for joining, in which case global menu is closed
+       if (m_menu.isOpen()) {
+               for (auto& i: m_instruments) {
+                       if (i.joining(time)) m_menu.close(); else i.toggleMenu(0);
+               }
+       }
+}
+
+/// Test if a given device type can join the current song.
+// TODO: Somehow avoid duplicating these same checks in ScreenSing::prepare.
+bool ScreenSing::devCanParticipate(input::DevType const& devType) const {
+       if (devType == input::DEVTYPE_DANCEPAD && m_song->hasDance()) return true;
+       if (devType == input::DEVTYPE_GUITAR && m_song->hasGuitars()) return true;
+       if (devType == input::DEVTYPE_DRUMS && m_song->hasDrums()) return true;
+       return false;   
+}
+
+
+void ScreenSing::draw() {
+       // Get the time in the song
+       double length = m_audio.getLength();
+       double time = m_audio.getPosition();
+       time -= config["audio/video_delay"].f();
+       double songPercent = clamp(time / length);
+
+       // Rendering starts
+       {
+               Transform ft(farTransform());
+               double ar = arMax;
+               // Background image
+               if (!m_background || m_background->empty()) m_background.reset(new Surface(m_backgrounds.getRandom()));
+               ar = m_background->dimensions.ar();
+               if (ar > arMax || (m_video && ar > arMin)) fillBG();  // Fill white background to avoid black borders
+               m_background->draw();
+               // Webcam
+               if (m_cam && config["graphic/webcam"].b()) m_cam->render();
+               // Video
+               if (m_video) {
+                       m_video->render(time); double tmp = m_video->dimensions().ar(); if (tmp > 0.0) ar = tmp;
+               }
+               // Top/bottom borders
+               ar = clamp(ar, arMin, arMax);
+               double offset = 0.5 / ar + 0.2;
+               theme->bg_bottom.dimensions.fixedWidth(1.0).bottom(offset);
+               theme->bg_bottom.draw();
+               theme->bg_top.dimensions.fixedWidth(1.0).top(-offset);
+               theme->bg_top.draw();
+       }
+
+       for (unsigned i = 0; i < m_layout_singer.size(); ++i) m_layout_singer[i].hideLyrics(m_audio.isPaused());
+
+       instrumentLayout(time);
+
+       bool fullSinger = m_instruments.empty() && m_layout_singer.size() <= 1;
+       for (unsigned i = 0; i < m_layout_singer.size(); ++i) {
+               m_layout_singer[i].draw(time, fullSinger ? LayoutSinger::FULL : (i == 0 ? LayoutSinger::TOP : LayoutSinger::BOTTOM));
+       }
+
+       Song::Status status = m_song->status(time);
+
+       // Compute and draw the timer and the progressbar
+       {
+               unsigned t = clamp(time, 0.0, length);
+               m_progress->dimensions.fixedWidth(0.4).left(-0.5).screenTop();
+               theme->timer.dimensions.screenTop(0.5 * m_progress->dimensions.h());
+               theme->songinfo.dimensions.screenBottom(-0.01);
+               m_progress->draw(songPercent);
+
+               Song::SongSection section("error", 0);
+               std::string statustxt;
+               if (m_song->getPrevSection(t - 1.0, section)) {
+                       statustxt = (boost::format("%02u:%02u - %s") % (t / 60) % (t % 60) % section.name).str();
+               } else  statustxt = (boost::format("%02u:%02u") % (t / 60) % (t % 60)).str();
+
+               if (!m_score_window.get() && m_instruments.empty() && !m_layout_singer.empty()) {
+                       if (status == Song::INSTRUMENTAL_BREAK)  statustxt += _("   ENTER to skip instrumental break");
+                       if (status == Song::FINISHED && !config["game/karaoke_mode"].i()) {
+                               if(config["game/autoplay"].b()) {
+                                       if(m_displayAutoPlay) {
+                                               statustxt += _("   Autoplay enabled");
+                                       }
+                                       else {
+                                                statustxt += _("   Remember to wait for grading!");
+                                       }
+
+                                       if(m_statusTextSwitch.get() == 0) {
+                                       m_displayAutoPlay = !m_displayAutoPlay;
+                                       m_statusTextSwitch.setValue(1);
+                                       }
+                                       } else {
+                                       statustxt += _("   Remember to wait for grading!");
+                               }
+                       } else if(status == Song::FINISHED) {
+                               statustxt += _("   Autoplay enabled");
+                       }
+               }
+
+               theme->timer.draw(statustxt);
+       }
+
+       if (config["game/karaoke_mode"].i() && !m_song->hasControllers()) { //guitar track? display the score window anyway!
+               if (!m_audio.isPlaying()) {
+                       Game* gm = Game::getSingletonPtr();
+                       gm->activateScreen("Playlist");
+                       return;
+               }
+       } else {
+               if (m_score_window.get()) {
+                       // Score window has been created (we are near the end)
+                       if (m_score_window->empty()) {  // No players to display scores for
+                               if (!m_audio.isPlaying()) { activateNextScreen(); return; }
+                       } else {  // Window being displayed
+                               if (m_quitTimer.get() == 0.0 && !m_audio.isPaused()) { activateNextScreen(); return; }
+                               m_score_window->draw();
+                       }
+               }
+               else if (!m_audio.isPlaying() || (status == Song::FINISHED
+                 && m_audio.getLength() - time <= (m_song->instrumentTracks.empty() && m_song->danceTracks.empty() ? 3.0 : 0.2) )) {
+                       // Time to create the score window
+                       m_quitTimer.setValue(QUIT_TIMEOUT);
+                       if (m_engine) m_engine->kill(); // kill the engine thread (to avoid consuming memory)
+                       m_score_window.reset(new ScoreWindow(m_instruments, m_database));
+               }
+       }
+
+       // Menus on top of everything
+       for (auto& i: m_instruments) if (i.menuOpen()) i.drawMenu();
+       if (m_menu.isOpen()) drawMenu();
+       if(!keyPressed && m_DuetTimeout.get() == 0) {
+               m_menu.action();
+               }
+       std::string songinfo = m_song->artist + " - " + m_song->title;
+       theme->songinfo.draw(songinfo);
+}
+
+void ScreenSing::drawMenu() {
+       if (m_menu.empty()) return;
+       // Some helper vars
+       ThemeInstrumentMenu& th = *m_menuTheme;
+       auto cur = static_cast<MenuOptions::const_iterator>(&m_menu.current());
+       double w = m_menu.dimensions.w();
+       const float txth = th.option_selected.h();
+       const float step = txth * 0.85f;
+       const float h = m_menu.getOptions().size() * step + step;
+       float y = -h * .5f + step;
+       float x = -w * .5f + step;
+       // Background
+       th.bg.dimensions.middle(0).center(0).stretch(w, h);
+       th.bg.draw();
+       // Loop through menu items
+       w = 0;
+       int player = 0;
+       boost::ptr_vector<Analyzer>& analyzers = m_audio.analyzers();
+       for (MenuOptions::const_iterator it = m_menu.begin(); it != m_menu.end(); ++it) {
+               // Pick the font object
+               SvgTxtTheme* txt = &th.option_selected;
+               if (cur != it) txt = &(th.getCachedOption(it->getName()));
+               // Set dimensions and draw
+               txt->dimensions.middle(x).center(y);
+               txt->draw(it->getName());
+               if (it->value == &m_vocalTracks[player]) {
+                       Color color = MicrophoneColor::get(analyzers[player].getId());
+                       ColorTrans c(color);
+                       m_player_icon->dimensions.right(x).fixedHeight(0.040).center(y);
+                       m_player_icon->draw();
+                       player++;
+               }
+               w = std::max(w, txt->w() + 2 * step); // Calculate the widest entry
+               y += step;
+       }
+       if (cur->getComment() != "") {
+               th.comment.dimensions.middle(0).screenBottom(-0.12);
+               th.comment.draw(cur->getComment());
+       }
+       m_menu.dimensions.stretch(w, h);
+}
+
+
+ScoreWindow::ScoreWindow(Instruments& instruments, Database& database):
+  m_database(database),
+  m_pos(0.8, 2.0),
+  m_bg(findFile("score_window.svg")),
+  m_scoreBar(findFile("score_bar_bg.svg"), findFile("score_bar_fg.svg"), ProgressBar::VERTICAL, 0.0, 0.0, false),
+  m_score_text(findFile("score_txt.svg")),
+  m_score_rank(findFile("score_rank.svg"))
+{
+       Game::getSingletonPtr()->showLogo();
+       m_pos.setTarget(0.0);
+       m_database.scores.clear();
+       // Singers
+       for (auto p = m_database.cur.begin(); p != m_database.cur.end();) {
+               ScoreItem item; item.type = input::DEVTYPE_VOCALS;
+               item.score = p->getScore();
+               if (item.score < 500) { p = m_database.cur.erase(p); continue; } // Dead
+               item.track = "Vocals"; // For database
+               item.track_simple = "vocals"; // For ScoreWindow
+               item.color = Color(p->m_color.r, p->m_color.g, p->m_color.b);
+
+               m_database.scores.push_back(item);
+               ++p;
+       }
+       // Instruments
+       for (Instruments::iterator it = instruments.begin(); it != instruments.end();) {
+               ScoreItem item;
+               item.type = it->getGraphType();
+               item.score = it->getScore();
+               if (item.score < 100) { it = instruments.erase(it); continue; } // Dead
+               item.track_simple = it->getTrack();
+               item.track = it->getModeId();
+               item.track[0] = toupper(item.track[0]); // Capitalize
+               if (item.track_simple == TrackName::DRUMS) item.color = Color(0.1, 0.1, 0.1);
+               else if (item.track_simple == TrackName::BASS) item.color = Color(0.5, 0.3, 0.1);
+               else item.color = Color(1.0, 0.0, 0.0);
+
+               m_database.scores.push_back(item);
+               ++it;
+       }
+
+       if (m_database.scores.empty())
+               m_rank = _("No player!");
+       else {
+               // Determine winner
+               ScoreItem winner = *std::min_element(m_database.scores.begin(), m_database.scores.end());  // Note: best score comes first
+               int topScore = winner.score;
+               // Determine rank
+               if (winner.type == input::DEVTYPE_VOCALS) {
+                       if (topScore > 8000) m_rank = _("Hit singer");
+                       else if (topScore > 6000) m_rank = _("Lead singer");
+                       else if (topScore > 4000) m_rank = _("Rising star");
+                       else if (topScore > 2000) m_rank = _("Amateur");
+                       else m_rank = _("Tone deaf");
+               } else if (winner.type == input::DEVTYPE_DANCEPAD) {
+                       if (topScore > 8000) m_rank = _("Maniac");
+                       else if (topScore > 6000) m_rank = _("Hoofer");
+                       else if (topScore > 4000) m_rank = _("Rising star");
+                       else if (topScore > 2000) m_rank = _("Amateur");
+                       else m_rank = _("Loser");
+               } else {
+                       if (topScore > 8000) m_rank = _("Virtuoso");
+                       else if (topScore > 6000) m_rank = _("Rocker");
+                       else if (topScore > 4000) m_rank = _("Rising star");
+                       else if (topScore > 2000) m_rank = _("Amateur");
+                       else m_rank = _("Tone deaf");
+               }
+       }
+       m_bg.dimensions.middle().center();
+}
+
+void ScoreWindow::draw() {
+       using namespace glmath;
+       Transform trans(translate(vec3(0.0, m_pos.get(), 0.0)));
+       m_bg.draw();
+       const double spacing = 0.1 + 0.1 / m_database.scores.size();
+       unsigned i = 0;
+
+       for (Database::cur_scores_t::const_iterator p = m_database.scores.begin(); p != m_database.scores.end(); ++p, ++i) {
+               int score = p->score;
+               ColorTrans c(p->color);
+               double x = -0.12 + spacing * (0.5 + i - 0.5 * m_database.scores.size());
+               m_scoreBar.dimensions.fixedWidth(0.09).middle(x).bottom(0.20);
+               m_scoreBar.draw(score / 10000.0);
+               m_score_text.render(boost::lexical_cast<std::string>(score));
+               m_score_text.dimensions().middle(x).top(0.24).fixedHeight(0.042);
+               m_score_text.draw();
+               m_score_text.render(p->track_simple);
+               m_score_text.dimensions().middle(x).top(0.20).fixedHeight(0.042);
+               m_score_text.draw();
+       }
+       m_score_rank.draw(m_rank);
+}
+
+bool ScoreWindow::empty() {
+       return m_database.scores.empty();
+}
diff --git a/game/screen_sing.hh b/game/screen_sing.hh
new file mode 100644 (file)
index 0000000..7c65c2c
--- /dev/null
@@ -0,0 +1,110 @@
+#pragma once
+
+#include "animvalue.hh"
+#include "audio.hh" // for AUDIO_MAX_ANALYZERS
+#include "configuration.hh"
+#include "menu.hh"
+#include "opengl_text.hh"
+#include "progressbar.hh"
+#include "screen.hh"
+#include "surface.hh"
+
+#include <boost/ptr_container/ptr_vector.hpp>
+#include <boost/scoped_ptr.hpp>
+#include <deque>
+
+class Audio;
+class Backgrounds;
+class Database;
+class Engine;
+class InstrumentGraph;
+class LayoutSinger;
+class Players;
+class Song;
+class ThemeInstrumentMenu;
+class ThemeSing;
+class Video;
+class Webcam;
+
+typedef boost::ptr_vector<InstrumentGraph> Instruments;
+
+/// shows score at end of song
+class ScoreWindow {
+  public:
+       /// constructor
+       ScoreWindow(Instruments& instruments, Database& database);
+       /// draws ScoreWindow
+       void draw();
+       bool empty();
+  private:
+       Database& m_database;
+       AnimValue m_pos;
+       Surface m_bg;
+       ProgressBar m_scoreBar;
+       SvgTxtThemeSimple m_score_text;
+       SvgTxtTheme m_score_rank;
+       std::string m_rank;
+};
+
+/// class for actual singing screen
+class ScreenSing: public Screen {
+  public:
+       /// constructor
+       ScreenSing(std::string const& name, Audio& audio, Database& database, Backgrounds& bgs);
+       void enter();
+       void exit();
+       void reloadGL();
+       void manageEvent(SDL_Event event);
+       void manageEvent(input::NavEvent const& event);
+       void prepare();
+       void draw();
+
+       void setupVocals();
+
+       void setSong (boost::shared_ptr<Song> song_)
+       {
+               m_song = song_;
+       }
+
+  private:
+       /**Activates Songs Screen or Players Screen.
+         This depends on
+         - the configuration (is Hiscore enabled)
+         - did a player reach a new hiscore
+         - is the hiscore file writable
+         */
+       void activateNextScreen();
+       void instrumentLayout(double time);
+       void createPauseMenu();
+       void drawMenu();
+       bool devCanParticipate(input::DevType const& devType) const;
+       Audio& m_audio;
+       Database& m_database;
+       Backgrounds& m_backgrounds;
+       boost::shared_ptr<Song> m_song; /// Pointer to the current song
+       boost::scoped_ptr<ScoreWindow> m_score_window;
+       boost::scoped_ptr<ProgressBar> m_progress;
+       boost::scoped_ptr<Surface> m_background;
+       boost::scoped_ptr<Video> m_video;
+       boost::scoped_ptr<Webcam> m_cam;
+       boost::scoped_ptr<Surface> m_pause_icon;
+       boost::scoped_ptr<Surface> m_player_icon;
+       boost::scoped_ptr<Surface> m_help;
+       boost::scoped_ptr<Engine> m_engine;
+       boost::ptr_vector<LayoutSinger> m_layout_singer;
+       boost::scoped_ptr<ThemeInstrumentMenu> m_menuTheme;
+       Menu m_menu;
+       Instruments m_instruments;
+       boost::shared_ptr<ThemeSing> theme;
+       AnimValue m_quitTimer;
+       AnimValue m_statusTextSwitch;
+       AnimValue m_DuetTimeout;
+       std::string m_selectedTrack;
+       std::string m_selectedTrackLocalized;
+       ConfigItem m_vocalTracks[AUDIO_MAX_ANALYZERS];
+       ConfigItem m_duet;
+       bool m_displayAutoPlay = false;
+       bool m_fadeIn = false;
+       bool keyPressed = false;
+};
+
diff --git a/game/screen_songs.cc b/game/screen_songs.cc
new file mode 100644 (file)
index 0000000..481100b
--- /dev/null
@@ -0,0 +1,536 @@
+#include "screen_songs.hh"
+
+#include "audio.hh"
+#include "configuration.hh"
+#include "database.hh"
+#include "hiscore.hh"
+#include "i18n.hh"
+#include "screen_sing.hh"
+#include "screen_playlist.hh"
+#include "songs.hh"
+#include "theme.hh"
+#include "util.hh"
+#include "playlist.hh"
+#include <iostream>
+#include <sstream>
+#include <boost/format.hpp>
+
+static const double IDLE_TIMEOUT = 45.0; // seconds
+
+ScreenSongs::ScreenSongs(std::string const& name, Audio& audio, Songs& songs, Database& database):
+  Screen(name), m_audio(audio), m_songs(songs), m_database(database), m_covers(50)
+{
+       m_songs.setAnimMargins(5.0, 5.0);
+       // Using AnimValues as a simple timers counting seconds
+       m_clock.setTarget(getInf());
+       m_idleTimer.setTarget(getInf());
+}
+
+void ScreenSongs::enter() {
+       m_menu.close();
+       m_songs.setFilter(m_search.text);
+       m_audio.fadeout();
+       m_menuPos = 1;
+       m_infoPos = 0;
+       m_jukebox = false;
+       reloadGL();
+}
+
+void ScreenSongs::reloadGL() {
+       theme.reset(new ThemeSongs());
+       m_menuTheme.reset(new ThemeInstrumentMenu());
+       m_songbg_default.reset(new Surface(findFile("songs_bg_default.svg")));
+       m_songbg_ground.reset(new Surface(findFile("songs_bg_ground.svg")));
+       m_singCover.reset(new Surface(findFile("no_cover.svg")));
+       m_instrumentCover.reset(new Surface(findFile("instrument_cover.svg")));
+       m_bandCover.reset(new Surface(findFile("band_cover.svg")));
+       m_danceCover.reset(new Surface(findFile("dance_cover.svg")));
+       m_instrumentList.reset(new Texture(findFile("instruments.svg")));
+}
+
+void ScreenSongs::exit() {
+       m_covers.clear();
+       m_menu.clear();
+       m_menuTheme.reset();
+       m_singCover.reset();
+       m_instrumentCover.reset();
+       m_danceCover.reset();
+       m_bandCover.reset();
+       m_instrumentList.reset();
+       theme.reset();
+       m_video.reset();
+       m_songbg.reset();
+       m_songbg_default.reset();
+       m_songbg_ground.reset();
+       m_playing.clear();
+}
+
+/// Implement left/right on menu
+void ScreenSongs::menuBrowse(int dir) {
+       switch (m_menuPos) {
+               case 4: m_infoPos = (m_infoPos + dir + 5) % 5; break;
+               case 3: m_songs.typeChange(dir); break;
+               case 2: m_songs.sortChange(dir); break;
+               case 1: m_songs.advance(dir); break;
+               case 0: /* no function on playlist yet */ break;
+       }
+}
+
+void ScreenSongs::manageEvent(input::NavEvent const& event) {
+       Game* gm = Game::getSingletonPtr();
+       input::NavButton nav = event.button;
+       // Handle basic navigational input that is possible also with instruments
+       m_idleTimer.setValue(0.0);  // Reset idle timer
+       if (nav == input::NAV_PAUSE) m_audio.togglePause();
+       else if (event.menu == input::NAVMENU_A_PREV) {
+               if (m_menu.isOpen()) m_menu.move(-1);
+               else menuBrowse(-1);
+       }
+       else if (event.menu == input::NAVMENU_A_NEXT) {
+               if (m_menu.isOpen()) m_menu.move(1);
+               else menuBrowse(1);
+       }
+       else if (nav == input::NAV_MOREUP) m_songs.advance(-10);
+       else if (nav == input::NAV_MOREDOWN) m_songs.advance(10);
+       else if (m_jukebox) {
+               if (nav == input::NAV_CANCEL) m_jukebox = false;
+               else if (nav == input::NAV_START) { addSong(); sing(); }
+               else if (event.menu == input::NAVMENU_B_NEXT)  m_audio.seek(-5);
+               else if (event.menu == input::NAVMENU_B_PREV) m_audio.seek(5);
+               else if (nav == input::NAV_MOREUP) m_audio.seek(-30);
+               else if (nav == input::NAV_MOREDOWN) m_audio.seek(30);
+       } else if (nav == input::NAV_CANCEL) {
+               if (m_menuPos != 1) m_menuPos = 1;  // Exit menu (back to song selection)
+               else if (!m_search.text.empty()) { m_search.text.clear(); m_songs.setFilter(m_search.text); }  // Clear search
+               else if (m_songs.typeNum()) m_songs.typeChange(0);  // Clear type filter
+               else gm->activateScreen("Intro");
+       }
+       // The rest are only available when there are songs available
+       else if (m_songs.empty()) return;
+       else if (nav == input::NAV_START) {
+               if (m_menu.isOpen()) {
+                       m_menu.action();
+               }
+               else if (m_menuPos == 1 /* Cover browser */) {
+                       if (addSong()) sing();  // Add song and sing if it was the first to be added
+               }
+               else if (m_menuPos == 4) {
+                       m_menuPos = 1;
+                       m_jukebox = true;
+               }
+               else if (m_menuPos == 0 /* Playlist */) {
+                       if (gm->getCurrentPlayList().isEmpty()) {
+                               m_menuPos = 1;
+                               addSong();
+                       } else {
+                               createPlaylistMenu();
+                               m_menu.open();
+                       }
+               }
+       }
+       else if (event.menu == input::NAVMENU_B_PREV) {
+               if (m_menu.isOpen()) m_menu.move(-1);
+               else if (m_menuPos < 4) ++m_menuPos;
+       }
+       else if (event.menu == input::NAVMENU_B_NEXT) {
+               if (m_menu.isOpen()) m_menu.move(1);
+               else if (m_menuPos > 0) --m_menuPos;
+       }
+}
+
+void ScreenSongs::manageEvent(SDL_Event event) {
+       // Handle less common, keyboard only keys
+       if (event.type == SDL_TEXTINPUT) {
+               m_search += event.text.text;
+               m_songs.setFilter(m_search.text);
+       }
+       else if (event.type == SDL_KEYDOWN) {
+               SDL_Keysym keysym = event.key.keysym;
+               int key = keysym.sym;
+               uint16_t mod = event.key.keysym.mod;
+               if (key == SDLK_F4) m_jukebox = !m_jukebox;
+               else if (key == SDLK_BACKSPACE) {
+                       m_search.backspace();
+                       m_songs.setFilter(m_search.text);
+               }
+               else if (!m_jukebox) {
+                       if (key == SDLK_r && mod & KMOD_CTRL) {
+                               m_songs.reload();
+                               m_songs.setFilter(m_search.text);
+                               }
+                       // Shortcut keys for accessing different type filter modes
+                       if (key == SDLK_TAB) m_songs.sortChange(1);
+                       if (key == SDLK_F5) m_songs.typeCycle(2);
+                       if (key == SDLK_F6) m_songs.typeCycle(3);
+                       if (key == SDLK_F7) m_songs.typeCycle(4);
+                       if (key == SDLK_F8) m_songs.typeCycle(1);
+               }
+       }
+       if (m_songs.empty()) m_jukebox = false;
+}
+
+void ScreenSongs::update() {
+       Game* sm = Game::getSingletonPtr();
+       sm->showLogo(!m_jukebox);
+       if (m_idleTimer.get() < 0.3) return;  // Only update when the user gives us a break
+       m_songs.update(); // Poll for new songs
+       bool songChange = false;  // Do we need to switch songs?
+       // Automatic song browsing
+       if (!m_audio.isPaused() && m_idleTimer.get() > 1.0) {
+               // If playback has ended or hasn't started
+               if (!m_audio.isPlaying() || m_audio.getPosition() > m_audio.getLength()) {
+                       songChange = true;  // Force reload even if the music happens to stay the same
+               }
+               // If the above, or if in regular mode and idle too long, advance to next song
+               if (songChange || (!m_jukebox && m_idleTimer.get() > IDLE_TIMEOUT)) {
+                       m_songs.advance(1);
+                       m_idleTimer.setValue(0.0);
+               }
+       }
+       // Check out if the music has changed
+       boost::shared_ptr<Song> song = m_songs.currentPtr();
+       Song::Music music;
+       if (song) music = song->music;
+       if (m_playing != music) songChange = true;
+       // Switch songs if needed, only when the user is not browsing for a moment
+       if (!songChange) return;
+       if (song) song->loadNotes();  // Needed for BPM info; TODO: drop notes when switching to another song.
+       m_playing = music;
+       // Clear the old content and load new content if available
+       m_songbg.reset(); m_video.reset();
+       double pstart = (!m_jukebox && song ? song->preview_start : 0.0);
+       m_audio.playMusic(music, true, 2.0, pstart);
+       if (song) {
+               fs::path const& background = song->background.empty() ? song->cover : song->background;
+               if (!background.empty()) try { m_songbg.reset(new Surface(background)); } catch (std::exception const&) {}
+               if (!song->video.empty() && config["graphic/video"].b()) m_video.reset(new Video(song->video, song->videoGap));
+       }
+}
+
+bool ScreenSongs::addSong() {
+       Game* gm = Game::getSingletonPtr();
+       auto& pl = gm->getCurrentPlayList();
+       bool empty = pl.getList().empty();
+       pl.addSong(m_songs.currentPtr());
+       return empty;
+}
+
+void ScreenSongs::sing() {
+       Game* gm = Game::getSingletonPtr();
+       ScreenSing& ss = dynamic_cast<ScreenSing&>(*gm->getScreen("Sing"));
+       ss.setSong(gm->getCurrentPlayList().getNext());
+       gm->activateScreen("Sing");
+}
+
+void ScreenSongs::prepare() {
+       double time = m_audio.getPosition() - config["audio/video_delay"].f();
+       if (m_video) m_video->prepare(time);
+}
+
+void ScreenSongs::drawJukebox() {
+       double pos = m_audio.getPosition();
+       double len = m_audio.getLength();
+       double diff = len - pos;
+       if (pos < diff) diff = pos;  // Diff from beginning instead of from end
+       if (!m_songbg.get() && !m_video.get()) diff = 0.0;  // Always display song name if there is no background
+       if (diff < 3.0) {
+               Song& song = m_songs.current();
+               // Draw the cover
+               Surface* cover = NULL;
+               if (!song.cover.empty()) try { cover = &m_covers[song.cover]; } catch (std::exception const&) {}
+               if (cover && !cover->empty()) {
+                       Surface& s = *cover;
+                       s.dimensions.left(theme->song.dimensions.x1()).top(theme->song.dimensions.y2() + 0.05).fitInside(0.15, 0.15);
+                       s.draw();
+               }
+               // Format && draw the song information text
+               std::ostringstream oss_song;
+               oss_song << song.title << '\n' << song.artist;
+               theme->song.draw(oss_song.str());
+       }
+}
+
+void ScreenSongs::drawMultimedia() {
+       if (!m_songs.empty()) {
+               Transform ft(farTransform());  // 3D effect
+               double length = m_audio.getLength();
+               double time = clamp(m_audio.getPosition() - config["audio/video_delay"].f(), 0.0, length);
+               m_songbg_default->draw();   // Default bg
+               if (m_songbg.get() && !m_video.get()) {
+                       if (m_songbg->width() > 512 && m_songbg->dimensions.ar() > 1.1) {
+                               // Full screen mode
+                               float s = sin(m_clock.get()) * 0.15 + 1.15;
+                               Transform sc(scale(glmath::vec3(s, s, s)));
+                               m_songbg->draw();
+                       } else {
+                               // Low res texture or cover image, render in tiled mode
+                               double x = 0.05 * m_clock.get();
+                               m_songbg->draw(m_songbg->dimensions, TexCoords(x, 0.0, x + 5.0, 5.0));
+                       }
+               }
+               if (m_video.get()) m_video->render(time);
+       }
+       if (!m_jukebox) {
+               m_songbg_ground->draw();
+               theme->bg.draw();
+               drawCovers();
+       }
+}
+
+void ScreenSongs::draw() {
+       update();
+       drawMultimedia();
+       std::ostringstream oss_song, oss_order, oss_hiscore;
+       // Test if there are no songs
+       if (m_songs.empty()) {
+               // Format the song information text
+               if (!m_search.text.empty()) {
+                       oss_song << _("Sorry, no songs match the search!");
+                       oss_order << m_search.text;
+               } else if (m_songs.typeNum()) {
+                       oss_song << _("Sorry, no songs match the filter!");
+                       oss_order << m_songs.typeDesc();
+               } else {
+                       oss_song << _("No songs found!");
+                       oss_order << _("Visit performous.org for free songs");
+               }
+       } else {
+               Song& song = m_songs.current();
+               // Format the song information text
+               oss_song << song.artist << ": " << song.title;
+               // Get hiscores from database
+               m_database.queryPerSongHiscore(oss_hiscore, m_songs.currentPtr());
+               // Escaped bytes of UTF-8 must be used here for compatibility with Windows (MSVC, mingw)
+               char const* VERT_ARROW = "\xe2\x86\x95 ";  // ↕
+               char const* HORIZ_ARROW = "\xe2\x86\x94 ";  // ↔
+               char const* ENTER = "\xe2\x86\xb5 ";  // ↵
+               char const* PAD = "   ";
+               switch (m_menuPos) {
+               case 1:
+                       if (!m_search.text.empty()) oss_order << m_search.text;
+                       else if (m_songs.typeNum()) oss_order << m_songs.typeDesc();
+                       else if (m_songs.sortNum()) oss_order << m_songs.sortDesc();
+                       else oss_order << _("<type in to search>") << PAD << HORIZ_ARROW << _("songs") << PAD << VERT_ARROW << _("options");
+                       break;
+               case 2: oss_order << HORIZ_ARROW << _("sort order: ") << m_songs.sortDesc(); break;
+               case 3: oss_order << HORIZ_ARROW << _("type filter: ") << m_songs.typeDesc(); break;
+               case 4: oss_order << HORIZ_ARROW << _("hiscores") << PAD << ENTER << _("jukebox mode"); break;
+               case 0:
+                       bool empty = Game::getSingletonPtr()->getCurrentPlayList().isEmpty();
+                       oss_order << ENTER << (empty ? _("start a playlist with this song!") : _("open the playlist menu"));
+                       break;
+               }
+       }
+
+       if (m_jukebox) drawJukebox();
+       else {
+               // Draw song and order texts
+               theme->song.draw(oss_song.str());
+               theme->order.draw(oss_order.str());
+               drawInstruments(Dimensions(1.0).fixedHeight(0.09).right(0.45).screenTop(0.02));
+               theme->hiscores.draw(oss_hiscore.str());
+       }
+       // Menus on top of everything
+       if (m_menu.isOpen()) drawMenu();
+}
+
+void ScreenSongs::drawCovers() {
+       double spos = m_songs.currentPosition(); // This needs to be polled to run the animation
+       std::size_t ss = m_songs.size();
+       int currentId = m_songs.currentId();
+       int baseidx = spos + 1.5; --baseidx; // Round correctly
+       double shift = spos - baseidx;
+       // Calculate beat
+       double beat = 0.5 + m_idleTimer.get() / 2.0;  // 30 BPM
+       if (ss > 0) {
+               // Use actual song BPM. FIXME: Should only do this if currentId is also playing.
+               double t = m_audio.getPosition() - config["audio/video_delay"].f();
+               Song::Beats const& beats = m_songs.current().beats;
+               auto it = std::lower_bound(beats.begin(), beats.end(), t);
+               if (it != beats.begin() && it != beats.end()) {
+                       double t1 = *(it - 1), t2 = *it;
+                       beat = (t - t1) / (t2 - t1);
+               }
+       }
+       beat = 1.0 + std::pow(std::abs(std::cos(3.141592 * beat)), 10.0);  // Overdrive pulse
+       // Draw covers and reflections
+       for (int i = -2; i < 6; ++i) {
+               if (baseidx + i < 0 || baseidx + i >= int(ss)) continue;
+               Song& song = *m_songs[baseidx + i];
+               Surface& s = getCover(song);
+               // Calculate dimensions for cover and instrument markers
+               double diff = 0.5 * (1.0 + std::cos(std::min(M_PI, std::abs(i - shift))));  // 0..1 for current cover hilight level
+               double y = 0.5 * virtH();
+               using namespace glmath;
+               Transform trans(
+                 translate(vec3(-0.2 + 0.20 * (i - shift), y, -0.2 - 0.3 * (1.0 - diff)))
+                 * rotate(0.4 * std::sin(std::min(M_PI, i - shift)), vec3(0.0, 1.0, 0.0))
+               );
+               double c = 0.4 + 0.6 * diff;
+               if (m_menuPos == 1 /* Cover browser */ && baseidx + i == currentId) c = beat;
+               ColorTrans c1(Color(c, c, c));
+               s.dimensions.middle().screenCenter().bottom().fitInside(0.17, 0.17);
+               // Draw the cover normally
+               s.draw();
+               // Draw the reflection
+               Transform transMirror(scale(vec3(1.0f, -1.0f, 1.0f)));
+               ColorTrans c2(Color::alpha(0.4));
+               s.draw();
+       }
+       // Draw the playlist
+    Game* gm = Game::getSingletonPtr();
+       auto const& playlist = gm->getCurrentPlayList().getList();
+       double c = (m_menuPos == 0 /* Playlist */ ? beat : 1.0);
+       ColorTrans c1(Color(c, c, c));
+       for (unsigned i = playlist.size() - 1; i < playlist.size(); --i) {
+               Surface& s = getCover(*playlist[i]);
+               double pos =  i / std::max<double>(5.0, playlist.size());
+               using namespace glmath;
+               Transform trans(
+                 translate(vec3(-0.35 + 0.06 * pos, 0.0, 0.3 - 0.2 * pos))
+                 * rotate(-0.0, vec3(0.0, 1.0, 0.0))
+               );
+               s.dimensions.middle().screenBottom(-0.06).fitInside(0.08, 0.08);
+               s.draw();
+       }
+}
+
+Surface& ScreenSongs::getCover(Song const& song) {
+       Surface* cover = nullptr;
+       // Fetch cover image from cache or try loading it
+       if (!song.cover.empty()) try { cover = &m_covers[song.cover]; } catch (std::exception const&) {}
+       // Fallback to background image as cover if needed
+       if (!cover && !song.background.empty()) try { cover = &m_covers[song.background]; } catch (std::exception const&) {}
+       // Use empty cover
+       if (!cover) {
+               if(song.hasDance()) {
+                       cover = m_danceCover.get();
+               } else if(song.hasDrums()) {
+                       cover = m_bandCover.get();
+               } else {
+                       size_t tracks = song.instrumentTracks.size();
+                       if (tracks == 0) cover = m_singCover.get();
+                       else cover = m_instrumentCover.get();
+               }
+       }
+       return *cover;
+}
+
+namespace {
+       float getIconTex(int i) {
+               static int iconcount = 8;
+               return (i-1)/float(iconcount);
+       }
+       void drawIcon(int i, Dimensions const& dim) {
+               glutil::VertexArray va;
+               va.texCoord(getIconTex(i), 0.0f).vertex(dim.x1(), dim.y1());
+               va.texCoord(getIconTex(i), 1.0f).vertex(dim.x1(), dim.y2());
+               va.texCoord(getIconTex(i + 1), 0.0f).vertex(dim.x2(), dim.y1());
+               va.texCoord(getIconTex(i + 1), 1.0f).vertex(dim.x2(), dim.y2());
+               va.draw();
+       }
+}
+
+void ScreenSongs::drawInstruments(Dimensions dim) const {
+       bool have_bass = false;
+       bool have_drums = false;
+       bool have_dance = false;
+       // TODO: Do something with is_karaoke
+       //bool is_karaoke = false;
+       int guitarCount = 0;
+       int vocalCount = 0;
+       if( !m_songs.empty() ) {
+               Song const& song = m_songs.current();
+               have_drums = song.hasDrums();
+               have_dance = song.hasDance();
+               //is_karaoke = (song.music.find("vocals") != song.music.end());
+               vocalCount = song.getVocalTrackNames().size();
+               if (isTrackInside(song.instrumentTracks,TrackName::GUITAR)) guitarCount++;
+               if (isTrackInside(song.instrumentTracks,TrackName::GUITAR_COOP)) guitarCount++;
+               if (isTrackInside(song.instrumentTracks,TrackName::GUITAR_RHYTHM)) guitarCount++;
+               if (isTrackInside(song.instrumentTracks,TrackName::BASS)) { guitarCount++; have_bass = true; }
+       }
+
+       UseTexture tex(*m_instrumentList);
+       double x = dim.x1();
+       // dancing
+       if (have_dance) {
+               drawIcon(6, dim.left(x));
+               x -= dim.w();
+       }
+       // drums
+       if (have_drums) {
+               drawIcon(4, dim.left(x));
+               x -= dim.w();
+       }
+       // guitars & bass
+       for (int i = guitarCount-1; i >= 0; i--) {
+               drawIcon(i == 0 && have_bass ? 3 : 2, dim.left(x));
+               x -= (i > 0 ? 0.3 : 1.0) * dim.w();
+       }
+       for (int i = vocalCount-1; i >= 0; i--) {
+               drawIcon(1, dim.left(x));
+               x -= (i > 0 ? 0.3 : 1.0) * dim.w();
+       }
+}
+
+void ScreenSongs::drawMenu() {
+       if (m_menu.empty()) return;
+       // Some helper vars
+       ThemeInstrumentMenu& th = *m_menuTheme;
+       auto cur = static_cast<MenuOptions::const_iterator>(&m_menu.current());
+       double w = m_menu.dimensions.w();
+       const float txth = th.option_selected.h();
+       const float step = txth * 0.85f;
+       const float h = m_menu.getOptions().size() * step + step;
+       float y = -h * .5f + step;
+       float x = -w * .5f + step;
+       // Background
+       th.bg.dimensions.middle(0).center(0).stretch(w, h);
+       th.bg.draw();
+       // Loop through menu items
+       w = 0;
+       for (MenuOptions::const_iterator it = m_menu.begin(); it != m_menu.end(); ++it) {
+               // Pick the font object
+               SvgTxtTheme* txt = &th.option_selected;
+               if (cur != it) txt = &(th.getCachedOption(it->getName()));
+               // Set dimensions and draw
+               txt->dimensions.middle(x).center(y);
+               txt->draw(it->getName());
+               w = std::max(w, txt->w() + 2 * step); // Calculate the widest entry
+               y += step;
+       }
+       if (cur->getComment() != "") {
+               th.comment.dimensions.middle(0).screenBottom(-0.12);
+               th.comment.draw(cur->getComment());
+       }
+       m_menu.dimensions.stretch(w, h);
+}
+
+void ScreenSongs::createPlaylistMenu() {
+       m_menu.clear();
+       m_menu.add(MenuOption(_("Play"), "").call([this]() {
+               Game* tm = Game::getSingletonPtr();
+               tm->getCurrentPlayList().addSong(m_songs.currentPtr());
+               m_menuPos = 1;
+               m_menu.close();
+               sing();
+       }));
+       m_menu.add(MenuOption(_("Shuffle"), "").call([this]() {
+               Game* tm = Game::getSingletonPtr();
+               tm->getCurrentPlayList().shuffle();
+               m_menuPos = 1;
+               m_menu.close();
+       }));
+       m_menu.add(MenuOption(_("View playlist"), "").screen("Playlist"));
+       m_menu.add(MenuOption(_("Clear playlist"), "").call([this]() {
+               Game* tm = Game::getSingletonPtr();
+               tm->getCurrentPlayList().clear();
+               m_menuPos = 1;
+               m_menu.close();
+       }));
+       m_menu.add(MenuOption(_("Back"), "").call([this]() {
+               m_menuPos = 1;
+               m_menu.close();
+       }));
+}
diff --git a/game/screen_songs.hh b/game/screen_songs.hh
new file mode 100644 (file)
index 0000000..72a3d0c
--- /dev/null
@@ -0,0 +1,75 @@
+#pragma once
+
+#include "animvalue.hh"
+#include "cachemap.hh"
+#include "controllers.hh"
+#include "screen.hh"
+#include "song.hh" // for Music class
+#include "textinput.hh"
+#include "video.hh"
+#include "playlist.hh"
+#include "menu.hh"
+
+#include <boost/scoped_ptr.hpp>
+
+
+class Audio;
+class Database;
+class Song;
+class Songs;
+class Surface;
+class ThemeSongs;
+
+class Backgrounds;
+class ThemeInstrumentMenu;
+
+/// song chooser screen
+class ScreenSongs : public Screen {
+public:
+       /// constructor
+       ScreenSongs(std::string const& name, Audio& audio, Songs& songs, Database& database);
+       void enter();
+       void exit();
+       void reloadGL();
+       void menuBrowse(int dir); ///< Left/Right on menu options
+       void manageEvent(SDL_Event event);
+       void manageEvent(input::NavEvent const& event);
+       void prepare();
+       void draw();
+       void drawCovers(); ///< draw the cover browser
+       Surface& getCover(Song const& song); ///< get appropriate cover image for the song (incl. no cover)
+       void drawJukebox(); ///< draw the songbrowser in jukebox mode (fullscreen, full previews, ...)
+
+private:
+       void manageSharedKey(input::NavEvent const& event); ///< same behaviour for jukebox and normal mode
+       void drawInstruments(Dimensions dim) const;
+       void drawMultimedia();
+       void update();
+       void drawMenu();
+       bool addSong(); ///< Add current song to playlist. Returns true if the playlist was empty.
+       void sing(); ///< Enter singing screen with current playlist.
+       void createPlaylistMenu();
+
+       Audio& m_audio;
+       Songs& m_songs;
+       Database& m_database;
+       boost::scoped_ptr<Surface> m_songbg, m_songbg_ground, m_songbg_default;
+       boost::scoped_ptr<Video> m_video;
+       boost::scoped_ptr<ThemeSongs> theme;
+       Song::Music m_playing;
+       AnimValue m_clock;
+       AnimValue m_idleTimer;
+       TextInput m_search;
+       boost::scoped_ptr<Surface> m_singCover;
+       boost::scoped_ptr<Surface> m_instrumentCover;
+       boost::scoped_ptr<Surface> m_bandCover;
+       boost::scoped_ptr<Surface> m_danceCover;
+       boost::scoped_ptr<Texture> m_instrumentList;
+       boost::scoped_ptr<ThemeInstrumentMenu> m_menuTheme;
+       Cachemap<fs::path, Surface> m_covers;
+       int m_menuPos, m_infoPos;
+       bool m_jukebox;
+       bool show_hiscores;
+       int hiscore_start_pos;
+       Menu m_menu;
+};
diff --git a/game/singleton.hh b/game/singleton.hh
new file mode 100644 (file)
index 0000000..d051eb2
--- /dev/null
@@ -0,0 +1,16 @@
+#pragma once
+
+/// template for creating singletons
+template <class T> class Singleton {
+  protected:
+       /// pointer to object
+       static T* ms_Singleton;
+
+  public:
+       Singleton() { ms_Singleton = static_cast<T*>(this); }
+       ~Singleton() { ms_Singleton = 0; }
+       /// gets reference to singleton object
+       inline static T& getSingleton() { return *ms_Singleton; }
+       /// gets pointer to singleton object
+       inline static T* getSingletonPtr() { return ms_Singleton; }
+};
diff --git a/game/song.cc b/game/song.cc
new file mode 100644 (file)
index 0000000..75245c7
--- /dev/null
@@ -0,0 +1,104 @@
+#include "song.hh"
+
+#include "songparser.hh"
+#include "util.hh"
+#include <limits>
+#include <algorithm>
+
+void Song::reload(bool errorIgnore) {
+       loadStatus = NONE;
+       vocalTracks.clear();
+       instrumentTracks.clear();
+       beats.clear();
+       midifilename.clear();
+       category.clear();
+       genre.clear();
+       edition.clear();
+       title.clear();
+       artist.clear();
+       collateByTitle.clear();
+       collateByTitleOnly.clear();
+       collateByArtist.clear();
+       collateByArtistOnly.clear();
+       text.clear();
+       creator.clear();
+       music.clear();
+       cover.clear();
+       background.clear();
+       video.clear();
+       videoGap = 0.0;
+       start = 0.0;
+       preview_start = getNaN();
+       hasBRE = false;
+       b0rked.clear();
+       try { SongParser(*this); } catch (...) { if (!errorIgnore) throw; }
+       collateUpdate();
+}
+
+void Song::loadNotes(bool errorIgnore) {
+       if (loadStatus == Song::FULL) return;
+       try { SongParser(*this); } catch (...) { if (!errorIgnore) throw; }
+}
+
+void Song::dropNotes() {
+       for (auto& trk: vocalTracks) trk.second.notes.clear();
+       for (auto& trk: instrumentTracks) trk.second.nm.clear();
+       for (auto& trk: danceTracks) trk.second.clear();
+       b0rked.clear();
+       loadStatus = HEADER;
+}
+
+void Song::collateUpdate() {
+       collateByTitle = collate(title + artist) + '\0' + filename.string();
+       collateByTitleOnly = collate(title);
+       collateByArtist = collate(artist + title) + '\0' + filename.string();
+       collateByArtistOnly = collate(artist);
+}
+
+std::string Song::collate(std::string const& str) {
+       return unicodeCollate(str);
+}
+
+namespace {
+       // Cannot simply take double as its second argument because of a C++ defect
+       bool noteEndLessThan(Note const& a, Note const& b) { return a.end < b.end; }
+}
+
+Song::Status Song::status(double time) {
+       Note target; target.end = time;
+       Notes::const_iterator it = std::lower_bound(getVocalTrack().notes.begin(), getVocalTrack().notes.end(), target, noteEndLessThan);
+       if (it == getVocalTrack().notes.end()) return FINISHED;
+       if (it->begin > time + 4.0) return INSTRUMENTAL_BREAK;
+       return NORMAL;
+}
+
+bool Song::getNextSection(double pos, SongSection &section) {
+       for (auto& sect: songsections) {
+               if (sect.begin > pos) {
+                       section = sect;
+                       return true;
+               }
+       }
+       // returning false here will jump forward 5s (see screen_sing.cc)
+       return false;
+}
+
+bool Song::getPrevSection(double pos, SongSection &section) {
+       for (auto it = songsections.rbegin(); it != songsections.rend(); ++it) {
+               // subtract 1 second so we can jump across a section
+               if (it->begin < pos - 1.0) {
+                       section = *it;
+                       return true;
+               }
+       }
+       // returning false here will jump backwards by 5s (see screen_sing.cc)
+       return false;
+}
+
+std::ostream& operator<<(std::ostream& os, SongParserException const& e) {
+       os << (e.silent() ? "songparser/debug: " : "songparser/warning: ") << e.file().string();
+       if (e.line()) os << ":" << e.line();
+       os << ":\n  " << e.what() << std::endl;
+       return os;
+}
+
diff --git a/game/song.hh b/game/song.hh
new file mode 100644 (file)
index 0000000..27fda60
--- /dev/null
@@ -0,0 +1,163 @@
+#pragma once
+
+#include "i18n.hh"
+#include "notes.hh"
+#include "util.hh"
+#include <boost/foreach.hpp>
+#include <boost/noncopyable.hpp>
+#include <stdexcept>
+#include <string>
+
+class SongParser;
+
+namespace TrackName {
+       const std::string BGMUSIC = "background";
+       const std::string GUITAR = "Guitar";
+       const std::string GUITAR_COOP = "Coop guitar";
+       const std::string GUITAR_RHYTHM = "Rhythm guitar";
+       const std::string BASS = "Bass";
+       const std::string KEYBOARD = "Keyboard";
+       const std::string DRUMS = "Drums";
+       const std::string LEAD_VOCAL = "Vocals";
+       #if 0 // Here is some dummy gettext calls to populate the dictionary
+       _("Guitar") _("Coop guitar") _("Rhythm guitar") _("Bass") _("Drums") _("Vocals")  _("Harmonic 1") _("Harmonic 2") _("Harmonic 3")
+       #endif
+}
+
+/// class to load and parse songfiles
+class Song: boost::noncopyable {
+       friend class SongParser;
+  public:
+       VocalTracks vocalTracks; ///< notes for the sing part
+       VocalTrack dummyVocal; ///< notes for the sing part
+       /// constructor
+       Song(fs::path const& path_, fs::path const& filename_): dummyVocal(TrackName::LEAD_VOCAL), path(path_), filename(filename_) { reload(false); }
+       /// reload song
+       void reload(bool errorIgnore = true);
+       /// parse field
+       bool parseField(std::string const& line);
+       /// Load notes (when only header has been loaded)
+       void loadNotes(bool errorIgnore = true);
+       /// drop notes (to conserve memory), but keep info about available tracks
+       void dropNotes();
+       /** Get formatted song label. **/
+       std::string str() const { return title + "  by  " + artist; }
+       /** Get full song information (used by the search function). **/
+       std::string strFull() const { return title + "\n" + artist + "\n" + genre + "\n" + edition + "\n" + path.string(); }
+       /// Is the song parsed from the file yet?
+       enum LoadStatus { NONE, HEADER, FULL } loadStatus;
+       /// status of song
+       enum Status { NORMAL, INSTRUMENTAL_BREAK, FINISHED };
+       /** Get the song status at a given timestamp **/
+       Status status(double time);
+       int randomIdx; ///< sorting index used for random order
+       void insertVocalTrack(std::string vocalTrack, VocalTrack track) {
+               eraseVocalTrack(vocalTrack);
+               vocalTracks.insert(std::make_pair(vocalTrack, track));
+       }
+       void eraseVocalTrack(std::string vocalTrack = TrackName::LEAD_VOCAL) {
+               vocalTracks.erase(vocalTrack);
+       }
+       // Get a selected track, or LEAD_VOCAL if not found or the first one if not found
+       VocalTrack& getVocalTrack(std::string vocalTrack = TrackName::LEAD_VOCAL) {
+               VocalTracks::iterator it = vocalTracks.find(vocalTrack);
+               if (it != vocalTracks.end()) {
+                       return it->second;
+               } else {
+                       it = vocalTracks.find(TrackName::LEAD_VOCAL);
+                       if (it != vocalTracks.end()) return it->second;
+                       else if (!vocalTracks.empty()) return vocalTracks.begin()->second;
+                       else return dummyVocal;
+               }
+       }
+       VocalTrack& getVocalTrack(unsigned idx) {
+               if (idx >= vocalTracks.size()) throw std::logic_error("Index out of bounds in Song::getVocalTrack");
+               VocalTracks::iterator it = vocalTracks.begin();
+               std::advance(it, idx);
+               return it->second;
+       }
+       std::vector<std::string> getVocalTrackNames() const {
+               std::vector<std::string> result;
+               BOOST_FOREACH(VocalTracks::value_type const &it, vocalTracks) {
+                       result.push_back(it.first);
+               }
+               return result;
+       }
+
+       InstrumentTracks instrumentTracks; ///< guitar etc. notes for this song
+       DanceTracks danceTracks; ///< dance tracks
+       bool hasDance() const { return !danceTracks.empty(); }
+       bool hasDrums() const { return instrumentTracks.find(TrackName::DRUMS) != instrumentTracks.end(); }
+       bool hasKeyboard() const { return instrumentTracks.find(TrackName::KEYBOARD) != instrumentTracks.end(); }
+       bool hasGuitars() const { return instrumentTracks.size() - hasDrums() - hasKeyboard(); }
+       bool hasVocals() const { return !vocalTracks.empty(); }
+       bool hasDuet() const { return vocalTracks.size() > 1; }
+       bool hasControllers() const { return !danceTracks.empty() || !instrumentTracks.empty(); }
+       fs::path path; ///< path of songfile
+       fs::path filename; ///< name of songfile
+       fs::path midifilename; ///< name of midi file in FoF format
+       std::vector<std::string> category; ///< category of song
+       std::string genre; ///< genre
+       std::string edition; ///< license
+       std::string title; ///< songtitle
+       std::string artist; ///< artist
+       std::string text; ///< songtext
+       std::string creator; ///< creator
+       std::string language; ///< language
+       typedef std::map<std::string, fs::path> Music;
+       Music music; ///< music files (background, guitar, rhythm/bass, drums, vocals)
+       fs::path cover; ///< cd cover
+       fs::path background; ///< background image
+       fs::path video; ///< video
+       /// Variables used for comparisons (sorting)
+       std::string collateByTitle;
+       std::string collateByTitleOnly;
+       /// Variables used for comparisons (sorting)
+       std::string collateByArtist;
+       std::string collateByArtistOnly;
+       /** Rebuild collate variables from other strings **/
+       void collateUpdate();
+       /** Convert a string to its collate form **/
+       static std::string collate(std::string const& str);
+       double videoGap; ///< gap with video
+       double start; ///< start of song
+       double preview_start; ///< starting time for the preview
+
+       typedef std::vector<std::pair<double,double> > Stops;
+       Stops stops; ///< related to dance
+       typedef std::vector<double> Beats;
+       Beats beats; ///< related to instrument and dance
+       bool hasBRE; ///< is there a Big Rock Ending? (used for drums only)
+       std::string b0rked; ///< Is something broken? (so that user can be notified)
+       struct SongSection {
+               std::string name;
+               double begin;
+               SongSection(std::string const& name, const double begin): name(name), begin(begin) {}
+       };
+       typedef std::vector<SongSection> SongSections;
+       SongSections songsections; ///< vector of song sections
+       bool getNextSection(double pos, SongSection &section);
+       bool getPrevSection(double pos, SongSection &section);
+};
+
+static inline bool operator<(Song const& l, Song const& r) { return l.collateByArtist < r.collateByArtist; }
+
+/// Thrown by SongParser when there is an error
+struct SongParserException: public std::runtime_error {
+       /// constructor
+       SongParserException(Song& s, std::string const& msg, unsigned int linenum, bool sil = false): runtime_error(msg), m_filename(s.filename), m_linenum(linenum), m_silent(sil) {
+               if (!sil) s.b0rked += msg + '\n';
+       }
+       ~SongParserException() throw() {}
+       fs::path const& file() const { return m_filename; } ///< file in which the error occured
+       unsigned int line() const { return m_linenum; } ///< line in which the error occured
+       bool silent() const { return m_silent; } ///< if the error should not be printed to user (file skipped)
+private:
+       fs::path m_filename;
+       unsigned int m_linenum;
+       bool m_silent;
+};
+
+/// Print a SongParserException in a format suitable for the logging system.
+std::ostream& operator<<(std::ostream& os, SongParserException const& e);
+
diff --git a/game/songitems.cc b/game/songitems.cc
new file mode 100644 (file)
index 0000000..35434f2
--- /dev/null
@@ -0,0 +1,105 @@
+#include "songitems.hh"
+
+#include "unicode.hh"
+
+#include <string>
+
+#include <boost/shared_ptr.hpp>
+#include <boost/lexical_cast.hpp>
+
+#include <libxml++/libxml++.h>
+
+
+void SongItems::load(xmlpp::NodeSet const& n) {
+       for (auto const& elem: n) {
+               xmlpp::Element& element = dynamic_cast<xmlpp::Element&>(*elem);
+
+               xmlpp::Attribute* a_id = element.get_attribute("id");
+               if (!a_id) throw SongItemsException("No attribute id");
+
+               xmlpp::Attribute* a_artist = element.get_attribute("artist");
+               if (!a_artist) throw SongItemsException("No attribute artist");
+
+               xmlpp::Attribute* a_title = element.get_attribute("title");
+               if (!a_title) throw SongItemsException("No attribute title");
+
+               addSongItem(a_artist->get_value(), a_title->get_value(), boost::lexical_cast<int>(a_id->get_value()));
+       }
+}
+
+void SongItems::save(xmlpp::Element* songs) {
+       for (auto const& song: m_songs) {
+               xmlpp::Element* element = songs->add_child("song");
+               element->set_attribute("id", boost::lexical_cast<std::string>(song.id));
+               element->set_attribute("artist", song.artist);
+               element->set_attribute("title", song.title);
+       }
+}
+
+int SongItems::addSongItem(std::string const& artist, std::string const& title, int id) {
+       SongItem si;
+       if (id==-1) id = assign_id_internal();
+       si.id = id;
+       si.artist = unicodeCollate(artist);
+       si.title = unicodeCollate(title);
+
+       std::pair<songs_t::iterator, bool> ret = m_songs.insert(si);
+       if (!ret.second)
+       {
+               si.id = assign_id_internal();
+               m_songs.insert(si); // now do the insert with the fresh id
+       }
+       return si.id;
+}
+
+void SongItems::addSong(boost::shared_ptr<Song> song) {
+       int id = lookup(song);
+       if (id == -1)
+       {
+               id = addSongItem(song->artist, song->title);
+       }
+
+       SongItem si;
+       si.id = id;
+       auto it = m_songs.find(si);
+       if (it == m_songs.end()) throw SongItemsException("Cant find song which was added just before");
+       // it->song.reset(song); // does not work, it is a read only structure...
+
+       // fill up the rest of the information
+       si.artist = it->artist;
+       si.title = it->title;
+       si.song = song;
+
+       m_songs.erase(it);
+       m_songs.insert(si);
+}
+
+int SongItems::lookup(boost::shared_ptr<Song> song) const {
+       for (auto const& s: m_songs) {
+               if (song->collateByArtistOnly == s.artist && song->collateByTitleOnly == s.title) return s.id;
+       }
+       return -1;
+}
+
+int SongItems::lookup(Song& song) const {
+       for (auto const& s: m_songs) {
+               if (song.collateByArtistOnly == s.artist && song.collateByTitleOnly == s.title) return s.id;
+       }
+       return -1;
+}
+
+std::string SongItems::lookup(int id) const {
+       SongItem si;
+       si.id = id;
+       auto it = m_songs.find(si);
+       if (it == m_songs.end()) return "Unkown Song";
+       else if (!it->song) return it->artist + " - " + it->title;
+       else return it->song->artist + " - " + it->song->title;
+}
+
+int SongItems::assign_id_internal() const {
+       // use the last one with highest id
+       auto it = m_songs.rbegin();
+       if (it != m_songs.rend()) return it->id+1;
+       else return 1; // empty set
+}
diff --git a/game/songitems.hh b/game/songitems.hh
new file mode 100644 (file)
index 0000000..a3a0eeb
--- /dev/null
@@ -0,0 +1,99 @@
+#pragma once
+
+#include "song.hh"
+
+#include <set>
+#include <vector>
+#include <string>
+#include <stdexcept>
+
+#include <boost/shared_ptr.hpp>
+
+namespace xmlpp { class Node; class Element; typedef std::vector<Node*>NodeSet; }
+
+/**Exception which will be thrown when loading or
+  saving Players fails.*/
+struct SongItemsException: public std::runtime_error {
+       SongItemsException (std::string const& msg) :
+               runtime_error(msg)
+       {}
+};
+
+struct SongItem
+{
+       int id; ///< The unique id for every song
+
+       /** This data is stored separate because it is read in before
+         the song is added.
+         A short, but relatively non-ambiguous collate form is used.
+         */
+       std::string artist;
+       std::string title;
+
+       /** This shared pointer is stored to access all song
+         information available.
+         E.g. the full artist information can be accessed using
+         this pointer.
+        */
+       boost::shared_ptr<Song> song;
+
+       bool operator< (SongItem const& other) const
+       {
+               return id < other.id;
+       }
+};
+
+/**A list of songs for the database.
+
+  Every song has a unique id managed by that database.
+  This class was introduced to hide the implementation
+  detail which data structure is used for the list away.
+
+  Currently a std::set is used, which makes both addSongItem()
+  and addSong() slow. The only advantage is that the id is
+  unique and it is cheap to get a new unique id.
+
+  When one of the methods is to slow, it can be optimized
+  easily. */
+class SongItems {
+public:
+       void load(xmlpp::NodeSet const& n);
+       void save(xmlpp::Element *players);
+
+       /**Adds a song item.
+         If the id is not unique or -1 a new one will be assigned.
+         There will be no check if artist and title already exist - if you
+         need that you want addSong().
+        */
+       int addSongItem(std::string const& artist, std::string const& title, int id = -1);
+       /**Adds or Links an already existing song with an songitem.
+
+         The id will be assigned and artist and title will be filled in.
+         If there is already a song with the same artist and title the existing
+         will be used.
+
+         Afterwards the pointer to the song will be stored for entire available
+         song information.
+
+         lookup is used internally to achieve that.
+         */
+       void addSong(boost::shared_ptr<Song> song);
+
+       /**Lookup a songid for a specific song.
+         @return -1 if no song found.*/
+       int lookup(boost::shared_ptr<Song> song) const;
+       int lookup(Song& song) const;
+
+       /**Lookup the artist + title for a specific song.
+         @return "Unknown Song" if nothing is found.
+         */
+       std::string lookup (int id) const;
+
+       std::size_t size() const { return m_songs.size(); }
+
+private:
+       int assign_id_internal() const;
+
+       typedef std::set<SongItem> songs_t;
+       songs_t m_songs;
+};
diff --git a/game/songparser-ini.cc b/game/songparser-ini.cc
new file mode 100644 (file)
index 0000000..80d358d
--- /dev/null
@@ -0,0 +1,46 @@
+#include "songparser.hh"
+
+#include <boost/algorithm/string.hpp>
+#include <boost/regex.hpp>
+#include <stdexcept>
+#include "midifile.hh"
+
+/// @file
+/// Functions used for parsing the Frets on Fire INI song format
+
+using namespace SongParserUtil;
+
+/// 'Magick' to check if this file looks like correct format
+bool SongParser::iniCheck(std::vector<char> const& data) const {
+       static const std::string header = "[song]";
+       return std::equal(header.begin(), header.end(), data.begin());
+}
+
+/// Parse header data for Songs screen
+void SongParser::iniParseHeader() {
+       Song& s = m_song;
+       std::string line;
+       while (getline(line)) {
+               if (line.empty()) continue;
+               if (line[0] == '[') continue; // Section header
+               std::istringstream iss(line);
+               std::string key, value;
+               if (!std::getline(iss, key, '=') || !std::getline(iss, value)) std::runtime_error("Invalid format, should be key=value");
+               boost::trim(key); boost::to_lower(key);
+               boost::trim(value);
+               // Supported tags
+               if (key == "name") s.title = value;
+               else if (key == "artist") s.artist = value;
+               else if (key == "cover") s.cover = fs::absolute(value, s.path);
+               else if (key == "background") s.background = fs::absolute(value, s.path);
+               else if (key == "video") s.video = fs::absolute(value, s.path);
+               else if (key == "genre") s.genre = value;
+               else if (key == "frets") s.creator = value;
+               else if (key == "delay") { assign(s.start, value); s.start/=1000.0; }
+               else if (key == "video_start_time") { assign(s.videoGap, value); s.videoGap/=1000.0; }
+               else if (key == "preview_start_time") { assign(s.preview_start, value); s.preview_start/=1000.0; }
+               // Before adding other tags: they should be checked with the already-existing tags in FoF format; in case any tag doesn't exist there, it should be discussed with FoFiX developers before adding it here.
+       }
+       if (s.title.empty() || s.artist.empty()) throw std::runtime_error("Required header fields missing");
+}
+
diff --git a/game/songparser-mid.cc b/game/songparser-mid.cc
new file mode 100644 (file)
index 0000000..5b63159
--- /dev/null
@@ -0,0 +1,220 @@
+#include "songparser.hh"
+
+#include <boost/algorithm/string.hpp>
+#include <boost/regex.hpp>
+#include <stdexcept>
+#include "midifile.hh"
+
+/// @file
+/// Functions used for parsing MIDI files (FoF and other song formats)
+
+using namespace SongParserUtil;
+
+const std::string HARMONIC_1 = "Harmonic 1";
+const std::string HARMONIC_2 = "Harmonic 2";
+const std::string HARMONIC_3 = "Harmonic 3";
+
+namespace {
+       bool isVocalTrack(std::string name) {
+               if(name == TrackName::LEAD_VOCAL) return true;
+               else if(name == HARMONIC_1) return true;
+               else if(name == HARMONIC_2) return true;
+               else if(name == HARMONIC_3) return true;
+               return false;
+       }
+       /// Change the MIDI track name to Performous track name
+       /// Return false if not valid
+       bool mangleTrackName(std::string& name) {
+               if (name == "T1 GEMS") { // Some old MIDI files have a track named T1 GEMS
+                       name = TrackName::GUITAR; return true;
+               }
+               else if (name.substr(0, 5) != "PART ") return false;
+               else name.erase(0, 5);
+               if (name == "GUITAR COOP") name = TrackName::GUITAR_COOP;
+               else if (name == "RHYTHM") name = TrackName::GUITAR_RHYTHM;
+               else if (name == "DRUM") name = TrackName::DRUMS;
+               else if (name == "DRUMS") name = TrackName::DRUMS;
+               else if (name == "BASS") name = TrackName::BASS;
+               else if (name == "KEYS") return false; // TODO: RB3 5 lane keyboard track
+               else if (name == "GUITAR") name = TrackName::GUITAR;
+               else if (name == "VOCALS") name = TrackName::LEAD_VOCAL;
+               else if (name == "HARM1") name = HARMONIC_1;
+               else if (name == "HARM2") name = HARMONIC_2;
+               else if (name == "HARM3") name = HARMONIC_3;
+               // expert stuffs
+               else if (name == "REAL_KEYS_X") return false; // TODO: RB3 pro keyboard expert track
+               else if (name == "REAL_KEYS_H") return false; // TODO: RB3 pro keyboard hard track
+               else if (name == "REAL_KEYS_M") return false; // TODO: RB3 pro keyboard medium track
+               else if (name == "REAL_KEYS_E") return false; // TODO: RB3 pro keyboard easy track
+               else if (name == "REAL_BASS") return false; // TODO: RB3 pro bass track
+               else if (name == "REAL_GUITAR") return false; // TODO: RB3 pro guitar 17 frets (Mustang) track
+               else if (name == "REAL_GUITAR_22") return false; // TODO: RB3 pro guitar 22 frets (Squier) track
+               else return false;
+               return true;
+       }
+}
+
+void SongParser::midParseHeader() {
+       Song& s = m_song;
+       // Parse tracks from midi
+       MidiFileParser midi(s.midifilename);
+       for (MidiFileParser::Tracks::const_iterator it = midi.tracks.begin(); it != midi.tracks.end(); ++it) {
+               // Figure out the track name
+               std::string name = it->name;
+               if (mangleTrackName(name)) ; // Beautify the track name
+               else if (midi.tracks.size() == 1) name = TrackName::GUITAR; // Original (old) FoF songs only have one track
+               else continue; // not a valid track
+               // Add dummy notes to tracks so that they can be seen in song browser
+               if (isVocalTrack(name)) s.insertVocalTrack(name, VocalTrack(name));
+               else {
+                       for (auto const& elem: it->notes) {
+                               // If a track has not enough notes on any level, ignore it
+                               if (elem.second.size() > 3) { s.instrumentTracks.insert(make_pair(name,InstrumentTrack(name))); break; }
+                       }
+               }
+       }
+}
+
+/// Parse notes
+void SongParser::midParse() {
+       Song& s = m_song;
+       s.instrumentTracks.clear();
+
+       MidiFileParser midi(s.midifilename);
+       int reversedNoteCount = 0;
+       for (uint32_t ts = 0, end = midi.ts_last + midi.division; ts < end; ts += midi.division) s.beats.push_back(midi.get_seconds(ts)+s.start);
+       for (MidiFileParser::Tracks::const_iterator it = midi.tracks.begin(); it != midi.tracks.end(); ++it) {
+               // Figure out the track name
+               std::string name = it->name;
+               if (mangleTrackName(name)) ; // Beautify the track name
+               else if (midi.tracks.size() == 1) name = TrackName::GUITAR; // Original (old) FoF songs only have one track
+               else continue; // not a valid track
+               if (!isVocalTrack(name)) {
+                       // Process non-vocal tracks
+                       double trackEnd = 0.0;
+                       s.instrumentTracks.insert(make_pair(name,InstrumentTrack(name)));
+                       NoteMap& nm2 = s.instrumentTracks.find(name)->second.nm;
+                       for (auto const& elem: it->notes) {
+                               Durations& dur = nm2[elem.first];
+                               MidiFileParser::Notes const& notes = elem.second;
+                               for (auto const& note: notes) {
+                                       double beg = midi.get_seconds(note.begin)+s.start;
+                                       double end = midi.get_seconds(note.end)+s.start;
+                                       if (end == 0) continue; // Note with no ending
+                                       if (beg > end) { // Reversed note
+                                               if (beg - end > 0.001) { reversedNoteCount++; continue; }
+                                               else end = beg; // Allow 1ms error to counter rounding etc errors
+                                       }
+                                       dur.push_back(Duration(beg, end));
+                                       if (trackEnd < end) trackEnd = end;
+                               }
+                       }
+                       // Discard empty tracks
+                       // Note: some songs have notes at the very beginning (but are otherwise empty)
+                       if (trackEnd < 1.0) s.instrumentTracks.erase(name);
+               } else {
+                       // Process vocal tracks
+                       VocalTrack vocal(name);
+                       for (auto const& lyric: it->lyrics) {
+                               Note n;
+                               n.begin = midi.get_seconds(lyric.begin)+s.start;
+                               n.end = midi.get_seconds(lyric.end)+s.start;
+                               n.notePrev = n.note = lyric.note;
+                               n.type = n.note > 100 ? Note::SLEEP : Note::NORMAL;
+                               if(n.note == 116 || n.note == 103 || n.note == 124)
+                                       continue; // managed in the next loop (GOLDEN/FREESTYLE notes)
+                               else if(n.note > 100) // is it always 105 ?
+                                       n.type = Note::SLEEP;
+                               else
+                                       n.type = Note::NORMAL;
+                               {
+                                       std::stringstream ss(lyric.lyric);
+                                       convertToUTF8(ss);
+                                       n.syllable = ss.str();
+                               }
+                               std::string& syl = n.syllable;
+                               if (n.type != Note::SLEEP) {
+                                       if (!syl.empty()) {
+                                               bool erase = false;
+                                               // Examine note styles (specified by the last character of the syllable)
+                                               {
+                                                       char& ch = *syl.rbegin();
+                                                       if (ch == '#') { n.type = Note::FREESTYLE; erase = true; }
+                                                       if (ch == '^') { n.type = Note::GOLDEN; erase = true; }
+                                                       if (ch == '+') { n.type = Note::SLIDE; ch = '~'; }
+                                               }
+                                               if (erase) syl.erase(syl.size() - 1);
+                                               // Add spaces between words, remove hyphens
+                                               {
+                                                       char ch = *syl.rbegin();
+                                                       if (ch == '-') syl.erase(syl.size() - 1);
+                                                       else if (ch == '=') { *syl.rbegin() = '-'; }
+                                                       else if (ch != '~') syl += ' ';
+                                               }
+                                       }
+                                       // Special processing for slides (which depend on the previous note)
+                                       if (n.type == Note::SLIDE) {
+                                               auto prev = vocal.notes.rbegin();
+                                               while (prev != vocal.notes.rend() && prev->type == Note::SLEEP) ++prev;
+                                               if (prev == vocal.notes.rend()) throw std::runtime_error("The song begins with a slide note");
+                                               eraseLast(prev->syllable); // Erase the space if there is any
+                                               {
+                                                       // insert new sliding note
+                                                       Note inter;
+                                                       inter.begin = prev->end;
+                                                       inter.end = n.begin;
+                                                       inter.notePrev = prev->note;
+                                                       inter.note = n.note;
+                                                       inter.type = Note::SLIDE;
+                                                       inter.syllable = std::string("~");
+                                                       vocal.noteMin = std::min(vocal.noteMin, inter.note);
+                                                       vocal.noteMax = std::max(vocal.noteMax,inter.note);
+                                                       vocal.notes.push_back(inter);
+                                               }
+                                               {
+                                                       // modifying current note to be normal again
+                                                       n.type = Note::NORMAL;
+                                               }
+                                       }
+                                       vocal.noteMin = std::min(vocal.noteMin, n.note);
+                                       vocal.noteMax = std::max(vocal.noteMax, n.note);
+                                       vocal.notes.push_back(n);
+                               } else if (!vocal.notes.empty() && vocal.notes.back().type != Note::SLEEP) {
+                                       eraseLast(vocal.notes.back().syllable);
+                                       vocal.notes.push_back(n);
+                               }
+                       }
+                       for (auto const& lyric: it->lyrics) {
+                               if(lyric.note == 116 || lyric.note == 103 || lyric.note == 124) {
+                                       for (auto& n: vocal.notes) {
+                                               if (n.begin == midi.get_seconds(lyric.begin) + s.start && n.type == Note::NORMAL) {
+                                                       if (lyric.note == 124) {
+                                                               n.type = Note::FREESTYLE;
+                                                       } else {
+                                                               n.type = Note::GOLDEN;
+                                                       }
+                                                       break;
+                                               }
+                                       }
+                               }
+                       }
+                       s.insertVocalTrack(name, vocal);
+               }
+       }
+       // Figure out if we have BRE in the song
+       for (MidiFileParser::CommandEvents::const_iterator it = midi.cmdevents.begin(); it != midi.cmdevents.end(); ++it) {
+               if (*it == "[section big_rock_ending]") s.hasBRE = true;
+       }
+       // Output some warning
+       if (reversedNoteCount > 0) {
+               std::ostringstream oss;
+               oss << "songparser/notice: Skipping " << reversedNoteCount << " reversed note(s) in " << s.midifilename.string();
+               std::clog << oss.str() << std::endl; // More likely to be atomic when written as one string
+       }
+       // copy midi sections to song section
+       // design goals: (1) keep midi parser free of dependencies on song (2) store data in song as parsers are discarded before song
+       // one option would be to pass a song reference to the midi parser however, that conflicts with goal (1)
+       for (auto& sect: midi.midisections) s.songsections.emplace_back(sect.name, sect.begin);
+}
+
+
diff --git a/game/songparser-sm.cc b/game/songparser-sm.cc
new file mode 100644 (file)
index 0000000..94b282e
--- /dev/null
@@ -0,0 +1,254 @@
+#include "songparser.hh"
+
+#include <boost/algorithm/string.hpp>
+#include <algorithm>
+#include <stdexcept>
+#include <map>
+
+/// @file
+/// Functions used for parsing the StepMania SM format
+
+using namespace SongParserUtil;
+
+/// 'Magick' to check if this file looks like correct format
+bool SongParser::smCheck(std::vector<char> const& data) const {
+       if (data[0] != '#' || data[1] < 'A' || data[1] > 'Z') return false;
+       for (char ch: data) {
+               if (ch == '\n') return false;
+               if (ch == ';') return true;
+       }
+       return false;
+}
+
+/* Parsing the note data is separated into three different functions: smParse, smParseField and smParseNote.
+- smParse only begins a loop which continues as long as there is something to read in the file. It also checks if the needed information
+could be read.
+- smParseField reads all data beginning with '#'. That is, all but the actual notes. This function calls smParseNotes every time it
+reaches value #NOTES.
+- smParseNotes reads the notes into vector called notes which is a vector of structs (Note);
+*/
+
+/// Parse header data for Songs screen
+// TODO: This actually parses the whole thing
+// TODO: Songparser drops parsed notes, remove it when smParseHeader is more intelligent
+void SongParser::smParseHeader() {
+       Song& s = m_song;
+       std::string line;
+       // Parse the the entire file
+       while (getline(line) && smParseField(line)) {}
+       if (m_song.danceTracks.empty() ) throw std::runtime_error("No note data in the file");
+       if (s.title.empty() || s.artist.empty()) throw std::runtime_error("Required header fields missing");
+       // Convert stops to the format required in Song
+       s.stops.resize(m_stops.size());
+       for (std::size_t i = 0; i < m_stops.size(); ++i) s.stops[i] = stopConvert(m_stops[i]);
+       m_tsPerBeat = 4;
+}
+
+/// Parse remaining stuff
+void SongParser::smParse() {
+       m_song.stops.clear();
+       m_song.danceTracks.clear();
+       smParseHeader();
+}
+
+bool SongParser::smParseField(std::string line) {
+       boost::trim(line);
+       if (line.empty()) return true;
+       if (line.substr(0, 2) == "//") return true; //jump over possible comments
+       if (line[0] == ';') return true; // HACK: Skip ; left over from previous field
+
+       //Here the data contained by the current line is separated in key and value.
+       //However, because of the differing format of notedata the value is analyzed only if key is not NOTES
+       std::string::size_type pos = line.find(':');
+       if (pos == std::string::npos) throw std::runtime_error("Invalid sm format, should be #key:value");
+       std::string key = boost::trim_copy(line.substr(1, pos - 1));
+       if (key == "NOTES") {
+               /*All remaining data is parsed here.
+                       All five lines of note metadata is read first and then smParseNotes is called to read
+                       the actual note data.
+                       All data is read into m_song.danceTracks map container.
+               */
+
+               while (getline(line)) {
+                       //<NotesType>:
+                       std::string notestype = boost::trim_copy(line.substr(0, line.find_first_of(':')));
+                       boost::to_lower(notestype);
+                       //<Description>:
+                       if(!getline(line)) { throw std::runtime_error("Required note data missing"); }
+                       std::string description = boost::trim_copy(line.substr(0, line.find_first_of(':')));
+                       //<DifficultyClass>:
+                       if(!getline(line)) { throw std::runtime_error("Required note data missing"); }
+                       std::string difficultyclass = boost::trim_copy(line.substr(0, line.find_first_of(':')));
+                       boost::to_upper(difficultyclass);
+                       DanceDifficulty danceDifficulty = DIFFICULTYCOUNT;
+                       if(difficultyclass == "BEGINNER") danceDifficulty = BEGINNER;
+                       if(difficultyclass == "EASY") danceDifficulty = EASY;
+                       if(difficultyclass == "MEDIUM") danceDifficulty = MEDIUM;
+                       if(difficultyclass == "HARD") danceDifficulty = HARD;
+                       if(difficultyclass == "CHALLENGE") danceDifficulty = CHALLENGE;
+
+                       //ignoring difficultymeter and radarvalues
+                       //<DifficultyMeter>:
+                       if(!getline(line)) { throw std::runtime_error("Required note data missing"); }
+                       if(!getline(line)) { throw std::runtime_error("Required note data missing"); }
+
+                       //<NoteData>:
+                       Notes notes = smParseNotes(line);
+
+                       //Here all note data from the current track is inserted into containers
+                       // TODO: support other track types. For now all others are simply ignored.
+                       if (notestype == "dance-single" || notestype == "dance-double" || notestype == "dance-solo"
+                         || notestype == "pump-single" || notestype == "ez2-single" || notestype == "ez2-real"
+                         || notestype == "para-single") {
+                               DanceTrack danceTrack(description, notes);
+                               if (m_song.danceTracks.find(notestype) == m_song.danceTracks.end() ) {
+                                       DanceDifficultyMap danceDifficultyMap;
+                                       m_song.danceTracks.insert(std::make_pair(notestype, danceDifficultyMap));
+                               }
+                               m_song.danceTracks[notestype].insert(std::make_pair(danceDifficulty, danceTrack));
+                       }
+               }
+               return false;
+       }
+       std::string value = boost::trim_copy(line.substr(pos + 1));
+       //In case the value continues to several lines, all text before the ending character ';' is read to single line.
+       while (value[value.size() -1] != ';') {
+               std::string str;
+               if (!getline (str)) throw std::runtime_error("Invalid format, semicolon missing after value of " + key);
+               value += boost::trim_copy(str);
+       }
+       value = value.substr(0, value.size() - 1);      //Here the end character(';') is eliminated
+       if (value.empty()) return true;
+
+       // Parse header data that is stored in SongParser rather than in song (and thus needs to be read every time)
+       if (key == "OFFSET") { assign(m_gap, value); m_gap *= -1; }
+       else if (key == "BPMS"){
+                       std::istringstream iss(value);
+                       double ts, bpm;
+                       char chr;
+                       while (iss >> ts >> chr >> bpm) {
+                               if (ts == 0.0) m_bpm = bpm;
+                               addBPM(ts * 4.0, bpm);
+                               if (!(iss >> chr)) break;
+                       }
+       }
+       else if (key == "STOPS"){
+                       std::istringstream iss(value);
+                       double beat, sec;
+                       char chr;
+                       while (iss >> beat >> chr >> sec) {
+                               m_stops.push_back(std::make_pair(beat * 4.0, sec));
+                               if (!(iss >> chr)) break;
+                       }
+       }
+
+       if (m_song.loadStatus >= Song::HEADER) return true;  // Only re-parsing now, skip any other data
+
+       // Parse header data that is directly stored in m_song
+       if (key == "TITLE") m_song.title = value.substr(value.find_first_not_of(" :"));
+       else if (key == "ARTIST") m_song.artist = value.substr(value.find_first_not_of(" "));
+       else if (key == "BANNER") m_song.cover = fs::absolute(value, m_song.path);
+       else if (key == "MUSIC") m_song.music[TrackName::BGMUSIC] = fs::absolute(value, m_song.path);
+       else if (key == "BACKGROUND") m_song.background = fs::absolute(value, m_song.path);
+       else if (key == "SAMPLESTART") assign(m_song.preview_start, value);
+       /*.sm fileformat has also the following constants but they are ignored in this version of the parser:
+       #SUBTITLE
+       #TITLETRANSLIT
+       #SUBTITLETRANSLIT
+       #ARTISTTRANSLIT
+       #CREDIT
+       #CDTITLE
+       #SAMPLESTART
+               #SAMPLELENGTH
+       #SELECTABLE
+       #BGCHANGE
+       */
+       // Add beat info to song
+       return true;
+}
+
+
+
+
+Notes SongParser::smParseNotes(std::string line) {
+       //container for dance songs
+       typedef std::map<int, Note> DanceChord; //int indicates "arrow" position (cmp. fret in guitar)
+       typedef std::vector<DanceChord> DanceChords;
+
+       DanceChords chords;     //temporary container for notes
+       Notes notes;
+       unsigned measure = 1;
+       double begin = 0.0;
+       bool forceMeasure = false;
+
+       std::map<int, int> holdMarks; // Keeps track of hold notes not yet terminated
+
+       while (forceMeasure || getline(line)) {
+               if (forceMeasure) { line = ";"; forceMeasure = false; }
+               boost::trim(line); // Remove whitespace
+               if (line.empty()) continue;
+               if (line.substr(0, 2) == "//") continue;  // Skip comments
+               if (line[0] == '#') break;  // HACK: This should read away the next #NOTES: line
+               if (line[0] == ',' || line[0] == ';') {
+                       double end = tsTime(measure * 16.0);
+                       unsigned div = chords.size();
+                       double step = (end - begin) / div;
+                       for (unsigned note = 0; note < div; ++note) {
+                               double t = begin + note * step;
+                               double phase = double(note) / div;
+                               for (auto& elem: chords[note]) {
+                                       int& holdIdx = holdMarks[elem.first];  // holdIdx for current arrow
+                                       Note& n = elem.second;
+                                       n.begin = n.end = t;
+                                       n.phase = phase;
+                                       // TODO: Proper LIFT handling
+                                       if (n.type == Note::TAP || n.type == Note::MINE || n.type == Note::LIFT) notes.push_back(n);
+                                       // TODO: Proper ROLL handling
+                                       if (n.type == Note::HOLDBEGIN || n.type == Note::ROLL) {
+                                               notes.push_back(n);  // Note added now, end time will be fixed later
+                                               holdIdx = notes.size(); // Store index in notes plus one
+                                               continue;
+                                       }
+                                       if (n.type == Note::HOLDEND) {
+                                               if (holdIdx == 0) throw std::runtime_error("Hold end without beginning");
+                                               notes[holdIdx - 1].end = t;
+                                       }
+                                       holdIdx = 0;
+                               }
+                       }
+                       chords.clear();
+                       begin = end;
+                       ++measure;
+                       continue;
+               }
+               /*Note data is read into temporary container chords before
+               finally reading it into vector notes. This is done so that the bpm and time stamp values
+               would be easier to count afterwards.
+               */
+               DanceChord chord;
+               // Deal with ; or , being on a same line
+               if (line[line.size()-1] == ';' || line[line.size()-1] == ',') {
+                       forceMeasure = true;
+                       line = line.substr(0, line.size()-1);
+               }
+               for(std::size_t i = 0; i < line.size(); i++) {
+                       char notetype = line[i];
+                       if (notetype == '0') continue;
+                       Note note;
+                       if(notetype == '1') note.type = Note::TAP;
+                       else if(notetype == '2') note.type = Note::HOLDBEGIN;
+                       else if(notetype == '3') note.type = Note::HOLDEND;
+                       else if(notetype == '4') note.type = Note::ROLL;
+                       else if(notetype == 'M') note.type = Note::MINE;
+                       else if(notetype == 'L') note.type = Note::LIFT;
+                       else if(notetype >= 'a' && notetype <= 'z') note.type = Note::TAP;
+                       else if(notetype >= 'A' && notetype <= 'Z') note.type = Note::TAP;
+                       else throw std::runtime_error(std::string("Invalid note command: ") + notetype);
+                       note.note = i;
+                       chord[i] = note;
+               }
+               chords.push_back(chord);
+       }
+       m_tsEnd = std::max(m_tsEnd, measure * 16);
+       return notes;
+}
diff --git a/game/songparser-txt.cc b/game/songparser-txt.cc
new file mode 100644 (file)
index 0000000..818e6d4
--- /dev/null
@@ -0,0 +1,191 @@
+#include "songparser.hh"
+
+#include <boost/algorithm/string.hpp>
+#include <algorithm>
+#include <stdexcept>
+
+/// @file
+/// Functions used for parsing the UltraStar TXT song format
+
+using namespace SongParserUtil;
+
+namespace {
+       const std::string DUET_P2 = "Duet singer"; // FIXME
+}
+
+/// 'Magick' to check if this file looks like correct format
+bool SongParser::txtCheck(std::vector<char> const& data) const {
+       return data[0] == '#' && data[1] >= 'A' && data[1] <= 'Z';
+}
+
+/// Parse header data for Songs screen
+void SongParser::txtParseHeader() {
+       Song& s = m_song;
+       std::string line;
+       while (getline(line) && txtParseField(line)) {}
+       if (s.title.empty() || s.artist.empty()) throw std::runtime_error("Required header fields missing");
+       if (m_bpm != 0.0) addBPM(0, m_bpm);
+       s.insertVocalTrack(TrackName::LEAD_VOCAL, VocalTrack(TrackName::LEAD_VOCAL)); // Dummy note to indicate there is a track
+}
+
+/// Parse notes
+void SongParser::txtParse() {
+       std::string line;
+       m_curSinger = P1;
+       m_song.insertVocalTrack(TrackName::LEAD_VOCAL, VocalTrack(TrackName::LEAD_VOCAL));
+       m_song.insertVocalTrack(DUET_P2, VocalTrack(DUET_P2));
+       while (getline(line) && txtParseField(line)) {} // Parse the header again
+       resetNoteParsingState();
+       while (txtParseNote(line) && getline(line)) {} // Parse notes
+
+       // Workaround for the terminating : 1 0 0 line, written by some converters
+       // FIXME: Should we do this for all tracks?
+       for (auto const& name: { TrackName::LEAD_VOCAL, DUET_P2 }) {
+               Notes& notes = m_song.getVocalTrack(name).notes;
+               auto it = notes.rbegin();
+               if (!notes.empty() && it->type != Note::SLEEP && it->begin == it->end) notes.pop_back();
+               if (notes.empty()) m_song.eraseVocalTrack(name);
+       }
+
+}
+
+bool SongParser::txtParseField(std::string const& line) {
+       if (line.empty()) return true;
+       if (line[0] != '#') return false;
+       std::string::size_type pos = line.find(':');
+       if (pos == std::string::npos) throw std::runtime_error("Invalid txt format, should be #key:value");
+       std::string key = boost::trim_copy(line.substr(1, pos - 1));
+       std::string value = boost::trim_copy(line.substr(pos + 1));
+       if (value.empty()) return true;
+
+       // Parse header data that is stored in SongParser rather than in song (and thus needs to be read every time)
+       if (key == "BPM") assign(m_bpm, value);
+       else if (key == "RELATIVE") assign(m_relative, value);
+       else if (key == "GAP") { assign(m_gap, value); m_gap *= 1e-3; }
+
+       if (m_song.loadStatus >= Song::HEADER) return true;  // Only re-parsing now, skip any other data
+
+       // Parse header data that is directly stored in m_song
+       if (key == "TITLE") m_song.title = value.substr(value.find_first_not_of(" :"));
+       else if (key == "ARTIST") m_song.artist = value.substr(value.find_first_not_of(" "));
+       else if (key == "EDITION") m_song.edition = value.substr(value.find_first_not_of(" "));
+       else if (key == "GENRE") m_song.genre = value.substr(value.find_first_not_of(" "));
+       else if (key == "CREATOR") m_song.creator = value.substr(value.find_first_not_of(" "));
+       else if (key == "COVER") m_song.cover = fs::absolute(value, m_song.path);
+       else if (key == "MP3") m_song.music["background"] = fs::absolute(value, m_song.path);
+       else if (key == "VOCALS") m_song.music["vocals"] = fs::absolute(value, m_song.path);
+       else if (key == "VIDEO") m_song.video = fs::absolute(value, m_song.path);
+       else if (key == "BACKGROUND") m_song.background = fs::absolute(value, m_song.path);
+       else if (key == "START") assign(m_song.start, value);
+       else if (key == "VIDEOGAP") assign(m_song.videoGap, value);
+       else if (key == "PREVIEWSTART") assign(m_song.preview_start, value);
+       else if (key == "LANGUAGE") m_song.language= value.substr(value.find_first_not_of(" "));
+       else if (key == "DUETSINGERP2") m_song.insertVocalTrack(DUET_P2, VocalTrack(DUET_P2)); // Strong hint that this is a duet, so it will be readily displayed with two singers in browser and properly filtered
+       return true;
+}
+
+bool SongParser::txtParseNote(std::string line) {
+       if (line.empty() || line == "\r") return true;
+       if (line[0] == '#') throw std::runtime_error("Key found in the middle of notes");
+       if (line[line.size() - 1] == '\r') line.erase(line.size() - 1);
+       if (line[0] == 'E') return false;
+       std::istringstream iss(line);
+       if (line[0] == 'B') {
+               unsigned int ts;
+               double bpm;
+               iss.ignore();
+               if (!(iss >> ts >> bpm)) throw std::runtime_error("Invalid BPM line format");
+               addBPM(ts, bpm);
+               return true;
+       }
+       if (line[0] == 'P') {
+               if (m_relative) // FIXME?
+                       throw std::runtime_error("Relative note timing not supported with multiple singers");
+               if (line.size() < 2) throw std::runtime_error("Invalid player info line [too short]: " + line);
+               else if (line[1] == '1') m_curSinger = P1;
+               else if (line[1] == '2') m_curSinger = P2;
+               else if (line[1] == '3') m_curSinger = BOTH;
+               else if (line.size() < 3) throw std::runtime_error("Invalid player info line [too short]: " + line);
+               else if (line[2] == '1') m_curSinger = P1;
+               else if (line[2] == '2') m_curSinger = P2;
+               else if (line[2] == '3') m_curSinger = BOTH;
+               else throw std::runtime_error("Invalid player info line [malformed]: " + line);
+               resetNoteParsingState();
+               return true;
+       }
+       Note n;
+       n.type = Note::Type(iss.get());
+       unsigned int ts = m_prevts;
+       switch (n.type) {
+         case Note::NORMAL:
+         case Note::FREESTYLE:
+         case Note::GOLDEN:
+               {
+                       unsigned int length = 0;
+                       if (!(iss >> ts >> length >> n.note)) throw std::runtime_error("Invalid note line format");
+                       n.notePrev = n.note; // No slide notes in TXT yet.
+                       if (m_relative) ts += m_relativeShift;
+                       if (iss.get() == ' ') std::getline(iss, n.syllable);
+                       n.end = tsTime(ts + length);
+               }
+               break;
+         case Note::SLEEP:
+               {
+                       unsigned int end;
+                       if (!(iss >> ts >> end)) end = ts;
+                       if (m_relative) {
+                               ts += m_relativeShift;
+                               end += m_relativeShift;
+                               m_relativeShift = end;
+                       }
+                       n.end = tsTime(end);
+               }
+               break;
+         default: throw std::runtime_error("Unknown note type");
+       }
+       n.begin = tsTime(ts);
+       VocalTrack& vocal = (m_curSinger & P1)
+         ? m_song.getVocalTrack(TrackName::LEAD_VOCAL)
+         : m_song.getVocalTrack(DUET_P2);
+       Notes& notes = vocal.notes;
+       if (m_relative && notes.empty()) m_relativeShift = ts;
+       m_prevts = ts;
+       // FIXME: These work-arounds don't work for P3 (both singers) case
+       if (n.begin < m_prevtime) {
+               // Oh no, overlapping notes (b0rked file)
+               // Can't do this because too many songs are b0rked: throw std::runtime_error("Note overlaps with previous note");
+               if (notes.size() >= 1) {
+                       Note& p = notes.back();
+                       // Workaround for songs that use semi-random timestamps for sleep
+                       if (p.type == Note::SLEEP) {
+                               p.end = p.begin;
+                               auto it = notes.rbegin();
+                               Note& p2 = *++it;
+                               if (p2.end < n.begin) p.begin = p.end = n.begin;
+                       }
+                       // Can we just make the previous note shorter?
+                       if (p.begin <= n.begin) p.end = n.begin;
+                       else if (m_song.b0rked.empty()) { // Cannot fix, warn and skip
+                               std::string msg = "Skipped overlapping notes.\n";
+                               m_song.b0rked = msg;
+                               std::clog << "songparser/notice: " + m_song.filename.string() + ": " + msg << std::endl;
+                               return true;
+                       }
+               } else throw std::runtime_error("The first note has negative timestamp");
+       }
+       double prevtime = m_prevtime;
+       m_prevtime = n.end;
+       if (n.type != Note::SLEEP && n.end > n.begin) {
+               vocal.noteMin = std::min(vocal.noteMin, n.note);
+               vocal.noteMax = std::max(vocal.noteMax, n.note);
+       }
+       if (n.type == Note::SLEEP) {
+               if (notes.empty()) return true; // Ignore sleeps at song beginning
+               n.begin = n.end = prevtime; // Normalize sleep notes
+       }
+       notes.push_back(n);
+       if (m_curSinger == BOTH)
+               m_song.getVocalTrack(DUET_P2).notes.push_back(n);
+       return true;
+}
+
diff --git a/game/songparser-xml.cc b/game/songparser-xml.cc
new file mode 100644 (file)
index 0000000..6781fa6
--- /dev/null
@@ -0,0 +1,217 @@
+#include "songparser.hh"
+
+#include "util.hh"
+#include <boost/algorithm/string.hpp>
+#include <boost/regex.hpp>
+#include <stdexcept>
+
+/// @file
+/// Functions used for parsing the SingStar XML song format
+
+using namespace SongParserUtil;
+
+/// 'Magick' to check if this file looks like correct format
+bool SongParser::xmlCheck(std::vector<char> const& data) const {
+       static const std::string header = "<?";
+       return std::equal(header.begin(), header.end(), data.begin());
+}
+
+#include <libxml++/libxml++.h>
+#include <glibmm/convert.h>
+
+/*
+// LibXML2 logging facility
+extern "C" void xmlLogger(void* logger, char const* msg, ...) { if (logger) *(std::ostream*)logger << msg; }
+void enableXMLLogger(std::ostream& os = std::cerr) { xmlSetGenericErrorFunc(&os, xmlLogger); }
+void disableXMLLogger() { xmlSetGenericErrorFunc(NULL, xmlLogger); }
+*/
+
+struct SSDom: public xmlpp::DomParser {
+       xmlpp::Node::PrefixNsMap nsmap;
+       SSDom(std::stringstream const& _ss) {
+               load(_ss.str());
+       }
+       void load(std::string const& buf) {
+               set_substitute_entities();
+               try {
+                       /*
+                       struct DisableLogger {
+                               DisableLogger() { disableXMLLogger(); }
+                               ~DisableLogger() { enableXMLLogger(); }
+                       } disabler;
+                       */
+                       parse_memory(buf);
+               } catch (...) {
+                       std::string buf2 = Glib::convert(buf, "UTF-8", "ISO-8859-1"); // Convert to UTF-8
+                       parse_memory(buf2);
+               }
+               nsmap["ss"] = get_document()->get_root_node()->get_namespace_uri();
+       }
+       bool find(xmlpp::Element const& elem, std::string xpath, xmlpp::NodeSet& n) {
+               if (nsmap["ss"].empty()) boost::erase_all(xpath, "ss:");
+               n = elem.find(xpath, nsmap);
+               return !n.empty();
+       }
+       bool find(std::string const& xpath, xmlpp::NodeSet& n) {
+               return find(*get_document()->get_root_node(), xpath, n);
+       }
+       bool getValue(std::string const& xpath, std::string& result) {
+               xmlpp::NodeSet n;
+               if (!find(xpath, n)) return false;
+               result = dynamic_cast<xmlpp::Element&>(*n[0]).get_child_text()->get_content();
+               return true;
+       }
+};
+
+namespace {
+       /// Parse str (from XML comment node) for header/value and store cleaned up value in result.
+       bool parseComment(std::string const& str, std::string const& header, std::string& result) {
+               if (!boost::starts_with(str, header)) return false;
+               result = boost::replace_all_copy(
+                 boost::trim_left_copy(str.substr(header.size())),
+                 "&amp;", "&");
+               return true;
+       }
+}
+
+/// Parse header data for Songs screen
+void SongParser::xmlParseHeader() {
+       Song& s = m_song;
+
+       // Parse notes.xml
+       SSDom dom(m_ss);
+       // Extract artist and title from XML comments
+       {
+               xmlpp::NodeSet comments;
+               // Comments inside or before root element
+               dom.find("/ss:MELODY/comment()", comments) || dom.find("/ss:MELODY/../comment()", comments);
+               for (auto const& node: comments) {
+                       std::string str = dynamic_cast<xmlpp::CommentNode const&>(*node).get_content();
+                       boost::trim(str);
+                       parseComment(str, "Artist:", s.artist) || parseComment(str, "Title:", s.title);
+               }
+               if (s.title.empty() || s.artist.empty()) throw std::runtime_error("Required header fields missing");
+       }
+       // Read TRACK elements (singer names), if available
+       std::string singers;  // Only used for "Together" track
+       xmlpp::NodeSet tracks;
+       dom.find("/ss:MELODY/ss:TRACK", tracks);
+       for (auto const& elem: tracks) {
+               auto const& trackNode = dynamic_cast<xmlpp::Element const&>(*elem);
+               std::string name = trackNode.get_attribute("Name")->get_value();  // "Player1" or "Player2"
+               xmlpp::Attribute* attr = trackNode.get_attribute("Artist");
+               std::string artist = attr ? std::string(attr->get_value()) : name;  // Singer name
+               if (attr) singers += (singers.empty() ? "" : " & ") + artist;
+               m_song.insertVocalTrack(name, VocalTrack(artist));
+       }
+       // If no tracks are specified, we can assume that it isn't duet
+       if (tracks.empty()) m_song.insertVocalTrack("Player1", VocalTrack(s.artist));
+       else if (tracks.size() > 1) m_song.insertVocalTrack("Together", VocalTrack(singers.empty() ? _("Together") : singers));
+}
+
+void addNoteToTrack(VocalTrack& vocal, const Note& note) {
+       if (note.type == Note::SLEEP) {
+               // Skip extra sleep notes
+               if (vocal.notes.empty() || vocal.notes.back().type == Note::SLEEP) return;
+       } else {
+               vocal.noteMin = std::min(vocal.noteMin, note.note);
+               vocal.noteMax = std::max(vocal.noteMax, note.note);
+       }
+       vocal.notes.push_back(note);
+}
+
+/// Parse notes
+void SongParser::xmlParse() {
+       // Parse notes.xml
+       SSDom dom(m_ss);
+       Song& s = m_song;
+       // Extract tempo
+       {
+               xmlpp::NodeSet n;
+               if (!dom.find("/ss:MELODY", n)) throw std::runtime_error("Unable to find BPM info");
+               auto const& e = dynamic_cast<xmlpp::Element const&>(*n[0]);
+               std::string res = e.get_attribute("Resolution")->get_value();
+               SongParserUtil::assign(m_bpm, e.get_attribute("Tempo")->get_value().c_str());
+               if (res == "Semiquaver") {}
+               else if (res == "Demisemiquaver") m_bpm *= 2.0;
+               else throw std::runtime_error("Unknown tempo resolution: " + res);
+       }
+       addBPM(0, m_bpm);
+
+       // Parse each track...
+       xmlpp::NodeSet tracks;
+       // First try version 1 (MELODY/SENTENCE), fallback to version 2/4 (MELODY/TRACK/SENTENCE).
+       dom.find("/ss:MELODY[ss:SENTENCE]", tracks) || dom.find("/ss:MELODY/ss:TRACK[ss:SENTENCE]", tracks);
+       if (tracks.empty()) throw std::runtime_error("No valid tracks or sentences found");
+       // Process each vocalTrack separately; use the same XML (version 1) track twice if needed
+       unsigned players = clamp<unsigned>(s.vocalTracks.size(), 1, 2);  // Don't count "Together" track
+       auto vocalIt = s.vocalTracks.begin();
+       for (unsigned player = 0; player < players; ++player, ++vocalIt) {
+               if (vocalIt == s.vocalTracks.end()) throw std::logic_error("SongParser-xml vocalIt past the end");
+               VocalTrack& vocal = vocalIt->second;
+               auto const& trackElem = dynamic_cast<xmlpp::Element const&>(*tracks[player % tracks.size()]);
+               std::string sentenceSinger = "Solo 1";  // The default value
+               xmlpp::NodeSet sentences;
+               dom.find(trackElem, "ss:SENTENCE", sentences);
+               unsigned ts = 0;
+               for (xmlpp::NodeSet::const_iterator it = sentences.begin(); it != sentences.end(); ++it ) {
+                       auto const& sentenceNode = dynamic_cast<xmlpp::Element const&>(**it);
+                       // Check if SENTENCE has new attributes
+                       {
+                               xmlpp::Attribute* attr = sentenceNode.get_attribute("Part");
+                               if (attr) m_song.songsections.push_back(Song::SongSection(attr->get_value(), tsTime(ts)));
+                               attr = sentenceNode.get_attribute("Singer");
+                               if (attr) sentenceSinger = attr->get_value();
+                       }
+                       // Begin each sentence with sleep (extras will be purged in addNoteToTrack)
+                       {
+                               Note sleep;
+                               sleep.type = Note::SLEEP;
+                               sleep.begin = sleep.end = tsTime(ts);
+                               addNoteToTrack(vocal, sleep);
+                       }
+                       // Notes of a sentence
+                       xmlpp::NodeSet notes;
+                       dom.find(sentenceNode, "ss:NOTE", notes);
+                       for (auto const& elem: notes) {
+                               auto const& noteNode = dynamic_cast<xmlpp::Element const&>(*elem);
+                               Note n = xmlParseNote(noteNode, ts);
+                               if (n.note == 0) continue;
+                               // Skip sentences that do not belong to current player
+                               if (player != 0 && sentenceSinger == "Solo 1") continue;
+                               if (players > 1 && player != 1 && sentenceSinger == "Solo 2") continue;
+                               // Actually add the note to current player's track...
+                               addNoteToTrack(vocal, n);
+                       }  // notes
+               }  // sentences
+       } // players (vocal tracks)
+}
+
+Note SongParser::xmlParseNote(xmlpp::Element const& noteNode, unsigned& ts) {
+       Note n;
+       std::string lyric = noteNode.get_attribute("Lyric")->get_value();
+       // Pretty print hyphenation
+       if (lyric.size() > 0 && lyric[lyric.size() - 1] == '-') {
+               if (lyric.size() > 1 && lyric[lyric.size() - 2] == ' ') lyric.erase(lyric.size() - 2);
+               else lyric[lyric.size() - 1] = '~';
+       } else {
+               lyric += ' ';
+       }
+       unsigned note, duration;
+       SongParserUtil::assign(note, noteNode.get_attribute("MidiNote")->get_value().c_str());
+       SongParserUtil::assign(duration, noteNode.get_attribute("Duration")->get_value().c_str());
+       if (noteNode.get_attribute("FreeStyle")) n.type = Note::FREESTYLE;
+       else if (noteNode.get_attribute("Bonus")) n.type = Note::GOLDEN;
+       else n.type = Note::NORMAL;
+
+       n.begin = tsTime(ts);
+       ts += duration;
+       n.end = tsTime(ts);
+       n.syllable = lyric;
+       n.note = note;
+       n.notePrev = note;
+
+       return n;
+}
+
+
diff --git a/game/songparser.cc b/game/songparser.cc
new file mode 100644 (file)
index 0000000..e116ebd
--- /dev/null
@@ -0,0 +1,256 @@
+#include "songparser.hh"
+
+#include <boost/algorithm/string.hpp>
+#include <boost/filesystem/fstream.hpp>
+#include <boost/lexical_cast.hpp>
+#include <boost/regex.hpp>
+
+
+namespace SongParserUtil {
+       void assign(int& var, std::string const& str) {
+               try {
+                       var = boost::lexical_cast<int>(str);
+               } catch (...) {
+                       throw std::runtime_error("\"" + str + "\" is not valid integer value");
+               }
+       }
+       void assign(unsigned& var, std::string const& str) {
+               try {
+                       var = boost::lexical_cast<int>(str);
+               } catch (...) {
+                       throw std::runtime_error("\"" + str + "\" is not valid unsigned integer value");
+               }
+       }
+       void assign(double& var, std::string str) {
+               std::replace(str.begin(), str.end(), ',', '.'); // Fix decimal separators
+               try {
+                       var = boost::lexical_cast<double>(str);
+               } catch (...) {
+                       throw std::runtime_error("\"" + str + "\" is not valid floating point value");
+               }
+       }
+       void assign(bool& var, std::string const& str) {
+               if (str == "YES" || str == "yes" || str == "1") var = true;
+               else if (str == "NO" || str == "no" || str == "0") var = false;
+               else throw std::runtime_error("Invalid boolean value: " + str);
+       }
+       void eraseLast(std::string& s, char ch) {
+               if (!s.empty() && *s.rbegin() == ch) s.erase(s.size() - 1);
+       }
+}
+
+
+/// constructor
+SongParser::SongParser(Song& s) try:
+  m_song(s),
+  m_linenum(),
+  m_relative(),
+  m_gap(),
+  m_bpm(),
+  m_prevtime(),
+  m_prevts(),
+  m_relativeShift(),
+  m_tsPerBeat(),
+  m_tsEnd()
+{
+       enum { NONE, TXT, XML, INI, SM } type = NONE;
+       // Read the file, determine the type and do some initial validation checks
+       {
+               fs::ifstream f(s.filename, std::ios::binary);
+               if (!f.is_open()) throw SongParserException(s, "Could not open song file", 0);
+               f.seekg(0, std::ios::end);
+               size_t size = f.tellg();
+               if (size < 10 || size > 100000) throw SongParserException(s, "Does not look like a song file (wrong size)", 1, true);
+               f.seekg(0);
+               std::vector<char> data(size);
+               if (!f.read(&data[0], size)) throw SongParserException(s, "Unexpected I/O error", 0);
+               if (smCheck(data)) type = SM;
+               else if (txtCheck(data)) type = TXT;
+               else if (iniCheck(data)) type = INI;
+               else if (xmlCheck(data)) type = XML;
+               else throw SongParserException(s, "Does not look like a song file (wrong header)", 1, true);
+               m_ss.write(&data[0], size);
+       }
+       // Convert m_ss; filename supplied for possible warning messages
+       convertToUTF8(m_ss, s.filename.string());
+       // Header already parsed?
+       if (s.loadStatus == Song::HEADER) {
+               if (type == TXT) txtParse();
+               else if (type == INI) midParse();  // INI doesn't contain notes, parse those from MIDI
+               else if (type == XML) xmlParse();
+               else if (type == SM) smParse();
+               finalize(); // Do some adjusting to the notes
+               s.loadStatus = Song::FULL;
+               return;
+       }
+       // Parse only header to speed up loading and conserve memory
+       if (type == TXT) txtParseHeader();
+       else if (type == INI) iniParseHeader();
+       else if (type == XML) xmlParseHeader();
+       else if (type == SM) { smParseHeader(); s.dropNotes(); } // Hack: drop notes here
+       // Default for preview position if none was specified in header
+       if (s.preview_start != s.preview_start) s.preview_start = (type == INI ? 5.0 : 30.0);  // 5 s for band mode, 30 s for others
+
+       guessFiles();
+       if (!m_song.midifilename.empty()) midParseHeader();
+
+       s.loadStatus = Song::HEADER;
+} catch (SongParserException&) {
+       throw;
+} catch (std::runtime_error& e) {
+       throw SongParserException(m_song, e.what(), m_linenum);
+} catch (std::exception& e) {
+       throw SongParserException(m_song, "Internal error: " + std::string(e.what()), m_linenum);
+}
+
+void SongParser::guessFiles() {
+       // List of fields containing filenames, and auto-matching regexps, in order of priority
+       const std::vector<std::pair<fs::path*, char const*>> fields = {
+               { &m_song.cover, R"((cover|album|label|banner|bn|\[co\])\.(png|jpeg|jpg|svg)$)" },
+               { &m_song.background, R"((background|bg|\[bg\])\.(png|jpeg|jpg|svg)$)" },
+               { &m_song.cover, R"(\.(png|jpeg|jpg|svg)$)" },
+               { &m_song.background, R"(\.(png|jpeg|jpg|svg)$)" },
+               { &m_song.video, R"(\.(avi|mpg|mpeg|flv|mov|mp4|mkv|m4v)$)" },
+               { &m_song.midifilename, R"(notes\.mid$)" },
+               { &m_song.midifilename, R"(\.mid$)" },
+               { &m_song.music[TrackName::GUITAR], R"(guitar\.(mp3|ogg|aac)$)" },
+               { &m_song.music[TrackName::BASS], R"(rhythm\.(mp3|ogg|aac)$)" },
+               { &m_song.music[TrackName::DRUMS], R"(drums\.(mp3|ogg|aac)$)" },
+               { &m_song.music[TrackName::KEYBOARD], R"(keyboard\.(mp3|ogg|aac)$)" },
+               { &m_song.music[TrackName::GUITAR_COOP], R"(guitar_coop\.(mp3|ogg|aac)$)"},
+               { &m_song.music[TrackName::GUITAR_RHYTHM], R"(guitar_rhythm\.(mp3|ogg|aac)$)"},
+               { &m_song.music[TrackName::LEAD_VOCAL], R"(vocals\.(mp3|ogg|aac)$)" },
+               { &m_song.music[TrackName::BGMUSIC], R"(song\.(mp3|ogg|aac)$)" },
+               { &m_song.music[TrackName::BGMUSIC], R"(\.(mp3|ogg|aac)$)" },
+       };
+
+       std::string logMissing, logFound;
+       
+       // Run checks, remove bogus values and construct regexps
+       std::vector<boost::regex> regexps;
+       bool missing = false;
+       for (auto const& p: fields) {
+               fs::path& file = *p.first;
+               if (!file.empty() && !is_regular_file(file)) {
+                       logMissing += "  " + file.filename().string();
+                       file.clear();
+               }
+               if (file.empty()) missing = true;
+               regexps.emplace_back(p.second, boost::regex_constants::icase);
+       }
+
+       if (!missing) return;  // All OK!
+
+       std::set<fs::path> files(fs::directory_iterator{m_song.path}, fs::directory_iterator{});
+       
+       for (unsigned i = 0; i < fields.size(); ++i) {
+               fs::path& field = *fields[i].first;
+               if (field.empty()) for (fs::path const& f: files) {
+                       std::string name = f.filename().string(); // File basename
+                       if (!regex_search(name, regexps[i])) continue;  // No match for current file
+                       field = f;
+                       logFound += "  " + name;
+               }
+               files.erase(field);  // Remove from available options
+       }
+
+       if (logFound.empty() && logMissing.empty()) return;
+       std::clog << "songparser/" << (logMissing.empty() ? "debug" : "notice") << ": " + m_song.filename.string() + ":\n";
+       if (!logMissing.empty()) std::clog << "  Not found:    " + logMissing + "\n";
+       if (!logFound.empty()) std::clog << "  Autodetected: " + logFound + "\n";
+       std::clog << std::flush;
+
+}
+
+void SongParser::resetNoteParsingState() {
+       m_prevtime = 0;
+       m_prevts = 0;
+       m_relativeShift = 0;
+       m_tsPerBeat = 0;
+       m_tsEnd = 0;
+       m_bpms.clear();
+       if (m_bpm != 0.0) addBPM(0, m_bpm);
+}
+
+void SongParser::vocalsTogether() {
+       auto togetherIt = m_song.vocalTracks.find("Together");
+       if (togetherIt == m_song.vocalTracks.end()) return;
+       Notes& together = togetherIt->second.notes;
+       if (!together.empty()) return;
+       Notes notes;
+       // Collect usable vocal tracks
+       struct TrackInfo {
+               typedef Notes::const_iterator It;
+               It it, end;
+               TrackInfo(It begin, It end): it(begin), end(end) {}
+       };
+       std::vector<TrackInfo> tracks;
+       for (auto& nt: m_song.vocalTracks) {
+               togetherIt->second.noteMin = std::min(togetherIt->second.noteMin, nt.second.noteMin);
+               togetherIt->second.noteMax = std::max(togetherIt->second.noteMax, nt.second.noteMax);
+
+               Notes& n = nt.second.notes;
+               if (!n.empty()) tracks.push_back(TrackInfo(n.begin(), n.end()));
+       }
+       if (tracks.empty()) return;
+       // Combine notes
+       // FIXME: This should do combining on sentence level rather than note-by-note
+       TrackInfo* trk = &tracks.front();
+       while (trk) {
+               Note const& n = *trk->it;
+               //std::cerr << " " << n.syllable << ": " << n.begin << "-" << n.end << std::endl;
+               notes.push_back(n);
+               ++trk->it;
+               trk = nullptr;
+               // Iterate all tracks past the processed note and find the new earliest track
+               for (TrackInfo& trk2: tracks) {
+                       // Skip until a sentence that begins after the note ended
+                       while (trk2.it != trk2.end && trk2.it->begin < n.end) ++trk2.it;
+                       if (trk2.it == trk2.end) continue;
+                       if (!trk || trk2.it->begin < trk->it->begin) trk = &trk2;
+               }
+       }
+       together.swap(notes);
+}
+
+void SongParser::finalize() {
+       vocalsTogether();
+       for (auto& nt: m_song.vocalTracks) {
+               VocalTrack& vocal = nt.second;
+               // Remove empty sentences
+               {
+                       Note::Type lastType = Note::NORMAL;
+                       for (auto itn = vocal.notes.begin(); itn != vocal.notes.end();) {
+                               Note::Type type = itn->type;
+                               if(type == Note::SLEEP && lastType == Note::SLEEP) {
+                                       std::clog << "songparser/info: " + m_song.filename.string() + ": Discarding empty sentence" << std::endl;
+                                       itn = vocal.notes.erase(itn);
+                               } else {
+                                       ++itn;
+                               }
+                               lastType = type;
+                       }
+               }
+               // Adjust negative notes
+               if (vocal.noteMin <= 0) {
+                       unsigned int shift = (1 - vocal.noteMin / 12) * 12;
+                       vocal.noteMin += shift;
+                       vocal.noteMax += shift;
+                       for (auto& elem: vocal.notes) {
+                               elem.note += shift;
+                               elem.notePrev += shift;
+                       }
+               }
+               // Set begin/end times
+               if (!vocal.notes.empty()) vocal.beginTime = vocal.notes.front().begin, vocal.endTime = vocal.notes.back().end;
+               else vocal.beginTime = vocal.endTime = 0.0;
+               // Compute maximum score
+               double max_score = 0.0;
+               for (auto& note: vocal.notes) max_score += note.maxScore();
+               vocal.m_scoreFactor = 1.0 / max_score;
+       }
+       if (m_tsPerBeat) {
+               // Add song beat markers
+               for (unsigned ts = 0; ts < m_tsEnd; ts += m_tsPerBeat) m_song.beats.push_back(tsTime(ts));
+       }
+}
diff --git a/game/songparser.hh b/game/songparser.hh
new file mode 100644 (file)
index 0000000..5196c8e
--- /dev/null
@@ -0,0 +1,101 @@
+#pragma once
+
+#include "song.hh"
+#include "unicode.hh"
+#include <sstream>
+#include <boost/filesystem.hpp>
+
+namespace SongParserUtil {
+       /// Parse an int from string and assign it to a variable
+       void assign(int& var, std::string const& str);
+       /// Parse an unsigned int from string and assign it to a variable
+       void assign(unsigned& var, std::string const& str);
+       /// Parse a double from string and assign it to a variable
+       void assign(double& var, std::string str);
+       /// Parse a boolean from string and assign it to a variable
+       void assign(bool& var, std::string const& str);
+       /// Erase last character if it matches
+       void eraseLast(std::string& s, char ch = ' ');
+}
+
+namespace xmlpp { class Element; };
+
+/// parses songfiles
+class SongParser {
+  public:
+       /// constructor
+       SongParser(Song& s);
+  private:
+       void finalize();
+       void vocalsTogether();
+       void guessFiles();
+       
+       Song& m_song;
+       std::stringstream m_ss;
+       unsigned int m_linenum;
+       bool getline(std::string& line) { ++m_linenum; return std::getline(m_ss, line);}
+       bool m_relative;
+       double m_gap;
+       double m_bpm;
+
+       bool txtCheck(std::vector<char> const& data) const;
+       void txtParseHeader();
+       void txtParse();
+       bool txtParseField(std::string const& line);
+       bool txtParseNote(std::string line);
+       bool iniCheck(std::vector<char> const& data) const;
+       void iniParseHeader();
+       bool midCheck(std::vector<char> const& data) const;
+       void midParseHeader();
+       void midParse();
+       bool xmlCheck(std::vector<char> const& data) const;
+       void xmlParseHeader();
+       void xmlParse();
+       Note xmlParseNote(xmlpp::Element const& noteNode, unsigned& ts);
+       bool smCheck(std::vector<char> const& data) const;
+       void smParseHeader();
+       void smParse();
+       bool smParseField(std::string line);
+       Notes smParseNotes(std::string line);
+       void resetNoteParsingState();
+       double m_prevtime;
+       unsigned int m_prevts;
+       unsigned int m_relativeShift;
+       enum CurrentSinger { P1 = 1, P2 = 2, BOTH = P1 | P2 } m_curSinger;
+       struct BPM {
+               BPM(double _begin, double _ts, double bpm): begin(_begin), step(0.25 * 60.0 / bpm), ts(_ts) {}
+               double begin; // Time in seconds
+               double step; // Seconds per quarter note
+               double ts;
+       };
+       typedef std::vector<BPM> bpms_t;
+       bpms_t m_bpms;
+       unsigned m_tsPerBeat;  ///< The ts increment per beat
+       unsigned m_tsEnd;  ///< The ending ts of the song
+       void addBPM(double ts, double bpm) {
+               if (!(bpm >= 1.0 && bpm < 1e12)) throw std::runtime_error("Invalid BPM value");
+               if (!m_bpms.empty() && m_bpms.back().ts >= ts) {
+                       if (m_bpms.back().ts < ts) throw std::runtime_error("Invalid BPM timestamp");
+                       m_bpms.pop_back(); // Some ITG songs contain repeated BPM definitions...
+               }
+               m_bpms.push_back(BPM(tsTime(ts), ts, bpm));
+       }
+       /// Convert a timestamp (beats) into time (seconds)
+       double tsTime(double ts) const {
+               if (m_bpms.empty()) {
+                       if (ts != 0) throw std::runtime_error("BPM data missing");
+                       return m_gap;
+               }
+               for (std::vector<BPM>::const_reverse_iterator it = m_bpms.rbegin(); it != m_bpms.rend(); ++it) {
+                       if (it->ts <= ts) return it->begin + (ts - it->ts) * it->step;
+               }
+               throw std::logic_error("INTERNAL ERROR: BPM data invalid");
+       }
+       /// Stops stored in <ts, duration> format
+       Song::Stops m_stops;
+       /// Convert a stop into <time, duration> (as stored in the song)
+       std::pair<double, double> stopConvert(std::pair<double, double> s) {
+               s.first = tsTime(s.first);
+               return s;
+       }
+};
diff --git a/game/songs.cc b/game/songs.cc
new file mode 100644 (file)
index 0000000..e2cb4d8
--- /dev/null
@@ -0,0 +1,285 @@
+#include "songs.hh"
+
+#include "configuration.hh"
+#include "fs.hh"
+#include "song.hh"
+#include "database.hh"
+#include "i18n.hh"
+#include "profiler.hh"
+
+#include <boost/bind.hpp>
+#include <boost/filesystem.hpp>
+#include <boost/format.hpp>
+#include <boost/lexical_cast.hpp>
+#include <boost/regex.hpp>
+#include <libxml++/libxml++.h>
+#include <algorithm>
+#include <iostream>
+#include <stdexcept>
+#include <cstdlib>
+
+Songs::Songs(Database & database, std::string const& songlist): m_songlist(songlist), math_cover(), m_database(database), m_type(), m_order(), m_dirty(false), m_loading(false) {
+       m_updateTimer.setTarget(getInf()); // Using this as a simple timer counting seconds
+       reload();
+}
+
+Songs::~Songs() {
+       m_loading = false; // Terminate song loading if currently in progress
+       m_thread->join();
+}
+
+void Songs::reload() {
+       if (m_loading) return;
+       // Run loading thread
+       m_loading = true;
+       m_thread.reset(new boost::thread(boost::bind(&Songs::reload_internal, boost::ref(*this))));
+}
+
+void Songs::reload_internal() {
+       {
+               boost::mutex::scoped_lock l(m_mutex);
+               m_songs.clear();
+               m_dirty = true;
+       }
+       Profiler prof("songloader");
+       Paths paths = getPathsConfig("paths/songs");
+       for (auto it = paths.begin(); m_loading && it != paths.end(); ++it) {
+               try {
+                       if (!fs::is_directory(*it)) { std::clog << "songs/info: >>> Not scanning: " << *it << " (no such directory)\n"; continue; }
+                       std::clog << "songs/info: >>> Scanning " << *it << std::endl;
+                       size_t count = m_songs.size();
+                       reload_internal(*it);
+                       size_t diff = m_songs.size() - count;
+                       if (diff > 0 && m_loading) std::clog << "songs/info: " << diff << " songs loaded\n";
+               } catch (std::exception& e) {
+                       std::clog << "songs/error: >>> Error scanning " << *it << ": " << e.what() << '\n';
+               }
+       }
+       prof("total");
+       if (m_loading) dumpSongs_internal(); // Dump the songlist to file (if requested)
+       std::clog << std::flush;
+       m_loading = false;
+}
+
+void Songs::reload_internal(fs::path const& parent) {
+       if (std::distance(parent.begin(), parent.end()) > 20) { std::clog << "songs/info: >>> Not scanning: " << parent.string() << " (maximum depth reached, possibly due to cyclic symlinks)\n"; return; }
+       try {
+               boost::regex expression(R"((\.txt|^song\.ini|^notes\.xml|\.sm)$)", boost::regex_constants::icase);
+               for (fs::directory_iterator dirIt(parent), dirEnd; m_loading && dirIt != dirEnd; ++dirIt) {
+                       fs::path p = dirIt->path();
+                       if (fs::is_directory(p)) { reload_internal(p); continue; }
+                       if (!regex_search(p.filename().string(), expression)) continue;
+                       try {
+                               boost::shared_ptr<Song>s(new Song(p.parent_path(), p));
+                               s->randomIdx = rand();
+                               boost::mutex::scoped_lock l(m_mutex);
+                               m_songs.push_back(s);
+                               m_dirty = true;
+                       } catch (SongParserException& e) {
+                               std::clog << e;
+                       }
+               }
+       } catch (std::exception const& e) {
+               std::clog << "songs/error: Error accessing " << parent << ": " << e.what() << '\n';
+       }
+}
+
+// Make std::find work with shared_ptrs and regular pointers
+static bool operator==(boost::shared_ptr<Song> const& a, Song const* b) { return a.get() == b; }
+
+/// Store currently selected song on construction and restore the selection on destruction
+/// Assumes that m_filtered has been modified and finds the old selection by pointer value.
+/// Sets up math_cover so that the old selection is restored if possible, otherwise the first song is selected.
+class Songs::RestoreSel {
+       Songs& m_s;
+       Song const* m_sel;
+  public:
+       /// constructor
+       RestoreSel(Songs& s): m_s(s), m_sel(s.empty() ? nullptr : &s.current()) {}
+       /// resets song to given song
+       void reset(Song const* song = nullptr) { m_sel = song; }
+       ~RestoreSel() {
+               int pos = 0;
+               if (m_sel) {
+                       SongVector& f = m_s.m_filtered;
+                       auto it = std::find(f.begin(), f.end(), m_sel);
+                       m_s.math_cover.reset();
+                       if (it != f.end()) pos = it - f.begin();
+               }
+               m_s.math_cover.setTarget(pos, m_s.size());
+       }
+};
+
+void Songs::update() {
+       if (m_dirty && m_updateTimer.get() > 0.5) filter_internal(); // Update with newly loaded songs
+       // A hack to move to the first song when the song screen is entered the first time
+       static bool first = true;
+       if (first) { first = false; math_cover.reset(); math_cover.setTarget(0, size()); }
+}
+
+void Songs::setFilter(std::string const& val) {
+       if (m_filter == val) return;
+       m_filter = val;
+       filter_internal();
+}
+
+void Songs::filter_internal() {
+       m_updateTimer.setValue(0.0);
+       boost::mutex::scoped_lock l(m_mutex);
+       m_dirty = false;
+       RestoreSel restore(*this);
+       try {
+               SongVector filtered;
+               for (SongVector::const_iterator it = m_songs.begin(); it != m_songs.end(); ++it) {
+                       Song& s = **it;
+                       // All, Dance, Vocals, Duet, Guitar, Band
+                       if (m_type == 1 && !s.hasDance()) continue;
+                       if (m_type == 2 && !s.hasVocals()) continue;
+                       if (m_type == 3 && !s.hasDuet()) continue;
+                       if (m_type == 4 && !s.hasGuitars()) continue;
+                       if (m_type == 5 && !s.hasDrums() && !s.hasKeyboard()) continue;
+                       if (m_type == 6 && (!s.hasVocals() || !s.hasGuitars() || (!s.hasDrums() && !s.hasKeyboard()))) continue;
+                       if (regex_search(s.strFull(), boost::regex(m_filter, boost::regex_constants::icase))) filtered.push_back(*it);
+               }
+               m_filtered.swap(filtered);
+       } catch (...) {
+               SongVector(m_songs.begin(), m_songs.end()).swap(m_filtered);  // Invalid regex => copy everything
+       }
+       sort_internal();
+}
+
+namespace {
+
+       /// A functor that compares songs based on a selected member field of them.
+       template<typename Field> class CmpByField {
+               Field Song::* m_field;
+         public:
+               /** @param field a pointer to the field to use (pointer to member) **/
+               CmpByField(Field Song::* field): m_field(field) {}
+               /// Compare left < right
+               bool operator()(Song const& left , Song const& right) {
+                   return left.*m_field < right.*m_field;
+               }
+               /// Compare *left < *right
+               bool operator()(boost::shared_ptr<Song> const& left, boost::shared_ptr<Song> const& right) {
+                       return operator()(*left, *right);
+               }
+       };
+
+       /// A helper for easily constructing CmpByField objects
+       template <typename T> CmpByField<T> comparator(T Song::*field) { return CmpByField<T>(field); }
+
+       static const int types = 7, orders = 7;
+
+}
+
+std::string Songs::typeDesc() const {
+       switch (m_type) {
+               case 0: return _("show all songs");
+               case 1: return _("has dance");
+               case 2: return _("has vocals");
+               case 3: return _("has duet");
+               case 4: return _("has guitar");
+               case 5: return _("drums or keytar");
+               case 6: return _("full band");
+       }
+       throw std::logic_error("Internal error: unknown type filter in Songs::typeDesc");
+}
+
+void Songs::typeChange(int diff) {
+       if (diff == 0) m_type = 0;
+       else {
+               m_type = (m_type + diff) % types;
+               if (m_type < 0) m_type += types;
+       }
+       filter_internal();
+}
+
+void Songs::typeCycle(int cat) {
+       static const int categories[types] = { 0, 1, 2, 2, 3, 3, 4 };
+       // Find the next matching category
+       int type = 0;
+       for (int t = (categories[m_type] == cat ? m_type + 1 : 0); t < types; ++t) {
+               if (categories[t] == cat) { type = t; break; }
+       }
+       m_type = type;
+       filter_internal();
+}
+
+std::string Songs::sortDesc() const {
+       std::string str;
+       switch (m_order) {
+         case 0: str = _("random order"); break;
+         case 1: str = _("sorted by song"); break;
+         case 2: str = _("sorted by artist"); break;
+         case 3: str = _("sorted by edition"); break;
+         case 4: str = _("sorted by genre"); break;
+         case 5: str = _("sorted by path"); break;
+         case 6: str = _("sorted by language"); break;
+         default: throw std::logic_error("Internal error: unknown sort order in Songs::sortDesc");
+       }
+       return str;
+}
+
+void Songs::sortChange(int diff) {
+       m_order = (m_order + diff) % orders;
+       if (m_order < 0) m_order += orders;
+       RestoreSel restore(*this);
+       sort_internal();
+}
+
+void Songs::sort_internal() {
+       switch (m_order) {
+         case 0: std::stable_sort(m_filtered.begin(), m_filtered.end(), comparator(&Song::randomIdx)); break;
+         case 1: std::sort(m_filtered.begin(), m_filtered.end(), comparator(&Song::collateByTitle)); break;
+         case 2: std::sort(m_filtered.begin(), m_filtered.end(), comparator(&Song::collateByArtist)); break;
+         case 3: std::sort(m_filtered.begin(), m_filtered.end(), comparator(&Song::edition)); break;
+         case 4: std::sort(m_filtered.begin(), m_filtered.end(), comparator(&Song::genre)); break;
+         case 5: std::sort(m_filtered.begin(), m_filtered.end(), comparator(&Song::path)); break;
+         case 6: std::sort(m_filtered.begin(), m_filtered.end(), comparator(&Song::language)); break;
+         default: throw std::logic_error("Internal error: unknown sort order in Songs::sortChange");
+       }
+}
+
+namespace {
+       void dumpCover(xmlpp::Element* song, Song const& s, size_t num) {
+               try {
+                       std::string ext = s.cover.extension().string();
+                       if (exists(s.cover)) {
+                               std::string coverlink = "covers/" + (boost::format("%|04|") % num).str() + ext;
+                               if (fs::is_symlink(coverlink)) fs::remove(coverlink);
+                               create_symlink(s.cover, coverlink);
+                               song->add_child("cover")->set_child_text(coverlink);
+                       }
+               } catch (std::exception& e) {
+                       std::cerr << "Songlist error handling cover image: " << e.what() << std::endl;
+               }
+       }
+       template <typename SongVector> void dumpXML(SongVector const& svec, std::string const& filename) {
+               xmlpp::Document doc;
+               xmlpp::Element* songlist = doc.create_root_node("songlist");
+               songlist->set_attribute("size", boost::lexical_cast<std::string>(svec.size()));
+               for (size_t i = 0; i < svec.size(); ++i) {
+                       Song const& s = *svec[i];
+                       xmlpp::Element* song = songlist->add_child("song");
+                       song->set_attribute("num", boost::lexical_cast<std::string>(i + 1));
+                       xmlpp::Element* collate = song->add_child("collate");
+                       collate->add_child("artist")->set_child_text(s.collateByArtist);
+                       collate->add_child("title")->set_child_text(s.collateByTitle);
+                       song->add_child("artist")->set_child_text(s.artist);
+                       song->add_child("title")->set_child_text(s.title);
+                       if (!s.cover.empty()) dumpCover(song, s, i + 1);
+               }
+               doc.write_to_file_formatted(filename, "UTF-8");
+       }
+}
+
+void Songs::dumpSongs_internal() const {
+       if (m_songlist.empty()) return;
+       SongVector svec = m_songs;
+       std::sort(svec.begin(), svec.end(), comparator(&Song::collateByArtist));
+       fs::path coverpath = fs::path(m_songlist) / "covers";
+       fs::create_directories(coverpath);
+       dumpXML(svec, m_songlist + "/songlist.xml");
+}
+
diff --git a/game/songs.hh b/game/songs.hh
new file mode 100644 (file)
index 0000000..b57ef3e
--- /dev/null
@@ -0,0 +1,93 @@
+#pragma once
+
+#include "animvalue.hh"
+#include "fs.hh"
+#include <boost/shared_ptr.hpp>
+#include <boost/scoped_ptr.hpp>
+#include <boost/thread/mutex.hpp>
+#include <boost/thread/thread.hpp>
+#include <set>
+#include <sstream>
+#include <vector>
+
+class Song;
+class Database;
+
+/// songs class for songs screen
+class Songs: boost::noncopyable {
+  public:
+       /// constructor
+       Songs(Database& database, std::string const& songlist = std::string());
+       ~Songs();
+       /// updates filtered songlist
+       void update();
+       /// reloads songlist
+       void reload();
+       /// array access
+       boost::shared_ptr<Song> operator[](std::size_t pos) { return m_filtered[pos]; }
+       /// number of songs
+       int size() const { return m_filtered.size(); };
+       /// true if empty
+       int empty() const { return m_filtered.empty(); };
+       /// advances to next song
+       void advance(int diff) {
+               int size = m_filtered.size();
+               if (size == 0) return;  // Do nothing if no songs are available
+               int _current = (int(math_cover.getTarget()) + diff) % size;
+               if (_current < 0) _current += size;
+               math_cover.setTarget(_current, size);
+       }
+       /// get current id
+       int currentId() const { return math_cover.getTarget(); }
+       /// gets current position
+       double currentPosition() { return math_cover.getValue(); }
+       /// gets current velocity
+       double currentVelocity() const { return math_cover.getVelocity(); }
+       /// sets margins for animation
+       void setAnimMargins(double left, double right) { math_cover.setMargins(left, right); }
+       /// @return current song
+       boost::shared_ptr<Song> currentPtr() { return m_filtered.empty() ? boost::shared_ptr<Song>() : m_filtered[math_cover.getTarget()]; }
+       /// @return current song
+       Song& current() { return *m_filtered[math_cover.getTarget()]; }
+       /// @return current Song
+       Song const& current() const { return *m_filtered[math_cover.getTarget()]; }
+       /// filters songlist by regular expression
+       void setFilter(std::string const& regex);
+       /// Get the current song type filter number
+       int typeNum() const { return m_type; }
+       /// Description of the current song type filter
+       std::string typeDesc() const;
+       /// Change song type filter (diff is normally -1 or 1; 0 has special meaning of reset)
+       void typeChange(int diff);
+       /// Cycle song type filters by filter category (0 = none, 1..4 = different categories)
+       void typeCycle(int cat);
+       int sortNum() const { return m_order; }
+       /// Description of the current sort mode
+       std::string sortDesc() const;
+       /// Change sorting mode (diff is normally -1 or 1)
+       void sortChange(int diff);
+       /// parses file into Song &tmp
+       void parseFile(Song& tmp);
+
+  private:
+       class RestoreSel;
+       typedef std::vector<boost::shared_ptr<Song> > SongVector;
+       std::string m_songlist;
+       SongVector m_songs, m_filtered;
+       AnimValue m_updateTimer;
+       AnimAcceleration math_cover;
+       std::string m_filter;
+       Database & m_database;
+       int m_type, m_order;
+       void dumpSongs_internal() const;
+       void reload_internal();
+       void reload_internal(fs::path const& p);
+       void randomize_internal();
+       void filter_internal();
+       void sort_internal();
+       volatile bool m_dirty;
+       volatile bool m_loading;
+       boost::scoped_ptr<boost::thread> m_thread;
+       mutable boost::mutex m_mutex;
+};
+
diff --git a/game/surface.cc b/game/surface.cc
new file mode 100644 (file)
index 0000000..13c444e
--- /dev/null
@@ -0,0 +1,206 @@
+#include "surface.hh"
+
+#include "configuration.hh"
+#include "video_driver.hh"
+#include "image.hh"
+#include "screen.hh"
+#include <boost/algorithm/string/case_conv.hpp>
+#include <boost/filesystem.hpp>
+#include <boost/thread/condition.hpp>
+#include <boost/thread/mutex.hpp>
+#include <boost/thread/thread.hpp>
+#include <cctype>
+#include <stdexcept>
+#include <sstream>
+#include <vector>
+
+using std::uint32_t;
+
+Shader& getShader(std::string const& name) {
+       return Game::getSingletonPtr()->window().shader(name);  // FIXME
+}
+
+float Dimensions::screenY() const {
+       switch (m_screenAnchor) {
+         case CENTER: return 0.0;
+         case TOP: return -0.5 * virtH();
+         case BOTTOM: return 0.5 * virtH();
+       }
+       throw std::logic_error("Dimensions::screenY(): unknown m_screenAnchor value");
+}
+
+struct Job {
+       fs::path name;
+       typedef boost::function<void (Bitmap& bitmap)> ApplyFunc;
+       ApplyFunc apply;
+       Bitmap bitmap;
+       Job() {}
+       Job(fs::path const& n, ApplyFunc const& a): name(n), apply(a) {}
+};
+
+class SurfaceLoader::Impl {
+       /// Load a file from disk into a buffer
+       static void load(Bitmap& bitmap, fs::path const& name) {
+               try {
+                       std::string ext = boost::algorithm::to_lower_copy(name.extension().string());
+                       if (!fs::is_regular_file(name)) throw std::runtime_error("File not found: " + name.string());
+                       else if (ext == ".svg") loadSVG(bitmap, name);
+                       else if (ext == ".jpg" || ext == ".jpeg") loadJPEG(bitmap, name);
+                       else if (ext == ".png") loadPNG(bitmap, name);
+                       else throw std::runtime_error("Unknown image file format: " + name.string());
+               } catch (std::exception& e) {
+                       std::clog << "image/error: " << e.what() << std::endl;
+               }
+       }
+       volatile bool m_quit;
+       boost::thread m_thread;
+       boost::mutex m_mutex;
+       boost::condition m_condition;
+       typedef std::map<void const*, Job> Jobs;
+       Jobs m_jobs;
+public:
+       Impl(): m_quit(), m_thread(&Impl::run, this) {}
+       ~Impl() { m_quit = true; m_condition.notify_one(); m_thread.join(); }
+       /// The loader main loop: poll for image load jobs and load into RAM
+       void run() {
+               while (!m_quit) {
+                       void const* target = nullptr;
+                       fs::path name;
+                       {
+                               // Poll for jobs to be done
+                               boost::mutex::scoped_lock l(m_mutex);
+                               for (auto& job: m_jobs) {
+                                       if (job.second.name.empty()) continue;  // Job already done
+                                       name = job.second.name;
+                                       target = job.first;
+                                       break;
+                               }
+                               // If not found, wait for one
+                               if (!target) {
+                                       m_condition.wait(l);
+                                       continue;
+                               }
+                       }
+                       // Load image file into buffer
+                       Bitmap bitmap;
+                       load(bitmap, name);
+                       // Store the result
+                       boost::mutex::scoped_lock l(m_mutex);
+                       auto it = m_jobs.find(target);
+                       if (it == m_jobs.end()) continue;  // The job has been removed already
+                       it->second.name.clear();  // Mark the job completed
+                       it->second.bitmap.swap(bitmap);  // Store the bitmap (if we got any)
+               }
+       }
+       /// Add a new job, using calling Surface's address as unique ID.
+       void push(void const* t, Job const& job) {
+               boost::mutex::scoped_lock l(m_mutex);
+               m_jobs[t] = job;
+               m_condition.notify_one();
+       }
+       /// Cancel a job in progress (no effect if the job has already completed)
+       void remove(void const* t) {
+               boost::mutex::scoped_lock l(m_mutex);
+               m_jobs.erase(t);
+       }
+       /// Upload all completed jobs to OpenGL (must be called from a valid OpenGL context)
+       void apply() {
+               boost::mutex::scoped_lock l(m_mutex);
+               for (auto it = m_jobs.begin(); it != m_jobs.end();) {
+                       {
+                               Job& j = it->second;
+                               if (!j.name.empty()) { ++it; continue; }  // Job incomplete, skip it
+                               j.apply(j.bitmap);  // Upload to OpenGL
+                       }
+                       m_jobs.erase(it++);
+               }
+       }
+};
+
+std::unique_ptr<SurfaceLoader::Impl> ldr = nullptr;
+
+SurfaceLoader::SurfaceLoader() {
+       if (ldr) throw std::logic_error("Surface Loader initialized twice. There can be only one.");
+       ldr.reset(new Impl());
+}
+
+SurfaceLoader::~SurfaceLoader() { ldr.reset(); }
+
+void updateSurfaces() { ldr->apply(); }
+
+template <typename T> void loader(T* target, fs::path const& name) {
+       // Temporarily add 1x1 pixel black texture
+       Bitmap bitmap;
+       bitmap.fmt = pix::RGB;
+       bitmap.resize(1, 1);
+       target->load(bitmap);
+       // Ask the loader to retrieve the image
+       ldr->push(target, Job(name, boost::bind(&T::load, target, _1)));
+}
+
+Surface::Surface(fs::path const& filename) { loader(this, filename); }
+Surface::~Surface() { ldr->remove(this); }
+
+// Stuff for converting pix::Format into OpenGL enum values & other flags
+namespace {
+       struct PixFmt {
+               PixFmt(): swap() {} // Required by std::map
+               PixFmt(GLenum f, GLenum t, bool s): format(f), type(t), swap(s) {}
+               GLenum format;
+               GLenum type;
+               bool swap;  // Reverse byte order
+       };
+       struct PixFormats {
+               typedef std::map<pix::Format, PixFmt> Map;
+               Map m;
+               PixFormats() {
+                       using namespace pix;
+                       m[RGB] = PixFmt(GL_RGB, GL_UNSIGNED_BYTE, false);
+                       m[BGR] = PixFmt(GL_BGR, GL_UNSIGNED_BYTE, true);
+                       m[CHAR_RGBA] = PixFmt(GL_RGBA, GL_UNSIGNED_BYTE, false);
+                       m[INT_ARGB] = PixFmt(GL_BGRA, GL_UNSIGNED_INT_8_8_8_8, true);
+               }
+       } pixFormats;
+       PixFmt const& getPixFmt(pix::Format format) {
+               PixFormats::Map::const_iterator it = pixFormats.m.find(format);
+               if (it != pixFormats.m.end()) return it->second;
+               throw std::logic_error("Unknown pixel format");
+       }
+       GLint internalFormat(bool linear) {
+               return (!linear && GL_EXT_framebuffer_sRGB ? GL_SRGB_ALPHA : GL_RGBA);
+       }
+}
+
+void Surface::load(Bitmap const& bitmap) {
+       glutil::GLErrorChecker glerror("Surface::load");
+       // Initialize dimensions
+       m_width = bitmap.width; m_height = bitmap.height;
+       dimensions = Dimensions(bitmap.ar).fixedWidth(1.0f);
+       m_premultiplied = bitmap.linearPremul;
+       UseTexture texture(*this);
+       // When texture area is small, bilinear filter the closest mipmap
+       glTexParameterf(type(), GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST);
+       // When texture area is large, bilinear filter the original
+       glTexParameterf(type(), GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+       glTexParameterf(type(), GL_TEXTURE_MAX_LEVEL, 4);
+       glerror.check("glTexParameterf");
+
+       // Anisotropy is potential trouble maker
+       if (GLEW_EXT_texture_filter_anisotropic) glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, 16.0f);
+       glerror.check("MAX_ANISOTROPY_EXT");
+
+       // Load the data into texture
+       PixFmt const& f = getPixFmt(bitmap.fmt);
+       glPixelStorei(GL_UNPACK_SWAP_BYTES, f.swap);
+       glTexImage2D(type(), 0, internalFormat(bitmap.linearPremul), bitmap.width, bitmap.height, 0, f.format, f.type, bitmap.data());
+       glGenerateMipmap(type());
+}
+
+void Surface::draw() const {
+       if (empty()) return;
+       // FIXME: This gets image alpha handling right but our ColorMatrix system always assumes premultiplied alpha
+       // (will produce incorrect results for fade effects)
+       glBlendFunc(m_premultiplied ? GL_ONE : GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+       draw(dimensions, TexCoords(tex.x1, tex.y1, tex.x2, tex.y2));
+}
+
diff --git a/game/surface.hh b/game/surface.hh
new file mode 100644 (file)
index 0000000..ed2d3e8
--- /dev/null
@@ -0,0 +1,252 @@
+#pragma once
+
+#include "glutil.hh"
+#include "video_driver.hh"
+#include <boost/noncopyable.hpp>
+#include <boost/shared_ptr.hpp>
+#include <cairo.h>
+#include <algorithm>
+#include <stdexcept>
+#include <string>
+#include <vector>
+
+/// class for geometry stuff
+class Dimensions {
+  public:
+       /** Initialize with aspect ratio but no size, centered at screen center. **/
+       Dimensions(float ar_ = 0.0f): m_ar(ar_), m_x(), m_y(), m_w(), m_h(), m_xAnchor(), m_yAnchor(), m_screenAnchor() {}
+       /** Initialize with top-left corner and width & height **/
+       Dimensions(float x1, float y1, float w, float h): m_ar(), m_x(x1), m_y(y1), m_w(w), m_h(h), m_xAnchor(LEFT), m_yAnchor(TOP), m_screenAnchor() {}
+       /// sets middle
+       Dimensions& middle(float x = 0.0f) { m_x = x; m_xAnchor = MIDDLE; return *this; }
+       /// sets left
+       Dimensions& left(float x = 0.0f) { m_x = x; m_xAnchor = LEFT; return *this; }
+       /// sets right
+       Dimensions& right(float x = 0.0f) { m_x = x; m_xAnchor = RIGHT; return *this; }
+       /// sets center
+       Dimensions& center(float y = 0.0f) { m_y = y; m_yAnchor = CENTER; return *this; }
+       /// sets top
+       Dimensions& top(float y = 0.0f) { m_y = y; m_yAnchor = TOP; return *this; }
+       /// sets bottom
+       Dimensions& bottom(float y = 0.0f) { m_y = y; m_yAnchor = BOTTOM; return *this; }
+       /// reset aspect ratio and switch to fixed width mode
+       Dimensions& ar(float ar) { m_ar = ar; return fixedWidth(m_w); }
+       /// fixes width
+       Dimensions& fixedWidth(float w) { m_w = w; m_h = w / m_ar; return *this; }
+       /// fixes height
+       Dimensions& fixedHeight(float h) { m_w = h * m_ar; m_h = h; return *this; }
+       /// fits inside
+       Dimensions& fitInside(float w, float h) { if (w / h > m_ar) fixedHeight(h); else fixedWidth(w); return *this; }
+       /// fits outside
+       Dimensions& fitOutside(float w, float h) { if (w / h > m_ar) fixedWidth(w); else fixedHeight(h); return *this; }
+       /// stretches dimensions
+       Dimensions& stretch(float w, float h) { m_w = w; m_h = h; m_ar = w / h; return *this; }
+       /// sets screen center
+       Dimensions& screenCenter(float y = 0.0f) { m_screenAnchor = CENTER; center(y); return *this; }
+       /// sets screen top
+       Dimensions& screenTop(float y = 0.0f) { m_screenAnchor = TOP; top(y); return *this; }
+       /// sets screen bottom
+       Dimensions& screenBottom(float y = 0.0f) { m_screenAnchor = BOTTOM; bottom(y); return *this; }
+       /// move the object without affecting anchoring
+       Dimensions& move(float x, float y) { m_x += x; m_y += y; return *this; }
+       /// returns ar XXX
+       float ar() const { return m_ar; }
+       /// returns left
+       float x1() const {
+               switch (m_xAnchor) {
+                 case LEFT: return m_x;
+                 case MIDDLE: return m_x - 0.5 * m_w;
+                 case RIGHT: return m_x - m_w;
+               }
+               throw std::logic_error("Unknown value in Dimensions::m_xAnchor");
+       }
+       /// returns top
+       float y1() const {
+               switch (m_yAnchor) {
+                 case TOP: return screenY() + m_y;
+                 case CENTER: return screenY() + m_y - 0.5 * m_h;
+                 case BOTTOM: return screenY() + m_y - m_h;
+               }
+               throw std::logic_error("Unknown value in Dimensions::m_yAnchor");
+       }
+       /// returns right
+       float x2() const { return x1() + w(); }
+       /// returns bottom
+       float y2() const { return y1() + h(); }
+       /// returns x center
+       float xc() const { return x1() + 0.5 * w(); }
+       /// returns y center
+       float yc() const { return y1() + 0.5 * h(); }
+       /// returns width
+       float w() const { return m_w; }
+       /// returns height
+       float h() const { return m_h; }
+
+  private:
+       float screenY() const;
+       float m_ar;
+       float m_x, m_y, m_w, m_h;
+       enum XAnchor { MIDDLE, LEFT, RIGHT } m_xAnchor;
+       enum YAnchor { CENTER, TOP, BOTTOM } m_yAnchor, m_screenAnchor;
+};
+
+/// texture coordinates
+struct TexCoords {
+       float x1, ///< left
+             y1, ///< top
+             x2, ///< right
+             y2; ///< bottom
+       /// constructor
+       TexCoords(float x1_ = 0.0, float y1_ = 0.0, float x2_ = 1.0, float y2_ = 1.0):
+         x1(x1_), y1(y1_), x2(x2_), y2(y2_) {}
+       bool outOfBounds() const {
+               return test(x1) || test(y1) || test(x2) || test(y2);
+       }
+private:
+       static bool test(float x) { return x < 0.0 || x > 1.0; }
+};
+
+/// This function hides the ugly global vari-- I mean singleton access to ScreenManager...
+Shader& getShader(std::string const& name);
+
+/** @short A RAII wrapper for allocating/deallocating OpenGL texture ID **/
+template <GLenum Type> class OpenGLTexture: boost::noncopyable {
+  public:
+       /// return Type
+       static GLenum type() { return Type; };
+       static Shader& shader() {
+               switch (Type) {
+               case GL_TEXTURE_2D: return getShader("texture");
+               case GL_TEXTURE_RECTANGLE: return getShader("surface");
+               }
+               throw std::logic_error("Unknown texture type");
+       }
+       OpenGLTexture(): m_id() { glGenTextures(1, &m_id); }
+       ~OpenGLTexture() { glDeleteTextures(1, &m_id); }
+       /// returns id
+       GLuint id() const { return m_id; };
+       /// draw in given dimensions, with given texture coordinates
+       void draw(Dimensions const& dim, TexCoords const& tex = TexCoords()) const;
+       /// draw a subsection of the orig dimensions, cropping by tex
+       void drawCropped(Dimensions const& orig, TexCoords const& tex) const;
+  private:
+       GLuint m_id;
+};
+
+/** @short A RAII wrapper for binding to a texture (using it, modifying it) **/
+class UseTexture: boost::noncopyable {
+  public:
+       /// constructor
+       template <GLenum Type> UseTexture(OpenGLTexture<Type> const& tex):
+         m_shader(/* hack of the year */ (glutil::GLErrorChecker("UseTexture"), glActiveTexture(GL_TEXTURE0), glBindTexture(Type, tex.id()), tex.shader())) {}
+
+  private:
+       UseShader m_shader;
+};
+
+template <GLenum Type> void OpenGLTexture<Type>::draw(Dimensions const& dim, TexCoords const& tex) const {
+       glutil::VertexArray va;
+
+       UseTexture texture(*this);
+
+       // The texture wraps over at the edges (repeat)
+       const bool repeating = tex.outOfBounds();
+       glTexParameterf(type(), GL_TEXTURE_WRAP_S, repeating ? GL_REPEAT : GL_CLAMP);
+       glTexParameterf(type(), GL_TEXTURE_WRAP_T, repeating ? GL_REPEAT : GL_CLAMP);
+
+       va.texCoord(tex.x1, tex.y1).vertex(dim.x1(), dim.y1());
+       va.texCoord(tex.x2, tex.y1).vertex(dim.x2(), dim.y1());
+       va.texCoord(tex.x1, tex.y2).vertex(dim.x1(), dim.y2());
+       va.texCoord(tex.x2, tex.y2).vertex(dim.x2(), dim.y2());
+
+       va.draw();
+}
+
+template <GLenum Type> void OpenGLTexture<Type>::drawCropped(Dimensions const& orig, TexCoords const& tex) const {
+       Dimensions dim(
+         orig.x1() + tex.x1 * orig.w(),
+         orig.y1() + tex.y1 * orig.h(),
+         orig.w() * (tex.x2 - tex.x1),
+         orig.h() * (tex.y2 - tex.y1)
+       );
+       draw(dim, tex);
+}
+
+namespace pix { enum Format {
+       INT_ARGB,  // Cairo's pixel format (SVG, text): premultiplied linear RGB (BGRA byte order)
+       CHAR_RGBA,  // libpng w/ alpha: non-premul sRGB (RGBA byte order)
+       RGB,  // libpng w/o alpha, libjpeg, ffmpeg: sRGB (RGB byte order, no padding)
+       BGR  // OpenCV/webcam: sRGB (BGR byte order, no padding)
+}; }
+
+struct Bitmap {
+       std::vector<unsigned char> buf;  // Pixel data if owned by Bitmap
+       unsigned char* ptr;  // Pixel data if owned by someone else
+       unsigned width, height;
+       double ar;  // Aspect ratio
+       double timestamp;  // Used for video frames
+       pix::Format fmt;
+       bool linearPremul;  // Is the data linear RGB and premultiplied (as opposed to sRGB and non-premultiplied)
+       bool bottomFirst;  // Upside-down (only used for taking screenshots)
+       Bitmap(unsigned char* ptr = NULL): ptr(ptr), width(), height(), ar(), timestamp(), fmt(pix::CHAR_RGBA), linearPremul(), bottomFirst() {}
+       void resize(unsigned w, unsigned h) {
+               if (!ptr) buf.resize(w * h * 4); else buf.clear();
+               width = w;
+               height = h;
+               ar = double(w) / h;
+       }
+       void swap(Bitmap& b) {
+               if (ptr || b.ptr) throw std::logic_error("Cannot Bitmap::swap foreign pointers.");
+               buf.swap(b.buf);
+               std::swap(width, b.width);
+               std::swap(height, b.height);
+               std::swap(ar, b.ar);
+               std::swap(timestamp, b.timestamp);
+               std::swap(fmt, b.fmt);
+       }
+       unsigned char const* data() const { return ptr ? ptr : &buf[0]; }
+       unsigned char* data() { return ptr ? ptr : &buf[0]; }
+};
+
+void updateSurfaces();
+
+/**
+* @short High level surface/image wrapper on top of OpenGLTexture
+**/
+class Surface: public OpenGLTexture<GL_TEXTURE_2D> {
+public:
+       struct Impl;
+       /// dimensions
+       Dimensions dimensions;
+       /// texture coordinates
+       TexCoords tex;
+       Surface(): m_width(0), m_height(0), m_premultiplied(true) {}
+       /// creates surface from file
+       Surface(fs::path const& filename);
+       ~Surface();
+       bool empty() const { return m_width * m_height == 0; } ///< Test if the loading has failed
+       /// draws surface
+       void draw() const;
+       using OpenGLTexture<GL_TEXTURE_2D>::draw;
+       /// loads surface into buffer
+       void load(Bitmap const& bitmap);
+       Shader& shader() { return m_texture.shader(); }
+       unsigned width() const { return m_width; }
+       unsigned height() const { return m_height; }
+private:
+       unsigned m_width, m_height;
+       bool m_premultiplied;
+       OpenGLTexture<GL_TEXTURE_2D> m_texture;
+};
+
+typedef Surface Texture;  // Backwards compatibility
+
+/// A RAII wrapper for surface loading worker thread. There must be exactly one (global) instance whenever any Surfaces exist.
+class SurfaceLoader {
+public:
+       SurfaceLoader();
+       ~SurfaceLoader();
+       class Impl;
+};
+
+
diff --git a/game/textinput.hh b/game/textinput.hh
new file mode 100644 (file)
index 0000000..5e7a92f
--- /dev/null
@@ -0,0 +1,57 @@
+#pragma once
+#include <SDL2/SDL.h>
+#include <string>
+
+/// type text
+struct TextInput {
+       /// text to operate on
+       std::string text;
+       /// processes keypresses
+       bool process(SDL_Keysym const& key) {
+               unsigned int ucs = key.sym;  //SDL2.0 uses unicode all the time, so replace with keycode
+                                                                       /* Scancodes are meant to be layout-independent. Think of this as "the user pressed the Q key as it would be on a US QWERTY keyboard" regardless of whether this is actually a European keyboard or a Dvorak keyboard or whatever. The scancode is always the same key position.
+                                                                       Keycodes are meant to be layout-dependent. Think of this as "the user pressed the key that is labelled 'Q' on his specific keyboard." */
+               if (ucs == SDLK_LEFT) return false;
+               if (ucs == SDLK_RIGHT) return false;
+               if (ucs == SDLK_UP) return false;
+               if (ucs == SDLK_DOWN) return false;
+               if (ucs == SDLK_BACKSPACE && !text.empty()) backspace();
+               else if(ucs!= SDLK_LALT && ucs!= SDLK_LCTRL && ucs!= SDLK_LSHIFT && ucs!= SDLK_RALT && ucs!= SDLK_RCTRL && ucs!= SDLK_END && ucs!= SDLK_HOME &&
+                       ucs!= SDLK_RSHIFT && ucs !=SDLK_PAGEDOWN && ucs!= SDLK_PAGEUP && ucs!= SDLK_RETURN && ucs!= SDLK_RETURN2 && ucs!= SDLK_ESCAPE && ucs != SDLK_BACKSPACE)
+               *this += ucs; //I know this is less accurate, but better readable. the old one required you to hold ctrl or shift otherwise textinput didnt work.
+               else return false;
+               return true;
+       }
+       /// appends unicode symbol
+       TextInput& operator+=(unsigned int ucs) { //don't know if this is still relevant since SDL2 handles unicode
+               if (ucs < 0x80) {
+                       text += ucs;
+               } else if (ucs < 0x800) {
+                       text += 0xC0 | (ucs >> 6);
+                       text += 0x80 | (ucs & 0x3F);
+               } else if (ucs < 0x10000) {
+                       text += 0xE0 | (ucs >> 12);
+                       text += 0x80 | ((ucs >> 6) & 0x3F);
+                       text += 0x80 | (ucs & 0x3F);
+               } else {
+                       text += 0xF0 | (ucs >> 18);
+                       text += 0x80 | ((ucs >> 12) & 0x3F);
+                       text += 0x80 | ((ucs >> 6) & 0x3F);
+                       text += 0x80 | (ucs & 0x3F);
+               }
+               return *this;
+       }
+       TextInput& operator+=(char cr[]) {
+               text += cr;
+               return *this;
+       }
+
+       /// deletes last char
+       void backspace() {
+               if (text.empty()) return;
+               std::string::size_type pos = text.size() - 1;
+               while ((text[pos] & 0xC0) == 0x80) --pos;
+               text.erase(pos);
+       }
+};
+
diff --git a/game/theme.cc b/game/theme.cc
new file mode 100644 (file)
index 0000000..c1ee3f4
--- /dev/null
@@ -0,0 +1,82 @@
+#include "theme.hh"
+
+#include "fs.hh"
+#include "configuration.hh"
+
+Theme::Theme()
+{}
+Theme::Theme(fs::path const& path) : bg(path)
+{}
+
+ThemeSongs::ThemeSongs():
+       Theme(findFile("songs_bg.svg")),
+       song(findFile("songs_song.svg"), config["graphic/text_lod"].f()),
+       order(findFile("songs_order.svg"), config["graphic/text_lod"].f()),
+       has_hiscore(findFile("songs_has_hiscore.svg"), config["graphic/text_lod"].f()),
+       hiscores(findFile("songs_hiscores.svg"), config["graphic/text_lod"].f())
+{
+       order.dimensions.screenBottom(-0.03f);
+}
+
+ThemePractice::ThemePractice():
+       Theme(findFile("practice_bg.svg")),
+       note(findFile("practice_note.svg")),
+       sharp(findFile("practice_sharp.svg")),
+       note_txt(findFile("practice_txt.svg"), config["graphic/text_lod"].f())
+{}
+
+ThemeSing::ThemeSing():
+       bg_top(findFile("sing_bg_top.svg")),
+       bg_bottom(findFile("sing_bg_bottom.svg")),
+       lyrics_now(findFile("sing_lyricscurrent.svg"), config["graphic/text_lod"].f()),
+       lyrics_next(findFile("sing_lyricsnext.svg"), config["graphic/text_lod"].f()),
+       timer(findFile("sing_timetxt.svg"), config["graphic/text_lod"].f()),
+       songinfo(findFile("sing-songinfo.svg"), config["graphic/text_lod"].f())
+{
+       lyrics_now.setHighlight(findFile("sing_lyricshighlight.svg"));
+}
+
+ThemeAudioDevices::ThemeAudioDevices():
+       Theme(findFile("audiodevices_bg.svg")),
+       device(findFile("mainmenu_comment.svg"), config["graphic/text_lod"].f()),
+       device_bg(findFile("audiodevices_dev_bg.svg")),
+       comment(findFile("mainmenu_comment.svg"), config["graphic/text_lod"].f()),
+       comment_bg(findFile("mainmenu_comment_bg.svg"))
+{}
+
+ThemeIntro::ThemeIntro():
+       Theme(findFile("intro_bg.svg")),
+       back_h(findFile("mainmenu_back_highlight.svg")),
+       options(30),
+       option_selected(findFile("mainmenu_option_selected.svg"), config["graphic/text_lod"].f()),
+       comment(findFile("mainmenu_comment.svg"), config["graphic/text_lod"].f()),
+       short_comment(findFile("mainmenu_short_comment.svg"), config["graphic/text_lod"].f()),
+       comment_bg(findFile("mainmenu_comment_bg.svg")),
+       short_comment_bg(findFile("mainmenu_scomment_bg.svg"))
+{}
+
+ThemeInstrumentMenu::ThemeInstrumentMenu():
+       Theme(findFile("instrumentmenu_bg.svg")),
+       back_h(findFile("instrumentmenu_back_highlight.svg")),
+       options(30),
+       option_selected(findFile("instrumentmenu_option_selected.svg"), config["graphic/text_lod"].f()),
+       comment(findFile("instrumentmenu_comment.svg"), config["graphic/text_lod"].f())
+       //comment_bg(findFile("menu_comment_bg.svg"))
+{
+       comment.setAlign(SvgTxtTheme::CENTER);
+}
+//at the moment just a copy of themeSong
+ThemePlaylistScreen::ThemePlaylistScreen():
+       Theme(findFile("songs_bg.svg")),
+       options(30),
+       option_selected(findFile("mainmenu_option_selected.svg"), config["graphic/text_lod"].f()),
+       comment(findFile("mainmenu_comment.svg"), config["graphic/text_lod"].f()),
+       short_comment(findFile("mainmenu_short_comment.svg"), config["graphic/text_lod"].f()),
+       comment_bg(findFile("mainmenu_comment_bg.svg")),
+       short_comment_bg(findFile("mainmenu_scomment_bg.svg"))
+{}
+
+SvgTxtTheme& ThemeInstrumentMenu::getCachedOption(const std::string& text) {
+       if (options.contains(text)) return options[text];
+       return *options.insert(text, new SvgTxtTheme(findFile("instrumentmenu_option.svg"), config["graphic/text_lod"].f()))->second;
+}
diff --git a/game/theme.hh b/game/theme.hh
new file mode 100644 (file)
index 0000000..93d296c
--- /dev/null
@@ -0,0 +1,131 @@
+#pragma once
+
+#include "opengl_text.hh"
+#include "surface.hh"
+#include "cachemap.hh"
+#include <boost/noncopyable.hpp>
+#include <string>
+
+/// abstract theme class
+class Theme: boost::noncopyable {
+protected:
+       Theme();
+       Theme(fs::path const& path); ///< creates theme from path
+public:
+       /// background image for theme
+       Surface bg;
+};
+
+/// theme for song selection
+class ThemeSongs: public Theme {
+public:
+       ThemeSongs();
+       /// song display
+       SvgTxtTheme song;
+       /// ordering display
+       SvgTxtTheme order;
+       /// has hiscore display
+       SvgTxtTheme has_hiscore;
+       /// hiscores display
+       SvgTxtTheme hiscores;
+};
+
+/// theme for practice screen
+class ThemePractice: public Theme {
+public:
+       ThemePractice();
+       /// note
+       Surface note;
+       /// sharp sign
+       Surface sharp;
+       /// note name text
+       SvgTxtTheme note_txt;
+};
+
+/// theme for singing screen
+class ThemeSing: public Theme {
+public:
+       ThemeSing();
+       /// top background
+       Surface bg_top;
+       /// bottom background
+       Surface bg_bottom;
+       /// current lyrics line
+       SvgTxtTheme lyrics_now;
+       /// next lyrics line
+       SvgTxtTheme lyrics_next;
+       /// time display
+       SvgTxtTheme timer;
+       /// show the current song info
+       SvgTxtTheme songinfo;
+};
+
+/// theme for audio device screen
+class ThemeAudioDevices: public Theme {
+public:
+       ThemeAudioDevices();
+       /// device item
+       SvgTxtTheme device;
+       /// device item background
+       Surface device_bg;
+       /// comment text
+       SvgTxtTheme comment;
+       /// comment background
+       Surface comment_bg;
+};
+
+/// theme for intro screen
+class ThemeIntro: public Theme {
+public:
+       ThemeIntro();
+       /// back highlight for selected option
+       Surface back_h;
+       /// menu option texts
+       Cachemap<std::string, SvgTxtTheme> options;
+       /// selected menu option text
+       SvgTxtTheme option_selected;
+       /// menu comment text
+       SvgTxtTheme comment;
+       /// configuration comment text (short tip)
+       SvgTxtTheme short_comment;
+       /// configuration comment background
+       Surface comment_bg;
+       /// configuration comment background (short tip)
+       Surface short_comment_bg;
+};
+
+/// theme for instrument menu
+class ThemeInstrumentMenu: public Theme {
+public:
+       ThemeInstrumentMenu();
+       /// back highlight for selected option
+       Surface back_h;
+       /// menu option texts
+       Cachemap<std::string, SvgTxtTheme> options;
+       /// menu selected option text
+       SvgTxtTheme option_selected;
+       /// menu comment text
+       SvgTxtTheme comment;
+       /// menu comment background
+       //Surface comment_bg;
+       /// get a cached option test
+       SvgTxtTheme& getCachedOption(const std::string& text);
+};
+
+//at the moment just a copy of ThemeSongs
+class ThemePlaylistScreen: public Theme {
+public:
+       ThemePlaylistScreen();
+       /// menu option texts
+       Cachemap<std::string, SvgTxtTheme> options;
+       /// selected menu option text
+       SvgTxtTheme option_selected;
+       /// menu comment text
+       SvgTxtTheme comment;
+       /// configuration comment text (short tip)
+       SvgTxtTheme short_comment;
+       /// configuration comment background
+       Surface comment_bg;
+       /// configuration comment background (short tip)
+       Surface short_comment_bg;
+};
diff --git a/game/unicode.cc b/game/unicode.cc
new file mode 100644 (file)
index 0000000..e2796ce
--- /dev/null
@@ -0,0 +1,70 @@
+#include "unicode.hh"
+#include "configuration.hh"
+
+#include <boost/scoped_ptr.hpp>
+#include <glibmm/ustring.h>
+#include <glib.h>
+#include <sstream>
+#include <stdexcept>
+
+namespace {
+       // Codepage choices from config
+       static const char* codesets[] = { "CP1250", "CP1251", "CP1252", "CP1253", "CP1254", "CP1255", "CP1256", "CP1257", "CP1258" };
+
+       // Convert a string using Glib, throw exception on error.
+       // This is in fact (slightly modified) Glib::convert from glibmm.
+       std::string convert(const std::string& str, const std::string& to_codeset, const std::string& from_codeset) {
+               gsize bytes_written = 0;
+               GError* gerror = nullptr;
+
+               char *const buf = g_convert(
+                 str.data(), str.size(), to_codeset.c_str(), from_codeset.c_str(),
+                 nullptr, &bytes_written, &gerror);
+
+               if (gerror) throw std::runtime_error("Conversion error"); // Throw on error
+               std::string ret(buf, bytes_written);
+               g_free(buf);
+               return ret;
+       }
+}
+
+void convertToUTF8(std::stringstream &_stream, std::string _filename) {
+       try {
+               std::string data = _stream.str();
+               convert(data, "UTF-8", "UTF-8"); // Test if input is UTF-8
+               if (data.substr(0, 3) == "\xEF\xBB\xBF") {
+                       std::clog << "unicode/warning: " << _filename << " UTF-8 BOM ignored. Please avoid editors that use BOMs (e.g. Notepad)." << std::endl;
+                       _stream.str(data.substr(3)); // Remove BOM if there is one
+               }
+       } catch(...) {
+               const char* codeset = codesets[config["game/fallback_encoding"].i()];
+               if (!_filename.empty())
+                       std::clog << "unicode/warning: " << _filename << " is not UTF-8.\n  Assuming " << codeset
+                               << ". Use recode " << codeset << "..UTF-8 */*.txt to convert your files." << std::endl;
+               try {
+                       _stream.str(convert(_stream.str(), "UTF-8", codeset)); // Convert from fallback encoding
+               } catch (...) {
+                       // Filter out anything but ASCII
+                       std::string tmp;
+                       for (char ch; _stream.get(ch);) tmp += (ch >= 0x20 && ch < 0x7F) ? ch : '?';
+               }
+       }
+}
+
+std::string convertToUTF8(std::string const& str) {
+       std::stringstream ss(str);
+       convertToUTF8(ss);
+       return ss.str();
+}
+
+std::string unicodeCollate(std::string const& str) {
+       Glib::ustring ustr = str, ustr2;
+       if (ustr.substr(0, 4) == "The ") ustr = ustr.substr(4) + "the";
+       if (ustr.substr(0, 2) == "A ") ustr = ustr.substr(2) + "a";
+       // Remove all non-alnum characters
+       for (Glib::ustring::iterator it = ustr.begin(), end = ustr.end(); it != end; ++it) {
+               if (Glib::Unicode::isalnum(*it)) ustr2 += Glib::Unicode::tolower(*it);
+       }
+       return ustr2;
+       // Should use ustr2.casefold_collate_key() instead of tolower, but it seems to be crashing...
+}
diff --git a/game/unicode.hh b/game/unicode.hh
new file mode 100644 (file)
index 0000000..95f3784
--- /dev/null
@@ -0,0 +1,8 @@
+#pragma once
+
+#include <iostream>
+#include <string>
+
+void convertToUTF8(std::stringstream &_stream, std::string _filename = std::string());
+std::string convertToUTF8(std::string const& str);
+std::string unicodeCollate(std::string const& str);
diff --git a/game/util.cc b/game/util.cc
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/game/util.hh b/game/util.hh
new file mode 100644 (file)
index 0000000..f07753d
--- /dev/null
@@ -0,0 +1,45 @@
+#pragma once
+
+#include <cstdint>
+#include <limits>
+#include <vector>
+#include <stdexcept>
+
+/** Limit val to range [min, max] **/
+template <typename T> T clamp(T val, T min = 0, T max = 1) {
+       if (min > max) throw std::logic_error("min > max");
+       if (val < min) return min;
+       if (val > max) return max;
+       return val;
+}
+
+template <typename Numeric> struct MinMax {
+       Numeric min, max;
+       explicit MinMax(Numeric min = std::numeric_limits<Numeric>::min(), Numeric max = std::numeric_limits<Numeric>::max()): min(min), max(max) {}
+       bool matches(Numeric val) const { return val >= min && val <= max; }
+};
+
+/** A convenient way for getting NaNs **/
+static inline double getNaN() { return std::numeric_limits<double>::quiet_NaN(); }
+
+/** A convenient way for getting infs **/
+static inline double getInf() { return std::numeric_limits<double>::infinity(); }
+
+static inline bool isPow2(unsigned int val) {
+       if (val == 0) return false;
+       if ((val & (val-1)) == 0) return true; // From Wikipedia: Power_of_two
+       return false;
+}
+
+static inline unsigned int nextPow2(unsigned int val) {
+       unsigned int ret = 1;
+       while (ret < val) ret *= 2;
+       return ret;
+}
+
+static inline unsigned int prevPow2(unsigned int val) {
+       unsigned int ret = 1;
+       while ((ret*2) < val) ret *= 2;
+       return ret;
+}
+
diff --git a/game/video.cc b/game/video.cc
new file mode 100644 (file)
index 0000000..3bc9bae
--- /dev/null
@@ -0,0 +1,36 @@
+#include "video.hh"
+
+#include "util.hh"
+#include <cmath>
+
+Video::Video(fs::path const& _videoFile, double videoGap): m_mpeg(_videoFile), m_videoGap(videoGap), m_surfaceTime(), m_lastTime(), m_alpha(-0.5, 1.5) {}
+
+void Video::prepare(double time) {
+       time += m_videoGap;
+       Bitmap& fr = m_videoFrame;
+       // Time to switch frame?
+       if (!fr.buf.empty() && time >= fr.timestamp) {
+               m_surface.load(fr);
+               m_surfaceTime = fr.timestamp;
+               fr.resize(0, 0);
+       }
+       // Preload the next future frame
+       if (fr.buf.empty()) while (m_mpeg.videoQueue.tryPop(fr) && fr.timestamp < time) {};
+       // Do a seek before next render, if required
+       if (time < m_lastTime - 1.0 || (!fr.buf.empty() && time > fr.timestamp + 7.0)) {
+               m_mpeg.seek(std::max(0.0, time - 5.0));  // -5 to workaround ffmpeg inaccurate seeking
+               fr.buf.clear();
+       }
+       m_lastTime = time;
+}
+
+void Video::render(double time) {
+       time += m_videoGap;
+       double tdist = std::abs(m_surfaceTime - time);
+       m_alpha.setTarget(tdist < 0.4 ? 1.2f : -0.5f);
+       double alpha = clamp(m_alpha.get());
+       if (alpha == 0.0) return;
+       ColorTrans c(Color::alpha(alpha));
+       m_surface.draw();
+}
+
diff --git a/game/video.hh b/game/video.hh
new file mode 100644 (file)
index 0000000..61aff7e
--- /dev/null
@@ -0,0 +1,29 @@
+#pragma once
+
+#include "animvalue.hh"
+#include "surface.hh"
+#include "ffmpeg.hh"
+#include <string>
+   
+/// class for playing videos  
+class Video {
+  public:
+       /// opens given video file
+       Video(fs::path const& videoFile, double videoGap = 0.0);
+       void prepare(double time);  ///< Load the current video frame into a texture
+       void render(double time);  ///< Render the prepared video frame
+       /// returns Dimensions of video clip
+       Dimensions& dimensions() { return m_surface.dimensions; }
+       /// returns Dimensions of video clip
+       Dimensions const& dimensions() const { return m_surface.dimensions; }
+
+  private:
+       FFmpeg m_mpeg;
+       double m_videoGap;
+       Bitmap m_videoFrame;
+       Surface m_surface;
+       double m_surfaceTime;
+       double m_lastTime;
+       AnimValue m_alpha;
+};
+
diff --git a/game/video_driver.cc b/game/video_driver.cc
new file mode 100644 (file)
index 0000000..13ef0e9
--- /dev/null
@@ -0,0 +1,420 @@
+#include "video_driver.hh"
+
+#include "config.hh"
+#include "fbo.hh"
+#include "fs.hh"
+#include "glmath.hh"
+#include "image.hh"
+#include "util.hh"
+#include "controllers.hh"
+#include "screen.hh"
+#include <boost/date_time.hpp>
+
+
+#ifndef GLEW_ARB_viewport_array
+# define GLEW_ARB_viewport_array GL_FALSE
+# define glViewportIndexedf(index, x, y,  w,  h) {}
+# warning "Your version of GLEW is too old, Performous is smart and let you compile it anyway"
+#endif
+#ifndef GLEW_VERSION_3_3
+# define GLEW_VERSION_3_3 GL_FALSE
+# warning "Your version of GLEW is too old, Performous is smart and let you compile it anyway"
+#endif
+#ifndef GLEW_VERSION_4_1
+# define GLEW_VERSION_4_1 GL_FALSE
+# warning "Your version of GLEW is too old, Performous is smart and let you compile it anyway"
+#endif
+
+
+namespace {
+       unsigned s_width;
+       unsigned s_height;
+       /// Attempt to set attribute and report errors.
+       /// Tests for success when destoryed.
+       struct GLattrSetter {
+               GLattrSetter(SDL_GLattr attr, int value): m_attr(attr), m_value(value) {
+                       if (SDL_GL_SetAttribute(attr, value)) std::clog << "video/warning: Error setting GLattr " << m_attr << std::endl;
+               }
+               ~GLattrSetter() {
+                       int value;
+                       SDL_GL_GetAttribute(m_attr, &value);
+                       if (value != m_value)
+                               std::clog << "video/warning: Error setting GLattr " << m_attr
+                               << ": requested " << m_value << ", got " << value << std::endl;
+               }
+               SDL_GLattr m_attr;
+               int m_value;
+       };
+
+       double getSeparation() {
+               return config["graphic/stereo3d"].b() ? 0.001f * config["graphic/stereo3dseparation"].f() : 0.0;
+       }
+
+       // stump: under MSVC, near and far are #defined to nothing for compatibility with ancient code, hence the underscores.
+       const float near_ = 0.1f; // This determines the near clipping distance (must be > 0)
+       const float far_ = 110.0f; // How far away can things be seen
+       const float z0 = 1.5f; // This determines FOV: the value is your distance from the monitor (the unit being the width of the Performous window)
+
+       glmath::mat4 g_color = glmath::mat4::identity();
+       glmath::mat4 g_projection = glmath::mat4::identity();
+       glmath::mat4 g_modelview =  glmath::mat4::identity();
+}
+
+unsigned int screenW() { return s_width; }
+unsigned int screenH() { return s_height; }
+
+Window::Window(unsigned int width, unsigned int height, bool fs): m_windowW(width), m_windowH(height), m_fullscreen(fs), screen() {
+       std::atexit(SDL_Quit);
+       if (SDL_Init(SDL_INIT_VIDEO|SDL_INIT_JOYSTICK))
+               throw std::runtime_error(std::string("SDL_Init failed: ") + SDL_GetError());
+       SDL_JoystickEventState(SDL_ENABLE);
+       SDL_SetWindowTitle(screen, PACKAGE " " VERSION);
+       {
+               SDL_Surface* icon = SDL_LoadBMP(findFile("icon.bmp").string().c_str());
+               SDL_SetWindowIcon(screen,icon);
+               SDL_FreeSurface(icon);
+       }
+       // SDL_SetVideoMode not called yet => get the desktop resolution for fs mode
+       SDL_DisplayMode current;
+       for(int i = 0; i < SDL_GetNumVideoDisplays(); ++i){
+               int should_be_zero = SDL_GetCurrentDisplayMode(i, &current);
+               if(should_be_zero != 0) throw std::runtime_error("Could not get display mode for video display");
+       }
+       std::clog << "video/info: Current display resolution is: " << current.w << "x" << current.h << std::endl;
+       m_fsW = current.w;
+       m_fsH = current.h;
+       { // Setup GL attributes for context creation
+               GLattrSetter attr_r(SDL_GL_RED_SIZE, 8);
+               GLattrSetter attr_g(SDL_GL_GREEN_SIZE, 8);
+               GLattrSetter attr_b(SDL_GL_BLUE_SIZE, 8);
+               GLattrSetter attr_a(SDL_GL_ALPHA_SIZE, 8);
+               GLattrSetter attr_buf(SDL_GL_BUFFER_SIZE, 32);
+               GLattrSetter attr_d(SDL_GL_DEPTH_SIZE, 24);
+               GLattrSetter attr_db(SDL_GL_DOUBLEBUFFER, 1);
+               if(width < 200) width = 640; //FIXME: window should have a minimum size
+               if(height < 200) height = 480;
+               screen = SDL_CreateWindow(PACKAGE " " VERSION, SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, width, height,
+                       (m_fullscreen ? SDL_WINDOW_FULLSCREEN_DESKTOP : 0) | SDL_WINDOW_RESIZABLE | SDL_WINDOW_OPENGL);
+               if (!screen) throw std::runtime_error(std::string("SDL_SetVideoMode failed: ") + SDL_GetError());
+               SDL_GL_CreateContext(screen);
+
+       }
+       if (!m_fullscreen) {
+               config["graphic/window_width"].i() = s_width;
+               config["graphic/window_height"].i() = s_height;
+       }
+       resize();
+       SDL_ShowCursor(SDL_DISABLE);
+       if (glewInit() != GLEW_OK) throw std::runtime_error("Initializing GLEW failed (is your OpenGL broken?)");
+       // Dump some OpenGL info
+       std::clog << "video/info: GL_VENDOR:     " << glGetString(GL_VENDOR) << std::endl;
+       std::clog << "video/info: GL_VERSION:    " << glGetString(GL_VERSION) << std::endl;
+       std::clog << "video/info: GL_RENDERER:   " << glGetString(GL_RENDERER) << std::endl;
+       // Extensions would need more complex outputting, otherwise they will break clog.
+       //std::clog << "video/info: GL_EXTENSIONS: " << glGetString(GL_EXTENSIONS) << std::endl;
+
+       if (!GLEW_VERSION_2_1) throw std::runtime_error("OpenGL 2.1 is required but not available");
+
+       if (GLEW_VERSION_3_3) {
+               // Compile geometry shaders when stereo is requested
+               shader("color").compileFile(findFile("shaders/stereo3d.geom"));
+               shader("surface").compileFile(findFile("shaders/stereo3d.geom"));
+               shader("texture").compileFile(findFile("shaders/stereo3d.geom"));
+               shader("3dobject").compileFile(findFile("shaders/stereo3d.geom"));
+               shader("dancenote").compileFile(findFile("shaders/stereo3d.geom"));
+               if (!GLEW_VERSION_4_1) {
+                       // Enable bugfix for some older Nvidia cards
+                       for (ShaderMap::iterator it = m_shaders.begin(); it != m_shaders.end(); ++it) {
+                               Shader& sh = *it->second;
+                               sh.addDefines("#define ENABLE_BOGUS\n");
+                       }
+               }
+       }
+
+       shader("color")
+         .addDefines("#define ENABLE_VERTEX_COLOR\n")
+         .compileFile(findFile("shaders/core.vert"))
+         .compileFile(findFile("shaders/core.frag"))
+         .link();
+       shader("surface")
+         .addDefines("#define ENABLE_TEXTURING 1\n")
+         .compileFile(findFile("shaders/core.vert"))
+         .compileFile(findFile("shaders/core.frag"))
+         .link();
+       shader("texture")
+         .addDefines("#define ENABLE_TEXTURING 2\n")
+         .addDefines("#define ENABLE_VERTEX_COLOR\n")
+         .compileFile(findFile("shaders/core.vert"))
+         .compileFile(findFile("shaders/core.frag"))
+         .link();
+       shader("3dobject")
+         .addDefines("#define ENABLE_LIGHTING\n")
+         .compileFile(findFile("shaders/core.vert"))
+         .compileFile(findFile("shaders/core.frag"))
+         .link();
+       shader("dancenote")
+         .addDefines("#define ENABLE_TEXTURING 2\n")
+         .addDefines("#define ENABLE_VERTEX_COLOR\n")
+         .compileFile(findFile("shaders/dancenote.vert"))
+         .compileFile(findFile("shaders/core.frag"))
+         .link();
+
+       updateColor();
+       view(0);  // For loading screens
+}
+
+Window::~Window() { }
+
+void Window::blank() {
+       glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+}
+
+void Window::updateStereo(float sepFactor) {
+       for (ShaderMap::iterator it = m_shaders.begin(); it != m_shaders.end(); ++it) {
+               Shader& sh = *it->second;
+               sh.bind();
+               try {
+                       sh["sepFactor"].set(sepFactor);
+                       sh["z0"].set(z0 - 2.0f * near_);  // Why minus two times zNear, I have no idea -Tronic
+               } catch(...) {}  // Not fatal if 3d shader is missing
+       }
+}
+
+void Window::updateColor() {
+       for (ShaderMap::iterator it = m_shaders.begin(); it != m_shaders.end(); ++it) {
+               Shader& sh = *it->second;
+               sh["colorMatrix"].setMat4(g_color);
+       }
+}
+
+void Window::updateTransforms() {
+       using namespace glmath;
+       mat3 normal(g_modelview);
+       for (ShaderMap::iterator it = m_shaders.begin(); it != m_shaders.end(); ++it) {
+               Shader& sh = *it->second;
+               sh.bind();
+               sh["projMatrix"].setMat4(g_projection);
+               sh["mvMatrix"].setMat4(g_modelview);
+               try {
+                       sh["normalMatrix"].setMat3(normal);
+               } catch(...) {}  // Not fatal if normalMatrix is missing (only 3d objects use it)
+       }
+}
+
+void Window::render(boost::function<void (void)> drawFunc) {
+       glutil::GLErrorChecker glerror("Window::render");
+       ViewTrans trans;  // Default frustum
+       bool stereo = config["graphic/stereo3d"].b();
+       int type = config["graphic/stereo3dtype"].i();
+
+       if (stereo && !GLEW_ARB_viewport_array) {
+               config["graphic/stereo3d"].b() = stereo = false;
+               std::clog << "video/warning: Your GPU does not support Stereo3D mode (OpenGL extension ARB_viewport_array is required)" << std::endl;
+               // TODO: Flash message on UI?
+       }
+
+       // Over/under only available in fullscreen
+       if (stereo && type == 2 && !m_fullscreen) stereo = false;
+
+       glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+       updateStereo(stereo ? getSeparation() : 0.0);
+       glerror.check("setup");
+       // Can we do direct to framebuffer rendering (no FBO)?
+       if (!stereo || type == 2) { view(stereo); drawFunc(); return; }
+       // Render both eyes to FBO (full resolution top/bottom for anaglyph)
+       unsigned w = s_width;
+       unsigned h = 2 * s_height;
+       FBO fbo(w, h);
+       glerror.check("FBO");
+       {
+               UseFBO user(fbo);
+               view(0);
+               glViewportIndexedf(1, 0, h / 2, w, h / 2);
+               glViewportIndexedf(2, 0, 0, w, h / 2);
+               drawFunc();
+       }
+       glerror.check("Render to FBO");
+       // Render to actual framebuffer from FBOs
+       UseTexture use(fbo.getTexture());
+       view(0);  // Viewport for drawable area
+       glDisable(GL_BLEND);
+       glmath::mat4 colorMatrix = glmath::mat4::identity();
+       updateStereo(0.0);  // Disable stereo mode while we composite
+       glerror.check("FBO->FB setup");
+       for (int num = 0; num < 2; ++num) {
+               {
+                       float saturation = 0.5;  // (0..1)
+                       float col = (1.0 + 2.0 * saturation) / 3.0;
+                       float gry = 0.5 * (1.0 - col);
+                       bool out[3] = {};  // Which colors to output
+                       if (type == 0 && num == 0) { out[0] = true; }  // Red
+                       if (type == 0 && num == 1) { out[1] = out[2] = true; }  // Cyan
+                       if (type == 1 && num == 0) { out[1] = true; }  // Green
+                       if (type == 1 && num == 1) { out[0] = out[2] = true; }  // Magenta
+                       for (unsigned i = 0; i < 3; ++i) {
+                               for (unsigned j = 0; j < 3; ++j) {
+                                       double val = 0.0;
+                                       if (out[i]) val = (i == j ? col : gry);
+                                       colorMatrix(i, j) = val;
+                               }
+                       }
+               }
+               // Render FBO with 1:1 pixels, properly filtered/positioned for 3d
+               ColorTrans c(colorMatrix);
+               Dimensions dim = Dimensions(double(w) / h).fixedWidth(1.0);
+               dim.center((num == 0 ? 0.25 : -0.25) * dim.h());
+               if (num == 1) {
+                       // Right eye blends over the left eye
+                       glEnable(GL_BLEND);
+                       glBlendFunc(GL_ONE, GL_ONE);
+               }
+               fbo.getTexture().draw(dim, TexCoords(0.0, h, w, 0));
+       }
+       glerror.check("FBO->FB postcondition");
+}
+
+void Window::view(unsigned num) {
+       glutil::GLErrorChecker glerror("Window::view");
+       // Set flags
+       glClearColor (0.0f, 0.0f, 0.0f, 1.0f);
+       glDisable(GL_DEPTH_TEST);
+       glDisable(GL_CULL_FACE);
+       glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+       glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
+       glShadeModel(GL_SMOOTH);
+       glEnable(GL_BLEND);
+       if (GL_EXT_framebuffer_sRGB) glEnable(GL_FRAMEBUFFER_SRGB);
+       shader("color").bind();
+       // Setup views (with black bars for cropping)
+       int windowWidth;
+       int windowHeight;
+       SDL_GetWindowSize(screen, &windowWidth, &windowHeight);
+       double vx = 0.5f * (windowWidth - s_width);
+       double vy = 0.5f * (windowHeight - s_height);
+       double vw = s_width, vh = s_height;
+       if (num == 0) {
+               glViewport(vx, vy, vw, vh);  // Drawable area of the window (excluding black bars)
+       } else {
+               // Splitscreen stereo3d
+               if (windowWidth == 1280 && windowHeight == 1470) {  // HDMI 720p 3D mode
+                       glViewportIndexedf(1, 0, 750, 1280, 720);
+                       glViewportIndexedf(2, 0, 0, 1280, 720);
+                       s_width = 1280;
+                       s_height = 720;
+               } else if (windowWidth == 1920 && windowHeight == 2205) {  // HDMI 1080p 3D mode
+                       glViewportIndexedf(1, 0, 1125, 1920, 1080);
+                       glViewportIndexedf(2, 0, 0, 1920, 1080);
+                       s_width = 1920;
+                       s_height = 1080;
+               } else {  // Regular top/bottom 3d
+                       glViewportIndexedf(1, 0, vh / 2, vw, vh / 2);  // Top half of the drawable area
+                       glViewportIndexedf(2, 0, 0, vw, vh / 2);  // Bottom half of the drawable area
+               }
+       }
+
+}
+
+void Window::swap() {
+       SDL_GL_SwapWindow(screen);
+}
+
+void Window::setFullscreen(bool _fs) {
+       if (m_fullscreen == _fs) return;
+       m_fullscreen = _fs;
+       SDL_SetWindowFullscreen(screen, (m_fullscreen? SDL_WINDOW_FULLSCREEN_DESKTOP : 0 ));
+       resize();
+}
+
+void Window::resize() {
+       unsigned width = m_fullscreen ? m_fsW : m_windowW;
+       unsigned height = m_fullscreen ? m_fsH : m_windowH;
+       glViewport(0,0,width,height);
+       int windowWidth;
+       int windowHeight;
+       SDL_GetWindowSize(screen, &windowWidth, &windowHeight);
+       s_width = windowWidth;
+       s_height = windowHeight;
+       // Enforce aspect ratio limits
+       if (s_height < 0.56f * s_width) s_width = round(s_height / 0.56f);
+       if (s_height > 0.8f * s_width) s_height = round(0.8f * s_width);
+}
+
+void Window::screenshot() {
+       Bitmap img;
+       img.width = m_fullscreen ? m_fsW : m_windowW;
+       img.height = m_fullscreen ? m_fsH : m_windowH;
+       unsigned stride = (img.width * 3 + 3) & ~3;  // Rows are aligned to 4 byte boundaries
+       img.buf.resize(stride * img.height);
+       img.fmt = pix::RGB;
+       img.bottomFirst = true;
+       // Get pixel data from OpenGL
+       glReadPixels(0, 0, img.width, img.height, GL_RGB, GL_UNSIGNED_BYTE, img.data());
+       // Compose filename from timestamp
+       fs::path filename = getHomeDir() / ("Performous_" + to_iso_string(boost::posix_time::second_clock::local_time()) + ".png");
+       // Save to disk
+       writePNG(filename.string(), img, stride);
+       std::clog << "video/info: Screenshot taken: " << filename << " (" << img.width << "x" << img.height << ")" << std::endl;
+}
+
+ColorTrans::ColorTrans(Color const& c): m_old(g_color) {
+       using namespace glmath;
+       g_color = g_color * mat4::diagonal(c.linear());
+       Game::getSingletonPtr()->window().updateColor();
+}
+
+ColorTrans::ColorTrans(glmath::mat4 const& mat): m_old(g_color) {
+       g_color = g_color * mat;
+       Game::getSingletonPtr()->window().updateColor();
+}
+
+ColorTrans::~ColorTrans() {
+       g_color = m_old;
+       Game::getSingletonPtr()->window().updateColor();
+}
+
+ViewTrans::ViewTrans(double offsetX, double offsetY, double frac): m_old(g_projection) {
+       // Setup the projection matrix for 2D translates
+       using namespace glmath;
+       double h = virtH();
+       const double f = near_ / z0;  // z0 to nearplane conversion factor
+       // Corners of the screen at z0
+       double x1 = -0.5, x2 = 0.5;
+       double y1 = 0.5 * h, y2 = -0.5 * h;
+       // Move the perspective point by frac of offset (i.e. move the image)
+       double persX = frac * offsetX, persY = frac * offsetY;
+       x1 -= persX; x2 -= persX;
+       y1 -= persY; y2 -= persY;
+       // Perspective projection + the rest of the offset in eye (world) space
+       g_projection = frustum(f * x1, f * x2, f * y1, f * y2, near_, far_)
+         * translate(vec3(offsetX - persX, offsetY - persY, -z0));
+       Game::getSingletonPtr()->window().updateTransforms();
+}
+
+ViewTrans::ViewTrans(glmath::mat4 const& m): m_old(g_projection) {
+       g_projection = g_projection * m;
+       Game::getSingletonPtr()->window().updateTransforms();
+}
+
+ViewTrans::~ViewTrans() {
+       g_projection = m_old;
+       Game::getSingletonPtr()->window().updateTransforms();
+}
+
+Transform::Transform(glmath::mat4 const& m): m_old(g_modelview) {
+       g_modelview = g_modelview * m;
+       Game::getSingletonPtr()->window().updateTransforms();
+}
+
+Transform::~Transform() {
+       g_modelview = m_old;
+       Game::getSingletonPtr()->window().updateTransforms();
+}
+
+glmath::mat4 farTransform() {
+       float z = far_ - 0.1f;  // Very near the far plane but just a bit closer to avoid accidental clipping
+       float s = z / z0;  // Scale the image so that it looks the same size
+       s *= 1.0 + 2.0 * getSeparation(); // A bit more for stereo3d (avoid black borders)
+       using namespace glmath;
+       return translate(vec3(0.0f, 0.0f, -z + z0)) * scale(s); // Very near the farplane
+}
+
diff --git a/game/video_driver.hh b/game/video_driver.hh
new file mode 100644 (file)
index 0000000..f9930fa
--- /dev/null
@@ -0,0 +1,99 @@
+#pragma once
+
+#include "glmath.hh"
+#include "glshader.hh"
+#include "glutil.hh"
+#include <boost/function.hpp>
+#include <boost/ptr_container/ptr_map.hpp>
+
+unsigned int screenW();
+unsigned int screenH();
+static inline float virtH() { return float(screenH()) / screenW(); }
+
+struct SDL_Surface;
+struct SDL_Window;
+
+struct ColorTrans {
+       ColorTrans(Color const& c);
+       ColorTrans(glmath::mat4 const& mat);
+       ~ColorTrans();
+private:
+       glmath::mat4 m_old;
+};
+
+class ViewTrans {
+public:
+       /// Apply a translation on top of current viewport translation
+       ViewTrans(glmath::mat4 const& m);
+       /// Apply a subviewport with different perspective projection
+       ViewTrans(double offsetX = 0.0, double offsetY = 0.0, double frac = 1.0);
+       ~ViewTrans();
+private:
+       glmath::mat4 m_old;
+};
+
+/// Apply a transform to current modelview stack
+class Transform {
+public:
+       Transform(glmath::mat4 const& m);
+       ~Transform();
+private:
+       glmath::mat4 m_old;
+};
+
+/// Performs a GL transform for displaying background image at far distance
+glmath::mat4 farTransform();
+
+/// handles the window
+class Window {
+public:
+       /// constructor
+       Window(unsigned int windowW, unsigned int windowH, bool fullscreen);
+       /// destructor
+       ~Window();
+       void render(boost::function<void (void)> drawFunc);
+       /// clears window
+       void blank();
+       /// swaps buffers
+       void swap();
+       /// Handler for SDL_VIDEORESIZE event (window resized by the user)
+       /** @param width the new width
+        * @param height the new height
+        */
+       void resize(unsigned width, unsigned height) {
+               if (m_fullscreen) return;  // Ignore window resize events when in fullscreen (gives bogus size on Gnome 3 and others).
+               m_windowW = width; m_windowH = height;
+               resize();
+       }
+       /// Resize window (contents) / toggle full screen according to m_fullscreen
+       void resize();
+       /// sets fullscreen
+       /** @param _fs true for fullscreen
+        */
+       void setFullscreen(bool _fs);
+       bool getFullscreen() const { return m_fullscreen; }
+       /// take a screenshot
+       void screenshot();
+
+       /// Construct a new shader or return an existing one by name
+       Shader& shader(std::string const& name) {
+               ShaderMap::iterator it = m_shaders.find(name);
+               if (it != m_shaders.end()) return *it->second;
+               // const_cast required to workaround ptr_map's protection against construction of temporaries
+               return *m_shaders.insert(const_cast<std::string&>(name), new Shader(name)).first->second;
+       }
+       void updateColor();
+       void updateTransforms();
+private:
+       /// Setup everything for drawing a view.
+       /// @param num 0 = no stereo, 1 = left eye, 2 = right eye
+       void view(unsigned num);
+       void updateStereo(float separation);
+       unsigned int m_windowW, m_windowH;
+       unsigned int m_fsW, m_fsH;
+       bool m_fullscreen;
+       typedef boost::ptr_map<std::string, Shader> ShaderMap;
+       ShaderMap m_shaders; ///< Shader programs by name
+       SDL_Window *screen;
+};
+
diff --git a/game/webcam.cc b/game/webcam.cc
new file mode 100644 (file)
index 0000000..1ce9094
--- /dev/null
@@ -0,0 +1,123 @@
+#include <iostream>
+#include <stdexcept>
+
+#include "webcam.hh"
+#include "xtime.hh"
+#include "fs.hh"
+
+#ifdef USE_OPENCV
+#include <opencv2/opencv.hpp>
+
+#else
+// Dummy classes
+namespace cv {
+       class VideoCapture {};
+       class VideoWriter {};
+}
+#endif
+
+Webcam::Webcam(int cam_id):
+  m_thread(), m_capture(), m_writer(), m_frameAvailable(false), m_running(false), m_quit(false)
+  {
+       #ifdef USE_OPENCV
+       // Initialize the capture device
+       m_capture.reset(new cv::VideoCapture(cam_id));
+       if (!m_capture->isOpened()) {
+               if (cam_id != -1) {
+                       std::clog << "Webcam/warning: Webcam id " << cam_id << " failed, trying autodetecting...";
+                       m_capture.reset(new cv::VideoCapture(-1));
+               }
+               if (!m_capture->isOpened())
+                       throw std::runtime_error("Could not initialize webcam capturing!");
+       }
+       // Try to get at least VGA resolution
+       if (m_capture->get(CV_CAP_PROP_FRAME_WIDTH) < 640
+         || m_capture->get(CV_CAP_PROP_FRAME_HEIGHT) < 480) {
+               m_capture->set(CV_CAP_PROP_FRAME_WIDTH, 640);
+               m_capture->set(CV_CAP_PROP_FRAME_HEIGHT, 480);
+       }
+       // Print actual values
+       std::cout << "Webcam frame properties: "
+         << m_capture->get(CV_CAP_PROP_FRAME_WIDTH) << "x"
+         << m_capture->get(CV_CAP_PROP_FRAME_HEIGHT) << std::endl;
+
+       // Initialize the video writer
+       #ifdef SAVE_WEBCAM_VIDEO
+       float fps = m_capture->get(CV_CAP_PROP_FPS);
+       int framew = m_capture->get(CV_CAP_PROP_FRAME_WIDTH);
+       int frameh = m_capture->get(CV_CAP_PROP_FRAME_HEIGHT);
+       int codec = CV_FOURCC('P','I','M','1'); // MPEG-1
+       std::string out_file = (getHomeDir() / "performous-webcam_out.mpg").string();
+       m_writer.reset(new cv::VideoWriter(out_file.c_str(), codec, fps > 0 ? fps : 30.0f, cvSize(framew,frameh)));
+       if (!m_writer->isOpened()) {
+               std::cout << "Could not initialize webcam video saving!" << std::endl;
+               m_writer.reset();
+       }
+       #endif
+       // Start thread
+       m_thread.reset(new boost::thread(boost::ref(*this)));
+       #else
+       (void)cam_id; // Avoid unused warning
+       #endif
+}
+
+Webcam::~Webcam() {
+       m_quit = true;
+       #ifdef USE_OPENCV
+       if (m_thread) m_thread->join();
+       #endif
+}
+
+void Webcam::operator()() {
+       #ifdef USE_OPENCV
+       m_running = true;
+       while (!m_quit) {
+               if (m_running) {
+                       try {
+                               // Get a new frame
+                               cv::Mat frame;
+                               *m_capture >> frame;
+                               if (m_writer) *m_writer << frame;
+                               boost::mutex::scoped_lock l(m_mutex);
+                               // Copy the frame to storage
+                               m_frame.width = frame.cols;
+                               m_frame.height = frame.rows;
+                               m_frame.data.assign(frame.data, frame.data + (m_frame.width * m_frame.height * 3));
+                               // Notify renderer
+                               m_frameAvailable = true;
+                       } catch (std::exception&) { std::cerr << "Error capturing webcam frame!" << std::endl; }
+               }
+               // Sleep a little, much if the cam isn't active
+               boost::thread::sleep(now() + (m_running ? 0.015 : 0.5));
+       }
+       #endif
+}
+
+void Webcam::pause(bool do_pause) {
+       #ifdef USE_OPENCV
+       boost::mutex::scoped_lock l(m_mutex);
+       #endif
+       m_running = !do_pause;
+       m_frameAvailable = false;
+}
+
+void Webcam::render() {
+       #ifdef USE_OPENCV
+       if (!m_capture || !m_running) return;
+       // Do we have a new frame available?
+       if (m_frameAvailable && !m_frame.data.empty()) {
+               boost::mutex::scoped_lock l(m_mutex);
+               // Load the image
+               Bitmap bitmap;
+               bitmap.fmt = pix::BGR;
+               bitmap.buf.swap(m_frame.data);
+               bitmap.resize(m_frame.width, m_frame.height);
+               m_surface.load(bitmap);
+               bitmap.buf.swap(m_frame.data);  // Get back our buffer (FIXME: do we need to?)
+               m_frameAvailable = false;
+       }
+       using namespace glmath;
+       Transform trans(scale(vec3(-1.0, 1.0, 1.0)));
+       m_surface.draw(); // Draw
+       #endif
+}
diff --git a/game/webcam.hh b/game/webcam.hh
new file mode 100644 (file)
index 0000000..33e4358
--- /dev/null
@@ -0,0 +1,61 @@
+#pragma once
+
+#include <boost/scoped_ptr.hpp>
+#include <boost/thread/mutex.hpp>
+#include <boost/thread/thread.hpp>
+#include <vector>
+
+#include "surface.hh"
+
+namespace cv {
+       // Forward declarations
+       class VideoCapture;
+       class VideoWriter;
+}
+
+struct CamFrame {
+       int width;
+       int height;
+       std::vector<boost::uint8_t> data;
+};
+
+class Webcam {
+  public:
+       /// cam_id -1 means pick any device
+       Webcam(int cam_id = -1);
+
+       ~Webcam();
+
+       /// Thread runs here, don't call directly
+       void operator()();
+
+       /// Is good?
+       bool is_good() const { return m_capture != 0 && m_running; }
+       /// When paused, does not get or render frames
+       void pause(bool do_pause = true);
+       /// Display frame
+       void render();
+
+       Dimensions& dimensions() { return m_surface.dimensions; }
+       Dimensions const& dimensions() const { return m_surface.dimensions; }
+
+  private:
+       boost::scoped_ptr<boost::thread> m_thread;
+       mutable boost::mutex m_mutex;
+       boost::scoped_ptr<cv::VideoCapture> m_capture;
+       boost::scoped_ptr<cv::VideoWriter> m_writer;
+       CamFrame m_frame;
+       Surface m_surface;
+       bool m_frameAvailable;
+       volatile bool m_running;
+       volatile bool m_quit;
+
+  public:
+       static bool enabled() {
+               #ifdef USE_OPENCV
+               return true;
+               #else
+               return false;
+               #endif
+       }
+};
diff --git a/game/xtime.hh b/game/xtime.hh
new file mode 100644 (file)
index 0000000..8f02a2b
--- /dev/null
@@ -0,0 +1,33 @@
+#pragma once
+
+#include <boost/version.hpp>
+#include <boost/thread/xtime.hpp>
+#include <cmath>
+
+// Boost WTF time format, directly from C...
+static inline boost::xtime& operator+=(boost::xtime& time, double seconds) {
+       double nsec = 1e9 * (time.sec + seconds) + time.nsec;
+       time.sec = boost::xtime::xtime_sec_t(nsec / 1e9);
+       time.nsec = boost::xtime::xtime_nsec_t(std::fmod(nsec, 1e9));
+       return time;
+}
+static inline boost::xtime operator+(boost::xtime const& left, double seconds) {
+       boost::xtime time = left;
+       return time += seconds;
+}
+static inline double operator-(boost::xtime const& a, boost::xtime const& b) {
+       return a.sec - b.sec + 1e-9 * (a.nsec - b.nsec);
+}
+static inline boost::xtime now() {
+       boost::xtime time;
+#if (BOOST_VERSION / 100 % 1000 >= 50)
+       boost::xtime_get(&time, boost::TIME_UTC_);
+#else
+       boost::xtime_get(&time, boost::TIME_UTC);
+#endif
+       return time;
+}
+static inline double seconds(boost::xtime const& time) {
+       return time.sec + time.nsec * 1e-9;
+}
+
diff --git a/lang/CMakeLists.txt b/lang/CMakeLists.txt
new file mode 100644 (file)
index 0000000..27dad1f
--- /dev/null
@@ -0,0 +1,13 @@
+cmake_minimum_required(VERSION 2.6)
+file(GLOB LANGUAGES *.po)
+foreach(language ${LANGUAGES})
+       string(REGEX REPLACE "(.+(\\\\|/))+" "" language ${language})
+       string(REGEX REPLACE "\\.po$" "" language ${language})
+       set(pofile "${CMAKE_CURRENT_SOURCE_DIR}/${language}.po")
+       set(mobuild "${CMAKE_CURRENT_BINARY_DIR}/${language}/LC_MESSAGES")
+       set(mofile "${mobuild}/${CMAKE_PROJECT_NAME}.mo")
+       file(MAKE_DIRECTORY "${mobuild}")
+       add_custom_command(OUTPUT "${mofile}" COMMAND "${Msgfmt_BIN}" -v "${pofile}" -o "${mofile}" MAIN_DEPENDENCY "${pofile}" COMMENT "Building ${language} locale" VERBATIM)
+       add_custom_target("locale_${language}" ALL DEPENDS "${mofile}")  # Make sure the mofiles are always built
+       install(FILES "${mofile}" DESTINATION "${LOCALE_DIR}/${language}/LC_MESSAGES")
+endforeach(language)
diff --git a/lang/README b/lang/README
new file mode 100644 (file)
index 0000000..205ac9c
--- /dev/null
@@ -0,0 +1,65 @@
+Translation guide
+=================
+
+We recommend using POEdit (http://www.poedit.net/)
+For Windows, download it from the website.
+Most Linux distros have it in their repositories.
+
+NOTE: Don't generate the binary .mo files - they are
+      compiled (and installed) with Performous build
+
+Updating existing translations
+------------------------------
+  1. Open the .po file in POEdit.
+  2. Hit the Synchronize to source button in the toolbar.
+  3. Start translating.
+  4. Remember to save.
+
+NOTES:
+  * Setup your name and email in POEdit preferences if you haven't used it before
+  * Also setup the Performous XML parser as instructed below
+  * POEdit C/C++ parser might not recognize .hh extension by default, so add that:
+    Edit -> Preferences -> Parsers -> C/C++ -> Edit -> List of extensions
+
+Configuring the Performous XML parser
+-------------------------------------
+These steps enable translation of the XML locate bits.
+  1. Click Edit -> Preferences
+  2. Click the Parsers tab
+  3. Click the New button and fill out the form like this:
+       Language: Performous XML
+       List of extensions: *.xml
+       Parser command: $SOURCE_ROOT/tools/scripts/xml_gettext.sh %o %C %F
+       An item in keywords list:
+       An item in input files list: %f
+       Source code charset: %c
+     Where $SOURCE_ROOT is the path to the performous sources root.
+  4. Click Okay
+
+Creating a new catalog
+----------------------
+These are the steps to create a new catalog, but easiest
+is probably just copy one of the existing ones and start
+from there (in which case you can skip these steps.)
+
+   1. Start POEdit
+   2. Click File -> New Catalog
+   3. Enter a project name (performous)
+   4. Click the Paths tab at the top
+   5. Click the New Item icon (second one, looks like a little square)
+   6. Enter the path to the directory containing your plug-in file ("." tells POEdit to scan the directory that you will save the file to, usually only need to include ../game and ../data), press enter
+   7. Click the Keywords tab at the top
+   8. Click the New Item icon
+   9. Enter _ (that's underscore), press enter
+  12. Click Okay
+  13. Choose a name for your .po file (performous) 
+  14. Follow the instructions above to enable XML translation
+
+REMEMBER TO SAVE WITH YOU LOCALE NAME
+
+Example for English:
+en.po
+
+Acknowledgements
+----------------
+Thanks to guide at http://codex.wordpress.org/User:Skippy/Creating_POT_Files
diff --git a/lang/TRANSLATORS b/lang/TRANSLATORS
new file mode 100644 (file)
index 0000000..f83ec37
--- /dev/null
@@ -0,0 +1,39 @@
+# -*- coding: utf-8 -*-
+#
+# Lines like this one (starting with a # are comments)
+# The rest of the lines have the following format:
+#  "$1:$2 Single line of text"
+#
+# Where $1 is the ISO-369-1 two letter language code
+# (the same as for the PO file name)
+#
+# The $2 is one of:
+#  COMMENT  - The comment that shows up on the wiki
+#             translation overview page
+#  CONTACT  - The contact for the translation
+#  STATUS   - The status of the translation, keep this short.
+#             ideally one of: active, inactive, not yet ready
+#
+# TRANSLATOR and LEAD is not yet known by translation_wiki_helper.sh.
+#
+# Also, presently only one CONTACT field per language is allowed
+# for now. (This limitation is indented to be fixed later)
+
+es:STATUS active
+es:CONTACT [[User:Peque|peque]] (Spanish native speaker)
+
+fr:STATUS active
+fr:CONTACT [[User:Yoda|yoda]] (French native speaker)
+
+ja:COMMENT Translations not ready for release.
+ja:STATUS not yet ready
+#ja:TRANSLATOR [[User:Scientica|scientica]] (not native speaker)
+ja:CONTACT [[User:Scientica|scientica]] (not native speaker)
+
+sv:STATUS active
+#sv:LEAD [[User:Scientica|scientica]] (Swedish native speaker)
+sv:CONTACT [[User:Scientica|scientica]] (Swedish native speaker)
+
+fa:STATUS not yet ready
+fa:CONTACT [[User:sajjadG|sajjadg]] (Farsi native speaker)
+fa:COMMENT work in progress...
diff --git a/lang/ast.po b/lang/ast.po
new file mode 100644 (file)
index 0000000..61cde88
--- /dev/null
@@ -0,0 +1,1156 @@
+# Asturian translation for performous
+# Copyright (c) 2011 Rosetta Contributors and Canonical Ltd 2011
+# This file is distributed under the same license as the performous package.
+# FIRST AUTHOR <EMAIL@ADDRESS>, 2011.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: performous\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2013-05-24 12:45+0100\n"
+"PO-Revision-Date: 2013-05-24 12:46+0100\n"
+"Last-Translator: niek nooijens <nieknooijens@gmail.com>\n"
+"Language-Team: Asturian <ast@li.org>\n"
+"Language: ast\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"X-Launchpad-Export-Date: 2011-08-01 18:01+0000\n"
+"X-Generator: Poedit 1.5.4\n"
+"X-Poedit-KeywordsList: _\n"
+"X-Poedit-Basepath: .\n"
+"X-Poedit-SourceCharset: UTF-8\n"
+"X-Poedit-SearchPath-0: ../game\n"
+"X-Poedit-SearchPath-1: ../data\n"
+
+#: ../game/screen_paths.cc:24
+msgid ""
+"This tool is not yet available.\n"
+"Configure paths by adding them\n"
+"as command line parameters and\n"
+"then save them in configuration menu."
+msgstr ""
+"Esta ferramienta nun ta enta disponible.\n"
+"Configura cartafueyos añadiendolos\n"
+"como parametru de llinia comandu y\n"
+"dempués atroxales nel menú de configuración."
+
+#: ../game/screen_paths.cc:70
+msgid "Press any key to exit."
+msgstr "Primi cualaquier tecla pa colar"
+
+#: ../game/screen_paths.cc:75
+msgid ""
+"Windows users can also use ConfigureSongDirectory.bat in the bin-directory."
+msgstr ""
+"LOs usuarios de Windows puen tamién usar ConfigureSongDirectory.bat nel "
+"cartafueyu bin."
+
+#: ../game/configuration.cc:117
+msgid "Enabled"
+msgstr "Activáu"
+
+#: ../game/configuration.cc:117
+msgid "Disabled"
+msgstr "Desactiváu"
+
+#: ../game/configuration.cc:121
+#, c-format
+msgid "%d items"
+msgstr "%d oxetos"
+
+#: ../game/instrumentgraph.cc:56 ../game/screen_sing.cc:123
+msgid "Resume"
+msgstr "reentamar"
+
+#: ../game/instrumentgraph.cc:56 ../game/screen_sing.cc:123
+msgid "Back to performing!"
+msgstr "¡Tornar de la actuación!"
+
+#: ../game/instrumentgraph.cc:57
+msgid "Rejoin"
+msgstr "Reaxuntar"
+
+#: ../game/instrumentgraph.cc:57
+msgid "Change selections"
+msgstr "Camudar les esbilles"
+
+#: ../game/instrumentgraph.cc:58 ../game/screen_sing.cc:124
+msgid "Restart"
+msgstr "Reaniciar"
+
+#: ../game/instrumentgraph.cc:58 ../game/screen_sing.cc:124
+msgid ""
+"Start the song\n"
+"from the beginning"
+msgstr ""
+"Entamar la canción\n"
+"Dende l'entamu"
+
+#: ../game/instrumentgraph.cc:59 ../game/guitargraph.cc:200
+#: ../game/screen_intro.cc:184 ../game/dancegraph.cc:137
+#: ../game/screen_sing.cc:92 ../game/screen_sing.cc:126
+msgid "Quit"
+msgstr "Colar"
+
+#: ../game/instrumentgraph.cc:59 ../game/guitargraph.cc:200
+#: ../game/dancegraph.cc:137 ../game/screen_sing.cc:92
+#: ../game/screen_sing.cc:126
+msgid "Exit to song browser"
+msgstr "Colar pal restolador canciones"
+
+#: ../game/guitargraph.cc:14
+msgid "Kids"
+msgstr "Guaḥes"
+
+#: ../game/guitargraph.cc:14 ../game/dancegraph.cc:18
+msgid "Easy"
+msgstr "Cenciello"
+
+#: ../game/guitargraph.cc:14 ../game/dancegraph.cc:18
+msgid "Medium"
+msgstr "Medio"
+
+#: ../game/guitargraph.cc:14 ../game/dancegraph.cc:18
+msgid "Hard"
+msgstr "Difícil"
+
+#: ../game/guitargraph.cc:14
+msgid "Expert"
+msgstr "Espertu"
+
+#: ../game/guitargraph.cc:163 ../game/dancegraph.cc:134
+msgid "Select difficulty"
+msgstr "Esbillar dificultá"
+
+#: ../game/guitargraph.cc:169 ../game/guitargraph.cc:186
+msgid "Lefty-mode"
+msgstr "Mou izquierdu"
+
+#: ../game/guitargraph.cc:183 ../game/dancegraph.cc:118
+msgid "Select track"
+msgstr "Esbillar camción"
+
+#: ../game/guitargraph.cc:194 ../game/dancegraph.cc:107
+msgid "Ready!"
+msgstr "¡Preparate!"
+
+#: ../game/guitargraph.cc:194 ../game/screen_intro.cc:166
+#: ../game/dancegraph.cc:107
+msgid "Start performing!"
+msgstr "¡Entamar  actuación!"
+
+#: ../game/guitargraph.cc:207
+msgid "ON"
+msgstr "ENCESU"
+
+#: ../game/guitargraph.cc:207
+msgid "OFF"
+msgstr "APAGÁU"
+
+#: ../game/guitargraph.cc:208
+msgid "Toggle lefty-mode"
+msgstr "Camudar mou izquierdu"
+
+#: ../game/guitargraph.cc:447 ../game/dancegraph.cc:319
+msgid "Streak!"
+msgstr "¡Racha!"
+
+#: ../game/guitargraph.cc:459
+msgid ""
+"God Mode\n"
+"Activated!"
+msgstr ""
+"Mou Dios\n"
+"¡Activáu!"
+
+#: ../game/guitargraph.cc:460
+msgid "Mistakes ignored!"
+msgstr "¡Erros inoraos!"
+
+#: ../game/guitargraph.cc:1102
+msgid "God Mode Ready!"
+msgstr "¡Preparate pal Mou Dios!"
+
+#: ../game/guitargraph.cc:1103
+msgid "Drum Fill!"
+msgstr "Drum Fill!"
+
+#: ../game/guitargraph.cc:1106
+msgid "Solo!"
+msgstr "¡Soledu!"
+
+#: ../game/songs.cc:194
+msgid "show all songs"
+msgstr ""
+
+#: ../game/songs.cc:195
+msgid "has dance"
+msgstr ""
+
+#: ../game/songs.cc:196
+#, fuzzy
+msgid "has vocals"
+msgstr "Vocales"
+
+#: ../game/songs.cc:197
+msgid "has duet"
+msgstr ""
+
+#: ../game/songs.cc:198
+#, fuzzy
+msgid "has guitar"
+msgstr "Guitarra rítmica"
+
+#: ../game/songs.cc:199
+msgid "drums or keytar"
+msgstr ""
+
+#: ../game/songs.cc:200
+msgid "full band"
+msgstr ""
+
+#: ../game/songs.cc:228
+msgid "random order"
+msgstr "Orde al debalu"
+
+#: ../game/songs.cc:229
+msgid "sorted by song"
+msgstr "Ordenao per canción"
+
+#: ../game/songs.cc:230
+msgid "sorted by artist"
+msgstr "Ordenao per artista"
+
+#: ../game/songs.cc:231
+msgid "sorted by edition"
+msgstr "Ordenao per edición"
+
+#: ../game/songs.cc:232
+msgid "sorted by genre"
+msgstr "Ordenao per xeneru"
+
+#: ../game/songs.cc:233
+msgid "sorted by path"
+msgstr "Ordenao per cartafueyu"
+
+#: ../game/songs.cc:234
+msgid "sorted by language"
+msgstr "Ordenao per llingua"
+
+#: ../game/screen_intro.cc:24
+msgid "No playback devices could be used.\n"
+msgstr "Preséu dalu de playback puen usase\n"
+
+#: ../game/screen_intro.cc:25
+msgid ""
+"\n"
+"Please configure some before playing."
+msgstr ""
+"\n"
+"Por favor configura daqué enantes d'entamar."
+
+#: ../game/screen_intro.cc:69
+msgid "Settings saved as system defaults."
+msgstr "Axustes atroxaos como per defeutu del sistema"
+
+#: ../game/screen_intro.cc:69
+msgid "Settings saved."
+msgstr "Axustes atroxaos"
+
+#: ../game/screen_intro.cc:149
+msgid "Ctrl + S to save, Ctrl + R to reset defaults"
+msgstr "Ctrl + S p'atroxar, Ctrl + R pa reaniciar axustes"
+
+#: ../game/screen_intro.cc:166
+msgid "Perform"
+msgstr "Actuar"
+
+#: ../game/screen_intro.cc:167
+msgid "Practice"
+msgstr "Prauticar"
+
+#: ../game/screen_intro.cc:167
+msgid "Check your skills or test the microphones"
+msgstr "Compreba les tos habilidades o preba los micrófonos"
+
+#: ../game/screen_intro.cc:183
+msgid "Configure"
+msgstr "Configurar"
+
+#: ../game/screen_intro.cc:183
+msgid "Configure audio and game options"
+msgstr "Configuar soníu y axustes de xuegu"
+
+#: ../game/screen_intro.cc:184
+msgid "Leave the game"
+msgstr "Colar del xuegu"
+
+#: ../game/dancegraph.cc:18
+msgid "Beginner"
+msgstr "Ñovatu"
+
+#: ../game/dancegraph.cc:18
+msgid "Challenge"
+msgstr "Retu"
+
+#: ../game/dancegraph.cc:248
+msgid "STOP!"
+msgstr "¡APARAR!"
+
+#: ../game/screen_playlist.cc:110 ../game/screen_playlist.cc:252
+msgid "Continue"
+msgstr ""
+
+#: ../game/screen_playlist.cc:110
+msgid "Continue playing"
+msgstr ""
+
+#: ../game/screen_playlist.cc:118
+msgid "Add songs"
+msgstr ""
+
+#: ../game/screen_playlist.cc:118
+msgid "Open the song browser to add more songs"
+msgstr ""
+
+#: ../game/screen_playlist.cc:119 ../game/screen_songs.cc:513
+msgid "Shuffle"
+msgstr ""
+
+#: ../game/screen_playlist.cc:119 ../game/screen_songs.cc:513
+msgid "Randomize the order of the playlist"
+msgstr ""
+
+#: ../game/screen_playlist.cc:125
+msgid "Clear and exit"
+msgstr ""
+
+#: ../game/screen_playlist.cc:125 ../game/screen_songs.cc:520
+msgid "Remove all the songs from the list"
+msgstr ""
+
+#: ../game/screen_playlist.cc:131 ../game/screen_playlist.cc:275
+#: ../game/screen_songs.cc:526
+msgid "Back"
+msgstr ""
+
+#: ../game/screen_playlist.cc:131 ../game/screen_playlist.cc:275
+msgid "Back to playlist viewer"
+msgstr ""
+
+#: ../game/screen_playlist.cc:237
+msgid "Press enter to view song options"
+msgstr ""
+
+#: ../game/screen_playlist.cc:244
+msgid "View more options"
+msgstr ""
+
+#: ../game/screen_playlist.cc:244
+#, fuzzy
+msgid "View general playlist settings"
+msgstr "Configuara axustes xenerales soníu"
+
+#: ../game/screen_playlist.cc:252
+msgid "Play first"
+msgstr ""
+
+#: ../game/screen_playlist.cc:254
+msgid "Ignore the playlist's order and play this song first"
+msgstr ""
+
+#: ../game/screen_playlist.cc:255
+msgid "Start the song already!"
+msgstr ""
+
+#: ../game/screen_playlist.cc:264
+msgid "Remove"
+msgstr ""
+
+#: ../game/screen_playlist.cc:264
+msgid "Remove this song from the list"
+msgstr ""
+
+#: ../game/main.cc:146
+msgid "Loading audio samples..."
+msgstr "Cargando exemplos de sonios..."
+
+#: ../game/main.cc:160
+msgid "Creating screens..."
+msgstr "Criando pantalles..."
+
+#: ../game/main.cc:170
+msgid "Entering main menu"
+msgstr "Entrando al menú d'entamu"
+
+#: ../game/main.cc:172 ../game/screen_sing.cc:97
+msgid "Loading complete"
+msgstr "Carga fecha darreu"
+
+#: ../game/main.cc:183
+msgid "Screenshot taken!"
+msgstr "¡Semeya coyía!"
+
+#: ../game/main.cc:186
+msgid "Screenshot failed!"
+msgstr "¡Semeya fallida!"
+
+#: ../game/screen_sing.cc:45
+msgid "Initializing webcam..."
+msgstr "Aniciando Cámara Web..."
+
+#: ../game/screen_sing.cc:52
+msgid "Loading video..."
+msgstr "Cargando vidéu..."
+
+#: ../game/screen_sing.cc:59
+msgid "Loading song..."
+msgstr "Cargando canción..."
+
+#: ../game/screen_sing.cc:66
+msgid "Song contains broken tracks!"
+msgstr "¡Les canciones tienen pistes rotes!"
+
+#: ../game/screen_sing.cc:71
+msgid "Loading menu..."
+msgstr "Cargando menú..."
+
+#: ../game/screen_sing.cc:76
+#, fuzzy
+msgid "Start"
+msgstr "Reaniciar"
+
+#: ../game/screen_sing.cc:76
+#, fuzzy
+msgid "Start performing"
+msgstr "¡Entamar  actuación!"
+
+#: ../game/screen_sing.cc:80
+#, fuzzy
+msgid "Duet mode"
+msgstr "Mou izquierdu"
+
+#: ../game/screen_sing.cc:81
+msgid "Normal mode"
+msgstr ""
+
+#: ../game/screen_sing.cc:82
+msgid "Switch between duet and regular singing mode"
+msgstr ""
+
+#: ../game/screen_sing.cc:90
+#, fuzzy
+msgid "Change vocal track"
+msgstr ""
+"Camudar pista de voz\n"
+"(Tienes de reaniciar)"
+
+#: ../game/screen_sing.cc:125
+msgid "Skip"
+msgstr ""
+
+#: ../game/screen_sing.cc:125
+msgid "Skip current song"
+msgstr ""
+
+#: ../game/screen_sing.cc:391
+msgid "Press UP to join dance!"
+msgstr ""
+
+#: ../game/screen_sing.cc:391
+msgid "Step UP to join!"
+msgstr ""
+
+#: ../game/screen_sing.cc:396
+msgid "Press 1 to join guitar!"
+msgstr ""
+
+#: ../game/screen_sing.cc:396
+msgid "Press GREEN to join!"
+msgstr ""
+
+#: ../game/screen_sing.cc:401
+msgid "Press SPACE to join drums!"
+msgstr ""
+
+#: ../game/screen_sing.cc:401
+msgid "KICK to join!"
+msgstr ""
+
+#: ../game/screen_sing.cc:475
+msgid "   ENTER to skip instrumental break"
+msgstr "   INTRO pa saltar rotura instrumental"
+
+#: ../game/screen_sing.cc:476
+msgid "   Remember to wait for grading!"
+msgstr "   ¡Remembra asperar pola clasificación!"
+
+#: ../game/screen_sing.cc:587
+msgid "No player!"
+msgstr "¡Ensín xugador!"
+
+#: ../game/screen_sing.cc:594
+msgid "Hit singer"
+msgstr "Hit cantante"
+
+#: ../game/screen_sing.cc:595
+msgid "Lead singer"
+msgstr "Cantante"
+
+#: ../game/screen_sing.cc:596 ../game/screen_sing.cc:602
+#: ../game/screen_sing.cc:608
+msgid "Rising star"
+msgstr "Medra d'estrella"
+
+#: ../game/screen_sing.cc:597 ../game/screen_sing.cc:603
+#: ../game/screen_sing.cc:609
+msgid "Amateur"
+msgstr "Amateur"
+
+#: ../game/screen_sing.cc:598 ../game/screen_sing.cc:610
+msgid "Tone deaf"
+msgstr "Tapecíu"
+
+#: ../game/screen_sing.cc:600
+msgid "Maniac"
+msgstr "Maniacu"
+
+#: ../game/screen_sing.cc:601
+msgid "Hoofer"
+msgstr "Artista"
+
+#: ../game/screen_sing.cc:604
+msgid "Loser"
+msgstr "Perdedor"
+
+#: ../game/screen_sing.cc:606
+msgid "Virtuoso"
+msgstr "Virtuosu"
+
+#: ../game/screen_sing.cc:607
+msgid "Rocker"
+msgstr "Roqueru"
+
+#: ../game/screen_songs.cc:279
+msgid "No songs found!"
+msgstr "¡Canción dala alcontrada!"
+
+#: ../game/screen_songs.cc:280
+msgid ""
+"Visit performous.org\n"
+"for free songs"
+msgstr ""
+"Visita performous.org\n"
+"pa canciones llibres"
+
+#: ../game/screen_songs.cc:282
+#, fuzzy
+msgid "Sorry, no songs match the search!"
+msgstr "Nun coinciden les canciones na gueta"
+
+#: ../game/screen_songs.cc:289
+#, fuzzy
+msgid "Hiscore\n"
+msgstr "Rexistru pa %1%\n"
+
+#: ../game/screen_songs.cc:298
+msgid "<type in to search>   ↔ songs    ↕ options"
+msgstr ""
+
+#: ../game/screen_songs.cc:301
+msgid "↔ sort order: "
+msgstr ""
+
+#: ../game/screen_songs.cc:302
+msgid "↔ type filter: "
+msgstr ""
+
+#: ../game/screen_songs.cc:303
+msgid "↔ hiscores   ↵ jukebox mode"
+msgstr ""
+
+#: ../game/screen_songs.cc:307
+msgid "↵ start a playlist with this song!"
+msgstr ""
+
+#: ../game/screen_songs.cc:309
+msgid "↵ open the playlist menu"
+msgstr ""
+
+#: ../game/screen_songs.cc:506
+msgid "Play"
+msgstr ""
+
+#: ../game/screen_songs.cc:506
+msgid "Start the game with all songs in playlist"
+msgstr ""
+
+#: ../game/screen_songs.cc:519
+msgid "View playlist"
+msgstr ""
+
+#: ../game/screen_songs.cc:519
+msgid "View the current playlist"
+msgstr ""
+
+#: ../game/screen_songs.cc:520
+msgid "Clear playlist"
+msgstr ""
+
+#: ../game/screen_songs.cc:526
+#, fuzzy
+msgid "Back to song browser"
+msgstr "Colar pal restolador canciones"
+
+#: ../game/screen_players.cc:115
+msgid "No players found!"
+msgstr "¡Xugador dalu!"
+
+#: ../game/screen_players.cc:116
+msgid "Enter a name to create a new player."
+msgstr "Pon un nome pa criar un xugador."
+
+#: ../game/screen_players.cc:118
+msgid "Press enter to create player!"
+msgstr "¡Primi Intro pa criar xugador!"
+
+#: ../game/screen_players.cc:122
+#, fuzzy
+msgid "No players worth mentioning!"
+msgstr "¡Xugador dalu!"
+
+#: ../game/screen_players.cc:127
+msgid "You reached %1% points!"
+msgstr "¡Llegasti a los %1% puntos!"
+
+#: ../game/screen_players.cc:128
+msgid "Change player with arrow keys."
+msgstr "Camudar xugador coles fleches."
+
+#: ../game/screen_players.cc:129
+msgid "Name:"
+msgstr "Nome:"
+
+#: ../game/screen_players.cc:132
+msgid "Type text to filter or create a new player."
+msgstr "Pon fieltru de testu o criar un nuevu  jugador."
+
+#: ../game/screen_players.cc:132
+msgid "Search Text:"
+msgstr "Guetar testu:"
+
+#: ../game/screen_audiodevices.cc:55
+msgid ""
+"It seems you have some manual configurations\n"
+"incompatible with this user interface.\n"
+"Saving these settings will override\n"
+"all existing audio device configuration.\n"
+"Your other options changes will be saved too."
+msgstr ""
+"Parez que dalgunes configuraciones manuales\n"
+"son incompatibles con esta interfaz d'usuariu.\n"
+"Atroxar estos axustes sobroescribirán\n"
+"toles esistentes na configuración del preséu de soníu.\n"
+"Les otres opciones camudaes atroxaranse tamién."
+
+#: ../game/screen_audiodevices.cc:114
+msgid "- Unassigned -"
+msgstr "- Non asignáu -"
+
+#: ../game/screen_audiodevices.cc:135
+msgid ""
+"Use arrow keys to configure. Hit Enter/Start to save and test or Esc/Select "
+"to cancel. Ctrl + R to reset defaults"
+msgstr ""
+"Usa les fleches pa configurar. Primi Enter/Start p'atroxar y prevar o Esc/"
+"Select p'atayar. Ctrl + R pa reaniciar"
+
+#: ../game/screen_audiodevices.cc:140
+msgid ""
+"For advanced device configuration, use command line parameter --audio (use --"
+"audiohelp for details)."
+msgstr ""
+"Pa configuración avanzada de preséu, usa'l parámetru na llinia de comandos --"
+"audio (usa --audiohelp pa detalles)"
+
+#: ../game/screen_audiodevices.cc:188
+msgid "Some devices failed to open!"
+msgstr "¡Dalgunos preseos nun s'abren!"
+
+#: ../game/database.cc:89 ../game/database.cc:107
+msgid "No Items up to now."
+msgstr "Nun hai oxetos agora."
+
+#: ../game/database.cc:90 ../game/database.cc:108
+msgid "Be the first to be listed here!"
+msgstr "¡Se'l primeru en ser escucháu eiquí!"
+
+#: ../game/song.hh:22
+msgid "Guitar"
+msgstr "Guitarra"
+
+#: ../game/song.hh:22
+msgid "Coop guitar"
+msgstr "Guitarra Coop"
+
+#: ../game/song.hh:22
+msgid "Rhythm guitar"
+msgstr "Guitarra rítmica"
+
+#: ../game/song.hh:22
+msgid "Bass"
+msgstr "Baxu"
+
+#: ../game/song.hh:22
+msgid "Drums"
+msgstr "Batería"
+
+#: ../game/song.hh:22
+msgid "Vocals"
+msgstr "Vocales"
+
+#: ../game/song.hh:22
+msgid "Harmonic 1"
+msgstr "Harmónica 1"
+
+#: ../game/song.hh:22
+msgid "Harmonic 2"
+msgstr "Harmónica 2"
+
+#: ../game/song.hh:22
+msgid "Harmonic 3"
+msgstr "Harmónica 3"
+
+#: /tmp/xml2gettext.ALpXYhCQJf:2
+msgid "Game"
+msgstr "Xuegu"
+
+#: /tmp/xml2gettext.ALpXYhCQJf:3
+msgid "Gameplay related options"
+msgstr "Opciones rellacionaes col mou de xuegu"
+
+#: /tmp/xml2gettext.ALpXYhCQJf:4
+#, fuzzy
+msgid "Graphic"
+msgstr "Gráficos."
+
+#: /tmp/xml2gettext.ALpXYhCQJf:5
+msgid "Configure rendering and video settings"
+msgstr "Configurar axustes de vidéu y renderizáu"
+
+#: /tmp/xml2gettext.ALpXYhCQJf:6
+msgid "Audio Devices"
+msgstr "Presos soníu"
+
+#: /tmp/xml2gettext.ALpXYhCQJf:7
+msgid "Setup microphones and playback"
+msgstr "Configurar microfonos y playback"
+
+#: /tmp/xml2gettext.ALpXYhCQJf:8
+msgid "Audio"
+msgstr "Soníu"
+
+#: /tmp/xml2gettext.ALpXYhCQJf:9
+msgid "Configure general audio settings"
+msgstr "Configuara axustes xenerales soníu"
+
+#: /tmp/xml2gettext.ALpXYhCQJf:10
+msgid "Paths"
+msgstr "Cartafueyos"
+
+#: /tmp/xml2gettext.ALpXYhCQJf:11
+msgid "Setup song and data paths"
+msgstr "Configurar canción y datos cartafueyos"
+
+#: /tmp/xml2gettext.ALpXYhCQJf:12
+msgid "Karaoke mode"
+msgstr ""
+
+#: /tmp/xml2gettext.ALpXYhCQJf:13
+msgid "Hide pitch wave, notes and scoring."
+msgstr ""
+
+#: /tmp/xml2gettext.ALpXYhCQJf:14
+msgid "Pitch waves"
+msgstr ""
+
+#: /tmp/xml2gettext.ALpXYhCQJf:15
+msgid "Enable singing pitch display (when not in karaoke mode)."
+msgstr ""
+
+#: /tmp/xml2gettext.ALpXYhCQJf:16
+msgid "Theme"
+msgstr ""
+
+#: /tmp/xml2gettext.ALpXYhCQJf:17
+msgid "Name of the theme to use."
+msgstr ""
+
+#: /tmp/xml2gettext.ALpXYhCQJf:18
+msgid "Keyboard as guitar"
+msgstr ""
+
+#: /tmp/xml2gettext.ALpXYhCQJf:19
+msgid "Enable keyboard as guitar (Frets on Fire mode)."
+msgstr ""
+
+#: /tmp/xml2gettext.ALpXYhCQJf:20
+msgid "Keyboard as drumkit"
+msgstr ""
+
+#: /tmp/xml2gettext.ALpXYhCQJf:21
+msgid "Enable keyboard as drumkit."
+msgstr ""
+
+#: /tmp/xml2gettext.ALpXYhCQJf:22
+msgid "Keyboard as dance pad"
+msgstr ""
+
+#: /tmp/xml2gettext.ALpXYhCQJf:23
+msgid "Enable keyboard as dance pad."
+msgstr ""
+
+#: /tmp/xml2gettext.ALpXYhCQJf:24
+msgid "Keyboard as keytar"
+msgstr ""
+
+#: /tmp/xml2gettext.ALpXYhCQJf:25
+msgid "Enable keyboard as keytar."
+msgstr ""
+
+#: /tmp/xml2gettext.ALpXYhCQJf:26
+msgid "Force controller A's type"
+msgstr ""
+
+#: /tmp/xml2gettext.ALpXYhCQJf:27
+msgid ""
+"Override autodetection and force the first controller to the given type."
+msgstr ""
+
+#: /tmp/xml2gettext.ALpXYhCQJf:28
+msgid "Force controller B's type"
+msgstr ""
+
+#: /tmp/xml2gettext.ALpXYhCQJf:29
+msgid ""
+"Override autodetection and force the second controller to the given type."
+msgstr ""
+
+#: /tmp/xml2gettext.ALpXYhCQJf:30
+msgid "Force controller C's type"
+msgstr ""
+
+#: /tmp/xml2gettext.ALpXYhCQJf:31
+msgid ""
+"Override autodetection and force the third controller to the given type."
+msgstr ""
+
+#: /tmp/xml2gettext.ALpXYhCQJf:32
+msgid "Force controller D's type"
+msgstr ""
+
+#: /tmp/xml2gettext.ALpXYhCQJf:33
+msgid ""
+"Override autodetection and force the fourth controller to the given type."
+msgstr ""
+
+#: /tmp/xml2gettext.ALpXYhCQJf:34
+msgid "Joystick configuration"
+msgstr ""
+
+#: /tmp/xml2gettext.ALpXYhCQJf:35
+msgid "Force joystick to some kind of instrument."
+msgstr ""
+
+#: /tmp/xml2gettext.ALpXYhCQJf:36
+msgid "Hardware MIDI input device"
+msgstr ""
+
+#: /tmp/xml2gettext.ALpXYhCQJf:37
+msgid ""
+"Regex for matching the MIDI devices to use. The default is to use all "
+"available devices."
+msgstr ""
+
+#: /tmp/xml2gettext.ALpXYhCQJf:38
+msgid "Fallback song encoding"
+msgstr ""
+
+#: /tmp/xml2gettext.ALpXYhCQJf:39
+msgid "Pick the text codec used for song files that are not UTF-8."
+msgstr ""
+
+#: /tmp/xml2gettext.ALpXYhCQJf:40
+msgid "Windowed width"
+msgstr ""
+
+#: /tmp/xml2gettext.ALpXYhCQJf:41
+msgid "The width of the window."
+msgstr ""
+
+#: /tmp/xml2gettext.ALpXYhCQJf:42
+msgid "Windowed height"
+msgstr ""
+
+#: /tmp/xml2gettext.ALpXYhCQJf:43
+msgid "The height of the window."
+msgstr ""
+
+#: /tmp/xml2gettext.ALpXYhCQJf:44
+msgid "Fullscreen mode"
+msgstr ""
+
+#: /tmp/xml2gettext.ALpXYhCQJf:45
+msgid "Enable fullscreen mode on startup."
+msgstr ""
+
+#: /tmp/xml2gettext.ALpXYhCQJf:46
+msgid "Stereoscopic 3D"
+msgstr ""
+
+#: /tmp/xml2gettext.ALpXYhCQJf:47
+msgid "Enable 3D rendering of Performous."
+msgstr ""
+
+#: /tmp/xml2gettext.ALpXYhCQJf:48
+msgid "Stereo3D type"
+msgstr ""
+
+#: /tmp/xml2gettext.ALpXYhCQJf:49
+msgid "Some modes may only get activated in fullscreen mode."
+msgstr ""
+
+#: /tmp/xml2gettext.ALpXYhCQJf:50
+msgid "Stereo3D separation"
+msgstr ""
+
+#: /tmp/xml2gettext.ALpXYhCQJf:51
+msgid ""
+"The strength of the effect. Experiment with different settings for best "
+"results."
+msgstr ""
+
+#: /tmp/xml2gettext.ALpXYhCQJf:52
+msgid "Video playback"
+msgstr ""
+
+#: /tmp/xml2gettext.ALpXYhCQJf:53
+msgid ""
+"Allows completely disabling background videos. It is recommended to leave "
+"this enabled as Performous will still smoothly fade out the video if your "
+"computer is not fast enough."
+msgstr ""
+
+#: /tmp/xml2gettext.ALpXYhCQJf:54
+#, fuzzy
+msgid "Webcam background"
+msgstr "Fondu al debalu..."
+
+#: /tmp/xml2gettext.ALpXYhCQJf:55
+msgid ""
+"Performous can use webcam as a background video. Disable it if Performous "
+"crashes while entering a song."
+msgstr ""
+
+#: /tmp/xml2gettext.ALpXYhCQJf:56
+msgid "Webcam id"
+msgstr ""
+
+#: /tmp/xml2gettext.ALpXYhCQJf:57
+msgid ""
+"Use -1 to autodetect or a number starting from 0 to choose specific device."
+msgstr ""
+
+#: /tmp/xml2gettext.ALpXYhCQJf:58
+msgid "SVG quality"
+msgstr ""
+
+#: /tmp/xml2gettext.ALpXYhCQJf:59
+msgid ""
+"Larger numbers cause vector graphics to be rendered in higher resolution. "
+"Decrease this to make navigating in menus faster."
+msgstr ""
+
+#: /tmp/xml2gettext.ALpXYhCQJf:60
+msgid "Text quality"
+msgstr ""
+
+#: /tmp/xml2gettext.ALpXYhCQJf:61
+msgid ""
+"Larger numbers cause text to be rendered in higher resolution. Decrease this "
+"to make everything a little faster."
+msgstr ""
+
+#: /tmp/xml2gettext.ALpXYhCQJf:62
+msgid "Benchmark mode"
+msgstr ""
+
+#: /tmp/xml2gettext.ALpXYhCQJf:63
+msgid ""
+"Framerate limit of 100 FPS is removed and the game instead renders at full "
+"speed. FPS values are printed to console. Please note that the display "
+"drivers may still limit the rendering speed to the screen refresh rate."
+msgstr ""
+
+#: /tmp/xml2gettext.ALpXYhCQJf:64
+msgid "Suggested latency"
+msgstr ""
+
+#: /tmp/xml2gettext.ALpXYhCQJf:65
+msgid ""
+"This is a hint for the audio engine about the desired latency. Set this as "
+"low as possible while retaining clear audio playback. Requires restart."
+msgstr ""
+
+#: /tmp/xml2gettext.ALpXYhCQJf:66
+msgid "Audio/video latency"
+msgstr ""
+
+#: /tmp/xml2gettext.ALpXYhCQJf:67
+msgid ""
+"Affects all modes. Use negative value if your display input lag is greater "
+"than the sound card output latency, positive values in the opposite case and "
+"zero if they are equal. This should be set so that the notes pass the cursor "
+"at the same time the audio is heard. Use Ctrl+F1/F2 to adjust this while "
+"performing."
+msgstr ""
+
+#: /tmp/xml2gettext.ALpXYhCQJf:68
+msgid "Audio round-trip latency"
+msgstr ""
+
+#: /tmp/xml2gettext.ALpXYhCQJf:69
+msgid ""
+"Affects singing only. The time it takes for Performous playback to reach "
+"your speakers, fly to the microphone and all the way back until Performous "
+"captures and analyzes it. While performing, press Ctrl+S for synth mode and "
+"adjust with Ctrl+F3/F4."
+msgstr ""
+
+#: /tmp/xml2gettext.ALpXYhCQJf:70
+msgid "Audio/controller latency"
+msgstr ""
+
+#: /tmp/xml2gettext.ALpXYhCQJf:71
+msgid ""
+"Affects instruments and dancing only. The total of USB (guitar or dance pad) "
+"latency combined with audio output latency. Adjust so that you can hit the "
+"notes best when playing by ear (not looking on screen). Use Ctrl+F5/F6 to "
+"adjust while performing."
+msgstr ""
+
+#: /tmp/xml2gettext.ALpXYhCQJf:72
+#, fuzzy
+msgid "Audio devices"
+msgstr "Presos soníu"
+
+#: /tmp/xml2gettext.ALpXYhCQJf:73
+msgid "List of audio devices to try."
+msgstr ""
+
+#: /tmp/xml2gettext.ALpXYhCQJf:74
+msgid "Menu volume"
+msgstr ""
+
+#: /tmp/xml2gettext.ALpXYhCQJf:75
+msgid "The volume level of menus, song previews and jukebox mode."
+msgstr ""
+
+#: /tmp/xml2gettext.ALpXYhCQJf:76
+msgid "Music volume"
+msgstr ""
+
+#: /tmp/xml2gettext.ALpXYhCQJf:77
+msgid ""
+"The ingame music volume. Values above 90 are not recommended as distortion "
+"may occur."
+msgstr ""
+
+#: /tmp/xml2gettext.ALpXYhCQJf:78
+msgid "Failure volume"
+msgstr ""
+
+#: /tmp/xml2gettext.ALpXYhCQJf:79
+msgid ""
+"The ingame fail sound volume. Values above 90 are not recommended as "
+"distortion may occur. 11 is louder than 10, but these go to 100. 89 louder!"
+msgstr ""
+
+#: /tmp/xml2gettext.ALpXYhCQJf:80
+msgid "Microphone pass-through"
+msgstr ""
+
+#: /tmp/xml2gettext.ALpXYhCQJf:81
+msgid "Send captured singing voice to speakers."
+msgstr ""
+
+#: /tmp/xml2gettext.ALpXYhCQJf:82
+msgid "Pass-through volume ratio"
+msgstr ""
+
+#: /tmp/xml2gettext.ALpXYhCQJf:83
+msgid "How much voice is amplified compared to the music."
+msgstr ""
+
+#: /tmp/xml2gettext.ALpXYhCQJf:84
+msgid "Song folders"
+msgstr ""
+
+#: /tmp/xml2gettext.ALpXYhCQJf:85
+msgid ""
+"Where to recursively look for songs. DATADIR at the beginning means all "
+"Performous data folders."
+msgstr ""
+
+#: /tmp/xml2gettext.ALpXYhCQJf:86
+msgid "Base folders for data"
+msgstr ""
+
+#: /tmp/xml2gettext.ALpXYhCQJf:87
+msgid ""
+"System defaults are included automatically. Additional paths can be added "
+"here."
+msgstr ""
+
+#~ msgid "Song is broken!"
+#~ msgstr "¡La canción ta rota!"
+
+#~ msgid "Loading instruments..."
+#~ msgstr "Cargando instrumentos..."
+
+#~ msgid "Finalizing..."
+#~ msgstr "Finando..."
+
+#, fuzzy
+#~ msgid "Loading graphics..."
+#~ msgstr "Cargando canción..."
+
+#~ msgid "Random background..."
+#~ msgstr "Fondu al debalu..."
+
+#~ msgid "(press END to view hiscores)"
+#~ msgstr "(primi END p'agüeyar rexistros)"
+
+#~ msgid "<type in to search>"
+#~ msgstr "<Escribe pala gueta>"
+
+#~ msgid "Graphics"
+#~ msgstr "Gráficos."
+
+#, fuzzy
+#~ msgid "Gameplay settings."
+#~ msgstr "Opciones rellacionaes col mou de xuegu"
+
+#, fuzzy
+#~ msgid "Video and rendering settings."
+#~ msgstr "Configurar axustes de vidéu y renderizáu"
+
+#~ msgid "Loading theme..."
+#~ msgstr "Cargando tema..."
+
+#~ msgid "Loading background..."
+#~ msgstr "Cargando fondu..."
+
+#~ msgid "Loading user interface..."
+#~ msgstr "Cargando interfaz d'usuariu..."
diff --git a/lang/da.po b/lang/da.po
new file mode 100644 (file)
index 0000000..23e15ea
--- /dev/null
@@ -0,0 +1,816 @@
+# Danish translation for Performous.
+# Copyright (C) 2010 performous.org
+# This file is distributed under the same license as the Performous package.
+# Anders Jenbo <anders@jenbo.dk>, 2010.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: Performous\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2013-05-24 12:46+0100\n"
+"PO-Revision-Date: 2013-05-24 12:47+0100\n"
+"Last-Translator: Tapio Vierros <tapiovierros@gmail.com>\n"
+"Language-Team: Danskgruppen <dansk@dansk-gruppen.dk>\n"
+"Language: da\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"X-Poedit-KeywordsList: _\n"
+"X-Poedit-Basepath: .\n"
+"X-Generator: Poedit 1.5.4\n"
+"X-Poedit-SearchPath-0: ../game\n"
+"X-Poedit-SearchPath-1: ../data\n"
+
+#: ../game/screen_paths.cc:24
+msgid ""
+"This tool is not yet available.\n"
+"Configure paths by adding them\n"
+"as command line parameters and\n"
+"then save them in configuration menu."
+msgstr ""
+
+#: ../game/screen_paths.cc:70
+msgid "Press any key to exit."
+msgstr ""
+
+#: ../game/screen_paths.cc:75
+msgid ""
+"Windows users can also use ConfigureSongDirectory.bat in the bin-directory."
+msgstr ""
+
+#: ../game/configuration.cc:117
+msgid "Enabled"
+msgstr ""
+
+#: ../game/configuration.cc:117
+msgid "Disabled"
+msgstr ""
+
+#: ../game/configuration.cc:121
+#, fuzzy, c-format
+msgid "%d items"
+msgstr "%d emner"
+
+#: ../game/instrumentgraph.cc:56 ../game/screen_sing.cc:123
+#, fuzzy
+msgid "Resume"
+msgstr "Genoptag"
+
+#: ../game/instrumentgraph.cc:56 ../game/screen_sing.cc:123
+#, fuzzy
+msgid "Back to performing!"
+msgstr "Tilbage til optræden!"
+
+#: ../game/instrumentgraph.cc:57
+msgid "Rejoin"
+msgstr ""
+
+#: ../game/instrumentgraph.cc:57
+msgid "Change selections"
+msgstr ""
+
+#: ../game/instrumentgraph.cc:58 ../game/screen_sing.cc:124
+#, fuzzy
+msgid "Restart"
+msgstr "Genstarter"
+
+#: ../game/instrumentgraph.cc:58 ../game/screen_sing.cc:124
+#, fuzzy
+msgid ""
+"Start the song\n"
+"from the beginning"
+msgstr ""
+"Start sangen\n"
+"fra begyndelsen"
+
+#: ../game/instrumentgraph.cc:59 ../game/guitargraph.cc:200
+#: ../game/screen_intro.cc:184 ../game/dancegraph.cc:137
+#: ../game/screen_sing.cc:92 ../game/screen_sing.cc:126
+msgid "Quit"
+msgstr "Afslut"
+
+#: ../game/instrumentgraph.cc:59 ../game/guitargraph.cc:200
+#: ../game/dancegraph.cc:137 ../game/screen_sing.cc:92
+#: ../game/screen_sing.cc:126
+msgid "Exit to song browser"
+msgstr ""
+
+#: ../game/guitargraph.cc:14
+#, fuzzy
+msgid "Kids"
+msgstr "Børn"
+
+#: ../game/guitargraph.cc:14 ../game/dancegraph.cc:18
+#, fuzzy
+msgid "Easy"
+msgstr "Let"
+
+#: ../game/guitargraph.cc:14 ../game/dancegraph.cc:18
+#, fuzzy
+msgid "Medium"
+msgstr "Medium"
+
+#: ../game/guitargraph.cc:14 ../game/dancegraph.cc:18
+#, fuzzy
+msgid "Hard"
+msgstr "Hård"
+
+#: ../game/guitargraph.cc:14
+#, fuzzy
+msgid "Expert"
+msgstr "Ekspert"
+
+#: ../game/guitargraph.cc:163 ../game/dancegraph.cc:134
+#, fuzzy
+msgid "Select difficulty"
+msgstr "Vælg sværhedsgrad"
+
+#: ../game/guitargraph.cc:169 ../game/guitargraph.cc:186
+msgid "Lefty-mode"
+msgstr ""
+
+#: ../game/guitargraph.cc:183 ../game/dancegraph.cc:118
+msgid "Select track"
+msgstr ""
+
+#: ../game/guitargraph.cc:194 ../game/dancegraph.cc:107
+#, fuzzy
+msgid "Ready!"
+msgstr "Klar!"
+
+#: ../game/guitargraph.cc:194 ../game/screen_intro.cc:166
+#: ../game/dancegraph.cc:107
+msgid "Start performing!"
+msgstr "Begynd at optræde!"
+
+#: ../game/guitargraph.cc:207
+#, fuzzy
+msgid "ON"
+msgstr "Tænt"
+
+#: ../game/guitargraph.cc:207
+#, fuzzy
+msgid "OFF"
+msgstr "Slukket"
+
+#: ../game/guitargraph.cc:208
+msgid "Toggle lefty-mode"
+msgstr ""
+
+#: ../game/guitargraph.cc:447 ../game/dancegraph.cc:319
+msgid "Streak!"
+msgstr ""
+
+#: ../game/guitargraph.cc:459
+#, fuzzy
+msgid ""
+"God Mode\n"
+"Activated!"
+msgstr ""
+"Gudetilstand\n"
+"Aktiveret!"
+
+#: ../game/guitargraph.cc:460
+#, fuzzy
+msgid "Mistakes ignored!"
+msgstr "Fejl ignoreret!"
+
+#: ../game/guitargraph.cc:1102
+#, fuzzy
+msgid "God Mode Ready!"
+msgstr "Gudetilstand klar!"
+
+#: ../game/guitargraph.cc:1103
+msgid "Drum Fill!"
+msgstr ""
+
+#: ../game/guitargraph.cc:1106
+#, fuzzy
+msgid "Solo!"
+msgstr "Solo!"
+
+#: ../game/songs.cc:194
+msgid "show all songs"
+msgstr ""
+
+#: ../game/songs.cc:195
+msgid "has dance"
+msgstr ""
+
+#: ../game/songs.cc:196
+msgid "has vocals"
+msgstr ""
+
+#: ../game/songs.cc:197
+msgid "has duet"
+msgstr ""
+
+#: ../game/songs.cc:198
+#, fuzzy
+msgid "has guitar"
+msgstr "Afslut"
+
+#: ../game/songs.cc:199
+msgid "drums or keytar"
+msgstr ""
+
+#: ../game/songs.cc:200
+msgid "full band"
+msgstr ""
+
+#: ../game/songs.cc:228
+msgid "random order"
+msgstr "tilfældig rækkefølge"
+
+#: ../game/songs.cc:229
+msgid "sorted by song"
+msgstr "sorter efter sang"
+
+#: ../game/songs.cc:230
+msgid "sorted by artist"
+msgstr "sorter efter kunstner"
+
+#: ../game/songs.cc:231
+msgid "sorted by edition"
+msgstr "sorter efter udgave"
+
+#: ../game/songs.cc:232
+msgid "sorted by genre"
+msgstr "sorter efter genre"
+
+#: ../game/songs.cc:233
+msgid "sorted by path"
+msgstr "sorter efter sti"
+
+#: ../game/songs.cc:234
+msgid "sorted by language"
+msgstr "sorter efter sprog"
+
+#: ../game/screen_intro.cc:24
+msgid "No playback devices could be used.\n"
+msgstr "Ingen afspilningsenhed kunne bruges\n"
+
+#: ../game/screen_intro.cc:25
+msgid ""
+"\n"
+"Please configure some before playing."
+msgstr ""
+"\n"
+"konfigurer venligst en før du spiller."
+
+#: ../game/screen_intro.cc:69
+msgid "Settings saved as system defaults."
+msgstr ""
+
+#: ../game/screen_intro.cc:69
+msgid "Settings saved."
+msgstr ""
+
+#: ../game/screen_intro.cc:149
+#, fuzzy
+msgid "Ctrl + S to save, Ctrl + R to reset defaults"
+msgstr "Ctrl+s for at gemme, ctrl+r for at genoprette standarder"
+
+#: ../game/screen_intro.cc:166
+msgid "Perform"
+msgstr "Optræd"
+
+#: ../game/screen_intro.cc:167
+msgid "Practice"
+msgstr "Øv"
+
+#: ../game/screen_intro.cc:167
+msgid "Check your skills or test the microphones"
+msgstr "Tjek dine evner eller test mikrofonerne"
+
+#: ../game/screen_intro.cc:183
+msgid "Configure"
+msgstr "Indstillinger"
+
+#: ../game/screen_intro.cc:183
+#, fuzzy
+msgid "Configure audio and game options"
+msgstr "Konfigurer lyd- og spilindstillinger"
+
+#: ../game/screen_intro.cc:184
+msgid "Leave the game"
+msgstr "Forlad spillet"
+
+#: ../game/dancegraph.cc:18
+#, fuzzy
+msgid "Beginner"
+msgstr "Begynner"
+
+#: ../game/dancegraph.cc:18
+#, fuzzy
+msgid "Challenge"
+msgstr "Udfordring"
+
+#: ../game/dancegraph.cc:248
+#, fuzzy
+msgid "STOP!"
+msgstr "STOP!"
+
+#: ../game/screen_playlist.cc:110 ../game/screen_playlist.cc:252
+msgid "Continue"
+msgstr ""
+
+#: ../game/screen_playlist.cc:110
+msgid "Continue playing"
+msgstr ""
+
+#: ../game/screen_playlist.cc:118
+msgid "Add songs"
+msgstr ""
+
+#: ../game/screen_playlist.cc:118
+msgid "Open the song browser to add more songs"
+msgstr ""
+
+#: ../game/screen_playlist.cc:119 ../game/screen_songs.cc:513
+msgid "Shuffle"
+msgstr ""
+
+#: ../game/screen_playlist.cc:119 ../game/screen_songs.cc:513
+msgid "Randomize the order of the playlist"
+msgstr ""
+
+#: ../game/screen_playlist.cc:125
+msgid "Clear and exit"
+msgstr ""
+
+#: ../game/screen_playlist.cc:125 ../game/screen_songs.cc:520
+msgid "Remove all the songs from the list"
+msgstr ""
+
+#: ../game/screen_playlist.cc:131 ../game/screen_playlist.cc:275
+#: ../game/screen_songs.cc:526
+msgid "Back"
+msgstr ""
+
+#: ../game/screen_playlist.cc:131 ../game/screen_playlist.cc:275
+msgid "Back to playlist viewer"
+msgstr ""
+
+#: ../game/screen_playlist.cc:237
+msgid "Press enter to view song options"
+msgstr ""
+
+#: ../game/screen_playlist.cc:244
+msgid "View more options"
+msgstr ""
+
+#: ../game/screen_playlist.cc:244
+#, fuzzy
+msgid "View general playlist settings"
+msgstr "Konfigurer generelle lydindstillinger"
+
+#: ../game/screen_playlist.cc:252
+msgid "Play first"
+msgstr ""
+
+#: ../game/screen_playlist.cc:254
+msgid "Ignore the playlist's order and play this song first"
+msgstr ""
+
+#: ../game/screen_playlist.cc:255
+msgid "Start the song already!"
+msgstr ""
+
+#: ../game/screen_playlist.cc:264
+msgid "Remove"
+msgstr ""
+
+#: ../game/screen_playlist.cc:264
+msgid "Remove this song from the list"
+msgstr ""
+
+#: ../game/main.cc:146
+msgid "Loading audio samples..."
+msgstr "Indlæser lydprøver..."
+
+#: ../game/main.cc:160
+#, fuzzy
+msgid "Creating screens..."
+msgstr "Opretter sener..."
+
+#: ../game/main.cc:170
+msgid "Entering main menu"
+msgstr ""
+
+#: ../game/main.cc:172 ../game/screen_sing.cc:97
+#, fuzzy
+msgid "Loading complete"
+msgstr "Indlæsning færdig"
+
+#: ../game/main.cc:183
+msgid "Screenshot taken!"
+msgstr ""
+
+#: ../game/main.cc:186
+msgid "Screenshot failed!"
+msgstr ""
+
+#: ../game/screen_sing.cc:45
+#, fuzzy
+msgid "Initializing webcam..."
+msgstr "Starter webcam..."
+
+#: ../game/screen_sing.cc:52
+#, fuzzy
+msgid "Loading video..."
+msgstr "Indlæser video..."
+
+#: ../game/screen_sing.cc:59
+#, fuzzy
+msgid "Loading song..."
+msgstr "Indlæser sang..."
+
+#: ../game/screen_sing.cc:66
+msgid "Song contains broken tracks!"
+msgstr ""
+
+#: ../game/screen_sing.cc:71
+#, fuzzy
+msgid "Loading menu..."
+msgstr "Indlæser menu..."
+
+#: ../game/screen_sing.cc:76
+#, fuzzy
+msgid "Start"
+msgstr "Genstarter"
+
+#: ../game/screen_sing.cc:76
+#, fuzzy
+msgid "Start performing"
+msgstr "Begynd at optræde!"
+
+#: ../game/screen_sing.cc:80
+msgid "Duet mode"
+msgstr ""
+
+#: ../game/screen_sing.cc:81
+msgid "Normal mode"
+msgstr ""
+
+#: ../game/screen_sing.cc:82
+msgid "Switch between duet and regular singing mode"
+msgstr ""
+
+#: ../game/screen_sing.cc:90
+msgid "Change vocal track"
+msgstr ""
+
+#: ../game/screen_sing.cc:125
+msgid "Skip"
+msgstr ""
+
+#: ../game/screen_sing.cc:125
+msgid "Skip current song"
+msgstr ""
+
+#: ../game/screen_sing.cc:391
+msgid "Press UP to join dance!"
+msgstr ""
+
+#: ../game/screen_sing.cc:391
+msgid "Step UP to join!"
+msgstr ""
+
+#: ../game/screen_sing.cc:396
+msgid "Press 1 to join guitar!"
+msgstr ""
+
+#: ../game/screen_sing.cc:396
+msgid "Press GREEN to join!"
+msgstr ""
+
+#: ../game/screen_sing.cc:401
+msgid "Press SPACE to join drums!"
+msgstr ""
+
+#: ../game/screen_sing.cc:401
+msgid "KICK to join!"
+msgstr ""
+
+#: ../game/screen_sing.cc:475
+msgid "   ENTER to skip instrumental break"
+msgstr "   ENTER for at springe over instrumental pause"
+
+#: ../game/screen_sing.cc:476
+msgid "   Remember to wait for grading!"
+msgstr "   Husk at vendte på karakteruddeling!"
+
+#: ../game/screen_sing.cc:587
+msgid "No player!"
+msgstr "Ingen spiller!"
+
+#: ../game/screen_sing.cc:594
+msgid "Hit singer"
+msgstr "Hitsanger"
+
+#: ../game/screen_sing.cc:595
+msgid "Lead singer"
+msgstr "Forsanger"
+
+#: ../game/screen_sing.cc:596 ../game/screen_sing.cc:602
+#: ../game/screen_sing.cc:608
+msgid "Rising star"
+msgstr "Ny stjerne"
+
+#: ../game/screen_sing.cc:597 ../game/screen_sing.cc:603
+#: ../game/screen_sing.cc:609
+msgid "Amateur"
+msgstr "Amatør"
+
+#: ../game/screen_sing.cc:598 ../game/screen_sing.cc:610
+msgid "Tone deaf"
+msgstr "Tonedøv"
+
+#: ../game/screen_sing.cc:600
+msgid "Maniac"
+msgstr "Galning"
+
+#: ../game/screen_sing.cc:601
+msgid "Hoofer"
+msgstr "Professionel danser"
+
+#: ../game/screen_sing.cc:604
+msgid "Loser"
+msgstr "Taber"
+
+#: ../game/screen_sing.cc:606
+msgid "Virtuoso"
+msgstr "Virtuos"
+
+#: ../game/screen_sing.cc:607
+msgid "Rocker"
+msgstr "Rocker"
+
+#: ../game/screen_songs.cc:279
+msgid "No songs found!"
+msgstr "Ingen sange fundet!"
+
+#: ../game/screen_songs.cc:280
+msgid ""
+"Visit performous.org\n"
+"for free songs"
+msgstr ""
+"Besøg performous.org\n"
+"for gratis sange"
+
+#: ../game/screen_songs.cc:282
+#, fuzzy
+msgid "Sorry, no songs match the search!"
+msgstr "ingen sange matchede søgning"
+
+#: ../game/screen_songs.cc:289
+#, fuzzy
+msgid "Hiscore\n"
+msgstr "Højeste resultater for %1%\n"
+
+#: ../game/screen_songs.cc:298
+msgid "<type in to search>   ↔ songs    ↕ options"
+msgstr ""
+
+#: ../game/screen_songs.cc:301
+msgid "↔ sort order: "
+msgstr ""
+
+#: ../game/screen_songs.cc:302
+#, fuzzy
+msgid "↔ type filter: "
+msgstr "filtrer: "
+
+#: ../game/screen_songs.cc:303
+msgid "↔ hiscores   ↵ jukebox mode"
+msgstr ""
+
+#: ../game/screen_songs.cc:307
+msgid "↵ start a playlist with this song!"
+msgstr ""
+
+#: ../game/screen_songs.cc:309
+msgid "↵ open the playlist menu"
+msgstr ""
+
+#: ../game/screen_songs.cc:506
+msgid "Play"
+msgstr ""
+
+#: ../game/screen_songs.cc:506
+msgid "Start the game with all songs in playlist"
+msgstr ""
+
+#: ../game/screen_songs.cc:519
+msgid "View playlist"
+msgstr ""
+
+#: ../game/screen_songs.cc:519
+msgid "View the current playlist"
+msgstr ""
+
+#: ../game/screen_songs.cc:520
+msgid "Clear playlist"
+msgstr ""
+
+#: ../game/screen_songs.cc:526
+msgid "Back to song browser"
+msgstr ""
+
+#: ../game/screen_players.cc:115
+msgid "No players found!"
+msgstr "Ingen spillere fundet!"
+
+#: ../game/screen_players.cc:116
+msgid "Enter a name to create a new player."
+msgstr "Indtaste et navn for at oprette ny spiller."
+
+#: ../game/screen_players.cc:118
+msgid "Press enter to create player!"
+msgstr "Tryk enter for at oprette spilleren!"
+
+#: ../game/screen_players.cc:122
+#, fuzzy
+msgid "No players worth mentioning!"
+msgstr "Ingen spillere fundet!"
+
+#: ../game/screen_players.cc:127
+msgid "You reached %1% points!"
+msgstr "Du opnåede %1% point!"
+
+#: ../game/screen_players.cc:128
+msgid "Change player with arrow keys."
+msgstr "Skift spiller med piletasterne."
+
+#: ../game/screen_players.cc:129
+msgid "Name:"
+msgstr "Navn:"
+
+#: ../game/screen_players.cc:132
+msgid "Type text to filter or create a new player."
+msgstr "Skriv tekst for at filtere eller oprette en ny spiller."
+
+#: ../game/screen_players.cc:132
+msgid "Search Text:"
+msgstr "Søgeord:"
+
+#: ../game/screen_audiodevices.cc:55
+msgid ""
+"It seems you have some manual configurations\n"
+"incompatible with this user interface.\n"
+"Saving these settings will override\n"
+"all existing audio device configuration.\n"
+"Your other options changes will be saved too."
+msgstr ""
+
+#: ../game/screen_audiodevices.cc:114
+msgid "- Unassigned -"
+msgstr ""
+
+#: ../game/screen_audiodevices.cc:135
+msgid ""
+"Use arrow keys to configure. Hit Enter/Start to save and test or Esc/Select "
+"to cancel. Ctrl + R to reset defaults"
+msgstr ""
+
+#: ../game/screen_audiodevices.cc:140
+msgid ""
+"For advanced device configuration, use command line parameter --audio (use --"
+"audiohelp for details)."
+msgstr ""
+
+#: ../game/screen_audiodevices.cc:188
+#, fuzzy
+msgid "Some devices failed to open!"
+msgstr "Nogle enheder kunne ikke åbnes!"
+
+#: ../game/database.cc:89 ../game/database.cc:107
+msgid "No Items up to now."
+msgstr ""
+
+#: ../game/database.cc:90 ../game/database.cc:108
+msgid "Be the first to be listed here!"
+msgstr ""
+
+#: ../game/song.hh:22
+#, fuzzy
+msgid "Guitar"
+msgstr "Afslut"
+
+#: ../game/song.hh:22
+msgid "Coop guitar"
+msgstr ""
+
+#: ../game/song.hh:22
+msgid "Rhythm guitar"
+msgstr ""
+
+#: ../game/song.hh:22
+#, fuzzy
+msgid "Bass"
+msgstr "Bas"
+
+#: ../game/song.hh:22
+#, fuzzy
+msgid "Drums"
+msgstr "Trummer"
+
+#: ../game/song.hh:22
+msgid "Vocals"
+msgstr ""
+
+#: ../game/song.hh:22
+msgid "Harmonic 1"
+msgstr ""
+
+#: ../game/song.hh:22
+msgid "Harmonic 2"
+msgstr ""
+
+#: ../game/song.hh:22
+msgid "Harmonic 3"
+msgstr ""
+
+#, fuzzy
+#~ msgid "Song is broken!"
+#~ msgstr "Sangen er i stykker!"
+
+#, fuzzy
+#~ msgid "Loading instruments..."
+#~ msgstr "Indlæser instrumenter..."
+
+#, fuzzy
+#~ msgid "Loading graphics..."
+#~ msgstr "Indlæser sang..."
+
+#, fuzzy
+#~ msgid "Random background..."
+#~ msgstr "Tilfældig bauggrund..."
+
+#~ msgid "(press END to view hiscores)"
+#~ msgstr "(tryk END for at se bedste resultater)"
+
+#, fuzzy
+#~ msgid "<type in to search>"
+#~ msgstr "<skriv for at søge>"
+
+#, fuzzy
+#~ msgid "Audio Devices"
+#~ msgstr "Lydenheder"
+
+#, fuzzy
+#~ msgid "Audio"
+#~ msgstr "Lyd"
+
+#, fuzzy
+#~ msgid "Graphics"
+#~ msgstr "Grafik"
+
+#, fuzzy
+#~ msgid "Configure rendering and video settings"
+#~ msgstr "Konfigurer renderings- og videoindstillinger"
+
+#, fuzzy
+#~ msgid "Game"
+#~ msgstr "Spil"
+
+#, fuzzy
+#~ msgid "Paths"
+#~ msgstr "Stier"
+
+#, fuzzy
+#~ msgid "Graphic"
+#~ msgstr "Grafik"
+
+#, fuzzy
+#~ msgid "Video and rendering settings."
+#~ msgstr "Konfigurer renderings- og videoindstillinger"
+
+#, fuzzy
+#~ msgid "Webcam background"
+#~ msgstr "Tilfældig bauggrund..."
+
+#, fuzzy
+#~ msgid "Audio devices"
+#~ msgstr "Lydenheder"
+
+#~ msgid "Loading theme..."
+#~ msgstr "Indlæser tema..."
+
+#~ msgid "Loading background..."
+#~ msgstr "Indlæser baggrund..."
+
+#, fuzzy
+#~ msgid "Loading user interface..."
+#~ msgstr "Indlæser brugerflade..."
+
+#, fuzzy
+#~ msgid "Audio..."
+#~ msgstr "Lyd..."
+
+#~ msgid "No microphones found.\n"
+#~ msgstr "Ingen mikrofon fundet.\n"
+
+#~ msgid "none"
+#~ msgstr "ingen"
diff --git a/lang/de.po b/lang/de.po
new file mode 100644 (file)
index 0000000..83d56b0
--- /dev/null
@@ -0,0 +1,1030 @@
+msgid ""
+msgstr ""
+"Project-Id-Version: Performous\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2013-05-24 12:47+0100\n"
+"PO-Revision-Date: \n"
+"Last-Translator: Tapio Vierros <tapiovierros@gmail.com>\n"
+"Language-Team: \n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"X-Poedit-KeywordsList: _\n"
+"X-Poedit-Basepath: .\n"
+"X-Generator: Poedit 1.5.4\n"
+"X-Poedit-SearchPath-0: ../game\n"
+"X-Poedit-SearchPath-1: ../data\n"
+
+#: ../game/screen_paths.cc:24
+msgid ""
+"This tool is not yet available.\n"
+"Configure paths by adding them\n"
+"as command line parameters and\n"
+"then save them in configuration menu."
+msgstr ""
+
+#: ../game/screen_paths.cc:70
+msgid "Press any key to exit."
+msgstr ""
+
+#: ../game/screen_paths.cc:75
+msgid ""
+"Windows users can also use ConfigureSongDirectory.bat in the bin-directory."
+msgstr ""
+
+#: ../game/configuration.cc:117
+msgid "Enabled"
+msgstr ""
+
+#: ../game/configuration.cc:117
+msgid "Disabled"
+msgstr ""
+
+#: ../game/configuration.cc:121
+#, c-format
+msgid "%d items"
+msgstr ""
+
+#: ../game/instrumentgraph.cc:56 ../game/screen_sing.cc:123
+msgid "Resume"
+msgstr "Weiter machen"
+
+#: ../game/instrumentgraph.cc:56 ../game/screen_sing.cc:123
+msgid "Back to performing!"
+msgstr "Zurück zu deinem Auftritt!"
+
+#: ../game/instrumentgraph.cc:57
+msgid "Rejoin"
+msgstr "Wieder einsteigen"
+
+#: ../game/instrumentgraph.cc:57
+msgid "Change selections"
+msgstr "Auswahl ändern"
+
+#: ../game/instrumentgraph.cc:58 ../game/screen_sing.cc:124
+msgid "Restart"
+msgstr "Neustarten"
+
+#: ../game/instrumentgraph.cc:58 ../game/screen_sing.cc:124
+msgid ""
+"Start the song\n"
+"from the beginning"
+msgstr "Den Song von Neuem beginnen"
+
+#: ../game/instrumentgraph.cc:59 ../game/guitargraph.cc:200
+#: ../game/screen_intro.cc:184 ../game/dancegraph.cc:137
+#: ../game/screen_sing.cc:92 ../game/screen_sing.cc:126
+msgid "Quit"
+msgstr "Beenden"
+
+#: ../game/instrumentgraph.cc:59 ../game/guitargraph.cc:200
+#: ../game/dancegraph.cc:137 ../game/screen_sing.cc:92
+#: ../game/screen_sing.cc:126
+msgid "Exit to song browser"
+msgstr "Zurück zum Songbrowser."
+
+#: ../game/guitargraph.cc:14
+msgid "Kids"
+msgstr "Kinderleicht"
+
+#: ../game/guitargraph.cc:14 ../game/dancegraph.cc:18
+msgid "Easy"
+msgstr "Leicht"
+
+#: ../game/guitargraph.cc:14 ../game/dancegraph.cc:18
+msgid "Medium"
+msgstr "Medium"
+
+#: ../game/guitargraph.cc:14 ../game/dancegraph.cc:18
+msgid "Hard"
+msgstr "Schwer"
+
+#: ../game/guitargraph.cc:14
+msgid "Expert"
+msgstr "Experte"
+
+#: ../game/guitargraph.cc:163 ../game/dancegraph.cc:134
+msgid "Select difficulty"
+msgstr "Schwierigkeit auswählen"
+
+#: ../game/guitargraph.cc:169 ../game/guitargraph.cc:186
+msgid "Lefty-mode"
+msgstr "Linkshänder"
+
+#: ../game/guitargraph.cc:183 ../game/dancegraph.cc:118
+msgid "Select track"
+msgstr "Titel auswählen"
+
+#: ../game/guitargraph.cc:194 ../game/dancegraph.cc:107
+msgid "Ready!"
+msgstr "Bereit?!"
+
+#: ../game/guitargraph.cc:194 ../game/screen_intro.cc:166
+#: ../game/dancegraph.cc:107
+msgid "Start performing!"
+msgstr "Starte deinen Auftritt!"
+
+#: ../game/guitargraph.cc:207
+msgid "ON"
+msgstr "AN"
+
+#: ../game/guitargraph.cc:207
+msgid "OFF"
+msgstr "AUS"
+
+#: ../game/guitargraph.cc:208
+msgid "Toggle lefty-mode"
+msgstr "Modus Linkshänder auswählen"
+
+#: ../game/guitargraph.cc:447 ../game/dancegraph.cc:319
+msgid "Streak!"
+msgstr ""
+
+#: ../game/guitargraph.cc:459
+msgid ""
+"God Mode\n"
+"Activated!"
+msgstr "God Mode aktiviert"
+
+#: ../game/guitargraph.cc:460
+msgid "Mistakes ignored!"
+msgstr "Fehler ignoriert!"
+
+#: ../game/guitargraph.cc:1102
+msgid "God Mode Ready!"
+msgstr "God Mode bereit!"
+
+#: ../game/guitargraph.cc:1103
+msgid "Drum Fill!"
+msgstr "Drummer Einsatz!"
+
+#: ../game/guitargraph.cc:1106
+msgid "Solo!"
+msgstr "Solo!"
+
+#: ../game/songs.cc:194
+msgid "show all songs"
+msgstr ""
+
+#: ../game/songs.cc:195
+msgid "has dance"
+msgstr ""
+
+#: ../game/songs.cc:196
+msgid "has vocals"
+msgstr ""
+
+#: ../game/songs.cc:197
+msgid "has duet"
+msgstr ""
+
+#: ../game/songs.cc:198
+#, fuzzy
+msgid "has guitar"
+msgstr "Tastatur als Gitarre nutzen"
+
+#: ../game/songs.cc:199
+msgid "drums or keytar"
+msgstr ""
+
+#: ../game/songs.cc:200
+msgid "full band"
+msgstr ""
+
+#: ../game/songs.cc:228
+msgid "random order"
+msgstr "Zufällige Reihenfolge"
+
+#: ../game/songs.cc:229
+msgid "sorted by song"
+msgstr "nach Liedern sortiert"
+
+#: ../game/songs.cc:230
+msgid "sorted by artist"
+msgstr "nach Interpreten sortiert"
+
+#: ../game/songs.cc:231
+msgid "sorted by edition"
+msgstr "nach Edition sortiert"
+
+#: ../game/songs.cc:232
+msgid "sorted by genre"
+msgstr "nach Genre sortiert"
+
+#: ../game/songs.cc:233
+msgid "sorted by path"
+msgstr "nach Dateipfad sortiert"
+
+#: ../game/songs.cc:234
+msgid "sorted by language"
+msgstr "nach Sprache sortiert"
+
+#: ../game/screen_intro.cc:24
+msgid "No playback devices could be used.\n"
+msgstr "Kann keine Wiedergabegeräte benutzen.\n"
+
+#: ../game/screen_intro.cc:25
+msgid ""
+"\n"
+"Please configure some before playing."
+msgstr ""
+"\n"
+"Du musst zuerst die Ein- und Ausgabegeräte konfigurieren, bevor du spielst."
+
+#: ../game/screen_intro.cc:69
+msgid "Settings saved as system defaults."
+msgstr ""
+
+#: ../game/screen_intro.cc:69
+msgid "Settings saved."
+msgstr ""
+
+#: ../game/screen_intro.cc:149
+msgid "Ctrl + S to save, Ctrl + R to reset defaults"
+msgstr ""
+"Drücke die Kombinationen Strg + S zum Speichern oder Strg + R um die "
+"Standardeinstellung wiederherzustellen"
+
+#: ../game/screen_intro.cc:166
+msgid "Perform"
+msgstr "Spielen"
+
+#: ../game/screen_intro.cc:167
+msgid "Practice"
+msgstr "Üben"
+
+#: ../game/screen_intro.cc:167
+msgid "Check your skills or test the microphones"
+msgstr "Teste deine Fähigkeiten - oder das Mikro!"
+
+#: ../game/screen_intro.cc:183
+msgid "Configure"
+msgstr "Konfigurieren"
+
+#: ../game/screen_intro.cc:183
+#, fuzzy
+msgid "Configure audio and game options"
+msgstr "Spieloptionen konfigurieren"
+
+#: ../game/screen_intro.cc:184
+msgid "Leave the game"
+msgstr "Spiel verlassen"
+
+#: ../game/dancegraph.cc:18
+msgid "Beginner"
+msgstr "Anfänger"
+
+#: ../game/dancegraph.cc:18
+msgid "Challenge"
+msgstr "Herausforderung"
+
+#: ../game/dancegraph.cc:248
+msgid "STOP!"
+msgstr "STOP!"
+
+#: ../game/screen_playlist.cc:110 ../game/screen_playlist.cc:252
+msgid "Continue"
+msgstr ""
+
+#: ../game/screen_playlist.cc:110
+msgid "Continue playing"
+msgstr ""
+
+#: ../game/screen_playlist.cc:118
+msgid "Add songs"
+msgstr ""
+
+#: ../game/screen_playlist.cc:118
+msgid "Open the song browser to add more songs"
+msgstr ""
+
+#: ../game/screen_playlist.cc:119 ../game/screen_songs.cc:513
+msgid "Shuffle"
+msgstr ""
+
+#: ../game/screen_playlist.cc:119 ../game/screen_songs.cc:513
+msgid "Randomize the order of the playlist"
+msgstr ""
+
+#: ../game/screen_playlist.cc:125
+msgid "Clear and exit"
+msgstr ""
+
+#: ../game/screen_playlist.cc:125 ../game/screen_songs.cc:520
+msgid "Remove all the songs from the list"
+msgstr ""
+
+#: ../game/screen_playlist.cc:131 ../game/screen_playlist.cc:275
+#: ../game/screen_songs.cc:526
+msgid "Back"
+msgstr ""
+
+#: ../game/screen_playlist.cc:131 ../game/screen_playlist.cc:275
+msgid "Back to playlist viewer"
+msgstr ""
+
+#: ../game/screen_playlist.cc:237
+msgid "Press enter to view song options"
+msgstr ""
+
+#: ../game/screen_playlist.cc:244
+msgid "View more options"
+msgstr ""
+
+#: ../game/screen_playlist.cc:244
+#, fuzzy
+msgid "View general playlist settings"
+msgstr "Spieloptionen konfigurieren"
+
+#: ../game/screen_playlist.cc:252
+msgid "Play first"
+msgstr ""
+
+#: ../game/screen_playlist.cc:254
+msgid "Ignore the playlist's order and play this song first"
+msgstr ""
+
+#: ../game/screen_playlist.cc:255
+msgid "Start the song already!"
+msgstr ""
+
+#: ../game/screen_playlist.cc:264
+msgid "Remove"
+msgstr ""
+
+#: ../game/screen_playlist.cc:264
+msgid "Remove this song from the list"
+msgstr ""
+
+#: ../game/main.cc:146
+#, fuzzy
+msgid "Loading audio samples..."
+msgstr "Lade Song ..."
+
+#: ../game/main.cc:160
+msgid "Creating screens..."
+msgstr ""
+
+#: ../game/main.cc:170
+msgid "Entering main menu"
+msgstr ""
+
+#: ../game/main.cc:172 ../game/screen_sing.cc:97
+msgid "Loading complete"
+msgstr ""
+
+#: ../game/main.cc:183
+msgid "Screenshot taken!"
+msgstr "Screenshot gemacht!"
+
+#: ../game/main.cc:186
+msgid "Screenshot failed!"
+msgstr "Screenshot schlug fehl!"
+
+#: ../game/screen_sing.cc:45
+msgid "Initializing webcam..."
+msgstr ""
+
+#: ../game/screen_sing.cc:52
+#, fuzzy
+msgid "Loading video..."
+msgstr "Lade Song ..."
+
+#: ../game/screen_sing.cc:59
+msgid "Loading song..."
+msgstr "Lade Song ..."
+
+#: ../game/screen_sing.cc:66
+msgid "Song contains broken tracks!"
+msgstr "Der Song enthält fehlerhafte Tonspuren!"
+
+#: ../game/screen_sing.cc:71
+#, fuzzy
+msgid "Loading menu..."
+msgstr "Hauptmenü …"
+
+#: ../game/screen_sing.cc:76
+#, fuzzy
+msgid "Start"
+msgstr "Neustarten"
+
+#: ../game/screen_sing.cc:76
+#, fuzzy
+msgid "Start performing"
+msgstr "Starte deinen Auftritt!"
+
+#: ../game/screen_sing.cc:80
+#, fuzzy
+msgid "Duet mode"
+msgstr "Linkshänder"
+
+#: ../game/screen_sing.cc:81
+#, fuzzy
+msgid "Normal mode"
+msgstr "Karaokemodus"
+
+#: ../game/screen_sing.cc:82
+msgid "Switch between duet and regular singing mode"
+msgstr ""
+
+#: ../game/screen_sing.cc:90
+msgid "Change vocal track"
+msgstr ""
+
+#: ../game/screen_sing.cc:125
+msgid "Skip"
+msgstr ""
+
+#: ../game/screen_sing.cc:125
+msgid "Skip current song"
+msgstr ""
+
+#: ../game/screen_sing.cc:391
+msgid "Press UP to join dance!"
+msgstr ""
+
+#: ../game/screen_sing.cc:391
+msgid "Step UP to join!"
+msgstr ""
+
+#: ../game/screen_sing.cc:396
+msgid "Press 1 to join guitar!"
+msgstr ""
+
+#: ../game/screen_sing.cc:396
+msgid "Press GREEN to join!"
+msgstr ""
+
+#: ../game/screen_sing.cc:401
+msgid "Press SPACE to join drums!"
+msgstr ""
+
+#: ../game/screen_sing.cc:401
+msgid "KICK to join!"
+msgstr ""
+
+#: ../game/screen_sing.cc:475
+msgid "   ENTER to skip instrumental break"
+msgstr "ENTER um Vorbereitung abzubrechen"
+
+#: ../game/screen_sing.cc:476
+msgid "   Remember to wait for grading!"
+msgstr "Bitte Warte auf die Bewertung!"
+
+#: ../game/screen_sing.cc:587
+msgid "No player!"
+msgstr "Keine Spieler!"
+
+#: ../game/screen_sing.cc:594
+msgid "Hit singer"
+msgstr "Hitsänger"
+
+#: ../game/screen_sing.cc:595
+msgid "Lead singer"
+msgstr "Leadsänger"
+
+#: ../game/screen_sing.cc:596 ../game/screen_sing.cc:602
+#: ../game/screen_sing.cc:608
+msgid "Rising star"
+msgstr "Nachwuchskünstler"
+
+#: ../game/screen_sing.cc:597 ../game/screen_sing.cc:603
+#: ../game/screen_sing.cc:609
+msgid "Amateur"
+msgstr "Amateur"
+
+#: ../game/screen_sing.cc:598 ../game/screen_sing.cc:610
+msgid "Tone deaf"
+msgstr "Taub"
+
+#: ../game/screen_sing.cc:600
+msgid "Maniac"
+msgstr "Wahnsinniger"
+
+#: ../game/screen_sing.cc:601
+msgid "Hoofer"
+msgstr "Profi-Tänzer"
+
+#: ../game/screen_sing.cc:604
+msgid "Loser"
+msgstr "Verlierer"
+
+#: ../game/screen_sing.cc:606
+msgid "Virtuoso"
+msgstr "Virtuose"
+
+#: ../game/screen_sing.cc:607
+msgid "Rocker"
+msgstr "Rocker"
+
+#: ../game/screen_songs.cc:279
+msgid "No songs found!"
+msgstr "Keine Songs vorhanden!"
+
+#: ../game/screen_songs.cc:280
+msgid ""
+"Visit performous.org\n"
+"for free songs"
+msgstr ""
+"Besuche performous.org\n"
+"für freie Songs"
+
+#: ../game/screen_songs.cc:282
+#, fuzzy
+msgid "Sorry, no songs match the search!"
+msgstr "Keine Songs gefunden"
+
+#: ../game/screen_songs.cc:289
+#, fuzzy
+msgid "Hiscore\n"
+msgstr "Punkte für %1%\n"
+
+#: ../game/screen_songs.cc:298
+msgid "<type in to search>   ↔ songs    ↕ options"
+msgstr ""
+
+#: ../game/screen_songs.cc:301
+msgid "↔ sort order: "
+msgstr ""
+
+#: ../game/screen_songs.cc:302
+msgid "↔ type filter: "
+msgstr ""
+
+#: ../game/screen_songs.cc:303
+msgid "↔ hiscores   ↵ jukebox mode"
+msgstr ""
+
+#: ../game/screen_songs.cc:307
+msgid "↵ start a playlist with this song!"
+msgstr ""
+
+#: ../game/screen_songs.cc:309
+msgid "↵ open the playlist menu"
+msgstr ""
+
+#: ../game/screen_songs.cc:506
+msgid "Play"
+msgstr ""
+
+#: ../game/screen_songs.cc:506
+msgid "Start the game with all songs in playlist"
+msgstr ""
+
+#: ../game/screen_songs.cc:519
+msgid "View playlist"
+msgstr ""
+
+#: ../game/screen_songs.cc:519
+msgid "View the current playlist"
+msgstr ""
+
+#: ../game/screen_songs.cc:520
+msgid "Clear playlist"
+msgstr ""
+
+#: ../game/screen_songs.cc:526
+#, fuzzy
+msgid "Back to song browser"
+msgstr "Zurück zum Songbrowser."
+
+#: ../game/screen_players.cc:115
+msgid "No players found!"
+msgstr "Keine Spieler gefunden!"
+
+#: ../game/screen_players.cc:116
+msgid "Enter a name to create a new player."
+msgstr "Namen eingeben um neuen Spieler zu erstellen."
+
+#: ../game/screen_players.cc:118
+msgid "Press enter to create player!"
+msgstr "Enter drücken um einen Spieler zu erstellen!"
+
+#: ../game/screen_players.cc:122
+#, fuzzy
+msgid "No players worth mentioning!"
+msgstr "Keine Spieler gefunden!"
+
+#: ../game/screen_players.cc:127
+msgid "You reached %1% points!"
+msgstr "Du hast %1% punkte erreicht!"
+
+#: ../game/screen_players.cc:128
+msgid "Change player with arrow keys."
+msgstr "Du kannst die Spieler mit den Pfeiltasten wechseln"
+
+#: ../game/screen_players.cc:129
+msgid "Name:"
+msgstr "Name:"
+
+#: ../game/screen_players.cc:132
+msgid "Type text to filter or create a new player."
+msgstr "Tippen um Spieler herauszufiltern oder einen Neuen zu erstellen."
+
+#: ../game/screen_players.cc:132
+msgid "Search Text:"
+msgstr "Suchtext:"
+
+#: ../game/screen_audiodevices.cc:55
+msgid ""
+"It seems you have some manual configurations\n"
+"incompatible with this user interface.\n"
+"Saving these settings will override\n"
+"all existing audio device configuration.\n"
+"Your other options changes will be saved too."
+msgstr ""
+
+#: ../game/screen_audiodevices.cc:114
+msgid "- Unassigned -"
+msgstr ""
+
+#: ../game/screen_audiodevices.cc:135
+msgid ""
+"Use arrow keys to configure. Hit Enter/Start to save and test or Esc/Select "
+"to cancel. Ctrl + R to reset defaults"
+msgstr ""
+
+#: ../game/screen_audiodevices.cc:140
+msgid ""
+"For advanced device configuration, use command line parameter --audio (use --"
+"audiohelp for details)."
+msgstr ""
+
+#: ../game/screen_audiodevices.cc:188
+msgid "Some devices failed to open!"
+msgstr ""
+
+#: ../game/database.cc:89 ../game/database.cc:107
+msgid "No Items up to now."
+msgstr "Hier steht noch nichts."
+
+#: ../game/database.cc:90 ../game/database.cc:108
+msgid "Be the first to be listed here!"
+msgstr "Trag dich als Erster in diese Liste ein!"
+
+#: ../game/song.hh:22
+#, fuzzy
+msgid "Guitar"
+msgstr "Beenden"
+
+#: ../game/song.hh:22
+msgid "Coop guitar"
+msgstr ""
+
+#: ../game/song.hh:22
+msgid "Rhythm guitar"
+msgstr ""
+
+#: ../game/song.hh:22
+msgid "Bass"
+msgstr ""
+
+#: ../game/song.hh:22
+msgid "Drums"
+msgstr ""
+
+#: ../game/song.hh:22
+msgid "Vocals"
+msgstr ""
+
+#: ../game/song.hh:22
+msgid "Harmonic 1"
+msgstr ""
+
+#: ../game/song.hh:22
+msgid "Harmonic 2"
+msgstr ""
+
+#: ../game/song.hh:22
+msgid "Harmonic 3"
+msgstr ""
+
+#~ msgid "Song is broken!"
+#~ msgstr "Der Song ist fehlerhaft!"
+
+#, fuzzy
+#~ msgid "Loading instruments..."
+#~ msgstr "Lade Song ..."
+
+#, fuzzy
+#~ msgid "Loading graphics..."
+#~ msgstr "Lade Song ..."
+
+#, fuzzy
+#~ msgid "Random background..."
+#~ msgstr "Webcam als Hintergrund"
+
+#~ msgid "(press END to view hiscores)"
+#~ msgstr "(ENDE drücken um Highscores anzuzeigen)"
+
+#~ msgid "<type in to search>"
+#~ msgstr "<für Suche tippen>"
+
+#, fuzzy
+#~ msgid "Audio Devices"
+#~ msgstr "Wiedergabegeräte"
+
+#~ msgid "Audio"
+#~ msgstr "Audio"
+
+#, fuzzy
+#~ msgid "Graphics"
+#~ msgstr "Grafik"
+
+#, fuzzy
+#~ msgid "Configure rendering and video settings"
+#~ msgstr "Video- und Rendereinstellungen"
+
+#~ msgid "Game"
+#~ msgstr "Spiel"
+
+#, fuzzy
+#~ msgid "Gameplay related options"
+#~ msgstr "Spieleinstellungen"
+
+#~ msgid "Gameplay settings."
+#~ msgstr "Spieleinstellungen"
+
+#~ msgid "Graphic"
+#~ msgstr "Grafik"
+
+#~ msgid "Video and rendering settings."
+#~ msgstr "Video- und Rendereinstellungen"
+
+#~ msgid "Audio-related settings."
+#~ msgstr "Audioeinstellungen"
+
+#~ msgid "System paths."
+#~ msgstr "Systempfad"
+
+#, fuzzy
+#~ msgid "Hide pitch wave, notes and scoring."
+#~ msgstr "Verstecke Pitch Wave, Noten und Punkte."
+
+#~ msgid "Pitch waves"
+#~ msgstr "Tonhöhe"
+
+#, fuzzy
+#~ msgid "Enable singing pitch display (when not in karaoke mode)."
+#~ msgstr "Aktiviere Gesangsanzeige"
+
+#~ msgid "Theme"
+#~ msgstr "Thema"
+
+#~ msgid "Name of the theme to use or absolute path to theme folder."
+#~ msgstr ""
+#~ "Wähle ein Thema oder nutze den absoluten Pfad zu deinem Themenordner."
+
+#~ msgid "Enable keyboard as guitar (Frets on Fire mode)."
+#~ msgstr "Aktivier Tastatur als Gitarre (\"Frets on Fire\"-Modus)."
+
+#~ msgid "Keyboard as drumkit"
+#~ msgstr "Tastatur als Schlagzeug nutzen"
+
+#~ msgid "Enable keyboard as drumkit."
+#~ msgstr "Aktiviere Tastatur als Schlagzeug"
+
+#~ msgid "Keyboard as dance pad"
+#~ msgstr "Tastatur als Dancepad nutzen"
+
+#~ msgid "Enable keyboard as dance pad."
+#~ msgstr "Aktiviere Keyboard als Dancepad"
+
+#, fuzzy
+#~ msgid "Keyboard as keyboard"
+#~ msgstr "Tastatur als Gitarre nutzen"
+
+#, fuzzy
+#~ msgid "Enable keyboard as keyboard."
+#~ msgstr "Aktiviere Keyboard als Dancepad"
+
+#~ msgid "Joystick configuration"
+#~ msgstr "Eingabegeräte konfigurieren"
+
+#~ msgid "Force joystick to some kind of instrument."
+#~ msgstr "Erzwinge Eingabegerät als spezielles Instrument"
+
+#~ msgid "Hardware MIDI input device"
+#~ msgstr "MIDI Eingabegerät"
+
+#~ msgid ""
+#~ "Part of sound card name or its number or empty to use the first available "
+#~ "device. Used currently for MIDI drum controllers."
+#~ msgstr ""
+#~ "Teil der Bezeichnung der Soundkarte oder die Nummer oder Freilassen für "
+#~ "das erste verfügbare Gerät. Momentan für MIDI Schlagzeug genutzt."
+
+#~ msgid "Windowed width"
+#~ msgstr "Fensterbreite"
+
+#~ msgid "The width of the window."
+#~ msgstr "Breite des Fensters"
+
+#~ msgid "Windowed height"
+#~ msgstr "Fensterhöhe"
+
+#~ msgid "The height of the window."
+#~ msgstr "Höhe des Fensters"
+
+#~ msgid "Fullscreen mode"
+#~ msgstr "Vollbildmodus"
+
+#~ msgid "Enable fullscreen mode on startup."
+#~ msgstr "Aktivere Vollbild beim Start"
+
+#~ msgid "Video playback"
+#~ msgstr "Video-Wiedergabe …"
+
+#~ msgid ""
+#~ "Allows completely disabling background videos. It is recommended to leave "
+#~ "this enabled as Performous will still smoothly fade out the video if your "
+#~ "computer is not fast enough."
+#~ msgstr ""
+#~ "Erlaubt es Hintergrundvideos komplett zu deaktivieren. Es ist "
+#~ "empfehlenswert dies Option aktiviert zu lassen - Performous wird das "
+#~ "Video trotzdem flüssig ausblenden, wenn dein Computer nicht schnell genug "
+#~ "ist."
+
+#~ msgid "Webcam background"
+#~ msgstr "Webcam als Hintergrund"
+
+#, fuzzy
+#~ msgid ""
+#~ "Performous can use webcam as a background video. Disable it if Performous "
+#~ "crashes while entering a song."
+#~ msgstr ""
+#~ "Performous kann deine Webcam für Hintergrundvideos nutzen. Du kannst "
+#~ "diese Option deaktivieren, wenn es dir nicht gefällt."
+
+#~ msgid "Webcam id"
+#~ msgstr "Webcam ID"
+
+#~ msgid ""
+#~ "Use -1 to autodetect or a number starting from 0 to choose specific "
+#~ "device."
+#~ msgstr ""
+#~ "Benutze -1 für Autoerkennung oder wähle eine Zahl für ein spezielles "
+#~ "Geräte"
+
+#~ msgid "3D notes"
+#~ msgstr "3D Noten"
+
+#~ msgid ""
+#~ "Draw instrument notes as 3-dimensional objects. May hurt performance on "
+#~ "older hardware."
+#~ msgstr ""
+#~ "Zeichnet die Noten der Instrumente als dreidimensionale Objekte. "
+#~ "Deaktivieren kann auf älterer Hardware die Performance verbessern."
+
+#~ msgid "SVG quality"
+#~ msgstr "SVG Grafikqualität"
+
+#~ msgid ""
+#~ "Larger numbers cause vector graphics to be rendered in higher resolution. "
+#~ "Decrease this to make navigating in menus faster."
+#~ msgstr ""
+#~ "Bei Hohen Werten rendert Performous Vektorgraphiken in höherer Auflösung. "
+#~ "Niedrigere Werte ermöglichen eine schnellere Navigation in den Menüs."
+
+#~ msgid "Text quality"
+#~ msgstr "Textqualität"
+
+#~ msgid ""
+#~ "Larger numbers cause text to be rendered in higher resolution. Decrease "
+#~ "this to make everything a little faster."
+#~ msgstr ""
+#~ "Bei hohen Werten rendert Performous Texte in höherer Auflösung. "
+#~ "Niedrigere Werte erhöhen die allgemeine Performance ein wenig."
+
+#~ msgid "Benchmark mode"
+#~ msgstr "Benchmarkmodus"
+
+#~ msgid ""
+#~ "Framerate limit of 100 FPS is removed and the game instead renders at "
+#~ "full speed. FPS values are printed to console. Please note that the "
+#~ "display drivers may still limit the rendering speed to the screen refresh "
+#~ "rate."
+#~ msgstr ""
+#~ "Das Limit für die Bildwiederholrate wird aufgehoben und die maximal "
+#~ "möglichen Werte in der Konsole ausgegeben. Bemerkung: Es ist möglich, "
+#~ "dass der Grafiktreiber die Geschwindigkeit immer noch auf die "
+#~ "Bildwiederholrate des Bildschirms beschränkt."
+
+#~ msgid "Suggested latency"
+#~ msgstr "Empfohlene Latenz"
+
+#~ msgid ""
+#~ "This is a hint for the audio engine about the desired latency. Set this "
+#~ "as low as possible while retaining clear audio playback. Requires restart."
+#~ msgstr ""
+#~ "Die Audioengine nutzt diesen Wert für die gewünschte Latenz im Spiel. "
+#~ "Diese Wert beeinflusst die Audiowiedergabequalität im Spiel. Bemerkung: "
+#~ "So niedrig, wie möglich, so hoch wie nötig - Erfordert einen Neustart."
+
+#~ msgid "Audio/video latency"
+#~ msgstr "Audio-/Videolatenz"
+
+#~ msgid "Audio round-trip latency"
+#~ msgstr "Gesangslatenz"
+
+#~ msgid ""
+#~ "Affects singing only. The time it takes for Performous playback to reach "
+#~ "your speakers, fly to the microphone and all the way back until "
+#~ "Performous captures and analyzes it. While performing, press Ctrl+S for "
+#~ "synth mode and adjust with Ctrl+F3/F4."
+#~ msgstr ""
+#~ "Betrifft nur den Gesang. Er markiert die Zeit von der Wiedergabe an den "
+#~ "Lautsprechern, zum Mikrofon und den gesamten Weg bis zur Aufnahme und "
+#~ "Analyse durch Performous. Kann durch während des Spiels direkt durch das "
+#~ "betätigen von Strg+S für den Synth-Modus und durch die Tasten Strg+F3/F4 "
+#~ "reguliert werden."
+
+#~ msgid "Audio/controller latency"
+#~ msgstr "Audio/Controller Latenz"
+
+#~ msgid ""
+#~ "Affects instruments and dancing only. The total of USB (guitar or dance "
+#~ "pad) latency combined with audio output latency. Adjust so that you can "
+#~ "hit the notes best when playing by ear (not looking on screen). Use Ctrl"
+#~ "+F5/F6 to adjust while performing."
+#~ msgstr ""
+#~ "Betrifft nur Instrumente und Tanzpads. So einstellen, dass du die Noten "
+#~ "gut nach Gehör spielen kannst. Es ist möglich, diesen Wert während des "
+#~ "Spiels mit den Tasten Strg+F5/F6 zu regulieren."
+
+#~ msgid "Audio devices"
+#~ msgstr "Wiedergabegeräte"
+
+#~ msgid "Menu volume"
+#~ msgstr "Menü Lautstärke"
+
+#~ msgid "The volume level of menus, song previews and jukebox mode."
+#~ msgstr "Lautstärke in den Menüs, Songpreviews und im Jukeboxmodus"
+
+#~ msgid "Music volume"
+#~ msgstr "Musik Lautstärke"
+
+#~ msgid ""
+#~ "The ingame music volume. Values above 90 are not recommended as "
+#~ "distortion may occur."
+#~ msgstr ""
+#~ "Lautstärke im Spiel. Werte über 90 sind nicht zu empfehlen aufgrund von "
+#~ "Verzerrungen und anderen Störungen."
+
+#~ msgid "Failure volume"
+#~ msgstr "Versager Lautstärke"
+
+#~ msgid ""
+#~ "The ingame fail sound volume. Values above 90 are not recommended as "
+#~ "distortion may occur. 11 is louder than 10, but these go to 100. 89 "
+#~ "louder!"
+#~ msgstr ""
+#~ "Die Lautstärke der Musik im Falle des Verspielens. Werte über 90 werden "
+#~ "nicht empfohlen aufgrund von Verzerrungen und anderen Störungen."
+
+#~ msgid "Song folders"
+#~ msgstr "Songordner"
+
+#~ msgid ""
+#~ "Where to recursively look for songs. DATADIR at the beginning means all "
+#~ "Performous data folders."
+#~ msgstr ""
+#~ "Dieser Ordner wird (rekursiv, d.h. mit allen Unterordnern) nach Songs "
+#~ "durchsucht. Die Verwendung von DATADIR bezeichnet hierbei den Datenordner "
+#~ "von Performous"
+
+#~ msgid "Base folders for data"
+#~ msgstr "Ordner für Daten"
+
+#~ msgid ""
+#~ "System defaults are included automatically. Additional paths can be added "
+#~ "here."
+#~ msgstr ""
+#~ "Standardpfade werden automatisch eingefügt. Hier können Neue hinzugefügt "
+#~ "werden."
+
+#, fuzzy
+#~ msgid "Loading theme..."
+#~ msgstr "Lade Song ..."
+
+#, fuzzy
+#~ msgid "Loading background..."
+#~ msgstr "Lade Song ..."
+
+#, fuzzy
+#~ msgid "Loading user interface..."
+#~ msgstr "Lade Song ..."
+
+#, fuzzy
+#~ msgid "Audio..."
+#~ msgstr "Audio"
+
+#, fuzzy
+#~ msgid "Press Enter to configure (TODO: implement)"
+#~ msgstr "Bestätige Enter, um dies zu Konfigurieren"
+
+#~ msgid "Miscellaneous..."
+#~ msgstr "Sonstiges …"
+
+#~ msgid "System"
+#~ msgstr "System"
diff --git a/lang/es.po b/lang/es.po
new file mode 100644 (file)
index 0000000..7830e0c
--- /dev/null
@@ -0,0 +1,1083 @@
+msgid ""
+msgstr ""
+"Project-Id-Version: Performous\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2013-07-13 17:34+0200\n"
+"PO-Revision-Date: \n"
+"Last-Translator: FooBar\n"
+"Language-Team: \n"
+"Language: es_ES\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"X-Poedit-KeywordsList: _\n"
+"X-Poedit-Basepath: .\n"
+"X-Generator: Poedit 1.5.4\n"
+"X-Poedit-SearchPath-0: ../game\n"
+"X-Poedit-SearchPath-1: ../data\n"
+
+#: ../game/configuration.cc:112
+msgid "Enabled"
+msgstr "Habilitado"
+
+#: ../game/configuration.cc:112
+msgid "Disabled"
+msgstr "Deshabilitado"
+
+#: ../game/configuration.cc:116
+#, c-format
+msgid "%d items"
+msgstr "%d elementos"
+
+#: ../game/screen_playlist.cc:110 ../game/screen_playlist.cc:252
+msgid "Continue"
+msgstr "Continuar"
+
+#: ../game/screen_playlist.cc:110
+msgid "Continue playing"
+msgstr "Continuar reproduciendo"
+
+#: ../game/screen_playlist.cc:118
+msgid "Add songs"
+msgstr "Añadir canciones"
+
+#: ../game/screen_playlist.cc:118
+msgid "Open the song browser to add more songs"
+msgstr "Abrir el buscador de canciones para añadir más canciones"
+
+#: ../game/screen_playlist.cc:119 ../game/screen_songs.cc:509
+msgid "Shuffle"
+msgstr "Aleatorizar"
+
+#: ../game/screen_playlist.cc:119
+msgid "Randomize the order of the playlist"
+msgstr "Aleatorizar el orden de la lista de reproducción"
+
+#: ../game/screen_playlist.cc:125
+msgid "Clear and exit"
+msgstr "Limpiar y salir"
+
+#: ../game/screen_playlist.cc:125
+msgid "Remove all the songs from the list"
+msgstr "Borrar todas las canciones de la lista"
+
+#: ../game/screen_playlist.cc:131 ../game/screen_playlist.cc:275
+#: ../game/screen_songs.cc:522
+msgid "Back"
+msgstr "Atrás"
+
+#: ../game/screen_playlist.cc:131 ../game/screen_playlist.cc:275
+msgid "Back to playlist viewer"
+msgstr "Volver al visor de lista de reproducción"
+
+#: ../game/screen_playlist.cc:237
+msgid "Press enter to view song options"
+msgstr "Presiona ENTRAR para ver las opciones de canción"
+
+#: ../game/screen_playlist.cc:244
+msgid "View more options"
+msgstr "Ver más opciones"
+
+#: ../game/screen_playlist.cc:244
+msgid "View general playlist settings"
+msgstr "Ver configuración general de lista de reproducción"
+
+#: ../game/screen_playlist.cc:252
+msgid "Play first"
+msgstr "Reproducir primero"
+
+#: ../game/screen_playlist.cc:254
+msgid "Ignore the playlist's order and play this song first"
+msgstr ""
+"Ignorar el orden de la lista de reproducción y reproducir primero esta "
+"canción"
+
+#: ../game/screen_playlist.cc:255
+msgid "Start the song already!"
+msgstr "¡Iniciar la canción ya!"
+
+#: ../game/screen_playlist.cc:264
+msgid "Remove"
+msgstr "Borrar"
+
+#: ../game/screen_playlist.cc:264
+msgid "Remove this song from the list"
+msgstr "Borrar esta canción de la lista"
+
+#: ../game/screen_paths.cc:24
+msgid ""
+"This tool is not yet available.\n"
+"Configure paths by adding them\n"
+"as command line parameters and\n"
+"then save them in configuration menu."
+msgstr ""
+"Esta herramienta no se encuentra aún disponible.\n"
+"Configura los directorios añadiéndolos\n"
+"como parámetros en la línea de comandos y\n"
+"guárdalos en el menú de configuración."
+
+#: ../game/screen_paths.cc:70
+msgid "Press any key to exit."
+msgstr "Presiona cualquier tecla para salir."
+
+#: ../game/screen_paths.cc:76
+#, fuzzy
+msgid "Windows users can also use ConfigureSongDirectory.bat script."
+msgstr ""
+"Los usuarios de Windows también pueden utilizar \"ConfigureSongDirectory.bat"
+"\" en la carpeta \"bin\"."
+
+#: ../game/dancegraph.cc:18
+msgid "Beginner"
+msgstr "Principiante"
+
+#: ../game/dancegraph.cc:18 ../game/guitargraph.cc:14
+msgid "Easy"
+msgstr "Fácil"
+
+#: ../game/dancegraph.cc:18 ../game/guitargraph.cc:14
+msgid "Medium"
+msgstr "Media"
+
+#: ../game/dancegraph.cc:18 ../game/guitargraph.cc:14
+msgid "Hard"
+msgstr "Difícil"
+
+#: ../game/dancegraph.cc:18
+msgid "Challenge"
+msgstr "Desafío"
+
+#: ../game/dancegraph.cc:107 ../game/guitargraph.cc:194
+msgid "Ready!"
+msgstr "¡Listo!"
+
+#: ../game/dancegraph.cc:107 ../game/guitargraph.cc:194
+#: ../game/screen_intro.cc:166
+msgid "Start performing!"
+msgstr "¡Comienza una partida!"
+
+#: ../game/dancegraph.cc:118 ../game/guitargraph.cc:183
+msgid "Select track"
+msgstr "Selecciona la pista"
+
+#: ../game/dancegraph.cc:134 ../game/guitargraph.cc:163
+msgid "Select difficulty"
+msgstr "Selecciona la dificultad"
+
+#: ../game/dancegraph.cc:137 ../game/instrumentgraph.cc:59
+#: ../game/guitargraph.cc:200 ../game/screen_intro.cc:184
+#: ../game/screen_sing.cc:92 ../game/screen_sing.cc:126
+msgid "Quit"
+msgstr "Salir"
+
+#: ../game/dancegraph.cc:137 ../game/instrumentgraph.cc:59
+#: ../game/guitargraph.cc:200 ../game/screen_sing.cc:92
+#: ../game/screen_sing.cc:126
+msgid "Exit to song browser"
+msgstr ""
+"Salir al menú de\n"
+"selección de canciones"
+
+#: ../game/dancegraph.cc:248
+msgid "STOP!"
+msgstr "¡PARA!"
+
+#: ../game/dancegraph.cc:321 ../game/guitargraph.cc:447
+msgid "Streak!"
+msgstr "Aciertos!"
+
+#: ../game/instrumentgraph.cc:56 ../game/screen_sing.cc:123
+msgid "Resume"
+msgstr "Continuar"
+
+#: ../game/instrumentgraph.cc:56 ../game/screen_sing.cc:123
+msgid "Back to performing!"
+msgstr "¡De vuelta al juego!"
+
+#: ../game/instrumentgraph.cc:57
+msgid "Rejoin"
+msgstr "Reincorporarse"
+
+#: ../game/instrumentgraph.cc:57
+msgid "Change selections"
+msgstr "Cambiar las selecciones"
+
+#: ../game/instrumentgraph.cc:58 ../game/screen_sing.cc:124
+msgid "Restart"
+msgstr "Reiniciar"
+
+#: ../game/instrumentgraph.cc:58 ../game/screen_sing.cc:124
+msgid ""
+"Start the song\n"
+"from the beginning"
+msgstr ""
+"Empezar de nuevo\n"
+"la canción"
+
+#: ../game/songs.cc:178
+msgid "show all songs"
+msgstr "mostrar todas las canciones"
+
+#: ../game/songs.cc:179
+msgid "has dance"
+msgstr "tiene baile"
+
+#: ../game/songs.cc:180
+msgid "has vocals"
+msgstr "tiene voz"
+
+#: ../game/songs.cc:181
+msgid "has duet"
+msgstr "tiene dúo"
+
+#: ../game/songs.cc:182
+msgid "has guitar"
+msgstr "tiene guitarra"
+
+#: ../game/songs.cc:183
+msgid "drums or keytar"
+msgstr "batería o guitarra-teclado"
+
+#: ../game/songs.cc:184
+msgid "full band"
+msgstr "banda completa"
+
+#: ../game/songs.cc:212
+msgid "random order"
+msgstr "ordenadas aleatoriamente"
+
+#: ../game/songs.cc:213
+msgid "sorted by song"
+msgstr "ordenadas por canción"
+
+#: ../game/songs.cc:214
+msgid "sorted by artist"
+msgstr "ordenadas por artista"
+
+#: ../game/songs.cc:215
+msgid "sorted by edition"
+msgstr "ordenadas por edición"
+
+#: ../game/songs.cc:216
+msgid "sorted by genre"
+msgstr "ordenadas por género"
+
+#: ../game/songs.cc:217
+msgid "sorted by path"
+msgstr "ordenadas por directorio"
+
+#: ../game/songs.cc:218
+msgid "sorted by language"
+msgstr "ordenadas por idioma"
+
+#: ../game/screen_audiodevices.cc:55
+msgid ""
+"It seems you have some manual configurations\n"
+"incompatible with this user interface.\n"
+"Saving these settings will override\n"
+"all existing audio device configuration.\n"
+"Your other options changes will be saved too."
+msgstr ""
+"Parece que tienes alguna configuración manual\n"
+"incompatible con esta interfaz de usuario.\n"
+"Guardando estas opciones sobrescribirás\n"
+"cualquier configuración existente de dispositivos de audio.\n"
+"Tus otros cambios en la configuración también se guardarán."
+
+#: ../game/screen_audiodevices.cc:114
+msgid "- Unassigned -"
+msgstr "- Sin asignar -"
+
+#: ../game/screen_audiodevices.cc:135
+msgid ""
+"Use arrow keys to configure. Hit Enter/Start to save and test or Esc/Select "
+"to cancel. Ctrl + R to reset defaults"
+msgstr ""
+"Utilizar las flechas para cambiar la configuración. Presiona Enter/Start "
+"para guardar y probar o Esc/Select para cancelar. Ctrl + R para restablecer "
+"valores."
+
+#: ../game/screen_audiodevices.cc:140
+msgid ""
+"For advanced device configuration, use command line parameter --audio (use --"
+"audiohelp for details)."
+msgstr ""
+"Para una configuración avanzada de dispositivos, utilizar el parámetro de "
+"comando --audio (utilizar --audiohelp para más detalles)."
+
+#: ../game/screen_audiodevices.cc:188
+msgid "Some devices failed to open!"
+msgstr "Hubo un fallo al abrir algunos dispositivos!"
+
+#: ../game/main.cc:145
+msgid "Loading audio samples..."
+msgstr "Cargando muestras de audio..."
+
+#: ../game/main.cc:159
+msgid "Creating screens..."
+msgstr "Generando pantallas..."
+
+#: ../game/main.cc:169
+msgid "Entering main menu"
+msgstr "Entrando en el menú principal"
+
+#: ../game/main.cc:171 ../game/screen_sing.cc:97
+msgid "Loading complete"
+msgstr "Carga completada"
+
+#: ../game/main.cc:182
+msgid "Screenshot taken!"
+msgstr "¡Captura de pantalla exitosa!"
+
+#: ../game/main.cc:185
+msgid "Screenshot failed!"
+msgstr "¡Captura de pantalla fallida!"
+
+#: ../game/guitargraph.cc:14
+msgid "Kids"
+msgstr "Niños"
+
+#: ../game/guitargraph.cc:14
+msgid "Expert"
+msgstr "Experto"
+
+#: ../game/guitargraph.cc:169 ../game/guitargraph.cc:186
+msgid "Lefty-mode"
+msgstr "Modo zurdo"
+
+#: ../game/guitargraph.cc:207
+msgid "ON"
+msgstr "ACTIVADO"
+
+#: ../game/guitargraph.cc:207
+msgid "OFF"
+msgstr "DESACTIVADO"
+
+#: ../game/guitargraph.cc:208
+msgid "Toggle lefty-mode"
+msgstr ""
+"Activar/desactivar\n"
+"el modo zurdo"
+
+#: ../game/guitargraph.cc:459
+msgid ""
+"God Mode\n"
+"Activated!"
+msgstr ""
+"¡Modo Dios\n"
+"Activado!"
+
+#: ../game/guitargraph.cc:460
+msgid "Mistakes ignored!"
+msgstr "¡Se ignoran los fallos!"
+
+#: ../game/guitargraph.cc:1102
+msgid "God Mode Ready!"
+msgstr "¡Modo Dios Disponible!"
+
+#: ../game/guitargraph.cc:1103
+msgid "Drum Fill!"
+msgstr "¡Enajenación!"
+
+#: ../game/guitargraph.cc:1106
+msgid "Solo!"
+msgstr "¡Solo!"
+
+#: ../game/screen_songs.cc:278
+msgid "Sorry, no songs match the search!"
+msgstr "¡Ninguna canción satisface el criterio de búsqueda!"
+
+#: ../game/screen_songs.cc:281
+#, fuzzy
+msgid "Sorry, no songs match the filter!"
+msgstr "¡Ninguna canción satisface el criterio de búsqueda!"
+
+#: ../game/screen_songs.cc:284
+msgid "No songs found!"
+msgstr "¡No se encontraron canciones!"
+
+#: ../game/screen_songs.cc:285
+msgid "Visit performous.org for free songs"
+msgstr "Visita performous.org para descargar canciones gratuitas"
+
+#: ../game/screen_songs.cc:303
+msgid "<type in to search>"
+msgstr "<escribe para buscar>"
+
+#: ../game/screen_songs.cc:303
+msgid "songs"
+msgstr "canciones"
+
+#: ../game/screen_songs.cc:303
+msgid "options"
+msgstr "opciones"
+
+#: ../game/screen_songs.cc:305
+msgid "sort order: "
+msgstr "ordenar por: "
+
+#: ../game/screen_songs.cc:306
+msgid "type filter: "
+msgstr "tipo de filtro: "
+
+#: ../game/screen_songs.cc:307
+msgid "hiscores"
+msgstr "Mejor puntuación"
+
+#: ../game/screen_songs.cc:307
+#, fuzzy
+msgid "jukebox mode"
+msgstr "Modo dúo"
+
+#: ../game/screen_songs.cc:310
+msgid "start a playlist with this song!"
+msgstr "¡comenzar una lista de reproducción con esta canción!"
+
+#: ../game/screen_songs.cc:310
+msgid "open the playlist menu"
+msgstr "abrir el menú de lista de reproducción"
+
+#: ../game/screen_songs.cc:502
+msgid "Play"
+msgstr "Reproducir"
+
+#: ../game/screen_songs.cc:515
+msgid "View playlist"
+msgstr "Ver lista de reproducción"
+
+#: ../game/screen_songs.cc:516
+msgid "Clear playlist"
+msgstr "Limpiar lista de reproducción"
+
+#: ../game/screen_intro.cc:24
+msgid "No playback devices could be used.\n"
+msgstr ""
+"No se pudo configurar ningún dispositivo\n"
+"de reproducción de audio.\n"
+
+#: ../game/screen_intro.cc:25
+msgid ""
+"\n"
+"Please configure some before playing."
+msgstr ""
+"\n"
+"Por favor, configura alguno antes de jugar."
+
+#: ../game/screen_intro.cc:69
+msgid "Settings saved as system defaults."
+msgstr "Configuración guardada como predeterminada."
+
+#: ../game/screen_intro.cc:69
+msgid "Settings saved."
+msgstr "Configuración guardada."
+
+#: ../game/screen_intro.cc:149
+msgid "Ctrl + S to save, Ctrl + R to reset defaults"
+msgstr "Ctrl + S para guardar, Ctrl + R para restablecer valores"
+
+#: ../game/screen_intro.cc:166
+msgid "Perform"
+msgstr "Jugar"
+
+#: ../game/screen_intro.cc:167
+msgid "Practice"
+msgstr "Practicar"
+
+#: ../game/screen_intro.cc:167
+msgid "Check your skills or test the microphones"
+msgstr "Comprueba tus habilidades o revisa los micrófonos"
+
+#: ../game/screen_intro.cc:183
+msgid "Configure"
+msgstr "Opciones"
+
+#: ../game/screen_intro.cc:183
+msgid "Configure audio and game options"
+msgstr "Configurar las opciones de audio y de juego"
+
+#: ../game/screen_intro.cc:184
+msgid "Leave the game"
+msgstr "Sal del juego"
+
+#: ../game/screen_players.cc:115
+msgid "No players found!"
+msgstr "¡No se han encontrado jugadores!"
+
+#: ../game/screen_players.cc:116
+msgid "Enter a name to create a new player."
+msgstr "Introduce un nombre para crear un nuevo jugador."
+
+#: ../game/screen_players.cc:118
+msgid "Press enter to create player!"
+msgstr "Presiona \"enter\" para crear el nuevo jugador:"
+
+#: ../game/screen_players.cc:122
+msgid "No players worth mentioning!"
+msgstr "¡Ningún jugador destacable!"
+
+#: ../game/screen_players.cc:127
+msgid "You reached %1% points!"
+msgstr "¡Has conseguido %1% puntos!"
+
+#: ../game/screen_players.cc:128
+msgid "Change player with arrow keys."
+msgstr "Cambia de jugador con las flechas del teclado"
+
+#: ../game/screen_players.cc:129
+msgid "Name:"
+msgstr "Nombre:"
+
+#: ../game/screen_players.cc:132
+msgid "Type text to filter or create a new player."
+msgstr "Introduce texto para filtrar o crear un nuevo jugador."
+
+#: ../game/screen_players.cc:132
+msgid "Search Text:"
+msgstr "Buscar texto:"
+
+#: ../game/screen_sing.cc:45
+msgid "Initializing webcam..."
+msgstr "Inicializando la webcam"
+
+#: ../game/screen_sing.cc:52
+msgid "Loading video..."
+msgstr "Cargando vídeo..."
+
+#: ../game/screen_sing.cc:59
+msgid "Loading song..."
+msgstr "Cargando canción..."
+
+#: ../game/screen_sing.cc:66
+msgid "Song contains broken tracks!"
+msgstr "¡La canción contiene pistas defectuosas!"
+
+#: ../game/screen_sing.cc:71
+msgid "Loading menu..."
+msgstr "Cargando el menú..."
+
+#: ../game/screen_sing.cc:76
+msgid "Start"
+msgstr "Comenzar"
+
+#: ../game/screen_sing.cc:76
+msgid "Start performing"
+msgstr "Comenzar"
+
+#: ../game/screen_sing.cc:80
+msgid "Duet mode"
+msgstr "Modo dúo"
+
+#: ../game/screen_sing.cc:81
+msgid "Normal mode"
+msgstr "Modo normal"
+
+#: ../game/screen_sing.cc:82
+msgid "Switch between duet and regular singing mode"
+msgstr "Cambiar entre modo dúo y modo normal"
+
+#: ../game/screen_sing.cc:90
+msgid "Change vocal track"
+msgstr "Cambiar la pista de voz"
+
+#: ../game/screen_sing.cc:125
+msgid "Skip"
+msgstr "Pasar"
+
+#: ../game/screen_sing.cc:125
+msgid "Skip current song"
+msgstr "Pasar la canción actual"
+
+#: ../game/screen_sing.cc:391
+msgid "Press UP to join dance!"
+msgstr "¡Presiona ARRIBA para unirte a bailar!"
+
+#: ../game/screen_sing.cc:391
+msgid "Step UP to join!"
+msgstr "¡Pisa ARRIBA para unirte!"
+
+#: ../game/screen_sing.cc:396
+msgid "Press 1 to join guitar!"
+msgstr "¡Presiona 1 para unirte con la guitarra!"
+
+#: ../game/screen_sing.cc:396
+msgid "Press GREEN to join!"
+msgstr "¡Presiona VERDE para unirte!"
+
+#: ../game/screen_sing.cc:401
+msgid "Press SPACE to join drums!"
+msgstr "¡Presiona ESPACIO para unirte con la batería!"
+
+#: ../game/screen_sing.cc:401
+msgid "KICK to join!"
+msgstr "¡Da con el pie para unirte!"
+
+#: ../game/screen_sing.cc:475
+msgid "   ENTER to skip instrumental break"
+msgstr "   ENTER para pasar la parte instrumental"
+
+#: ../game/screen_sing.cc:476
+msgid "   Remember to wait for grading!"
+msgstr "   Recuerda esperar para ser evaluado!"
+
+#: ../game/screen_sing.cc:587
+msgid "No player!"
+msgstr "¡No se han encontrado jugadores!"
+
+#: ../game/screen_sing.cc:594
+msgid "Hit singer"
+msgstr "Superestrella"
+
+#: ../game/screen_sing.cc:595
+msgid "Lead singer"
+msgstr "Vocalista"
+
+#: ../game/screen_sing.cc:596 ../game/screen_sing.cc:602
+#: ../game/screen_sing.cc:608
+msgid "Rising star"
+msgstr "Aficionado"
+
+#: ../game/screen_sing.cc:597 ../game/screen_sing.cc:603
+#: ../game/screen_sing.cc:609
+msgid "Amateur"
+msgstr "Novato"
+
+#: ../game/screen_sing.cc:598 ../game/screen_sing.cc:610
+msgid "Tone deaf"
+msgstr "Sin oído"
+
+#: ../game/screen_sing.cc:600
+msgid "Maniac"
+msgstr "Maníaco"
+
+#: ../game/screen_sing.cc:601
+msgid "Hoofer"
+msgstr "Artista"
+
+#: ../game/screen_sing.cc:604
+msgid "Loser"
+msgstr "Perdedor"
+
+#: ../game/screen_sing.cc:606
+msgid "Virtuoso"
+msgstr "Virtuoso"
+
+#: ../game/screen_sing.cc:607
+msgid "Rocker"
+msgstr "Rockero"
+
+#~ msgid "<type in to search>   ↔ songs    ↕ options"
+#~ msgstr "<escribe para buscar>   ↔ canciones    ↕ opciones"
+
+#~ msgid "↔ hiscores   ↵ jukebox mode"
+#~ msgstr "↔ mejores puntuaciones   ↵ modo \"jukebox\""
+
+#~ msgid "Start the game with all songs in playlist"
+#~ msgstr ""
+#~ "Comenzar el juego con todas las canciones en la lista de reproducción"
+
+#~ msgid "View the current playlist"
+#~ msgstr "Ver lista de reproducción actual"
+
+#~ msgid "Back to song browser"
+#~ msgstr "De vuelta al buscador de canciones"
+
+#~ msgid "No Items up to now."
+#~ msgstr "No hay mejores puntuaciones guardadas."
+
+#~ msgid "Be the first to be listed here!"
+#~ msgstr "¡Sé el primero en aparecer aquí!"
+
+#~ msgid "Guitar"
+#~ msgstr "Guitarra"
+
+#~ msgid "Coop guitar"
+#~ msgstr "Guitarra secundaria"
+
+#~ msgid "Rhythm guitar"
+#~ msgstr "Guitarra rítmica"
+
+#~ msgid "Bass"
+#~ msgstr "Bajo"
+
+#~ msgid "Drums"
+#~ msgstr "Batería"
+
+#~ msgid "Vocals"
+#~ msgstr "Voz"
+
+#~ msgid "Harmonic 1"
+#~ msgstr "Armónico 1"
+
+#~ msgid "Harmonic 2"
+#~ msgstr "Armónico 2"
+
+#~ msgid "Harmonic 3"
+#~ msgstr "Armónico 3"
+
+#~ msgid "Song is broken!"
+#~ msgstr "¡Canción defectuosa!"
+
+#~ msgid "Loading instruments..."
+#~ msgstr "Cargando los instrumentos..."
+
+#~ msgid "Finalizing..."
+#~ msgstr "Finalizando..."
+
+#, fuzzy
+#~ msgid "Loading graphics..."
+#~ msgstr "Cargando canción..."
+
+#~ msgid "Random background..."
+#~ msgstr "Fondo aleatorio..."
+
+#~ msgid "(press END to view hiscores)"
+#~ msgstr "(presiona FIN para ver las mejores puntuaciones)"
+
+#~ msgid "Audio Devices"
+#~ msgstr "Dispositivos de Audio"
+
+#~ msgid "Setup microphones and playback"
+#~ msgstr "Configurar los micrófonos y la reproducción"
+
+#~ msgid "Audio"
+#~ msgstr "Audio"
+
+#~ msgid "Graphics"
+#~ msgstr "Gráficos"
+
+#~ msgid "Configure rendering and video settings"
+#~ msgstr "Configurar las opciones de vídeo y reproducción"
+
+#~ msgid "Game"
+#~ msgstr "Juego"
+
+#~ msgid "Gameplay related options"
+#~ msgstr "Opciones del juego"
+
+#~ msgid "Paths"
+#~ msgstr "Directorios"
+
+#~ msgid "Setup song and data paths"
+#~ msgstr "Configurar los directorios de datos y canciones"
+
+#~ msgid "Gameplay settings."
+#~ msgstr "Opciones del juego."
+
+#~ msgid "Graphic"
+#~ msgstr "Gráfico"
+
+#~ msgid "Video and rendering settings."
+#~ msgstr "Opciones de vídeo y reproducción."
+
+#~ msgid "Audio-related settings."
+#~ msgstr "Opciones de audio."
+
+#~ msgid "System paths."
+#~ msgstr "Directorios del sistema."
+
+#~ msgid "Hide pitch wave, notes and scoring."
+#~ msgstr "Oculta las ondas de tono, las notas y la puntuación."
+
+#~ msgid "Pitch waves"
+#~ msgstr "Ondas de tono"
+
+#~ msgid "Enable singing pitch display (when not in karaoke mode)."
+#~ msgstr ""
+#~ "Habilita la representación del tono al cantar (cuando no estamos en modo "
+#~ "karaoke)."
+
+#~ msgid "Theme"
+#~ msgstr "Tema"
+
+#~ msgid "Name of the theme to use or absolute path to theme folder."
+#~ msgstr "Nombre del tema a utilizar o ruta absoluta de la carpeta del tema."
+
+#~ msgid "Keyboard as guitar"
+#~ msgstr "Teclado como guitarra"
+
+#~ msgid "Enable keyboard as guitar (Frets on Fire mode)."
+#~ msgstr "Habilita el teclado como guitarra (Modo Frets on Fire)."
+
+#~ msgid "Keyboard as drumkit"
+#~ msgstr "Teclado como batería"
+
+#~ msgid "Enable keyboard as drumkit."
+#~ msgstr "Habilita el teclado como batería."
+
+#~ msgid "Keyboard as dance pad"
+#~ msgstr "Teclado como alfombrilla de baile"
+
+#~ msgid "Enable keyboard as dance pad."
+#~ msgstr "Habilita el teclado como alfombrilla de baile."
+
+#, fuzzy
+#~ msgid "Keyboard as keyboard"
+#~ msgstr "Teclado como guitarra"
+
+#, fuzzy
+#~ msgid "Enable keyboard as keyboard."
+#~ msgstr "Habilita el teclado como alfombrilla de baile."
+
+#~ msgid "Joystick configuration"
+#~ msgstr "Configuración del Joystick"
+
+#~ msgid "Force joystick to some kind of instrument."
+#~ msgstr "Forzar la utilización del joystick como algún tipo de instrumento."
+
+#~ msgid "Hardware MIDI input device"
+#~ msgstr "Dispositivo de entrada MIDI"
+
+#~ msgid ""
+#~ "Part of sound card name or its number or empty to use the first available "
+#~ "device. Used currently for MIDI drum controllers."
+#~ msgstr ""
+#~ "Parte del nombre de la tarjeta de sonido, o su número, o vacío para "
+#~ "utilizar el primer dispositivo disponible. Actualmente se usa para los "
+#~ "controladores de batería MIDI."
+
+#~ msgid "Windowed width"
+#~ msgstr "Anchura en modo ventana"
+
+#~ msgid "The width of the window."
+#~ msgstr "Anchura de la ventana."
+
+#~ msgid "Windowed height"
+#~ msgstr "Altura en modo ventana"
+
+#~ msgid "The height of the window."
+#~ msgstr "Altura de la ventana."
+
+#~ msgid "Fullscreen mode"
+#~ msgstr "Modo pantalla completa"
+
+#~ msgid "Enable fullscreen mode on startup."
+#~ msgstr "Habilita el modo pantalla completa al iniciar la aplicación."
+
+#~ msgid "Stereoscopic 3D"
+#~ msgstr "3D Esteroscópico"
+
+#~ msgid "Enable 3D rendering of Performous."
+#~ msgstr "Habilitar renderizado 3D de Performous."
+
+#, fuzzy
+#~ msgid "Stereo3D type"
+#~ msgstr "Tipo de 3D Esteoscópico"
+
+#~ msgid "Some modes may only get activated in fullscreen mode."
+#~ msgstr "Algunos modos pueden activarse solo en modo pantalla completa."
+
+#, fuzzy
+#~ msgid "Stereo3D separation"
+#~ msgstr "Separación de 3D Estereoscópico"
+
+#~ msgid ""
+#~ "The strength of the effect. Experiment with different settings for best "
+#~ "results."
+#~ msgstr ""
+#~ "Fuerza del efecto. Experimentar con diferentes configuraciones para "
+#~ "mejores resultados."
+
+#~ msgid "Video playback"
+#~ msgstr "Reproducción de vídeo de fondo"
+
+#~ msgid ""
+#~ "Allows completely disabling background videos. It is recommended to leave "
+#~ "this enabled as Performous will still smoothly fade out the video if your "
+#~ "computer is not fast enough."
+#~ msgstr ""
+#~ "Permite desactivar la reproducción de vídeo de fondo. Se recomienda "
+#~ "dejarla activada ya que Performous se encargará de ello si es necesario "
+#~ "para mejorar el rendimiento."
+
+#~ msgid "Webcam background"
+#~ msgstr "Cámara web como fondo"
+
+#, fuzzy
+#~ msgid ""
+#~ "Performous can use webcam as a background video. Disable it if Performous "
+#~ "crashes while entering a song."
+#~ msgstr ""
+#~ "Performous puede intentar utilizar la cámara web como vídeo de fondo. "
+#~ "Puedes deshabilitar esta opción si te incomoda."
+
+#~ msgid "Webcam id"
+#~ msgstr "ID de la cámara web"
+
+#~ msgid ""
+#~ "Use -1 to autodetect or a number starting from 0 to choose specific "
+#~ "device."
+#~ msgstr ""
+#~ "Utilizar -1 para detectar automáticamente o un número mayor o igual que 0 "
+#~ "para escoger un dispositivo en particular."
+
+#~ msgid "3D notes"
+#~ msgstr "Notas 3D"
+
+#~ msgid ""
+#~ "Draw instrument notes as 3-dimensional objects. May hurt performance on "
+#~ "older hardware."
+#~ msgstr ""
+#~ "Dibujar las notas de los instrumentos como objetos tridimensionales. "
+#~ "Puede perjudicar el rendimiento en máquinas antiguas."
+
+#~ msgid "SVG quality"
+#~ msgstr "Calidad SVG"
+
+#~ msgid ""
+#~ "Larger numbers cause vector graphics to be rendered in higher resolution. "
+#~ "Decrease this to make navigating in menus faster."
+#~ msgstr ""
+#~ "Valores más altos hacen que los gráficos vectoriales se muestren con "
+#~ "mayor resolución. Valores más bajos hacen que la navegación en los menús "
+#~ "sea más rápida."
+
+#~ msgid "Text quality"
+#~ msgstr "Calidad del texto"
+
+#~ msgid ""
+#~ "Larger numbers cause text to be rendered in higher resolution. Decrease "
+#~ "this to make everything a little faster."
+#~ msgstr ""
+#~ "Valores más altos hacen que el texto se muestre con mayor resolución. "
+#~ "Valores más bajos hacen que el rendimiento sea mayor."
+
+#~ msgid "Benchmark mode"
+#~ msgstr "Modo prueba de rendimiento"
+
+#~ msgid ""
+#~ "Framerate limit of 100 FPS is removed and the game instead renders at "
+#~ "full speed. FPS values are printed to console. Please note that the "
+#~ "display drivers may still limit the rendering speed to the screen refresh "
+#~ "rate."
+#~ msgstr ""
+#~ "Elimina el límite de 100 cuadros por segundo (FPS) y el juego se ejecuta "
+#~ "a la máxima velocidad. Los valores de FPS son impresos en la consola.\n"
+#~ "Nótese que los controladores de la tarjeta gráfica pueden aún así limitar "
+#~ "la velocidad de representación a la frecuencia de actualización de la "
+#~ "pantalla."
+
+#~ msgid "Suggested latency"
+#~ msgstr "Latencia sugerida"
+
+#~ msgid ""
+#~ "This is a hint for the audio engine about the desired latency. Set this "
+#~ "as low as possible while retaining clear audio playback. Requires restart."
+#~ msgstr ""
+#~ "Es un indicio para el motor de sonido sobre la latencia deseada. Utiliza "
+#~ "un valor lo más bajo posible mientras se mantenga una reproducción de "
+#~ "audio clara. Requiere reiniciar la aplicación."
+
+#~ msgid "Audio/video latency"
+#~ msgstr "Latencia audio/vídeo"
+
+#~ msgid ""
+#~ "Affects all modes. Use negative value if your display input lag is "
+#~ "greater than the sound card output latency, positive values in the "
+#~ "opposite case and zero if they are equal. This should be set so that the "
+#~ "notes pass the cursor at the same time the audio is heard. Use Ctrl+F1/F2 "
+#~ "to adjust this while performing."
+#~ msgstr ""
+#~ "Afecta a todos los modos. Utiliza un valor negativo si tu retraso de "
+#~ "entrada es mayor que la latencia de salida de la tarjeta de sonido, "
+#~ "valores positivos en caso contrario y cero si son iguales.\n"
+#~ "Esto debería ajustarse de forma que las notas pasen el cursor al mismo "
+#~ "tiempo que el sonido se escucha. Puedes ajustar estos valores mientras "
+#~ "juegas con las teclas Ctrl+F1/F2."
+
+#~ msgid "Audio round-trip latency"
+#~ msgstr "Latencia de ida y vuelta"
+
+#~ msgid ""
+#~ "Affects singing only. The time it takes for Performous playback to reach "
+#~ "your speakers, fly to the microphone and all the way back until "
+#~ "Performous captures and analyzes it. While performing, press Ctrl+S for "
+#~ "synth mode and adjust with Ctrl+F3/F4."
+#~ msgstr ""
+#~ "Afecta sólo al cantar. Es el tiempo que le lleva a Performous reproducir "
+#~ "el sonido a través de tus altavoces, viajar hasta el micrófono y de "
+#~ "vuelta otra vez hasta que Performous lo captura y analiza.\n"
+#~ "Puedes ajustar estos valores mientras juegas: presiona Ctrl+S para "
+#~ "activar el modo sincronización, pon el micrófono junto al altavoz, y a "
+#~ "continuación ajusta con Ctrl+F3/F4."
+
+#~ msgid "Audio/controller latency"
+#~ msgstr "Latencia audio/controlador"
+
+#~ msgid ""
+#~ "Affects instruments and dancing only. The total of USB (guitar or dance "
+#~ "pad) latency combined with audio output latency. Adjust so that you can "
+#~ "hit the notes best when playing by ear (not looking on screen). Use Ctrl"
+#~ "+F5/F6 to adjust while performing."
+#~ msgstr ""
+#~ "Afecta sólo a los instrumentos y al baile. La latencia total de los USB "
+#~ "(guitarras o alfombrillas de baile) combinada con la latencia de salida. "
+#~ "Ajústala de forma que aciertes el mayor número de notas\n"
+#~ "cuando juegas sólo escuchando (sin mirar a la pantalla). Utiliza Ctrl+F5/"
+#~ "F6 durante el juego para ajustar estos valores."
+
+#~ msgid "Audio devices"
+#~ msgstr "Dispositivos de audio"
+
+#~ msgid "List of audio devices to try."
+#~ msgstr "Lista de dispositivos para probar."
+
+#~ msgid "Menu volume"
+#~ msgstr "Volumen del menú"
+
+#~ msgid "The volume level of menus, song previews and jukebox mode."
+#~ msgstr ""
+#~ "Volumen del menú del juego, la vista previa de las canciones y el modo "
+#~ "tocadiscos (jukebox)."
+
+#~ msgid "Music volume"
+#~ msgstr "Volumen de la música"
+
+#~ msgid ""
+#~ "The ingame music volume. Values above 90 are not recommended as "
+#~ "distortion may occur."
+#~ msgstr ""
+#~ "Volumen de la música durante el juego. Valores por encima de 90 no son "
+#~ "recomendables ya que pueden producir distorsiones."
+
+#~ msgid "Failure volume"
+#~ msgstr "Volumen de fallo"
+
+#~ msgid ""
+#~ "The ingame fail sound volume. Values above 90 are not recommended as "
+#~ "distortion may occur. 11 is louder than 10, but these go to 100. 89 "
+#~ "louder!"
+#~ msgstr ""
+#~ "Volumen de fallo durante el juego. Valores por encima de 90 no son "
+#~ "recomendables ya que pueden producir distorsiones."
+
+#~ msgid "Song folders"
+#~ msgstr "Carpetas de canciones"
+
+#~ msgid ""
+#~ "Where to recursively look for songs. DATADIR at the beginning means all "
+#~ "Performous data folders."
+#~ msgstr ""
+#~ "Dónde buscar canciones de forma recurrente. DATADIR al comienzo significa "
+#~ "todas las carpetas de datos de Performous."
+
+#~ msgid "Base folders for data"
+#~ msgstr "Carpetas de datos"
+
+#~ msgid ""
+#~ "System defaults are included automatically. Additional paths can be added "
+#~ "here."
+#~ msgstr ""
+#~ "Las predefinidas por el sistema son incluidas de forma automática. "
+#~ "Cualquier otra puede ser añadida aquí."
+
+#~ msgid "Loading theme..."
+#~ msgstr "Cargando el tema..."
+
+#~ msgid "Loading background..."
+#~ msgstr "Cargando el fondo..."
+
+#~ msgid "Loading user interface..."
+#~ msgstr "Cargando la interfaz de usuario..."
+
+#~ msgid "Miscellaneous..."
+#~ msgstr "Varios..."
diff --git a/lang/fa.po b/lang/fa.po
new file mode 100644 (file)
index 0000000..c5ac650
--- /dev/null
@@ -0,0 +1,1129 @@
+msgid ""
+msgstr ""
+"Project-Id-Version: performous\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2013-07-12 14:55+0330\n"
+"PO-Revision-Date: \n"
+"Last-Translator: sajjadg <sajjad.gerami@gmail.com>\n"
+"Language-Team: GeramiBros <sajjad.gerami@gmail.com>\n"
+"Language: fa_IR\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"X-Poedit-KeywordsList: _\n"
+"X-Poedit-Basepath: .\n"
+"X-Poedit-SourceCharset: utf-8\n"
+"X-Generator: Poedit 1.5.4\n"
+"X-Poedit-SearchPath-0: ../game\n"
+"X-Poedit-SearchPath-1: ../data\n"
+
+#: ../game/dancegraph.cc:18
+msgid "Beginner"
+msgstr "تازه کار"
+
+#: ../game/dancegraph.cc:18 ../game/guitargraph.cc:14
+msgid "Easy"
+msgstr "آسان"
+
+#: ../game/dancegraph.cc:18 ../game/guitargraph.cc:14
+msgid "Medium"
+msgstr "متوسط"
+
+#: ../game/dancegraph.cc:18 ../game/guitargraph.cc:14
+msgid "Hard"
+msgstr "دشوار"
+
+# مسابقه
+#: ../game/dancegraph.cc:18
+msgid "Challenge"
+msgstr "رقابت"
+
+#: ../game/dancegraph.cc:107 ../game/guitargraph.cc:194
+msgid "Ready!"
+msgstr "آماده!"
+
+#: ../game/dancegraph.cc:107 ../game/screen_intro.cc:166
+#: ../game/guitargraph.cc:194
+msgid "Start performing!"
+msgstr "اجرا رو شروع کن!"
+
+#: ../game/dancegraph.cc:118 ../game/guitargraph.cc:183
+msgid "Select track"
+msgstr "انتخاب قطعه"
+
+#: ../game/dancegraph.cc:134 ../game/guitargraph.cc:163
+msgid "Select difficulty"
+msgstr "انتخاب میزان سختی"
+
+#: ../game/dancegraph.cc:137 ../game/screen_intro.cc:184
+#: ../game/instrumentgraph.cc:59 ../game/screen_sing.cc:92
+#: ../game/screen_sing.cc:126 ../game/guitargraph.cc:200
+msgid "Quit"
+msgstr "خروج"
+
+#: ../game/dancegraph.cc:137 ../game/instrumentgraph.cc:59
+#: ../game/screen_sing.cc:92 ../game/screen_sing.cc:126
+#: ../game/guitargraph.cc:200
+msgid "Exit to song browser"
+msgstr "خروج به مرورگر آهنگ"
+
+#: ../game/dancegraph.cc:248
+msgid "STOP!"
+msgstr "توقف!"
+
+# نوار باریک
+# خط
+#: ../game/dancegraph.cc:321 ../game/guitargraph.cc:447
+msgid "Streak!"
+msgstr "ماشاالله!"
+
+#: ../game/configuration.cc:112
+msgid "Enabled"
+msgstr "فعال شد"
+
+#: ../game/configuration.cc:112
+msgid "Disabled"
+msgstr "غیر فعال شد"
+
+#: ../game/configuration.cc:116
+#, c-format
+msgid "%d items"
+msgstr "مورد %d"
+
+#: ../game/screen_paths.cc:24
+msgid ""
+"This tool is not yet available.\n"
+"Configure paths by adding them\n"
+"as command line parameters and\n"
+"then save them in configuration menu."
+msgstr ""
+"این ابزار هنوز موجود نیست.\n"
+"مسیرها را با اضافه کردن آنها به عنوان\n"
+"پارامترهای خط فرمان پیکربندی کنید سپس\n"
+"آنها را در منو پیکربندی(تنظیمات) ذخیره کنید."
+
+#: ../game/screen_paths.cc:70
+msgid "Press any key to exit."
+msgstr "برای خروج کلیدی را بفشارید."
+
+#: ../game/screen_paths.cc:76
+msgid "Windows users can also use ConfigureSongDirectory.bat script."
+msgstr ""
+"کاربران ویندوز همچنین می توانند از ConfigureSongDirectory.bat استفاده کنند."
+
+#: ../game/screen_players.cc:115
+msgid "No players found!"
+msgstr "هیچ بازیکنی یافت نشد."
+
+#: ../game/screen_players.cc:116
+msgid "Enter a name to create a new player."
+msgstr "برای ایجاد بازیکن جدید نامی را وارد کنید."
+
+#: ../game/screen_players.cc:118
+msgid "Press enter to create player!"
+msgstr "برای ساختن بازیکن Enter را بزنید!"
+
+#: ../game/screen_players.cc:122
+msgid "No players worth mentioning!"
+msgstr "هیچ بازیکنی یافت نشد."
+
+#: ../game/screen_players.cc:127
+msgid "You reached %1% points!"
+msgstr "به امتیاز %1% رسیدی!"
+
+#: ../game/screen_players.cc:128
+msgid "Change player with arrow keys."
+msgstr "با کلید های جهت نما  بازیکن را تغییر دهید."
+
+#: ../game/screen_players.cc:129
+msgid "Name:"
+msgstr "اسم:"
+
+#: ../game/screen_players.cc:132
+msgid "Type text to filter or create a new player."
+msgstr "برای فیلتر کردن یا ایجاد بازیکن جدید‍‍‍‍ متنی را وارد کنید."
+
+#: ../game/screen_players.cc:132
+msgid "Search Text:"
+msgstr "متن جستجو:"
+
+#: ../game/screen_intro.cc:24
+msgid "No playback devices could be used.\n"
+msgstr "از هیچ دستگاهی با قابلیت پخش نمی توان استفاده کرد. \n"
+
+#: ../game/screen_intro.cc:25
+msgid ""
+"\n"
+"Please configure some before playing."
+msgstr ""
+"\n"
+"لطفا قبل از بازی پیکربندی کنید."
+
+#: ../game/screen_intro.cc:69
+msgid "Settings saved as system defaults."
+msgstr "تنظیمان به عنوان پیش فرض سیستم ذخیره شد."
+
+#: ../game/screen_intro.cc:69
+msgid "Settings saved."
+msgstr "تنظیمات ذخیره شد."
+
+#: ../game/screen_intro.cc:149
+msgid "Ctrl + S to save, Ctrl + R to reset defaults"
+msgstr "برای ذخیره Ctrl + S و برای تنظیمات اولیه Ctrl + R"
+
+#: ../game/screen_intro.cc:166
+msgid "Perform"
+msgstr "اجرا"
+
+#: ../game/screen_intro.cc:167
+msgid "Practice"
+msgstr "تمرین"
+
+#: ../game/screen_intro.cc:167
+msgid "Check your skills or test the microphones"
+msgstr "مهارتتان را بررسی و یا میکروفن را تست کنید"
+
+#: ../game/screen_intro.cc:183
+msgid "Configure"
+msgstr "پیکربندی"
+
+#: ../game/screen_intro.cc:183
+msgid "Configure audio and game options"
+msgstr "پیکربندی صوت و تنظیمات بازی"
+
+#: ../game/screen_intro.cc:184
+msgid "Leave the game"
+msgstr "ترک کردن بازی"
+
+#: ../game/screen_playlist.cc:110 ../game/screen_playlist.cc:252
+msgid "Continue"
+msgstr "ادامه"
+
+#: ../game/screen_playlist.cc:110
+msgid "Continue playing"
+msgstr "ادامه اجرا"
+
+#: ../game/screen_playlist.cc:118
+msgid "Add songs"
+msgstr "اضافه کردن آهنگ"
+
+#: ../game/screen_playlist.cc:118
+msgid "Open the song browser to add more songs"
+msgstr "برای اضافه کردن آهنگ جدید، پویشگر آهنگ را باز کن"
+
+#: ../game/screen_playlist.cc:119 ../game/screen_songs.cc:509
+msgid "Shuffle"
+msgstr "مخلوط کردن"
+
+#: ../game/screen_playlist.cc:119
+msgid "Randomize the order of the playlist"
+msgstr "ترتیب لیست اجرا را بهم بزن"
+
+#: ../game/screen_playlist.cc:125
+msgid "Clear and exit"
+msgstr "پاک کردن و خروج"
+
+#: ../game/screen_playlist.cc:125
+msgid "Remove all the songs from the list"
+msgstr "همه آهنگ ها را از لیست حذف کن"
+
+#: ../game/screen_playlist.cc:131 ../game/screen_playlist.cc:275
+#: ../game/screen_songs.cc:522
+msgid "Back"
+msgstr "بازگشت"
+
+#: ../game/screen_playlist.cc:131 ../game/screen_playlist.cc:275
+msgid "Back to playlist viewer"
+msgstr "بازگشت به لیست نمایش آهنگ ها"
+
+#: ../game/screen_playlist.cc:237
+msgid "Press enter to view song options"
+msgstr "برای دیدن تنظیمات enter بزن"
+
+#: ../game/screen_playlist.cc:244
+msgid "View more options"
+msgstr "تنظیمات بیشتر را ببین"
+
+#: ../game/screen_playlist.cc:244
+msgid "View general playlist settings"
+msgstr "نمایش تنظیمات کلی"
+
+#: ../game/screen_playlist.cc:252
+msgid "Play first"
+msgstr "اول اجرا کن"
+
+#: ../game/screen_playlist.cc:254
+msgid "Ignore the playlist's order and play this song first"
+msgstr "اولویت لیست پخشو بی خیال و این آهنگ رو اول اجرا کن"
+
+#: ../game/screen_playlist.cc:255
+msgid "Start the song already!"
+msgstr "همین الان آهنگ رو اجرا کن"
+
+#: ../game/screen_playlist.cc:264
+msgid "Remove"
+msgstr "حذف"
+
+#: ../game/screen_playlist.cc:264
+msgid "Remove this song from the list"
+msgstr "حذف این آهنگ رو از لیست"
+
+#: ../game/screen_songs.cc:278
+msgid "Sorry, no songs match the search!"
+msgstr "هیچ آهنگی با واژه جستجو شده مطابقت ندارد!"
+
+#: ../game/screen_songs.cc:281
+msgid "Sorry, no songs match the filter!"
+msgstr "ببخشید، هیچ آهنگی با واژه جستجو شده مطابقت ندارد!"
+
+#: ../game/screen_songs.cc:284
+msgid "No songs found!"
+msgstr "هیچ آهنگی یافت نشد!"
+
+#: ../game/screen_songs.cc:285
+msgid "Visit performous.org for free songs"
+msgstr "برای دریافت موسیقی رایگان به سایت www.performous.org مراجعه کنید."
+
+#: ../game/screen_songs.cc:303
+msgid "<type in to search>"
+msgstr "<تایپ کن تا بگردم>"
+
+#: ../game/screen_songs.cc:303
+msgid "songs"
+msgstr "آهنگ ها"
+
+#: ../game/screen_songs.cc:303
+msgid "options"
+msgstr "تنظیمات"
+
+#: ../game/screen_songs.cc:305
+msgid "sort order: "
+msgstr "مرتب سازی اولویت"
+
+#: ../game/screen_songs.cc:306
+msgid "type filter: "
+msgstr "فیلتر رو تایپ کن:"
+
+# \n
+#: ../game/screen_songs.cc:307
+msgid "hiscores"
+msgstr "برترین امتیازات"
+
+#: ../game/screen_songs.cc:307
+msgid "jukebox mode"
+msgstr "حالت جوکباکس"
+
+#: ../game/screen_songs.cc:310
+msgid "start a playlist with this song!"
+msgstr "لیست پخشی با این آهنگ بساز"
+
+#: ../game/screen_songs.cc:310
+msgid "open the playlist menu"
+msgstr "لیست پخش را باز کن"
+
+#: ../game/screen_songs.cc:502
+msgid "Play"
+msgstr "اجرا"
+
+#: ../game/screen_songs.cc:515
+msgid "View playlist"
+msgstr "لیست پخش رو ببین"
+
+#: ../game/screen_songs.cc:516
+msgid "Clear playlist"
+msgstr "لیست پخش را پاک کن"
+
+#: ../game/songs.cc:178
+msgid "show all songs"
+msgstr "نمایش همه آهنگ ها"
+
+#: ../game/songs.cc:179
+msgid "has dance"
+msgstr "رقص دار"
+
+#: ../game/songs.cc:180
+msgid "has vocals"
+msgstr "خوانندگی دار"
+
+#: ../game/songs.cc:181
+msgid "has duet"
+msgstr "دو نوازی دار"
+
+#: ../game/songs.cc:182
+msgid "has guitar"
+msgstr "گیتار دار"
+
+#: ../game/songs.cc:183
+msgid "drums or keytar"
+msgstr "تمبک یا درام"
+
+#: ../game/songs.cc:184
+msgid "full band"
+msgstr "گروه کامل"
+
+#: ../game/songs.cc:212
+msgid "random order"
+msgstr "ترتیب تصادفی"
+
+#: ../game/songs.cc:213
+msgid "sorted by song"
+msgstr "مرتب شده توسط آهنگ"
+
+#: ../game/songs.cc:214
+msgid "sorted by artist"
+msgstr "مرتب شده بر اساس خواننده"
+
+#: ../game/songs.cc:215
+msgid "sorted by edition"
+msgstr "مرتب شده بر اساس ویرایش"
+
+#: ../game/songs.cc:216
+msgid "sorted by genre"
+msgstr "مرتب شده بر اساس سبک"
+
+#: ../game/songs.cc:217
+msgid "sorted by path"
+msgstr "مرتب شده بر اساس مسیر"
+
+#: ../game/songs.cc:218
+msgid "sorted by language"
+msgstr "مرتب شده بر اساس زبان"
+
+#: ../game/instrumentgraph.cc:56 ../game/screen_sing.cc:123
+msgid "Resume"
+msgstr "ادامه دادن"
+
+#: ../game/instrumentgraph.cc:56 ../game/screen_sing.cc:123
+msgid "Back to performing!"
+msgstr "بازگشت به اجرا"
+
+#: ../game/instrumentgraph.cc:57
+msgid "Rejoin"
+msgstr "پیوستن مجدد"
+
+#: ../game/instrumentgraph.cc:57
+msgid "Change selections"
+msgstr "تغییر انتخاب ها"
+
+#: ../game/instrumentgraph.cc:58 ../game/screen_sing.cc:124
+msgid "Restart"
+msgstr "شروع مجدد"
+
+#: ../game/instrumentgraph.cc:58 ../game/screen_sing.cc:124
+msgid ""
+"Start the song\n"
+"from the beginning"
+msgstr ""
+"آهنگ رو از ابتدا\n"
+"شروع کن"
+
+#: ../game/screen_sing.cc:45
+msgid "Initializing webcam..."
+msgstr "در حال راه اندازی دوربین..."
+
+#: ../game/screen_sing.cc:52
+msgid "Loading video..."
+msgstr "در حال بارگیری تصویر"
+
+#: ../game/screen_sing.cc:59
+msgid "Loading song..."
+msgstr "در حال بارگذاری آهنگ..."
+
+# آهنگ شامل موردهای خراب است
+#: ../game/screen_sing.cc:66
+msgid "Song contains broken tracks!"
+msgstr "قسمتی از آهنگ خراب است!"
+
+#: ../game/screen_sing.cc:71
+msgid "Loading menu..."
+msgstr "در حال بارگیری فهرست..."
+
+#: ../game/screen_sing.cc:76
+msgid "Start"
+msgstr "شروع"
+
+#: ../game/screen_sing.cc:76
+msgid "Start performing"
+msgstr "شروع اجرا "
+
+#: ../game/screen_sing.cc:80
+msgid "Duet mode"
+msgstr "دونوازی"
+
+#: ../game/screen_sing.cc:81
+msgid "Normal mode"
+msgstr "حالت عادی"
+
+#: ../game/screen_sing.cc:82
+msgid "Switch between duet and regular singing mode"
+msgstr "تغییر بین دونوازی و تک نوازی"
+
+#: ../game/screen_sing.cc:90
+msgid "Change vocal track"
+msgstr "تغییر شیار صوتی"
+
+#: ../game/screen_sing.cc:97 ../game/main.cc:171
+msgid "Loading complete"
+msgstr "بارگزاری کامل شد"
+
+#: ../game/screen_sing.cc:125
+msgid "Skip"
+msgstr "پرش"
+
+#: ../game/screen_sing.cc:125
+msgid "Skip current song"
+msgstr "برش از روی آهنگ فعلی"
+
+#: ../game/screen_sing.cc:391
+msgid "Press UP to join dance!"
+msgstr "واسه رقص بالا را بزن"
+
+#: ../game/screen_sing.cc:391
+msgid "Step UP to join!"
+msgstr "برای ملحق شدن بالا رو بزن"
+
+#: ../game/screen_sing.cc:396
+msgid "Press 1 to join guitar!"
+msgstr "برای اضافه کردن گیتار ۱ رو بزن"
+
+#: ../game/screen_sing.cc:396
+msgid "Press GREEN to join!"
+msgstr "برای ملحق شدن سبز رو بزن"
+
+#: ../game/screen_sing.cc:401
+msgid "Press SPACE to join drums!"
+msgstr "برای اضافه کردن تمبک space بزن"
+
+#: ../game/screen_sing.cc:401
+msgid "KICK to join!"
+msgstr "برای اضافه شدن ضربه بزن"
+
+#: ../game/screen_sing.cc:475
+msgid "   ENTER to skip instrumental break"
+msgstr "برای پخش نشدن صدای خراب کردن ساز کلید Enter بزنید"
+
+#: ../game/screen_sing.cc:476
+msgid "   Remember to wait for grading!"
+msgstr "  فراموش نکنید که برای درجه بندی صبر کنید!"
+
+#: ../game/screen_sing.cc:587
+msgid "No player!"
+msgstr "هیچ بازیکنی!"
+
+#: ../game/screen_sing.cc:594
+msgid "Hit singer"
+msgstr "انتخاب خواننده"
+
+#: ../game/screen_sing.cc:595
+msgid "Lead singer"
+msgstr "خواننده را بارگیری کن"
+
+#: ../game/screen_sing.cc:596 ../game/screen_sing.cc:602
+#: ../game/screen_sing.cc:608
+msgid "Rising star"
+msgstr "افزایش ستاره"
+
+#: ../game/screen_sing.cc:597 ../game/screen_sing.cc:603
+#: ../game/screen_sing.cc:609
+msgid "Amateur"
+msgstr "مبتدی"
+
+#: ../game/screen_sing.cc:598 ../game/screen_sing.cc:610
+msgid "Tone deaf"
+msgstr "کر"
+
+# ديوانه‌
+# مجنون
+#: ../game/screen_sing.cc:600
+msgid "Maniac"
+msgstr "ديوانه‌ وار"
+
+#: ../game/screen_sing.cc:601
+msgid "Hoofer"
+msgstr "رقاص‌ حرفه‌ اي‌"
+
+#: ../game/screen_sing.cc:604
+msgid "Loser"
+msgstr "بازنده‌"
+
+#: ../game/screen_sing.cc:606
+msgid "Virtuoso"
+msgstr "هنرشناس‌"
+
+#: ../game/screen_sing.cc:607
+msgid "Rocker"
+msgstr "گیتاریست"
+
+#: ../game/screen_audiodevices.cc:55
+msgid ""
+"It seems you have some manual configurations\n"
+"incompatible with this user interface.\n"
+"Saving these settings will override\n"
+"all existing audio device configuration.\n"
+"Your other options changes will be saved too."
+msgstr ""
+"به نظر میرسد که شما کمی تنظیمات دستی دارید\n"
+"که با این رابط کاربری مطابقت ندارد\n"
+"ذخیره کردن این تنظیمات باعث پاک شدن تمام\n"
+"تنظیمات مربوط به دستگاه ها می شود\n"
+"تغییرات دیگر شما در تنظیمات نیز ذخیره می شود."
+
+#: ../game/screen_audiodevices.cc:114
+msgid "- Unassigned -"
+msgstr "-تخصیص نیافته-"
+
+#: ../game/screen_audiodevices.cc:135
+msgid ""
+"Use arrow keys to configure. Hit Enter/Start to save and test or Esc/Select "
+"to cancel. Ctrl + R to reset defaults"
+msgstr ""
+"از کلیدهای جهت نما جهت پیکربندی استفاده کنید. برای ذخیره Enter/Start و برای "
+"لغو test یا Esc/Select بزنید. Ctrl + R برای بازگشت به حالت اولیه"
+
+#: ../game/screen_audiodevices.cc:140
+msgid ""
+"For advanced device configuration, use command line parameter --audio (use --"
+"audiohelp for details)."
+msgstr ""
+"برای پیکربندی پیشرفته دستگاه از پارامتر audio-- خط فرمان استفاده کنید (برای "
+"اطلاعات بیشتر از audiohelp-- استفاده کنید)."
+
+#: ../game/screen_audiodevices.cc:188
+msgid "Some devices failed to open!"
+msgstr "باز کردن بعضی از دستگاه ها با مشکل مواجه شد!"
+
+#: ../game/main.cc:145
+msgid "Loading audio samples..."
+msgstr "در حال بارگزاری آهنگ ..."
+
+#: ../game/main.cc:159
+msgid "Creating screens..."
+msgstr "در حال ایجاد صفحات ..."
+
+#: ../game/main.cc:169
+msgid "Entering main menu"
+msgstr "ورود به منو اصلی"
+
+#: ../game/main.cc:182
+msgid "Screenshot taken!"
+msgstr "عکس صفحه گرفته شد!"
+
+#: ../game/main.cc:185
+msgid "Screenshot failed!"
+msgstr "گرفتن عکس صفحه با شکست مواجه شد!"
+
+#: ../game/guitargraph.cc:14
+msgid "Kids"
+msgstr "بچه ها"
+
+#: ../game/guitargraph.cc:14
+msgid "Expert"
+msgstr "حرفه ای"
+
+#: ../game/guitargraph.cc:169 ../game/guitargraph.cc:186
+msgid "Lefty-mode"
+msgstr "چپ دست"
+
+#: ../game/guitargraph.cc:207
+msgid "ON"
+msgstr "روشن"
+
+#: ../game/guitargraph.cc:207
+msgid "OFF"
+msgstr "خاموش"
+
+#: ../game/guitargraph.cc:208
+msgid "Toggle lefty-mode"
+msgstr "تعویض به چپ دست"
+
+#: ../game/guitargraph.cc:459
+msgid ""
+"God Mode\n"
+"Activated!"
+msgstr ""
+"حالت فوق العده\n"
+"فعال شد!"
+
+#: ../game/guitargraph.cc:460
+msgid "Mistakes ignored!"
+msgstr "از اشتباهات صرف نظر شد!"
+
+#: ../game/guitargraph.cc:1102
+msgid "God Mode Ready!"
+msgstr "حالت فوق العاده آماده است!"
+
+#: ../game/guitargraph.cc:1103
+msgid "Drum Fill!"
+msgstr "درام پر است!"
+
+#: ../game/guitargraph.cc:1106
+msgid "Solo!"
+msgstr "تک نوازی!"
+
+#: ../game/song.hh:23
+msgid "Guitar"
+msgstr "گیتار"
+
+#: ../game/song.hh:23
+msgid "Coop guitar"
+msgstr "گیتار دوم"
+
+#: ../game/song.hh:23
+msgid "Rhythm guitar"
+msgstr "گیتار ریتم"
+
+#: ../game/song.hh:23
+msgid "Bass"
+msgstr "باس"
+
+#: ../game/song.hh:23
+msgid "Drums"
+msgstr "تمبک"
+
+#: ../game/song.hh:23
+msgid "Vocals"
+msgstr "خوانندگی"
+
+#: ../game/song.hh:23
+msgid "Harmonic 1"
+msgstr "هارمونیک ۱"
+
+#: ../game/song.hh:23
+msgid "Harmonic 2"
+msgstr "هارمونیک ۲"
+
+#: ../game/song.hh:23
+msgid "Harmonic 3"
+msgstr "هارمونیک ۳"
+
+#: /tmp/xml2gettext.KLMLVC3iaY:2
+msgid "Game"
+msgstr "بازی"
+
+# ترجمه جایگزین برای گیم پلی چیست؟
+#: /tmp/xml2gettext.KLMLVC3iaY:3
+msgid "Gameplay related options"
+msgstr "تنظیمات مریوط به گیم پلی"
+
+#: /tmp/xml2gettext.KLMLVC3iaY:4
+msgid "Graphic"
+msgstr "گرافیک (نگاره)"
+
+#: /tmp/xml2gettext.KLMLVC3iaY:5
+msgid "Configure rendering and video settings"
+msgstr "پیکربندی رندر کردن و تنظیمات تصویر"
+
+#: /tmp/xml2gettext.KLMLVC3iaY:6
+msgid "Audio Devices"
+msgstr "دستگاه های صوتی"
+
+#: /tmp/xml2gettext.KLMLVC3iaY:7
+msgid "Setup microphones and playback"
+msgstr "راه اندازی میکروفن(دهنی) و بازبخش"
+
+#: /tmp/xml2gettext.KLMLVC3iaY:8
+msgid "Audio"
+msgstr "صوت"
+
+#: /tmp/xml2gettext.KLMLVC3iaY:9
+msgid "Configure general audio settings"
+msgstr "پیکربندی کلی تنظیمات صوتی"
+
+#: /tmp/xml2gettext.KLMLVC3iaY:10
+msgid "Paths"
+msgstr "مسیر"
+
+#: /tmp/xml2gettext.KLMLVC3iaY:11
+msgid "Setup song and data paths"
+msgstr "راه اندازی آهنگ و مسیرهای داده"
+
+#: /tmp/xml2gettext.KLMLVC3iaY:12
+msgid "Karaoke mode"
+msgstr "حالت همخوانی"
+
+#: /tmp/xml2gettext.KLMLVC3iaY:13
+msgid "Hide pitch wave, notes and scoring."
+msgstr "مخفی کردن دانگ صدا نت ها و امتیازها"
+
+#: /tmp/xml2gettext.KLMLVC3iaY:14
+msgid "Pitch waves"
+msgstr "دانگ‌ اصوات"
+
+#: /tmp/xml2gettext.KLMLVC3iaY:15
+msgid "Enable singing pitch display (when not in karaoke mode)."
+msgstr "فعال کردن نمایش زیر و بمی صدا (زمانی که در حالت همخوانی نیستید)"
+
+#: /tmp/xml2gettext.KLMLVC3iaY:16
+msgid "Theme"
+msgstr "پوسته"
+
+#: /tmp/xml2gettext.KLMLVC3iaY:17
+msgid "Name of the theme to use."
+msgstr "نام پوسته یا مسیر پوشه ی پوسته ها"
+
+#: /tmp/xml2gettext.KLMLVC3iaY:18
+msgid "Keyboard as guitar"
+msgstr "صفحه کلید به جای گیتار"
+
+#: /tmp/xml2gettext.KLMLVC3iaY:19
+msgid "Enable keyboard as guitar (Frets on Fire mode)."
+msgstr "فعال کردن صفحه کلید بجای گیتار(حالت Frets on Fire)"
+
+#: /tmp/xml2gettext.KLMLVC3iaY:20
+msgid "Keyboard as drumkit"
+msgstr "صفحه کلید بجای درام"
+
+#: /tmp/xml2gettext.KLMLVC3iaY:21
+msgid "Enable keyboard as drumkit."
+msgstr "فعال کردن صفحه کلید بجای درام"
+
+#: /tmp/xml2gettext.KLMLVC3iaY:22
+msgid "Keyboard as dance pad"
+msgstr "صفحه کلید بجای تخته رقص"
+
+#: /tmp/xml2gettext.KLMLVC3iaY:23
+msgid "Enable keyboard as dance pad."
+msgstr "فعال کردن صفحه کلید بجای تخته رقص."
+
+#: /tmp/xml2gettext.KLMLVC3iaY:24
+msgid "Keyboard as keytar"
+msgstr "صفحه کلید بجای کیتار."
+
+#: /tmp/xml2gettext.KLMLVC3iaY:25
+msgid "Enable keyboard as keytar."
+msgstr "فعال کردن صفحه کلید بجای کیتار."
+
+#: /tmp/xml2gettext.KLMLVC3iaY:26
+msgid "Force controller A's type"
+msgstr "مدل A دسته را اعمال کن"
+
+#: /tmp/xml2gettext.KLMLVC3iaY:27
+msgid ""
+"Override autodetection and force the first controller to the given type."
+msgstr "شناسایی خودکار را با اولین نوع دسته داده شده جایگزین کن"
+
+#: /tmp/xml2gettext.KLMLVC3iaY:28
+msgid "Force controller B's type"
+msgstr "مدل B دسته را اعمال کن"
+
+#: /tmp/xml2gettext.KLMLVC3iaY:29
+msgid ""
+"Override autodetection and force the second controller to the given type."
+msgstr "شناسایی خودکار را با دومین نوع دسته داده شده جایگزین کن"
+
+#: /tmp/xml2gettext.KLMLVC3iaY:30
+msgid "Force controller C's type"
+msgstr "مدل C دسته را اعمال کن"
+
+#: /tmp/xml2gettext.KLMLVC3iaY:31
+msgid ""
+"Override autodetection and force the third controller to the given type."
+msgstr "شناسایی خودکار را با سومین نوع دسته داده شده جایگزین کن"
+
+#: /tmp/xml2gettext.KLMLVC3iaY:32
+msgid "Force controller D's type"
+msgstr "مدل D دسته را اعمال کن"
+
+#: /tmp/xml2gettext.KLMLVC3iaY:33
+msgid ""
+"Override autodetection and force the fourth controller to the given type."
+msgstr "شناسایی خودکار را با چهارمین نوع دسته داده شده جایگزین کن"
+
+#: /tmp/xml2gettext.KLMLVC3iaY:34
+msgid "Joystick configuration"
+msgstr "پیکربندی دسته فرمان"
+
+#: /tmp/xml2gettext.KLMLVC3iaY:35
+msgid "Force joystick to some kind of instrument."
+msgstr "اجبار کردن دسته فرمان برای ساز"
+
+#: /tmp/xml2gettext.KLMLVC3iaY:36
+msgid "Hardware MIDI input device"
+msgstr "دستگاه سخت افزار ورودی MIDI"
+
+#: /tmp/xml2gettext.KLMLVC3iaY:37
+msgid ""
+"Regex for matching the MIDI devices to use. The default is to use all "
+"available devices."
+msgstr "الگوی تطابق دستگاه های MIDI. پیش فرض استفاده از همه دستگاه هاست."
+
+#: /tmp/xml2gettext.KLMLVC3iaY:38
+msgid "Fallback song encoding"
+msgstr "رمزگزاری آهنگ جایگزین"
+
+#: /tmp/xml2gettext.KLMLVC3iaY:39
+msgid "Pick the text codec used for song files that are not UTF-8."
+msgstr "برای آهنگ هایی که UTF-8 نیستند رمزگشای متن را استفاده کن."
+
+#: /tmp/xml2gettext.KLMLVC3iaY:40
+msgid "Windowed width"
+msgstr "عرض صفحه"
+
+#: /tmp/xml2gettext.KLMLVC3iaY:41
+msgid "The width of the window."
+msgstr "عرض صفحه"
+
+#: /tmp/xml2gettext.KLMLVC3iaY:42
+msgid "Windowed height"
+msgstr "ارتفاع صفحه"
+
+#: /tmp/xml2gettext.KLMLVC3iaY:43
+msgid "The height of the window."
+msgstr "ارتفاع صفحه"
+
+#: /tmp/xml2gettext.KLMLVC3iaY:44
+msgid "Fullscreen mode"
+msgstr "حالت تمام صفحه"
+
+#: /tmp/xml2gettext.KLMLVC3iaY:45
+msgid "Enable fullscreen mode on startup."
+msgstr "فعال کردن حالت تمام صفحه هنگام شروع"
+
+#: /tmp/xml2gettext.KLMLVC3iaY:46
+msgid "Stereoscopic 3D"
+msgstr "برجسته بین سه بعدی"
+
+#: /tmp/xml2gettext.KLMLVC3iaY:47
+msgid "Enable 3D rendering of Performous."
+msgstr "فعال کردن حالت سه یعدی پرفورمیوس"
+
+#: /tmp/xml2gettext.KLMLVC3iaY:48
+msgid "Stereo3D type"
+msgstr "حالت سه بعدی"
+
+#: /tmp/xml2gettext.KLMLVC3iaY:49
+msgid "Some modes may only get activated in fullscreen mode."
+msgstr "بعضی از حالات فقط در حالت تمام صفحه فعال می شوند"
+
+#: /tmp/xml2gettext.KLMLVC3iaY:50
+msgid "Stereo3D separation"
+msgstr "تفکیک سه بعدی"
+
+#: /tmp/xml2gettext.KLMLVC3iaY:51
+msgid ""
+"The strength of the effect. Experiment with different settings for best "
+"results."
+msgstr "قدرت اثر. برای نتیجه بهتر با یک تنظیم دیگر امتحان کنید."
+
+#: /tmp/xml2gettext.KLMLVC3iaY:52
+msgid "Video playback"
+msgstr "پخش تصویر"
+
+#: /tmp/xml2gettext.KLMLVC3iaY:53
+msgid ""
+"Allows completely disabling background videos. It is recommended to leave "
+"this enabled as Performous will still smoothly fade out the video if your "
+"computer is not fast enough."
+msgstr ""
+"اجازه دادن برای غیر فعال کردن کامل پس ضمینه ی تصویری. توصیه می شود این گزینه "
+"را در حالت فعال قرار دهید چون که اگر رایانه شما به اندازه کافی سریع نباشد "
+"پرفورمیوس تصویر را به نرمی محو می کند."
+
+#: /tmp/xml2gettext.KLMLVC3iaY:54
+msgid "Webcam background"
+msgstr "تصویر زمینه دوربین..."
+
+#: /tmp/xml2gettext.KLMLVC3iaY:55
+msgid ""
+"Performous can use webcam as a background video. Disable it if Performous "
+"crashes while entering a song."
+msgstr ""
+"پرفورمیوس میتواند از دوربین به عنوان تصویر پس ضمینه استفاده کند. اگر "
+"پرفورمیوس موقع ورود به یک آهنگ متوقف شد این گزینه را غیر فعال کنید."
+
+#: /tmp/xml2gettext.KLMLVC3iaY:56
+msgid "Webcam id"
+msgstr "شماره دوربین"
+
+#: /tmp/xml2gettext.KLMLVC3iaY:57
+msgid ""
+"Use -1 to autodetect or a number starting from 0 to choose specific device."
+msgstr ""
+"برای شناسایی خودکار -۱ و یا یک عدد که با ۰ شروع می شود را برای انتخاب دستگاه "
+"خاص وارد کنید."
+
+#: /tmp/xml2gettext.KLMLVC3iaY:58
+msgid "SVG quality"
+msgstr "کیفیت SVG"
+
+#: /tmp/xml2gettext.KLMLVC3iaY:59
+msgid ""
+"Larger numbers cause vector graphics to be rendered in higher resolution. "
+"Decrease this to make navigating in menus faster."
+msgstr ""
+"مقادیر بزرگ باعث می شود که بردارهای گرافیکی با کیفیت بالا نقش شوند. کاهش "
+"مقادیر باعث سرعت منو می شود."
+
+#: /tmp/xml2gettext.KLMLVC3iaY:60
+msgid "Text quality"
+msgstr "کیفیت متن"
+
+#: /tmp/xml2gettext.KLMLVC3iaY:61
+msgid ""
+"Larger numbers cause text to be rendered in higher resolution. Decrease this "
+"to make everything a little faster."
+msgstr ""
+"مقادیر بزرگ باعث می شود که متون با کیفیت بالا نقش شوند. کاهش مقادیر باعث "
+"سرعت اندکی در همه چیز می شود."
+
+#: /tmp/xml2gettext.KLMLVC3iaY:62
+msgid "Benchmark mode"
+msgstr "حالت محک"
+
+#: /tmp/xml2gettext.KLMLVC3iaY:63
+msgid ""
+"Framerate limit of 100 FPS is removed and the game instead renders at full "
+"speed. FPS values are printed to console. Please note that the display "
+"drivers may still limit the rendering speed to the screen refresh rate."
+msgstr ""
+"حد نرخ عبور تصویر(FPS) برابر ۱۰۰ حذف گردید و بازی با سرعت بالا نگاره می شود. "
+"مقادیر FPS در کنسول چاپ می شود. لطفا توجه داشته باشید که درایور صفحه نمایش "
+"هنوز هم ممکن است سرعت نگاره را با سرعت جاروب صفحه نمایش محدود کند."
+
+#: /tmp/xml2gettext.KLMLVC3iaY:64
+msgid "Suggested latency"
+msgstr "زمان تاخیر پیشنهادی"
+
+#: /tmp/xml2gettext.KLMLVC3iaY:65
+msgid ""
+"This is a hint for the audio engine about the desired latency. Set this as "
+"low as possible while retaining clear audio playback. Requires restart."
+msgstr ""
+"این یک تذکر برای متور صدا درمورد تاخیر خواسته شده است. اگر کیفیت صدای پایین "
+"دارید این مقدار را پایین بیاورید. نیاز به شروع مجدد دارد."
+
+#: /tmp/xml2gettext.KLMLVC3iaY:66
+msgid "Audio/video latency"
+msgstr "تاخیر صدا و تصویر"
+
+#: /tmp/xml2gettext.KLMLVC3iaY:67
+msgid ""
+"Affects all modes. Use negative value if your display input lag is greater "
+"than the sound card output latency, positive values in the opposite case and "
+"zero if they are equal. This should be set so that the notes pass the cursor "
+"at the same time the audio is heard. Use Ctrl+F1/F2 to adjust this while "
+"performing."
+msgstr ""
+"روی همه ی حالت ها تاثر دارد. اگر تاخیر در ورودی نمایش بزرگتر از تاخیر کارت "
+"صداست از مقادیر منفی استفاده کنید در حالت برعکس از مقادیر مثبت و صفر اگر "
+"باهم برابر است. این مقدار باید تنظیم شود تا نت همان زمانی که صدایش شنیده می "
+"شود از خط عبور کند. از کلید Ctrl+F1/F2 در حال اجرا برای تنظیم استفاده کنید."
+
+#: /tmp/xml2gettext.KLMLVC3iaY:68
+msgid "Audio round-trip latency"
+msgstr "تاخیر در رفت و آمد صدا"
+
+#: /tmp/xml2gettext.KLMLVC3iaY:69
+msgid ""
+"Affects singing only. The time it takes for Performous playback to reach "
+"your speakers, fly to the microphone and all the way back until Performous "
+"captures and analyzes it. While performing, press Ctrl+S for synth mode and "
+"adjust with Ctrl+F3/F4."
+msgstr ""
+"فقط روی خواندن تاثیر میگذارد. زمانی که طول می کشد که پخش پرفورمیوس به "
+"بلندگوی شما برسد از میکروفن عبور کند و پرفورمیوس آن را دریافت کند و تجزیه و "
+"تحلیل کند. در زمان اجرا Ctrl+S بزنید تا به حالت تنظیم بروید و با Ctrl+F3/F4 "
+"تنظیم کنید."
+
+#: /tmp/xml2gettext.KLMLVC3iaY:70
+msgid "Audio/controller latency"
+msgstr "تاخیر در صدا و کنترلر"
+
+#: /tmp/xml2gettext.KLMLVC3iaY:71
+msgid ""
+"Affects instruments and dancing only. The total of USB (guitar or dance pad) "
+"latency combined with audio output latency. Adjust so that you can hit the "
+"notes best when playing by ear (not looking on screen). Use Ctrl+F5/F6 to "
+"adjust while performing."
+msgstr ""
+"فقط روی ساز و رقص تاثیر دارد. کل تاخیر یو اس بی (گیتار و تخته رقص) به همراه "
+"تاخیر خروجی صدا. تنظیم کنید تا بتوانید در بهترین حالت زمانی که نت را می "
+"شنوید بزنید (نه زمانی که نت را روی صفحه می بینید). از کلید Ctrl+F5/F6 برای "
+"تنظیم حین اجرا استفاده کنید."
+
+#: /tmp/xml2gettext.KLMLVC3iaY:72
+msgid "Audio devices"
+msgstr "دستگاه های صوتی"
+
+#: /tmp/xml2gettext.KLMLVC3iaY:73
+msgid "List of audio devices to try."
+msgstr "فهرستی از دستگاه های صدا برای آزمایش کردن."
+
+#: /tmp/xml2gettext.KLMLVC3iaY:74
+msgid "Menu volume"
+msgstr "میزان صدای منو"
+
+#: /tmp/xml2gettext.KLMLVC3iaY:75
+msgid "The volume level of menus, song previews and jukebox mode."
+msgstr "میزان صدای منوها پیش نمایش آهنگ ها و حالت جعبه موزیک"
+
+#: /tmp/xml2gettext.KLMLVC3iaY:76
+msgid "Music volume"
+msgstr "میزان صدای آهنگ"
+
+#: /tmp/xml2gettext.KLMLVC3iaY:77
+msgid ""
+"The ingame music volume. Values above 90 are not recommended as distortion "
+"may occur."
+msgstr ""
+"میزان صدای آهنگ داخل بازی. مقادیر بالاتر از ۹۰ توصیه نمی شوند چون ممکن است "
+"باعث اغتشاش صوتی گردند."
+
+#: /tmp/xml2gettext.KLMLVC3iaY:78
+msgid "Failure volume"
+msgstr "میزان صدای خراب کردن آهنگ"
+
+#: /tmp/xml2gettext.KLMLVC3iaY:79
+msgid ""
+"The ingame fail sound volume. Values above 90 are not recommended as "
+"distortion may occur. 11 is louder than 10, but these go to 100. 89 louder!"
+msgstr ""
+"میزان صدای خراب کردن آهنگ داخل بازی. مقادیر بالاتر از ۹۰ توصیه نمی شوند چون "
+"ممکن است باعث اغتشاش صوتی گردند. 11 بلندتر از 9 است اما تا ۱۰۰ می رود. 89 "
+"بلندترین"
+
+#: /tmp/xml2gettext.KLMLVC3iaY:80
+msgid "Microphone pass-through"
+msgstr "صدای میانی میکروفن"
+
+#: /tmp/xml2gettext.KLMLVC3iaY:81
+msgid "Send captured singing voice to speakers."
+msgstr "ارسال صدای خواننده به بلندگو"
+
+#: /tmp/xml2gettext.KLMLVC3iaY:82
+msgid "Pass-through volume ratio"
+msgstr "میزان حجم صدای میانی"
+
+#: /tmp/xml2gettext.KLMLVC3iaY:83
+msgid "How much voice is amplified compared to the music."
+msgstr "چقدر صدا در مقایسه با موسیقی بلند شده."
+
+#: /tmp/xml2gettext.KLMLVC3iaY:84
+msgid "Song folders"
+msgstr "پوشه آهنگ ها"
+
+#: /tmp/xml2gettext.KLMLVC3iaY:85
+msgid ""
+"Where to recursively look for songs. DATADIR at the beginning means all "
+"Performous data folders."
+msgstr ""
+"جایی که به صورت بازگشتی به دنبال آهنگ میگردد. DATADIR در آغاز به معنی تمامی "
+"پوشه های پرفورمیوس است."
+
+#: /tmp/xml2gettext.KLMLVC3iaY:86
+msgid "Base folders for data"
+msgstr "پوشه اصلی اطلاعات"
+
+#: /tmp/xml2gettext.KLMLVC3iaY:87
+msgid ""
+"System defaults are included automatically. Additional paths can be added "
+"here."
+msgstr ""
+"پیش فرض های سیستم بصورت خودکار اضافه شده اند. مسیر های اضافی را اینجا وارد "
+"کنید."
+
+#~ msgid "<type in to search>   ↔ songs    ↕ options"
+#~ msgstr "<تایت کن تا بگردم>         ↔ آهنگ        ↕ تنظیمات"
+
+#~ msgid "↔ hiscores   ↵ jukebox mode"
+#~ msgstr "↔ برترین امتیازات    ↵ جعبه آهنگ"
diff --git a/lang/fi.po b/lang/fi.po
new file mode 100644 (file)
index 0000000..cc29945
--- /dev/null
@@ -0,0 +1,1128 @@
+msgid ""
+msgstr ""
+"Project-Id-Version: Performous\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2013-07-13 17:48+0200\n"
+"PO-Revision-Date: \n"
+"Last-Translator: FooBar\n"
+"Language-Team: \n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"X-Poedit-KeywordsList: _\n"
+"X-Poedit-Basepath: .\n"
+"X-Generator: Poedit 1.5.4\n"
+"X-Poedit-SourceCharset: UTF-8\n"
+"X-Poedit-SearchPath-0: ../game\n"
+"X-Poedit-SearchPath-1: ../data\n"
+
+#: ../game/configuration.cc:112
+msgid "Enabled"
+msgstr "Päällä"
+
+#: ../game/configuration.cc:112
+msgid "Disabled"
+msgstr "Pois"
+
+#: ../game/configuration.cc:116
+#, c-format
+msgid "%d items"
+msgstr "%d kohtaa"
+
+#: ../game/screen_playlist.cc:110 ../game/screen_playlist.cc:252
+msgid "Continue"
+msgstr "Jatka"
+
+#: ../game/screen_playlist.cc:110
+msgid "Continue playing"
+msgstr "Jatka esiintymistä"
+
+#: ../game/screen_playlist.cc:118
+msgid "Add songs"
+msgstr "Lisää kappaleita"
+
+#: ../game/screen_playlist.cc:118
+msgid "Open the song browser to add more songs"
+msgstr "Avaa musiikkiselain lisätäksesi kappaleita"
+
+#: ../game/screen_playlist.cc:119 ../game/screen_songs.cc:509
+msgid "Shuffle"
+msgstr "Sekoita"
+
+#: ../game/screen_playlist.cc:119
+msgid "Randomize the order of the playlist"
+msgstr "Sekoittaa soittolistan järjestyksen"
+
+#: ../game/screen_playlist.cc:125
+msgid "Clear and exit"
+msgstr "Tyhjennä ja poistu"
+
+#: ../game/screen_playlist.cc:125
+msgid "Remove all the songs from the list"
+msgstr "Poista kaikki kappaleet listasta"
+
+#: ../game/screen_playlist.cc:131 ../game/screen_playlist.cc:275
+#: ../game/screen_songs.cc:522
+msgid "Back"
+msgstr "Takaisin"
+
+#: ../game/screen_playlist.cc:131 ../game/screen_playlist.cc:275
+msgid "Back to playlist viewer"
+msgstr "Takaisin soittolistaan"
+
+#: ../game/screen_playlist.cc:237
+msgid "Press enter to view song options"
+msgstr "Paina enter avataksesi kappalevalinnat"
+
+#: ../game/screen_playlist.cc:244
+msgid "View more options"
+msgstr "Näytä lisää valintoja"
+
+#: ../game/screen_playlist.cc:244
+msgid "View general playlist settings"
+msgstr "Näytä yleiset soittolista-asetukset"
+
+#: ../game/screen_playlist.cc:252
+msgid "Play first"
+msgstr "Soita ensimmäinen"
+
+#: ../game/screen_playlist.cc:254
+msgid "Ignore the playlist's order and play this song first"
+msgstr "Jätä soittolistan järjestys huomioimatta ja soita tämä kappale ensiksi"
+
+#: ../game/screen_playlist.cc:255
+msgid "Start the song already!"
+msgstr "Aloita jo!"
+
+#: ../game/screen_playlist.cc:264
+msgid "Remove"
+msgstr "Poista"
+
+#: ../game/screen_playlist.cc:264
+msgid "Remove this song from the list"
+msgstr "Poista tämä kappale listasta"
+
+#: ../game/screen_paths.cc:24
+msgid ""
+"This tool is not yet available.\n"
+"Configure paths by adding them\n"
+"as command line parameters and\n"
+"then save them in configuration menu."
+msgstr ""
+"Tämä työkalu ei ole vielä saatavilla.\n"
+"Aseta polut antamalla ne\n"
+"komentoriviparametreinä ja\n"
+"tallenna ne sitten asetusvalikosta."
+
+#: ../game/screen_paths.cc:70
+msgid "Press any key to exit."
+msgstr "Paina mitä tahansa näppäintä jatkaaksesi."
+
+#: ../game/screen_paths.cc:76
+msgid "Windows users can also use ConfigureSongDirectory.bat script."
+msgstr ""
+"Windows-käyttäjät voivat myös käyttää ConfigureSongDirectory.bat-skriptiä."
+
+#: ../game/dancegraph.cc:18
+msgid "Beginner"
+msgstr "Aloittelija"
+
+#: ../game/dancegraph.cc:18 ../game/guitargraph.cc:14
+msgid "Easy"
+msgstr "Helppo"
+
+#: ../game/dancegraph.cc:18 ../game/guitargraph.cc:14
+msgid "Medium"
+msgstr "Keskitaso"
+
+#: ../game/dancegraph.cc:18 ../game/guitargraph.cc:14
+msgid "Hard"
+msgstr "Vaikea"
+
+#: ../game/dancegraph.cc:18
+msgid "Challenge"
+msgstr "Haastavin"
+
+#: ../game/dancegraph.cc:107 ../game/guitargraph.cc:194
+msgid "Ready!"
+msgstr "Valmis!"
+
+#: ../game/dancegraph.cc:107 ../game/guitargraph.cc:194
+#: ../game/screen_intro.cc:166
+msgid "Start performing!"
+msgstr "Aloita esiintyminen!"
+
+#: ../game/dancegraph.cc:118 ../game/guitargraph.cc:183
+msgid "Select track"
+msgstr "Valitse pelimuoto"
+
+#: ../game/dancegraph.cc:134 ../game/guitargraph.cc:163
+msgid "Select difficulty"
+msgstr "Valitse vaikeusaste"
+
+#: ../game/dancegraph.cc:137 ../game/instrumentgraph.cc:59
+#: ../game/guitargraph.cc:200 ../game/screen_intro.cc:184
+#: ../game/screen_sing.cc:92 ../game/screen_sing.cc:126
+msgid "Quit"
+msgstr "Lopeta"
+
+#: ../game/dancegraph.cc:137 ../game/instrumentgraph.cc:59
+#: ../game/guitargraph.cc:200 ../game/screen_sing.cc:92
+#: ../game/screen_sing.cc:126
+msgid "Exit to song browser"
+msgstr "Poistu kappalevalintaan"
+
+#: ../game/dancegraph.cc:248
+msgid "STOP!"
+msgstr "SEIS!"
+
+#: ../game/dancegraph.cc:321 ../game/guitargraph.cc:447
+msgid "Streak!"
+msgstr "Sarja!"
+
+#: ../game/instrumentgraph.cc:56 ../game/screen_sing.cc:123
+msgid "Resume"
+msgstr "Jatka"
+
+#: ../game/instrumentgraph.cc:56 ../game/screen_sing.cc:123
+msgid "Back to performing!"
+msgstr "Takaisin esiintymään!"
+
+#: ../game/instrumentgraph.cc:57
+msgid "Rejoin"
+msgstr "Liity uudelleen"
+
+#: ../game/instrumentgraph.cc:57
+msgid "Change selections"
+msgstr "Vaihda valintoja"
+
+#: ../game/instrumentgraph.cc:58 ../game/screen_sing.cc:124
+msgid "Restart"
+msgstr "Uudestaan"
+
+#: ../game/instrumentgraph.cc:58 ../game/screen_sing.cc:124
+msgid ""
+"Start the song\n"
+"from the beginning"
+msgstr ""
+"Aloita kappale\n"
+"alusta uudelleen"
+
+#: ../game/songs.cc:178
+msgid "show all songs"
+msgstr "näytä kaikki kappaleet"
+
+#: ../game/songs.cc:179
+msgid "has dance"
+msgstr "tanssi"
+
+#: ../game/songs.cc:180
+msgid "has vocals"
+msgstr "laulu"
+
+#: ../game/songs.cc:181
+msgid "has duet"
+msgstr "duetto"
+
+#: ../game/songs.cc:182
+msgid "has guitar"
+msgstr "kitara"
+
+#: ../game/songs.cc:183
+msgid "drums or keytar"
+msgstr "rummut tai koskettimisto"
+
+#: ../game/songs.cc:184
+msgid "full band"
+msgstr "täysi bändi"
+
+#: ../game/songs.cc:212
+msgid "random order"
+msgstr "satunnainen järjestys"
+
+#: ../game/songs.cc:213
+msgid "sorted by song"
+msgstr "järjestetty kappaleen mukaan"
+
+#: ../game/songs.cc:214
+msgid "sorted by artist"
+msgstr "järjestetty esittäjän mukaan"
+
+#: ../game/songs.cc:215
+msgid "sorted by edition"
+msgstr "järjestetty julkaisun mukaan"
+
+#: ../game/songs.cc:216
+msgid "sorted by genre"
+msgstr "järjestetty lajityypin mukaan"
+
+#: ../game/songs.cc:217
+msgid "sorted by path"
+msgstr "järjestetty polun mukaan"
+
+#: ../game/songs.cc:218
+msgid "sorted by language"
+msgstr "järjestetty kielen mukaan"
+
+#: ../game/screen_audiodevices.cc:55
+msgid ""
+"It seems you have some manual configurations\n"
+"incompatible with this user interface.\n"
+"Saving these settings will override\n"
+"all existing audio device configuration.\n"
+"Your other options changes will be saved too."
+msgstr ""
+"Näyttäisi, että sinulla on manuaalisia säätöjä,\n"
+"jotka ovat epäyhteensopivia tämän työkalun kanssa.\n"
+"Tallentaminen ylikirjoittaa kaikki aiemmat\n"
+"äänilaitevalintasi. Muut mahdolliset säädöt\n"
+"tallennetaan samalla."
+
+#: ../game/screen_audiodevices.cc:114
+msgid "- Unassigned -"
+msgstr "- Ei asetettu -"
+
+#: ../game/screen_audiodevices.cc:135
+msgid ""
+"Use arrow keys to configure. Hit Enter/Start to save and test or Esc/Select "
+"to cancel. Ctrl + R to reset defaults"
+msgstr ""
+"Nuolinäppäimet säätävät. Enter/Start tallentaa ja testaa, Esc/Select "
+"peruuttaa. Ctrl + R palauttaaksesi oletukset."
+
+#: ../game/screen_audiodevices.cc:140
+msgid ""
+"For advanced device configuration, use command line parameter --audio (use --"
+"audiohelp for details)."
+msgstr ""
+"Monimutkaisempia asetuksia halutessasi, käytä --audio komentoriviparametriä "
+"(--audiohelp auttaa)."
+
+#: ../game/screen_audiodevices.cc:188
+msgid "Some devices failed to open!"
+msgstr "Jotkin laitteista eivät olleet saatavilla!"
+
+#: ../game/main.cc:145
+msgid "Loading audio samples..."
+msgstr "Ladataan ääniä..."
+
+#: ../game/main.cc:159
+msgid "Creating screens..."
+msgstr "Luodaan näkymät..."
+
+#: ../game/main.cc:169
+msgid "Entering main menu"
+msgstr "Päävalikko..."
+
+#: ../game/main.cc:171 ../game/screen_sing.cc:97
+msgid "Loading complete"
+msgstr "Lataaminen valmis"
+
+#: ../game/main.cc:182
+msgid "Screenshot taken!"
+msgstr "Kuvakaappaus tallennettu!"
+
+#: ../game/main.cc:185
+msgid "Screenshot failed!"
+msgstr "Kuvakaappaus epäonnistui!"
+
+#: ../game/guitargraph.cc:14
+msgid "Kids"
+msgstr "Lapset"
+
+#: ../game/guitargraph.cc:14
+msgid "Expert"
+msgstr "Ekspertti"
+
+#: ../game/guitargraph.cc:169 ../game/guitargraph.cc:186
+msgid "Lefty-mode"
+msgstr "Vasuritila"
+
+#: ../game/guitargraph.cc:207
+msgid "ON"
+msgstr "Päällä"
+
+#: ../game/guitargraph.cc:207
+msgid "OFF"
+msgstr "Pois"
+
+#: ../game/guitargraph.cc:208
+msgid "Toggle lefty-mode"
+msgstr "Vasenkätisyystila"
+
+#: ../game/guitargraph.cc:459
+msgid ""
+"God Mode\n"
+"Activated!"
+msgstr ""
+"Jumalmoodi\n"
+"Aktivoitu!"
+
+#: ../game/guitargraph.cc:460
+msgid "Mistakes ignored!"
+msgstr "Virheitä ei huomioida!"
+
+#: ../game/guitargraph.cc:1102
+msgid "God Mode Ready!"
+msgstr "Jumalmoodi valmis!"
+
+#: ../game/guitargraph.cc:1103
+msgid "Drum Fill!"
+msgstr "Rumpufilli!"
+
+#: ../game/guitargraph.cc:1106
+msgid "Solo!"
+msgstr "Soolo!"
+
+#: ../game/screen_songs.cc:278
+msgid "Sorry, no songs match the search!"
+msgstr "Yksikään kappale ei vastannut hakuasi!"
+
+#: ../game/screen_songs.cc:281
+msgid "Sorry, no songs match the filter!"
+msgstr "Valitun tyyppisiä kappaleita ei löydy!"
+
+#: ../game/screen_songs.cc:284
+msgid "No songs found!"
+msgstr "Kappaleita ei löytynyt!"
+
+#: ../game/screen_songs.cc:285
+msgid "Visit performous.org for free songs"
+msgstr "Hae ilmaista musiikkia osoitteesta performous.org"
+
+#: ../game/screen_songs.cc:303
+msgid "<type in to search>"
+msgstr "<kirjoita etsiäksesi>"
+
+#: ../game/screen_songs.cc:303
+msgid "songs"
+msgstr "biisit"
+
+#: ../game/screen_songs.cc:303
+msgid "options"
+msgstr "vaihtoehdot"
+
+#: ../game/screen_songs.cc:305
+msgid "sort order: "
+msgstr "järjestys: "
+
+#: ../game/screen_songs.cc:306
+msgid "type filter: "
+msgstr "tyyppisuodin: "
+
+#: ../game/screen_songs.cc:307
+msgid "hiscores"
+msgstr "ennätykset"
+
+#: ../game/screen_songs.cc:307
+msgid "jukebox mode"
+msgstr "musiikkisoitin"
+
+#: ../game/screen_songs.cc:310
+msgid "start a playlist with this song!"
+msgstr "aloita soittolista tällä kappaleella"
+
+#: ../game/screen_songs.cc:310
+msgid "open the playlist menu"
+msgstr "avaa soittolistavalikko"
+
+#: ../game/screen_songs.cc:502
+msgid "Play"
+msgstr "Pelaa"
+
+#: ../game/screen_songs.cc:515
+msgid "View playlist"
+msgstr "Näytä soittolista"
+
+#: ../game/screen_songs.cc:516
+msgid "Clear playlist"
+msgstr "Tyhjennä soittolista"
+
+#: ../game/screen_intro.cc:24
+msgid "No playback devices could be used.\n"
+msgstr "Äänen ulostulolaitteita ei löytynyt.\n"
+
+#: ../game/screen_intro.cc:25
+msgid ""
+"\n"
+"Please configure some before playing."
+msgstr ""
+"\n"
+"Säädä ääniasetuksia ennen pelaamista."
+
+#: ../game/screen_intro.cc:69
+msgid "Settings saved as system defaults."
+msgstr "Asetukset tallennettu järjestelmän oletuksiksi."
+
+#: ../game/screen_intro.cc:69
+msgid "Settings saved."
+msgstr "Asetukset tallennettu."
+
+#: ../game/screen_intro.cc:149
+msgid "Ctrl + S to save, Ctrl + R to reset defaults"
+msgstr "Ctrl + S tallentaaksesi, Ctrl + R palauttaaksesi oletusarvot"
+
+#: ../game/screen_intro.cc:166
+msgid "Perform"
+msgstr "Esiinny"
+
+#: ../game/screen_intro.cc:167
+msgid "Practice"
+msgstr "Harjoittele"
+
+#: ../game/screen_intro.cc:167
+msgid "Check your skills or test the microphones"
+msgstr "Tarkista taitosi tai testaa mikrofonit"
+
+#: ../game/screen_intro.cc:183
+msgid "Configure"
+msgstr "Asetukset"
+
+#: ../game/screen_intro.cc:183
+msgid "Configure audio and game options"
+msgstr "Muokkaa pelin asetuksia"
+
+#: ../game/screen_intro.cc:184
+msgid "Leave the game"
+msgstr "Poistu pelistä"
+
+#: ../game/screen_players.cc:115
+msgid "No players found!"
+msgstr "Pelaajia ei löytynyt!"
+
+#: ../game/screen_players.cc:116
+msgid "Enter a name to create a new player."
+msgstr "Syötä nimi luodaksesi uuden pelaajan."
+
+#: ../game/screen_players.cc:118
+msgid "Press enter to create player!"
+msgstr "Paina Enter luodaksesi pelaajan!"
+
+#: ../game/screen_players.cc:122
+msgid "No players worth mentioning!"
+msgstr "Ei maininnan arvoisia pelaajia!"
+
+#: ../game/screen_players.cc:127
+msgid "You reached %1% points!"
+msgstr "Sait %1% pistettä!"
+
+#: ../game/screen_players.cc:128
+msgid "Change player with arrow keys."
+msgstr "Valitse pelaaja nuolinäppäimillä."
+
+#: ../game/screen_players.cc:129
+msgid "Name:"
+msgstr "Nimi:"
+
+#: ../game/screen_players.cc:132
+msgid "Type text to filter or create a new player."
+msgstr "Kirjoita etsiäksesi tai luodaksesi uuden pelaajan."
+
+#: ../game/screen_players.cc:132
+msgid "Search Text:"
+msgstr "Etsi:"
+
+#: ../game/screen_sing.cc:45
+msgid "Initializing webcam..."
+msgstr "Alustetaan webkameraa..."
+
+#: ../game/screen_sing.cc:52
+msgid "Loading video..."
+msgstr "Ladataan videota..."
+
+#: ../game/screen_sing.cc:59
+msgid "Loading song..."
+msgstr "Ladataan kappaletta..."
+
+#: ../game/screen_sing.cc:66
+msgid "Song contains broken tracks!"
+msgstr "Kappaleessa on rikkinäisiä osia!"
+
+#: ../game/screen_sing.cc:71
+msgid "Loading menu..."
+msgstr "Ladataan valikkoa..."
+
+#: ../game/screen_sing.cc:76
+msgid "Start"
+msgstr "Aloita"
+
+#: ../game/screen_sing.cc:76
+msgid "Start performing"
+msgstr "Aloita esiintymään"
+
+#: ../game/screen_sing.cc:80
+msgid "Duet mode"
+msgstr "Duettotila"
+
+#: ../game/screen_sing.cc:81
+msgid "Normal mode"
+msgstr "Normaalitila"
+
+#: ../game/screen_sing.cc:82
+msgid "Switch between duet and regular singing mode"
+msgstr "Vaihda dueton ja normaalin laulamisen välillä"
+
+#: ../game/screen_sing.cc:90
+msgid "Change vocal track"
+msgstr "Vaihda lauluraita"
+
+#: ../game/screen_sing.cc:125
+msgid "Skip"
+msgstr "Skippaa"
+
+#: ../game/screen_sing.cc:125
+msgid "Skip current song"
+msgstr "Hyppää nykyisen kappaleen yli"
+
+#: ../game/screen_sing.cc:391
+msgid "Press UP to join dance!"
+msgstr "Paina YLÖS liittyäksesi tanssiin!"
+
+#: ../game/screen_sing.cc:391
+msgid "Step UP to join!"
+msgstr "Paina YLÖS tanssiaksesi!"
+
+#: ../game/screen_sing.cc:396
+msgid "Press 1 to join guitar!"
+msgstr "Paina 1 liittyäksesi kitaralla!"
+
+#: ../game/screen_sing.cc:396
+msgid "Press GREEN to join!"
+msgstr "Paina VIHREÄÄ liittyäksesi!"
+
+#: ../game/screen_sing.cc:401
+msgid "Press SPACE to join drums!"
+msgstr "Paina VÄLI liittyäksesi rummuilla!"
+
+#: ../game/screen_sing.cc:401
+msgid "KICK to join!"
+msgstr "Paina BASSORUMPUA liittyäksesi!"
+
+#: ../game/screen_sing.cc:475
+msgid "   ENTER to skip instrumental break"
+msgstr "   ENTER hypätäksesi lauluosaan"
+
+#: ../game/screen_sing.cc:476
+msgid "   Remember to wait for grading!"
+msgstr "   Muista odottaa arvostelua!"
+
+#: ../game/screen_sing.cc:587
+msgid "No player!"
+msgstr "Pelaajia ei löytynyt!"
+
+#: ../game/screen_sing.cc:594
+msgid "Hit singer"
+msgstr "Tähti"
+
+#: ../game/screen_sing.cc:595
+msgid "Lead singer"
+msgstr "Solisti"
+
+#: ../game/screen_sing.cc:596 ../game/screen_sing.cc:602
+#: ../game/screen_sing.cc:608
+msgid "Rising star"
+msgstr "Harrastaja"
+
+#: ../game/screen_sing.cc:597 ../game/screen_sing.cc:603
+#: ../game/screen_sing.cc:609
+msgid "Amateur"
+msgstr "Amatööri"
+
+#: ../game/screen_sing.cc:598 ../game/screen_sing.cc:610
+msgid "Tone deaf"
+msgstr "Lahjaton"
+
+#: ../game/screen_sing.cc:600
+msgid "Maniac"
+msgstr "Maanikko"
+
+#: ../game/screen_sing.cc:601
+msgid "Hoofer"
+msgstr "Ekspertti"
+
+#: ../game/screen_sing.cc:604
+msgid "Loser"
+msgstr "Luuseri"
+
+#: ../game/screen_sing.cc:606
+msgid "Virtuoso"
+msgstr "Virtuoosi"
+
+#: ../game/screen_sing.cc:607
+msgid "Rocker"
+msgstr "Rokkari"
+
+#~ msgid "<type in to search>   ↔ songs    ↕ options"
+#~ msgstr "<kirjota etsiäksesi>   ↔ kappaleet    ↕ valinnat"
+
+#~ msgid "↔ hiscores   ↵ jukebox mode"
+#~ msgstr "↔ ennätykset   ↵ jukeboksi"
+
+#~ msgid "No Items up to now."
+#~ msgstr "Ei pisteitä tähän mennessä."
+
+#~ msgid "Be the first to be listed here!"
+#~ msgstr "Ole ensimmäinen!"
+
+#~ msgid "Guitar"
+#~ msgstr "Kitara"
+
+#~ msgid "Coop guitar"
+#~ msgstr "Soolokitara"
+
+#~ msgid "Rhythm guitar"
+#~ msgstr "Rytmikitara"
+
+#~ msgid "Bass"
+#~ msgstr "Basso"
+
+#~ msgid "Drums"
+#~ msgstr "Rummut"
+
+#~ msgid "Vocals"
+#~ msgstr "Laulu"
+
+#~ msgid "Harmonic 1"
+#~ msgstr "Harmonia 1"
+
+#~ msgid "Harmonic 2"
+#~ msgstr "Harmonia 2"
+
+#~ msgid "Harmonic 3"
+#~ msgstr "Harmonia 3"
+
+#~ msgid "Game"
+#~ msgstr "Peli"
+
+#~ msgid "Gameplay related options"
+#~ msgstr "Peliasetukset"
+
+#~ msgid "Graphic"
+#~ msgstr "Grafiikka"
+
+#~ msgid "Configure rendering and video settings"
+#~ msgstr "Muokkaa grafiikka- ja videoasetuksia"
+
+#~ msgid "Audio Devices"
+#~ msgstr "Äänilaitteet"
+
+#~ msgid "Setup microphones and playback"
+#~ msgstr "Tee mikrofoni- ja äänentoistoasetukset"
+
+#~ msgid "Audio"
+#~ msgstr "Ääni"
+
+#~ msgid "Configure general audio settings"
+#~ msgstr "Muokkaa yleisiä ääniasetuksia"
+
+#~ msgid "Paths"
+#~ msgstr "Tiedostopolut"
+
+#~ msgid "Setup song and data paths"
+#~ msgstr "Aseta musiikki- ja datakansioiden polut"
+
+#~ msgid "Karaoke mode"
+#~ msgstr "Karaoketila"
+
+#~ msgid "Hide pitch wave, notes and scoring."
+#~ msgstr "Piilota ääniaallon piirto, nuotit ja pisteytys."
+
+#~ msgid "Pitch waves"
+#~ msgstr "Äänenkorkeusaallot"
+
+#~ msgid "Enable singing pitch display (when not in karaoke mode)."
+#~ msgstr ""
+#~ "Ota käyttöön laulun äänenkorkeuden näyttäminen (kun ei olla "
+#~ "karaokemoodissa)."
+
+#~ msgid "Theme"
+#~ msgstr "Teema"
+
+#~ msgid "Name of the theme to use."
+#~ msgstr "Käytettävän teeman nimi."
+
+#~ msgid "Keyboard as guitar"
+#~ msgstr "Näppäimistö kitarana"
+
+#~ msgid "Enable keyboard as guitar (Frets on Fire mode)."
+#~ msgstr "Käytä näppäimistöä kitarana (Frets on Fire -pelitila)."
+
+#~ msgid "Keyboard as drumkit"
+#~ msgstr "Näppäimistö rumpuina"
+
+#~ msgid "Enable keyboard as drumkit."
+#~ msgstr "Käytä näppäimistöä rumpusettinä."
+
+#~ msgid "Keyboard as dance pad"
+#~ msgstr "Näppäimistö tanssimattona"
+
+#~ msgid "Enable keyboard as dance pad."
+#~ msgstr "Käytä näppäimistöä tanssimattona."
+
+#~ msgid "Keyboard as keytar"
+#~ msgstr "Näppäimistö pianona"
+
+#~ msgid "Enable keyboard as keytar."
+#~ msgstr "Käytä näppäimistöä pianona."
+
+#~ msgid "Force controller A's type"
+#~ msgstr "Pakota peliohjain A:n tyyppi"
+
+#~ msgid ""
+#~ "Override autodetection and force the first controller to the given type."
+#~ msgstr ""
+#~ "Ohita automaattinen tunnistus ja pakota ensimmäisen peliohjaimen tyyppi."
+
+#~ msgid "Force controller B's type"
+#~ msgstr "Pakota peliohjain B:n tyyppi"
+
+#~ msgid ""
+#~ "Override autodetection and force the second controller to the given type."
+#~ msgstr "Ohita automaattinen tunnistus ja pakota toisen peliohjaimen tyyppi."
+
+#~ msgid "Force controller C's type"
+#~ msgstr "Pakota peliohjain C:n tyyppi"
+
+#~ msgid ""
+#~ "Override autodetection and force the third controller to the given type."
+#~ msgstr ""
+#~ "Ohita automaattinen tunnistus ja pakota kolmannen peliohjaimen tyyppi."
+
+#~ msgid "Force controller D's type"
+#~ msgstr "Pakota peliohjain D:n tyyppi"
+
+#~ msgid ""
+#~ "Override autodetection and force the fourth controller to the given type."
+#~ msgstr ""
+#~ "Ohita automaattinen tunnistus ja pakota neljännen peliohjaimen tyyppi."
+
+#~ msgid "Joystick configuration"
+#~ msgstr "Peliohjain säädöt"
+
+#~ msgid "Force joystick to some kind of instrument."
+#~ msgstr "Pakota peliohjain jonkinlaiseksi instrumentiksi."
+
+#~ msgid "Hardware MIDI input device"
+#~ msgstr "MIDI sisääntulolaite"
+
+#~ msgid ""
+#~ "Regex for matching the MIDI devices to use. The default is to use all "
+#~ "available devices."
+#~ msgstr ""
+#~ "Säännöllinen lauseke MIDI laitteen valitsemiseksi. Oletuksena käytetään "
+#~ "kaikkia saatavilla olevia."
+
+#~ msgid "Fallback song encoding"
+#~ msgstr "Tekstin varakoodaus"
+
+#~ msgid "Pick the text codec used for song files that are not UTF-8."
+#~ msgstr "Tekstin koodaus jos se ei ole UTF-8."
+
+#~ msgid "Windowed width"
+#~ msgstr "Ikkunoitu leveys"
+
+#~ msgid "The width of the window."
+#~ msgstr "Ikkunan leveys."
+
+#~ msgid "Windowed height"
+#~ msgstr "Ikkunoitu korkeus"
+
+#~ msgid "The height of the window."
+#~ msgstr "Ikkunan korkeus."
+
+#~ msgid "Fullscreen mode"
+#~ msgstr "Kokoruututila"
+
+#~ msgid "Enable fullscreen mode on startup."
+#~ msgstr "Ota kokoruututila käyttöön."
+
+#~ msgid "Stereoscopic 3D"
+#~ msgstr "Stereo 3D"
+
+#~ msgid "Enable 3D rendering of Performous."
+#~ msgstr "Aktivoi Performouksen 3D renderöinti."
+
+#~ msgid "Stereo3D type"
+#~ msgstr "Stereo 3D:n tyyppi"
+
+#~ msgid "Some modes may only get activated in fullscreen mode."
+#~ msgstr "Jotkin tilat aktivoituvat vain kokoruudun tilassa."
+
+#~ msgid "Stereo3D separation"
+#~ msgstr "Stereoerotus"
+
+#~ msgid ""
+#~ "The strength of the effect. Experiment with different settings for best "
+#~ "results."
+#~ msgstr ""
+#~ "Efektin voimakkuus. Kokeile erilaisia arvoja saavuttaaksesi parhaan "
+#~ "tuloksen."
+
+#~ msgid "Video playback"
+#~ msgstr "Videotoisto"
+
+#~ msgid ""
+#~ "Allows completely disabling background videos. It is recommended to leave "
+#~ "this enabled as Performous will still smoothly fade out the video if your "
+#~ "computer is not fast enough."
+#~ msgstr ""
+#~ "Poista musiikkivideot käytöstä. Suositeltavaa on jättää ne päälle, koska "
+#~ "Performous osaa häivyttää ne automaattisesti, jos tietokoneesta näyttää "
+#~ "loppuvan tehot."
+
+#~ msgid "Webcam background"
+#~ msgstr "Web-kamera taustana"
+
+#~ msgid ""
+#~ "Performous can use webcam as a background video. Disable it if Performous "
+#~ "crashes while entering a song."
+#~ msgstr ""
+#~ "Performous voi yrittää käyttää web-kameran videota kappaleiden "
+#~ "taustakuvana. Poista käytöstä jos peli kaatuu kappaletta ladatessa."
+
+#~ msgid "Webcam id"
+#~ msgstr "Web-kameran tunniste"
+
+#~ msgid ""
+#~ "Use -1 to autodetect or a number starting from 0 to choose specific "
+#~ "device."
+#~ msgstr ""
+#~ "Arvo -1 valitsee kameran automaattisesti, sitä suuremmat kokonaisluvut "
+#~ "valitsevat tietyn laitteen."
+
+#~ msgid "SVG quality"
+#~ msgstr "Vektorikuvien laatu"
+
+#~ msgid ""
+#~ "Larger numbers cause vector graphics to be rendered in higher resolution. "
+#~ "Decrease this to make navigating in menus faster."
+#~ msgstr ""
+#~ "Suuremmilla luvuilla vektorikuvat luodaan korkeammalla tarkkuudella. "
+#~ "Pienentämällä arvoa valikoissa liikkuminen nopeutuu."
+
+#~ msgid "Text quality"
+#~ msgstr "Tekstin laatu"
+
+#~ msgid ""
+#~ "Larger numbers cause text to be rendered in higher resolution. Decrease "
+#~ "this to make everything a little faster."
+#~ msgstr ""
+#~ "Suuremmilla arvoilla teksti piirretään tarkempana. Tämä vaikuttaa hieman "
+#~ "suorituskykyyn lähes kaikkialla."
+
+#~ msgid "Benchmark mode"
+#~ msgstr "Suorituskyvynmittaustila"
+
+#~ msgid ""
+#~ "Framerate limit of 100 FPS is removed and the game instead renders at "
+#~ "full speed. FPS values are printed to console. Please note that the "
+#~ "display drivers may still limit the rendering speed to the screen refresh "
+#~ "rate."
+#~ msgstr ""
+#~ "Ruudunpäivitysnopeuden raja 100 FPS poistetaan ja sen nopeusarvoja "
+#~ "tulostetaan terminaaliin. Huomaa, että näytönohjainajurit saattavat vielä "
+#~ "rajoittaa nopeutta."
+
+#~ msgid "Suggested latency"
+#~ msgstr "Toivottu latenssi"
+
+#~ msgid ""
+#~ "This is a hint for the audio engine about the desired latency. Set this "
+#~ "as low as possible while retaining clear audio playback. Requires restart."
+#~ msgstr ""
+#~ "Vihje äänilaitteille kuinka pieni latenssi halutaan. Aseta niin matalaksi "
+#~ "kuin mahdollista ilman äänen häiriöitä. Vaatii uudelleenkäynnistyksen. "
+
+#~ msgid "Audio/video latency"
+#~ msgstr "Ääni/video latenssi"
+
+#~ msgid ""
+#~ "Affects all modes. Use negative value if your display input lag is "
+#~ "greater than the sound card output latency, positive values in the "
+#~ "opposite case and zero if they are equal. This should be set so that the "
+#~ "notes pass the cursor at the same time the audio is heard. Use Ctrl+F1/F2 "
+#~ "to adjust this while performing."
+#~ msgstr ""
+#~ "Vaikuttaa kaikkiin pelimuotoihin. Käytä negatiivista arvoa jos näytön "
+#~ "sisääntuloviive on suurempi kuin äänikortin ulostulolatenssi ja "
+#~ "päinvastoin. Tämän pitäisi olla säädetty siten, että nuotit ohittavat "
+#~ "\"kursorin\" samaan aikaan kun ääni kuullaan. Ctrl+F1/F2 säätävät pelin "
+#~ "aikana."
+
+#~ msgid "Audio round-trip latency"
+#~ msgstr "Äänen edestakainen latenssi"
+
+#~ msgid ""
+#~ "Affects singing only. The time it takes for Performous playback to reach "
+#~ "your speakers, fly to the microphone and all the way back until "
+#~ "Performous captures and analyzes it. While performing, press Ctrl+S for "
+#~ "synth mode and adjust with Ctrl+F3/F4."
+#~ msgstr ""
+#~ "Vaikuttaa ainoastaan laulamiseen. Tämä on aika, joka Performouksen "
+#~ "ääniltä kestää saavuttaa kaiuttimesi, lentää mikrofoniin ja takaisin "
+#~ "Performouksen kaapattavaksi ja analysoitavaksi. Pelatessa, paina Ctrl+S "
+#~ "aktivoidaksesi syntetisaattoritilan ja säädä Ctrl+F3/F4 näppäimillä."
+
+#~ msgid "Audio/controller latency"
+#~ msgstr "Ääni/peliohjain latenssi"
+
+#~ msgid ""
+#~ "Affects instruments and dancing only. The total of USB (guitar or dance "
+#~ "pad) latency combined with audio output latency. Adjust so that you can "
+#~ "hit the notes best when playing by ear (not looking on screen). Use Ctrl"
+#~ "+F5/F6 to adjust while performing."
+#~ msgstr ""
+#~ "Vaikuttaa vain soittamiseen ja tanssimiseen. Tämä on USB:n viive "
+#~ "yhdistettynä äänen ulostuloviiveeseen. Säädä siten, että osut nuotteihin "
+#~ "hyvin pelkän kuulon avulla. Ctrl+F5/F6 pelin aikana."
+
+#~ msgid "Audio devices"
+#~ msgstr "Äänilaitteet"
+
+#~ msgid "List of audio devices to try."
+#~ msgstr "Lista kokeiltavista äänilaitteista."
+
+#~ msgid "Menu volume"
+#~ msgstr "Valikkojen äänenvoimakkuus"
+
+#~ msgid "The volume level of menus, song previews and jukebox mode."
+#~ msgstr ""
+#~ "Äänenvoimakkuus valikoissa, kappaleiden esikuunteluissa ja jukeboksi "
+#~ "tilassa."
+
+#~ msgid "Music volume"
+#~ msgstr "Musiikin voimakkuus"
+
+#~ msgid ""
+#~ "The ingame music volume. Values above 90 are not recommended as "
+#~ "distortion may occur."
+#~ msgstr ""
+#~ "Pelin äänenvoimakkuus. Arvot yli 90 eivät ole suositeltuja mahdollisen "
+#~ "äänen vääristymisen takia."
+
+#~ msgid "Failure volume"
+#~ msgstr "Virheiden äänenvoimakkuus"
+
+#~ msgid ""
+#~ "The ingame fail sound volume. Values above 90 are not recommended as "
+#~ "distortion may occur. 11 is louder than 10, but these go to 100. 89 "
+#~ "louder!"
+#~ msgstr ""
+#~ "Virheäänien voimakkuus. Arvot yli 90 eivät ole suositeltuja mahdollisen "
+#~ "äänen vääristymisen takia."
+
+#~ msgid "Microphone pass-through"
+#~ msgstr "Äänen läpivienti"
+
+#~ msgid "Send captured singing voice to speakers."
+#~ msgstr "Lähetä mikrofonista nauhoitettu ääni kaiuttimille."
+
+#~ msgid "Pass-through volume ratio"
+#~ msgstr "Läpiviennin äänenvoimakkuussuhde"
+
+#~ msgid "How much voice is amplified compared to the music."
+#~ msgstr "Kuinka paljon laulun tasoa suurennetaan musiikkiin suhteutettuna."
+
+#~ msgid "Song folders"
+#~ msgstr "Kappaleiden sijainnit"
+
+#~ msgid ""
+#~ "Where to recursively look for songs. DATADIR at the beginning means all "
+#~ "Performous data folders."
+#~ msgstr ""
+#~ "Mistä etsiä rekursiivisesti kappaleita. DATADIR alussa tarkoittaa kaikkia "
+#~ "Performouksen järjestelmäkansioita."
+
+#~ msgid "Base folders for data"
+#~ msgstr "Järjestelmäkansiot"
+
+#~ msgid ""
+#~ "System defaults are included automatically. Additional paths can be added "
+#~ "here."
+#~ msgstr ""
+#~ "Järjestelmän oletuskansiot sisällytetään automaattisesti. Omia voi lisätä "
+#~ "tähän."
+
+#~ msgid "Start the game with all songs in playlist"
+#~ msgstr "Aloita peli kaikilla soittolistan kappaleilla"
+
+#~ msgid "View the current playlist"
+#~ msgstr "Näytä tämän hetkinen soittolista"
+
+#~ msgid "Back to song browser"
+#~ msgstr "Takaisin kappalevalintaan"
+
+#~ msgid "Song is broken!"
+#~ msgstr "Kappale on rikki!"
+
+#~ msgid "Loading instruments..."
+#~ msgstr "Ladataan instrumentteja..."
+
+#~ msgid "Finalizing..."
+#~ msgstr "Viimeistellään..."
+
+#~ msgid "Loading graphics..."
+#~ msgstr "Ladataan grafiikoita..."
+
+#~ msgid "Random background..."
+#~ msgstr "Satunnainen taustakuva..."
+
+#~ msgid "(press END to view hiscores)"
+#~ msgstr "(paina END nähdäksesi ennätykset)"
+
+#~ msgid "Graphics"
+#~ msgstr "Grafiikka"
+
+#~ msgid "Gameplay settings."
+#~ msgstr "Peliasetukset."
+
+#~ msgid "Video and rendering settings."
+#~ msgstr "Video ja kuva-asetukset."
+
+#~ msgid "Audio-related settings."
+#~ msgstr "Ääniasetukset."
+
+#~ msgid "System paths."
+#~ msgstr "Järjestelmän tiedostopolut."
+
+#~ msgid ""
+#~ "Part of sound card name or its number or empty to use the first available "
+#~ "device. Used currently for MIDI drum controllers."
+#~ msgstr ""
+#~ "Osa äänikortin nimestä tai sen numero. Tyhjä arvo valitsee ensimmäisen "
+#~ "mahdollisen. Käytetään MIDI rumpujen kanssa."
+
+#~ msgid "3D notes"
+#~ msgstr "3D nuotit"
+
+#~ msgid ""
+#~ "Draw instrument notes as 3-dimensional objects. May hurt performance on "
+#~ "older hardware."
+#~ msgstr "Piirrä instrumenttinuotit kolmiulotteisina objekteina."
+
+#~ msgid "Loading theme..."
+#~ msgstr "Ladataan teemaa..."
+
+#~ msgid "Loading background..."
+#~ msgstr "Ladataan taustaa..."
+
+#~ msgid "Loading user interface..."
+#~ msgstr "Ladataan käyttöliittymää..."
+
+#~ msgid "Audio..."
+#~ msgstr "Ääni..."
+
+#~ msgid "Launching background loaders..."
+#~ msgstr "Käynnistetään taustalataajat..."
+
+#~ msgid "Press Enter to configure (TODO: implement)"
+#~ msgstr "Käytä Äänilaitteet-työkalua."
+
+#~ msgid "Go back to main menu"
+#~ msgstr "Palaa päävalikkoon"
+
+#~ msgid "System"
+#~ msgstr "Järjestelmä"
+
+#~ msgid "Miscellaneous..."
+#~ msgstr "Sekalaista..."
diff --git a/lang/fr.po b/lang/fr.po
new file mode 100644 (file)
index 0000000..96ce4b4
--- /dev/null
@@ -0,0 +1,1192 @@
+msgid ""
+msgstr ""
+"Project-Id-Version: Performous\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2013-07-13 11:16+0100\n"
+"PO-Revision-Date: \n"
+"Last-Translator: \n"
+"Language-Team: \n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"X-Poedit-KeywordsList: _\n"
+"X-Poedit-Basepath: .\n"
+"X-Generator: Poedit 1.5.5\n"
+"X-Poedit-SearchPath-0: ../game\n"
+"X-Poedit-SearchPath-1: ../data\n"
+
+#: ../game/screen_audiodevices.cc:55
+msgid ""
+"It seems you have some manual configurations\n"
+"incompatible with this user interface.\n"
+"Saving these settings will override\n"
+"all existing audio device configuration.\n"
+"Your other options changes will be saved too."
+msgstr ""
+"Il semble que vous ayez certaines configurations\n"
+"incompatibles avec cette interface d'utilisation.\n"
+"Sauvegarder cette configuration va écraser\n"
+"toutes les configurations audio préexistantes.\n"
+"Vos autres changements seront également sauvegardés."
+
+#: ../game/screen_audiodevices.cc:114
+msgid "- Unassigned -"
+msgstr "- Non assigné -"
+
+#: ../game/screen_audiodevices.cc:135
+msgid ""
+"Use arrow keys to configure. Hit Enter/Start to save and test or Esc/Select "
+"to cancel. Ctrl + R to reset defaults"
+msgstr ""
+"Utilisez les flèches pour configurer. Tapez Entrer/Démarrer pour sauvegarder "
+"ou Ech/Select pour annuler. Ctrl+R pour remettre à zéro."
+
+#: ../game/screen_audiodevices.cc:140
+msgid ""
+"For advanced device configuration, use command line parameter --audio (use --"
+"audiohelp for details)."
+msgstr ""
+"Pour une configuration avancée veuillez utiliser la ligne de commande --"
+"audio (--audiohelp pour l'aide)."
+
+#: ../game/screen_audiodevices.cc:188
+msgid "Some devices failed to open!"
+msgstr "Certains périphériques n'ont pas pu être ouverts !"
+
+#: ../game/screen_sing.cc:45
+msgid "Initializing webcam..."
+msgstr "Initialisation de la webcam..."
+
+#: ../game/screen_sing.cc:52
+msgid "Loading video..."
+msgstr "Chargement de la vidéo..."
+
+#: ../game/screen_sing.cc:59
+msgid "Loading song..."
+msgstr "Chargement de la chanson..."
+
+#: ../game/screen_sing.cc:66
+msgid "Song contains broken tracks!"
+msgstr "Chanson contenant des pistes défectueuses !"
+
+#: ../game/screen_sing.cc:71
+msgid "Loading menu..."
+msgstr "Chargement du menu..."
+
+#: ../game/screen_sing.cc:76
+msgid "Start"
+msgstr "Démarrer"
+
+#: ../game/screen_sing.cc:76
+msgid "Start performing"
+msgstr "Commencer une partie"
+
+#: ../game/screen_sing.cc:80
+msgid "Duet mode"
+msgstr "Mode duo"
+
+#: ../game/screen_sing.cc:81
+msgid "Normal mode"
+msgstr "Mode normal"
+
+#: ../game/screen_sing.cc:82
+msgid "Switch between duet and regular singing mode"
+msgstr "Basculer entre le mode standard et le mode duo"
+
+#: ../game/screen_sing.cc:90
+msgid "Change vocal track"
+msgstr "Change la piste de chant"
+
+#: ../game/screen_sing.cc:92 ../game/screen_sing.cc:126
+#: ../game/screen_intro.cc:184 ../game/guitargraph.cc:200
+#: ../game/dancegraph.cc:137 ../game/instrumentgraph.cc:59
+msgid "Quit"
+msgstr "Quitter"
+
+#: ../game/screen_sing.cc:92 ../game/screen_sing.cc:126
+#: ../game/guitargraph.cc:200 ../game/dancegraph.cc:137
+#: ../game/instrumentgraph.cc:59
+msgid "Exit to song browser"
+msgstr "Revenir vers la liste des morceaux"
+
+#: ../game/screen_sing.cc:97 ../game/main.cc:171
+msgid "Loading complete"
+msgstr "Chargement effectué"
+
+#: ../game/screen_sing.cc:123 ../game/instrumentgraph.cc:56
+msgid "Resume"
+msgstr "Reprendre"
+
+#: ../game/screen_sing.cc:123 ../game/instrumentgraph.cc:56
+msgid "Back to performing!"
+msgstr "Retourner à la partie !"
+
+#: ../game/screen_sing.cc:124 ../game/instrumentgraph.cc:58
+msgid "Restart"
+msgstr "Redémarrer"
+
+#: ../game/screen_sing.cc:124 ../game/instrumentgraph.cc:58
+msgid ""
+"Start the song\n"
+"from the beginning"
+msgstr ""
+"Démarrer le morceau\n"
+"depuis le début"
+
+#: ../game/screen_sing.cc:125
+msgid "Skip"
+msgstr "Passer"
+
+#: ../game/screen_sing.cc:125
+msgid "Skip current song"
+msgstr "Passer le morceau actuel"
+
+#: ../game/screen_sing.cc:391
+msgid "Press UP to join dance!"
+msgstr "Appuyer sur HAUT pour entrer dans la danse !"
+
+#: ../game/screen_sing.cc:391
+msgid "Step UP to join!"
+msgstr "Appuyer sur HAUT pour jouer !"
+
+#: ../game/screen_sing.cc:396
+msgid "Press 1 to join guitar!"
+msgstr "Appuyer sur 1 pour jouer avec une guitare !"
+
+#: ../game/screen_sing.cc:396
+msgid "Press GREEN to join!"
+msgstr "Appuyer sur VERT pour jouer !"
+
+#: ../game/screen_sing.cc:401
+msgid "Press SPACE to join drums!"
+msgstr "Appuyer sur ESPACE pour jouer avec une batterie !"
+
+#: ../game/screen_sing.cc:401
+msgid "KICK to join!"
+msgstr "Appuyer sur la PEDALE pour jouer !"
+
+#: ../game/screen_sing.cc:475
+msgid "   ENTER to skip instrumental break"
+msgstr "   \"Entrée\" pour passer l'instrumental"
+
+#: ../game/screen_sing.cc:476
+msgid "   Remember to wait for grading!"
+msgstr "   Restez pour votre classement !"
+
+#: ../game/screen_sing.cc:587
+msgid "No player!"
+msgstr "Aucun joueur n'a été trouvé !"
+
+#: ../game/screen_sing.cc:594
+msgid "Hit singer"
+msgstr "Superstar"
+
+#: ../game/screen_sing.cc:595
+msgid "Lead singer"
+msgstr "Soliste"
+
+#: ../game/screen_sing.cc:596 ../game/screen_sing.cc:602
+#: ../game/screen_sing.cc:608
+msgid "Rising star"
+msgstr "Etoile montante"
+
+#: ../game/screen_sing.cc:597 ../game/screen_sing.cc:603
+#: ../game/screen_sing.cc:609
+msgid "Amateur"
+msgstr "Amateur"
+
+#: ../game/screen_sing.cc:598 ../game/screen_sing.cc:610
+msgid "Tone deaf"
+msgstr "Casserole"
+
+#: ../game/screen_sing.cc:600
+msgid "Maniac"
+msgstr "Maniac"
+
+#: ../game/screen_sing.cc:601
+msgid "Hoofer"
+msgstr "Claquettiste"
+
+#: ../game/screen_sing.cc:604
+msgid "Loser"
+msgstr "Perdant"
+
+#: ../game/screen_sing.cc:606
+msgid "Virtuoso"
+msgstr "Virtuose"
+
+#: ../game/screen_sing.cc:607
+msgid "Rocker"
+msgstr "Rockeur"
+
+#: ../game/songs.cc:178
+msgid "show all songs"
+msgstr "Montrer tous les morceaux"
+
+#: ../game/songs.cc:179
+msgid "has dance"
+msgstr "Contient de la danse"
+
+#: ../game/songs.cc:180
+msgid "has vocals"
+msgstr "Contient du chant"
+
+#: ../game/songs.cc:181
+msgid "has duet"
+msgstr "Contient un mode duo"
+
+#: ../game/songs.cc:182
+msgid "has guitar"
+msgstr "Contient une guitare"
+
+#: ../game/songs.cc:183
+msgid "drums or keytar"
+msgstr "batterie ou keytar"
+
+#: ../game/songs.cc:184
+msgid "full band"
+msgstr "Groupe complet"
+
+#: ../game/songs.cc:212
+msgid "random order"
+msgstr "ordre aléatoire"
+
+#: ../game/songs.cc:213
+msgid "sorted by song"
+msgstr "classement par chanson"
+
+#: ../game/songs.cc:214
+msgid "sorted by artist"
+msgstr "classement par artiste"
+
+#: ../game/songs.cc:215
+msgid "sorted by edition"
+msgstr "classement par édition"
+
+#: ../game/songs.cc:216
+msgid "sorted by genre"
+msgstr "classement par genre"
+
+#: ../game/songs.cc:217
+msgid "sorted by path"
+msgstr "classement par chemin"
+
+#: ../game/songs.cc:218
+msgid "sorted by language"
+msgstr "classement par langue"
+
+#: ../game/screen_intro.cc:24
+msgid "No playback devices could be used.\n"
+msgstr "Aucun périphérique audio de sortie n'est utilisable.\n"
+
+#: ../game/screen_intro.cc:25
+msgid ""
+"\n"
+"Please configure some before playing."
+msgstr ""
+"\n"
+"Veuillez les configurer avant de jouer."
+
+#: ../game/screen_intro.cc:69
+msgid "Settings saved as system defaults."
+msgstr "Configuration enregistrée comme configuration par défaut."
+
+#: ../game/screen_intro.cc:69
+msgid "Settings saved."
+msgstr "Configuration enregistrée."
+
+#: ../game/screen_intro.cc:149
+msgid "Ctrl + S to save, Ctrl + R to reset defaults"
+msgstr "Ctrl + S pour sauvegarder, Ctrl + R pour réinitialiser"
+
+#: ../game/screen_intro.cc:166
+msgid "Perform"
+msgstr "Jouer"
+
+#: ../game/screen_intro.cc:166 ../game/guitargraph.cc:194
+#: ../game/dancegraph.cc:107
+msgid "Start performing!"
+msgstr "Commencer une partie !"
+
+#: ../game/screen_intro.cc:167
+msgid "Practice"
+msgstr "S'exercer"
+
+#: ../game/screen_intro.cc:167
+msgid "Check your skills or test the microphones"
+msgstr "Chauffer votre voix et tester les micros"
+
+#: ../game/screen_intro.cc:183
+msgid "Configure"
+msgstr "Options"
+
+#: ../game/screen_intro.cc:183
+msgid "Configure audio and game options"
+msgstr "Configurer les options de jeu"
+
+#: ../game/screen_intro.cc:184
+msgid "Leave the game"
+msgstr "Sortir du jeu"
+
+#: ../game/guitargraph.cc:14
+msgid "Kids"
+msgstr "Enfantin"
+
+#: ../game/guitargraph.cc:14 ../game/dancegraph.cc:18
+msgid "Easy"
+msgstr "Facile"
+
+#: ../game/guitargraph.cc:14 ../game/dancegraph.cc:18
+msgid "Medium"
+msgstr "Moyen"
+
+#: ../game/guitargraph.cc:14 ../game/dancegraph.cc:18
+msgid "Hard"
+msgstr "Difficile"
+
+#: ../game/guitargraph.cc:14
+msgid "Expert"
+msgstr "Expert"
+
+#: ../game/guitargraph.cc:163 ../game/dancegraph.cc:134
+msgid "Select difficulty"
+msgstr "Sélectionner la difficulté"
+
+#: ../game/guitargraph.cc:169 ../game/guitargraph.cc:186
+msgid "Lefty-mode"
+msgstr "Mode gaucher"
+
+#: ../game/guitargraph.cc:183 ../game/dancegraph.cc:118
+msgid "Select track"
+msgstr "Sélectionner la piste"
+
+#: ../game/guitargraph.cc:194 ../game/dancegraph.cc:107
+msgid "Ready!"
+msgstr "Prêt !"
+
+#: ../game/guitargraph.cc:207
+msgid "ON"
+msgstr "Activé"
+
+#: ../game/guitargraph.cc:207
+msgid "OFF"
+msgstr "Désactivé"
+
+#: ../game/guitargraph.cc:208
+msgid "Toggle lefty-mode"
+msgstr "Basculer en mode gaucher"
+
+#: ../game/guitargraph.cc:447 ../game/dancegraph.cc:321
+msgid "Streak!"
+msgstr "d'affilées !"
+
+#: ../game/guitargraph.cc:459
+msgid ""
+"God Mode\n"
+"Activated!"
+msgstr ""
+"God Mode\n"
+"Activé"
+
+#: ../game/guitargraph.cc:460
+msgid "Mistakes ignored!"
+msgstr "Erreurs ignorées !"
+
+#: ../game/guitargraph.cc:1102
+msgid "God Mode Ready!"
+msgstr "God Mode Prêt !"
+
+#: ../game/guitargraph.cc:1103
+msgid "Drum Fill!"
+msgstr "Solo Batterie"
+
+#: ../game/guitargraph.cc:1106
+msgid "Solo!"
+msgstr "Solo !"
+
+#: ../game/configuration.cc:112
+msgid "Enabled"
+msgstr "Activé"
+
+#: ../game/configuration.cc:112
+msgid "Disabled"
+msgstr "Désactivé"
+
+#: ../game/configuration.cc:116
+#, c-format
+msgid "%d items"
+msgstr "%d entrées"
+
+#: ../game/screen_songs.cc:278
+msgid "Sorry, no songs match the search!"
+msgstr "Désolé, aucun morceau ne correspond à cette recherche !"
+
+#: ../game/screen_songs.cc:281
+msgid "Sorry, no songs match the filter!"
+msgstr "Désolé, aucun morceau ne correspond à ce filtre !"
+
+#: ../game/screen_songs.cc:284
+msgid "No songs found!"
+msgstr "Aucun morceau trouvé !"
+
+#: ../game/screen_songs.cc:285
+msgid "Visit performous.org for free songs"
+msgstr "Visitez performous.org pour des morceaux gratuits"
+
+#: ../game/screen_songs.cc:303
+msgid "<type in to search>"
+msgstr "<Entrez votre recherche>"
+
+#: ../game/screen_songs.cc:303
+msgid "songs"
+msgstr "morceaux"
+
+#: ../game/screen_songs.cc:303
+msgid "options"
+msgstr "options"
+
+#: ../game/screen_songs.cc:305
+msgid "sort order: "
+msgstr "ordre :"
+
+#: ../game/screen_songs.cc:306
+msgid "type filter: "
+msgstr "filtre :"
+
+#: ../game/screen_songs.cc:307
+msgid "hiscores"
+msgstr "Records"
+
+#: ../game/screen_songs.cc:307
+msgid "jukebox mode"
+msgstr "Mode jukebox"
+
+#: ../game/screen_songs.cc:310
+msgid "start a playlist with this song!"
+msgstr "Commencer une liste de lecture avec ce morceau !"
+
+#: ../game/screen_songs.cc:310
+msgid "open the playlist menu"
+msgstr "ouvrir le menu de listes de lecture"
+
+#: ../game/screen_songs.cc:502
+msgid "Play"
+msgstr "Jouer"
+
+#: ../game/screen_songs.cc:509 ../game/screen_playlist.cc:119
+msgid "Shuffle"
+msgstr "Aléatoire"
+
+#: ../game/screen_songs.cc:515
+msgid "View playlist"
+msgstr "Voir la liste de lecture"
+
+#: ../game/screen_songs.cc:516
+msgid "Clear playlist"
+msgstr "Vider la liste de lecture"
+
+#: ../game/screen_songs.cc:522 ../game/screen_playlist.cc:131
+#: ../game/screen_playlist.cc:275
+msgid "Back"
+msgstr "Précédent"
+
+#: ../game/screen_players.cc:115
+msgid "No players found!"
+msgstr "Aucun joueur n'a été trouvé !"
+
+#: ../game/screen_players.cc:116
+msgid "Enter a name to create a new player."
+msgstr "Entrez un nom pour créer un nouveau joueur."
+
+#: ../game/screen_players.cc:118
+msgid "Press enter to create player!"
+msgstr "Pressez Entrer pour créer un nouveau joueur !"
+
+#: ../game/screen_players.cc:122
+msgid "No players worth mentioning!"
+msgstr "Pas de joueur digne de ce nom !"
+
+#: ../game/screen_players.cc:127
+msgid "You reached %1% points!"
+msgstr "%1% points marqués !"
+
+#: ../game/screen_players.cc:128
+msgid "Change player with arrow keys."
+msgstr "Changez de joueur avec les flèches."
+
+#: ../game/screen_players.cc:129
+msgid "Name:"
+msgstr "Nom :"
+
+#: ../game/screen_players.cc:132
+msgid "Type text to filter or create a new player."
+msgstr "Entrez un nom pour créer un nouveau joueur."
+
+#: ../game/screen_players.cc:132
+msgid "Search Text:"
+msgstr "Recherche :"
+
+#: ../game/main.cc:145
+msgid "Loading audio samples..."
+msgstr "Chargement des samples..."
+
+#: ../game/main.cc:159
+msgid "Creating screens..."
+msgstr "Création des écrans..."
+
+#: ../game/main.cc:169
+msgid "Entering main menu"
+msgstr "Entrée dans le menu principal..."
+
+#: ../game/main.cc:182
+msgid "Screenshot taken!"
+msgstr "Capture d'écran effectuée"
+
+#: ../game/main.cc:185
+msgid "Screenshot failed!"
+msgstr "Echec de la capture d'écran"
+
+#: ../game/screen_playlist.cc:110 ../game/screen_playlist.cc:252
+msgid "Continue"
+msgstr "Continuer"
+
+#: ../game/screen_playlist.cc:110
+msgid "Continue playing"
+msgstr "Continuer à jouer"
+
+#: ../game/screen_playlist.cc:118
+msgid "Add songs"
+msgstr "Ajouter des morceaux"
+
+#: ../game/screen_playlist.cc:118
+msgid "Open the song browser to add more songs"
+msgstr "Ouvrir le navigateur de morceaux pour ajouter plus de morceaux"
+
+#: ../game/screen_playlist.cc:119
+msgid "Randomize the order of the playlist"
+msgstr "Mélanger l'ordre de la liste de lecture"
+
+#: ../game/screen_playlist.cc:125
+msgid "Clear and exit"
+msgstr "Vider et quitter"
+
+#: ../game/screen_playlist.cc:125
+msgid "Remove all the songs from the list"
+msgstr "Enlever l'ensemble des morceaux de la liste"
+
+#: ../game/screen_playlist.cc:131 ../game/screen_playlist.cc:275
+msgid "Back to playlist viewer"
+msgstr "Retourner à la liste de lecture"
+
+#: ../game/screen_playlist.cc:237
+msgid "Press enter to view song options"
+msgstr "Appuyer sur ENTREE pour voir les options du morceau"
+
+#: ../game/screen_playlist.cc:244
+msgid "View more options"
+msgstr "Voir plus d'options"
+
+#: ../game/screen_playlist.cc:244
+msgid "View general playlist settings"
+msgstr "Configurer les options de la liste de lecture"
+
+#: ../game/screen_playlist.cc:252
+msgid "Play first"
+msgstr "Jouer en premier"
+
+#: ../game/screen_playlist.cc:254
+msgid "Ignore the playlist's order and play this song first"
+msgstr "Ignorer l'ordre de la liste de lecture et jouer ce morceau en premier"
+
+#: ../game/screen_playlist.cc:255
+msgid "Start the song already!"
+msgstr "Démarre-le ce morceau !"
+
+#: ../game/screen_playlist.cc:264
+msgid "Remove"
+msgstr "Enlever"
+
+#: ../game/screen_playlist.cc:264
+msgid "Remove this song from the list"
+msgstr "Enlever ce morceau de la liste"
+
+#: ../game/dancegraph.cc:18
+msgid "Beginner"
+msgstr "Débutant"
+
+#: ../game/dancegraph.cc:18
+msgid "Challenge"
+msgstr "Défi"
+
+#: ../game/dancegraph.cc:248
+msgid "STOP!"
+msgstr "STOP !"
+
+#: ../game/screen_paths.cc:24
+msgid ""
+"This tool is not yet available.\n"
+"Configure paths by adding them\n"
+"as command line parameters and\n"
+"then save them in configuration menu."
+msgstr ""
+"Cet outil n'est pas encore disponible.\n"
+"Configurez les chemins en les ajoutant\n"
+"à la ligne de commande et\n"
+"sauvegardez-les dans le menu de configuration."
+
+#: ../game/screen_paths.cc:70
+msgid "Press any key to exit."
+msgstr "Appuyer sur n'importe quelle touche pour quitter."
+
+#: ../game/screen_paths.cc:76
+msgid "Windows users can also use ConfigureSongDirectory.bat script."
+msgstr ""
+"Les utilisateurs de Windows peuvent aussi utiliser le script "
+"ConfigureSongDirectory.bat."
+
+#: ../game/instrumentgraph.cc:57
+msgid "Rejoin"
+msgstr "Rejoindre le jeu"
+
+#: ../game/instrumentgraph.cc:57
+msgid "Change selections"
+msgstr "Changer les paramètres"
+
+#: /tmp/xml2gettext.Ct75FJW52s:2
+msgid "Game"
+msgstr "Jeu"
+
+#: /tmp/xml2gettext.Ct75FJW52s:3
+msgid "Gameplay related options"
+msgstr "Configurer les options de jeu"
+
+#: /tmp/xml2gettext.Ct75FJW52s:4
+msgid "Graphic"
+msgstr "Graphique"
+
+#: /tmp/xml2gettext.Ct75FJW52s:5
+msgid "Configure rendering and video settings"
+msgstr "Configurer les options vidéos et graphiques"
+
+#: /tmp/xml2gettext.Ct75FJW52s:6
+msgid "Audio Devices"
+msgstr "Périphériques audio"
+
+#: /tmp/xml2gettext.Ct75FJW52s:7
+msgid "Setup microphones and playback"
+msgstr "Configurer les microphones et la sortie son"
+
+#: /tmp/xml2gettext.Ct75FJW52s:8
+msgid "Audio"
+msgstr "Audio"
+
+#: /tmp/xml2gettext.Ct75FJW52s:9
+msgid "Configure general audio settings"
+msgstr "Configurer les options audio"
+
+#: /tmp/xml2gettext.Ct75FJW52s:10
+msgid "Paths"
+msgstr "Chemins"
+
+#: /tmp/xml2gettext.Ct75FJW52s:11
+msgid "Setup song and data paths"
+msgstr "Configurer les chemins des morceaux et des données"
+
+#: /tmp/xml2gettext.Ct75FJW52s:12
+msgid "Karaoke mode"
+msgstr "Mode karaoké"
+
+#: /tmp/xml2gettext.Ct75FJW52s:13
+msgid "Hide pitch wave, notes and scoring."
+msgstr "Cache la hauteur chantée, les notes et le score."
+
+#: /tmp/xml2gettext.Ct75FJW52s:14
+msgid "Pitch waves"
+msgstr "Hauteur chantée"
+
+#: /tmp/xml2gettext.Ct75FJW52s:15
+msgid "Enable singing pitch display (when not in karaoke mode)."
+msgstr "Active l'affichage de la hauteur du chant (pas dans le mode karaoké)"
+
+#: /tmp/xml2gettext.Ct75FJW52s:16
+msgid "Theme"
+msgstr "Thème"
+
+#: /tmp/xml2gettext.Ct75FJW52s:17
+msgid "Name of the theme to use."
+msgstr "Nom du thème à utiliser"
+
+#: /tmp/xml2gettext.Ct75FJW52s:18
+msgid "Keyboard as guitar"
+msgstr "Guitare au clavier"
+
+#: /tmp/xml2gettext.Ct75FJW52s:19
+msgid "Enable keyboard as guitar (Frets on Fire mode)."
+msgstr "Activer la guitare au clavier (mode Frets on Fire)"
+
+#: /tmp/xml2gettext.Ct75FJW52s:20
+msgid "Keyboard as drumkit"
+msgstr "Batterie au clavier"
+
+#: /tmp/xml2gettext.Ct75FJW52s:21
+msgid "Enable keyboard as drumkit."
+msgstr "Activer la batterie au clavier"
+
+#: /tmp/xml2gettext.Ct75FJW52s:22
+msgid "Keyboard as dance pad"
+msgstr "Tapis de dance au clavier"
+
+#: /tmp/xml2gettext.Ct75FJW52s:23
+msgid "Enable keyboard as dance pad."
+msgstr "Activer le tapis de dance au clavier"
+
+#: /tmp/xml2gettext.Ct75FJW52s:24
+msgid "Keyboard as keytar"
+msgstr "Keytar au clavier"
+
+#: /tmp/xml2gettext.Ct75FJW52s:25
+msgid "Enable keyboard as keytar."
+msgstr "Activer le keytar au clavier"
+
+#: /tmp/xml2gettext.Ct75FJW52s:26
+msgid "Force controller A's type"
+msgstr "Forcer le contrôleur de type A"
+
+#: /tmp/xml2gettext.Ct75FJW52s:27
+msgid ""
+"Override autodetection and force the first controller to the given type."
+msgstr ""
+"Ignorer l'auto-détection et forcer le premier contrôleur à utiliser un "
+"certain type d'instrument."
+
+#: /tmp/xml2gettext.Ct75FJW52s:28
+msgid "Force controller B's type"
+msgstr "Forcer le contrôleur de type B"
+
+#: /tmp/xml2gettext.Ct75FJW52s:29
+msgid ""
+"Override autodetection and force the second controller to the given type."
+msgstr ""
+"Ignorer l'auto-détection et forcer le deuxième contrôleur à utiliser un "
+"certain type d'instrument."
+
+#: /tmp/xml2gettext.Ct75FJW52s:30
+msgid "Force controller C's type"
+msgstr "Forcer le contrôleur de type C"
+
+#: /tmp/xml2gettext.Ct75FJW52s:31
+msgid ""
+"Override autodetection and force the third controller to the given type."
+msgstr ""
+"Ignorer l'auto-détection et forcer le troisième contrôleur à utiliser un "
+"certain type d'instrument."
+
+#: /tmp/xml2gettext.Ct75FJW52s:32
+msgid "Force controller D's type"
+msgstr "Forcer le contrôleur de type D"
+
+#: /tmp/xml2gettext.Ct75FJW52s:33
+msgid ""
+"Override autodetection and force the fourth controller to the given type."
+msgstr ""
+"Ignorer l'auto-détection et forcer le quatrième contrôleur à utiliser un "
+"certain type d'instrument."
+
+#: /tmp/xml2gettext.Ct75FJW52s:34
+msgid "Joystick configuration"
+msgstr "Configuration des manettes"
+
+#: /tmp/xml2gettext.Ct75FJW52s:35
+msgid "Force joystick to some kind of instrument."
+msgstr "Attribuer de force une manette à un type d'instrument."
+
+#: /tmp/xml2gettext.Ct75FJW52s:36
+msgid "Hardware MIDI input device"
+msgstr "Périphérique MIDI d'entrée"
+
+#: /tmp/xml2gettext.Ct75FJW52s:37
+msgid ""
+"Regex for matching the MIDI devices to use. The default is to use all "
+"available devices."
+msgstr ""
+"Expression régulière pour sélectionner le périphérique MIDI à utiliser. Par "
+"défaut utiliser tous les périphériques disponibles."
+
+#: /tmp/xml2gettext.Ct75FJW52s:38
+msgid "Fallback song encoding"
+msgstr "Encodage des morceaux de secours"
+
+#: /tmp/xml2gettext.Ct75FJW52s:39
+msgid "Pick the text codec used for song files that are not UTF-8."
+msgstr "Choisir l'encodage utilisé pour les morceaux qui ne sont pas en UTF-8."
+
+#: /tmp/xml2gettext.Ct75FJW52s:40
+msgid "Windowed width"
+msgstr "Largeur de la fenêtre"
+
+#: /tmp/xml2gettext.Ct75FJW52s:41
+msgid "The width of the window."
+msgstr "La largeur de la fenêtre"
+
+#: /tmp/xml2gettext.Ct75FJW52s:42
+msgid "Windowed height"
+msgstr "Hauteur de la fenêtre"
+
+#: /tmp/xml2gettext.Ct75FJW52s:43
+msgid "The height of the window."
+msgstr "La hauteur de la fenêtre"
+
+#: /tmp/xml2gettext.Ct75FJW52s:44
+msgid "Fullscreen mode"
+msgstr "Mode plein écran"
+
+#: /tmp/xml2gettext.Ct75FJW52s:45
+msgid "Enable fullscreen mode on startup."
+msgstr "Activer le mode plein écran au démarage"
+
+#: /tmp/xml2gettext.Ct75FJW52s:46
+msgid "Stereoscopic 3D"
+msgstr "Stéréoscopie"
+
+#: /tmp/xml2gettext.Ct75FJW52s:47
+msgid "Enable 3D rendering of Performous."
+msgstr "Activer le rendu 3D stéréoscopique"
+
+#: /tmp/xml2gettext.Ct75FJW52s:48
+msgid "Stereo3D type"
+msgstr "Type de rendu stéréoscopique"
+
+#: /tmp/xml2gettext.Ct75FJW52s:49
+msgid "Some modes may only get activated in fullscreen mode."
+msgstr "Certains modes ne peuvent être activés qu'en plein écran."
+
+#: /tmp/xml2gettext.Ct75FJW52s:50
+msgid "Stereo3D separation"
+msgstr "Séparation Stereo3D"
+
+#: /tmp/xml2gettext.Ct75FJW52s:51
+msgid ""
+"The strength of the effect. Experiment with different settings for best "
+"results."
+msgstr ""
+"Espacement des deux images stéréoscopiques. Essayez plusieurs valeurs pour "
+"obtenir le meilleur résultat."
+
+#: /tmp/xml2gettext.Ct75FJW52s:52
+msgid "Video playback"
+msgstr "Vidéo playback"
+
+#: /tmp/xml2gettext.Ct75FJW52s:53
+msgid ""
+"Allows completely disabling background videos. It is recommended to leave "
+"this enabled as Performous will still smoothly fade out the video if your "
+"computer is not fast enough."
+msgstr ""
+"Permet de désactiver toutes les vidéos. Il est recommandé de garder cette "
+"option activée car Performous va automatiquement désactiver la vidéo en cas "
+"de problème de performances de votre ordinateur."
+
+#: /tmp/xml2gettext.Ct75FJW52s:54
+msgid "Webcam background"
+msgstr "Webcam en fond d'écran"
+
+#: /tmp/xml2gettext.Ct75FJW52s:55
+msgid ""
+"Performous can use webcam as a background video. Disable it if Performous "
+"crashes while entering a song."
+msgstr ""
+"Performous peut essayer d'utiliser une webcam comme vidéo. Désactivez en cas "
+"de crash."
+
+#: /tmp/xml2gettext.Ct75FJW52s:56
+msgid "Webcam id"
+msgstr "Id de la webcam"
+
+#: /tmp/xml2gettext.Ct75FJW52s:57
+msgid ""
+"Use -1 to autodetect or a number starting from 0 to choose specific device."
+msgstr ""
+"Utilisez -1 pour l'autodétection ou un numéro en partant de 0 pour choisir "
+"un périphérique spécifique."
+
+#: /tmp/xml2gettext.Ct75FJW52s:58
+msgid "SVG quality"
+msgstr "Qualité SVG"
+
+#: /tmp/xml2gettext.Ct75FJW52s:59
+msgid ""
+"Larger numbers cause vector graphics to be rendered in higher resolution. "
+"Decrease this to make navigating in menus faster."
+msgstr ""
+"Les grandes valeurs génèrent les images vectorielles en haute résolution. "
+"Diminuez cette valeur en cas de problèmes de performance."
+
+#: /tmp/xml2gettext.Ct75FJW52s:60
+msgid "Text quality"
+msgstr "Qualité des textes"
+
+#: /tmp/xml2gettext.Ct75FJW52s:61
+msgid ""
+"Larger numbers cause text to be rendered in higher resolution. Decrease this "
+"to make everything a little faster."
+msgstr ""
+"Les grandes valeurs génèrent les textes en haute résolution. Diminuez cette "
+"valeur en cas de problèmes de performance."
+
+#: /tmp/xml2gettext.Ct75FJW52s:62
+msgid "Benchmark mode"
+msgstr "Mode perfomance"
+
+#: /tmp/xml2gettext.Ct75FJW52s:63
+msgid ""
+"Framerate limit of 100 FPS is removed and the game instead renders at full "
+"speed. FPS values are printed to console. Please note that the display "
+"drivers may still limit the rendering speed to the screen refresh rate."
+msgstr ""
+"La limite de 100 FPS est supprimée et le jeu tourne à vitesse maximale. Les "
+"FPS sont affichées dans la console. Veuillez noter que le driver peut "
+"néanmoins limiter la vitesse au taux de rafraîchissement."
+
+#: /tmp/xml2gettext.Ct75FJW52s:64
+msgid "Suggested latency"
+msgstr "Latence suggérée"
+
+#: /tmp/xml2gettext.Ct75FJW52s:65
+msgid ""
+"This is a hint for the audio engine about the desired latency. Set this as "
+"low as possible while retaining clear audio playback. Requires restart."
+msgstr ""
+"Ceci est une aide donnée au moteur audio pour la latence souhaitée. Choisir "
+"la valeur la plus petite possible sans que cela ne nuise à la qualité audio. "
+"Redémarrez."
+
+#: /tmp/xml2gettext.Ct75FJW52s:66
+msgid "Audio/video latency"
+msgstr "Latence audio/vidéo"
+
+#: /tmp/xml2gettext.Ct75FJW52s:67
+msgid ""
+"Affects all modes. Use negative value if your display input lag is greater "
+"than the sound card output latency, positive values in the opposite case and "
+"zero if they are equal. This should be set so that the notes pass the cursor "
+"at the same time the audio is heard. Use Ctrl+F1/F2 to adjust this while "
+"performing."
+msgstr ""
+"Affecte tous les modes. Choisissez une valeur négative si le lag entre "
+"l'entrée et l'affichage est plus important que la latence audio. Choisissez "
+"une valeur positive dans le cas opposé, et une valeur nulle s'ils sont "
+"égaux. Ajustez pour faire en sorte que les notes passent le curseur en "
+"rythme avec la musique. Utilisez Ctrl+F1/F2 pour l'ajuster pendant une "
+"chanson."
+
+#: /tmp/xml2gettext.Ct75FJW52s:68
+msgid "Audio round-trip latency"
+msgstr "Latence audio/audio"
+
+#: /tmp/xml2gettext.Ct75FJW52s:69
+msgid ""
+"Affects singing only. The time it takes for Performous playback to reach "
+"your speakers, fly to the microphone and all the way back until Performous "
+"captures and analyzes it. While performing, press Ctrl+S for synth mode and "
+"adjust with Ctrl+F3/F4."
+msgstr ""
+"Affecte uniquement la voix. Latence entre la capture du micro et le son des "
+"enceintes. Utilisez Ctrl+F3/F4 pour l'ajuster pendant une chanson"
+
+#: /tmp/xml2gettext.Ct75FJW52s:70
+msgid "Audio/controller latency"
+msgstr "Latence audio/controlleur"
+
+#: /tmp/xml2gettext.Ct75FJW52s:71
+msgid ""
+"Affects instruments and dancing only. The total of USB (guitar or dance pad) "
+"latency combined with audio output latency. Adjust so that you can hit the "
+"notes best when playing by ear (not looking on screen). Use Ctrl+F5/F6 to "
+"adjust while performing."
+msgstr ""
+"Affecte uniquement les instruments et les tapis de danse. Latence entre le "
+"périphérique USB et la sortie sonore. Utilisez Ctrl+F5/F6 pour l'ajuster "
+"pendant une chanson."
+
+#: /tmp/xml2gettext.Ct75FJW52s:72
+msgid "Audio devices"
+msgstr "Périphériques audio"
+
+#: /tmp/xml2gettext.Ct75FJW52s:73
+msgid "List of audio devices to try."
+msgstr "Liste des périphériques audio à tester."
+
+#: /tmp/xml2gettext.Ct75FJW52s:74
+msgid "Menu volume"
+msgstr "Volume du menu"
+
+#: /tmp/xml2gettext.Ct75FJW52s:75
+msgid "The volume level of menus, song previews and jukebox mode."
+msgstr ""
+"Le volume sonore des menus, de l'aperçu des chansons et du mode jukebox."
+
+#: /tmp/xml2gettext.Ct75FJW52s:76
+msgid "Music volume"
+msgstr "Volume de la musique"
+
+#: /tmp/xml2gettext.Ct75FJW52s:77
+msgid ""
+"The ingame music volume. Values above 90 are not recommended as distortion "
+"may occur."
+msgstr ""
+"Le volume de la musique pendant le jeu. Les valeurs supérieures à 90 ne sont "
+"pas recommandées (distorsion)."
+
+#: /tmp/xml2gettext.Ct75FJW52s:78
+msgid "Failure volume"
+msgstr "Volume des erreurs"
+
+#: /tmp/xml2gettext.Ct75FJW52s:79
+msgid ""
+"The ingame fail sound volume. Values above 90 are not recommended as "
+"distortion may occur. 11 is louder than 10, but these go to 100. 89 louder!"
+msgstr ""
+"Le volume des morceaux en cas d'erreur. Les valeurs supérieures à 90 ne sont "
+"pas recommandées (distorsion)."
+
+#: /tmp/xml2gettext.Ct75FJW52s:80
+msgid "Microphone pass-through"
+msgstr "Microphone \"pass-through\""
+
+#: /tmp/xml2gettext.Ct75FJW52s:81
+msgid "Send captured singing voice to speakers."
+msgstr "Envoyer la sortie des micros vers les haut-parleurs."
+
+#: /tmp/xml2gettext.Ct75FJW52s:82
+msgid "Pass-through volume ratio"
+msgstr "Volume du \"pass-through\""
+
+#: /tmp/xml2gettext.Ct75FJW52s:83
+msgid "How much voice is amplified compared to the music."
+msgstr ""
+"Quel est le niveau d'amplification des micros par rapport à la musique."
+
+#: /tmp/xml2gettext.Ct75FJW52s:84
+msgid "Song folders"
+msgstr "Répertoires des chansons"
+
+#: /tmp/xml2gettext.Ct75FJW52s:85
+msgid ""
+"Where to recursively look for songs. DATADIR at the beginning means all "
+"Performous data folders."
+msgstr ""
+"Où chercher récursivement pour des morceaux. DATADIR au début désigne tous "
+"les répertoires de données."
+
+#: /tmp/xml2gettext.Ct75FJW52s:86
+msgid "Base folders for data"
+msgstr "Répertoire de base pour les données"
+
+#: /tmp/xml2gettext.Ct75FJW52s:87
+msgid ""
+"System defaults are included automatically. Additional paths can be added "
+"here."
+msgstr ""
+"Les valeurs par défaut du système sont incluses automatiquement. D'autres "
+"chemins peuvent être ajoutés ici."
+
+#, fuzzy
+#~ msgid "Back to song browser"
+#~ msgstr "Quitter vers la liste des morceaux"
+
+#~ msgid "No Items up to now."
+#~ msgstr "Aucun élément jusqu'à présent"
+
+#~ msgid "Be the first to be listed here!"
+#~ msgstr "Soyez le premier à être listé ici!"
+
+#~ msgid "Guitar"
+#~ msgstr "Guitare"
+
+#~ msgid "Coop guitar"
+#~ msgstr "Guitare Coop"
+
+#~ msgid "Rhythm guitar"
+#~ msgstr "Guitare rythmique"
+
+#~ msgid "Bass"
+#~ msgstr "Basse"
+
+#~ msgid "Drums"
+#~ msgstr "Batterie"
+
+#~ msgid "Vocals"
+#~ msgstr "Voix principale"
+
+#~ msgid "Harmonic 1"
+#~ msgstr "Harmonique 1"
+
+#~ msgid "Harmonic 2"
+#~ msgstr "Harmonique 2"
+
+#~ msgid "Harmonic 3"
+#~ msgstr "Harmonique 3"
+
+#~ msgid "Song is broken!"
+#~ msgstr "Chanson cassée"
+
+#~ msgid "Loading instruments..."
+#~ msgstr "Chargement des instruments..."
+
+#~ msgid "Finalizing..."
+#~ msgstr "Finalisation"
+
+#, fuzzy
+#~ msgid "Loading graphics..."
+#~ msgstr "Chargement de la chanson..."
+
+#~ msgid "Random background..."
+#~ msgstr "Papier peint aléatoires..."
+
+#~ msgid "(press END to view hiscores)"
+#~ msgstr "(presser Fin pour voir le classement)"
+
+#~ msgid "Graphics"
+#~ msgstr "Graphiques"
+
+#~ msgid "Gameplay settings."
+#~ msgstr "Options de jeu"
+
+#~ msgid "Video and rendering settings."
+#~ msgstr "Options vidéo et de rendu"
+
+#~ msgid "Audio-related settings."
+#~ msgstr "Options audio"
+
+#~ msgid "System paths."
+#~ msgstr "Chemins système"
+
+#~ msgid ""
+#~ "Part of sound card name or its number or empty to use the first available "
+#~ "device. Used currently for MIDI drum controllers."
+#~ msgstr ""
+#~ "Partie du nom de la carte son ou son numéro ou vide pour utiliser la "
+#~ "première disponible. Utilisé pour les batteries MIDI pour le moment."
+
+#~ msgid "3D notes"
+#~ msgstr "Notes 3D"
+
+#~ msgid ""
+#~ "Draw instrument notes as 3-dimensional objects. May hurt performance on "
+#~ "older hardware."
+#~ msgstr "Dessinne les notes des instruments en 3D"
+
+#~ msgid "Loading theme..."
+#~ msgstr "Chargement du thème..."
+
+#~ msgid "Loading background..."
+#~ msgstr "Chargement du fond d'écran..."
+
+#~ msgid "Loading user interface..."
+#~ msgstr "Chargement de l'interface utilisateur..."
+
+#~ msgid "Audio..."
+#~ msgstr "Audio..."
+
+#~ msgid "Launching background loaders..."
+#~ msgstr "Lancement des chargements en arrière plan..."
diff --git a/lang/hu.po b/lang/hu.po
new file mode 100644 (file)
index 0000000..47cd40e
--- /dev/null
@@ -0,0 +1,717 @@
+#
+# Gegsite <gegsite@freemail.hu>, 2010.
+msgid ""
+msgstr ""
+"Project-Id-Version: Performous\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2013-05-24 12:47+0100\n"
+"PO-Revision-Date: 2013-05-24 12:47+0100\n"
+"Last-Translator: Tapio Vierros <tapiovierros@gmail.com>\n"
+"Language-Team: Hungarian <>\n"
+"Language: hu\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"X-Poedit-KeywordsList: _\n"
+"X-Poedit-Basepath: .\n"
+"X-Generator: Poedit 1.5.4\n"
+"X-Poedit-SearchPath-0: ../game\n"
+"X-Poedit-SearchPath-1: ../data\n"
+
+#: ../game/screen_paths.cc:24
+msgid ""
+"This tool is not yet available.\n"
+"Configure paths by adding them\n"
+"as command line parameters and\n"
+"then save them in configuration menu."
+msgstr ""
+
+#: ../game/screen_paths.cc:70
+msgid "Press any key to exit."
+msgstr ""
+
+#: ../game/screen_paths.cc:75
+msgid ""
+"Windows users can also use ConfigureSongDirectory.bat in the bin-directory."
+msgstr ""
+
+#: ../game/configuration.cc:117
+msgid "Enabled"
+msgstr ""
+
+#: ../game/configuration.cc:117
+msgid "Disabled"
+msgstr ""
+
+#: ../game/configuration.cc:121
+#, c-format
+msgid "%d items"
+msgstr ""
+
+#: ../game/instrumentgraph.cc:56 ../game/screen_sing.cc:123
+msgid "Resume"
+msgstr ""
+
+#: ../game/instrumentgraph.cc:56 ../game/screen_sing.cc:123
+#, fuzzy
+msgid "Back to performing!"
+msgstr "Kezd az előadást!"
+
+#: ../game/instrumentgraph.cc:57
+msgid "Rejoin"
+msgstr ""
+
+#: ../game/instrumentgraph.cc:57
+msgid "Change selections"
+msgstr ""
+
+#: ../game/instrumentgraph.cc:58 ../game/screen_sing.cc:124
+msgid "Restart"
+msgstr ""
+
+#: ../game/instrumentgraph.cc:58 ../game/screen_sing.cc:124
+msgid ""
+"Start the song\n"
+"from the beginning"
+msgstr ""
+
+#: ../game/instrumentgraph.cc:59 ../game/guitargraph.cc:200
+#: ../game/screen_intro.cc:184 ../game/dancegraph.cc:137
+#: ../game/screen_sing.cc:92 ../game/screen_sing.cc:126
+msgid "Quit"
+msgstr "Kilépés"
+
+#: ../game/instrumentgraph.cc:59 ../game/guitargraph.cc:200
+#: ../game/dancegraph.cc:137 ../game/screen_sing.cc:92
+#: ../game/screen_sing.cc:126
+msgid "Exit to song browser"
+msgstr ""
+
+#: ../game/guitargraph.cc:14
+msgid "Kids"
+msgstr ""
+
+#: ../game/guitargraph.cc:14 ../game/dancegraph.cc:18
+msgid "Easy"
+msgstr ""
+
+#: ../game/guitargraph.cc:14 ../game/dancegraph.cc:18
+msgid "Medium"
+msgstr ""
+
+#: ../game/guitargraph.cc:14 ../game/dancegraph.cc:18
+msgid "Hard"
+msgstr ""
+
+#: ../game/guitargraph.cc:14
+msgid "Expert"
+msgstr ""
+
+#: ../game/guitargraph.cc:163 ../game/dancegraph.cc:134
+msgid "Select difficulty"
+msgstr ""
+
+#: ../game/guitargraph.cc:169 ../game/guitargraph.cc:186
+msgid "Lefty-mode"
+msgstr ""
+
+#: ../game/guitargraph.cc:183 ../game/dancegraph.cc:118
+msgid "Select track"
+msgstr ""
+
+#: ../game/guitargraph.cc:194 ../game/dancegraph.cc:107
+msgid "Ready!"
+msgstr ""
+
+#: ../game/guitargraph.cc:194 ../game/screen_intro.cc:166
+#: ../game/dancegraph.cc:107
+msgid "Start performing!"
+msgstr "Kezd az előadást!"
+
+#: ../game/guitargraph.cc:207
+msgid "ON"
+msgstr ""
+
+#: ../game/guitargraph.cc:207
+msgid "OFF"
+msgstr ""
+
+#: ../game/guitargraph.cc:208
+msgid "Toggle lefty-mode"
+msgstr ""
+
+#: ../game/guitargraph.cc:447 ../game/dancegraph.cc:319
+msgid "Streak!"
+msgstr ""
+
+#: ../game/guitargraph.cc:459
+msgid ""
+"God Mode\n"
+"Activated!"
+msgstr ""
+
+#: ../game/guitargraph.cc:460
+msgid "Mistakes ignored!"
+msgstr ""
+
+#: ../game/guitargraph.cc:1102
+msgid "God Mode Ready!"
+msgstr ""
+
+#: ../game/guitargraph.cc:1103
+msgid "Drum Fill!"
+msgstr ""
+
+#: ../game/guitargraph.cc:1106
+msgid "Solo!"
+msgstr ""
+
+#: ../game/songs.cc:194
+msgid "show all songs"
+msgstr ""
+
+#: ../game/songs.cc:195
+msgid "has dance"
+msgstr ""
+
+#: ../game/songs.cc:196
+msgid "has vocals"
+msgstr ""
+
+#: ../game/songs.cc:197
+msgid "has duet"
+msgstr ""
+
+#: ../game/songs.cc:198
+#, fuzzy
+msgid "has guitar"
+msgstr "Kilépés"
+
+#: ../game/songs.cc:199
+msgid "drums or keytar"
+msgstr ""
+
+#: ../game/songs.cc:200
+msgid "full band"
+msgstr ""
+
+#: ../game/songs.cc:228
+msgid "random order"
+msgstr "Véletlen elrendezés"
+
+#: ../game/songs.cc:229
+msgid "sorted by song"
+msgstr "Zeneszám alapján"
+
+#: ../game/songs.cc:230
+msgid "sorted by artist"
+msgstr "Előadó alapján"
+
+#: ../game/songs.cc:231
+msgid "sorted by edition"
+msgstr "Kivitel alapján"
+
+#: ../game/songs.cc:232
+msgid "sorted by genre"
+msgstr "Kategória alapján"
+
+#: ../game/songs.cc:233
+msgid "sorted by path"
+msgstr "Elérési út alapján"
+
+#: ../game/songs.cc:234
+msgid "sorted by language"
+msgstr "Nyelv alapján"
+
+#: ../game/screen_intro.cc:24
+msgid "No playback devices could be used.\n"
+msgstr "Nem találtam használható lejátszó eszközt.\n"
+
+#: ../game/screen_intro.cc:25
+msgid ""
+"\n"
+"Please configure some before playing."
+msgstr ""
+"\n"
+"Állíts be egy-két dolgot a játék előtt."
+
+#: ../game/screen_intro.cc:69
+msgid "Settings saved as system defaults."
+msgstr ""
+
+#: ../game/screen_intro.cc:69
+msgid "Settings saved."
+msgstr ""
+
+#: ../game/screen_intro.cc:149
+msgid "Ctrl + S to save, Ctrl + R to reset defaults"
+msgstr ""
+
+#: ../game/screen_intro.cc:166
+msgid "Perform"
+msgstr "Előadás"
+
+#: ../game/screen_intro.cc:167
+msgid "Practice"
+msgstr "Gyakorlás"
+
+#: ../game/screen_intro.cc:167
+msgid "Check your skills or test the microphones"
+msgstr "Énekelj és ellenőrizd a mikrofont"
+
+#: ../game/screen_intro.cc:183
+msgid "Configure"
+msgstr "Beállítás"
+
+#: ../game/screen_intro.cc:183
+#, fuzzy
+msgid "Configure audio and game options"
+msgstr "Játék beállítások"
+
+#: ../game/screen_intro.cc:184
+msgid "Leave the game"
+msgstr "Játék abbahagyása"
+
+#: ../game/dancegraph.cc:18
+msgid "Beginner"
+msgstr ""
+
+#: ../game/dancegraph.cc:18
+msgid "Challenge"
+msgstr ""
+
+#: ../game/dancegraph.cc:248
+msgid "STOP!"
+msgstr ""
+
+#: ../game/screen_playlist.cc:110 ../game/screen_playlist.cc:252
+msgid "Continue"
+msgstr ""
+
+#: ../game/screen_playlist.cc:110
+msgid "Continue playing"
+msgstr ""
+
+#: ../game/screen_playlist.cc:118
+msgid "Add songs"
+msgstr ""
+
+#: ../game/screen_playlist.cc:118
+msgid "Open the song browser to add more songs"
+msgstr ""
+
+#: ../game/screen_playlist.cc:119 ../game/screen_songs.cc:513
+msgid "Shuffle"
+msgstr ""
+
+#: ../game/screen_playlist.cc:119 ../game/screen_songs.cc:513
+msgid "Randomize the order of the playlist"
+msgstr ""
+
+#: ../game/screen_playlist.cc:125
+msgid "Clear and exit"
+msgstr ""
+
+#: ../game/screen_playlist.cc:125 ../game/screen_songs.cc:520
+msgid "Remove all the songs from the list"
+msgstr ""
+
+#: ../game/screen_playlist.cc:131 ../game/screen_playlist.cc:275
+#: ../game/screen_songs.cc:526
+msgid "Back"
+msgstr ""
+
+#: ../game/screen_playlist.cc:131 ../game/screen_playlist.cc:275
+msgid "Back to playlist viewer"
+msgstr ""
+
+#: ../game/screen_playlist.cc:237
+msgid "Press enter to view song options"
+msgstr ""
+
+#: ../game/screen_playlist.cc:244
+msgid "View more options"
+msgstr ""
+
+#: ../game/screen_playlist.cc:244
+#, fuzzy
+msgid "View general playlist settings"
+msgstr "Játék beállítások"
+
+#: ../game/screen_playlist.cc:252
+msgid "Play first"
+msgstr ""
+
+#: ../game/screen_playlist.cc:254
+msgid "Ignore the playlist's order and play this song first"
+msgstr ""
+
+#: ../game/screen_playlist.cc:255
+msgid "Start the song already!"
+msgstr ""
+
+#: ../game/screen_playlist.cc:264
+msgid "Remove"
+msgstr ""
+
+#: ../game/screen_playlist.cc:264
+msgid "Remove this song from the list"
+msgstr ""
+
+#: ../game/main.cc:146
+msgid "Loading audio samples..."
+msgstr ""
+
+#: ../game/main.cc:160
+msgid "Creating screens..."
+msgstr ""
+
+#: ../game/main.cc:170
+msgid "Entering main menu"
+msgstr ""
+
+#: ../game/main.cc:172 ../game/screen_sing.cc:97
+msgid "Loading complete"
+msgstr ""
+
+#: ../game/main.cc:183
+msgid "Screenshot taken!"
+msgstr "Képernyőkép elkészült!"
+
+#: ../game/main.cc:186
+msgid "Screenshot failed!"
+msgstr "Képernyőkép nem sikerült!"
+
+#: ../game/screen_sing.cc:45
+msgid "Initializing webcam..."
+msgstr ""
+
+#: ../game/screen_sing.cc:52
+msgid "Loading video..."
+msgstr ""
+
+#: ../game/screen_sing.cc:59
+msgid "Loading song..."
+msgstr ""
+
+#: ../game/screen_sing.cc:66
+msgid "Song contains broken tracks!"
+msgstr ""
+
+#: ../game/screen_sing.cc:71
+#, fuzzy
+msgid "Loading menu..."
+msgstr "Főmenü …"
+
+#: ../game/screen_sing.cc:76
+msgid "Start"
+msgstr ""
+
+#: ../game/screen_sing.cc:76
+#, fuzzy
+msgid "Start performing"
+msgstr "Kezd az előadást!"
+
+#: ../game/screen_sing.cc:80
+msgid "Duet mode"
+msgstr ""
+
+#: ../game/screen_sing.cc:81
+msgid "Normal mode"
+msgstr ""
+
+#: ../game/screen_sing.cc:82
+msgid "Switch between duet and regular singing mode"
+msgstr ""
+
+#: ../game/screen_sing.cc:90
+msgid "Change vocal track"
+msgstr ""
+
+#: ../game/screen_sing.cc:125
+msgid "Skip"
+msgstr ""
+
+#: ../game/screen_sing.cc:125
+msgid "Skip current song"
+msgstr ""
+
+#: ../game/screen_sing.cc:391
+msgid "Press UP to join dance!"
+msgstr ""
+
+#: ../game/screen_sing.cc:391
+msgid "Step UP to join!"
+msgstr ""
+
+#: ../game/screen_sing.cc:396
+msgid "Press 1 to join guitar!"
+msgstr ""
+
+#: ../game/screen_sing.cc:396
+msgid "Press GREEN to join!"
+msgstr ""
+
+#: ../game/screen_sing.cc:401
+msgid "Press SPACE to join drums!"
+msgstr ""
+
+#: ../game/screen_sing.cc:401
+msgid "KICK to join!"
+msgstr ""
+
+#: ../game/screen_sing.cc:475
+msgid "   ENTER to skip instrumental break"
+msgstr "Nyomj ENTER-et a zenei rész átugrásához"
+
+#: ../game/screen_sing.cc:476
+msgid "   Remember to wait for grading!"
+msgstr "Ne feledd a besorolást megvárni!"
+
+#: ../game/screen_sing.cc:587
+msgid "No player!"
+msgstr "Nincs játékos!"
+
+#: ../game/screen_sing.cc:594
+msgid "Hit singer"
+msgstr "Kiváló énekes"
+
+#: ../game/screen_sing.cc:595
+msgid "Lead singer"
+msgstr "Szólista"
+
+#: ../game/screen_sing.cc:596 ../game/screen_sing.cc:602
+#: ../game/screen_sing.cc:608
+msgid "Rising star"
+msgstr "Születő csillag"
+
+#: ../game/screen_sing.cc:597 ../game/screen_sing.cc:603
+#: ../game/screen_sing.cc:609
+msgid "Amateur"
+msgstr "Amatőr"
+
+#: ../game/screen_sing.cc:598 ../game/screen_sing.cc:610
+msgid "Tone deaf"
+msgstr "Botfülű"
+
+#: ../game/screen_sing.cc:600
+msgid "Maniac"
+msgstr "Mániákus"
+
+#: ../game/screen_sing.cc:601
+msgid "Hoofer"
+msgstr "Profi táncos"
+
+#: ../game/screen_sing.cc:604
+msgid "Loser"
+msgstr "Vesztes"
+
+#: ../game/screen_sing.cc:606
+msgid "Virtuoso"
+msgstr "Virtuóz"
+
+#: ../game/screen_sing.cc:607
+msgid "Rocker"
+msgstr "Rockker"
+
+#: ../game/screen_songs.cc:279
+msgid "No songs found!"
+msgstr "Zenét nem találtam!"
+
+#: ../game/screen_songs.cc:280
+msgid ""
+"Visit performous.org\n"
+"for free songs"
+msgstr ""
+"Látogass el a performous.org -ra\n"
+"ingyenes zenékért"
+
+#: ../game/screen_songs.cc:282
+#, fuzzy
+msgid "Sorry, no songs match the search!"
+msgstr "A keresett zene nem található"
+
+#: ../game/screen_songs.cc:289
+#, fuzzy
+msgid "Hiscore\n"
+msgstr "Pontozás %1!\n"
+
+#: ../game/screen_songs.cc:298
+msgid "<type in to search>   ↔ songs    ↕ options"
+msgstr ""
+
+#: ../game/screen_songs.cc:301
+msgid "↔ sort order: "
+msgstr ""
+
+#: ../game/screen_songs.cc:302
+msgid "↔ type filter: "
+msgstr ""
+
+#: ../game/screen_songs.cc:303
+msgid "↔ hiscores   ↵ jukebox mode"
+msgstr ""
+
+#: ../game/screen_songs.cc:307
+msgid "↵ start a playlist with this song!"
+msgstr ""
+
+#: ../game/screen_songs.cc:309
+msgid "↵ open the playlist menu"
+msgstr ""
+
+#: ../game/screen_songs.cc:506
+msgid "Play"
+msgstr ""
+
+#: ../game/screen_songs.cc:506
+msgid "Start the game with all songs in playlist"
+msgstr ""
+
+#: ../game/screen_songs.cc:519
+msgid "View playlist"
+msgstr ""
+
+#: ../game/screen_songs.cc:519
+msgid "View the current playlist"
+msgstr ""
+
+#: ../game/screen_songs.cc:520
+msgid "Clear playlist"
+msgstr ""
+
+#: ../game/screen_songs.cc:526
+msgid "Back to song browser"
+msgstr ""
+
+#: ../game/screen_players.cc:115
+msgid "No players found!"
+msgstr "Nem találtam játékost!"
+
+#: ../game/screen_players.cc:116
+msgid "Enter a name to create a new player."
+msgstr "Írd be az új játékos nevét."
+
+#: ../game/screen_players.cc:118
+msgid "Press enter to create player!"
+msgstr "Nyomj ENTER-t a létrehozáshoz!"
+
+#: ../game/screen_players.cc:122
+#, fuzzy
+msgid "No players worth mentioning!"
+msgstr "Nem találtam játékost!"
+
+#: ../game/screen_players.cc:127
+msgid "You reached %1% points!"
+msgstr "%1% pontot kaptál!"
+
+#: ../game/screen_players.cc:128
+msgid "Change player with arrow keys."
+msgstr "Válts a nyilakkal játékost."
+
+#: ../game/screen_players.cc:129
+msgid "Name:"
+msgstr "Név:"
+
+#: ../game/screen_players.cc:132
+msgid "Type text to filter or create a new player."
+msgstr "Írj be szöveget a szűréshez, vagy csinálj egy új játékost."
+
+#: ../game/screen_players.cc:132
+msgid "Search Text:"
+msgstr "Szöveg kereső:"
+
+#: ../game/screen_audiodevices.cc:55
+msgid ""
+"It seems you have some manual configurations\n"
+"incompatible with this user interface.\n"
+"Saving these settings will override\n"
+"all existing audio device configuration.\n"
+"Your other options changes will be saved too."
+msgstr ""
+
+#: ../game/screen_audiodevices.cc:114
+msgid "- Unassigned -"
+msgstr ""
+
+#: ../game/screen_audiodevices.cc:135
+msgid ""
+"Use arrow keys to configure. Hit Enter/Start to save and test or Esc/Select "
+"to cancel. Ctrl + R to reset defaults"
+msgstr ""
+
+#: ../game/screen_audiodevices.cc:140
+msgid ""
+"For advanced device configuration, use command line parameter --audio (use --"
+"audiohelp for details)."
+msgstr ""
+
+#: ../game/screen_audiodevices.cc:188
+msgid "Some devices failed to open!"
+msgstr ""
+
+#: ../game/database.cc:89 ../game/database.cc:107
+msgid "No Items up to now."
+msgstr ""
+
+#: ../game/database.cc:90 ../game/database.cc:108
+msgid "Be the first to be listed here!"
+msgstr ""
+
+#: ../game/song.hh:22
+#, fuzzy
+msgid "Guitar"
+msgstr "Kilépés"
+
+#: ../game/song.hh:22
+msgid "Coop guitar"
+msgstr ""
+
+#: ../game/song.hh:22
+msgid "Rhythm guitar"
+msgstr ""
+
+#: ../game/song.hh:22
+msgid "Bass"
+msgstr ""
+
+#: ../game/song.hh:22
+msgid "Drums"
+msgstr ""
+
+#: ../game/song.hh:22
+msgid "Vocals"
+msgstr ""
+
+#: ../game/song.hh:22
+msgid "Harmonic 1"
+msgstr ""
+
+#: ../game/song.hh:22
+msgid "Harmonic 2"
+msgstr ""
+
+#: ../game/song.hh:22
+msgid "Harmonic 3"
+msgstr ""
+
+#, fuzzy
+#~ msgid "Loading graphics..."
+#~ msgstr "Főmenü …"
+
+#~ msgid "(press END to view hiscores)"
+#~ msgstr "(Nyomj END-et a ranglistához)"
+
+#~ msgid "<type in to search>"
+#~ msgstr "<írj a kereséshez>"
+
+#, fuzzy
+#~ msgid "Configure rendering and video settings"
+#~ msgstr "Játék beállítások"
+
+#, fuzzy
+#~ msgid "Video playback"
+#~ msgstr "Hang lejátszás..."
+
+#~ msgid "Miscellaneous..."
+#~ msgstr "Vegyes..."
diff --git a/lang/it.po b/lang/it.po
new file mode 100644 (file)
index 0000000..c754989
--- /dev/null
@@ -0,0 +1,1060 @@
+msgid ""
+msgstr ""
+"Project-Id-Version: Perf try\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2013-05-24 12:47+0100\n"
+"PO-Revision-Date: 2013-05-24 12:47+0100\n"
+"Last-Translator: Tapio Vierros <tapiovierros@gmail.com>\n"
+"Language-Team: \n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"X-Poedit-KeywordsList: _;gettext;gettext_noop\n"
+"X-Poedit-Basepath: .\n"
+"X-Generator: Poedit 1.5.4\n"
+"X-Poedit-SearchPath-0: ../game\n"
+"X-Poedit-SearchPath-1: ../data\n"
+
+#: ../game/screen_paths.cc:24
+msgid ""
+"This tool is not yet available.\n"
+"Configure paths by adding them\n"
+"as command line parameters and\n"
+"then save them in configuration menu."
+msgstr ""
+"Questo strumento non è ancora disponibile.\n"
+"Configura le path aggiungendole\n"
+"come parametro da linea di comando\n"
+"e salvale nel menu di configurazione."
+
+#: ../game/screen_paths.cc:70
+msgid "Press any key to exit."
+msgstr "Premi qualsiasi tasto per uscire."
+
+#: ../game/screen_paths.cc:75
+msgid ""
+"Windows users can also use ConfigureSongDirectory.bat in the bin-directory."
+msgstr ""
+"Gli utenti Windows possono anche usare ConfigureSongDirectory.bat nella "
+"cartella bin."
+
+#: ../game/configuration.cc:117
+msgid "Enabled"
+msgstr "Abilitato"
+
+#: ../game/configuration.cc:117
+msgid "Disabled"
+msgstr "Disabilitato"
+
+#: ../game/configuration.cc:121
+#, c-format
+msgid "%d items"
+msgstr "%d elementi"
+
+#: ../game/instrumentgraph.cc:56 ../game/screen_sing.cc:123
+msgid "Resume"
+msgstr "Ritorna"
+
+#: ../game/instrumentgraph.cc:56 ../game/screen_sing.cc:123
+msgid "Back to performing!"
+msgstr "Ritorna a fare performing!"
+
+#: ../game/instrumentgraph.cc:57
+msgid "Rejoin"
+msgstr "Riunisciti"
+
+#: ../game/instrumentgraph.cc:57
+msgid "Change selections"
+msgstr "Cambia selezione"
+
+#: ../game/instrumentgraph.cc:58 ../game/screen_sing.cc:124
+msgid "Restart"
+msgstr "Ricomincia"
+
+#: ../game/instrumentgraph.cc:58 ../game/screen_sing.cc:124
+msgid ""
+"Start the song\n"
+"from the beginning"
+msgstr ""
+"Comincia la canzone\n"
+"dall'inizio"
+
+#: ../game/instrumentgraph.cc:59 ../game/guitargraph.cc:200
+#: ../game/screen_intro.cc:184 ../game/dancegraph.cc:137
+#: ../game/screen_sing.cc:92 ../game/screen_sing.cc:126
+msgid "Quit"
+msgstr "Esci"
+
+#: ../game/instrumentgraph.cc:59 ../game/guitargraph.cc:200
+#: ../game/dancegraph.cc:137 ../game/screen_sing.cc:92
+#: ../game/screen_sing.cc:126
+msgid "Exit to song browser"
+msgstr "Ritorna alle canzoni"
+
+#: ../game/guitargraph.cc:14
+msgid "Kids"
+msgstr "Bambini"
+
+#: ../game/guitargraph.cc:14 ../game/dancegraph.cc:18
+msgid "Easy"
+msgstr "Facile"
+
+#: ../game/guitargraph.cc:14 ../game/dancegraph.cc:18
+msgid "Medium"
+msgstr "Medio"
+
+#: ../game/guitargraph.cc:14 ../game/dancegraph.cc:18
+msgid "Hard"
+msgstr "Difficile"
+
+#: ../game/guitargraph.cc:14
+msgid "Expert"
+msgstr "Esperto"
+
+#: ../game/guitargraph.cc:163 ../game/dancegraph.cc:134
+msgid "Select difficulty"
+msgstr "Seleziona la difficoltà"
+
+#: ../game/guitargraph.cc:169 ../game/guitargraph.cc:186
+msgid "Lefty-mode"
+msgstr "Modalità Lefty"
+
+#: ../game/guitargraph.cc:183 ../game/dancegraph.cc:118
+msgid "Select track"
+msgstr "Seleziona la canzone"
+
+#: ../game/guitargraph.cc:194 ../game/dancegraph.cc:107
+msgid "Ready!"
+msgstr "Pronto!"
+
+#: ../game/guitargraph.cc:194 ../game/screen_intro.cc:166
+#: ../game/dancegraph.cc:107
+msgid "Start performing!"
+msgstr "Comincia il performing!"
+
+#: ../game/guitargraph.cc:207
+msgid "ON"
+msgstr "ON"
+
+#: ../game/guitargraph.cc:207
+msgid "OFF"
+msgstr "OFF"
+
+#: ../game/guitargraph.cc:208
+msgid "Toggle lefty-mode"
+msgstr "Abilita/disabilita modalità lefty"
+
+#: ../game/guitargraph.cc:447 ../game/dancegraph.cc:319
+msgid "Streak!"
+msgstr "Streak!"
+
+#: ../game/guitargraph.cc:459
+msgid ""
+"God Mode\n"
+"Activated!"
+msgstr ""
+"Modalità God\n"
+"Attivata!"
+
+#: ../game/guitargraph.cc:460
+msgid "Mistakes ignored!"
+msgstr "Errori ignorati!"
+
+#: ../game/guitargraph.cc:1102
+msgid "God Mode Ready!"
+msgstr "Modalità God pronta!"
+
+#: ../game/guitargraph.cc:1103
+msgid "Drum Fill!"
+msgstr "Fill di batteria!"
+
+#: ../game/guitargraph.cc:1106
+msgid "Solo!"
+msgstr "Assolo!"
+
+#: ../game/songs.cc:194
+msgid "show all songs"
+msgstr ""
+
+#: ../game/songs.cc:195
+msgid "has dance"
+msgstr ""
+
+#: ../game/songs.cc:196
+#, fuzzy
+msgid "has vocals"
+msgstr "Cantato"
+
+#: ../game/songs.cc:197
+msgid "has duet"
+msgstr ""
+
+#: ../game/songs.cc:198
+#, fuzzy
+msgid "has guitar"
+msgstr "Chitarra ritmica"
+
+#: ../game/songs.cc:199
+msgid "drums or keytar"
+msgstr ""
+
+#: ../game/songs.cc:200
+msgid "full band"
+msgstr ""
+
+#: ../game/songs.cc:228
+msgid "random order"
+msgstr "ordine casuale"
+
+#: ../game/songs.cc:229
+msgid "sorted by song"
+msgstr "ordinato per canzone"
+
+#: ../game/songs.cc:230
+msgid "sorted by artist"
+msgstr "ordinato per artista"
+
+#: ../game/songs.cc:231
+msgid "sorted by edition"
+msgstr "ordinato per edizione"
+
+#: ../game/songs.cc:232
+msgid "sorted by genre"
+msgstr "ordinato per genere"
+
+#: ../game/songs.cc:233
+msgid "sorted by path"
+msgstr "ordinato per percorso"
+
+#: ../game/songs.cc:234
+msgid "sorted by language"
+msgstr "ordinato per lingua"
+
+#: ../game/screen_intro.cc:24
+msgid "No playback devices could be used.\n"
+msgstr "Nessun dispositivo di playback può essere usato.\n"
+
+#: ../game/screen_intro.cc:25
+msgid ""
+"\n"
+"Please configure some before playing."
+msgstr ""
+"\n"
+"Per favore configura qualcosa prima di giocare."
+
+#: ../game/screen_intro.cc:69
+msgid "Settings saved as system defaults."
+msgstr "Impostazioni salvate come default di sistema."
+
+#: ../game/screen_intro.cc:69
+msgid "Settings saved."
+msgstr "Impostazioni salvate."
+
+#: ../game/screen_intro.cc:149
+msgid "Ctrl + S to save, Ctrl + R to reset defaults"
+msgstr "Ctrl + S per salvare, Ctrl + R per tornare al default"
+
+#: ../game/screen_intro.cc:166
+msgid "Perform"
+msgstr "Gioca"
+
+#: ../game/screen_intro.cc:167
+msgid "Practice"
+msgstr "Pratica"
+
+#: ../game/screen_intro.cc:167
+msgid "Check your skills or test the microphones"
+msgstr "Controlla la tua bravura! / Test microfono"
+
+#: ../game/screen_intro.cc:183
+msgid "Configure"
+msgstr "Configura"
+
+#: ../game/screen_intro.cc:183
+msgid "Configure audio and game options"
+msgstr "Impostazioni audio e gioco"
+
+#: ../game/screen_intro.cc:184
+msgid "Leave the game"
+msgstr "Lascia il gioco"
+
+#: ../game/dancegraph.cc:18
+msgid "Beginner"
+msgstr "Principiante"
+
+#: ../game/dancegraph.cc:18
+msgid "Challenge"
+msgstr "Sfida"
+
+#: ../game/dancegraph.cc:248
+msgid "STOP!"
+msgstr "STOP!"
+
+#: ../game/screen_playlist.cc:110 ../game/screen_playlist.cc:252
+msgid "Continue"
+msgstr ""
+
+#: ../game/screen_playlist.cc:110
+msgid "Continue playing"
+msgstr ""
+
+#: ../game/screen_playlist.cc:118
+msgid "Add songs"
+msgstr ""
+
+#: ../game/screen_playlist.cc:118
+msgid "Open the song browser to add more songs"
+msgstr ""
+
+#: ../game/screen_playlist.cc:119 ../game/screen_songs.cc:513
+msgid "Shuffle"
+msgstr ""
+
+#: ../game/screen_playlist.cc:119 ../game/screen_songs.cc:513
+msgid "Randomize the order of the playlist"
+msgstr ""
+
+#: ../game/screen_playlist.cc:125
+msgid "Clear and exit"
+msgstr ""
+
+#: ../game/screen_playlist.cc:125 ../game/screen_songs.cc:520
+msgid "Remove all the songs from the list"
+msgstr ""
+
+#: ../game/screen_playlist.cc:131 ../game/screen_playlist.cc:275
+#: ../game/screen_songs.cc:526
+msgid "Back"
+msgstr ""
+
+#: ../game/screen_playlist.cc:131 ../game/screen_playlist.cc:275
+msgid "Back to playlist viewer"
+msgstr ""
+
+#: ../game/screen_playlist.cc:237
+msgid "Press enter to view song options"
+msgstr ""
+
+#: ../game/screen_playlist.cc:244
+msgid "View more options"
+msgstr ""
+
+#: ../game/screen_playlist.cc:244
+#, fuzzy
+msgid "View general playlist settings"
+msgstr "Impostazioni generali audio"
+
+#: ../game/screen_playlist.cc:252
+msgid "Play first"
+msgstr ""
+
+#: ../game/screen_playlist.cc:254
+msgid "Ignore the playlist's order and play this song first"
+msgstr ""
+
+#: ../game/screen_playlist.cc:255
+msgid "Start the song already!"
+msgstr ""
+
+#: ../game/screen_playlist.cc:264
+msgid "Remove"
+msgstr ""
+
+#: ../game/screen_playlist.cc:264
+msgid "Remove this song from the list"
+msgstr ""
+
+#: ../game/main.cc:146
+msgid "Loading audio samples..."
+msgstr "Caricamento canzoni di esempio..."
+
+#: ../game/main.cc:160
+msgid "Creating screens..."
+msgstr "Creazione dele schermate..."
+
+#: ../game/main.cc:170
+msgid "Entering main menu"
+msgstr "Entrando nel menu principale"
+
+#: ../game/main.cc:172 ../game/screen_sing.cc:97
+msgid "Loading complete"
+msgstr "Caricamento completato"
+
+#: ../game/main.cc:183
+msgid "Screenshot taken!"
+msgstr "Screenshot eseguito!"
+
+#: ../game/main.cc:186
+msgid "Screenshot failed!"
+msgstr "Screenshot fallito!"
+
+#: ../game/screen_sing.cc:45
+msgid "Initializing webcam..."
+msgstr "Inizializzazione webcam..."
+
+#: ../game/screen_sing.cc:52
+msgid "Loading video..."
+msgstr "Caricamento video..."
+
+#: ../game/screen_sing.cc:59
+msgid "Loading song..."
+msgstr "Caricamento canzoni..."
+
+#: ../game/screen_sing.cc:66
+msgid "Song contains broken tracks!"
+msgstr "La canzone contiene tracce rovinate!"
+
+#: ../game/screen_sing.cc:71
+msgid "Loading menu..."
+msgstr "Caricamento menu..."
+
+#: ../game/screen_sing.cc:76
+#, fuzzy
+msgid "Start"
+msgstr "Ricomincia"
+
+#: ../game/screen_sing.cc:76
+#, fuzzy
+msgid "Start performing"
+msgstr "Comincia il performing!"
+
+#: ../game/screen_sing.cc:80
+#, fuzzy
+msgid "Duet mode"
+msgstr "Modalità Lefty"
+
+#: ../game/screen_sing.cc:81
+#, fuzzy
+msgid "Normal mode"
+msgstr "Modalità karaoke"
+
+#: ../game/screen_sing.cc:82
+msgid "Switch between duet and regular singing mode"
+msgstr ""
+
+#: ../game/screen_sing.cc:90
+#, fuzzy
+msgid "Change vocal track"
+msgstr ""
+"Cambia traccia vocale\n"
+"(riavvio richiesto)"
+
+#: ../game/screen_sing.cc:125
+msgid "Skip"
+msgstr ""
+
+#: ../game/screen_sing.cc:125
+msgid "Skip current song"
+msgstr ""
+
+#: ../game/screen_sing.cc:391
+msgid "Press UP to join dance!"
+msgstr ""
+
+#: ../game/screen_sing.cc:391
+msgid "Step UP to join!"
+msgstr ""
+
+#: ../game/screen_sing.cc:396
+msgid "Press 1 to join guitar!"
+msgstr ""
+
+#: ../game/screen_sing.cc:396
+msgid "Press GREEN to join!"
+msgstr ""
+
+#: ../game/screen_sing.cc:401
+msgid "Press SPACE to join drums!"
+msgstr ""
+
+#: ../game/screen_sing.cc:401
+msgid "KICK to join!"
+msgstr ""
+
+#: ../game/screen_sing.cc:475
+msgid "   ENTER to skip instrumental break"
+msgstr "   INVIO per saltare la pausa strumentale"
+
+#: ../game/screen_sing.cc:476
+msgid "   Remember to wait for grading!"
+msgstr "   Ricordati di aspettare per il punteggio!"
+
+#: ../game/screen_sing.cc:587
+msgid "No player!"
+msgstr "Nessun giocatore trovato!"
+
+#: ../game/screen_sing.cc:594
+msgid "Hit singer"
+msgstr "Star"
+
+#: ../game/screen_sing.cc:595
+msgid "Lead singer"
+msgstr "Cantante"
+
+#: ../game/screen_sing.cc:596 ../game/screen_sing.cc:602
+#: ../game/screen_sing.cc:608
+msgid "Rising star"
+msgstr "Dilettante"
+
+#: ../game/screen_sing.cc:597 ../game/screen_sing.cc:603
+#: ../game/screen_sing.cc:609
+msgid "Amateur"
+msgstr "Amatore"
+
+#: ../game/screen_sing.cc:598 ../game/screen_sing.cc:610
+msgid "Tone deaf"
+msgstr "Stonato"
+
+#: ../game/screen_sing.cc:600
+msgid "Maniac"
+msgstr "Maniaco"
+
+#: ../game/screen_sing.cc:601
+msgid "Hoofer"
+msgstr "Professionista"
+
+#: ../game/screen_sing.cc:604
+msgid "Loser"
+msgstr "Perdente"
+
+#: ../game/screen_sing.cc:606
+msgid "Virtuoso"
+msgstr "Virtuoso"
+
+#: ../game/screen_sing.cc:607
+msgid "Rocker"
+msgstr "Rockstar"
+
+#: ../game/screen_songs.cc:279
+msgid "No songs found!"
+msgstr "Nessuna canzone trovata!"
+
+#: ../game/screen_songs.cc:280
+msgid ""
+"Visit performous.org\n"
+"for free songs"
+msgstr ""
+"Visita performous.org\n"
+"per canzoni gratuite"
+
+#: ../game/screen_songs.cc:282
+#, fuzzy
+msgid "Sorry, no songs match the search!"
+msgstr "nessuna canzone trovata"
+
+#: ../game/screen_songs.cc:289
+#, fuzzy
+msgid "Hiscore\n"
+msgstr "Highscore per %1%\n"
+
+#: ../game/screen_songs.cc:298
+msgid "<type in to search>   ↔ songs    ↕ options"
+msgstr ""
+
+#: ../game/screen_songs.cc:301
+msgid "↔ sort order: "
+msgstr ""
+
+#: ../game/screen_songs.cc:302
+msgid "↔ type filter: "
+msgstr ""
+
+#: ../game/screen_songs.cc:303
+msgid "↔ hiscores   ↵ jukebox mode"
+msgstr ""
+
+#: ../game/screen_songs.cc:307
+msgid "↵ start a playlist with this song!"
+msgstr ""
+
+#: ../game/screen_songs.cc:309
+msgid "↵ open the playlist menu"
+msgstr ""
+
+#: ../game/screen_songs.cc:506
+msgid "Play"
+msgstr ""
+
+#: ../game/screen_songs.cc:506
+msgid "Start the game with all songs in playlist"
+msgstr ""
+
+#: ../game/screen_songs.cc:519
+msgid "View playlist"
+msgstr ""
+
+#: ../game/screen_songs.cc:519
+msgid "View the current playlist"
+msgstr ""
+
+#: ../game/screen_songs.cc:520
+msgid "Clear playlist"
+msgstr ""
+
+#: ../game/screen_songs.cc:526
+#, fuzzy
+msgid "Back to song browser"
+msgstr "Ritorna alle canzoni"
+
+#: ../game/screen_players.cc:115
+msgid "No players found!"
+msgstr "Nessun giocatore trovato!"
+
+#: ../game/screen_players.cc:116
+msgid "Enter a name to create a new player."
+msgstr "Inserisci un nome per creare un nuovo giocatore."
+
+#: ../game/screen_players.cc:118
+msgid "Press enter to create player!"
+msgstr "Premi invio per creare il giocatore!"
+
+#: ../game/screen_players.cc:122
+#, fuzzy
+msgid "No players worth mentioning!"
+msgstr "Nessun giocatore trovato!"
+
+#: ../game/screen_players.cc:127
+msgid "You reached %1% points!"
+msgstr "Hai fatto %1% punti!"
+
+#: ../game/screen_players.cc:128
+msgid "Change player with arrow keys."
+msgstr "Cambia il giocatore con le frecce."
+
+#: ../game/screen_players.cc:129
+msgid "Name:"
+msgstr "Nome:"
+
+#: ../game/screen_players.cc:132
+msgid "Type text to filter or create a new player."
+msgstr "Inserisci un nome per selezionare un giocatore o crearne uno nuovo."
+
+#: ../game/screen_players.cc:132
+msgid "Search Text:"
+msgstr "Testo di ricerca"
+
+#: ../game/screen_audiodevices.cc:55
+msgid ""
+"It seems you have some manual configurations\n"
+"incompatible with this user interface.\n"
+"Saving these settings will override\n"
+"all existing audio device configuration.\n"
+"Your other options changes will be saved too."
+msgstr ""
+"Sembra che qualche configurazione manuale\n"
+"sia incompatibile con questa interfaccia utente.\n"
+"Salvando queste impostazioni verranno sovrascritte\n"
+"tutte le impostazioni di configurazione dei dispositivi audio.\n"
+"Saranno salvate anche le tue altre opzioni."
+
+#: ../game/screen_audiodevices.cc:114
+msgid "- Unassigned -"
+msgstr "- Non assegnato -"
+
+#: ../game/screen_audiodevices.cc:135
+msgid ""
+"Use arrow keys to configure. Hit Enter/Start to save and test or Esc/Select "
+"to cancel. Ctrl + R to reset defaults"
+msgstr ""
+"Usa le frecce direzionali per configuare. Premi Invio/Start per salvare e "
+"fare il test oppure Esc/Select per cancellare. Crtl + R per tornare ai "
+"parametri originali"
+
+#: ../game/screen_audiodevices.cc:140
+msgid ""
+"For advanced device configuration, use command line parameter --audio (use --"
+"audiohelp for details)."
+msgstr ""
+"Per la configurazione avanzata, usa il parametro --audio nella riga di "
+"comando (--audiohelp per i dettagli)"
+
+#: ../game/screen_audiodevices.cc:188
+msgid "Some devices failed to open!"
+msgstr "Errore di apertura su qualche dispositivo!"
+
+#: ../game/database.cc:89 ../game/database.cc:107
+msgid "No Items up to now."
+msgstr "Nessun elemento fino ad ora."
+
+#: ../game/database.cc:90 ../game/database.cc:108
+msgid "Be the first to be listed here!"
+msgstr "Sii il primo ad essere qui!"
+
+#: ../game/song.hh:22
+msgid "Guitar"
+msgstr "Chitarra"
+
+#: ../game/song.hh:22
+msgid "Coop guitar"
+msgstr "Chitarra coop"
+
+#: ../game/song.hh:22
+msgid "Rhythm guitar"
+msgstr "Chitarra ritmica"
+
+#: ../game/song.hh:22
+msgid "Bass"
+msgstr "Basso"
+
+#: ../game/song.hh:22
+msgid "Drums"
+msgstr "Batteria"
+
+#: ../game/song.hh:22
+msgid "Vocals"
+msgstr "Cantato"
+
+#: ../game/song.hh:22
+msgid "Harmonic 1"
+msgstr "Armonico 1"
+
+#: ../game/song.hh:22
+msgid "Harmonic 2"
+msgstr "Armonico 2"
+
+#: ../game/song.hh:22
+msgid "Harmonic 3"
+msgstr "Armonico 3"
+
+#~ msgid "Song is broken!"
+#~ msgstr "La canzone è corrotta!"
+
+#~ msgid "Loading instruments..."
+#~ msgstr "Caricamento strumenti..."
+
+#~ msgid "Finalizing..."
+#~ msgstr "Finalizzazione..."
+
+#, fuzzy
+#~ msgid "Loading graphics..."
+#~ msgstr "Caricamento canzoni..."
+
+#~ msgid "Random background..."
+#~ msgstr "Sfondo casuale..."
+
+#~ msgid "(press END to view hiscores)"
+#~ msgstr "(premi END per vedere i punteggi migliori)"
+
+#~ msgid "<type in to search>"
+#~ msgstr "<premi qualche lettera per cercare>"
+
+#~ msgid "Audio Devices"
+#~ msgstr "Dispositivi audio"
+
+#~ msgid "Setup microphones and playback"
+#~ msgstr "Imposta microfoni e riproduzione"
+
+#~ msgid "Audio"
+#~ msgstr "Audio"
+
+#~ msgid "Graphics"
+#~ msgstr "Grafica"
+
+#~ msgid "Configure rendering and video settings"
+#~ msgstr "Impostazioni video e rendering"
+
+#~ msgid "Game"
+#~ msgstr "Gioco"
+
+#~ msgid "Gameplay related options"
+#~ msgstr "Opzione relative al Gameplay"
+
+#~ msgid "Paths"
+#~ msgstr "Percorsi (path)"
+
+#~ msgid "Setup song and data paths"
+#~ msgstr "Imposta percorsi (path) canzoni e dati"
+
+#~ msgid "Gameplay settings."
+#~ msgstr "Impostazioni gameplay."
+
+#~ msgid "Graphic"
+#~ msgstr "Grafica"
+
+#~ msgid "Video and rendering settings."
+#~ msgstr "Impostazioni video e rendering."
+
+#~ msgid "Audio-related settings."
+#~ msgstr "Impostazioni relativa all'audio"
+
+#~ msgid "System paths."
+#~ msgstr "Path di sistema."
+
+#~ msgid "Hide pitch wave, notes and scoring."
+#~ msgstr "Nascondi pitch wave, note e punteggio"
+
+#~ msgid "Pitch waves"
+#~ msgstr "Pitch wave"
+
+#~ msgid "Enable singing pitch display (when not in karaoke mode)."
+#~ msgstr ""
+#~ "Abilita la visualizzazione dinamica delle note da cantare (quando non si "
+#~ "è in modalità karaoke)"
+
+#~ msgid "Theme"
+#~ msgstr "Tema"
+
+#~ msgid "Name of the theme to use or absolute path to theme folder."
+#~ msgstr ""
+#~ "Nome del tema da usare oppure la path assoluta alla cartella del tema"
+
+#~ msgid "Keyboard as guitar"
+#~ msgstr "Tastiera come chitarra"
+
+#~ msgid "Enable keyboard as guitar (Frets on Fire mode)."
+#~ msgstr "Abilita la tastiera come chitarra (modalità Frets on Fire)."
+
+#~ msgid "Keyboard as drumkit"
+#~ msgstr "Tastiera come drumkit"
+
+#~ msgid "Enable keyboard as drumkit."
+#~ msgstr "Abilita la tastiera come drumkit"
+
+#~ msgid "Keyboard as dance pad"
+#~ msgstr "Tastiera come dance pad"
+
+#~ msgid "Enable keyboard as dance pad."
+#~ msgstr "Abilita la tastiera come dance pad"
+
+#, fuzzy
+#~ msgid "Keyboard as keyboard"
+#~ msgstr "Tastiera come chitarra"
+
+#, fuzzy
+#~ msgid "Enable keyboard as keyboard."
+#~ msgstr "Abilita la tastiera come dance pad"
+
+#~ msgid "Joystick configuration"
+#~ msgstr "Configurazione joystick"
+
+#~ msgid "Force joystick to some kind of instrument."
+#~ msgstr "Forza il joystick a qualche tipo di strumento"
+
+#~ msgid "Hardware MIDI input device"
+#~ msgstr "Dispositivo hardware di input MIDI"
+
+#~ msgid ""
+#~ "Part of sound card name or its number or empty to use the first available "
+#~ "device. Used currently for MIDI drum controllers."
+#~ msgstr ""
+#~ "Parte della scheda audio oppure il suo numero oppure vuoto per prendere "
+#~ "il primo dispositivo disponibile. Utilizzato al momento per il controller "
+#~ "batteria MIDI."
+
+#~ msgid "Windowed width"
+#~ msgstr "Larghezza finestra"
+
+#~ msgid "The width of the window."
+#~ msgstr "La larghezza della finestra"
+
+#~ msgid "Windowed height"
+#~ msgstr "Altezza finestra"
+
+#~ msgid "The height of the window."
+#~ msgstr "L'altezza della finestra"
+
+#~ msgid "Fullscreen mode"
+#~ msgstr "Fullscreen"
+
+#~ msgid "Enable fullscreen mode on startup."
+#~ msgstr "Abilita fullscreen all'avvio."
+
+#~ msgid "Video playback"
+#~ msgstr "Riproduzione video"
+
+#~ msgid ""
+#~ "Allows completely disabling background videos. It is recommended to leave "
+#~ "this enabled as Performous will still smoothly fade out the video if your "
+#~ "computer is not fast enough."
+#~ msgstr ""
+#~ "Abilita la completa disabilitazione del video di background. Si "
+#~ "raccomanda di lasciare questa opzione attivata perchè Performous farà "
+#~ "svanire il video se il computer non è abbastanza veloce."
+
+#~ msgid "Webcam background"
+#~ msgstr "Sfondo della webcam"
+
+#, fuzzy
+#~ msgid ""
+#~ "Performous can use webcam as a background video. Disable it if Performous "
+#~ "crashes while entering a song."
+#~ msgstr ""
+#~ "Performous può provare ad usare la webcam come video di background. Lo "
+#~ "puoi disabilitare se ti dà fastidio."
+
+#~ msgid "Webcam id"
+#~ msgstr "Webcam id"
+
+#~ msgid ""
+#~ "Use -1 to autodetect or a number starting from 0 to choose specific "
+#~ "device."
+#~ msgstr ""
+#~ "Usa -1 per la rilevazione automatica oppure un numero che parte da 0 per "
+#~ "selezionare uno specifico dispositivo."
+
+#~ msgid "3D notes"
+#~ msgstr "Note 3D"
+
+#~ msgid ""
+#~ "Draw instrument notes as 3-dimensional objects. May hurt performance on "
+#~ "older hardware."
+#~ msgstr ""
+#~ "Disegna le note degli strumenti come oggetti tridimensionali. Potrebbe "
+#~ "diminuire le performance nei vecchi hardware."
+
+#~ msgid "SVG quality"
+#~ msgstr "Qualità SVG"
+
+#~ msgid ""
+#~ "Larger numbers cause vector graphics to be rendered in higher resolution. "
+#~ "Decrease this to make navigating in menus faster."
+#~ msgstr ""
+#~ "Numeri grandi aumentanno la risoluzione di visualizzazione delle "
+#~ "immagini. Diminuisci questo per navigare nei menu più rapidamente."
+
+#~ msgid "Text quality"
+#~ msgstr "Qualità testo"
+
+#~ msgid ""
+#~ "Larger numbers cause text to be rendered in higher resolution. Decrease "
+#~ "this to make everything a little faster."
+#~ msgstr ""
+#~ "Numeri grandi aumenteranno la risoluzione di visualizzazione del testo. "
+#~ "Diminuisci questo per rendere tutto un po' più veloce."
+
+#~ msgid "Benchmark mode"
+#~ msgstr "Modalità benchmark"
+
+#~ msgid ""
+#~ "Framerate limit of 100 FPS is removed and the game instead renders at "
+#~ "full speed. FPS values are printed to console. Please note that the "
+#~ "display drivers may still limit the rendering speed to the screen refresh "
+#~ "rate."
+#~ msgstr ""
+#~ "Il limite di framerate di 100 FPS è rimosso e il gioco gira a piena "
+#~ "potenza. I valori degli FPS sono stampati su console. Da notare che i "
+#~ "driver della scheda video potrebbero ancora limitare la velocità di "
+#~ "rendering alla velocità di refresh dello schermo."
+
+#~ msgid "Suggested latency"
+#~ msgstr "Latenza suggerita"
+
+#~ msgid ""
+#~ "This is a hint for the audio engine about the desired latency. Set this "
+#~ "as low as possible while retaining clear audio playback. Requires restart."
+#~ msgstr ""
+#~ "Questo è un consiglio per il motore audio relativo alla latenza "
+#~ "desiderata. Imposta questo valore il più piccolo valore possibile per "
+#~ "avere un buon playback audio. Richiede riavvio."
+
+#~ msgid "Audio/video latency"
+#~ msgstr "Latenza audio/video"
+
+#~ msgid ""
+#~ "Affects all modes. Use negative value if your display input lag is "
+#~ "greater than the sound card output latency, positive values in the "
+#~ "opposite case and zero if they are equal. This should be set so that the "
+#~ "notes pass the cursor at the same time the audio is heard. Use Ctrl+F1/F2 "
+#~ "to adjust this while performing."
+#~ msgstr ""
+#~ "Influisce su tutte le modalità. Usa dei valori negativi se il lag del "
+#~ "display è maggiore della latenza della scheda audio, positivi nel caso "
+#~ "opposto e zero se sono uguali. Questo parametro dovrebbe essere impostato "
+#~ "in maniera tale che le note passino sotto al cursore nell stesso tempo "
+#~ "che si sente l'audio. Usare Ctrl+F1/F2 per regolare mentre si è in "
+#~ "performing."
+
+#~ msgid "Audio round-trip latency"
+#~ msgstr "Latenza audio di ritorno"
+
+#~ msgid ""
+#~ "Affects singing only. The time it takes for Performous playback to reach "
+#~ "your speakers, fly to the microphone and all the way back until "
+#~ "Performous captures and analyzes it. While performing, press Ctrl+S for "
+#~ "synth mode and adjust with Ctrl+F3/F4."
+#~ msgstr ""
+#~ "Influisce solo la parte cantata. Il tempo che serve al playback di "
+#~ "Performous per raggiungere gli altoparlandi, volare al microfono e tutta "
+#~ "la strada indietro finchè Performous non lo cattura e lo analizza. Mentre "
+#~ "si è in performing, premere Ctrl+S per la modalità synth e regolare con "
+#~ "Ctrl+F3/F4."
+
+#~ msgid "Audio/controller latency"
+#~ msgstr "Latenza audio/controller."
+
+#~ msgid ""
+#~ "Affects instruments and dancing only. The total of USB (guitar or dance "
+#~ "pad) latency combined with audio output latency. Adjust so that you can "
+#~ "hit the notes best when playing by ear (not looking on screen). Use Ctrl"
+#~ "+F5/F6 to adjust while performing."
+#~ msgstr ""
+#~ "Influisce solo strumenti e danza. Il totale della latenza USB (chitarra o "
+#~ "dance pad) combinata con la latenza di output audio. Regolala in maniera "
+#~ "tale che puoi colpire le note meglio quando si suona ad orecchio (senza "
+#~ "guardare lo schermo). Usa Ctrl+F5/F6 per regolare mentre si è in "
+#~ "performing."
+
+#~ msgid "Audio devices"
+#~ msgstr "Dispositivi audio"
+
+#~ msgid "List of audio devices to try."
+#~ msgstr "Lista dei dispositivi audio da provare."
+
+#~ msgid "Menu volume"
+#~ msgstr "Volume menu"
+
+#~ msgid "The volume level of menus, song previews and jukebox mode."
+#~ msgstr ""
+#~ "Il livello del volume dei menu, anteprima delle canzoni e modalità "
+#~ "jukebox."
+
+#~ msgid "Music volume"
+#~ msgstr "Volume musica"
+
+#~ msgid ""
+#~ "The ingame music volume. Values above 90 are not recommended as "
+#~ "distortion may occur."
+#~ msgstr ""
+#~ "Il volume della musica nel gioco. Valori sopra 90 sono sconsigliati "
+#~ "perchè potrebbero verificarsi distorsioni."
+
+#~ msgid "Failure volume"
+#~ msgstr "Volume errore"
+
+#~ msgid ""
+#~ "The ingame fail sound volume. Values above 90 are not recommended as "
+#~ "distortion may occur. 11 is louder than 10, but these go to 100. 89 "
+#~ "louder!"
+#~ msgstr ""
+#~ "Il volume del suono dell'errore nel gioco. Valori sopra 90 sono "
+#~ "sconsigliati perchè potrebbero verificarsi distorsioni. 11 è più alto di "
+#~ "10, ma questi vanno a 100. 89 il più alto!"
+
+#~ msgid "Song folders"
+#~ msgstr "Cartella canzoni"
+
+#~ msgid ""
+#~ "Where to recursively look for songs. DATADIR at the beginning means all "
+#~ "Performous data folders."
+#~ msgstr ""
+#~ "Dove guardare ricorsivamente per tutte le canzoni. DATADIR all'inizio "
+#~ "vuol dire tutte le cartelle dei dati di Performous."
+
+#~ msgid "Base folders for data"
+#~ msgstr "Cartelle basi per i dati"
+
+#~ msgid ""
+#~ "System defaults are included automatically. Additional paths can be added "
+#~ "here."
+#~ msgstr ""
+#~ "Le predefinite di sistema sono incluse automaticamente. Path addizionali "
+#~ "possono essere aggiunte qui."
+
+#~ msgid "Loading theme..."
+#~ msgstr "Caricamente tema..."
+
+#~ msgid "Loading background..."
+#~ msgstr "Caricamento sfondo..."
+
+#~ msgid "Loading user interface..."
+#~ msgstr "Caricamento interfaccia utente..."
diff --git a/lang/ja.po b/lang/ja.po
new file mode 100644 (file)
index 0000000..475712c
--- /dev/null
@@ -0,0 +1,1164 @@
+msgid ""
+msgstr ""
+"Project-Id-Version: Performous\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2013-11-06 09:00+0100\n"
+"PO-Revision-Date: 2013-11-06 09:29+0100\n"
+"Last-Translator: niek nooijens <nieknooijens@gmail.com>\n"
+"Language-Team: \n"
+"Language: ja_JP\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"X-Poedit-KeywordsList: _;gettext;gettext_noop\n"
+"X-Poedit-Basepath: .\n"
+"X-Poedit-SourceCharset: UTF-8\n"
+"X-Generator: Poedit 1.5.4\n"
+"X-Poedit-SearchPath-0: ../data\n"
+"X-Poedit-SearchPath-1: ../game\n"
+
+#: ../game/screen_paths.cc:24
+msgid ""
+"This tool is not yet available.\n"
+"Configure paths by adding them\n"
+"as command line parameters and\n"
+"then save them in configuration menu."
+msgstr ""
+"この道具はまた使えません。\n"
+"コマンドラインで加えて\n"
+"コンフィグレーシオンメニユーでセーブして下さい。"
+
+#: ../game/screen_paths.cc:70
+#, fuzzy
+msgid "Press any key to exit."
+msgstr "止める為キーを打って下さい。"
+
+#: ../game/screen_paths.cc:76
+msgid "Windows users can also use ConfigureSongDirectory.bat script."
+msgstr "ウィンドーズ・ユーザーズはConfigureSongDirectory.batも使えますよ。"
+
+#: ../game/configuration.cc:112
+msgid "Enabled"
+msgstr "使用可能"
+
+#: ../game/configuration.cc:112
+msgid "Disabled"
+msgstr "使用禁止"
+
+#: ../game/configuration.cc:116
+#, c-format
+msgid "%d items"
+msgstr "%d 細目"
+
+#: ../game/instrumentgraph.cc:56 ../game/screen_sing.cc:123
+msgid "Resume"
+msgstr "再会"
+
+#: ../game/instrumentgraph.cc:56 ../game/screen_sing.cc:123
+msgid "Back to performing!"
+msgstr "演奏に再会する"
+
+#: ../game/instrumentgraph.cc:57
+msgid "Rejoin"
+msgstr "再加入"
+
+#: ../game/instrumentgraph.cc:57
+msgid "Change selections"
+msgstr "曲目を変更"
+
+#: ../game/instrumentgraph.cc:58 ../game/screen_sing.cc:124
+msgid "Restart"
+msgstr "再起動"
+
+#: ../game/instrumentgraph.cc:58 ../game/screen_sing.cc:124
+msgid ""
+"Start the song\n"
+"from the beginning"
+msgstr "初めから曲を開始する"
+
+#: ../game/instrumentgraph.cc:59 ../game/guitargraph.cc:200
+#: ../game/screen_intro.cc:184 ../game/dancegraph.cc:137
+#: ../game/screen_sing.cc:92 ../game/screen_sing.cc:126
+msgid "Quit"
+msgstr "終了"
+
+#: ../game/instrumentgraph.cc:59 ../game/guitargraph.cc:200
+#: ../game/dancegraph.cc:137 ../game/screen_sing.cc:92
+#: ../game/screen_sing.cc:126
+msgid "Exit to song browser"
+msgstr "音楽ブラウザに終了する"
+
+#: ../game/guitargraph.cc:14
+msgid "Kids"
+msgstr "子供"
+
+#: ../game/guitargraph.cc:14 ../game/dancegraph.cc:18
+msgid "Easy"
+msgstr "易しい"
+
+#: ../game/guitargraph.cc:14 ../game/dancegraph.cc:18
+#, fuzzy
+msgid "Medium"
+msgstr "中間"
+
+#: ../game/guitargraph.cc:14 ../game/dancegraph.cc:18
+msgid "Hard"
+msgstr "難しい"
+
+#: ../game/guitargraph.cc:14
+msgid "Expert"
+msgstr "専門家"
+
+# or would 難しさにして下さい work?
+#: ../game/guitargraph.cc:163 ../game/dancegraph.cc:134
+msgid "Select difficulty"
+msgstr "難しさを決めて下さい"
+
+#: ../game/guitargraph.cc:169 ../game/guitargraph.cc:186
+msgid "Lefty-mode"
+msgstr "左手モード"
+
+# or would トラックにして下さい work?
+#: ../game/guitargraph.cc:183 ../game/dancegraph.cc:118
+msgid "Select track"
+msgstr "トラックを決めて下さい"
+
+# There's probably a better word
+#: ../game/guitargraph.cc:194 ../game/dancegraph.cc:107
+msgid "Ready!"
+msgstr "レディー!"
+
+# See comment about Perform
+#: ../game/guitargraph.cc:194 ../game/screen_intro.cc:166
+#: ../game/dancegraph.cc:107
+msgid "Start performing!"
+msgstr "演奏しはじめて"
+
+#: ../game/guitargraph.cc:207
+msgid "ON"
+msgstr "オン"
+
+#: ../game/guitargraph.cc:207
+msgid "OFF"
+msgstr "オフ"
+
+#: ../game/guitargraph.cc:208
+msgid "Toggle lefty-mode"
+msgstr "左手モードをトグル"
+
+#: ../game/guitargraph.cc:447 ../game/dancegraph.cc:321
+msgid "Streak!"
+msgstr "ストリーク!"
+
+#: ../game/guitargraph.cc:459
+msgid ""
+"God Mode\n"
+"Activated!"
+msgstr ""
+"神モード\n"
+"活性化!"
+
+#: ../game/guitargraph.cc:460
+msgid "Mistakes ignored!"
+msgstr "間違い無視"
+
+#: ../game/guitargraph.cc:1102
+msgid "God Mode Ready!"
+msgstr "神モードできた"
+
+#: ../game/guitargraph.cc:1103
+msgid "Drum Fill!"
+msgstr "ドラム・フィル"
+
+#: ../game/guitargraph.cc:1106
+msgid "Solo!"
+msgstr "ソロー"
+
+#: ../game/songs.cc:178
+msgid "show all songs"
+msgstr "全部の曲を見せて"
+
+#: ../game/songs.cc:179
+msgid "has dance"
+msgstr "「踊」がある。"
+
+#: ../game/songs.cc:180
+#, fuzzy
+msgid "has vocals"
+msgstr "ボーカル"
+
+#: ../game/songs.cc:181
+msgid "has duet"
+msgstr "二部合唱がある"
+
+#: ../game/songs.cc:182
+#, fuzzy
+msgid "has guitar"
+msgstr "リズムギター"
+
+#: ../game/songs.cc:183
+#, fuzzy
+msgid "drums or keytar"
+msgstr "どラムズかキーターか。"
+
+#: ../game/songs.cc:184
+msgid "full band"
+msgstr "全楽団"
+
+#: ../game/songs.cc:212
+msgid "random order"
+msgstr "無作為並べ替え"
+
+#: ../game/songs.cc:213
+msgid "sorted by song"
+msgstr "歌順に並べ替えた"
+
+#: ../game/songs.cc:214
+msgid "sorted by artist"
+msgstr "アーティスト順に並べ替えた"
+
+#: ../game/songs.cc:215
+msgid "sorted by edition"
+msgstr "版順に並べ替えた"
+
+#: ../game/songs.cc:216
+msgid "sorted by genre"
+msgstr "ジャンル順に並べ替えた"
+
+#: ../game/songs.cc:217
+msgid "sorted by path"
+msgstr "パス順に並べ替えた"
+
+#: ../game/songs.cc:218
+msgid "sorted by language"
+msgstr "言語に並べ替え"
+
+#: ../game/screen_intro.cc:24
+msgid "No playback devices could be used.\n"
+msgstr "再生装置が見つかりませんでした\n"
+
+#: ../game/screen_intro.cc:25
+msgid ""
+"\n"
+"Please configure some before playing."
+msgstr ""
+"\n"
+" 遊ぶ前に再生装置を設定して下さい。"
+
+#: ../game/screen_intro.cc:69
+msgid "Settings saved as system defaults."
+msgstr "設定はシステム・デファウルトにセーブされました。"
+
+#: ../game/screen_intro.cc:69
+msgid "Settings saved."
+msgstr "設定をセーブしました。"
+
+#: ../game/screen_intro.cc:149
+msgid "Ctrl + S to save, Ctrl + R to reset defaults"
+msgstr "セーブするはCtrl + S で、設定元に戻るはCtrl + Rです。"
+
+# 塩素する = musical performance
+# I think 本番 could work, unless sence 3 of Jim's WWWJDIC is the most common meaning...
+# I get the feeling that 演じろ is more theatrical.
+# パフォーマンスする feels to english imo
+# Perhaps suru should be dropped?
+#: ../game/screen_intro.cc:166
+msgid "Perform"
+msgstr "演奏する"
+
+# not sure this is the best word
+#: ../game/screen_intro.cc:167
+msgid "Practice"
+msgstr "トレーニング"
+
+#: ../game/screen_intro.cc:167
+msgid "Check your skills or test the microphones"
+msgstr "自分の能力とマイクをテストできます。"
+
+#: ../game/screen_intro.cc:183
+msgid "Configure"
+msgstr "設定"
+
+#: ../game/screen_intro.cc:183
+msgid "Configure audio and game options"
+msgstr "オーディオとゲームのオプションを設定する"
+
+#: ../game/screen_intro.cc:184
+msgid "Leave the game"
+msgstr "ゲームを終了する"
+
+#: ../game/dancegraph.cc:18
+msgid "Beginner"
+msgstr "初心者"
+
+#: ../game/dancegraph.cc:18
+msgid "Challenge"
+msgstr "挑戦"
+
+# 止まって or 止めて, not sure which english stop that's indented.
+#: ../game/dancegraph.cc:248
+msgid "STOP!"
+msgstr "止まって!"
+
+#: ../game/screen_playlist.cc:24 ../game/screen_sing.cc:45
+msgid "Initializing webcam..."
+msgstr "カメラを組み立ています"
+
+#: ../game/screen_playlist.cc:166 ../game/screen_playlist.cc:308
+msgid "Continue"
+msgstr "続く"
+
+#: ../game/screen_playlist.cc:166
+msgid "Continue playing"
+msgstr "遊び続く"
+
+#: ../game/screen_playlist.cc:174
+msgid "Add songs"
+msgstr "曲を加え"
+
+#: ../game/screen_playlist.cc:174
+msgid "Open the song browser to add more songs"
+msgstr "もっと曲を加えるのに曲選択画面へ戻る"
+
+#: ../game/screen_playlist.cc:175 ../game/screen_songs.cc:509
+msgid "Shuffle"
+msgstr "シャッフル"
+
+#: ../game/screen_playlist.cc:175
+msgid "Randomize the order of the playlist"
+msgstr "リストの曲を更迭する。"
+
+#: ../game/screen_playlist.cc:181
+msgid "Clear and exit"
+msgstr "消すと止める。"
+
+#: ../game/screen_playlist.cc:181
+msgid "Remove all the songs from the list"
+msgstr "全曲をリストから消すと止める。"
+
+#: ../game/screen_playlist.cc:187 ../game/screen_playlist.cc:331
+#: ../game/screen_songs.cc:522
+msgid "Back"
+msgstr "戻る"
+
+#: ../game/screen_playlist.cc:187 ../game/screen_playlist.cc:331
+msgid "Back to playlist viewer"
+msgstr "リスト画面へ戻る"
+
+#: ../game/screen_playlist.cc:293
+msgid "Press enter to view song options"
+msgstr "曲設定を見る為にエンターを押して下さい"
+
+#: ../game/screen_playlist.cc:300
+msgid "View more options"
+msgstr "もっとの設定をみる"
+
+#: ../game/screen_playlist.cc:300
+#, fuzzy
+msgid "View general playlist settings"
+msgstr "全般オーディオのオプションを設定する"
+
+#: ../game/screen_playlist.cc:308
+msgid "Play first"
+msgstr "今すぐプレイする"
+
+#: ../game/screen_playlist.cc:310
+msgid "Ignore the playlist's order and play this song first"
+msgstr "この曲を今すぐプレイされます"
+
+#: ../game/screen_playlist.cc:311
+msgid "Start the song already!"
+msgstr "曲を始めよう"
+
+#: ../game/screen_playlist.cc:320
+msgid "Remove"
+msgstr "消す"
+
+#: ../game/screen_playlist.cc:320
+msgid "Remove this song from the list"
+msgstr "この曲はリストから消す。"
+
+# note: says "music" instead of "audio samples"
+#: ../game/main.cc:147
+msgid "Loading audio samples..."
+msgstr "音楽を読み替えていまうす…"
+
+#: ../game/main.cc:161
+msgid "Creating screens..."
+msgstr "画面を作り中"
+
+#: ../game/main.cc:171
+msgid "Entering main menu"
+msgstr "メインメニューに入り中"
+
+#: ../game/main.cc:173 ../game/screen_sing.cc:97
+msgid "Loading complete"
+msgstr "良い込みできた"
+
+#: ../game/main.cc:184
+msgid "Screenshot taken!"
+msgstr "スクリーンショットを取りました"
+
+#: ../game/main.cc:187
+msgid "Screenshot failed!"
+msgstr "スクリーンショットを失敗しました"
+
+# ます-form (suspended form) + 中 means that something is in progress and is more often used in signs,
+# て+います is more conversational
+#: ../game/screen_sing.cc:52
+msgid "Loading video..."
+msgstr "ビデオを読み込み中…"
+
+#: ../game/screen_sing.cc:59
+msgid "Loading song..."
+msgstr "音楽を読み替えていまうす…"
+
+#: ../game/screen_sing.cc:66
+msgid "Song contains broken tracks!"
+msgstr "音楽には壊れてトラックが含まれます"
+
+#: ../game/screen_sing.cc:71
+msgid "Loading menu..."
+msgstr "メニューを読み込み中…"
+
+#: ../game/screen_sing.cc:76
+#, fuzzy
+msgid "Start"
+msgstr "再起動"
+
+# See comment about Perform
+#: ../game/screen_sing.cc:76
+#, fuzzy
+msgid "Start performing"
+msgstr "演奏しはじめて"
+
+#: ../game/screen_sing.cc:80
+msgid "Duet mode"
+msgstr "二部合唱モード"
+
+# could 開式 be used for this?
+#: ../game/screen_sing.cc:81
+msgid "Normal mode"
+msgstr "普通モード"
+
+#: ../game/screen_sing.cc:82
+msgid "Switch between duet and regular singing mode"
+msgstr ""
+
+#: ../game/screen_sing.cc:90
+msgid "Change vocal track"
+msgstr "歌手トラックを変更する"
+
+#: ../game/screen_sing.cc:125
+msgid "Skip"
+msgstr ""
+
+#: ../game/screen_sing.cc:125
+msgid "Skip current song"
+msgstr ""
+
+#: ../game/screen_sing.cc:391
+msgid "Press UP to join dance!"
+msgstr ""
+
+#: ../game/screen_sing.cc:391
+msgid "Step UP to join!"
+msgstr ""
+
+#: ../game/screen_sing.cc:396
+msgid "Press 1 to join guitar!"
+msgstr ""
+
+#: ../game/screen_sing.cc:396
+msgid "Press GREEN to join!"
+msgstr ""
+
+#: ../game/screen_sing.cc:401
+msgid "Press SPACE to join drums!"
+msgstr ""
+
+#: ../game/screen_sing.cc:401
+msgid "KICK to join!"
+msgstr ""
+
+# maybe 無視 instead of skip?
+# is 場合は superflous?
+# インストゥルメンタル could work instead of 楽器の休憩
+# or should a のに construction be used?
+# 場合 if a hepothetical situation, とき could be better because it has a wider range of usage
+# 押して下さい is however more polite than 押す
+#: ../game/screen_sing.cc:475
+msgid "   ENTER to skip instrumental break"
+msgstr "   楽器の休憩をスキップ欲しい場合は、エンターキーを押して下さい"
+
+#: ../game/screen_sing.cc:479 ../game/screen_sing.cc:493
+msgid "   Autoplay enabled"
+msgstr ""
+
+#: ../game/screen_sing.cc:482 ../game/screen_sing.cc:490
+msgid "   Remember to wait for grading!"
+msgstr "   採点を待って忘れないで下さい"
+
+#: ../game/screen_sing.cc:606
+msgid "No player!"
+msgstr "選手がいません!"
+
+#: ../game/screen_sing.cc:613
+msgid "Hit singer"
+msgstr "ヒット歌手"
+
+#: ../game/screen_sing.cc:614
+msgid "Lead singer"
+msgstr "歌手一番"
+
+#: ../game/screen_sing.cc:615 ../game/screen_sing.cc:621
+#: ../game/screen_sing.cc:627
+msgid "Rising star"
+msgstr "上がる星"
+
+#: ../game/screen_sing.cc:616 ../game/screen_sing.cc:622
+#: ../game/screen_sing.cc:628
+msgid "Amateur"
+msgstr "素人"
+
+# from dictionary: 音痴 おんち (n,adj-no) (1) tone-deafness; amusia; having no ear for music; (adj-na) (2) tone-deaf; off-key; (suf) (3) having no sense (of something); being hopeless (when it comes to something)
+#: ../game/screen_sing.cc:617 ../game/screen_sing.cc:629
+msgid "Tone deaf"
+msgstr "音痴"
+
+#: ../game/screen_sing.cc:619
+msgid "Maniac"
+msgstr "マニアック"
+
+#: ../game/screen_sing.cc:620
+msgid "Hoofer"
+msgstr "ホーファー"
+
+# 敗者 はいしゃ (n) the defeated; vanquished; loser; could be here as well
+#: ../game/screen_sing.cc:623
+msgid "Loser"
+msgstr "負け犬"
+
+#: ../game/screen_sing.cc:625
+msgid "Virtuoso"
+msgstr "妙手"
+
+#: ../game/screen_sing.cc:626
+msgid "Rocker"
+msgstr "ロッカー"
+
+#: ../game/screen_songs.cc:278
+msgid "Sorry, no songs match the search!"
+msgstr ""
+
+#: ../game/screen_songs.cc:281
+msgid "Sorry, no songs match the filter!"
+msgstr ""
+
+#: ../game/screen_songs.cc:284
+msgid "No songs found!"
+msgstr "曲が全然見つけませんでした。"
+
+#: ../game/screen_songs.cc:285
+msgid "Visit performous.org for free songs"
+msgstr "無料曲をダウンロードに「performous.org」行って下さい"
+
+#: ../game/screen_songs.cc:303
+msgid "<type in to search>"
+msgstr ""
+
+#: ../game/screen_songs.cc:303
+msgid "songs"
+msgstr ""
+
+#: ../game/screen_songs.cc:303
+msgid "options"
+msgstr ""
+
+#: ../game/screen_songs.cc:305
+msgid "sort order: "
+msgstr ""
+
+#: ../game/screen_songs.cc:306
+msgid "type filter: "
+msgstr ""
+
+# ハイスコア or 高得点?
+#: ../game/screen_songs.cc:307
+#, fuzzy
+msgid "hiscores"
+msgstr "%1%の高得点\n"
+
+#: ../game/screen_songs.cc:307
+#, fuzzy
+msgid "jukebox mode"
+msgstr "左手モード"
+
+#: ../game/screen_songs.cc:310
+msgid "start a playlist with this song!"
+msgstr ""
+
+#: ../game/screen_songs.cc:310
+msgid "open the playlist menu"
+msgstr ""
+
+#: ../game/screen_songs.cc:502
+msgid "Play"
+msgstr ""
+
+#: ../game/screen_songs.cc:515
+msgid "View playlist"
+msgstr ""
+
+#: ../game/screen_songs.cc:516
+msgid "Clear playlist"
+msgstr ""
+
+# or perhaps a less polite for would do?
+# 見つからなかった, but that's only 2 kana less.
+#: ../game/screen_players.cc:115
+msgid "No players found!"
+msgstr "千住が見つかりませんでした"
+
+# Unless I'm wrong:
+# [S1]なら[S2] = if S1 then S2 will happen
+# or is 名前に入れば... better?
+# なら is same as 入れば only なら should be put after a noun or な-adjective,
+# so 入れば would be better.
+# however, to "insert" text like a name is 入力する and a goal can be described either as ように
+# or as ために, ように is used with verbs that don't contain volition but ために is used with verbs that do.
+# finally, from the dictionary I got: 選手 せんしゅ (n) player (in game); team member; 千住 isn't anything according to my
+#: ../game/screen_players.cc:116
+msgid "Enter a name to create a new player."
+msgstr "選手を作るように名前を入力して下さい"
+
+#: ../game/screen_players.cc:118
+msgid "Press enter to create player!"
+msgstr "エンターキーを押せば選手を作って"
+
+# or perhaps a less polite for would do?
+# 見つからなかった, but that's only 2 kana less.
+#: ../game/screen_players.cc:122
+#, fuzzy
+msgid "No players worth mentioning!"
+msgstr "千住が見つかりませんでした"
+
+#: ../game/screen_players.cc:127
+msgid "You reached %1% points!"
+msgstr "%1%点をとりました"
+
+#: ../game/screen_players.cc:128
+msgid "Change player with arrow keys."
+msgstr "矢印キーで千住を変えます。"
+
+#: ../game/screen_players.cc:129
+msgid "Name:"
+msgstr "名前:"
+
+#: ../game/screen_players.cc:132
+msgid "Type text to filter or create a new player."
+msgstr "新しい選手を作るように字を入力して下さい"
+
+# will search criteria do? 検索テクスト feels wrong to me (僕がでもが外人だ… ;)
+#: ../game/screen_players.cc:132
+msgid "Search Text:"
+msgstr "検索条件:"
+
+#: ../game/screen_audiodevices.cc:55
+msgid ""
+"It seems you have some manual configurations\n"
+"incompatible with this user interface.\n"
+"Saving these settings will override\n"
+"all existing audio device configuration.\n"
+"Your other options changes will be saved too."
+msgstr ""
+"自分の相対立する設定が有るのようです。 \n"
+"この設定をセーブするのは他の機会コンフィグレーションを上書きます。\n"
+"別の設定変更もセーブしますよ。"
+
+#: ../game/screen_audiodevices.cc:114
+msgid "- Unassigned -"
+msgstr "ー 当たらない ー"
+
+#: ../game/screen_audiodevices.cc:135
+msgid ""
+"Use arrow keys to configure. Hit Enter/Start to save and test or Esc/Select "
+"to cancel. Ctrl + R to reset defaults"
+msgstr ""
+"矢印キーはコンフィギアーのに使います。エンターとスタートはセーブとテストのに"
+"使ってエスケープとセレクトはキャンセルのにつかいます。ctrl+R は設定を戻るのに"
+"使います"
+
+#: ../game/screen_audiodevices.cc:140
+msgid ""
+"For advanced device configuration, use command line parameter --audio (use --"
+"audiohelp for details)."
+msgstr ""
+
+#: ../game/screen_audiodevices.cc:188
+msgid "Some devices failed to open!"
+msgstr "機械をあけません。"
+
+#: ../game/song.hh:23
+msgid "Guitar"
+msgstr "ギタ−"
+
+#: ../game/song.hh:23
+msgid "Coop guitar"
+msgstr "コーオップ・ギター"
+
+#: ../game/song.hh:23
+msgid "Rhythm guitar"
+msgstr "リズムギター"
+
+#: ../game/song.hh:23
+msgid "Bass"
+msgstr "ベースギター"
+
+#: ../game/song.hh:23
+msgid "Drums"
+msgstr "ドラム"
+
+#: ../game/song.hh:23
+msgid "Vocals"
+msgstr "ボーカル"
+
+#: ../game/song.hh:23
+msgid "Harmonic 1"
+msgstr "ハルモニク 1"
+
+#: ../game/song.hh:23
+msgid "Harmonic 2"
+msgstr "ハルモニク 2"
+
+#: ../game/song.hh:23
+msgid "Harmonic 3"
+msgstr "ハルモニク 3"
+
+#: /tmp/xml2gettext.s2sBZ1Pogj:2
+msgid "Game"
+msgstr "ゲーム"
+
+#: /tmp/xml2gettext.s2sBZ1Pogj:3
+msgid "Gameplay related options"
+msgstr ""
+
+#: /tmp/xml2gettext.s2sBZ1Pogj:4
+msgid "Graphic"
+msgstr ""
+
+#: /tmp/xml2gettext.s2sBZ1Pogj:5
+msgid "Configure rendering and video settings"
+msgstr "Renderingとビデオのオプションを設定する"
+
+#: /tmp/xml2gettext.s2sBZ1Pogj:6
+msgid "Audio Devices"
+msgstr ""
+
+#: /tmp/xml2gettext.s2sBZ1Pogj:7
+msgid "Setup microphones and playback"
+msgstr ""
+
+#: /tmp/xml2gettext.s2sBZ1Pogj:8
+msgid "Audio"
+msgstr "オーディオ"
+
+#: /tmp/xml2gettext.s2sBZ1Pogj:9
+msgid "Configure general audio settings"
+msgstr "全般オーディオのオプションを設定する"
+
+#: /tmp/xml2gettext.s2sBZ1Pogj:10
+msgid "Paths"
+msgstr "パス"
+
+#: /tmp/xml2gettext.s2sBZ1Pogj:11
+msgid "Setup song and data paths"
+msgstr ""
+
+# could 開式 be used for this?
+#: /tmp/xml2gettext.s2sBZ1Pogj:12
+msgid "Karaoke mode"
+msgstr "カラオケモード"
+
+#: /tmp/xml2gettext.s2sBZ1Pogj:13
+msgid "Hide pitch wave, notes and scoring."
+msgstr ""
+
+# could 開式 be used for this?
+#: /tmp/xml2gettext.s2sBZ1Pogj:14
+#, fuzzy
+msgid "Karaoke mode centered text"
+msgstr "文はカラオケモードで画面中に"
+
+#: /tmp/xml2gettext.s2sBZ1Pogj:15
+msgid "Place the text in center of the screen during karaoke-mode."
+msgstr ""
+
+#: /tmp/xml2gettext.s2sBZ1Pogj:16
+msgid "Autoplay"
+msgstr ""
+
+#: /tmp/xml2gettext.s2sBZ1Pogj:17
+msgid "Keep playing random songs after the playlist is empty."
+msgstr ""
+
+#: /tmp/xml2gettext.s2sBZ1Pogj:18
+msgid "Pitch waves"
+msgstr ""
+
+#: /tmp/xml2gettext.s2sBZ1Pogj:19
+msgid "Enable singing pitch display (when not in karaoke mode)."
+msgstr ""
+
+# Note: skin
+#: /tmp/xml2gettext.s2sBZ1Pogj:20
+msgid "Theme"
+msgstr "スキン"
+
+#: /tmp/xml2gettext.s2sBZ1Pogj:21
+msgid "Name of the theme to use."
+msgstr ""
+
+#: /tmp/xml2gettext.s2sBZ1Pogj:22
+msgid "Keyboard as guitar"
+msgstr ""
+
+#: /tmp/xml2gettext.s2sBZ1Pogj:23
+msgid "Enable keyboard as guitar (Frets on Fire mode)."
+msgstr ""
+
+#: /tmp/xml2gettext.s2sBZ1Pogj:24
+msgid "Keyboard as drumkit"
+msgstr ""
+
+#: /tmp/xml2gettext.s2sBZ1Pogj:25
+msgid "Enable keyboard as drumkit."
+msgstr ""
+
+#: /tmp/xml2gettext.s2sBZ1Pogj:26
+msgid "Keyboard as dance pad"
+msgstr ""
+
+#: /tmp/xml2gettext.s2sBZ1Pogj:27
+msgid "Enable keyboard as dance pad."
+msgstr ""
+
+#: /tmp/xml2gettext.s2sBZ1Pogj:28
+msgid "Keyboard as keytar"
+msgstr ""
+
+#: /tmp/xml2gettext.s2sBZ1Pogj:29
+msgid "Enable keyboard as keytar."
+msgstr ""
+
+#: /tmp/xml2gettext.s2sBZ1Pogj:30
+msgid "Force controller A's type"
+msgstr ""
+
+#: /tmp/xml2gettext.s2sBZ1Pogj:31
+msgid ""
+"Override autodetection and force the first controller to the given type."
+msgstr ""
+
+#: /tmp/xml2gettext.s2sBZ1Pogj:32
+msgid "Force controller B's type"
+msgstr ""
+
+#: /tmp/xml2gettext.s2sBZ1Pogj:33
+msgid ""
+"Override autodetection and force the second controller to the given type."
+msgstr ""
+
+#: /tmp/xml2gettext.s2sBZ1Pogj:34
+msgid "Force controller C's type"
+msgstr ""
+
+#: /tmp/xml2gettext.s2sBZ1Pogj:35
+msgid ""
+"Override autodetection and force the third controller to the given type."
+msgstr ""
+
+#: /tmp/xml2gettext.s2sBZ1Pogj:36
+msgid "Force controller D's type"
+msgstr ""
+
+#: /tmp/xml2gettext.s2sBZ1Pogj:37
+msgid ""
+"Override autodetection and force the fourth controller to the given type."
+msgstr ""
+
+#: /tmp/xml2gettext.s2sBZ1Pogj:38
+msgid "Joystick configuration"
+msgstr ""
+
+#: /tmp/xml2gettext.s2sBZ1Pogj:39
+msgid "Force joystick to some kind of instrument."
+msgstr ""
+
+#: /tmp/xml2gettext.s2sBZ1Pogj:40
+msgid "Hardware MIDI input device"
+msgstr ""
+
+#: /tmp/xml2gettext.s2sBZ1Pogj:41
+msgid ""
+"Regex for matching the MIDI devices to use. The default is to use all "
+"available devices."
+msgstr ""
+
+#: /tmp/xml2gettext.s2sBZ1Pogj:42
+msgid "Fallback song encoding"
+msgstr ""
+
+#: /tmp/xml2gettext.s2sBZ1Pogj:43
+msgid "Pick the text codec used for song files that are not UTF-8."
+msgstr ""
+
+#: /tmp/xml2gettext.s2sBZ1Pogj:44
+msgid "Windowed width"
+msgstr ""
+
+#: /tmp/xml2gettext.s2sBZ1Pogj:45
+msgid "The width of the window."
+msgstr ""
+
+#: /tmp/xml2gettext.s2sBZ1Pogj:46
+msgid "Windowed height"
+msgstr ""
+
+#: /tmp/xml2gettext.s2sBZ1Pogj:47
+msgid "The height of the window."
+msgstr ""
+
+#: /tmp/xml2gettext.s2sBZ1Pogj:48
+msgid "Fullscreen mode"
+msgstr ""
+
+#: /tmp/xml2gettext.s2sBZ1Pogj:49
+msgid "Enable fullscreen mode on startup."
+msgstr ""
+
+#: /tmp/xml2gettext.s2sBZ1Pogj:50
+msgid "Stereoscopic 3D"
+msgstr ""
+
+#: /tmp/xml2gettext.s2sBZ1Pogj:51
+msgid "Enable 3D rendering of Performous."
+msgstr ""
+
+#: /tmp/xml2gettext.s2sBZ1Pogj:52
+msgid "Stereo3D type"
+msgstr ""
+
+#: /tmp/xml2gettext.s2sBZ1Pogj:53
+msgid "Some modes may only get activated in fullscreen mode."
+msgstr ""
+
+#: /tmp/xml2gettext.s2sBZ1Pogj:54
+msgid "Stereo3D separation"
+msgstr ""
+
+#: /tmp/xml2gettext.s2sBZ1Pogj:55
+msgid ""
+"The strength of the effect. Experiment with different settings for best "
+"results."
+msgstr ""
+
+#: /tmp/xml2gettext.s2sBZ1Pogj:56
+msgid "Video playback"
+msgstr ""
+
+#: /tmp/xml2gettext.s2sBZ1Pogj:57
+msgid ""
+"Allows completely disabling background videos. It is recommended to leave "
+"this enabled as Performous will still smoothly fade out the video if your "
+"computer is not fast enough."
+msgstr ""
+
+#: /tmp/xml2gettext.s2sBZ1Pogj:58
+msgid "Webcam background"
+msgstr ""
+
+#: /tmp/xml2gettext.s2sBZ1Pogj:59
+msgid ""
+"Performous can use webcam as a background video. Disable it if Performous "
+"crashes while entering a song."
+msgstr ""
+
+#: /tmp/xml2gettext.s2sBZ1Pogj:60
+msgid "Webcam id"
+msgstr ""
+
+#: /tmp/xml2gettext.s2sBZ1Pogj:61
+msgid ""
+"Use -1 to autodetect or a number starting from 0 to choose specific device."
+msgstr ""
+
+#: /tmp/xml2gettext.s2sBZ1Pogj:62
+msgid "SVG quality"
+msgstr "SVGの品質"
+
+#: /tmp/xml2gettext.s2sBZ1Pogj:63
+msgid ""
+"Larger numbers cause vector graphics to be rendered in higher resolution. "
+"Decrease this to make navigating in menus faster."
+msgstr ""
+
+#: /tmp/xml2gettext.s2sBZ1Pogj:64
+msgid "Text quality"
+msgstr "テクストの品質"
+
+#: /tmp/xml2gettext.s2sBZ1Pogj:65
+msgid ""
+"Larger numbers cause text to be rendered in higher resolution. Decrease this "
+"to make everything a little faster."
+msgstr ""
+
+#: /tmp/xml2gettext.s2sBZ1Pogj:66
+msgid "Benchmark mode"
+msgstr ""
+
+#: /tmp/xml2gettext.s2sBZ1Pogj:67
+msgid ""
+"Framerate limit of 100 FPS is removed and the game instead renders at full "
+"speed. FPS values are printed to console. Please note that the display "
+"drivers may still limit the rendering speed to the screen refresh rate."
+msgstr ""
+
+#: /tmp/xml2gettext.s2sBZ1Pogj:68
+msgid "Suggested latency"
+msgstr ""
+
+#: /tmp/xml2gettext.s2sBZ1Pogj:69
+msgid ""
+"This is a hint for the audio engine about the desired latency. Set this as "
+"low as possible while retaining clear audio playback. Requires restart."
+msgstr ""
+
+#: /tmp/xml2gettext.s2sBZ1Pogj:70
+msgid "Audio/video latency"
+msgstr ""
+
+#: /tmp/xml2gettext.s2sBZ1Pogj:71
+msgid ""
+"Affects all modes. Use negative value if your display input lag is greater "
+"than the sound card output latency, positive values in the opposite case and "
+"zero if they are equal. This should be set so that the notes pass the cursor "
+"at the same time the audio is heard. Use Ctrl+F1/F2 to adjust this while "
+"performing."
+msgstr ""
+
+#: /tmp/xml2gettext.s2sBZ1Pogj:72
+msgid "Audio round-trip latency"
+msgstr ""
+
+#: /tmp/xml2gettext.s2sBZ1Pogj:73
+msgid ""
+"Affects singing only. The time it takes for Performous playback to reach "
+"your speakers, fly to the microphone and all the way back until Performous "
+"captures and analyzes it. While performing, press Ctrl+S for synth mode and "
+"adjust with Ctrl+F3/F4."
+msgstr ""
+
+#: /tmp/xml2gettext.s2sBZ1Pogj:74
+msgid "Audio/controller latency"
+msgstr ""
+
+#: /tmp/xml2gettext.s2sBZ1Pogj:75
+msgid ""
+"Affects instruments and dancing only. The total of USB (guitar or dance pad) "
+"latency combined with audio output latency. Adjust so that you can hit the "
+"notes best when playing by ear (not looking on screen). Use Ctrl+F5/F6 to "
+"adjust while performing."
+msgstr ""
+
+#: /tmp/xml2gettext.s2sBZ1Pogj:76
+msgid "Audio devices"
+msgstr ""
+
+#: /tmp/xml2gettext.s2sBZ1Pogj:77
+msgid "List of audio devices to try."
+msgstr ""
+
+#: /tmp/xml2gettext.s2sBZ1Pogj:78
+msgid "Menu volume"
+msgstr "メニューの音量"
+
+#: /tmp/xml2gettext.s2sBZ1Pogj:79
+msgid "The volume level of menus, song previews and jukebox mode."
+msgstr ""
+
+#: /tmp/xml2gettext.s2sBZ1Pogj:80
+msgid "Music volume"
+msgstr "音楽の音量"
+
+#: /tmp/xml2gettext.s2sBZ1Pogj:81
+msgid ""
+"The ingame music volume. Values above 90 are not recommended as distortion "
+"may occur."
+msgstr ""
+
+#: /tmp/xml2gettext.s2sBZ1Pogj:82
+msgid "Failure volume"
+msgstr "失敗の音量"
+
+#: /tmp/xml2gettext.s2sBZ1Pogj:83
+msgid ""
+"The ingame fail sound volume. Values above 90 are not recommended as "
+"distortion may occur. 11 is louder than 10, but these go to 100. 89 louder!"
+msgstr ""
+
+#: /tmp/xml2gettext.s2sBZ1Pogj:84
+msgid "Microphone pass-through"
+msgstr ""
+
+#: /tmp/xml2gettext.s2sBZ1Pogj:85
+msgid "Send captured singing voice to speakers."
+msgstr ""
+
+#: /tmp/xml2gettext.s2sBZ1Pogj:86
+msgid "Pass-through volume ratio"
+msgstr ""
+
+#: /tmp/xml2gettext.s2sBZ1Pogj:87
+msgid "How much voice is amplified compared to the music."
+msgstr ""
+
+#: /tmp/xml2gettext.s2sBZ1Pogj:88
+msgid "Song folders"
+msgstr ""
+
+#: /tmp/xml2gettext.s2sBZ1Pogj:89
+msgid ""
+"Where to recursively look for songs. DATADIR at the beginning means all "
+"Performous data folders."
+msgstr ""
+
+#: /tmp/xml2gettext.s2sBZ1Pogj:90
+msgid "Base folders for data"
+msgstr ""
+
+#: /tmp/xml2gettext.s2sBZ1Pogj:91
+msgid ""
+"System defaults are included automatically. Additional paths can be added "
+"here."
+msgstr ""
+
+#, fuzzy
+#~ msgid "Back to song browser"
+#~ msgstr "音楽ブラウザに終了する"
+
+#~ msgid "Song is broken!"
+#~ msgstr "音楽が壊れています!"
+
+#~ msgid "Loading instruments..."
+#~ msgstr "楽器を読み込み中…"
+
+#~ msgid "Finalizing..."
+#~ msgstr "纏め中"
+
+#, fuzzy
+#~ msgid "Loading graphics..."
+#~ msgstr "音楽を読み込み中…"
+
+#~ msgid "Random background..."
+#~ msgstr "ランダム・バックグラウンド"
diff --git a/lang/nl.po b/lang/nl.po
new file mode 100644 (file)
index 0000000..c3fa3e7
--- /dev/null
@@ -0,0 +1,1063 @@
+msgid ""
+msgstr ""
+"Project-Id-Version: performous\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2013-07-13 17:59+0200\n"
+"PO-Revision-Date: \n"
+"Last-Translator: FooBar\n"
+"Language-Team: \n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"X-Poedit-KeywordsList: _\n"
+"X-Poedit-Basepath: .\n"
+"X-Generator: Poedit 1.5.4\n"
+"X-Poedit-SearchPath-0: ../game\n"
+"X-Poedit-SearchPath-1: ../data\n"
+
+#: ../game/configuration.cc:112
+msgid "Enabled"
+msgstr "Ingeschakeld"
+
+#: ../game/configuration.cc:112
+msgid "Disabled"
+msgstr "Uitgeschakeld"
+
+#: ../game/configuration.cc:116
+#, c-format
+msgid "%d items"
+msgstr "%d items"
+
+#: ../game/screen_playlist.cc:110 ../game/screen_playlist.cc:252
+msgid "Continue"
+msgstr "Doorgaan"
+
+#: ../game/screen_playlist.cc:110
+msgid "Continue playing"
+msgstr "Doorgaan met spelen"
+
+#: ../game/screen_playlist.cc:118
+msgid "Add songs"
+msgstr "Nummers toevoegen"
+
+#: ../game/screen_playlist.cc:118
+msgid "Open the song browser to add more songs"
+msgstr "Open de muziekverkenner om meer nummers toe te voegen."
+
+#: ../game/screen_playlist.cc:119 ../game/screen_songs.cc:509
+msgid "Shuffle"
+msgstr "Door elkaar"
+
+#: ../game/screen_playlist.cc:119
+msgid "Randomize the order of the playlist"
+msgstr "Gooi de volgorde van de afspeellijst door elkaar"
+
+#: ../game/screen_playlist.cc:125
+msgid "Clear and exit"
+msgstr "Leegmaken en afsluiten"
+
+#: ../game/screen_playlist.cc:125
+msgid "Remove all the songs from the list"
+msgstr "Haal alle nummers uit de lijst"
+
+#: ../game/screen_playlist.cc:131 ../game/screen_playlist.cc:275
+#: ../game/screen_songs.cc:522
+msgid "Back"
+msgstr "Terug"
+
+#: ../game/screen_playlist.cc:131 ../game/screen_playlist.cc:275
+msgid "Back to playlist viewer"
+msgstr "Terug naar afspeellijstoverzicht"
+
+#: ../game/screen_playlist.cc:237
+msgid "Press enter to view song options"
+msgstr "Druk op enter om nummeropties weer te geven."
+
+#: ../game/screen_playlist.cc:244
+msgid "View more options"
+msgstr "Meer opties"
+
+#: ../game/screen_playlist.cc:244
+msgid "View general playlist settings"
+msgstr "Pas algemene afspeellijstinstellingen aan"
+
+#: ../game/screen_playlist.cc:252
+msgid "Play first"
+msgstr "Speel als eerste"
+
+#: ../game/screen_playlist.cc:254
+msgid "Ignore the playlist's order and play this song first"
+msgstr "Negeer de volgorde van de afspeellijst en speel dit nummer als eerste"
+
+#: ../game/screen_playlist.cc:255
+msgid "Start the song already!"
+msgstr "Start het nummer eens!"
+
+#: ../game/screen_playlist.cc:264
+msgid "Remove"
+msgstr "Verwijderen"
+
+#: ../game/screen_playlist.cc:264
+msgid "Remove this song from the list"
+msgstr "Verwijder dit nummer uit de lijst"
+
+#: ../game/screen_paths.cc:24
+msgid ""
+"This tool is not yet available.\n"
+"Configure paths by adding them\n"
+"as command line parameters and\n"
+"then save them in configuration menu."
+msgstr ""
+"Deze functie is nog niet beschikbaar.\n"
+"Pas de locaties aan door deze toe te voegen\n"
+"als commando parameters en\n"
+"daarna op te slaan in het optie menu."
+
+#: ../game/screen_paths.cc:70
+msgid "Press any key to exit."
+msgstr "Druk een toets om dit scherm te verlaten."
+
+#: ../game/screen_paths.cc:76
+#, fuzzy
+msgid "Windows users can also use ConfigureSongDirectory.bat script."
+msgstr ""
+"Windowsgebruikers kunnen ook gebruik maken van ConfigureSongDirectory.bat in "
+"de bin-directory."
+
+#: ../game/dancegraph.cc:18
+msgid "Beginner"
+msgstr "Beginner"
+
+#: ../game/dancegraph.cc:18 ../game/guitargraph.cc:14
+msgid "Easy"
+msgstr "Gemakkelijk"
+
+#: ../game/dancegraph.cc:18 ../game/guitargraph.cc:14
+msgid "Medium"
+msgstr "Medium"
+
+#: ../game/dancegraph.cc:18 ../game/guitargraph.cc:14
+msgid "Hard"
+msgstr "Moeilijk"
+
+#: ../game/dancegraph.cc:18
+msgid "Challenge"
+msgstr "Daag uit"
+
+#: ../game/dancegraph.cc:107 ../game/guitargraph.cc:194
+msgid "Ready!"
+msgstr "Klaar!"
+
+#: ../game/dancegraph.cc:107 ../game/guitargraph.cc:194
+#: ../game/screen_intro.cc:166
+msgid "Start performing!"
+msgstr "Opvoering starten!"
+
+#: ../game/dancegraph.cc:118 ../game/guitargraph.cc:183
+msgid "Select track"
+msgstr "Selecteer track"
+
+#: ../game/dancegraph.cc:134 ../game/guitargraph.cc:163
+msgid "Select difficulty"
+msgstr "Selecteer moeilijkheidsgraad"
+
+#: ../game/dancegraph.cc:137 ../game/instrumentgraph.cc:59
+#: ../game/guitargraph.cc:200 ../game/screen_intro.cc:184
+#: ../game/screen_sing.cc:92 ../game/screen_sing.cc:126
+msgid "Quit"
+msgstr "Afsluiten"
+
+#: ../game/dancegraph.cc:137 ../game/instrumentgraph.cc:59
+#: ../game/guitargraph.cc:200 ../game/screen_sing.cc:92
+#: ../game/screen_sing.cc:126
+msgid "Exit to song browser"
+msgstr "Ga naar muziekverkenner"
+
+#: ../game/dancegraph.cc:248
+msgid "STOP!"
+msgstr "STOP!"
+
+#: ../game/dancegraph.cc:321 ../game/guitargraph.cc:447
+msgid "Streak!"
+msgstr "Streak!"
+
+#: ../game/instrumentgraph.cc:56 ../game/screen_sing.cc:123
+msgid "Resume"
+msgstr "Hervatten"
+
+#: ../game/instrumentgraph.cc:56 ../game/screen_sing.cc:123
+msgid "Back to performing!"
+msgstr "Terug naar optreden!"
+
+#: ../game/instrumentgraph.cc:57
+msgid "Rejoin"
+msgstr "Opnieuw meedoen"
+
+#: ../game/instrumentgraph.cc:57
+msgid "Change selections"
+msgstr "Wijzig selecties"
+
+#: ../game/instrumentgraph.cc:58 ../game/screen_sing.cc:124
+msgid "Restart"
+msgstr "Herstart"
+
+#: ../game/instrumentgraph.cc:58 ../game/screen_sing.cc:124
+msgid ""
+"Start the song\n"
+"from the beginning"
+msgstr ""
+"Start het lied\n"
+"vanaf het begin"
+
+#: ../game/songs.cc:178
+msgid "show all songs"
+msgstr "Laat alle nummers zien"
+
+#: ../game/songs.cc:179
+msgid "has dance"
+msgstr "heeft dans"
+
+#: ../game/songs.cc:180
+msgid "has vocals"
+msgstr "heeft zang"
+
+#: ../game/songs.cc:181
+msgid "has duet"
+msgstr "heeft duet"
+
+#: ../game/songs.cc:182
+msgid "has guitar"
+msgstr "heeft gitaar"
+
+#: ../game/songs.cc:183
+msgid "drums or keytar"
+msgstr "drums of toetsengitaar"
+
+#: ../game/songs.cc:184
+msgid "full band"
+msgstr "volledige band"
+
+#: ../game/songs.cc:212
+msgid "random order"
+msgstr "willekeurige volgorde"
+
+#: ../game/songs.cc:213
+msgid "sorted by song"
+msgstr "gesorteerd op titel"
+
+#: ../game/songs.cc:214
+msgid "sorted by artist"
+msgstr "gesorteerd op artiest"
+
+#: ../game/songs.cc:215
+msgid "sorted by edition"
+msgstr "gesorteerd op editie"
+
+#: ../game/songs.cc:216
+msgid "sorted by genre"
+msgstr "gesorteerd op genre"
+
+#: ../game/songs.cc:217
+msgid "sorted by path"
+msgstr "gesorteerd op pad"
+
+#: ../game/songs.cc:218
+msgid "sorted by language"
+msgstr "gesorteerd op taal"
+
+#: ../game/screen_audiodevices.cc:55
+msgid ""
+"It seems you have some manual configurations\n"
+"incompatible with this user interface.\n"
+"Saving these settings will override\n"
+"all existing audio device configuration.\n"
+"Your other options changes will be saved too."
+msgstr ""
+"Het lijkt erop dat je enkele handmatige opties hebt\n"
+"die niet compatibel zijn met deze interface.\n"
+"Opslaan van deze instellingen zal de bestaande\n"
+"opties voor audio-apparaten overschrijven.\n"
+"De andere optiewijzigingen zullen ook opgeslagen worden."
+
+#: ../game/screen_audiodevices.cc:114
+msgid "- Unassigned -"
+msgstr "- Niet toegewezen -"
+
+#: ../game/screen_audiodevices.cc:135
+msgid ""
+"Use arrow keys to configure. Hit Enter/Start to save and test or Esc/Select "
+"to cancel. Ctrl + R to reset defaults"
+msgstr ""
+"Gebruik de pijltjestoetsen om aan te passen. Duw Enter/Start om op te slaan "
+"en te testen of Esc/Select om te annuleren. Ctrl + R laadt de standaardopties"
+
+#: ../game/screen_audiodevices.cc:140
+msgid ""
+"For advanced device configuration, use command line parameter --audio (use --"
+"audiohelp for details)."
+msgstr ""
+"Voor geavanceerde apparaatinstellingen, gebruik de commandolijnparameter --"
+"audio (voor details: --audiohelp)."
+
+#: ../game/screen_audiodevices.cc:188
+msgid "Some devices failed to open!"
+msgstr "Openen van sommige apparaten is gefaald!"
+
+#: ../game/main.cc:145
+msgid "Loading audio samples..."
+msgstr "Laden geluiden..."
+
+#: ../game/main.cc:159
+msgid "Creating screens..."
+msgstr "Schermen aanmaken..."
+
+#: ../game/main.cc:169
+msgid "Entering main menu"
+msgstr "Hoofdmenu tonen"
+
+#: ../game/main.cc:171 ../game/screen_sing.cc:97
+msgid "Loading complete"
+msgstr "Laden afgerond"
+
+#: ../game/main.cc:182
+msgid "Screenshot taken!"
+msgstr "Schermafdruk genomen!"
+
+#: ../game/main.cc:185
+msgid "Screenshot failed!"
+msgstr "Schermafdruk nemen mislukt!"
+
+#: ../game/guitargraph.cc:14
+msgid "Kids"
+msgstr "Kinderen"
+
+#: ../game/guitargraph.cc:14
+msgid "Expert"
+msgstr "Expert"
+
+#: ../game/guitargraph.cc:169 ../game/guitargraph.cc:186
+msgid "Lefty-mode"
+msgstr "Linkshandige modus"
+
+#: ../game/guitargraph.cc:207
+msgid "ON"
+msgstr "AAN"
+
+#: ../game/guitargraph.cc:207
+msgid "OFF"
+msgstr "UIT"
+
+#: ../game/guitargraph.cc:208
+msgid "Toggle lefty-mode"
+msgstr "Linkshandige modus aan/uit"
+
+#: ../game/guitargraph.cc:459
+msgid ""
+"God Mode\n"
+"Activated!"
+msgstr ""
+"God Mode\n"
+"Geactiveerd!"
+
+#: ../game/guitargraph.cc:460
+msgid "Mistakes ignored!"
+msgstr "Fouten genegeerd!"
+
+#: ../game/guitargraph.cc:1102
+msgid "God Mode Ready!"
+msgstr "God Mode Klaar!"
+
+#: ../game/guitargraph.cc:1103
+msgid "Drum Fill!"
+msgstr "Drum Fill!"
+
+#: ../game/guitargraph.cc:1106
+msgid "Solo!"
+msgstr "Solo!"
+
+#: ../game/screen_songs.cc:278
+msgid "Sorry, no songs match the search!"
+msgstr "filter geeft geen resultaat"
+
+#: ../game/screen_songs.cc:281
+msgid "Sorry, no songs match the filter!"
+msgstr "Filter geeft geen resultaat"
+
+#: ../game/screen_songs.cc:284
+msgid "No songs found!"
+msgstr "Geen liedjes gevonden!"
+
+#: ../game/screen_songs.cc:285
+msgid "Visit performous.org for free songs"
+msgstr "Bezoek performous.org voor gratis nummers"
+
+#: ../game/screen_songs.cc:303
+msgid "<type in to search>"
+msgstr "<typ tekst om te zoeken>"
+
+#: ../game/screen_songs.cc:303
+msgid "songs"
+msgstr "nummers"
+
+#: ../game/screen_songs.cc:303
+msgid "options"
+msgstr "opties"
+
+#: ../game/screen_songs.cc:305
+msgid "sort order: "
+msgstr "sorteervolgorde:"
+
+#: ../game/screen_songs.cc:306
+msgid "type filter: "
+msgstr "type sortering:"
+
+#: ../game/screen_songs.cc:307
+msgid "hiscores"
+msgstr "scores"
+
+#: ../game/screen_songs.cc:307
+msgid "jukebox mode"
+msgstr "jukebox modus"
+
+#: ../game/screen_songs.cc:310
+msgid "start a playlist with this song!"
+msgstr "begin een afspeellijst met dit nummer!"
+
+#: ../game/screen_songs.cc:310
+msgid "open the playlist menu"
+msgstr "open het afspeellijst menu"
+
+#: ../game/screen_songs.cc:502
+msgid "Play"
+msgstr "Afspelen"
+
+#: ../game/screen_songs.cc:515
+msgid "View playlist"
+msgstr "Bekijk afspeellijst"
+
+#: ../game/screen_songs.cc:516
+msgid "Clear playlist"
+msgstr "Afspeellijst wissen"
+
+#: ../game/screen_intro.cc:24
+msgid "No playback devices could be used.\n"
+msgstr "Geen bruikbare afspeelapparaten.\n"
+
+#: ../game/screen_intro.cc:25
+msgid ""
+"\n"
+"Please configure some before playing."
+msgstr ""
+"\n"
+"Gelieve dit eerst in te stellen."
+
+#: ../game/screen_intro.cc:69
+msgid "Settings saved as system defaults."
+msgstr "Instellingen opgeslagen als systeem-standaard"
+
+#: ../game/screen_intro.cc:69
+msgid "Settings saved."
+msgstr "Instellingen opgeslagen"
+
+#: ../game/screen_intro.cc:149
+msgid "Ctrl + S to save, Ctrl + R to reset defaults"
+msgstr "Ctrl + S: opslaan, Ctrl + R: standaardinstellingen"
+
+#: ../game/screen_intro.cc:166
+msgid "Perform"
+msgstr "Optreden"
+
+#: ../game/screen_intro.cc:167
+msgid "Practice"
+msgstr "Oefenen"
+
+#: ../game/screen_intro.cc:167
+msgid "Check your skills or test the microphones"
+msgstr "Je vaardigheden testen en de microfoons controleren"
+
+#: ../game/screen_intro.cc:183
+msgid "Configure"
+msgstr "Opties"
+
+#: ../game/screen_intro.cc:183
+msgid "Configure audio and game options"
+msgstr "Aanpassen geluids- en spelinstellingen"
+
+#: ../game/screen_intro.cc:184
+msgid "Leave the game"
+msgstr "Spel verlaten"
+
+#: ../game/screen_players.cc:115
+msgid "No players found!"
+msgstr "Geen spelers gevonden!"
+
+#: ../game/screen_players.cc:116
+msgid "Enter a name to create a new player."
+msgstr "Voer een naam in om een nieuwe speler aan te maken."
+
+#: ../game/screen_players.cc:118
+msgid "Press enter to create player!"
+msgstr "Druk op enter om de nieuwe speler te maken!"
+
+#: ../game/screen_players.cc:122
+msgid "No players worth mentioning!"
+msgstr "Geen spelers gevonden!"
+
+#: ../game/screen_players.cc:127
+msgid "You reached %1% points!"
+msgstr "Je hebt %1% punten behaald!"
+
+#: ../game/screen_players.cc:128
+msgid "Change player with arrow keys."
+msgstr "Verander de speler met de pijltjes-toetsen"
+
+#: ../game/screen_players.cc:129
+msgid "Name:"
+msgstr "Naam:"
+
+#: ../game/screen_players.cc:132
+msgid "Type text to filter or create a new player."
+msgstr "Typ tekst om te zoeken of een nieuwe speler aan te maken."
+
+#: ../game/screen_players.cc:132
+msgid "Search Text:"
+msgstr "Zoek op tekst:"
+
+#: ../game/screen_sing.cc:45
+msgid "Initializing webcam..."
+msgstr "Initialiseren webcam..."
+
+#: ../game/screen_sing.cc:52
+msgid "Loading video..."
+msgstr "Laden video..."
+
+#: ../game/screen_sing.cc:59
+msgid "Loading song..."
+msgstr "Laden nummer..."
+
+#: ../game/screen_sing.cc:66
+msgid "Song contains broken tracks!"
+msgstr "Lied bevat kapotte tracks!"
+
+#: ../game/screen_sing.cc:71
+msgid "Loading menu..."
+msgstr "Laden menu..."
+
+#: ../game/screen_sing.cc:76
+msgid "Start"
+msgstr "Start"
+
+#: ../game/screen_sing.cc:76
+msgid "Start performing"
+msgstr "Optreden starten!"
+
+#: ../game/screen_sing.cc:80
+msgid "Duet mode"
+msgstr "Duet modus"
+
+#: ../game/screen_sing.cc:81
+msgid "Normal mode"
+msgstr "Normale modus"
+
+#: ../game/screen_sing.cc:82
+msgid "Switch between duet and regular singing mode"
+msgstr "Wissel tussen duet en normale zangmodus."
+
+#: ../game/screen_sing.cc:90
+msgid "Change vocal track"
+msgstr ""
+"Verander van zanger\n"
+"(herstart vereist)"
+
+#: ../game/screen_sing.cc:125
+msgid "Skip"
+msgstr "Overslaan"
+
+#: ../game/screen_sing.cc:125
+msgid "Skip current song"
+msgstr "Sla huidig nummer over"
+
+#: ../game/screen_sing.cc:391
+msgid "Press UP to join dance!"
+msgstr "Druk op ↑ om mee te dansen!"
+
+#: ../game/screen_sing.cc:391
+msgid "Step UP to join!"
+msgstr "Ga op ↑ staan om mee te doen!"
+
+#: ../game/screen_sing.cc:396
+msgid "Press 1 to join guitar!"
+msgstr "Druk op 1 om mee te spelen op gitaar!"
+
+#: ../game/screen_sing.cc:396
+msgid "Press GREEN to join!"
+msgstr "Druk op GROEN om mee te doen!"
+
+#: ../game/screen_sing.cc:401
+msgid "Press SPACE to join drums!"
+msgstr "Druk op SPATIE om mee te drummen!"
+
+#: ../game/screen_sing.cc:401
+msgid "KICK to join!"
+msgstr "TRAP om mee te doen!"
+
+#: ../game/screen_sing.cc:475
+msgid "   ENTER to skip instrumental break"
+msgstr "   ENTER: sla muzikaal stuk over"
+
+#: ../game/screen_sing.cc:476
+msgid "   Remember to wait for grading!"
+msgstr "   Wacht A.U.B. op de uitslag!"
+
+#: ../game/screen_sing.cc:587
+msgid "No player!"
+msgstr "Geen speler!"
+
+#: ../game/screen_sing.cc:594
+msgid "Hit singer"
+msgstr "Hitzanger"
+
+#: ../game/screen_sing.cc:595
+msgid "Lead singer"
+msgstr "Solozanger"
+
+#: ../game/screen_sing.cc:596 ../game/screen_sing.cc:602
+#: ../game/screen_sing.cc:608
+msgid "Rising star"
+msgstr "Opkomende ster"
+
+#: ../game/screen_sing.cc:597 ../game/screen_sing.cc:603
+#: ../game/screen_sing.cc:609
+msgid "Amateur"
+msgstr "Amateur"
+
+#: ../game/screen_sing.cc:598 ../game/screen_sing.cc:610
+msgid "Tone deaf"
+msgstr "Toondoof"
+
+#: ../game/screen_sing.cc:600
+msgid "Maniac"
+msgstr "Maniak"
+
+#: ../game/screen_sing.cc:601
+msgid "Hoofer"
+msgstr "Professional"
+
+#: ../game/screen_sing.cc:604
+msgid "Loser"
+msgstr "Verliezer"
+
+#: ../game/screen_sing.cc:606
+msgid "Virtuoso"
+msgstr "Virtuoos"
+
+#: ../game/screen_sing.cc:607
+msgid "Rocker"
+msgstr "Rocker"
+
+#~ msgid "<type in to search>   ↔ songs    ↕ options"
+#~ msgstr "<typ om te zoeken> ↔ nummers  ↕ opties"
+
+#~ msgid "↔ hiscores   ↵ jukebox mode"
+#~ msgstr "↔ scores  ↵ jukebox mode"
+
+#~ msgid "Start the game with all songs in playlist"
+#~ msgstr "Start het spel met alle nummers in de afspeellijst"
+
+#~ msgid "View the current playlist"
+#~ msgstr "Bekijk de huidige afspellijst"
+
+#~ msgid "Back to song browser"
+#~ msgstr "Ga naar muziekverkenner"
+
+#~ msgid "No Items up to now."
+#~ msgstr "Geen item tot nu toe."
+
+#~ msgid "Be the first to be listed here!"
+#~ msgstr "Wees de eerste hier!"
+
+#~ msgid "Guitar"
+#~ msgstr "Gitaar"
+
+#~ msgid "Coop guitar"
+#~ msgstr "Coop gitaar"
+
+#~ msgid "Rhythm guitar"
+#~ msgstr "Ritmegitaar"
+
+#~ msgid "Bass"
+#~ msgstr "Bas"
+
+#~ msgid "Drums"
+#~ msgstr "Drum"
+
+#~ msgid "Vocals"
+#~ msgstr "Stemmen"
+
+#~ msgid "Harmonic 1"
+#~ msgstr "Harmonische 1"
+
+#~ msgid "Harmonic 2"
+#~ msgstr "Harmonische 2"
+
+#~ msgid "Harmonic 3"
+#~ msgstr "Harmonische 3"
+
+#~ msgid "Song is broken!"
+#~ msgstr "Nummer is kapot!"
+
+#~ msgid "Loading instruments..."
+#~ msgstr "Laden instrumenten..."
+
+#~ msgid "Finalizing..."
+#~ msgstr "Beëindigen"
+
+#, fuzzy
+#~ msgid "Loading graphics..."
+#~ msgstr "Laden lied..."
+
+#~ msgid "Random background..."
+#~ msgstr "Willekeurige achtergrond"
+
+#~ msgid "(press END to view hiscores)"
+#~ msgstr "(gebruik END-toets om recordscores te zien)"
+
+#~ msgid "Audio Devices"
+#~ msgstr "Geluidsapparaten"
+
+#~ msgid "Setup microphones and playback"
+#~ msgstr "Regel microfoons en afspelen"
+
+#~ msgid "Audio"
+#~ msgstr "Geluid"
+
+#~ msgid "Graphics"
+#~ msgstr "Visueel"
+
+#~ msgid "Configure rendering and video settings"
+#~ msgstr "Aanpassen render- en video-instellingen"
+
+#~ msgid "Game"
+#~ msgstr "Spel"
+
+#~ msgid "Gameplay related options"
+#~ msgstr "Aan spel gerelateerde opties"
+
+#~ msgid "Paths"
+#~ msgstr "Locaties"
+
+#~ msgid "Setup song and data paths"
+#~ msgstr "Aanpassen locatie van liedjes en bestanden"
+
+#~ msgid "Gameplay settings."
+#~ msgstr "Spelopties."
+
+#~ msgid "Graphic"
+#~ msgstr "Grafisch"
+
+#~ msgid "Video and rendering settings."
+#~ msgstr "Beeld- en tekenopties."
+
+#~ msgid "Audio-related settings."
+#~ msgstr "Aan geluid gerelateerde opties."
+
+#~ msgid "System paths."
+#~ msgstr "Systeemlocaties"
+
+#~ msgid "Hide pitch wave, notes and scoring."
+#~ msgstr "Verberg toonhoogte, noten en sores."
+
+#~ msgid "Pitch waves"
+#~ msgstr "Toonhoogte golven"
+
+#~ msgid "Enable singing pitch display (when not in karaoke mode)."
+#~ msgstr "Toon toonhoogte (indien niet in karaoke modus)."
+
+#~ msgid "Theme"
+#~ msgstr "Thema"
+
+#~ msgid "Name of the theme to use or absolute path to theme folder."
+#~ msgstr "Naam van het thema of absoluut pad naar themamap."
+
+#~ msgid "Keyboard as guitar"
+#~ msgstr "Keyboard als gitaar"
+
+#~ msgid "Enable keyboard as guitar (Frets on Fire mode)."
+#~ msgstr "Gebruik keyboard als gitaar (Frets on Fire modus)."
+
+#~ msgid "Keyboard as drumkit"
+#~ msgstr "Keyboard als drumstel"
+
+#~ msgid "Enable keyboard as drumkit."
+#~ msgstr "Gebruik keyboard als drumstel."
+
+#~ msgid "Keyboard as dance pad"
+#~ msgstr "Keyboard als dance pad"
+
+#~ msgid "Enable keyboard as dance pad."
+#~ msgstr "Gebruik keyboard als dance pad."
+
+#, fuzzy
+#~ msgid "Keyboard as keyboard"
+#~ msgstr "Keyboard als gitaar"
+
+#, fuzzy
+#~ msgid "Enable keyboard as keyboard."
+#~ msgstr "Gebruik keyboard als dance pad."
+
+#~ msgid "Joystick configuration"
+#~ msgstr "Joystickinstellingen"
+
+#~ msgid "Force joystick to some kind of instrument."
+#~ msgstr "Forceer joystick als een soort instrument."
+
+#~ msgid "Hardware MIDI input device"
+#~ msgstr "Hardware MIDI invoerapparaat"
+
+#~ msgid ""
+#~ "Part of sound card name or its number or empty to use the first available "
+#~ "device. Used currently for MIDI drum controllers."
+#~ msgstr ""
+#~ "Deel van de geluidskaartnaam of zijn nummer of leeg om het eerste "
+#~ "beschikbare apparaat te gebruiken. Momenteel gebruikt voor MIDI drum "
+#~ "controllers."
+
+#~ msgid "Windowed width"
+#~ msgstr "Breedte in venstermodus"
+
+#~ msgid "The width of the window."
+#~ msgstr "De breedte van het venster."
+
+#~ msgid "Windowed height"
+#~ msgstr "Hoogte in venstermodus"
+
+#~ msgid "The height of the window."
+#~ msgstr "De hoogte van het venster."
+
+#~ msgid "Fullscreen mode"
+#~ msgstr "Fullscreen modus"
+
+#~ msgid "Enable fullscreen mode on startup."
+#~ msgstr "Gebruik fullscreen modus vanaf het starten."
+
+#~ msgid "Stereoscopic 3D"
+#~ msgstr "Stereoscopisch 3D"
+
+#~ msgid "Enable 3D rendering of Performous."
+#~ msgstr "Schake 3D-tekeningen van Performous in."
+
+#~ msgid "Stereo3D type"
+#~ msgstr "Stereo3D-type"
+
+#~ msgid "Some modes may only get activated in fullscreen mode."
+#~ msgstr "Sommige functies zullen alleen werken in Volledig-scherm modus."
+
+#~ msgid "Stereo3D separation"
+#~ msgstr "Stereo3D-sterkte"
+
+#~ msgid ""
+#~ "The strength of the effect. Experiment with different settings for best "
+#~ "results."
+#~ msgstr ""
+#~ "De sterkte van het effect, Probeer verschillende instellingen voor de "
+#~ "beste resultaten."
+
+#~ msgid "Video playback"
+#~ msgstr "Video weergave..."
+
+#~ msgid ""
+#~ "Allows completely disabling background videos. It is recommended to leave "
+#~ "this enabled as Performous will still smoothly fade out the video if your "
+#~ "computer is not fast enough."
+#~ msgstr ""
+#~ "Staat je toe de achtergrondvideo's volledig af te zetten. Het is "
+#~ "aangeraden om dit aan te laten aangezien Performous de video zacht zal "
+#~ "uitfaden als je computer niet snel genoeg is."
+
+#~ msgid "Webcam background"
+#~ msgstr "Webcam achtergrond"
+
+# this was translated as "disable it if it annoys you"
+#, fuzzy
+#~ msgid ""
+#~ "Performous can use webcam as a background video. Disable it if Performous "
+#~ "crashes while entering a song."
+#~ msgstr ""
+#~ "Performous kan een webcam als achtergrond proberen te gebruiken. Je kan "
+#~ "dit afzetten als performous vastloopt bij het spelen van een nummer."
+
+#~ msgid "Webcam id"
+#~ msgstr "Webcam id"
+
+#~ msgid ""
+#~ "Use -1 to autodetect or a number starting from 0 to choose specific "
+#~ "device."
+#~ msgstr ""
+#~ "Gebruik -1 om automatisch te detecteren of een nummer vanaf 0 om een "
+#~ "specifiek apparaat te kiezen."
+
+#~ msgid "3D notes"
+#~ msgstr "3D noten"
+
+#~ msgid ""
+#~ "Draw instrument notes as 3-dimensional objects. May hurt performance on "
+#~ "older hardware."
+#~ msgstr ""
+#~ "Teken instrumentnoten als 3-dimensionale objecten. Kan een negatieve "
+#~ "invloed hebben op prestaties op oudere hardware."
+
+#~ msgid "SVG quality"
+#~ msgstr "SVG-kwaliteit"
+
+#~ msgid ""
+#~ "Larger numbers cause vector graphics to be rendered in higher resolution. "
+#~ "Decrease this to make navigating in menus faster."
+#~ msgstr ""
+#~ "Grotere getallen zorgen voor het renderen van vectorafbeeldingen in "
+#~ "hogere resolutie. Verlaag dit om het navigeren in menu's vlugger te maken."
+
+#~ msgid "Text quality"
+#~ msgstr "Tekstkwaliteit"
+
+#~ msgid ""
+#~ "Larger numbers cause text to be rendered in higher resolution. Decrease "
+#~ "this to make everything a little faster."
+#~ msgstr ""
+#~ "Grotere getallen zorgen voor een rendering in hogere resolutie. Verlaag "
+#~ "dit om alles wat vlugger te maken."
+
+#~ msgid "Benchmark mode"
+#~ msgstr "Benchmark modus"
+
+#~ msgid ""
+#~ "Framerate limit of 100 FPS is removed and the game instead renders at "
+#~ "full speed. FPS values are printed to console. Please note that the "
+#~ "display drivers may still limit the rendering speed to the screen refresh "
+#~ "rate."
+#~ msgstr ""
+#~ "De framerate limiet van 100 FPS is verwijderd en het spel rendert nu op "
+#~ "volle snelheid. FPS waarden worden geprint in de console. De "
+#~ "beeldkaartdrivers kunnen nog altijd de rendersnelheid beperking tot de "
+#~ "refresh rate van het scherm"
+
+#~ msgid "Suggested latency"
+#~ msgstr "Voorgestelde latency"
+
+#~ msgid ""
+#~ "This is a hint for the audio engine about the desired latency. Set this "
+#~ "as low as possible while retaining clear audio playback. Requires restart."
+#~ msgstr ""
+#~ "Dit is een suggestie voor de latency voor de geluidverwerking. Zet dit zo "
+#~ "laag mogelijk terwijl je goed geluid behoudt. Vereist een herstart."
+
+#~ msgid "Audio/video latency"
+#~ msgstr "Geluid/video latency"
+
+#~ msgid ""
+#~ "Affects all modes. Use negative value if your display input lag is "
+#~ "greater than the sound card output latency, positive values in the "
+#~ "opposite case and zero if they are equal. This should be set so that the "
+#~ "notes pass the cursor at the same time the audio is heard. Use Ctrl+F1/F2 "
+#~ "to adjust this while performing."
+#~ msgstr ""
+#~ "Heeft effect op alle modussen. Gebruik negatieve waarden als je "
+#~ "scherminvoervertraging groter is dan de geluidskaard outputlatency, "
+#~ "gebruik positieve waarden in het omgekeerde geval en nul als ze gelijk "
+#~ "zijn. Dit zou zo gezet moeten worden dat de noten de cursor passeren op "
+#~ "hetzelfde moment dat het geluid te horen is. Gebruik Ctrl+F1/F2 om aan te "
+#~ "passen tijdens het opvoeren."
+
+#~ msgid "Audio round-trip latency"
+#~ msgstr "Geluid round-trip latency"
+
+#~ msgid ""
+#~ "Affects singing only. The time it takes for Performous playback to reach "
+#~ "your speakers, fly to the microphone and all the way back until "
+#~ "Performous captures and analyzes it. While performing, press Ctrl+S for "
+#~ "synth mode and adjust with Ctrl+F3/F4."
+#~ msgstr ""
+#~ "Heeft enkel effect tijdens het zingen. De tijd die het Performousgeluid "
+#~ "nodig heeft om de luidsprekers te bereiken, naar de microfoons te vliegen "
+#~ "en de ganse weg terug tot Performous het opvangt en analyseert. Gebruik "
+#~ "Ctrl+S voor synth mode en Ctrl+F3/F4 om aan te passen tijdens het "
+#~ "opvoeren."
+
+#~ msgid "Audio/controller latency"
+#~ msgstr "Geluid/controller latency"
+
+#~ msgid ""
+#~ "Affects instruments and dancing only. The total of USB (guitar or dance "
+#~ "pad) latency combined with audio output latency. Adjust so that you can "
+#~ "hit the notes best when playing by ear (not looking on screen). Use Ctrl"
+#~ "+F5/F6 to adjust while performing."
+#~ msgstr ""
+#~ "Heeft enkel effect op instrumenten en dansen. De totale USB- (gitaar of "
+#~ "dancepad) latency, gecombineerd met de geluidlatency. Aanpassen zodat je "
+#~ "de noten goed kunt treffen tijdens het spelen op gehoor (zonder te kijken "
+#~ "op het scherm). Gebruik Ctrl+F5/F6 om aan te passen tijdens het opvoeren."
+
+#~ msgid "Audio devices"
+#~ msgstr "Geluidsapparaten"
+
+#~ msgid "List of audio devices to try."
+#~ msgstr "Lijst van te proberen geluidsapparaten."
+
+#~ msgid "Menu volume"
+#~ msgstr "Menu volume"
+
+#~ msgid "The volume level of menus, song previews and jukebox mode."
+#~ msgstr "Het volumeniveau voor menu's, liedvoorbeelden en jukebox modus."
+
+#~ msgid "Music volume"
+#~ msgstr "Muziekvolume"
+
+#~ msgid ""
+#~ "The ingame music volume. Values above 90 are not recommended as "
+#~ "distortion may occur."
+#~ msgstr ""
+#~ "Volume voor muziek tijdens het spel. Waarden boven 90 zijn niet "
+#~ "aangeraden aangezien dan vervorming kan voorkomen."
+
+#~ msgid "Failure volume"
+#~ msgstr "Foutboodschapvolume"
+
+#~ msgid ""
+#~ "The ingame fail sound volume. Values above 90 are not recommended as "
+#~ "distortion may occur. 11 is louder than 10, but these go to 100. 89 "
+#~ "louder!"
+#~ msgstr ""
+#~ "Volume voor foutboodschappen tijdens het spel. Waarden boven 90 zijn niet "
+#~ "aangeraden aangezien dan vervorming kan voorkomen. 11 is luider dan 10, "
+#~ "maar het gaat tot 100."
+
+#~ msgid "Song folders"
+#~ msgstr "Mappen voor liedjes"
+
+#~ msgid ""
+#~ "Where to recursively look for songs. DATADIR at the beginning means all "
+#~ "Performous data folders."
+#~ msgstr ""
+#~ "Locatie om recursief te zoeken naar liedjes. DATADIR in het begin "
+#~ "betekent alle Performous mappen voor data."
+
+#~ msgid "Base folders for data"
+#~ msgstr "Basismappen voor gegevens"
+
+#~ msgid ""
+#~ "System defaults are included automatically. Additional paths can be added "
+#~ "here."
+#~ msgstr ""
+#~ "Systeem standaardinstellingen worden automatisch geladen. Extra locaties "
+#~ "kunnen hier toegevoegd worden."
+
+#~ msgid "Loading theme..."
+#~ msgstr "Laden thema..."
+
+#~ msgid "Loading background..."
+#~ msgstr "Laden achtergrond..."
+
+#~ msgid "Loading user interface..."
+#~ msgstr "Laden gebruikersinterface..."
+
+#~ msgid "Miscellaneous..."
+#~ msgstr "Diversen..."
diff --git a/lang/performous.pot b/lang/performous.pot
new file mode 100644 (file)
index 0000000..5a35540
--- /dev/null
@@ -0,0 +1,851 @@
+# SOME DESCRIPTIVE TITLE.
+# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
+# This file is distributed under the same license as the PACKAGE package.
+# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
+#
+#, fuzzy
+msgid ""
+msgstr ""
+"Project-Id-Version: PACKAGE VERSION\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2011-04-10 23:42+0300\n"
+"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
+"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
+"Language-Team: LANGUAGE <LL@li.org>\n"
+"Language: \n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=CHARSET\n"
+"Content-Transfer-Encoding: 8bit\n"
+"X-Poedit-KeywordsList: _\n"
+"X-Poedit-Basepath: .\n"
+"X-Poedit-SearchPath-0: ../game\n"
+"X-Poedit-SearchPath-1: ../data\n"
+
+#: ../game/song.hh:36
+msgid "Guitar"
+msgstr ""
+
+#: ../game/song.hh:36
+msgid "Coop guitar"
+msgstr ""
+
+#: ../game/song.hh:36
+msgid "Rhythm guitar"
+msgstr ""
+
+#: ../game/song.hh:36
+msgid "Bass"
+msgstr ""
+
+#: ../game/song.hh:36
+msgid "Drums"
+msgstr ""
+
+#: ../game/song.hh:36
+msgid "Vocals"
+msgstr ""
+
+#: ../game/song.hh:36
+msgid "Harmonic 1"
+msgstr ""
+
+#: ../game/song.hh:36
+msgid "Harmonic 2"
+msgstr ""
+
+#: ../game/song.hh:36
+msgid "Harmonic 3"
+msgstr ""
+
+#: ../game/dancegraph.cc:18
+msgid "Beginner"
+msgstr ""
+
+#: ../game/dancegraph.cc:18
+#: ../game/guitargraph.cc:14
+msgid "Easy"
+msgstr ""
+
+#: ../game/dancegraph.cc:18
+#: ../game/guitargraph.cc:14
+msgid "Medium"
+msgstr ""
+
+#: ../game/dancegraph.cc:18
+#: ../game/guitargraph.cc:14
+msgid "Hard"
+msgstr ""
+
+#: ../game/dancegraph.cc:18
+msgid "Challenge"
+msgstr ""
+
+#: ../game/dancegraph.cc:111
+#: ../game/guitargraph.cc:197
+msgid "Ready!"
+msgstr ""
+
+#: ../game/dancegraph.cc:111
+#: ../game/guitargraph.cc:197
+msgid "Start performing!"
+msgstr ""
+
+#: ../game/dancegraph.cc:122
+#: ../game/guitargraph.cc:186
+msgid "Select track"
+msgstr ""
+
+#: ../game/dancegraph.cc:138
+#: ../game/guitargraph.cc:166
+msgid "Select difficulty"
+msgstr ""
+
+#: ../game/dancegraph.cc:141
+#: ../game/guitargraph.cc:203
+msgid "Quit"
+msgstr ""
+
+#: ../game/dancegraph.cc:141
+#: ../game/guitargraph.cc:203
+msgid "Exit to song browser"
+msgstr ""
+
+#: ../game/dancegraph.cc:260
+msgid "STOP!"
+msgstr ""
+
+#: ../game/dancegraph.cc:335
+#: ../game/guitargraph.cc:482
+msgid "Streak!"
+msgstr ""
+
+#: ../game/guitargraph.cc:14
+msgid "Kids"
+msgstr ""
+
+#: ../game/guitargraph.cc:14
+msgid "Expert"
+msgstr ""
+
+#: ../game/guitargraph.cc:172
+#: ../game/guitargraph.cc:189
+msgid "Lefty-mode"
+msgstr ""
+
+#: ../game/guitargraph.cc:210
+msgid "ON"
+msgstr ""
+
+#: ../game/guitargraph.cc:210
+msgid "OFF"
+msgstr ""
+
+#: ../game/guitargraph.cc:211
+msgid "Toggle lefty-mode"
+msgstr ""
+
+#: ../game/guitargraph.cc:499
+msgid ""
+"God Mode\n"
+"Activated!"
+msgstr ""
+"Jumalmoodi\n"
+"Aktivoitu!"
+
+#: ../game/guitargraph.cc:500
+msgid "Mistakes ignored!"
+msgstr ""
+
+#: ../game/guitargraph.cc:1181
+msgid "Drum Fill!"
+msgstr ""
+
+#: ../game/guitargraph.cc:1182
+msgid "God Mode Ready!"
+msgstr ""
+
+#: ../game/guitargraph.cc:1185
+msgid "Solo!"
+msgstr ""
+
+#: ../game/configuration.cc:116
+msgid "Enabled"
+msgstr ""
+
+#: ../game/configuration.cc:116
+msgid "Disabled"
+msgstr ""
+
+#: ../game/configuration.cc:120
+#, c-format
+msgid "%d items"
+msgstr ""
+
+#: ../game/screen_sing.cc:34
+msgid "Loading song..."
+msgstr ""
+
+#: ../game/screen_sing.cc:40
+msgid "Song is broken!"
+msgstr ""
+
+#: ../game/screen_sing.cc:45
+msgid "Initializing webcam..."
+msgstr ""
+
+#: ../game/screen_sing.cc:52
+msgid "Loading video..."
+msgstr ""
+
+#: ../game/screen_sing.cc:60
+msgid "Loading instruments..."
+msgstr ""
+
+#: ../game/screen_sing.cc:82
+msgid "Loading menu..."
+msgstr ""
+
+#: ../game/screen_sing.cc:84
+msgid "Resume"
+msgstr ""
+
+#: ../game/screen_sing.cc:84
+msgid "Back to performing!"
+msgstr ""
+
+#: ../game/screen_sing.cc:85
+msgid "Restart"
+msgstr ""
+
+#: ../game/screen_sing.cc:85
+msgid ""
+"Start the song\n"
+"from the beginning"
+msgstr ""
+"Aloita kappale\n"
+"alusta uudelleen"
+
+#: ../game/screen_sing.cc:98
+msgid ""
+"Change vocal track\n"
+"(restart required)"
+msgstr ""
+"Vaihda lauluraita\n"
+"(uudelleen aloitus vaaditaan)"
+
+#: ../game/screen_sing.cc:107
+msgid "Finalizing..."
+msgstr ""
+
+#: ../game/screen_sing.cc:111
+msgid "Song contains broken tracks!"
+msgstr ""
+
+#: ../game/screen_sing.cc:113
+msgid "Loading graphics..."
+msgstr ""
+
+#: ../game/screen_sing.cc:114
+msgid "Loading complete"
+msgstr ""
+
+#: ../game/screen_sing.cc:140
+msgid "Random background..."
+msgstr ""
+
+#: ../game/screen_sing.cc:485
+msgid "   ENTER to skip instrumental break"
+msgstr ""
+
+#: ../game/screen_sing.cc:486
+msgid "   Remember to wait for grading!"
+msgstr ""
+
+#: ../game/screen_sing.cc:618
+msgid "No player!"
+msgstr ""
+
+#: ../game/screen_sing.cc:627
+msgid "Hit singer"
+msgstr ""
+
+#: ../game/screen_sing.cc:628
+msgid "Lead singer"
+msgstr ""
+
+#: ../game/screen_sing.cc:629
+#: ../game/screen_sing.cc:635
+#: ../game/screen_sing.cc:641
+msgid "Rising star"
+msgstr ""
+
+#: ../game/screen_sing.cc:630
+#: ../game/screen_sing.cc:636
+#: ../game/screen_sing.cc:642
+msgid "Amateur"
+msgstr ""
+
+#: ../game/screen_sing.cc:631
+#: ../game/screen_sing.cc:643
+msgid "Tone deaf"
+msgstr ""
+
+#: ../game/screen_sing.cc:633
+msgid "Maniac"
+msgstr ""
+
+#: ../game/screen_sing.cc:634
+msgid "Hoofer"
+msgstr ""
+
+#: ../game/screen_sing.cc:637
+msgid "Loser"
+msgstr ""
+
+#: ../game/screen_sing.cc:639
+msgid "Virtuoso"
+msgstr ""
+
+#: ../game/screen_sing.cc:640
+msgid "Rocker"
+msgstr ""
+
+#: ../game/songs.cc:205
+msgid "random order"
+msgstr ""
+
+#: ../game/songs.cc:206
+msgid "sorted by song"
+msgstr ""
+
+#: ../game/songs.cc:207
+msgid "sorted by artist"
+msgstr ""
+
+#: ../game/songs.cc:208
+msgid "sorted by edition"
+msgstr ""
+
+#: ../game/songs.cc:209
+msgid "sorted by genre"
+msgstr ""
+
+#: ../game/songs.cc:210
+msgid "sorted by path"
+msgstr ""
+
+#: ../game/songs.cc:211
+msgid "sorted by language"
+msgstr ""
+
+#: ../game/screen_players.cc:111
+msgid "No players found!"
+msgstr ""
+
+#: ../game/screen_players.cc:112
+msgid "Enter a name to create a new player."
+msgstr ""
+
+#: ../game/screen_players.cc:114
+msgid "Press enter to create player!"
+msgstr ""
+
+#: ../game/screen_players.cc:121
+msgid "You reached %1% points!"
+msgstr ""
+
+#: ../game/screen_players.cc:122
+msgid "Change player with arrow keys."
+msgstr ""
+
+#: ../game/screen_players.cc:123
+msgid "Name:"
+msgstr ""
+
+#: ../game/screen_players.cc:126
+msgid "Type text to filter or create a new player."
+msgstr ""
+
+#: ../game/screen_players.cc:126
+msgid "Search Text:"
+msgstr ""
+
+#: ../game/main.cc:134
+msgid "Loading audio samples..."
+msgstr ""
+
+#: ../game/main.cc:148
+msgid "Creating screens..."
+msgstr ""
+
+#: ../game/main.cc:157
+msgid "Entering main menu"
+msgstr ""
+
+#: ../game/main.cc:169
+msgid "Screenshot taken!"
+msgstr ""
+
+#: ../game/main.cc:172
+msgid "Screenshot failed!"
+msgstr ""
+
+#: ../game/screen_audiodevices.cc:56
+msgid ""
+"It seems you have some manual configurations\n"
+"incompatible with this user interface.\n"
+"Saving these settings will override\n"
+"all existing audio device configuration.\n"
+"Your other options changes will be saved too."
+msgstr ""
+"Näyttäisi, että sinulla on manuaalisia säätöjä,\n"
+"jotka ovat epäyhteensopivia tämän työkalun kanssa.\n"
+"Tallentaminen ylikirjoittaa kaikki aiemmat\n"
+"äänilaitevalintasi. Muut mahdolliset säädöt\n"
+"tallennetaan samalla."
+
+#: ../game/screen_audiodevices.cc:111
+msgid "- Unassigned -"
+msgstr ""
+
+#: ../game/screen_audiodevices.cc:131
+msgid "Use arrow keys to configure. Hit Enter/Start to save and test or Esc/Select to cancel. Ctrl + R to reset defaults"
+msgstr ""
+
+#: ../game/screen_audiodevices.cc:136
+msgid "For advanced device configuration, use command line parameter --audio (use --audiohelp for details)."
+msgstr ""
+
+#: ../game/screen_audiodevices.cc:191
+msgid "Some devices failed to open!"
+msgstr ""
+
+#: ../game/screen_songs.cc:213
+msgid "No songs found!"
+msgstr ""
+
+#: ../game/screen_songs.cc:214
+msgid ""
+"Visit performous.org\n"
+"for free songs"
+msgstr ""
+"Hae ilmaista musiikkia\n"
+"osoitteesta performous.org"
+
+#: ../game/screen_songs.cc:216
+msgid "no songs match search"
+msgstr ""
+
+#: ../game/screen_songs.cc:224
+msgid "(press END to view hiscores)"
+msgstr ""
+
+#: ../game/screen_songs.cc:225
+msgid "<type in to search>"
+msgstr ""
+
+#: ../game/screen_songs.cc:230
+msgid "Hisccore for %1%\n"
+msgstr ""
+
+#: ../game/instrumentgraph.cc:49
+msgid "Rejoin"
+msgstr ""
+
+#: ../game/instrumentgraph.cc:49
+msgid "Change selections"
+msgstr ""
+
+#: ../game/screen_intro.cc:24
+msgid "No playback devices could be used.\n"
+msgstr ""
+
+#: ../game/screen_intro.cc:25
+msgid ""
+"\n"
+"Please configure some before playing."
+msgstr ""
+"\n"
+"Säädä ääniasetuksia ennen pelaamista."
+
+#: ../game/screen_intro.cc:64
+msgid "Settings saved as system defaults."
+msgstr ""
+
+#: ../game/screen_intro.cc:64
+msgid "Settings saved."
+msgstr ""
+
+#: ../game/screen_intro.cc:146
+msgid "Ctrl + S to save, Ctrl + R to reset defaults"
+msgstr ""
+
+#: ../game/screen_intro.cc:160
+msgid "Perform"
+msgstr ""
+
+#: ../game/screen_intro.cc:161
+msgid "Practice"
+msgstr ""
+
+#: ../game/screen_intro.cc:161
+msgid "Check your skills or test the microphones"
+msgstr ""
+
+#: ../game/screen_intro.cc:180
+msgid "Audio Devices"
+msgstr ""
+
+#: ../game/screen_intro.cc:180
+msgid "Setup microphones and playback"
+msgstr ""
+
+#: ../game/screen_intro.cc:181
+msgid "Audio"
+msgstr ""
+
+#: ../game/screen_intro.cc:181
+msgid "Configure general audio settings"
+msgstr ""
+
+#: ../game/screen_intro.cc:182
+msgid "Graphics"
+msgstr ""
+
+#: ../game/screen_intro.cc:182
+msgid "Configure rendering and video settings"
+msgstr ""
+
+#: ../game/screen_intro.cc:183
+msgid "Game"
+msgstr ""
+
+#: ../game/screen_intro.cc:183
+msgid "Gameplay related options"
+msgstr ""
+
+#: ../game/screen_intro.cc:184
+msgid "Paths"
+msgstr ""
+
+#: ../game/screen_intro.cc:184
+msgid "Setup song and data paths"
+msgstr ""
+
+#: ../game/screen_intro.cc:186
+msgid "Configure"
+msgstr ""
+
+#: ../game/screen_intro.cc:186
+msgid "Configure audio and game options"
+msgstr ""
+
+#: ../game/screen_intro.cc:189
+msgid "Leave the game"
+msgstr ""
+
+#: ../game/screen_paths.cc:24
+msgid ""
+"This tool is not yet available.\n"
+"Configure paths by adding them\n"
+"as command line parameters and\n"
+"then save them in configuration menu."
+msgstr ""
+"Tämä työkalu ei ole vielä saatavilla.\n"
+"Aseta polut antamalla ne\n"
+"komentoriviparametreinä ja\n"
+"tallenna ne sitten asetusvalikosta."
+
+#: ../game/screen_paths.cc:69
+msgid "Press any key to exit."
+msgstr ""
+
+#: ../game/screen_paths.cc:74
+msgid "Windows users can also use ConfigureSongDirectory.bat in the bin-directory."
+msgstr ""
+
+#: ../game/database.cc:107
+#: ../game/database.cc:127
+msgid "No Items up to now."
+msgstr ""
+
+#: ../game/database.cc:108
+#: ../game/database.cc:128
+msgid "Be the first to be listed here!"
+msgstr ""
+
+#: /tmp/xml2gettext.n68PNWaJWN:3
+msgid "Gameplay settings."
+msgstr ""
+
+#: /tmp/xml2gettext.n68PNWaJWN:4
+msgid "Graphic"
+msgstr ""
+
+#: /tmp/xml2gettext.n68PNWaJWN:5
+msgid "Video and rendering settings."
+msgstr ""
+
+#: /tmp/xml2gettext.n68PNWaJWN:7
+msgid "Audio-related settings."
+msgstr ""
+
+#: /tmp/xml2gettext.n68PNWaJWN:9
+msgid "System paths."
+msgstr ""
+
+#: /tmp/xml2gettext.n68PNWaJWN:10
+msgid "Karaoke mode"
+msgstr ""
+
+#: /tmp/xml2gettext.n68PNWaJWN:11
+msgid "Hide pitch wave, notes and scoring."
+msgstr ""
+
+#: /tmp/xml2gettext.n68PNWaJWN:12
+msgid "Pitch waves"
+msgstr ""
+
+#: /tmp/xml2gettext.n68PNWaJWN:13
+msgid "Enable singing pitch display (when not in karaoke mode)."
+msgstr ""
+
+#: /tmp/xml2gettext.n68PNWaJWN:14
+msgid "Theme"
+msgstr ""
+
+#: /tmp/xml2gettext.n68PNWaJWN:15
+msgid "Name of the theme to use or absolute path to theme folder."
+msgstr ""
+
+#: /tmp/xml2gettext.n68PNWaJWN:16
+msgid "Keyboard as guitar"
+msgstr ""
+
+#: /tmp/xml2gettext.n68PNWaJWN:17
+msgid "Enable keyboard as guitar (Frets on Fire mode)."
+msgstr ""
+
+#: /tmp/xml2gettext.n68PNWaJWN:18
+msgid "Keyboard as drumkit"
+msgstr ""
+
+#: /tmp/xml2gettext.n68PNWaJWN:19
+msgid "Enable keyboard as drumkit."
+msgstr ""
+
+#: /tmp/xml2gettext.n68PNWaJWN:20
+msgid "Keyboard as dance pad"
+msgstr ""
+
+#: /tmp/xml2gettext.n68PNWaJWN:21
+msgid "Enable keyboard as dance pad."
+msgstr ""
+
+#: /tmp/xml2gettext.n68PNWaJWN:22
+msgid "Keyboard as keyboard"
+msgstr ""
+
+#: /tmp/xml2gettext.n68PNWaJWN:23
+msgid "Enable keyboard as keyboard."
+msgstr ""
+
+#: /tmp/xml2gettext.n68PNWaJWN:24
+msgid "Joystick configuration"
+msgstr ""
+
+#: /tmp/xml2gettext.n68PNWaJWN:25
+msgid "Force joystick to some kind of instrument."
+msgstr ""
+
+#: /tmp/xml2gettext.n68PNWaJWN:26
+msgid "Hardware MIDI input device"
+msgstr ""
+
+#: /tmp/xml2gettext.n68PNWaJWN:27
+msgid "Part of sound card name or its number or empty to use the first available device. Used currently for MIDI drum controllers."
+msgstr ""
+
+#: /tmp/xml2gettext.n68PNWaJWN:28
+msgid "Windowed width"
+msgstr ""
+
+#: /tmp/xml2gettext.n68PNWaJWN:29
+msgid "The width of the window."
+msgstr ""
+
+#: /tmp/xml2gettext.n68PNWaJWN:30
+msgid "Windowed height"
+msgstr ""
+
+#: /tmp/xml2gettext.n68PNWaJWN:31
+msgid "The height of the window."
+msgstr ""
+
+#: /tmp/xml2gettext.n68PNWaJWN:32
+msgid "Fullscreen mode"
+msgstr ""
+
+#: /tmp/xml2gettext.n68PNWaJWN:33
+msgid "Enable fullscreen mode on startup."
+msgstr ""
+
+#: /tmp/xml2gettext.n68PNWaJWN:34
+msgid "Stereoscopic 3D"
+msgstr ""
+
+#: /tmp/xml2gettext.n68PNWaJWN:35
+msgid "Enable 3D rendering of Performous."
+msgstr ""
+
+#: /tmp/xml2gettext.n68PNWaJWN:36
+msgid "Stereo3D type"
+msgstr ""
+
+#: /tmp/xml2gettext.n68PNWaJWN:37
+msgid "Some modes may only get activated in fullscreen mode."
+msgstr ""
+
+#: /tmp/xml2gettext.n68PNWaJWN:38
+msgid "Stereo3D separation"
+msgstr ""
+
+#: /tmp/xml2gettext.n68PNWaJWN:39
+msgid "The strength of the effect. Experiment with different settings for best results."
+msgstr ""
+
+#: /tmp/xml2gettext.n68PNWaJWN:40
+msgid "Video playback"
+msgstr ""
+
+#: /tmp/xml2gettext.n68PNWaJWN:41
+msgid "Allows completely disabling background videos. It is recommended to leave this enabled as Performous will still smoothly fade out the video if your computer is not fast enough."
+msgstr ""
+
+#: /tmp/xml2gettext.n68PNWaJWN:42
+msgid "Webcam background"
+msgstr ""
+
+#: /tmp/xml2gettext.n68PNWaJWN:43
+msgid "Performous can use webcam as a background video. Disable it if Performous crashes while entering a song."
+msgstr ""
+
+#: /tmp/xml2gettext.n68PNWaJWN:44
+msgid "Webcam id"
+msgstr ""
+
+#: /tmp/xml2gettext.n68PNWaJWN:45
+msgid "Use -1 to autodetect or a number starting from 0 to choose specific device."
+msgstr ""
+
+#: /tmp/xml2gettext.n68PNWaJWN:46
+msgid "3D notes"
+msgstr ""
+
+#: /tmp/xml2gettext.n68PNWaJWN:47
+msgid "Draw instrument notes as 3-dimensional objects. May hurt performance on older hardware."
+msgstr ""
+
+#: /tmp/xml2gettext.n68PNWaJWN:48
+msgid "SVG quality"
+msgstr ""
+
+#: /tmp/xml2gettext.n68PNWaJWN:49
+msgid "Larger numbers cause vector graphics to be rendered in higher resolution. Decrease this to make navigating in menus faster."
+msgstr ""
+
+#: /tmp/xml2gettext.n68PNWaJWN:50
+msgid "Text quality"
+msgstr ""
+
+#: /tmp/xml2gettext.n68PNWaJWN:51
+msgid "Larger numbers cause text to be rendered in higher resolution. Decrease this to make everything a little faster."
+msgstr ""
+
+#: /tmp/xml2gettext.n68PNWaJWN:52
+msgid "Benchmark mode"
+msgstr ""
+
+#: /tmp/xml2gettext.n68PNWaJWN:53
+msgid "Framerate limit of 100 FPS is removed and the game instead renders at full speed. FPS values are printed to console. Please note that the display drivers may still limit the rendering speed to the screen refresh rate."
+msgstr ""
+
+#: /tmp/xml2gettext.n68PNWaJWN:54
+msgid "Suggested latency"
+msgstr ""
+
+#: /tmp/xml2gettext.n68PNWaJWN:55
+msgid "This is a hint for the audio engine about the desired latency. Set this as low as possible while retaining clear audio playback. Requires restart."
+msgstr ""
+
+#: /tmp/xml2gettext.n68PNWaJWN:56
+msgid "Audio/video latency"
+msgstr ""
+
+#: /tmp/xml2gettext.n68PNWaJWN:57
+msgid "Affects all modes. Use negative value if your display input lag is greater than the sound card output latency, positive values in the opposite case and zero if they are equal. This should be set so that the notes pass the cursor at the same time the audio is heard. Use Ctrl+F1/F2 to adjust this while performing."
+msgstr ""
+
+#: /tmp/xml2gettext.n68PNWaJWN:58
+msgid "Audio round-trip latency"
+msgstr ""
+
+#: /tmp/xml2gettext.n68PNWaJWN:59
+msgid "Affects singing only. The time it takes for Performous playback to reach your speakers, fly to the microphone and all the way back until Performous captures and analyzes it. While performing, press Ctrl+S for synth mode and adjust with Ctrl+F3/F4."
+msgstr ""
+
+#: /tmp/xml2gettext.n68PNWaJWN:60
+msgid "Audio/controller latency"
+msgstr ""
+
+#: /tmp/xml2gettext.n68PNWaJWN:61
+msgid "Affects instruments and dancing only. The total of USB (guitar or dance pad) latency combined with audio output latency. Adjust so that you can hit the notes best when playing by ear (not looking on screen). Use Ctrl+F5/F6 to adjust while performing."
+msgstr ""
+
+#: /tmp/xml2gettext.n68PNWaJWN:62
+msgid "Audio devices"
+msgstr ""
+
+#: /tmp/xml2gettext.n68PNWaJWN:63
+msgid "List of audio devices to try."
+msgstr ""
+
+#: /tmp/xml2gettext.n68PNWaJWN:64
+msgid "Menu volume"
+msgstr ""
+
+#: /tmp/xml2gettext.n68PNWaJWN:65
+msgid "The volume level of menus, song previews and jukebox mode."
+msgstr ""
+
+#: /tmp/xml2gettext.n68PNWaJWN:66
+msgid "Music volume"
+msgstr ""
+
+#: /tmp/xml2gettext.n68PNWaJWN:67
+msgid "The ingame music volume. Values above 90 are not recommended as distortion may occur."
+msgstr ""
+
+#: /tmp/xml2gettext.n68PNWaJWN:68
+msgid "Failure volume"
+msgstr ""
+
+#: /tmp/xml2gettext.n68PNWaJWN:69
+msgid "The ingame fail sound volume. Values above 90 are not recommended as distortion may occur. 11 is louder than 10, but these go to 100. 89 louder!"
+msgstr ""
+
+#: /tmp/xml2gettext.n68PNWaJWN:70
+msgid "Song folders"
+msgstr ""
+
+#: /tmp/xml2gettext.n68PNWaJWN:71
+msgid "Where to recursively look for songs. DATADIR at the beginning means all Performous data folders."
+msgstr ""
+
+#: /tmp/xml2gettext.n68PNWaJWN:72
+msgid "Base folders for data"
+msgstr ""
+
+#: /tmp/xml2gettext.n68PNWaJWN:73
+msgid "System defaults are included automatically. Additional paths can be added here."
+msgstr ""
diff --git a/lang/pl.po b/lang/pl.po
new file mode 100644 (file)
index 0000000..ef3c471
--- /dev/null
@@ -0,0 +1,987 @@
+msgid ""
+msgstr ""
+"Project-Id-Version: Performous\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2013-05-24 12:48+0100\n"
+"PO-Revision-Date: \n"
+"Last-Translator: Tapio Vierros <tapiovierros@gmail.com>\n"
+"Language-Team: \n"
+"Language: pl_PL\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"X-Poedit-KeywordsList: _\n"
+"X-Poedit-Basepath: .\n"
+"X-Generator: Poedit 1.5.4\n"
+"X-Poedit-SearchPath-0: ../game\n"
+"X-Poedit-SearchPath-1: ../data\n"
+
+#: ../game/screen_paths.cc:24
+msgid ""
+"This tool is not yet available.\n"
+"Configure paths by adding them\n"
+"as command line parameters and\n"
+"then save them in configuration menu."
+msgstr ""
+"Opcja jeszcze nie gotowa.\n"
+"Dodaj katalogi wpisując je\n"
+"w postaci parametrów lini poleceń\n"
+"następnie zapisz ustawienia w menu."
+
+#: ../game/screen_paths.cc:70
+msgid "Press any key to exit."
+msgstr "Naciśnij dowolny klawisz aby wyjść."
+
+#: ../game/screen_paths.cc:75
+msgid ""
+"Windows users can also use ConfigureSongDirectory.bat in the bin-directory."
+msgstr ""
+"Użytkownicy systemu Windows do zmiany katalogu utworów mogą wykorzystać "
+"skrypt ConfigureSongDirectory.bat umieszczony w kat. bin"
+
+#: ../game/configuration.cc:117
+msgid "Enabled"
+msgstr "Aktywne"
+
+#: ../game/configuration.cc:117
+msgid "Disabled"
+msgstr "Nieaktywne"
+
+#: ../game/configuration.cc:121
+#, fuzzy, c-format
+msgid "%d items"
+msgstr "%d elementów"
+
+#: ../game/instrumentgraph.cc:56 ../game/screen_sing.cc:123
+msgid "Resume"
+msgstr "Kontynuuj"
+
+#: ../game/instrumentgraph.cc:56 ../game/screen_sing.cc:123
+msgid "Back to performing!"
+msgstr "Wróć do występu!"
+
+#: ../game/instrumentgraph.cc:57
+msgid "Rejoin"
+msgstr ""
+
+#: ../game/instrumentgraph.cc:57
+msgid "Change selections"
+msgstr ""
+
+#: ../game/instrumentgraph.cc:58 ../game/screen_sing.cc:124
+msgid "Restart"
+msgstr "Restart"
+
+#: ../game/instrumentgraph.cc:58 ../game/screen_sing.cc:124
+msgid ""
+"Start the song\n"
+"from the beginning"
+msgstr "Rozpocznij od nowa"
+
+#: ../game/instrumentgraph.cc:59 ../game/guitargraph.cc:200
+#: ../game/screen_intro.cc:184 ../game/dancegraph.cc:137
+#: ../game/screen_sing.cc:92 ../game/screen_sing.cc:126
+msgid "Quit"
+msgstr "Wyjdź"
+
+#: ../game/instrumentgraph.cc:59 ../game/guitargraph.cc:200
+#: ../game/dancegraph.cc:137 ../game/screen_sing.cc:92
+#: ../game/screen_sing.cc:126
+msgid "Exit to song browser"
+msgstr "Powrót do wyboru utworów."
+
+#: ../game/guitargraph.cc:14
+msgid "Kids"
+msgstr "Bardzo łatwy"
+
+#: ../game/guitargraph.cc:14 ../game/dancegraph.cc:18
+msgid "Easy"
+msgstr "Łatwy"
+
+#: ../game/guitargraph.cc:14 ../game/dancegraph.cc:18
+msgid "Medium"
+msgstr "Średni"
+
+#: ../game/guitargraph.cc:14 ../game/dancegraph.cc:18
+msgid "Hard"
+msgstr "Trudny"
+
+#: ../game/guitargraph.cc:14
+msgid "Expert"
+msgstr "Bardzo trudny"
+
+#: ../game/guitargraph.cc:163 ../game/dancegraph.cc:134
+msgid "Select difficulty"
+msgstr "Wybierz poziom trudności"
+
+#: ../game/guitargraph.cc:169 ../game/guitargraph.cc:186
+#, fuzzy
+msgid "Lefty-mode"
+msgstr "Tryb dla leworęcznych"
+
+#: ../game/guitargraph.cc:183 ../game/dancegraph.cc:118
+msgid "Select track"
+msgstr "Wybierz utwór"
+
+#: ../game/guitargraph.cc:194 ../game/dancegraph.cc:107
+msgid "Ready!"
+msgstr "Gotowy?!"
+
+#: ../game/guitargraph.cc:194 ../game/screen_intro.cc:166
+#: ../game/dancegraph.cc:107
+msgid "Start performing!"
+msgstr "Rozpocznij występ!"
+
+#: ../game/guitargraph.cc:207
+msgid "ON"
+msgstr "Włączone"
+
+#: ../game/guitargraph.cc:207
+msgid "OFF"
+msgstr "Wyłączone"
+
+#: ../game/guitargraph.cc:208
+#, fuzzy
+msgid "Toggle lefty-mode"
+msgstr "Przełącz tryb dla leworęcznych"
+
+#: ../game/guitargraph.cc:447 ../game/dancegraph.cc:319
+msgid "Streak!"
+msgstr ""
+
+#: ../game/guitargraph.cc:459
+msgid ""
+"God Mode\n"
+"Activated!"
+msgstr ""
+"God Mode\n"
+"Aktywny!"
+
+#: ../game/guitargraph.cc:460
+msgid "Mistakes ignored!"
+msgstr "Ignorowanie błędów!"
+
+#: ../game/guitargraph.cc:1102
+msgid "God Mode Ready!"
+msgstr "God Mode gotowy!"
+
+#: ../game/guitargraph.cc:1103
+msgid "Drum Fill!"
+msgstr "Podkład perkusyjny!"
+
+#: ../game/guitargraph.cc:1106
+msgid "Solo!"
+msgstr "Solo!"
+
+#: ../game/songs.cc:194
+msgid "show all songs"
+msgstr ""
+
+#: ../game/songs.cc:195
+msgid "has dance"
+msgstr ""
+
+#: ../game/songs.cc:196
+#, fuzzy
+msgid "has vocals"
+msgstr "Wokale"
+
+#: ../game/songs.cc:197
+msgid "has duet"
+msgstr ""
+
+#: ../game/songs.cc:198
+#, fuzzy
+msgid "has guitar"
+msgstr "Klawiatura w roli gitary"
+
+#: ../game/songs.cc:199
+msgid "drums or keytar"
+msgstr ""
+
+#: ../game/songs.cc:200
+msgid "full band"
+msgstr ""
+
+#: ../game/songs.cc:228
+msgid "random order"
+msgstr "losowy"
+
+#: ../game/songs.cc:229
+msgid "sorted by song"
+msgstr "sort. wg. Tytułu"
+
+#: ../game/songs.cc:230
+msgid "sorted by artist"
+msgstr "sort. wg. Artysty"
+
+#: ../game/songs.cc:231
+msgid "sorted by edition"
+msgstr "sort. wg. Źródła"
+
+#: ../game/songs.cc:232
+msgid "sorted by genre"
+msgstr "sort. wg. Gatunku"
+
+#: ../game/songs.cc:233
+msgid "sorted by path"
+msgstr "sort. wg. Katalogu"
+
+#: ../game/songs.cc:234
+msgid "sorted by language"
+msgstr "sort. wg. Języka"
+
+#: ../game/screen_intro.cc:24
+msgid "No playback devices could be used.\n"
+msgstr "Brak urządzeń odtwarzających.\n"
+
+#: ../game/screen_intro.cc:25
+msgid ""
+"\n"
+"Please configure some before playing."
+msgstr ""
+"\n"
+"Skonfiguruj zanim rozpoczniesz grę."
+
+#: ../game/screen_intro.cc:69
+msgid "Settings saved as system defaults."
+msgstr ""
+
+#: ../game/screen_intro.cc:69
+msgid "Settings saved."
+msgstr ""
+
+#: ../game/screen_intro.cc:149
+msgid "Ctrl + S to save, Ctrl + R to reset defaults"
+msgstr "Ctrl + S zapisuje ustawienia, Ctrl + R przywraca ustawienia domyślne"
+
+#: ../game/screen_intro.cc:166
+msgid "Perform"
+msgstr "Występ"
+
+#: ../game/screen_intro.cc:167
+msgid "Practice"
+msgstr "Próba"
+
+#: ../game/screen_intro.cc:167
+msgid "Check your skills or test the microphones"
+msgstr "Próba mikrofonu oraz twoich możliwości"
+
+#: ../game/screen_intro.cc:183
+msgid "Configure"
+msgstr "Opcje"
+
+#: ../game/screen_intro.cc:183
+msgid "Configure audio and game options"
+msgstr "Konfiguracja ustawień"
+
+#: ../game/screen_intro.cc:184
+msgid "Leave the game"
+msgstr "Wyjście z gry"
+
+#: ../game/dancegraph.cc:18
+msgid "Beginner"
+msgstr "Początkujący"
+
+#: ../game/dancegraph.cc:18
+msgid "Challenge"
+msgstr "Wyzwanie"
+
+#: ../game/dancegraph.cc:248
+msgid "STOP!"
+msgstr "STOP!"
+
+#: ../game/screen_playlist.cc:110 ../game/screen_playlist.cc:252
+msgid "Continue"
+msgstr ""
+
+#: ../game/screen_playlist.cc:110
+msgid "Continue playing"
+msgstr ""
+
+#: ../game/screen_playlist.cc:118
+msgid "Add songs"
+msgstr ""
+
+#: ../game/screen_playlist.cc:118
+msgid "Open the song browser to add more songs"
+msgstr ""
+
+#: ../game/screen_playlist.cc:119 ../game/screen_songs.cc:513
+msgid "Shuffle"
+msgstr ""
+
+#: ../game/screen_playlist.cc:119 ../game/screen_songs.cc:513
+msgid "Randomize the order of the playlist"
+msgstr ""
+
+#: ../game/screen_playlist.cc:125
+msgid "Clear and exit"
+msgstr ""
+
+#: ../game/screen_playlist.cc:125 ../game/screen_songs.cc:520
+msgid "Remove all the songs from the list"
+msgstr ""
+
+#: ../game/screen_playlist.cc:131 ../game/screen_playlist.cc:275
+#: ../game/screen_songs.cc:526
+msgid "Back"
+msgstr ""
+
+#: ../game/screen_playlist.cc:131 ../game/screen_playlist.cc:275
+msgid "Back to playlist viewer"
+msgstr ""
+
+#: ../game/screen_playlist.cc:237
+msgid "Press enter to view song options"
+msgstr ""
+
+#: ../game/screen_playlist.cc:244
+msgid "View more options"
+msgstr ""
+
+#: ../game/screen_playlist.cc:244
+#, fuzzy
+msgid "View general playlist settings"
+msgstr "Konfiguracja ustawień audio"
+
+#: ../game/screen_playlist.cc:252
+msgid "Play first"
+msgstr ""
+
+#: ../game/screen_playlist.cc:254
+msgid "Ignore the playlist's order and play this song first"
+msgstr ""
+
+#: ../game/screen_playlist.cc:255
+msgid "Start the song already!"
+msgstr ""
+
+#: ../game/screen_playlist.cc:264
+msgid "Remove"
+msgstr ""
+
+#: ../game/screen_playlist.cc:264
+msgid "Remove this song from the list"
+msgstr ""
+
+#: ../game/main.cc:146
+msgid "Loading audio samples..."
+msgstr "Wczytywanie sampli audio..."
+
+#: ../game/main.cc:160
+msgid "Creating screens..."
+msgstr ""
+
+#: ../game/main.cc:170
+msgid "Entering main menu"
+msgstr "Uruchamianie menu głównego"
+
+#: ../game/main.cc:172 ../game/screen_sing.cc:97
+msgid "Loading complete"
+msgstr "Wczytano"
+
+#: ../game/main.cc:183
+msgid "Screenshot taken!"
+msgstr "Utworzono zrzut ekranu!"
+
+#: ../game/main.cc:186
+msgid "Screenshot failed!"
+msgstr "Błąd tworzenia zrzutu ekranul!"
+
+#: ../game/screen_sing.cc:45
+msgid "Initializing webcam..."
+msgstr "Inicjalizacja kamery..."
+
+#: ../game/screen_sing.cc:52
+msgid "Loading video..."
+msgstr "Wczytywanie video..."
+
+#: ../game/screen_sing.cc:59
+msgid "Loading song..."
+msgstr "Wczytywanie utworu..."
+
+#: ../game/screen_sing.cc:66
+msgid "Song contains broken tracks!"
+msgstr "Utwór zawiera uszkodzone ścieżki!"
+
+#: ../game/screen_sing.cc:71
+msgid "Loading menu..."
+msgstr "Wczytywanie menu głównego…"
+
+#: ../game/screen_sing.cc:76
+#, fuzzy
+msgid "Start"
+msgstr "Restart"
+
+#: ../game/screen_sing.cc:76
+#, fuzzy
+msgid "Start performing"
+msgstr "Rozpocznij występ!"
+
+#: ../game/screen_sing.cc:80
+#, fuzzy
+msgid "Duet mode"
+msgstr "Tryb dla leworęcznych"
+
+#: ../game/screen_sing.cc:81
+#, fuzzy
+msgid "Normal mode"
+msgstr "Tryb Karaoke"
+
+#: ../game/screen_sing.cc:82
+msgid "Switch between duet and regular singing mode"
+msgstr ""
+
+#: ../game/screen_sing.cc:90
+msgid "Change vocal track"
+msgstr ""
+
+#: ../game/screen_sing.cc:125
+msgid "Skip"
+msgstr ""
+
+#: ../game/screen_sing.cc:125
+msgid "Skip current song"
+msgstr ""
+
+#: ../game/screen_sing.cc:391
+msgid "Press UP to join dance!"
+msgstr ""
+
+#: ../game/screen_sing.cc:391
+msgid "Step UP to join!"
+msgstr ""
+
+#: ../game/screen_sing.cc:396
+msgid "Press 1 to join guitar!"
+msgstr ""
+
+#: ../game/screen_sing.cc:396
+msgid "Press GREEN to join!"
+msgstr ""
+
+#: ../game/screen_sing.cc:401
+msgid "Press SPACE to join drums!"
+msgstr ""
+
+#: ../game/screen_sing.cc:401
+msgid "KICK to join!"
+msgstr ""
+
+#: ../game/screen_sing.cc:475
+msgid "   ENTER to skip instrumental break"
+msgstr "   ENTER pomija część instrumentalną"
+
+#: ../game/screen_sing.cc:476
+msgid "   Remember to wait for grading!"
+msgstr "   Pamiętaj, aby poczekać na klasyfikację!"
+
+#: ../game/screen_sing.cc:587
+msgid "No player!"
+msgstr "Brak Graczy!"
+
+#: ../game/screen_sing.cc:594
+msgid "Hit singer"
+msgstr "Gwiazda piosenki"
+
+#: ../game/screen_sing.cc:595
+msgid "Lead singer"
+msgstr "Wokalista"
+
+#: ../game/screen_sing.cc:596 ../game/screen_sing.cc:602
+#: ../game/screen_sing.cc:608
+msgid "Rising star"
+msgstr "Debiutant"
+
+#: ../game/screen_sing.cc:597 ../game/screen_sing.cc:603
+#: ../game/screen_sing.cc:609
+msgid "Amateur"
+msgstr "Amator"
+
+#: ../game/screen_sing.cc:598 ../game/screen_sing.cc:610
+msgid "Tone deaf"
+msgstr "Głuchy"
+
+#: ../game/screen_sing.cc:600
+msgid "Maniac"
+msgstr "Maniak"
+
+#: ../game/screen_sing.cc:601
+msgid "Hoofer"
+msgstr "Tancerz"
+
+#: ../game/screen_sing.cc:604
+msgid "Loser"
+msgstr "Przegrany"
+
+#: ../game/screen_sing.cc:606
+msgid "Virtuoso"
+msgstr "Wirtuoz"
+
+#: ../game/screen_sing.cc:607
+msgid "Rocker"
+msgstr "Rocker"
+
+#: ../game/screen_songs.cc:279
+msgid "No songs found!"
+msgstr "Nie znaleziono żadnych utworów!"
+
+#: ../game/screen_songs.cc:280
+msgid ""
+"Visit performous.org\n"
+"for free songs"
+msgstr ""
+"Odwiedź performous.org,\n"
+"aby pobrać darmowe utwory"
+
+#: ../game/screen_songs.cc:282
+#, fuzzy
+msgid "Sorry, no songs match the search!"
+msgstr "Brak utworów spełniających kryterium"
+
+#: ../game/screen_songs.cc:289
+#, fuzzy
+msgid "Hiscore\n"
+msgstr "Wynik dla %1%\n"
+
+#: ../game/screen_songs.cc:298
+msgid "<type in to search>   ↔ songs    ↕ options"
+msgstr ""
+
+#: ../game/screen_songs.cc:301
+msgid "↔ sort order: "
+msgstr ""
+
+#: ../game/screen_songs.cc:302
+msgid "↔ type filter: "
+msgstr ""
+
+#: ../game/screen_songs.cc:303
+msgid "↔ hiscores   ↵ jukebox mode"
+msgstr ""
+
+#: ../game/screen_songs.cc:307
+msgid "↵ start a playlist with this song!"
+msgstr ""
+
+#: ../game/screen_songs.cc:309
+msgid "↵ open the playlist menu"
+msgstr ""
+
+#: ../game/screen_songs.cc:506
+msgid "Play"
+msgstr ""
+
+#: ../game/screen_songs.cc:506
+msgid "Start the game with all songs in playlist"
+msgstr ""
+
+#: ../game/screen_songs.cc:519
+msgid "View playlist"
+msgstr ""
+
+#: ../game/screen_songs.cc:519
+msgid "View the current playlist"
+msgstr ""
+
+#: ../game/screen_songs.cc:520
+msgid "Clear playlist"
+msgstr ""
+
+#: ../game/screen_songs.cc:526
+#, fuzzy
+msgid "Back to song browser"
+msgstr "Powrót do wyboru utworów."
+
+#: ../game/screen_players.cc:115
+msgid "No players found!"
+msgstr "Nie znaleziono żadnego gracza!"
+
+#: ../game/screen_players.cc:116
+msgid "Enter a name to create a new player."
+msgstr "Podaj imię, aby utworzyć nowego gracza."
+
+#: ../game/screen_players.cc:118
+msgid "Press enter to create player!"
+msgstr "Wciśnij ENTER, aby dodać nowego gracza!"
+
+#: ../game/screen_players.cc:122
+#, fuzzy
+msgid "No players worth mentioning!"
+msgstr "Nie znaleziono żadnego gracza!"
+
+#: ../game/screen_players.cc:127
+msgid "You reached %1% points!"
+msgstr "Zdobyłeś %1% punktów!"
+
+#: ../game/screen_players.cc:128
+msgid "Change player with arrow keys."
+msgstr "Użyj strzałek, aby zmienić gracza."
+
+#: ../game/screen_players.cc:129
+msgid "Name:"
+msgstr "Imię:"
+
+#: ../game/screen_players.cc:132
+msgid "Type text to filter or create a new player."
+msgstr "Wpisz tekst aby wyszukać lub utworzyć nowego gracza."
+
+#: ../game/screen_players.cc:132
+msgid "Search Text:"
+msgstr "Wyszukaj tekst:"
+
+#: ../game/screen_audiodevices.cc:55
+msgid ""
+"It seems you have some manual configurations\n"
+"incompatible with this user interface.\n"
+"Saving these settings will override\n"
+"all existing audio device configuration.\n"
+"Your other options changes will be saved too."
+msgstr ""
+
+#: ../game/screen_audiodevices.cc:114
+#, fuzzy
+msgid "- Unassigned -"
+msgstr "-Nieprzydzielone-"
+
+#: ../game/screen_audiodevices.cc:135
+msgid ""
+"Use arrow keys to configure. Hit Enter/Start to save and test or Esc/Select "
+"to cancel. Ctrl + R to reset defaults"
+msgstr ""
+"Nawiguj za pomocą strzałek. ENTER/START aby zapisać  przetestować. ESC/"
+"SELECT aby anulować.Ctrl + R aby przywrócić wartości domyślne."
+
+#: ../game/screen_audiodevices.cc:140
+msgid ""
+"For advanced device configuration, use command line parameter --audio (use --"
+"audiohelp for details)."
+msgstr ""
+"Zaawansowanej konfiguracji dokonaj wykorzystując parametr --audio w konsoli "
+"(--audiohelp wyświetla pomoc)."
+
+#: ../game/screen_audiodevices.cc:188
+msgid "Some devices failed to open!"
+msgstr ""
+
+#: ../game/database.cc:89 ../game/database.cc:107
+#, fuzzy
+msgid "No Items up to now."
+msgstr "Lista jest pusta."
+
+#: ../game/database.cc:90 ../game/database.cc:108
+msgid "Be the first to be listed here!"
+msgstr "Bądź pierwszym na tej liście!"
+
+#: ../game/song.hh:22
+msgid "Guitar"
+msgstr "Gitara"
+
+#: ../game/song.hh:22
+msgid "Coop guitar"
+msgstr ""
+
+#: ../game/song.hh:22
+msgid "Rhythm guitar"
+msgstr ""
+
+#: ../game/song.hh:22
+msgid "Bass"
+msgstr "Gitara Basowa"
+
+#: ../game/song.hh:22
+msgid "Drums"
+msgstr "Perkusja"
+
+#: ../game/song.hh:22
+msgid "Vocals"
+msgstr "Wokale"
+
+#: ../game/song.hh:22
+msgid "Harmonic 1"
+msgstr "Harmonika 1"
+
+#: ../game/song.hh:22
+msgid "Harmonic 2"
+msgstr "Harmonika 2"
+
+#: ../game/song.hh:22
+msgid "Harmonic 3"
+msgstr "Harmonika 3"
+
+#~ msgid "Song is broken!"
+#~ msgstr "Utwór jest uszkodzony!"
+
+#~ msgid "Loading instruments..."
+#~ msgstr "Wczytywanie instrumentów..."
+
+#, fuzzy
+#~ msgid "Loading graphics..."
+#~ msgstr "Wczytywanie utworu..."
+
+#~ msgid "Random background..."
+#~ msgstr "Losowe tło..."
+
+#~ msgid "(press END to view hiscores)"
+#~ msgstr "(END wyświetla listę zwycięzców)"
+
+#~ msgid "<type in to search>"
+#~ msgstr "<wpisz szukaną frazę>"
+
+#~ msgid "Audio Devices"
+#~ msgstr "Urządzenia audio"
+
+#~ msgid "Setup microphones and playback"
+#~ msgstr "Ustawienia mikrofonów oraz odtwarzania"
+
+#~ msgid "Audio"
+#~ msgstr "Opcje Audio"
+
+#~ msgid "Graphics"
+#~ msgstr "Opcje Video"
+
+#~ msgid "Configure rendering and video settings"
+#~ msgstr "Konfiguracja ustawień video"
+
+#~ msgid "Game"
+#~ msgstr "Opcje Gry"
+
+#~ msgid "Gameplay related options"
+#~ msgstr "Konfiguracja ustawień gry"
+
+#~ msgid "Paths"
+#~ msgstr "Foldery"
+
+#~ msgid "Setup song and data paths"
+#~ msgstr "Ustawienia katalogów"
+
+#~ msgid "Gameplay settings."
+#~ msgstr "Ustawienia gry"
+
+#~ msgid "Graphic"
+#~ msgstr "Grafika"
+
+#~ msgid "Video and rendering settings."
+#~ msgstr "Ustawienia video"
+
+#~ msgid "Audio-related settings."
+#~ msgstr "Ustawnienia audio"
+
+#~ msgid "System paths."
+#~ msgstr "Katalog systemowy"
+
+#~ msgid "Hide pitch wave, notes and scoring."
+#~ msgstr ""
+#~ "Wyłącza wyświetlanie aktualnej wysokości dźwięku, nut oraz punktacji,"
+
+#~ msgid "Pitch waves"
+#~ msgstr "Wysokość dźwięku"
+
+#~ msgid "Enable singing pitch display (when not in karaoke mode)."
+#~ msgstr ""
+#~ "Aktywuje wyświetlanie aktualnej wysokości dźwięku (gdy wyłączony tryb "
+#~ "karaoke)."
+
+#~ msgid "Theme"
+#~ msgstr "Kompozycja"
+
+#~ msgid "Name of the theme to use or absolute path to theme folder."
+#~ msgstr ""
+#~ "Nazwa aktualnej kompozycji lub bezwzględna ścieżka dostępu do katalogu "
+#~ "kompozycji."
+
+#~ msgid "Enable keyboard as guitar (Frets on Fire mode)."
+#~ msgstr ""
+#~ "Wykorzystanie klawiatury jako wirtualnej gitary(Tryb \"Frets on Fire\")."
+
+#~ msgid "Keyboard as drumkit"
+#~ msgstr "Klawiatura w roli perkusji"
+
+#~ msgid "Enable keyboard as drumkit."
+#~ msgstr "Wykorzystanie klawiatury jako wirtualnej perkusji."
+
+#~ msgid "Keyboard as dance pad"
+#~ msgstr "Klawiatura w roli maty"
+
+#~ msgid "Enable keyboard as dance pad."
+#~ msgstr "Wykorzystanie klawiatury jako wirtualnej maty do tańczenia."
+
+#, fuzzy
+#~ msgid "Keyboard as keyboard"
+#~ msgstr "Klawiatura w roli gitary"
+
+#, fuzzy
+#~ msgid "Enable keyboard as keyboard."
+#~ msgstr "Wykorzystanie klawiatury jako wirtualnej maty do tańczenia."
+
+#~ msgid "Joystick configuration"
+#~ msgstr "Konfiguracja joystick'a"
+
+#~ msgid "Force joystick to some kind of instrument."
+#~ msgstr "Wykorzystaj joystick jako kontroler gry."
+
+#~ msgid "Hardware MIDI input device"
+#~ msgstr "Wejście urządzenia MIDI"
+
+#~ msgid "Windowed width"
+#~ msgstr "Szerokość okna"
+
+#~ msgid "The width of the window."
+#~ msgstr "Rozdzielczość pozioma aplikacji uruchomionej w oknie."
+
+#~ msgid "Windowed height"
+#~ msgstr "Wysokość okna"
+
+#~ msgid "The height of the window."
+#~ msgstr "Rozdzielczość pionowa aplikacji uruchomionej w oknie."
+
+#~ msgid "Fullscreen mode"
+#~ msgstr "Tryb pełnoekranowy"
+
+#~ msgid "Enable fullscreen mode on startup."
+#~ msgstr "Aktywuj tryb pełnoekranowy przy starcie."
+
+#~ msgid "Video playback"
+#~ msgstr "Odtwarzanie video"
+
+#~ msgid ""
+#~ "Allows completely disabling background videos. It is recommended to leave "
+#~ "this enabled as Performous will still smoothly fade out the video if your "
+#~ "computer is not fast enough."
+#~ msgstr ""
+#~ "Pozwala wyłączyć odtwarzanie klipów video. Zaleca się pozostawienie tej "
+#~ "opcji włączonej a Performous wyłączy klip w przypadku, gdy komputer okaże "
+#~ "się zbyt mało wydajny."
+
+#~ msgid "Webcam background"
+#~ msgstr "Obraz z kamery jako tło"
+
+#, fuzzy
+#~ msgid ""
+#~ "Performous can use webcam as a background video. Disable it if Performous "
+#~ "crashes while entering a song."
+#~ msgstr ""
+#~ "Performous może wykorzystać obraz z kamery internetowej jako tło. "
+#~ "Dezaktywuj opcję, jeśli cię drażni."
+
+#~ msgid "Webcam id"
+#~ msgstr "ID kamery internetowej"
+
+#~ msgid ""
+#~ "Use -1 to autodetect or a number starting from 0 to choose specific "
+#~ "device."
+#~ msgstr ""
+#~ "Użyj wartości -1 aby dokonać autodetekcji lub wprowadź liczbę wskazującą "
+#~ "na konkretne urządzenie."
+
+#~ msgid "3D notes"
+#~ msgstr "Nuty 3D"
+
+#~ msgid ""
+#~ "Draw instrument notes as 3-dimensional objects. May hurt performance on "
+#~ "older hardware."
+#~ msgstr ""
+#~ "Wyświetla trójwymiarowe nuty. Może powodować spadek wydajności na "
+#~ "starszym sprzęcie."
+
+#~ msgid "SVG quality"
+#~ msgstr "Jakość grafiki SVG"
+
+#~ msgid ""
+#~ "Larger numbers cause vector graphics to be rendered in higher resolution. "
+#~ "Decrease this to make navigating in menus faster."
+#~ msgstr ""
+#~ "Wyższe wartości spowodują, że grafika wektorowa będzie renderowana w "
+#~ "wyższej rozdzielczości, niższe przyspieszą działanie menu."
+
+#~ msgid "Text quality"
+#~ msgstr "Jakość tekstu"
+
+#~ msgid ""
+#~ "Larger numbers cause text to be rendered in higher resolution. Decrease "
+#~ "this to make everything a little faster."
+#~ msgstr ""
+#~ "Wyższe wartości spowodują, że tekst będzie renderowany w wyższej "
+#~ "rozdzielczości, niższe przyspieszą działanie menu."
+
+#~ msgid "Benchmark mode"
+#~ msgstr "Tryb Benchmark"
+
+#~ msgid ""
+#~ "Framerate limit of 100 FPS is removed and the game instead renders at "
+#~ "full speed. FPS values are printed to console. Please note that the "
+#~ "display drivers may still limit the rendering speed to the screen refresh "
+#~ "rate."
+#~ msgstr ""
+#~ "Znosi limit dot. maks. wartości FPS.Aktualna wartość FPS wyświetlana jest "
+#~ "w konsoli. Jednak sterowniki karty graficznej mogą wciąż ograniczać ilość "
+#~ "FPS do wartości wyznaczonej przez częstotliwość odświerzania ekranu."
+
+#~ msgid "Suggested latency"
+#~ msgstr "Zalecane opóźnienie"
+
+#~ msgid "Audio/video latency"
+#~ msgstr "Opóźnienie audio/video"
+
+#~ msgid "Audio round-trip latency"
+#~ msgstr "Opóźnienie wokalu"
+
+#~ msgid "Audio/controller latency"
+#~ msgstr "Opóźnienie kontrolera"
+
+#~ msgid "Audio devices"
+#~ msgstr "Urządzenia audio"
+
+#~ msgid "List of audio devices to try."
+#~ msgstr "Lista dostępnych urządzeń audio"
+
+#~ msgid "Menu volume"
+#~ msgstr "Głośność menu"
+
+#~ msgid "The volume level of menus, song previews and jukebox mode."
+#~ msgstr "Głośność menu, podglądu utworów oraz w trybie Grającej szafy."
+
+#~ msgid "Music volume"
+#~ msgstr "Glośność muzyki"
+
+#~ msgid ""
+#~ "The ingame music volume. Values above 90 are not recommended as "
+#~ "distortion may occur."
+#~ msgstr ""
+#~ "Głośność muzyki podczas gry. Wartości powyżej 90 mogą powodować "
+#~ "zniekształcenia."
+
+#~ msgid "Song folders"
+#~ msgstr "Katalog utworów"
+
+#~ msgid ""
+#~ "Where to recursively look for songs. DATADIR at the beginning means all "
+#~ "Performous data folders."
+#~ msgstr "Katalog ten jest przeszukiwany rekursywnie w poszukiwaniu utworów."
+
+#~ msgid "Base folders for data"
+#~ msgstr "Katalogi danych"
+
+#~ msgid "Loading theme..."
+#~ msgstr "Wczytywanie kompozycji..."
+
+#~ msgid "Loading background..."
+#~ msgstr "Wczytywanie tła..."
+
+#~ msgid "Loading user interface..."
+#~ msgstr "Wczytywanie interfejsu urzytkownika..."
+
+#, fuzzy
+#~ msgid "Audio..."
+#~ msgstr "Audio"
+
+#, fuzzy
+#~ msgid "Press Enter to configure (TODO: implement)"
+#~ msgstr "Bestätige Enter, um dies zu Konfigurieren"
+
+#~ msgid "Miscellaneous..."
+#~ msgstr "Sonstiges …"
+
+#~ msgid "System"
+#~ msgstr "System"
diff --git a/lang/pt_BR.po b/lang/pt_BR.po
new file mode 100644 (file)
index 0000000..3b8a771
--- /dev/null
@@ -0,0 +1,1072 @@
+# Brazilian Portuguese translation for Performous
+# Copyright (C) 2006-2012 Performous Devel Team
+# This file is distributed under the same license as the Performous package.
+# Rafael Ferreira <rafael.f.f1@gmail.com>, 2012.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: Performous\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2013-05-24 12:48+0100\n"
+"PO-Revision-Date: 2013-05-24 12:48+0100\n"
+"Last-Translator: Rafael Ferreira <rafael.f.f1@gmail.com>\n"
+"Language-Team: \n"
+"Language: Português (Brasil)\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"X-Poedit-KeywordsList: _\n"
+"X-Poedit-Basepath: .\n"
+"Plural-Forms: nplurals=2; plural=(n > 1);\n"
+"X-Generator: Poedit 1.5.4\n"
+"X-Poedit-SearchPath-0: ../game\n"
+"X-Poedit-SearchPath-1: ../data\n"
+
+#: ../game/screen_paths.cc:24
+msgid ""
+"This tool is not yet available.\n"
+"Configure paths by adding them\n"
+"as command line parameters and\n"
+"then save them in configuration menu."
+msgstr ""
+"Essa ferramenta não está disponível ainda.\n"
+"Configure os caminhos adicionando-os\n"
+"como parâmetros de linha de comando e,\n"
+"então, salve-os no menu de configuração."
+
+#: ../game/screen_paths.cc:70
+msgid "Press any key to exit."
+msgstr "Pressione qualquer tecla para sair."
+
+#: ../game/screen_paths.cc:75
+msgid ""
+"Windows users can also use ConfigureSongDirectory.bat in the bin-directory."
+msgstr ""
+"Usuários Windows também podem user ConfigureSongDirectory.bat no diretório "
+"bin."
+
+#: ../game/configuration.cc:117
+msgid "Enabled"
+msgstr "Habilitado"
+
+#: ../game/configuration.cc:117
+msgid "Disabled"
+msgstr "Desabilitado"
+
+#: ../game/configuration.cc:121
+#, c-format
+msgid "%d items"
+msgstr "%d itens"
+
+#: ../game/instrumentgraph.cc:56 ../game/screen_sing.cc:123
+msgid "Resume"
+msgstr "Resumir"
+
+#: ../game/instrumentgraph.cc:56 ../game/screen_sing.cc:123
+msgid "Back to performing!"
+msgstr "Volte à apresentação!"
+
+# Rejoin is described as change song.
+#: ../game/instrumentgraph.cc:57
+msgid "Rejoin"
+msgstr "Alterar"
+
+#: ../game/instrumentgraph.cc:57
+msgid "Change selections"
+msgstr "Alterar seleções"
+
+#: ../game/instrumentgraph.cc:58 ../game/screen_sing.cc:124
+msgid "Restart"
+msgstr "Reiniciar"
+
+#: ../game/instrumentgraph.cc:58 ../game/screen_sing.cc:124
+msgid ""
+"Start the song\n"
+"from the beginning"
+msgstr ""
+"Comece a música\n"
+"do começo"
+
+#: ../game/instrumentgraph.cc:59 ../game/guitargraph.cc:200
+#: ../game/screen_intro.cc:184 ../game/dancegraph.cc:137
+#: ../game/screen_sing.cc:92 ../game/screen_sing.cc:126
+msgid "Quit"
+msgstr "Sair"
+
+#: ../game/instrumentgraph.cc:59 ../game/guitargraph.cc:200
+#: ../game/dancegraph.cc:137 ../game/screen_sing.cc:92
+#: ../game/screen_sing.cc:126
+msgid "Exit to song browser"
+msgstr "Sair do navegador de músicas"
+
+#: ../game/guitargraph.cc:14
+msgid "Kids"
+msgstr "Crianças"
+
+#: ../game/guitargraph.cc:14 ../game/dancegraph.cc:18
+msgid "Easy"
+msgstr "Fácil"
+
+#: ../game/guitargraph.cc:14 ../game/dancegraph.cc:18
+msgid "Medium"
+msgstr "Médio"
+
+#: ../game/guitargraph.cc:14 ../game/dancegraph.cc:18
+msgid "Hard"
+msgstr "Difícil"
+
+#: ../game/guitargraph.cc:14
+msgid "Expert"
+msgstr "Especialista"
+
+#: ../game/guitargraph.cc:163 ../game/dancegraph.cc:134
+msgid "Select difficulty"
+msgstr "Selecione a dificuldade"
+
+#: ../game/guitargraph.cc:169 ../game/guitargraph.cc:186
+msgid "Lefty-mode"
+msgstr "Modo canhoto"
+
+#: ../game/guitargraph.cc:183 ../game/dancegraph.cc:118
+msgid "Select track"
+msgstr "Seleciona a faixa"
+
+#: ../game/guitargraph.cc:194 ../game/dancegraph.cc:107
+msgid "Ready!"
+msgstr "Pronto!"
+
+#: ../game/guitargraph.cc:194 ../game/screen_intro.cc:166
+#: ../game/dancegraph.cc:107
+msgid "Start performing!"
+msgstr "Comece a apresentação!"
+
+#: ../game/guitargraph.cc:207
+msgid "ON"
+msgstr "ON"
+
+#: ../game/guitargraph.cc:207
+msgid "OFF"
+msgstr "OFF"
+
+#: ../game/guitargraph.cc:208
+msgid "Toggle lefty-mode"
+msgstr "Ativar modo canhoto"
+
+#: ../game/guitargraph.cc:447 ../game/dancegraph.cc:319
+msgid "Streak!"
+msgstr "Acerto!"
+
+#: ../game/guitargraph.cc:459
+msgid ""
+"God Mode\n"
+"Activated!"
+msgstr ""
+"God Mode\n"
+"ativado!"
+
+#: ../game/guitargraph.cc:460
+msgid "Mistakes ignored!"
+msgstr "Erros ignorados!"
+
+#: ../game/guitargraph.cc:1102
+msgid "God Mode Ready!"
+msgstr "God Mode disponível!"
+
+#: ../game/guitargraph.cc:1103
+msgid "Drum Fill!"
+msgstr "Ritmo de bateria!"
+
+#: ../game/guitargraph.cc:1106
+msgid "Solo!"
+msgstr "Solo!"
+
+#: ../game/songs.cc:194
+msgid "show all songs"
+msgstr ""
+
+#: ../game/songs.cc:195
+msgid "has dance"
+msgstr ""
+
+#: ../game/songs.cc:196
+#, fuzzy
+msgid "has vocals"
+msgstr "Vocais"
+
+#: ../game/songs.cc:197
+msgid "has duet"
+msgstr ""
+
+#: ../game/songs.cc:198
+#, fuzzy
+msgid "has guitar"
+msgstr "Guitarra rítmica"
+
+#: ../game/songs.cc:199
+msgid "drums or keytar"
+msgstr ""
+
+#: ../game/songs.cc:200
+msgid "full band"
+msgstr ""
+
+#: ../game/songs.cc:228
+msgid "random order"
+msgstr "ordem aleatória"
+
+#: ../game/songs.cc:229
+msgid "sorted by song"
+msgstr "ordenar por música"
+
+#: ../game/songs.cc:230
+msgid "sorted by artist"
+msgstr "ordenar por artista"
+
+#: ../game/songs.cc:231
+msgid "sorted by edition"
+msgstr "ordenar por edição"
+
+#: ../game/songs.cc:232
+msgid "sorted by genre"
+msgstr "ordenar por gênero"
+
+#: ../game/songs.cc:233
+msgid "sorted by path"
+msgstr "ordenar por caminho"
+
+#: ../game/songs.cc:234
+msgid "sorted by language"
+msgstr "ordenar por idioma"
+
+#: ../game/screen_intro.cc:24
+msgid "No playback devices could be used.\n"
+msgstr "Nenhum dispositivo de reprodução pôde ser usado.\n"
+
+#: ../game/screen_intro.cc:25
+msgid ""
+"\n"
+"Please configure some before playing."
+msgstr ""
+"\n"
+"Por favor, configure algumas algum antes de jogar."
+
+#: ../game/screen_intro.cc:69
+msgid "Settings saved as system defaults."
+msgstr "Configurações salvas como padrão do sistema."
+
+#: ../game/screen_intro.cc:69
+msgid "Settings saved."
+msgstr "Configurações salvas."
+
+#: ../game/screen_intro.cc:149
+msgid "Ctrl + S to save, Ctrl + R to reset defaults"
+msgstr "Ctrl + S para salvar, Ctrl + R para redefinir para o padrão"
+
+#: ../game/screen_intro.cc:166
+msgid "Perform"
+msgstr "Apresentar"
+
+#: ../game/screen_intro.cc:167
+msgid "Practice"
+msgstr "Praticar"
+
+#: ../game/screen_intro.cc:167
+msgid "Check your skills or test the microphones"
+msgstr "Verifique suas habilidades ou teste seus microfones"
+
+#: ../game/screen_intro.cc:183
+msgid "Configure"
+msgstr "Configurar"
+
+#: ../game/screen_intro.cc:183
+msgid "Configure audio and game options"
+msgstr "Configurar opções de áudio e jogo"
+
+#: ../game/screen_intro.cc:184
+msgid "Leave the game"
+msgstr "Sair do jogo"
+
+#: ../game/dancegraph.cc:18
+msgid "Beginner"
+msgstr "Iniciante"
+
+#: ../game/dancegraph.cc:18
+msgid "Challenge"
+msgstr "Desafio"
+
+#: ../game/dancegraph.cc:248
+msgid "STOP!"
+msgstr "PARE!"
+
+#: ../game/screen_playlist.cc:110 ../game/screen_playlist.cc:252
+msgid "Continue"
+msgstr ""
+
+#: ../game/screen_playlist.cc:110
+msgid "Continue playing"
+msgstr ""
+
+#: ../game/screen_playlist.cc:118
+msgid "Add songs"
+msgstr ""
+
+#: ../game/screen_playlist.cc:118
+msgid "Open the song browser to add more songs"
+msgstr ""
+
+#: ../game/screen_playlist.cc:119 ../game/screen_songs.cc:513
+msgid "Shuffle"
+msgstr ""
+
+#: ../game/screen_playlist.cc:119 ../game/screen_songs.cc:513
+msgid "Randomize the order of the playlist"
+msgstr ""
+
+#: ../game/screen_playlist.cc:125
+msgid "Clear and exit"
+msgstr ""
+
+#: ../game/screen_playlist.cc:125 ../game/screen_songs.cc:520
+msgid "Remove all the songs from the list"
+msgstr ""
+
+#: ../game/screen_playlist.cc:131 ../game/screen_playlist.cc:275
+#: ../game/screen_songs.cc:526
+msgid "Back"
+msgstr ""
+
+#: ../game/screen_playlist.cc:131 ../game/screen_playlist.cc:275
+msgid "Back to playlist viewer"
+msgstr ""
+
+#: ../game/screen_playlist.cc:237
+msgid "Press enter to view song options"
+msgstr ""
+
+#: ../game/screen_playlist.cc:244
+msgid "View more options"
+msgstr ""
+
+#: ../game/screen_playlist.cc:244
+#, fuzzy
+msgid "View general playlist settings"
+msgstr "Configurar configurações gerais de áudio"
+
+#: ../game/screen_playlist.cc:252
+msgid "Play first"
+msgstr ""
+
+#: ../game/screen_playlist.cc:254
+msgid "Ignore the playlist's order and play this song first"
+msgstr ""
+
+#: ../game/screen_playlist.cc:255
+msgid "Start the song already!"
+msgstr ""
+
+#: ../game/screen_playlist.cc:264
+msgid "Remove"
+msgstr ""
+
+#: ../game/screen_playlist.cc:264
+msgid "Remove this song from the list"
+msgstr ""
+
+#: ../game/main.cc:146
+msgid "Loading audio samples..."
+msgstr "Carregando amostras de áudio..."
+
+#: ../game/main.cc:160
+msgid "Creating screens..."
+msgstr "Criando telas..."
+
+#: ../game/main.cc:170
+msgid "Entering main menu"
+msgstr "Entrando no menu principal"
+
+#: ../game/main.cc:172 ../game/screen_sing.cc:97
+msgid "Loading complete"
+msgstr "Carregamento concluído"
+
+#: ../game/main.cc:183
+msgid "Screenshot taken!"
+msgstr "Captura de tela armazenada!"
+
+#: ../game/main.cc:186
+msgid "Screenshot failed!"
+msgstr "Captura de tela falhou!"
+
+#: ../game/screen_sing.cc:45
+msgid "Initializing webcam..."
+msgstr "Inicializando webcam..."
+
+#: ../game/screen_sing.cc:52
+msgid "Loading video..."
+msgstr "Carregando vídeo..."
+
+#: ../game/screen_sing.cc:59
+msgid "Loading song..."
+msgstr "Carregando música..."
+
+#: ../game/screen_sing.cc:66
+msgid "Song contains broken tracks!"
+msgstr "A música contém faixas corrompidas!"
+
+#: ../game/screen_sing.cc:71
+msgid "Loading menu..."
+msgstr "Carregando menu..."
+
+#: ../game/screen_sing.cc:76
+#, fuzzy
+msgid "Start"
+msgstr "Reiniciar"
+
+#: ../game/screen_sing.cc:76
+#, fuzzy
+msgid "Start performing"
+msgstr "Comece a apresentação!"
+
+#: ../game/screen_sing.cc:80
+#, fuzzy
+msgid "Duet mode"
+msgstr "Modo canhoto"
+
+#: ../game/screen_sing.cc:81
+#, fuzzy
+msgid "Normal mode"
+msgstr "Modo karaokê"
+
+#: ../game/screen_sing.cc:82
+msgid "Switch between duet and regular singing mode"
+msgstr ""
+
+#: ../game/screen_sing.cc:90
+#, fuzzy
+msgid "Change vocal track"
+msgstr ""
+"Altere a faixa vocal\n"
+"(requer reinicialização)"
+
+#: ../game/screen_sing.cc:125
+msgid "Skip"
+msgstr ""
+
+#: ../game/screen_sing.cc:125
+msgid "Skip current song"
+msgstr ""
+
+#: ../game/screen_sing.cc:391
+msgid "Press UP to join dance!"
+msgstr ""
+
+#: ../game/screen_sing.cc:391
+msgid "Step UP to join!"
+msgstr ""
+
+#: ../game/screen_sing.cc:396
+msgid "Press 1 to join guitar!"
+msgstr ""
+
+#: ../game/screen_sing.cc:396
+msgid "Press GREEN to join!"
+msgstr ""
+
+#: ../game/screen_sing.cc:401
+msgid "Press SPACE to join drums!"
+msgstr ""
+
+#: ../game/screen_sing.cc:401
+msgid "KICK to join!"
+msgstr ""
+
+#: ../game/screen_sing.cc:475
+msgid "   ENTER to skip instrumental break"
+msgstr "   ENTER para pular o intervalo instrumental"
+
+#: ../game/screen_sing.cc:476
+msgid "   Remember to wait for grading!"
+msgstr "   Lembre-se de esperar pela pontuação!"
+
+#: ../game/screen_sing.cc:587
+msgid "No player!"
+msgstr "Nenhum jogador!"
+
+#: ../game/screen_sing.cc:594
+msgid "Hit singer"
+msgstr "Cantor de sucesso"
+
+#: ../game/screen_sing.cc:595
+msgid "Lead singer"
+msgstr "Cantor líder"
+
+#: ../game/screen_sing.cc:596 ../game/screen_sing.cc:602
+#: ../game/screen_sing.cc:608
+msgid "Rising star"
+msgstr "Estrela em ascensão"
+
+#: ../game/screen_sing.cc:597 ../game/screen_sing.cc:603
+#: ../game/screen_sing.cc:609
+msgid "Amateur"
+msgstr "Amador"
+
+#: ../game/screen_sing.cc:598 ../game/screen_sing.cc:610
+msgid "Tone deaf"
+msgstr "Surdo"
+
+#: ../game/screen_sing.cc:600
+msgid "Maniac"
+msgstr "Maníaco"
+
+#: ../game/screen_sing.cc:601
+msgid "Hoofer"
+msgstr "Dançarino"
+
+#: ../game/screen_sing.cc:604
+msgid "Loser"
+msgstr "Perdedor"
+
+#: ../game/screen_sing.cc:606
+msgid "Virtuoso"
+msgstr "Virtuoso"
+
+#: ../game/screen_sing.cc:607
+msgid "Rocker"
+msgstr "Rockeiro"
+
+#: ../game/screen_songs.cc:279
+msgid "No songs found!"
+msgstr "Nenhuma música encontrada!"
+
+#: ../game/screen_songs.cc:280
+msgid ""
+"Visit performous.org\n"
+"for free songs"
+msgstr ""
+"Visite performous.org\n"
+"para obter músicas livres"
+
+#: ../game/screen_songs.cc:282
+#, fuzzy
+msgid "Sorry, no songs match the search!"
+msgstr "Nenhuma música corresponde à pesquisa"
+
+#: ../game/screen_songs.cc:289
+#, fuzzy
+msgid "Hiscore\n"
+msgstr "Recorde de %1%\n"
+
+#: ../game/screen_songs.cc:298
+msgid "<type in to search>   ↔ songs    ↕ options"
+msgstr ""
+
+#: ../game/screen_songs.cc:301
+msgid "↔ sort order: "
+msgstr ""
+
+#: ../game/screen_songs.cc:302
+msgid "↔ type filter: "
+msgstr ""
+
+#: ../game/screen_songs.cc:303
+msgid "↔ hiscores   ↵ jukebox mode"
+msgstr ""
+
+#: ../game/screen_songs.cc:307
+msgid "↵ start a playlist with this song!"
+msgstr ""
+
+#: ../game/screen_songs.cc:309
+msgid "↵ open the playlist menu"
+msgstr ""
+
+#: ../game/screen_songs.cc:506
+msgid "Play"
+msgstr ""
+
+#: ../game/screen_songs.cc:506
+msgid "Start the game with all songs in playlist"
+msgstr ""
+
+#: ../game/screen_songs.cc:519
+msgid "View playlist"
+msgstr ""
+
+#: ../game/screen_songs.cc:519
+msgid "View the current playlist"
+msgstr ""
+
+#: ../game/screen_songs.cc:520
+msgid "Clear playlist"
+msgstr ""
+
+#: ../game/screen_songs.cc:526
+#, fuzzy
+msgid "Back to song browser"
+msgstr "Sair do navegador de músicas"
+
+#: ../game/screen_players.cc:115
+msgid "No players found!"
+msgstr "Nenhum jogador encontrado!"
+
+#: ../game/screen_players.cc:116
+msgid "Enter a name to create a new player."
+msgstr "Digite um nome para criar um novo jogador."
+
+#: ../game/screen_players.cc:118
+msgid "Press enter to create player!"
+msgstr "Pressione enter para criar o jogador!"
+
+#: ../game/screen_players.cc:122
+#, fuzzy
+msgid "No players worth mentioning!"
+msgstr "Nenhum jogador encontrado!"
+
+#: ../game/screen_players.cc:127
+msgid "You reached %1% points!"
+msgstr "Você alcançou %1% pontos!"
+
+#: ../game/screen_players.cc:128
+msgid "Change player with arrow keys."
+msgstr "Mude de jogador com as setas do teclado."
+
+#: ../game/screen_players.cc:129
+msgid "Name:"
+msgstr "Nome:"
+
+#: ../game/screen_players.cc:132
+msgid "Type text to filter or create a new player."
+msgstr "Digite texto para filtrar ou criar um novo jogador."
+
+#: ../game/screen_players.cc:132
+msgid "Search Text:"
+msgstr "Pesquisar texto:"
+
+#: ../game/screen_audiodevices.cc:55
+msgid ""
+"It seems you have some manual configurations\n"
+"incompatible with this user interface.\n"
+"Saving these settings will override\n"
+"all existing audio device configuration.\n"
+"Your other options changes will be saved too."
+msgstr ""
+"Parece que você tem algumas configurações\n"
+"manuais incompatíveis com essa interface de\n"
+"usuário. Ao salvar essas configurações vai\n"
+"sobrescrever todos as configurações dos \n"
+"dispositivos de áudio existentes. Suas outras\n"
+"alterações também serão salvas."
+
+#: ../game/screen_audiodevices.cc:114
+msgid "- Unassigned -"
+msgstr "- Não atribuído -"
+
+#: ../game/screen_audiodevices.cc:135
+msgid ""
+"Use arrow keys to configure. Hit Enter/Start to save and test or Esc/Select "
+"to cancel. Ctrl + R to reset defaults"
+msgstr ""
+"Use as setas do teclado para configurar. Pressione Enter/Start para salvar e "
+"testar ou Esc/Select para cancelar. Ctrl + R para redefinir para o padrão"
+
+#: ../game/screen_audiodevices.cc:140
+msgid ""
+"For advanced device configuration, use command line parameter --audio (use --"
+"audiohelp for details)."
+msgstr ""
+"Para configurações avançada de dispositivo, use o parâmetro de linha de "
+"comando --audio (use --audiohelp para detalhes)."
+
+#: ../game/screen_audiodevices.cc:188
+msgid "Some devices failed to open!"
+msgstr "Alguns dispositivos falharam ao abrir!"
+
+#: ../game/database.cc:89 ../game/database.cc:107
+msgid "No Items up to now."
+msgstr "Nenhum item até agora."
+
+#: ../game/database.cc:90 ../game/database.cc:108
+msgid "Be the first to be listed here!"
+msgstr "Seja o primeiro a estar listado aqui!"
+
+#: ../game/song.hh:22
+msgid "Guitar"
+msgstr "Guitarra"
+
+#: ../game/song.hh:22
+msgid "Coop guitar"
+msgstr "Guitarra co-op"
+
+#: ../game/song.hh:22
+msgid "Rhythm guitar"
+msgstr "Guitarra rítmica"
+
+#: ../game/song.hh:22
+msgid "Bass"
+msgstr "Baixo"
+
+#: ../game/song.hh:22
+msgid "Drums"
+msgstr "Baterias"
+
+#: ../game/song.hh:22
+msgid "Vocals"
+msgstr "Vocais"
+
+#: ../game/song.hh:22
+msgid "Harmonic 1"
+msgstr "Harmônica 1"
+
+#: ../game/song.hh:22
+msgid "Harmonic 2"
+msgstr "Harmônica 2"
+
+#: ../game/song.hh:22
+msgid "Harmonic 3"
+msgstr "Harmônica 3"
+
+#~ msgid "Song is broken!"
+#~ msgstr "A música está corrompida!"
+
+#~ msgid "Loading instruments..."
+#~ msgstr "Carregando instrumentos..."
+
+#~ msgid "Finalizing..."
+#~ msgstr "Finalizando..."
+
+#~ msgid "Loading graphics..."
+#~ msgstr "Carregando gráficos..."
+
+#~ msgid "Random background..."
+#~ msgstr "Planos de fundo aleatórios..."
+
+#~ msgid "(press END to view hiscores)"
+#~ msgstr "(pressione END para ver os recordes)"
+
+#~ msgid "<type in to search>"
+#~ msgstr "<digite para pesquisar>"
+
+#~ msgid "Audio Devices"
+#~ msgstr "Dispositivos de áudio"
+
+#~ msgid "Setup microphones and playback"
+#~ msgstr "Configurar microfones e reprodução"
+
+#~ msgid "Audio"
+#~ msgstr "Áudio"
+
+#~ msgid "Graphics"
+#~ msgstr "Gráficos"
+
+#~ msgid "Configure rendering and video settings"
+#~ msgstr "Configurar renderização e configurações de vídeo"
+
+#~ msgid "Game"
+#~ msgstr "Jogo"
+
+#~ msgid "Gameplay related options"
+#~ msgstr "Opções relacionadas à jogabilidade"
+
+#~ msgid "Paths"
+#~ msgstr "Caminhos"
+
+#~ msgid "Setup song and data paths"
+#~ msgstr "Configurar caminhos de músicas e dados"
+
+#~ msgid "Gameplay settings."
+#~ msgstr "Configurações de jogabilidade."
+
+#~ msgid "Graphic"
+#~ msgstr "Gráfico"
+
+#~ msgid "Video and rendering settings."
+#~ msgstr "Configurações de vídeo e renderização."
+
+#~ msgid "Audio-related settings."
+#~ msgstr "Configurações relacionadas ao áudio."
+
+#~ msgid "System paths."
+#~ msgstr "Caminhos do sistema."
+
+#~ msgid "Hide pitch wave, notes and scoring."
+#~ msgstr "Esconder onda de frequência, notas e pontuação."
+
+#~ msgid "Pitch waves"
+#~ msgstr "Ondas de frequência"
+
+#~ msgid "Enable singing pitch display (when not in karaoke mode)."
+#~ msgstr ""
+#~ "Habilitar visualização de frequência no canto (quando não estiver no modo "
+#~ "karaokê)."
+
+#~ msgid "Theme"
+#~ msgstr "Tema"
+
+#~ msgid "Name of the theme to use or absolute path to theme folder."
+#~ msgstr "Nome do tema usado ou caminho absoluto para a pasta do tema."
+
+#~ msgid "Keyboard as guitar"
+#~ msgstr "Teclado como guitarra"
+
+#~ msgid "Enable keyboard as guitar (Frets on Fire mode)."
+#~ msgstr "Habilita o teclado como guitarra (modo Frets on Fire)."
+
+#~ msgid "Keyboard as drumkit"
+#~ msgstr "Teclado como kit de bateria"
+
+#~ msgid "Enable keyboard as drumkit."
+#~ msgstr "Habilita o teclado com kit de bateria."
+
+#~ msgid "Keyboard as dance pad"
+#~ msgstr "Teclado como tapete de dança"
+
+#~ msgid "Enable keyboard as dance pad."
+#~ msgstr "Habilita o teclado como tapete de dança."
+
+#~ msgid "Keyboard as keyboard"
+#~ msgstr "Teclado como teclado"
+
+#~ msgid "Enable keyboard as keyboard."
+#~ msgstr "Habilita o teclado como teclado."
+
+#~ msgid "Joystick configuration"
+#~ msgstr "Configuração do joystick"
+
+#~ msgid "Force joystick to some kind of instrument."
+#~ msgstr "Forçar o joystick para algum tipo de instrumento."
+
+#~ msgid "Hardware MIDI input device"
+#~ msgstr "Dispositivo de entrada MIDI de hardware"
+
+#~ msgid ""
+#~ "Part of sound card name or its number or empty to use the first available "
+#~ "device. Used currently for MIDI drum controllers."
+#~ msgstr ""
+#~ "Parte do nome da placa de som ou seu número ou vazio, para usar o "
+#~ "primeiro dispositivo disponível. Atualmente usado para controles de "
+#~ "bateria MIDI."
+
+#~ msgid "Windowed width"
+#~ msgstr "Largura de janela"
+
+#~ msgid "The width of the window."
+#~ msgstr "A largura da janela."
+
+#~ msgid "Windowed height"
+#~ msgstr "Altura de janela"
+
+#~ msgid "The height of the window."
+#~ msgstr "A altura da janela."
+
+#~ msgid "Fullscreen mode"
+#~ msgstr "Modo tela cheia"
+
+#~ msgid "Enable fullscreen mode on startup."
+#~ msgstr "Habilita o modo tela cheia na inicialização."
+
+#~ msgid "Stereoscopic 3D"
+#~ msgstr "3D estereoscópico"
+
+#~ msgid "Enable 3D rendering of Performous."
+#~ msgstr "Habilita renderização 3D do Performous."
+
+#~ msgid "Stereo3D type"
+#~ msgstr "Tipo do stereo3D"
+
+#~ msgid "Some modes may only get activated in fullscreen mode."
+#~ msgstr "Alguns modos podem ser ativados somente em modo tela cheia."
+
+#~ msgid "Stereo3D separation"
+#~ msgstr "Separação do stereo3D"
+
+#~ msgid ""
+#~ "The strength of the effect. Experiment with different settings for best "
+#~ "results."
+#~ msgstr ""
+#~ "A qualidade do efeito. Experimente com configurações diferentes para "
+#~ "melhores resultados."
+
+#~ msgid "Video playback"
+#~ msgstr "Reprodução de vídeo"
+
+#~ msgid ""
+#~ "Allows completely disabling background videos. It is recommended to leave "
+#~ "this enabled as Performous will still smoothly fade out the video if your "
+#~ "computer is not fast enough."
+#~ msgstr ""
+#~ "Permite desabilitar completamente vídeos em plano de fundo. É recomendado "
+#~ "manter isso habilitado pois o Performous vai continuar a escurecer o "
+#~ "vídeo suavemente se o seu computador não foi suficientemente rápido."
+
+#~ msgid "Webcam background"
+#~ msgstr "Webcam como plano de fundo"
+
+#~ msgid ""
+#~ "Performous can use webcam as a background video. Disable it if Performous "
+#~ "crashes while entering a song."
+#~ msgstr ""
+#~ "Performous pode usar a webcam como vídeo de plano de fundo. Desabilite "
+#~ "essa opção se o Performous travar enquanto estiver entrando em uma música."
+
+#~ msgid "Webcam id"
+#~ msgstr "ID da webcam"
+
+#~ msgid ""
+#~ "Use -1 to autodetect or a number starting from 0 to choose specific "
+#~ "device."
+#~ msgstr ""
+#~ "Use -1 para detectar automaticamente ou um número começando em 0 para "
+#~ "escolher um dispositivo específico."
+
+#~ msgid "3D notes"
+#~ msgstr "Notas em 3D"
+
+#~ msgid ""
+#~ "Draw instrument notes as 3-dimensional objects. May hurt performance on "
+#~ "older hardware."
+#~ msgstr ""
+#~ "Desenhar notas de instrumentos como objetos tridimensionais. Pode afetar "
+#~ "a performance em hardwares antigos."
+
+#~ msgid "SVG quality"
+#~ msgstr "Qualidade SVG"
+
+#~ msgid ""
+#~ "Larger numbers cause vector graphics to be rendered in higher resolution. "
+#~ "Decrease this to make navigating in menus faster."
+#~ msgstr ""
+#~ "Números grandes fazem com que o vetor de gráficos seja renderizado em "
+#~ "resolução mais alta. Reduza-o para tornar a navegação nos menus mais "
+#~ "rápida."
+
+#~ msgid "Text quality"
+#~ msgstr "Qualidade do texto"
+
+#~ msgid ""
+#~ "Larger numbers cause text to be rendered in higher resolution. Decrease "
+#~ "this to make everything a little faster."
+#~ msgstr ""
+#~ "Números muito grandes fazem com que o texto seja renderizado em resolução "
+#~ "mais alta. Reduza-o para tornar tudo um pouco mais rápido."
+
+#~ msgid "Benchmark mode"
+#~ msgstr "Modo benchmark"
+
+#~ msgid ""
+#~ "Framerate limit of 100 FPS is removed and the game instead renders at "
+#~ "full speed. FPS values are printed to console. Please note that the "
+#~ "display drivers may still limit the rendering speed to the screen refresh "
+#~ "rate."
+#~ msgstr ""
+#~ "Limite de framrate de 100 FPS é removido e, portanto, o jogo renderiza em "
+#~ "velocidade máxima. Os valores de FPS são exibidos no console. Por favor, "
+#~ "repare que os drivers de vídeo ainda podem limitar a velocidade de "
+#~ "renderização à taxa de atualização da tela."
+
+#~ msgid "Suggested latency"
+#~ msgstr "Latência sugerida"
+
+#~ msgid ""
+#~ "This is a hint for the audio engine about the desired latency. Set this "
+#~ "as low as possible while retaining clear audio playback. Requires restart."
+#~ msgstr ""
+#~ "Essa é uma dica para o motor de áudio sobre a latência desejada. Defina "
+#~ "isso para o mínimo possível, e preservando uma reprodução limita do áudio."
+
+#~ msgid "Audio/video latency"
+#~ msgstr "Latência de áudio/vídeo"
+
+#~ msgid ""
+#~ "Affects all modes. Use negative value if your display input lag is "
+#~ "greater than the sound card output latency, positive values in the "
+#~ "opposite case and zero if they are equal. This should be set so that the "
+#~ "notes pass the cursor at the same time the audio is heard. Use Ctrl+F1/F2 "
+#~ "to adjust this while performing."
+#~ msgstr ""
+#~ "Afeta todos os modos. Use um valor negativo se o lag da entrada de vídeo "
+#~ "for maior do que a latência da saída da placa de som, valores positivos "
+#~ "no caso oposto e zero se eles forem iguais. Isso pode ser definido de "
+#~ "forma que as notas passem o cursor ao mesmo tempo que o áudio é ouvido. "
+#~ "Use Ctrl+F1/F2 para ajustar isso enquanto durante a apresentação."
+
+#~ msgid "Audio round-trip latency"
+#~ msgstr "Latência de ida e volta do áudio"
+
+#~ msgid ""
+#~ "Affects singing only. The time it takes for Performous playback to reach "
+#~ "your speakers, fly to the microphone and all the way back until "
+#~ "Performous captures and analyzes it. While performing, press Ctrl+S for "
+#~ "synth mode and adjust with Ctrl+F3/F4."
+#~ msgstr ""
+#~ "Afeta somente o canto. O tempo que leva para a reprodução do Performous "
+#~ "chegar ao seus alto-falantes, ir até o microfone e todo o caminho de "
+#~ "volta até que Performous capture e analise-o. Durante a apresentação, "
+#~ "pressione Ctrl+S para o modo sintetizador e ajuste com Ctrl+F3/F4."
+
+#~ msgid "Audio/controller latency"
+#~ msgstr "Latência do áudio/controle"
+
+#~ msgid ""
+#~ "Affects instruments and dancing only. The total of USB (guitar or dance "
+#~ "pad) latency combined with audio output latency. Adjust so that you can "
+#~ "hit the notes best when playing by ear (not looking on screen). Use Ctrl"
+#~ "+F5/F6 to adjust while performing."
+#~ msgstr ""
+#~ "Afeta instrumentos e dança somente. O total de latência do USB (guitarra "
+#~ "ou tapete de dança) combinado com a latência da saída. Ajuste de forma "
+#~ "que você possa acertar melhor as notas enquanto joga só ouvindo (não "
+#~ "olhando para a tela). Use Ctrl+F5/F6 para ajustar durante a apresentação."
+
+#~ msgid "Audio devices"
+#~ msgstr "Dispositivos de áudio"
+
+#~ msgid "List of audio devices to try."
+#~ msgstr "Lista de dispositivos de áudio para tentar."
+
+#~ msgid "Menu volume"
+#~ msgstr "Volume dos menus"
+
+#~ msgid "The volume level of menus, song previews and jukebox mode."
+#~ msgstr ""
+#~ "O nível do volume de menus, pré-visualização de músicas e modo jukebox."
+
+#~ msgid "Music volume"
+#~ msgstr "Volume das músicas"
+
+#~ msgid ""
+#~ "The ingame music volume. Values above 90 are not recommended as "
+#~ "distortion may occur."
+#~ msgstr ""
+#~ "O volume da música durante a apresentação. Valores acima de 90 não são "
+#~ "recomendados pois pode ocorrer distorção."
+
+#~ msgid "Failure volume"
+#~ msgstr "Volume das falhas"
+
+#~ msgid ""
+#~ "The ingame fail sound volume. Values above 90 are not recommended as "
+#~ "distortion may occur. 11 is louder than 10, but these go to 100. 89 "
+#~ "louder!"
+#~ msgstr ""
+#~ "O volume do som de falhas  durente a apresentação. Valores acima de 90 "
+#~ "não são recomendados pois pode ocorrer distorção. 11 é mais alto do que "
+#~ "10, mas pode chegar até 100. 89 é bem alto!"
+
+#~ msgid "Song folders"
+#~ msgstr "Pastas das músicas"
+
+#~ msgid ""
+#~ "Where to recursively look for songs. DATADIR at the beginning means all "
+#~ "Performous data folders."
+#~ msgstr ""
+#~ "Onde procurar recursivamente por músicas. DATADIR no começo significa "
+#~ "todas as pastas de dados do Performous."
+
+#~ msgid "Base folders for data"
+#~ msgstr "Pastas base para dados"
+
+#~ msgid ""
+#~ "System defaults are included automatically. Additional paths can be added "
+#~ "here."
+#~ msgstr ""
+#~ "Padrões do sistema são incluídos automaticamente. Caminhos adicionais "
+#~ "podem ser adicionados aqui."
diff --git a/lang/sv.po b/lang/sv.po
new file mode 100644 (file)
index 0000000..a059a8c
--- /dev/null
@@ -0,0 +1,1217 @@
+msgid ""
+msgstr ""
+"Project-Id-Version: Performous\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2013-05-24 12:48+0100\n"
+"PO-Revision-Date: 2013-05-24 12:49+0100\n"
+"Last-Translator: Tapio Vierros <tapiovierros@gmail.com>\n"
+"Language-Team: \n"
+"Language: sv_SE\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"X-Poedit-KeywordsList: _;gettext;gettext_noop\n"
+"X-Poedit-Basepath: .\n"
+"X-Poedit-SourceCharset: utf-8\n"
+"X-Generator: Poedit 1.5.4\n"
+"X-Poedit-SearchPath-0: ../game\n"
+"X-Poedit-SearchPath-1: ../data\n"
+
+#: ../game/screen_paths.cc:24
+msgid ""
+"This tool is not yet available.\n"
+"Configure paths by adding them\n"
+"as command line parameters and\n"
+"then save them in configuration menu."
+msgstr ""
+"Detta verktyget är inte tillgängligt ännu.\n"
+"Ställ in sökvägar genom att lägga till\n"
+"dem som kommandoradsargument och\n"
+"spara dem sedan i inställningsmenyn."
+
+#: ../game/screen_paths.cc:70
+msgid "Press any key to exit."
+msgstr "Tryck på valfri knapp för att avsluta."
+
+#: ../game/screen_paths.cc:75
+msgid ""
+"Windows users can also use ConfigureSongDirectory.bat in the bin-directory."
+msgstr ""
+"Windows användare kan också använda ConfigureSongDirectory.bat i bin-"
+"katalogen"
+
+#: ../game/configuration.cc:117
+msgid "Enabled"
+msgstr "Aktiverad"
+
+#: ../game/configuration.cc:117
+msgid "Disabled"
+msgstr "Inaktiverad"
+
+# alternativ verkar passa med string_list i koden
+#: ../game/configuration.cc:121
+#, c-format
+msgid "%d items"
+msgstr "%d alternativ"
+
+#: ../game/instrumentgraph.cc:56 ../game/screen_sing.cc:123
+msgid "Resume"
+msgstr "Fortsätt"
+
+# ...
+#: ../game/instrumentgraph.cc:56 ../game/screen_sing.cc:123
+msgid "Back to performing!"
+msgstr "Tillbaks till uppträdande"
+
+#: ../game/instrumentgraph.cc:57
+msgid "Rejoin"
+msgstr "Välj om"
+
+# ...
+#: ../game/instrumentgraph.cc:57
+msgid "Change selections"
+msgstr "Ändra val"
+
+#: ../game/instrumentgraph.cc:58 ../game/screen_sing.cc:124
+msgid "Restart"
+msgstr "Börja om"
+
+# start <-> restart?
+#: ../game/instrumentgraph.cc:58 ../game/screen_sing.cc:124
+msgid ""
+"Start the song\n"
+"from the beginning"
+msgstr ""
+"Börja låten\n"
+"från början"
+
+#: ../game/instrumentgraph.cc:59 ../game/guitargraph.cc:200
+#: ../game/screen_intro.cc:184 ../game/dancegraph.cc:137
+#: ../game/screen_sing.cc:92 ../game/screen_sing.cc:126
+msgid "Quit"
+msgstr "Avsluta"
+
+# låt/sång
+#: ../game/instrumentgraph.cc:59 ../game/guitargraph.cc:200
+#: ../game/dancegraph.cc:137 ../game/screen_sing.cc:92
+#: ../game/screen_sing.cc:126
+msgid "Exit to song browser"
+msgstr "Återgå till låt bläddraren"
+
+#: ../game/guitargraph.cc:14
+msgid "Kids"
+msgstr "Barn"
+
+# Lätt eller enkel
+#: ../game/guitargraph.cc:14 ../game/dancegraph.cc:18
+msgid "Easy"
+msgstr "Lätt"
+
+# Medium eller mellan kanske
+#: ../game/guitargraph.cc:14 ../game/dancegraph.cc:18
+msgid "Medium"
+msgstr "Medium"
+
+#: ../game/guitargraph.cc:14 ../game/dancegraph.cc:18
+msgid "Hard"
+msgstr "Svårt"
+
+#: ../game/guitargraph.cc:14
+msgid "Expert"
+msgstr "Expert"
+
+#: ../game/guitargraph.cc:163 ../game/dancegraph.cc:134
+msgid "Select difficulty"
+msgstr "Välj svårighetsgrad"
+
+#: ../game/guitargraph.cc:169 ../game/guitargraph.cc:186
+msgid "Lefty-mode"
+msgstr "Vänsterläge"
+
+#: ../game/guitargraph.cc:183 ../game/dancegraph.cc:118
+msgid "Select track"
+msgstr "Välj spår"
+
+# Redo! eller klar!
+#: ../game/guitargraph.cc:194 ../game/dancegraph.cc:107
+msgid "Ready!"
+msgstr "Redo!"
+
+# ...
+#: ../game/guitargraph.cc:194 ../game/screen_intro.cc:166
+#: ../game/dancegraph.cc:107
+msgid "Start performing!"
+msgstr "Börja uppträd!"
+
+#: ../game/guitargraph.cc:207
+msgid "ON"
+msgstr "PÅ"
+
+#: ../game/guitargraph.cc:207
+msgid "OFF"
+msgstr "AV"
+
+#: ../game/guitargraph.cc:208
+msgid "Toggle lefty-mode"
+msgstr "Växla vänsterläge"
+
+# [RFC:sv] "Stråk!" känns rumphugget, "Vinnar Stråk!" inte heller bra. "Serie" blir också konstigt...
+#: ../game/guitargraph.cc:447 ../game/dancegraph.cc:319
+msgid "Streak!"
+msgstr ""
+
+# ...
+#: ../game/guitargraph.cc:459
+msgid ""
+"God Mode\n"
+"Activated!"
+msgstr ""
+"God Mode\n"
+"Aktiverat!"
+
+#: ../game/guitargraph.cc:460
+msgid "Mistakes ignored!"
+msgstr "Misstag ignorerade"
+
+# ...
+# förberet?
+#: ../game/guitargraph.cc:1102
+msgid "God Mode Ready!"
+msgstr "God Mode Redo!"
+
+# ...
+# kör på en översättning av tysk översättningen :P
+#: ../game/guitargraph.cc:1103
+msgid "Drum Fill!"
+msgstr "Trum-insats!"
+
+#: ../game/guitargraph.cc:1106
+msgid "Solo!"
+msgstr "Solo!"
+
+#: ../game/songs.cc:194
+msgid "show all songs"
+msgstr ""
+
+#: ../game/songs.cc:195
+msgid "has dance"
+msgstr ""
+
+# Vokal (musik), Sång, etc
+#: ../game/songs.cc:196
+#, fuzzy
+msgid "has vocals"
+msgstr "Såmg"
+
+#: ../game/songs.cc:197
+msgid "has duet"
+msgstr ""
+
+#: ../game/songs.cc:198
+#, fuzzy
+msgid "has guitar"
+msgstr "Kompgitarr"
+
+#: ../game/songs.cc:199
+msgid "drums or keytar"
+msgstr ""
+
+#: ../game/songs.cc:200
+msgid "full band"
+msgstr ""
+
+#: ../game/songs.cc:228
+msgid "random order"
+msgstr "slumpmässig ordning"
+
+#: ../game/songs.cc:229
+msgid "sorted by song"
+msgstr "sorterat efter låt"
+
+#: ../game/songs.cc:230
+msgid "sorted by artist"
+msgstr "sorterat efter artist"
+
+#: ../game/songs.cc:231
+msgid "sorted by edition"
+msgstr "sorterat efter utgåva"
+
+#: ../game/songs.cc:232
+msgid "sorted by genre"
+msgstr "sorterat efter genre"
+
+#: ../game/songs.cc:233
+msgid "sorted by path"
+msgstr "sorterat efter sökväg"
+
+#: ../game/songs.cc:234
+msgid "sorted by language"
+msgstr "sorterat efter språk"
+
+#: ../game/screen_intro.cc:24
+msgid "No playback devices could be used.\n"
+msgstr "Inga uppspelningsenheter kunde användas.\n"
+
+# ...
+#: ../game/screen_intro.cc:25
+msgid ""
+"\n"
+"Please configure some before playing."
+msgstr ""
+"\n"
+"Var god och konfigurera något innan du spelar."
+
+#: ../game/screen_intro.cc:69
+msgid "Settings saved as system defaults."
+msgstr ""
+
+#: ../game/screen_intro.cc:69
+msgid "Settings saved."
+msgstr ""
+
+# add "ESC returns" to it?
+#: ../game/screen_intro.cc:149
+msgid "Ctrl + S to save, Ctrl + R to reset defaults"
+msgstr "Ctrl + S sparar, Ctrl + R återställer ursprungsvärden"
+
+# ...
+#: ../game/screen_intro.cc:166
+msgid "Perform"
+msgstr "Uppträd"
+
+#: ../game/screen_intro.cc:167
+msgid "Practice"
+msgstr "Träna"
+
+#: ../game/screen_intro.cc:167
+msgid "Check your skills or test the microphones"
+msgstr "Testa dina förmågor eller mikrofoner"
+
+#: ../game/screen_intro.cc:183
+msgid "Configure"
+msgstr "Konfigurera"
+
+#: ../game/screen_intro.cc:183
+msgid "Configure audio and game options"
+msgstr "Ställ in ljud- och spelalternativ"
+
+# Avsluta/Lämna
+#: ../game/screen_intro.cc:184
+msgid "Leave the game"
+msgstr "Avsluta spelet"
+
+#: ../game/dancegraph.cc:18
+msgid "Beginner"
+msgstr "Nybörjare"
+
+#: ../game/dancegraph.cc:18
+msgid "Challenge"
+msgstr "Utmaning"
+
+# stanna eller sluta?
+#: ../game/dancegraph.cc:248
+msgid "STOP!"
+msgstr "STANNA!"
+
+#: ../game/screen_playlist.cc:110 ../game/screen_playlist.cc:252
+msgid "Continue"
+msgstr ""
+
+#: ../game/screen_playlist.cc:110
+msgid "Continue playing"
+msgstr ""
+
+#: ../game/screen_playlist.cc:118
+msgid "Add songs"
+msgstr ""
+
+#: ../game/screen_playlist.cc:118
+msgid "Open the song browser to add more songs"
+msgstr ""
+
+#: ../game/screen_playlist.cc:119 ../game/screen_songs.cc:513
+msgid "Shuffle"
+msgstr ""
+
+#: ../game/screen_playlist.cc:119 ../game/screen_songs.cc:513
+msgid "Randomize the order of the playlist"
+msgstr ""
+
+#: ../game/screen_playlist.cc:125
+msgid "Clear and exit"
+msgstr ""
+
+#: ../game/screen_playlist.cc:125 ../game/screen_songs.cc:520
+msgid "Remove all the songs from the list"
+msgstr ""
+
+#: ../game/screen_playlist.cc:131 ../game/screen_playlist.cc:275
+#: ../game/screen_songs.cc:526
+msgid "Back"
+msgstr ""
+
+#: ../game/screen_playlist.cc:131 ../game/screen_playlist.cc:275
+msgid "Back to playlist viewer"
+msgstr ""
+
+#: ../game/screen_playlist.cc:237
+msgid "Press enter to view song options"
+msgstr ""
+
+#: ../game/screen_playlist.cc:244
+msgid "View more options"
+msgstr ""
+
+#: ../game/screen_playlist.cc:244
+#, fuzzy
+msgid "View general playlist settings"
+msgstr "Konfigurera allmänna ljudalternativ"
+
+#: ../game/screen_playlist.cc:252
+msgid "Play first"
+msgstr ""
+
+#: ../game/screen_playlist.cc:254
+msgid "Ignore the playlist's order and play this song first"
+msgstr ""
+
+#: ../game/screen_playlist.cc:255
+msgid "Start the song already!"
+msgstr ""
+
+#: ../game/screen_playlist.cc:264
+msgid "Remove"
+msgstr ""
+
+#: ../game/screen_playlist.cc:264
+msgid "Remove this song from the list"
+msgstr ""
+
+#: ../game/main.cc:146
+msgid "Loading audio samples..."
+msgstr "Laddar ljud..."
+
+#: ../game/main.cc:160
+msgid "Creating screens..."
+msgstr "Skapar skärmar..."
+
+#: ../game/main.cc:170
+msgid "Entering main menu"
+msgstr "Går in i huvudmenyn"
+
+#: ../game/main.cc:172 ../game/screen_sing.cc:97
+msgid "Loading complete"
+msgstr "Laddning klar"
+
+#: ../game/main.cc:183
+msgid "Screenshot taken!"
+msgstr "Skärmdump tagen!"
+
+#: ../game/main.cc:186
+msgid "Screenshot failed!"
+msgstr "Misslyckades att ta skärmdump!"
+
+#: ../game/screen_sing.cc:45
+msgid "Initializing webcam..."
+msgstr "Sätter upp web-kamera"
+
+#: ../game/screen_sing.cc:52
+msgid "Loading video..."
+msgstr "Laddar video..."
+
+#: ../game/screen_sing.cc:59
+msgid "Loading song..."
+msgstr "Laddar låt..."
+
+#: ../game/screen_sing.cc:66
+msgid "Song contains broken tracks!"
+msgstr "Låten innehåller trasiga spår!"
+
+#: ../game/screen_sing.cc:71
+msgid "Loading menu..."
+msgstr "Laddar meny..."
+
+#: ../game/screen_sing.cc:76
+#, fuzzy
+msgid "Start"
+msgstr "Börja om"
+
+# ...
+#: ../game/screen_sing.cc:76
+#, fuzzy
+msgid "Start performing"
+msgstr "Börja uppträd!"
+
+#: ../game/screen_sing.cc:80
+#, fuzzy
+msgid "Duet mode"
+msgstr "Vänsterläge"
+
+#: ../game/screen_sing.cc:81
+#, fuzzy
+msgid "Normal mode"
+msgstr "Karaoke-läge"
+
+#: ../game/screen_sing.cc:82
+msgid "Switch between duet and regular singing mode"
+msgstr ""
+
+#: ../game/screen_sing.cc:90
+#, fuzzy
+msgid "Change vocal track"
+msgstr ""
+"Byt röst spår\n"
+"(omstart krävs)"
+
+#: ../game/screen_sing.cc:125
+msgid "Skip"
+msgstr ""
+
+#: ../game/screen_sing.cc:125
+msgid "Skip current song"
+msgstr ""
+
+#: ../game/screen_sing.cc:391
+msgid "Press UP to join dance!"
+msgstr ""
+
+#: ../game/screen_sing.cc:391
+msgid "Step UP to join!"
+msgstr ""
+
+#: ../game/screen_sing.cc:396
+msgid "Press 1 to join guitar!"
+msgstr ""
+
+#: ../game/screen_sing.cc:396
+msgid "Press GREEN to join!"
+msgstr ""
+
+#: ../game/screen_sing.cc:401
+msgid "Press SPACE to join drums!"
+msgstr ""
+
+#: ../game/screen_sing.cc:401
+msgid "KICK to join!"
+msgstr ""
+
+# skippa/hoppa över
+# ... instrumentalt mellanspel ...
+#: ../game/screen_sing.cc:475
+msgid "   ENTER to skip instrumental break"
+msgstr "   ENTER för att skippa mellanspel"
+
+# gradering eller betygsättning?
+#: ../game/screen_sing.cc:476
+msgid "   Remember to wait for grading!"
+msgstr "   Kom ihåg att vänta på graderingen!"
+
+#: ../game/screen_sing.cc:587
+msgid "No player!"
+msgstr "Ingen spelare!"
+
+#: ../game/screen_sing.cc:594
+msgid "Hit singer"
+msgstr "Hit sångare"
+
+# ...
+#: ../game/screen_sing.cc:595
+msgid "Lead singer"
+msgstr "Lead sångare"
+
+#: ../game/screen_sing.cc:596 ../game/screen_sing.cc:602
+#: ../game/screen_sing.cc:608
+msgid "Rising star"
+msgstr "Stjärnskott"
+
+#: ../game/screen_sing.cc:597 ../game/screen_sing.cc:603
+#: ../game/screen_sing.cc:609
+msgid "Amateur"
+msgstr "Amatör"
+
+#: ../game/screen_sing.cc:598 ../game/screen_sing.cc:610
+msgid "Tone deaf"
+msgstr "Tondöv"
+
+#: ../game/screen_sing.cc:600
+msgid "Maniac"
+msgstr "Galning"
+
+# ...
+#: ../game/screen_sing.cc:601
+msgid "Hoofer"
+msgstr "Dansare"
+
+#: ../game/screen_sing.cc:604
+msgid "Loser"
+msgstr "Förlorare"
+
+#: ../game/screen_sing.cc:606
+msgid "Virtuoso"
+msgstr "Virtuos"
+
+# ...
+#: ../game/screen_sing.cc:607
+msgid "Rocker"
+msgstr "Rockare"
+
+#: ../game/screen_songs.cc:279
+msgid "No songs found!"
+msgstr "Inga låtar funna"
+
+# gratis eller fria?
+# (tysk översättning ger freie)
+#: ../game/screen_songs.cc:280
+msgid ""
+"Visit performous.org\n"
+"for free songs"
+msgstr ""
+"Besök performous.org\n"
+"för fria låtar"
+
+#: ../game/screen_songs.cc:282
+#, fuzzy
+msgid "Sorry, no songs match the search!"
+msgstr "inga låtar matchar sökningen"
+
+# ...
+#: ../game/screen_songs.cc:289
+#, fuzzy
+msgid "Hiscore\n"
+msgstr "Highscore för %1%\n"
+
+#: ../game/screen_songs.cc:298
+msgid "<type in to search>   ↔ songs    ↕ options"
+msgstr ""
+
+#: ../game/screen_songs.cc:301
+msgid "↔ sort order: "
+msgstr ""
+
+#: ../game/screen_songs.cc:302
+msgid "↔ type filter: "
+msgstr ""
+
+#: ../game/screen_songs.cc:303
+msgid "↔ hiscores   ↵ jukebox mode"
+msgstr ""
+
+#: ../game/screen_songs.cc:307
+msgid "↵ start a playlist with this song!"
+msgstr ""
+
+#: ../game/screen_songs.cc:309
+msgid "↵ open the playlist menu"
+msgstr ""
+
+#: ../game/screen_songs.cc:506
+msgid "Play"
+msgstr ""
+
+#: ../game/screen_songs.cc:506
+msgid "Start the game with all songs in playlist"
+msgstr ""
+
+#: ../game/screen_songs.cc:519
+msgid "View playlist"
+msgstr ""
+
+#: ../game/screen_songs.cc:519
+msgid "View the current playlist"
+msgstr ""
+
+#: ../game/screen_songs.cc:520
+msgid "Clear playlist"
+msgstr ""
+
+# låt/sång
+#: ../game/screen_songs.cc:526
+#, fuzzy
+msgid "Back to song browser"
+msgstr "Återgå till låt bläddraren"
+
+#: ../game/screen_players.cc:115
+msgid "No players found!"
+msgstr "Inga spelare funna!"
+
+#: ../game/screen_players.cc:116
+msgid "Enter a name to create a new player."
+msgstr "Ange ett namn för att skapa spelare."
+
+#: ../game/screen_players.cc:118
+msgid "Press enter to create player!"
+msgstr "Tryck på enter för att skapa spelaren!"
+
+#: ../game/screen_players.cc:122
+#, fuzzy
+msgid "No players worth mentioning!"
+msgstr "Inga spelare funna!"
+
+# fick/klarade/tog/plockade
+#: ../game/screen_players.cc:127
+msgid "You reached %1% points!"
+msgstr "Du fick %1% poäng!"
+
+#: ../game/screen_players.cc:128
+msgid "Change player with arrow keys."
+msgstr "Byt spelare med piltangenterna."
+
+#: ../game/screen_players.cc:129
+msgid "Name:"
+msgstr "Namn:"
+
+#: ../game/screen_players.cc:132
+msgid "Type text to filter or create a new player."
+msgstr "Skriv in en text för att filtrera eller skapa spelare"
+
+#: ../game/screen_players.cc:132
+msgid "Search Text:"
+msgstr "Sök text:"
+
+#: ../game/screen_audiodevices.cc:55
+msgid ""
+"It seems you have some manual configurations\n"
+"incompatible with this user interface.\n"
+"Saving these settings will override\n"
+"all existing audio device configuration.\n"
+"Your other options changes will be saved too."
+msgstr ""
+"Det ser ut som om du har några manuella inställningar\n"
+"som är inkompatibla med detta användargränssnittet.\n"
+"Sparande av dessa inställningar kommer skriva över\n"
+"alla befintliga alternativ för ljudenhetskonfiguration.\n"
+"Alla andra ändringar av alternativ kommer sparas också."
+
+#: ../game/screen_audiodevices.cc:114
+msgid "- Unassigned -"
+msgstr "- Ej tilldelad -"
+
+#: ../game/screen_audiodevices.cc:135
+msgid ""
+"Use arrow keys to configure. Hit Enter/Start to save and test or Esc/Select "
+"to cancel. Ctrl + R to reset defaults"
+msgstr ""
+"Använd piltangenterna för att konfigurera. Tryck Enter/Start för att spara "
+"och testa eller Esc/Select för att avbryta. Ctrl + R för att återställa "
+"standardvärden"
+
+#: ../game/screen_audiodevices.cc:140
+msgid ""
+"For advanced device configuration, use command line parameter --audio (use --"
+"audiohelp for details)."
+msgstr ""
+"För avancerad enhetskonfiguration, använd kommandoradsparametern --audio "
+"(använd --audiohelp för detaljer)."
+
+#: ../game/screen_audiodevices.cc:188
+msgid "Some devices failed to open!"
+msgstr "Några enheter kunde inte öppnas!"
+
+# items -> players?
+#: ../game/database.cc:89 ../game/database.cc:107
+msgid "No Items up to now."
+msgstr "Inga spelare ännu."
+
+#: ../game/database.cc:90 ../game/database.cc:108
+msgid "Be the first to be listed here!"
+msgstr "Bli den första att bli listad här!"
+
+#: ../game/song.hh:22
+msgid "Guitar"
+msgstr "Gitarr"
+
+#: ../game/song.hh:22
+msgid "Coop guitar"
+msgstr ""
+
+#: ../game/song.hh:22
+msgid "Rhythm guitar"
+msgstr "Kompgitarr"
+
+#: ../game/song.hh:22
+msgid "Bass"
+msgstr "Bas"
+
+#: ../game/song.hh:22
+msgid "Drums"
+msgstr "Trummor"
+
+# Vokal (musik), Sång, etc
+#: ../game/song.hh:22
+msgid "Vocals"
+msgstr "Såmg"
+
+#: ../game/song.hh:22
+msgid "Harmonic 1"
+msgstr "Överton 1"
+
+#: ../game/song.hh:22
+msgid "Harmonic 2"
+msgstr "Överton 2"
+
+#: ../game/song.hh:22
+msgid "Harmonic 3"
+msgstr "Överton 3"
+
+#: /tmp/xml2gettext.pJaf2puMzZ:2
+msgid "Game"
+msgstr "Spel"
+
+# Gameplay skulle nog tom kunna funka...
+#: /tmp/xml2gettext.pJaf2puMzZ:3
+msgid "Gameplay related options"
+msgstr "Spelstils relaterade alternativ"
+
+#: /tmp/xml2gettext.pJaf2puMzZ:4
+msgid "Graphic"
+msgstr "Grafik"
+
+#: /tmp/xml2gettext.pJaf2puMzZ:5
+msgid "Configure rendering and video settings"
+msgstr "Ställ in renderings- och videoalternativ"
+
+#: /tmp/xml2gettext.pJaf2puMzZ:6
+msgid "Audio Devices"
+msgstr "Ljudenheter"
+
+#: /tmp/xml2gettext.pJaf2puMzZ:7
+msgid "Setup microphones and playback"
+msgstr "Ställ in mikrofoner och uppspelning"
+
+#: /tmp/xml2gettext.pJaf2puMzZ:8
+msgid "Audio"
+msgstr "Ljud"
+
+#: /tmp/xml2gettext.pJaf2puMzZ:9
+msgid "Configure general audio settings"
+msgstr "Konfigurera allmänna ljudalternativ"
+
+#: /tmp/xml2gettext.pJaf2puMzZ:10
+msgid "Paths"
+msgstr "Sökvägar"
+
+#: /tmp/xml2gettext.pJaf2puMzZ:11
+msgid "Setup song and data paths"
+msgstr "Ställ in låt- och datasökvägar"
+
+#: /tmp/xml2gettext.pJaf2puMzZ:12
+msgid "Karaoke mode"
+msgstr "Karaoke-läge"
+
+#: /tmp/xml2gettext.pJaf2puMzZ:13
+msgid "Hide pitch wave, notes and scoring."
+msgstr "Döljer tonhöjdsvågorna, noterna och poängräkningen"
+
+#: /tmp/xml2gettext.pJaf2puMzZ:14
+msgid "Pitch waves"
+msgstr "Tonhöjdsvågor"
+
+#: /tmp/xml2gettext.pJaf2puMzZ:15
+msgid "Enable singing pitch display (when not in karaoke mode)."
+msgstr "Aktivera tonhöjds visning (när ej i karaoke-läge)"
+
+#: /tmp/xml2gettext.pJaf2puMzZ:16
+msgid "Theme"
+msgstr "Tema"
+
+#: /tmp/xml2gettext.pJaf2puMzZ:17
+#, fuzzy
+msgid "Name of the theme to use."
+msgstr "Namnet på temat att använda eller absolut sökväg till temakatalogen"
+
+#: /tmp/xml2gettext.pJaf2puMzZ:18
+msgid "Keyboard as guitar"
+msgstr "Tangentbord som gitarr"
+
+# ...
+# Enable -> Use?
+#: /tmp/xml2gettext.pJaf2puMzZ:19
+msgid "Enable keyboard as guitar (Frets on Fire mode)."
+msgstr "Använd tangentbordet som gitarr (Frets on Fire läge)"
+
+#: /tmp/xml2gettext.pJaf2puMzZ:20
+msgid "Keyboard as drumkit"
+msgstr "Tangentbord som trumkit"
+
+# ...
+# Enable -> Use?
+#: /tmp/xml2gettext.pJaf2puMzZ:21
+msgid "Enable keyboard as drumkit."
+msgstr "Använd tangentbordet som trumkit "
+
+#: /tmp/xml2gettext.pJaf2puMzZ:22
+msgid "Keyboard as dance pad"
+msgstr "Tangentbord som dansmatta"
+
+# ...
+# Enable -> Use?
+#: /tmp/xml2gettext.pJaf2puMzZ:23
+msgid "Enable keyboard as dance pad."
+msgstr "Använd tangentbordet som dansmatta"
+
+#: /tmp/xml2gettext.pJaf2puMzZ:24
+#, fuzzy
+msgid "Keyboard as keytar"
+msgstr "Tangentbord som gitarr"
+
+# ...
+# Enable -> Use?
+#: /tmp/xml2gettext.pJaf2puMzZ:25
+#, fuzzy
+msgid "Enable keyboard as keytar."
+msgstr "Använd tangentbordet som dansmatta"
+
+#: /tmp/xml2gettext.pJaf2puMzZ:26
+msgid "Force controller A's type"
+msgstr ""
+
+#: /tmp/xml2gettext.pJaf2puMzZ:27
+msgid ""
+"Override autodetection and force the first controller to the given type."
+msgstr ""
+
+#: /tmp/xml2gettext.pJaf2puMzZ:28
+msgid "Force controller B's type"
+msgstr ""
+
+#: /tmp/xml2gettext.pJaf2puMzZ:29
+msgid ""
+"Override autodetection and force the second controller to the given type."
+msgstr ""
+
+#: /tmp/xml2gettext.pJaf2puMzZ:30
+msgid "Force controller C's type"
+msgstr ""
+
+#: /tmp/xml2gettext.pJaf2puMzZ:31
+msgid ""
+"Override autodetection and force the third controller to the given type."
+msgstr ""
+
+#: /tmp/xml2gettext.pJaf2puMzZ:32
+msgid "Force controller D's type"
+msgstr ""
+
+#: /tmp/xml2gettext.pJaf2puMzZ:33
+msgid ""
+"Override autodetection and force the fourth controller to the given type."
+msgstr ""
+
+#: /tmp/xml2gettext.pJaf2puMzZ:34
+msgid "Joystick configuration"
+msgstr "Joystick-konfiguration"
+
+#: /tmp/xml2gettext.pJaf2puMzZ:35
+msgid "Force joystick to some kind of instrument."
+msgstr "Tvinga joysticken till något from av instrument"
+
+#: /tmp/xml2gettext.pJaf2puMzZ:36
+msgid "Hardware MIDI input device"
+msgstr "Hårdvaru MIDI indataenhet"
+
+#: /tmp/xml2gettext.pJaf2puMzZ:37
+msgid ""
+"Regex for matching the MIDI devices to use. The default is to use all "
+"available devices."
+msgstr ""
+
+#: /tmp/xml2gettext.pJaf2puMzZ:38
+msgid "Fallback song encoding"
+msgstr ""
+
+#: /tmp/xml2gettext.pJaf2puMzZ:39
+msgid "Pick the text codec used for song files that are not UTF-8."
+msgstr ""
+
+#: /tmp/xml2gettext.pJaf2puMzZ:40
+msgid "Windowed width"
+msgstr "Fönsterbredd"
+
+#: /tmp/xml2gettext.pJaf2puMzZ:41
+msgid "The width of the window."
+msgstr "Fönstrets bredd i fönsterläge"
+
+#: /tmp/xml2gettext.pJaf2puMzZ:42
+msgid "Windowed height"
+msgstr "Fönsterhöjd"
+
+#: /tmp/xml2gettext.pJaf2puMzZ:43
+msgid "The height of the window."
+msgstr "Fönstrets höjd i fönsterläge"
+
+#: /tmp/xml2gettext.pJaf2puMzZ:44
+msgid "Fullscreen mode"
+msgstr "Helskärmsläge"
+
+#: /tmp/xml2gettext.pJaf2puMzZ:45
+msgid "Enable fullscreen mode on startup."
+msgstr "Aktivera helskärmsläge vid uppstart"
+
+#: /tmp/xml2gettext.pJaf2puMzZ:46
+msgid "Stereoscopic 3D"
+msgstr ""
+
+#: /tmp/xml2gettext.pJaf2puMzZ:47
+msgid "Enable 3D rendering of Performous."
+msgstr ""
+
+#: /tmp/xml2gettext.pJaf2puMzZ:48
+msgid "Stereo3D type"
+msgstr ""
+
+#: /tmp/xml2gettext.pJaf2puMzZ:49
+msgid "Some modes may only get activated in fullscreen mode."
+msgstr ""
+
+#: /tmp/xml2gettext.pJaf2puMzZ:50
+msgid "Stereo3D separation"
+msgstr ""
+
+#: /tmp/xml2gettext.pJaf2puMzZ:51
+msgid ""
+"The strength of the effect. Experiment with different settings for best "
+"results."
+msgstr ""
+
+#: /tmp/xml2gettext.pJaf2puMzZ:52
+msgid "Video playback"
+msgstr "Video uppspelning"
+
+#: /tmp/xml2gettext.pJaf2puMzZ:53
+msgid ""
+"Allows completely disabling background videos. It is recommended to leave "
+"this enabled as Performous will still smoothly fade out the video if your "
+"computer is not fast enough."
+msgstr ""
+"Möjliggör total avstängning av bakgrundsvideor. Det är rekommenderat att "
+"lämna detta aktiverat eftersom Performous automatiskt tonar ut video om din "
+"dator inte är snabb nog."
+
+#: /tmp/xml2gettext.pJaf2puMzZ:54
+msgid "Webcam background"
+msgstr "Web-kamerabakgrund"
+
+#: /tmp/xml2gettext.pJaf2puMzZ:55
+#, fuzzy
+msgid ""
+"Performous can use webcam as a background video. Disable it if Performous "
+"crashes while entering a song."
+msgstr ""
+"Performous kan försöka använda web-kameran som bakgrundsvideo. Du kan stänga "
+"av detta om det stör dig."
+
+#: /tmp/xml2gettext.pJaf2puMzZ:56
+msgid "Webcam id"
+msgstr "Web-kamera id"
+
+#: /tmp/xml2gettext.pJaf2puMzZ:57
+msgid ""
+"Use -1 to autodetect or a number starting from 0 to choose specific device."
+msgstr ""
+"Använd -1 för autodetektering eller ett tal med början från 0 för att välja "
+"en specifik enhet."
+
+#: /tmp/xml2gettext.pJaf2puMzZ:58
+msgid "SVG quality"
+msgstr "SVG-kvalitet"
+
+#: /tmp/xml2gettext.pJaf2puMzZ:59
+msgid ""
+"Larger numbers cause vector graphics to be rendered in higher resolution. "
+"Decrease this to make navigating in menus faster."
+msgstr ""
+"Större tal gör att vektorgrafiken renderas is högre upplösning. Minska detta "
+"för att göra menynavigation snabbare."
+
+#: /tmp/xml2gettext.pJaf2puMzZ:60
+msgid "Text quality"
+msgstr "Textkvalitet"
+
+#: /tmp/xml2gettext.pJaf2puMzZ:61
+msgid ""
+"Larger numbers cause text to be rendered in higher resolution. Decrease this "
+"to make everything a little faster."
+msgstr ""
+"Större tal gör att text renderas is högre upplösning. Minska detta för att "
+"göra allt lite snabbare."
+
+#: /tmp/xml2gettext.pJaf2puMzZ:62
+msgid "Benchmark mode"
+msgstr "Prestandamätnings-läge"
+
+#: /tmp/xml2gettext.pJaf2puMzZ:63
+msgid ""
+"Framerate limit of 100 FPS is removed and the game instead renders at full "
+"speed. FPS values are printed to console. Please note that the display "
+"drivers may still limit the rendering speed to the screen refresh rate."
+msgstr ""
+"Ramhastighetsbegränsningen på 100 FPS tas bort och spelet renderas istället "
+"i full hastighet. FPS värden skrivs ut till konsollen. Notera att skärmens "
+"drivrutin fortfarande kan begränsa renderingshastigheten till skärmens "
+"uppdateringshastighet."
+
+#: /tmp/xml2gettext.pJaf2puMzZ:64
+msgid "Suggested latency"
+msgstr "Föreslagen fördröjning"
+
+#: /tmp/xml2gettext.pJaf2puMzZ:65
+msgid ""
+"This is a hint for the audio engine about the desired latency. Set this as "
+"low as possible while retaining clear audio playback. Requires restart."
+msgstr ""
+"Detta är en ledtråd till ljudmotorn om den önskade fördröjningen. Ställ in "
+"detta till lägsta möjliga värde med bibehållet klar ljuduppspelning. Kräver "
+"omstart."
+
+#: /tmp/xml2gettext.pJaf2puMzZ:66
+msgid "Audio/video latency"
+msgstr "Ljud/video-fördröjning"
+
+# display input lag.
+# sound card output latency.
+# IMO: the details ("Use neg...") should be *after* the "This should be set". (translation preserves current order.)
+#: /tmp/xml2gettext.pJaf2puMzZ:67
+msgid ""
+"Affects all modes. Use negative value if your display input lag is greater "
+"than the sound card output latency, positive values in the opposite case and "
+"zero if they are equal. This should be set so that the notes pass the cursor "
+"at the same time the audio is heard. Use Ctrl+F1/F2 to adjust this while "
+"performing."
+msgstr ""
+"Påverkar alla lägen. Använd negativa värden om skräm in eftersläpet är "
+"större än ljudkortets ut fördröjning, välj positiva värden om det är tvärtom "
+"och noll om de lika stora. Detta bör ställas in så att noterna passerar "
+"markören samtidigt som ljudet hörs. Använd Ctrl+F1/F2 för att justera under "
+"pågående uppträdande."
+
+# ...
+#: /tmp/xml2gettext.pJaf2puMzZ:68
+msgid "Audio round-trip latency"
+msgstr "Ljud round-trip fördröjning"
+
+#: /tmp/xml2gettext.pJaf2puMzZ:69
+msgid ""
+"Affects singing only. The time it takes for Performous playback to reach "
+"your speakers, fly to the microphone and all the way back until Performous "
+"captures and analyzes it. While performing, press Ctrl+S for synth mode and "
+"adjust with Ctrl+F3/F4."
+msgstr ""
+"Påverkar endast sjungande. Tiden det tar för Performous ljuduppspelning att "
+"från högtalarna, till mikrofonen och hela vägen tillbaks tills Performous "
+"plockar upp det och analyserar det. Tryck Ctrl+S för synt-läge under "
+"pågående uppträdande och justera med Ctrl+F3/F4."
+
+#: /tmp/xml2gettext.pJaf2puMzZ:70
+msgid "Audio/controller latency"
+msgstr "Ljud/kontroll-fördröjning"
+
+#: /tmp/xml2gettext.pJaf2puMzZ:71
+msgid ""
+"Affects instruments and dancing only. The total of USB (guitar or dance pad) "
+"latency combined with audio output latency. Adjust so that you can hit the "
+"notes best when playing by ear (not looking on screen). Use Ctrl+F5/F6 to "
+"adjust while performing."
+msgstr ""
+"Påverkar endast instrument och dans. Den totala USB (gitarr eller dansmatta) "
+"fördröjningen kombinerat med utgående ljud-fördröjning. Justera så att du "
+"kan träffa noterna när du spelar efter känsla (inte ser på skärmen). Använd "
+"Ctrl+F5/F6 för att justera under uppträdande."
+
+#: /tmp/xml2gettext.pJaf2puMzZ:72
+msgid "Audio devices"
+msgstr "Ljudenheter"
+
+#: /tmp/xml2gettext.pJaf2puMzZ:73
+msgid "List of audio devices to try."
+msgstr "Lista med ljudenheter att prova."
+
+#: /tmp/xml2gettext.pJaf2puMzZ:74
+msgid "Menu volume"
+msgstr "Meny-volym"
+
+#: /tmp/xml2gettext.pJaf2puMzZ:75
+msgid "The volume level of menus, song previews and jukebox mode."
+msgstr "Ljudvolymen i menyer, vid förhandsgranskning av låtar och jukebox-läge"
+
+#: /tmp/xml2gettext.pJaf2puMzZ:76
+msgid "Music volume"
+msgstr "Musik-volym"
+
+#: /tmp/xml2gettext.pJaf2puMzZ:77
+msgid ""
+"The ingame music volume. Values above 90 are not recommended as distortion "
+"may occur."
+msgstr ""
+"Ljudvolymen i spelet. Värden över 90 rekommenderas inte då distortion kan "
+"ske."
+
+#: /tmp/xml2gettext.pJaf2puMzZ:78
+msgid "Failure volume"
+msgstr "Misslyckande-volym"
+
+# ... heh?
+# Following the german trans: ignoring "89 louder!"
+#: /tmp/xml2gettext.pJaf2puMzZ:79
+msgid ""
+"The ingame fail sound volume. Values above 90 are not recommended as "
+"distortion may occur. 11 is louder than 10, but these go to 100. 89 louder!"
+msgstr ""
+"Ljudvolymen vid misslyckande under spel. Värden över 90 rekommenderas inte "
+"eftersom förvrängning kan ske. 11 är högre än 10, men dessa går upp till 100."
+
+#: /tmp/xml2gettext.pJaf2puMzZ:80
+msgid "Microphone pass-through"
+msgstr ""
+
+#: /tmp/xml2gettext.pJaf2puMzZ:81
+msgid "Send captured singing voice to speakers."
+msgstr ""
+
+#: /tmp/xml2gettext.pJaf2puMzZ:82
+msgid "Pass-through volume ratio"
+msgstr ""
+
+#: /tmp/xml2gettext.pJaf2puMzZ:83
+msgid "How much voice is amplified compared to the music."
+msgstr ""
+
+# Låt/Sång
+#: /tmp/xml2gettext.pJaf2puMzZ:84
+msgid "Song folders"
+msgstr "Låtkataloger"
+
+#: /tmp/xml2gettext.pJaf2puMzZ:85
+msgid ""
+"Where to recursively look for songs. DATADIR at the beginning means all "
+"Performous data folders."
+msgstr ""
+"Anger var rekursiv sökning efter låtar sker. DATADIR i början innebär alla "
+"Performous datakataloger."
+
+#: /tmp/xml2gettext.pJaf2puMzZ:86
+msgid "Base folders for data"
+msgstr "Baskatalog för data"
+
+#: /tmp/xml2gettext.pJaf2puMzZ:87
+msgid ""
+"System defaults are included automatically. Additional paths can be added "
+"here."
+msgstr ""
+"Systemets standardvärden inkluderas automatiskt. Extra sökvägar kan läggas "
+"till här."
+
+#~ msgid "Song is broken!"
+#~ msgstr "Låten är trasig!"
+
+#~ msgid "Loading instruments..."
+#~ msgstr "Laddar instrument..."
+
+#~ msgid "Finalizing..."
+#~ msgstr "Slutför..."
+
+#, fuzzy
+#~ msgid "Loading graphics..."
+#~ msgstr "Laddar låt..."
+
+#~ msgid "Random background..."
+#~ msgstr "Slumpmässig bakgrund"
diff --git a/lang/zh.po b/lang/zh.po
new file mode 100644 (file)
index 0000000..ab1c744
--- /dev/null
@@ -0,0 +1,993 @@
+# Traditional Chinese Messages for performous.
+# Copyright (C) 2010 The performous Project (msgids)
+# This file is distributed under the same license as the performous package.
+# Wei-Lun Chao <william.chao@ossii.com.tw>, 2010.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: performous 0.6.1\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2013-07-13 18:07+0200\n"
+"PO-Revision-Date: 2013-07-13 18:09+0200\n"
+"Last-Translator: FooBar\n"
+"Language-Team: Chinese (traditional) <zh-l10n@linux.org.tw>\n"
+"Language: zh_TW\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=1; plural=0;\n"
+"X-Generator: Poedit 1.5.4\n"
+"X-Poedit-Basepath: ../game/\n"
+"X-Poedit-SearchPath-0: .\n"
+
+#: configuration.cc:112
+msgid "Enabled"
+msgstr "已啟用"
+
+#: configuration.cc:112
+msgid "Disabled"
+msgstr "已停用"
+
+#: configuration.cc:116
+#, c-format
+msgid "%d items"
+msgstr "%d 項"
+
+#: screen_playlist.cc:110 screen_playlist.cc:252
+msgid "Continue"
+msgstr ""
+
+#: screen_playlist.cc:110
+msgid "Continue playing"
+msgstr ""
+
+#: screen_playlist.cc:118
+msgid "Add songs"
+msgstr ""
+
+#: screen_playlist.cc:118
+msgid "Open the song browser to add more songs"
+msgstr ""
+
+#: screen_playlist.cc:119 screen_songs.cc:509
+msgid "Shuffle"
+msgstr ""
+
+#: screen_playlist.cc:119
+msgid "Randomize the order of the playlist"
+msgstr ""
+
+#: screen_playlist.cc:125
+msgid "Clear and exit"
+msgstr ""
+
+#: screen_playlist.cc:125
+msgid "Remove all the songs from the list"
+msgstr ""
+
+#: screen_playlist.cc:131 screen_playlist.cc:275 screen_songs.cc:522
+msgid "Back"
+msgstr ""
+
+#: screen_playlist.cc:131 screen_playlist.cc:275
+msgid "Back to playlist viewer"
+msgstr ""
+
+#: screen_playlist.cc:237
+msgid "Press enter to view song options"
+msgstr ""
+
+#: screen_playlist.cc:244
+msgid "View more options"
+msgstr ""
+
+#: screen_playlist.cc:244
+#, fuzzy
+msgid "View general playlist settings"
+msgstr "組配一般音效設定值"
+
+#: screen_playlist.cc:252
+msgid "Play first"
+msgstr ""
+
+#: screen_playlist.cc:254
+msgid "Ignore the playlist's order and play this song first"
+msgstr ""
+
+#: screen_playlist.cc:255
+msgid "Start the song already!"
+msgstr ""
+
+#: screen_playlist.cc:264
+msgid "Remove"
+msgstr ""
+
+#: screen_playlist.cc:264
+msgid "Remove this song from the list"
+msgstr ""
+
+#: screen_paths.cc:24
+msgid ""
+"This tool is not yet available.\n"
+"Configure paths by adding them\n"
+"as command line parameters and\n"
+"then save them in configuration menu."
+msgstr ""
+"這個工具尚不可用。\n"
+"經由做為命令列參數\n"
+"加入它們以組配路徑\n"
+"然後將它們儲存在組態選單中。"
+
+#: screen_paths.cc:70
+msgid "Press any key to exit."
+msgstr "按下任何鍵以離開。"
+
+#: screen_paths.cc:76
+msgid "Windows users can also use ConfigureSongDirectory.bat script."
+msgstr "Windows 使用者也可以使用在 中的 ConfigureSongDirectory.bat。"
+
+#: dancegraph.cc:18
+msgid "Beginner"
+msgstr "初學者"
+
+#: dancegraph.cc:18 guitargraph.cc:14
+msgid "Easy"
+msgstr "輕鬆"
+
+#: dancegraph.cc:18 guitargraph.cc:14
+msgid "Medium"
+msgstr "中等"
+
+#: dancegraph.cc:18 guitargraph.cc:14
+msgid "Hard"
+msgstr "硬底"
+
+#: dancegraph.cc:18
+msgid "Challenge"
+msgstr "挑戰"
+
+#: dancegraph.cc:107 guitargraph.cc:194
+msgid "Ready!"
+msgstr "就緒!"
+
+#: dancegraph.cc:107 guitargraph.cc:194 screen_intro.cc:166
+msgid "Start performing!"
+msgstr "開始歡唱!"
+
+#: dancegraph.cc:118 guitargraph.cc:183
+msgid "Select track"
+msgstr "選取軌段"
+
+#: dancegraph.cc:134 guitargraph.cc:163
+msgid "Select difficulty"
+msgstr "選取難度"
+
+#: dancegraph.cc:137 instrumentgraph.cc:59 guitargraph.cc:200
+#: screen_intro.cc:184 screen_sing.cc:92 screen_sing.cc:126
+msgid "Quit"
+msgstr "離開"
+
+#: dancegraph.cc:137 instrumentgraph.cc:59 guitargraph.cc:200
+#: screen_sing.cc:92 screen_sing.cc:126
+msgid "Exit to song browser"
+msgstr "離開到歌曲瀏覽器"
+
+#: dancegraph.cc:248
+msgid "STOP!"
+msgstr "停止!"
+
+#: dancegraph.cc:321 guitargraph.cc:447
+msgid "Streak!"
+msgstr "劃線!"
+
+#: instrumentgraph.cc:56 screen_sing.cc:123
+msgid "Resume"
+msgstr "再續"
+
+#: instrumentgraph.cc:56 screen_sing.cc:123
+msgid "Back to performing!"
+msgstr "回到歡唱!"
+
+#: instrumentgraph.cc:57
+msgid "Rejoin"
+msgstr "重新連結"
+
+#: instrumentgraph.cc:57
+msgid "Change selections"
+msgstr "變更選擇"
+
+#: instrumentgraph.cc:58 screen_sing.cc:124
+msgid "Restart"
+msgstr "重新啟動"
+
+#: instrumentgraph.cc:58 screen_sing.cc:124
+msgid ""
+"Start the song\n"
+"from the beginning"
+msgstr ""
+"從開始部分\n"
+"播放歌曲"
+
+#: songs.cc:178
+msgid "show all songs"
+msgstr ""
+
+#: songs.cc:179
+msgid "has dance"
+msgstr ""
+
+#: songs.cc:180
+#, fuzzy
+msgid "has vocals"
+msgstr "人聲"
+
+#: songs.cc:181
+msgid "has duet"
+msgstr ""
+
+#: songs.cc:182
+#, fuzzy
+msgid "has guitar"
+msgstr "節奏吉他"
+
+#: songs.cc:183
+msgid "drums or keytar"
+msgstr ""
+
+#: songs.cc:184
+msgid "full band"
+msgstr ""
+
+#: songs.cc:212
+msgid "random order"
+msgstr "隨機排序"
+
+#: songs.cc:213
+msgid "sorted by song"
+msgstr "依歌曲排序"
+
+#: songs.cc:214
+msgid "sorted by artist"
+msgstr "依歌手排序"
+
+#: songs.cc:215
+msgid "sorted by edition"
+msgstr "依專輯排序"
+
+#: songs.cc:216
+msgid "sorted by genre"
+msgstr "依類型排序"
+
+#: songs.cc:217
+msgid "sorted by path"
+msgstr "依路徑排序"
+
+#: songs.cc:218
+msgid "sorted by language"
+msgstr "依語言排序"
+
+#: screen_audiodevices.cc:55
+msgid ""
+"It seems you have some manual configurations\n"
+"incompatible with this user interface.\n"
+"Saving these settings will override\n"
+"all existing audio device configuration.\n"
+"Your other options changes will be saved too."
+msgstr ""
+"您似乎有某些手動的組態\n"
+"與這個使用者介面不相容。\n"
+"儲存這些設定值將會強制變更\n"
+"所有現存音效裝置的組態。\n"
+"您的其他選項變更也將被儲存。"
+
+#: screen_audiodevices.cc:114
+msgid "- Unassigned -"
+msgstr "- 未賦值的 -"
+
+#: screen_audiodevices.cc:135
+msgid ""
+"Use arrow keys to configure. Hit Enter/Start to save and test or Esc/Select "
+"to cancel. Ctrl + R to reset defaults"
+msgstr ""
+"使用方向鍵以組配。點擊 輸入/開始 以儲存與測試,或 Esc/選取 以取消。Ctrl + R "
+"以重置預設值"
+
+#: screen_audiodevices.cc:140
+msgid ""
+"For advanced device configuration, use command line parameter --audio (use --"
+"audiohelp for details)."
+msgstr ""
+"使用命令列參數 --audio (使用 --audiohelp 以瞭解細節) 用於進階裝置組態。"
+
+#: screen_audiodevices.cc:188
+msgid "Some devices failed to open!"
+msgstr "無法開啟某些裝置!"
+
+#: main.cc:145
+msgid "Loading audio samples..."
+msgstr "載入音效樣本…"
+
+#: main.cc:159
+msgid "Creating screens..."
+msgstr "建立畫面…"
+
+#: main.cc:169
+msgid "Entering main menu"
+msgstr "進入主選單"
+
+#: main.cc:171 screen_sing.cc:97
+msgid "Loading complete"
+msgstr "載入完成"
+
+#: main.cc:182
+msgid "Screenshot taken!"
+msgstr "拍下螢幕快照!"
+
+#: main.cc:185
+msgid "Screenshot failed!"
+msgstr "螢幕快照失敗!"
+
+#: guitargraph.cc:14
+msgid "Kids"
+msgstr "兒童"
+
+#: guitargraph.cc:14
+msgid "Expert"
+msgstr "專家"
+
+#: guitargraph.cc:169 guitargraph.cc:186
+msgid "Lefty-mode"
+msgstr "左手模式"
+
+#: guitargraph.cc:207
+msgid "ON"
+msgstr "開"
+
+#: guitargraph.cc:207
+msgid "OFF"
+msgstr "關閉"
+
+#: guitargraph.cc:208
+msgid "Toggle lefty-mode"
+msgstr "切換左手模式"
+
+#: guitargraph.cc:459
+msgid ""
+"God Mode\n"
+"Activated!"
+msgstr ""
+"上帝模式\n"
+"啟用!"
+
+#: guitargraph.cc:460
+msgid "Mistakes ignored!"
+msgstr "忽略錯誤!"
+
+#: guitargraph.cc:1102
+msgid "God Mode Ready!"
+msgstr "上帝模式就緒!"
+
+#: guitargraph.cc:1103
+msgid "Drum Fill!"
+msgstr "填滿鼓聲!"
+
+#: guitargraph.cc:1106
+msgid "Solo!"
+msgstr "獨唱!"
+
+#: screen_songs.cc:278
+#, fuzzy
+msgid "Sorry, no songs match the search!"
+msgstr "沒有符合搜尋的歌曲"
+
+#: screen_songs.cc:281
+#, fuzzy
+msgid "Sorry, no songs match the filter!"
+msgstr "沒有符合搜尋的歌曲"
+
+#: screen_songs.cc:284
+msgid "No songs found!"
+msgstr "找不到歌曲!"
+
+#: screen_songs.cc:285
+#, fuzzy
+msgid "Visit performous.org for free songs"
+msgstr ""
+"造訪 performous.org\n"
+"以取得免費歌曲"
+
+#: screen_songs.cc:303
+msgid "<type in to search>"
+msgstr "<輸入以搜尋>"
+
+#: screen_songs.cc:303
+msgid "songs"
+msgstr ""
+
+#: screen_songs.cc:303
+msgid "options"
+msgstr ""
+
+#: screen_songs.cc:305
+msgid "sort order: "
+msgstr ""
+
+#: screen_songs.cc:306
+msgid "type filter: "
+msgstr ""
+
+#: screen_songs.cc:307
+msgid "hiscores"
+msgstr ""
+
+#: screen_songs.cc:307
+msgid "jukebox mode"
+msgstr ""
+
+#: screen_songs.cc:310
+msgid "start a playlist with this song!"
+msgstr ""
+
+#: screen_songs.cc:310
+msgid "open the playlist menu"
+msgstr ""
+
+#: screen_songs.cc:502
+msgid "Play"
+msgstr ""
+
+#: screen_songs.cc:515
+msgid "View playlist"
+msgstr ""
+
+#: screen_songs.cc:516
+msgid "Clear playlist"
+msgstr ""
+
+#: screen_intro.cc:24
+msgid "No playback devices could be used.\n"
+msgstr "沒有播放控制裝置可供使用。\n"
+
+#: screen_intro.cc:25
+msgid ""
+"\n"
+"Please configure some before playing."
+msgstr ""
+"\n"
+"請於播放前設定一些項目。"
+
+#: screen_intro.cc:69
+msgid "Settings saved as system defaults."
+msgstr ""
+
+#: screen_intro.cc:69
+msgid "Settings saved."
+msgstr ""
+
+#: screen_intro.cc:149
+msgid "Ctrl + S to save, Ctrl + R to reset defaults"
+msgstr "Ctrl + S 以儲存,Ctrl + R 以重置預設值"
+
+#: screen_intro.cc:166
+msgid "Perform"
+msgstr "開唱"
+
+#: screen_intro.cc:167
+msgid "Practice"
+msgstr "練習"
+
+#: screen_intro.cc:167
+msgid "Check your skills or test the microphones"
+msgstr "檢查您的技巧或測試一下麥克風"
+
+#: screen_intro.cc:183
+msgid "Configure"
+msgstr "設定"
+
+#: screen_intro.cc:183
+msgid "Configure audio and game options"
+msgstr "組配音效和遊戲選項"
+
+#: screen_intro.cc:184
+msgid "Leave the game"
+msgstr "離開遊戲"
+
+#: screen_players.cc:115
+msgid "No players found!"
+msgstr "找不到演唱者!"
+
+#: screen_players.cc:116
+msgid "Enter a name to create a new player."
+msgstr "輸入名稱以建立新的演唱者。"
+
+#: screen_players.cc:118
+msgid "Press enter to create player!"
+msgstr "按下輸入以建立演唱者!"
+
+#: screen_players.cc:122
+#, fuzzy
+msgid "No players worth mentioning!"
+msgstr "找不到演唱者!"
+
+#: screen_players.cc:127
+msgid "You reached %1% points!"
+msgstr "您得到了 %1% 分!"
+
+#: screen_players.cc:128
+msgid "Change player with arrow keys."
+msgstr "利用方向鍵變更演唱者。"
+
+#: screen_players.cc:129
+msgid "Name:"
+msgstr "名稱:"
+
+#: screen_players.cc:132
+msgid "Type text to filter or create a new player."
+msgstr "輸入文字到篩選器或建立新的演唱者。"
+
+#: screen_players.cc:132
+msgid "Search Text:"
+msgstr "搜尋文字:"
+
+#: screen_sing.cc:45
+msgid "Initializing webcam..."
+msgstr "初始化網路攝影機…"
+
+#: screen_sing.cc:52
+msgid "Loading video..."
+msgstr "載入影像…"
+
+#: screen_sing.cc:59
+msgid "Loading song..."
+msgstr "載入歌曲…"
+
+#: screen_sing.cc:66
+msgid "Song contains broken tracks!"
+msgstr "歌曲含有不完整的軌段!"
+
+#: screen_sing.cc:71
+msgid "Loading menu..."
+msgstr "載入選單…"
+
+#: screen_sing.cc:76
+#, fuzzy
+msgid "Start"
+msgstr "重新啟動"
+
+#: screen_sing.cc:76
+#, fuzzy
+msgid "Start performing"
+msgstr "開始歡唱!"
+
+#: screen_sing.cc:80
+#, fuzzy
+msgid "Duet mode"
+msgstr "左手模式"
+
+#: screen_sing.cc:81
+#, fuzzy
+msgid "Normal mode"
+msgstr "卡拉OK模式"
+
+#: screen_sing.cc:82
+msgid "Switch between duet and regular singing mode"
+msgstr ""
+
+#: screen_sing.cc:90
+#, fuzzy
+msgid "Change vocal track"
+msgstr ""
+"變更人聲軌段\n"
+"(需要重新啟動)"
+
+#: screen_sing.cc:125
+msgid "Skip"
+msgstr ""
+
+#: screen_sing.cc:125
+msgid "Skip current song"
+msgstr ""
+
+#: screen_sing.cc:391
+msgid "Press UP to join dance!"
+msgstr ""
+
+#: screen_sing.cc:391
+msgid "Step UP to join!"
+msgstr ""
+
+#: screen_sing.cc:396
+msgid "Press 1 to join guitar!"
+msgstr ""
+
+#: screen_sing.cc:396
+msgid "Press GREEN to join!"
+msgstr ""
+
+#: screen_sing.cc:401
+msgid "Press SPACE to join drums!"
+msgstr ""
+
+#: screen_sing.cc:401
+msgid "KICK to join!"
+msgstr ""
+
+#: screen_sing.cc:475
+msgid "   ENTER to skip instrumental break"
+msgstr "   按下輸入鍵以跳過樂器演奏中斷時間"
+
+#: screen_sing.cc:476
+msgid "   Remember to wait for grading!"
+msgstr "   記得等一下看評分!"
+
+#: screen_sing.cc:587
+msgid "No player!"
+msgstr "沒有演唱者!"
+
+#: screen_sing.cc:594
+msgid "Hit singer"
+msgstr "熱門歌手"
+
+#: screen_sing.cc:595
+msgid "Lead singer"
+msgstr "領先歌手"
+
+#: screen_sing.cc:596 screen_sing.cc:602 screen_sing.cc:608
+msgid "Rising star"
+msgstr "上升之星"
+
+#: screen_sing.cc:597 screen_sing.cc:603 screen_sing.cc:609
+msgid "Amateur"
+msgstr "業餘"
+
+#: screen_sing.cc:598 screen_sing.cc:610
+msgid "Tone deaf"
+msgstr "音癡"
+
+#: screen_sing.cc:600
+msgid "Maniac"
+msgstr "瘋子"
+
+#: screen_sing.cc:601
+msgid "Hoofer"
+msgstr "舞者"
+
+#: screen_sing.cc:604
+msgid "Loser"
+msgstr "輸家"
+
+#: screen_sing.cc:606
+msgid "Virtuoso"
+msgstr "鑒賞家"
+
+#: screen_sing.cc:607
+msgid "Rocker"
+msgstr "搖滾者"
+
+#~ msgid "Audio Devices"
+#~ msgstr "音效裝置"
+
+#~ msgid "Setup microphones and playback"
+#~ msgstr "設定麥克風和播放控制"
+
+#~ msgid "Audio"
+#~ msgstr "音效"
+
+#~ msgid "Graphics"
+#~ msgstr "圖形"
+
+#~ msgid "Configure rendering and video settings"
+#~ msgstr "組配潤算和影像設定值"
+
+#~ msgid "Game"
+#~ msgstr "遊戲"
+
+#~ msgid "Gameplay related options"
+#~ msgstr "遊戲相關的選項"
+
+#~ msgid "Paths"
+#~ msgstr "路徑"
+
+#~ msgid "Setup song and data paths"
+#~ msgstr "設定歌曲和資料路徑"
+
+#~ msgid "Loading theme..."
+#~ msgstr "載入布景主題…"
+
+#~ msgid "Song is broken!"
+#~ msgstr "歌曲已損壞!"
+
+#~ msgid "Loading background..."
+#~ msgstr "載入背景…"
+
+#~ msgid "Random background..."
+#~ msgstr "隨機背景…"
+
+#~ msgid "Loading user interface..."
+#~ msgstr "載入使用者介面…"
+
+#~ msgid "Loading instruments..."
+#~ msgstr "載入樂器…"
+
+#~ msgid "Finalizing..."
+#~ msgstr "結束…"
+
+#~ msgid "No Items up to now."
+#~ msgstr "目前還沒有名單。"
+
+#~ msgid "Be the first to be listed here!"
+#~ msgstr "在此成為清單中的第一位!"
+
+#~ msgid "(press END to view hiscores)"
+#~ msgstr "(按下結束以檢視評分結果)"
+
+#~ msgid "Hisccore for %1%\n"
+#~ msgstr "%1% 的評分結果\n"
+
+#~ msgid "Guitar"
+#~ msgstr "吉他"
+
+#~ msgid "Coop guitar"
+#~ msgstr "合奏吉他"
+
+#~ msgid "Bass"
+#~ msgstr "低音"
+
+#~ msgid "Drums"
+#~ msgstr "鼓聲"
+
+#~ msgid "Harmonic 1"
+#~ msgstr "調和 1"
+
+#~ msgid "Harmonic 2"
+#~ msgstr "調和 2"
+
+#~ msgid "Harmonic 3"
+#~ msgstr "調和 3"
+
+#~ msgid "Gameplay settings."
+#~ msgstr "遊戲設定值。"
+
+#~ msgid "Graphic"
+#~ msgstr "圖形"
+
+#~ msgid "Video and rendering settings."
+#~ msgstr "影像和潤算設定值。"
+
+#~ msgid "Audio-related settings."
+#~ msgstr "音效相關設定值。"
+
+#~ msgid "System paths."
+#~ msgstr "系統路徑。"
+
+#~ msgid "Hide pitch wave, notes and scoring."
+#~ msgstr "隱藏音高、音符和評分。"
+
+#~ msgid "Pitch waves"
+#~ msgstr "音波"
+
+#~ msgid "Enable singing pitch display (when not in karaoke mode)."
+#~ msgstr "啟用歌唱音高顯示 (當不在卡拉OK模式下)。"
+
+#~ msgid "Theme"
+#~ msgstr "布景主題"
+
+#~ msgid "Name of the theme to use or absolute path to theme folder."
+#~ msgstr "使用的布景主題名稱或是布景主題資料夾的絕對路徑。"
+
+#~ msgid "Keyboard as guitar"
+#~ msgstr "鍵盤做為吉他"
+
+#~ msgid "Enable keyboard as guitar (Frets on Fire mode)."
+#~ msgstr "啟用鍵盤做為吉他 (Frets on Fire 模式)。"
+
+#~ msgid "Keyboard as drumkit"
+#~ msgstr "鍵盤做為爵士鼓"
+
+#~ msgid "Enable keyboard as drumkit."
+#~ msgstr "啟用鍵盤做為爵士鼓。"
+
+#~ msgid "Keyboard as dance pad"
+#~ msgstr "鍵盤做為舞墊"
+
+#~ msgid "Enable keyboard as dance pad."
+#~ msgstr "啟用鍵盤做為舞墊。"
+
+#~ msgid "Joystick configuration"
+#~ msgstr "搖桿組態"
+
+#~ msgid "Force joystick to some kind of instrument."
+#~ msgstr "強制搖桿成為某種樂器。"
+
+#~ msgid "Hardware MIDI input device"
+#~ msgstr "硬體 MIDI 輸入裝置"
+
+#~ msgid ""
+#~ "Part of sound card name or its number or empty to use the first available "
+#~ "device. Used currently for MIDI drum controllers."
+#~ msgstr ""
+#~ "音效卡的部分名稱、它的編號或是空白,以使用第一個可用裝置。使用目前的做為 "
+#~ "MIDI 鼓聲控制器。"
+
+#~ msgid "Windowed width"
+#~ msgstr "視窗寬度"
+
+#~ msgid "The width of the window."
+#~ msgstr "視窗的寬度。"
+
+#~ msgid "Windowed height"
+#~ msgstr "視窗高度"
+
+#~ msgid "The height of the window."
+#~ msgstr "視窗的高度。"
+
+#~ msgid "Fullscreen mode"
+#~ msgstr "全螢幕模式"
+
+#~ msgid "Enable fullscreen mode on startup."
+#~ msgstr "啟動時啟用全螢幕模式。"
+
+#~ msgid "Video playback"
+#~ msgstr "影像播放控制"
+
+#~ msgid ""
+#~ "Allows completely disabling background videos. It is recommended to leave "
+#~ "this enabled as Performous will still smoothly fade out the video if your "
+#~ "computer is not fast enough."
+#~ msgstr ""
+#~ "允許完全停用背景影像。建議保持其為啟用,因為如果您的電腦不夠快,"
+#~ "Performous 仍將平滑淡出影像。"
+
+#~ msgid "Webcam background"
+#~ msgstr "網路攝影機背景"
+
+#~ msgid ""
+#~ "Performous can try to use webcam as a background video. You can disable "
+#~ "it if it annoys you."
+#~ msgstr ""
+#~ "Performous 可以試著使用網路攝影機做為背景影像。如果它使您厭煩,您可以停用"
+#~ "它。"
+
+#~ msgid "Webcam id"
+#~ msgstr "網路攝影機識別號"
+
+#~ msgid ""
+#~ "Use -1 to autodetect or a number starting from 0 to choose specific "
+#~ "device."
+#~ msgstr "使用 -1 以自動偵測,或是一個從 0 開始的數字以選擇特定的裝置。"
+
+#~ msgid "3D notes"
+#~ msgstr "立體音符"
+
+#~ msgid ""
+#~ "Draw instrument notes as 3-dimensional objects. May hurt performance on "
+#~ "older hardware."
+#~ msgstr "以立體物件繪製樂器音符。在舊硬體上也許有損效能。"
+
+#~ msgid "SVG quality"
+#~ msgstr "SVG 品質"
+
+#~ msgid ""
+#~ "Larger numbers cause vector graphics to be rendered in higher resolution. "
+#~ "Decrease this to make navigating in menus faster."
+#~ msgstr ""
+#~ "較大的數字會造成向量圖形以較高解析度進行潤算。減少它以便較快巡覽選單。"
+
+#~ msgid "Text quality"
+#~ msgstr "文字品質"
+
+#~ msgid ""
+#~ "Larger numbers cause text to be rendered in higher resolution. Decrease "
+#~ "this to make everything a little faster."
+#~ msgstr ""
+#~ "較大的數字會造成文字以較高解析度進行潤算。減少它好讓所有東西快一點。"
+
+#~ msgid "Benchmark mode"
+#~ msgstr "效能評定模式"
+
+#~ msgid ""
+#~ "Framerate limit of 100 FPS is removed and the game instead renders at "
+#~ "full speed. FPS values are printed to console. Please note that the "
+#~ "display drivers may still limit the rendering speed to the screen refresh "
+#~ "rate."
+#~ msgstr ""
+#~ "已移除 100 FPS 的影格率限制,遊戲則以全速進行潤算。FPS 值已印出至主控臺。"
+#~ "要注意的是,顯示卡驅動程式也許仍然會限制潤算速度為螢幕重新整理速率。"
+
+#~ msgid "Suggested latency"
+#~ msgstr "建議的延時"
+
+#~ msgid ""
+#~ "This is a hint for the audio engine about the desired latency. Set this "
+#~ "as low as possible while retaining clear audio playback. Requires restart."
+#~ msgstr ""
+#~ "這是關於所設想延時用於音效引擎的提示。在保持乾淨的音效播放條件下,儘可能將"
+#~ "它設低一點。需要重新啟動。"
+
+#~ msgid "Audio/video latency"
+#~ msgstr "音效/影像延時"
+
+#~ msgid ""
+#~ "Affects all modes. Use negative value if your display input lag is "
+#~ "greater than the sound card output latency, positive values in the "
+#~ "opposite case and zero if they are equal. This should be set so that the "
+#~ "notes pass the cursor at the same time the audio is heard. Use Ctrl+F1/F2 "
+#~ "to adjust this while performing."
+#~ msgstr ""
+#~ "會影響所有模式。如果您的顯示輸入滯後大於音效卡輸出延時就使用負值,反之則用"
+#~ "正值,如果它們相等就為零。這個應該要設定才會讓音符經過游標的同時也會聽到音"
+#~ "效。執行時期可以使用 Ctrl+F1/F2 來調整它。"
+
+#~ msgid "Audio round-trip latency"
+#~ msgstr "音效往返延時"
+
+#~ msgid ""
+#~ "Affects singing only. The time it takes for Performous playback to reach "
+#~ "your speakers, fly to the microphone and all the way back until "
+#~ "Performous captures and analyzes it. While performing, press Ctrl+S for "
+#~ "synth mode and adjust with Ctrl+F3/F4."
+#~ msgstr ""
+#~ "只會影響歌唱。Performous 的播放控制到達您的揚聲器所需的時間,傳到麥克風然"
+#~ "後一路回來直到 Performous 擷取並分析它。執行時期可以按下 Ctrl+S 進入同步模"
+#~ "式,並利用 Ctrl+F3/F4 來調整。"
+
+#~ msgid "Audio/controller latency"
+#~ msgstr "音效/控制器延時"
+
+#~ msgid ""
+#~ "Affects instruments and dancing only. The total of USB (guitar or dance "
+#~ "pad) latency combined with audio output latency. Adjust so that you can "
+#~ "hit the notes best when playing by ear (not looking on screen). Use Ctrl"
+#~ "+F5/F6 to adjust while performing."
+#~ msgstr ""
+#~ "只會影響樂器和跳舞。USB 裝置(吉他或舞墊) 與音效輸出延時合併的延時總計。如"
+#~ "此調整您就可以很好地經由聽聲音而點擊音符 (不需要看著螢幕)。執行時期可以使"
+#~ "用 Ctrl+F5/F6 來調整它。"
+
+#~ msgid "Audio devices"
+#~ msgstr "音效裝置"
+
+#~ msgid "List of audio devices to try."
+#~ msgstr "要嘗試的音效裝置清單。"
+
+#~ msgid "Menu volume"
+#~ msgstr "選單音量"
+
+#~ msgid "The volume level of menus, song previews and jukebox mode."
+#~ msgstr "選單、歌曲預覽和媒體櫃模式的音量等級。"
+
+#~ msgid "Music volume"
+#~ msgstr "音樂音量"
+
+#~ msgid ""
+#~ "The ingame music volume. Values above 90 are not recommended as "
+#~ "distortion may occur."
+#~ msgstr "遊戲時音樂音量。不建議 90 以上的值,因為也許會發生扭曲。"
+
+#~ msgid "Failure volume"
+#~ msgstr "失敗音量"
+
+#~ msgid ""
+#~ "The ingame fail sound volume. Values above 90 are not recommended as "
+#~ "distortion may occur. 11 is louder than 10, but these go to 100. 89 "
+#~ "louder!"
+#~ msgstr ""
+#~ "遊戲時失敗音量。不建議 90 以上的值,因為也許會發生扭曲。11 要比 10 大聲,"
+#~ "但是這些會到 100。89 比較大聲!"
+
+#~ msgid "Song folders"
+#~ msgstr "歌曲資料夾"
+
+#~ msgid ""
+#~ "Where to recursively look for songs. DATADIR at the beginning means all "
+#~ "Performous data folders."
+#~ msgstr ""
+#~ "遞迴找尋歌曲的位置。起始部分的 DATADIR 表示所有 Performous 的資料夾。"
+
+#~ msgid "Base folders for data"
+#~ msgstr "資料的基底資料夾"
+
+#~ msgid ""
+#~ "System defaults are included automatically. Additional paths can be added "
+#~ "here."
+#~ msgstr "自動會包含系統預設值。可以在此加入額外路徑。"
diff --git a/osx-utils/CMakeCache.txt b/osx-utils/CMakeCache.txt
new file mode 100644 (file)
index 0000000..b18ef89
--- /dev/null
@@ -0,0 +1,40 @@
+# This is the CMakeCache file.
+# For build in directory: /Users/Koji/performous/osx-utils
+# It was generated by CMake: /opt/local/bin/cmake
+# You can edit this file to change values found and used by cmake.
+# If you do not want to change any of the values, simply exit the editor.
+# If you do want to change a value, simply edit, save, and exit the editor.
+# The syntax for the file is as follows:
+# KEY:TYPE=VALUE
+# KEY is the name of a variable in the cache.
+# TYPE is a hint to GUIs for the type of VALUE, DO NOT EDIT TYPE!.
+# VALUE is the current value for the KEY.
+
+########################
+# EXTERNAL cache entries
+########################
+
+
+########################
+# INTERNAL cache entries
+########################
+
+//This is the directory where this CMakeCache.txt was created
+CMAKE_CACHEFILE_DIR:INTERNAL=/Users/Koji/performous/osx-utils
+//Major version of cmake used to create the current loaded cache
+CMAKE_CACHE_MAJOR_VERSION:INTERNAL=2
+//Minor version of cmake used to create the current loaded cache
+CMAKE_CACHE_MINOR_VERSION:INTERNAL=8
+//Patch version of cmake used to create the current loaded cache
+CMAKE_CACHE_PATCH_VERSION:INTERNAL=12
+//Path to CMake executable.
+CMAKE_COMMAND:INTERNAL=/opt/local/bin/cmake
+//Path to cpack program executable.
+CMAKE_CPACK_COMMAND:INTERNAL=/opt/local/bin/cpack
+//Path to ctest program executable.
+CMAKE_CTEST_COMMAND:INTERNAL=/opt/local/bin/ctest
+//Path to cache edit program executable.
+CMAKE_EDIT_COMMAND:INTERNAL=/opt/local/bin/ccmake
+//Path to CMake installation.
+CMAKE_ROOT:INTERNAL=/opt/local/share/cmake-2.8
+
diff --git a/osx-utils/CMakeFiles/cmake.check_cache b/osx-utils/CMakeFiles/cmake.check_cache
new file mode 100644 (file)
index 0000000..3dccd73
--- /dev/null
@@ -0,0 +1 @@
+# This file is generated by cmake for dependency checking of the CMakeCache.txt file
diff --git a/osx-utils/performous-app-build.sh b/osx-utils/performous-app-build.sh
new file mode 100755 (executable)
index 0000000..68e6ec6
--- /dev/null
@@ -0,0 +1,93 @@
+set -o errexit
+# the very first step is to check that dylibbundler exists,
+# without it the bundle would be broken
+if which dylibbundler &> /dev/null; then
+    echo "dylibbundler found!"
+else
+    echo "dylibbundler not found! you need to install it before creating the bundle."
+    exit
+fi
+
+SOURCE="${BASH_SOURCE[0]}"
+while [ -h "$SOURCE" ]; do # resolve $SOURCE until the file is no longer a symlink
+  DIR="$( cd -P "$( dirname "$SOURCE" )" && pwd )"
+  SOURCE="$(readlink "$SOURCE")"
+  [[ $SOURCE != /* ]] && SOURCE="$DIR/$SOURCE" # if $SOURCE was a relative symlink, we need to resolve it relative to the path where the symlink file was located
+done
+CURRDIR="$( cd -P "$( dirname "$SOURCE" )" && pwd )"
+
+# first compile performous, build dir shouldn't exist at this stage
+
+# define Bundle structure
+TEMPDIR="$CURRDIR/out/Performous.app/Contents"
+RESDIR="$TEMPDIR/Resources"
+LIBDIR="$RESDIR/lib"
+LOCALEDIR="$RESDIR/Locales"
+FRAMEWORKDIR="$RESDIR/Frameworks"
+BINDIR="$TEMPDIR/MacOS"
+ETCDIR="$RESDIR/etc"
+
+rm -rf "$TEMPDIR"
+mkdir -p "$TEMPDIR"
+
+rm -rd ./build
+mkdir build
+cd build
+
+cmake -DCMAKE_INSTALL_PREFIX=$TEMPDIR -DENABLE_TOOLS=OFF -DCMAKE_BUILD_TYPE=Debug -DCMAKE_VERBOSE_MAKEFILE=1 -DFreetype_INCLUDE_DIR=/opt/local/include/freetype2 -DCMAKE_OSX_DEPLOYMENT_TARGET=10.9 -DFontconfig_INCLUDE_DIR=/opt/local/include/fontconfig -DPng_INCLUDE_DIR=/opt/local/include/libpng -DAVCodec_INCLUDE_DIR=/opt/local/include/libavcodec -DGLEW_LIBRARY=/Library/Frameworks/GLEW.framework -DGLEW_INCLUDE_DIR=/Library/Frameworks/GLEW.framework/Headers -DOpenGL_GL_LIBRARY=/System/Library/Frameworks/OpenGL.framework -DOpenGL_GLU_LIBRARY=/System/Library/Frameworks/OpenGL.framework -DOpenGL_INCLUDE_DIR=/System/Library/Frameworks/OpenGL.framework/Headers -DAVFormat_INCLUDE_DIR=/opt/local/include/libavformat -DSWScale_INCLUDE_DIR=/opt/local/include/libswscale  -DSDL2_INCLUDE_DIR=/Library/Frameworks/SDL2.Framework/Headers -DSDL2_LIBRARY=/Library/Frameworks/SDL2.framework -DFreetype_INCLUDE_DIR=/opt/local/include/freetype2/ -DLibXML2_LIBRARY=/opt/local/lib/libxml2.dylib -DLibXML2_INCLUDE_DIR=/opt/local/include/libxml2 -DLibXML++Config_INCLUDE_DIR=/opt/local/lib/libxml++-2.6/include -DGettext_LIBRARY=/opt/local/lib/libgettextlib.dylib  -DGettext_INCLUDE_DIR=/opt/local/include/ -DGlibmmConfig_INCLUDE_DIR=/opt/local/lib/glibmm-2.4/include -DGlibConfig_INCLUDE_DIR=/opt/local/lib/glib-2.0/include -DCMAKE_C_COMPILER=/opt/local/bin/gcc-mp-4.8 -DCMAKE_CXX_COMPILER=/opt/local/bin/g++-mp-4.8 -DCMAKE_C_FLAGS="-arch x86_64" -DSHARE_INSTALL=Resources -DLOCALE_DIR=Resources/Locales -DCMAKE_CXX_FLAGS="-Wno-unused-function -Wno-unused-local-typedefs -Wno-ignored-qualifiers -lstdc++ -arch x86_64 -L/opt/local/lib -lintl -Wl,-framework -Wl,CoreFoundation,-headerpad_max_install_names" -DCMAKE_EXE_LINKER_FLAGS="-ldl -lstdc++ -arch x86_64" -DCMAKE_MODULE_LINKER_FLAGS="-ldl -lstdc++ -arch x86_64" -DCMAKE_OSX_ARCHITECTURES="x86_64" -DCMAKE_SHARED_LINKER_FLAGS="-ldl -lstdc++ -arch x86_64" -DCMAKE_STATIC_LINKER_FLAGS="-ldl -lstdc++ -arch x86_64" ../..
+make -j2 install
+
+# then create the rest of the app bundle
+
+mkdir -p "$BINDIR"
+mv "$TEMPDIR/bin" "$BINDIR"
+
+cp ../resources/performous-launcher "$BINDIR"
+cp ../resources/performous.icns "$RESDIR"
+cp ../resources/Info.plist "$TEMPDIR"
+
+mkdir -p $FRAMEWORKDIR
+cp -R /Library/Frameworks/SDL2.framework "$FRAMEWORKDIR/SDL2.framework"
+mkdir -p $LIBDIR
+
+dylibbundler -od -b -x "$BINDIR/performous" -d "$LIBDIR" -p @executable_path/../Resources/lib/
+
+cp -av /opt/local/lib/pango $LIBDIR/
+
+OLDPREFIX=/opt/local
+NEWPREFIX=$LIBDIR
+
+mkdir -p $ETCDIR/fonts
+cp -av /opt/local/etc/fonts $ETCDIR
+cp -av /opt/local/etc/pango $ETCDIR
+cd $ETCDIR/pango
+
+sed -i '' -e "s|$OLDPREFIX\/etc\/pango\/|\.\/|g" pangorc
+sed -i '' -e "s|$OLDPREFIX|\.\.\/\.\.|g" pango.modules
+
+cd $ETCDIR/fonts
+sed -i '' -e 's|\/opt\/local/share|\.\.\/\.\.\/\.\.\/Resources|g' fonts.conf
+sed -i '' -e 's|\/opt\/local/var/cache|\~\/\.cache|g' fonts.conf
+sed -i '' -e 's|\<\!-- Font directory list --\>|\<\!-- Font directory list --\>\
+    <dir>\.\.\/\.\.\/pixmaps</dir>|g' fonts.conf
+
+cd $LIBDIR/pango/
+cd `find . -type d -maxdepth 1 -mindepth 1`
+cd `find . -type d -maxdepth 1 -mindepth 1` 
+
+for if in `pwd`/*.so
+do
+dylibbundler -x "$if" \
+-p @executable_path/../Resources/lib/ \
+-d "$LIBDIR"
+done 
+
+
+cd "$CURRDIR"
+# then build the disk image
+ln -sf /Applications "${CURRDIR}/out/Applications"
+/usr/bin/hdiutil create -ov -srcfolder out -volname Performous -fs HFS+ -fsargs "-c c=64,a=16,e=16" -format UDRW RWPerformous.dmg
+/usr/bin/hdiutil convert -ov RWPerformous.dmg -format UDZO -imagekey zlib-level=9 -o Performous.dmg
+rm -f RWPerformous.dmg
+
+cd ..
\ No newline at end of file
diff --git a/osx-utils/performous.icns b/osx-utils/performous.icns
new file mode 100644 (file)
index 0000000..7152e91
Binary files /dev/null and b/osx-utils/performous.icns differ
diff --git a/osx-utils/resources/Info.plist b/osx-utils/resources/Info.plist
new file mode 100644 (file)
index 0000000..3d09d66
--- /dev/null
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+       <key>CFBundleDevelopmentRegion</key>
+       <string>English</string>
+       <key>CFBundleExecutable</key>
+       <string>performous-launcher</string>
+       <key>CFBundleGetInfoString</key>
+       <string>Performous</string>
+       <key>CFBundleIconFile</key>
+       <string>performous.icns</string>
+       <key>CFBundleIdentifier</key>
+       <string>org.performous.Performous</string>
+       <key>CFBundleInfoDictionaryVersion</key>
+       <string>6.0</string>
+       <key>CFBundleName</key>
+       <string>performous</string>
+       <key>CFBundlePackageType</key>
+       <string>APPL</string>
+       <key>CFBundleShortVersionString</key>
+       <string>0.8.0+</string>
+       <key>CFBundleSignature</key>
+       <string>????</string>
+       <key>CFBundleVersion</key>
+       <string>0.8.0+</string>
+       <key>LSUIElement</key>
+       <false/>
+       
+       <key>NSHumanReadableCopyright</key>
+       <string>Performous contributors GPLv2+</string>
+</dict>
+</plist>
diff --git a/osx-utils/resources/performous-launcher b/osx-utils/resources/performous-launcher
new file mode 100755 (executable)
index 0000000..5339f06
--- /dev/null
@@ -0,0 +1,17 @@
+#!/bin/bash
+SOURCE="${BASH_SOURCE[0]}"
+while [ -h "$SOURCE" ]; do # resolve $SOURCE until the file is no longer a symlink
+  DIR="$( cd -P "$( dirname "$SOURCE" )" && pwd )"
+  SOURCE="$(readlink "$SOURCE")"
+  [[ $SOURCE != /* ]] && SOURCE="$DIR/$SOURCE" # if $SOURCE was a relative symlink, we need to resolve it relative to the path where the symlink file was located
+done
+CURRDIR="$( cd -P "$( dirname "$SOURCE" )" && pwd )"
+export PATH="${PATH}:${CURRDIR}"
+# Point to the pango and fontconfig config files inside the bundle, in turn linking to modules and fonts inside the bundle as well.
+export FONTCONFIG_PATH="${CURRDIR}/../Resources/etc/fonts"
+export PANGO_RC_FILE="${CURRDIR}/../Resources/etc/pango/pangorc"
+# Without this line, pixbuf tries to use the config file from macports
+# environment. Apparently it works just fine without it too.
+export GDK_PIXBUF_MODULE_FILE=""
+# TODO: might be a good idea to turn-off all console output
+"${CURRDIR}/performous" # Make sure the executable is actually found.
\ No newline at end of file
diff --git a/osx-utils/resources/performous.icns b/osx-utils/resources/performous.icns
new file mode 100644 (file)
index 0000000..7152e91
Binary files /dev/null and b/osx-utils/resources/performous.icns differ
diff --git a/portage-overlay/games-arcade/performous/files/performous-gentoopaths.patch b/portage-overlay/games-arcade/performous/files/performous-gentoopaths.patch
new file mode 100644 (file)
index 0000000..e3023de
--- /dev/null
@@ -0,0 +1,51 @@
+diff --git a/CMakeLists.txt b/CMakeLists.txt
+index d7bb77c..a6c173c 100644
+--- a/CMakeLists.txt
++++ b/CMakeLists.txt
+@@ -24,6 +24,9 @@ else(WIN32)
+       if(NOT SHARE_INSTALL)
+               set(SHARE_INSTALL "share/games/performous" CACHE STRING "Data file install path. Must be a relative path (from CMAKE_INSTALL_PREFIX), with no trailing slash.")
+       endif(NOT SHARE_INSTALL)
++      if(NOT GENTOO_DATA_DIR)
++              SET (GENTOO_DATA_DIR "/usr/share/games/performous" CACHE PATH "data directory prefix")
++      endif(NOT GENTOO_DATA_DIR)
+ endif(WIN32)
+ mark_as_advanced(SHARE_INSTALL)
+diff --git a/game/config.cmake.hh b/game/config.cmake.hh
+index 300ba05..83b38d2 100644
+--- a/game/config.cmake.hh
++++ b/game/config.cmake.hh
+@@ -10,6 +10,7 @@
+ #define VERSION "@PROJECT_VERSION@"
+ #define SHARED_DATA_DIR "@SHARE_INSTALL@"
++#define GENTOO_DATA_DIR "@GENTOO_DATA_DIR@"
+ // FFMPEG libraries use changing include file names... Get them from CMake.
+ #define AVCODEC_INCLUDE <@AVCodec_INCLUDE@>
+diff --git a/game/fs.cc b/game/fs.cc
+index 718d630..2604256 100644
+--- a/game/fs.cc
++++ b/game/fs.cc
+@@ -197,6 +197,9 @@ Paths const& getPaths(bool refresh) {
+               // Adding users data dir
+               dirs.push_back(getDataDir());
++              // Adding gentoo path
++              dirs.push_back(std::string(GENTOO_DATA_DIR));
++
+               // Adding relative path from executable
+               dirs.push_back(plugin::execname().parent_path().parent_path() / shareDir);
+ #ifndef _WIN32
+@@ -223,7 +226,9 @@ fs::path getDefaultConfig(fs::path const &configFile) {
+       typedef std::vector<std::string> ConfigList;
+       ConfigList config_list;
+       char const* root = getenv("PERFORMOUS_ROOT");
+-      if (root) config_list.push_back(std::string(root) + "/" SHARED_DATA_DIR + configFile.string());
++      if (root) config_list.push_back(std::string(root) + "/" + configFile.string());
++      // Adding gentoo specific directory (keeping PERFORMOUS_ROOT first)
++      config_list.push_back(std::string(GENTOO_DATA_DIR) + configFile.string());
+       fs::path exec = plugin::execname();
+       if (!exec.empty()) config_list.push_back(exec.parent_path().string() + "/../" SHARED_DATA_DIR + configFile.string());
+       ConfigList::const_iterator it = std::find_if(config_list.begin(), config_list.end(), static_cast<bool(&)(fs::path const&)>(fs::exists));
diff --git a/portage-overlay/games-arcade/performous/performous-0.4.0.ebuild b/portage-overlay/games-arcade/performous/performous-0.4.0.ebuild
new file mode 100644 (file)
index 0000000..33a0f51
--- /dev/null
@@ -0,0 +1,100 @@
+# Copyright 1999-2006 Gentoo Foundation
+# Distributed under the terms of the GNU General Public License v2
+# $Header: /cvsroot/ultrastar-ng/UltraStar-ng/portage-overlay/games-arcade/performous/performous-9999.ebuild,v 1.10 2007/09/29 13:04:19 yoda-jm Exp $
+
+EAPI=2
+inherit cmake-utils games
+
+RESTRICT="nostrip"
+
+SONGS_PN=ultrastar-songs
+MY_PN=Performous
+MY_P=${MY_PN}-${PV}-Source
+SONGS_PN=ultrastar-songs
+
+DESCRIPTION="Karaoke game similar to Singstar"
+HOMEPAGE="http://performous.org"
+SRC_URI="mirror://sourceforge/${PN}/${MY_P}.tar.bz2
+       songs? ( 
+               mirror://sourceforge/${PN}/${SONGS_PN}-jc-1.zip
+               mirror://sourceforge/${PN}/${SONGS_PN}-libre-3.zip
+               mirror://sourceforge/${PN}/${SONGS_PN}-restricted-3.zip
+               mirror://sourceforge/${PN}/${SONGS_PN}-shearer-1.zip
+       )"
+
+EGIT_REPO_URI="git://performous.git.sourceforge.net/gitroot/performous/performous"
+
+LICENSE="GPL-2
+       songs? (
+               CCPL-Attribution-ShareAlike-NonCommercial-2.5
+               CCPL-Attribution-NonCommercial-NoDerivs-2.5
+       )"
+SLOT="0"
+KEYWORDS="~x86 ~amd64 ~ppc ~ppc64"
+
+IUSE="debug alsa portaudio pulseaudio jack songs gstreamer tools editor"
+
+RDEPEND="gnome-base/librsvg
+       >=dev-libs/boost-1.36.0
+       x11-libs/pango
+       dev-cpp/libxmlpp
+       media-libs/glew
+       media-libs/libsdl[joystick,opengl]
+       media-gfx/imagemagick[png]
+       >=media-video/ffmpeg-0.4.9_p20070616-r20
+       alsa? ( media-libs/alsa-lib )
+       jack? ( media-sound/jack-audio-connection-kit )
+       portaudio? ( media-libs/portaudio )
+       gstreamer? ( media-libs/gstreamer )
+       pulseaudio? ( media-sound/pulseaudio )
+       sys-apps/help2man
+       !games-arcade/ultrastar-ng"
+DEPEND="${RDEPEND}
+    >=dev-util/cmake-2.6.0"
+
+S="${WORKDIR}/${MY_P}"
+
+src_unpack() {
+       unpack "${MY_P}.tar.bz2"
+       if use songs; then
+               cd "${S}"
+               unpack "${SONGS_PN}-jc-1.zip"
+               unpack "${SONGS_PN}-libre-3.zip"
+               unpack "${SONGS_PN}-restricted-3.zip"
+               unpack "${SONGS_PN}-shearer-1.zip"
+       fi
+}
+
+src_configure() {
+       local mycmakeargs="
+               $(cmake-utils_use alsa LIBDA_PLUGIN_ALSA)
+               $(cmake-utils_use jack LIBDA_PLUGIN_JACK)
+               $(cmake-utils_use gstreamer LIBDA_PLUGIN_GSTREAMER)
+               $(cmake-utils_use portaudio LIBDA_PLUGIN_PORTAUDIO)
+               $(cmake-utils_use pulseaudio LIBDA_PLUGIN_PULSEAUDIO)
+               $(cmake-utils_use_enable tools TOOLS)
+               $(cmake-utils_use_enable editor EDITOR)
+               -DCMAKE_INSTALL_PREFIX=${GAMES_PREFIX}
+               -DSHARE_INSTALL=share/performous/
+               -DLIBDA_AUTODETECT_PLUGINS=false
+               -DLIBDA_PLUGIN_TESTING=false
+               -DCMAKE_BUILD_TYPE=Release"
+
+       cmake-utils_src_configure
+}
+
+src_compile() {
+       cmake-utils_src_compile
+}
+
+src_install() {
+       DOCS="docs/*.txt" cmake-utils_src_install
+
+       if use songs; then
+               insinto "/usr/share/games/ultrastar"
+               doins -r "${S}/songs" || die "doins songs failed"
+       fi
+       doicon "${S}/data/${PN}.xpm"
+       domenu "${S}/data/${PN}.desktop"
+       prepgamesdirs
+}
diff --git a/portage-overlay/games-arcade/performous/performous-0.5.1.ebuild b/portage-overlay/games-arcade/performous/performous-0.5.1.ebuild
new file mode 100644 (file)
index 0000000..1af2d4b
--- /dev/null
@@ -0,0 +1,102 @@
+# Copyright 1999-2006 Gentoo Foundation
+# Distributed under the terms of the GNU General Public License v2
+# $Header: /cvsroot/ultrastar-ng/UltraStar-ng/portage-overlay/games-arcade/performous/performous-9999.ebuild,v 1.10 2007/09/29 13:04:19 yoda-jm Exp $
+
+EAPI=2
+inherit games cmake-utils
+
+RESTRICT="nostrip"
+
+SONGS_PN=ultrastar-songs
+
+MY_PN=Performous
+MY_P=${MY_PN}-${PV}-Source
+SONGS_PN=ultrastar-songs
+
+DESCRIPTION="Karaoke game similar to Singstar"
+HOMEPAGE="http://performous.org"
+SRC_URI="mirror://sourceforge/${PN}/${MY_P}.tar.bz2
+       songs? ( 
+               mirror://sourceforge/${PN}/${SONGS_PN}-jc-1.zip
+               mirror://sourceforge/${PN}/${SONGS_PN}-libre-3.zip
+               mirror://sourceforge/${PN}/${SONGS_PN}-restricted-3.zip
+               mirror://sourceforge/${PN}/${SONGS_PN}-shearer-1.zip
+       )"
+
+LICENSE="GPL-2
+       songs? (
+               CCPL-Attribution-ShareAlike-NonCommercial-2.5
+               CCPL-Attribution-NonCommercial-NoDerivs-2.5
+       )"
+SLOT="0"
+KEYWORDS="~x86 ~amd64 ~ppc ~ppc64"
+
+IUSE="debug alsa portaudio pulseaudio jack songs gstreamer tools editor"
+
+RDEPEND="gnome-base/librsvg
+       dev-libs/boost
+       x11-libs/pango
+       dev-cpp/libxmlpp
+       media-libs/glew
+       media-libs/libsdl[joystick,opengl]
+       media-libs/libpng
+       media-libs/jpeg
+       tools? ( media-gfx/imagemagick[png] )
+       editor? ( media-gfx/imagemagick[png] )
+       >=media-video/ffmpeg-0.4.9_p20070616-r20
+       alsa? ( media-libs/alsa-lib )
+       jack? ( media-sound/jack-audio-connection-kit )
+       portaudio? ( media-libs/portaudio )
+       gstreamer? ( media-libs/gstreamer )
+       pulseaudio? ( media-sound/pulseaudio )
+       sys-apps/help2man
+       !games-arcade/ultrastar-ng"
+DEPEND="${RDEPEND}
+    >=dev-util/cmake-2.6.0"
+
+S="${WORKDIR}/${MY_P}"
+
+src_unpack() {
+       unpack "${MY_P}.tar.bz2"
+       if use songs; then
+               cd "${S}"
+               unpack "${SONGS_PN}-jc-1.zip"
+               unpack "${SONGS_PN}-libre-3.zip"
+               unpack "${SONGS_PN}-restricted-3.zip"
+               unpack "${SONGS_PN}-shearer-1.zip"
+       fi
+}
+
+src_configure() {
+       local mycmakeargs="
+               $(cmake-utils_use alsa LIBDA_PLUGIN_ALSA)
+               $(cmake-utils_use jack LIBDA_PLUGIN_JACK)
+               $(cmake-utils_use gstreamer LIBDA_PLUGIN_GSTREAMER)
+               $(cmake-utils_use portaudio LIBDA_PLUGIN_PORTAUDIO)
+               $(cmake-utils_use pulseaudio LIBDA_PLUGIN_PULSEAUDIO)
+               $(cmake-utils_use_enable tools TOOLS)
+               $(cmake-utils_use_enable editor EDITOR)
+               -DCMAKE_INSTALL_PREFIX=${GAMES_PREFIX}
+               -DSHARE_INSTALL=share/performous
+               -DLIBDA_AUTODETECT_PLUGINS=false
+               -DLIBDA_PLUGIN_TESTING=false
+               -DCMAKE_BUILD_TYPE=Release"
+
+       cmake-utils_src_configure
+}
+
+src_compile() {
+       cmake-utils_src_compile
+}
+
+src_install() {
+       DOCS="docs/*.txt" cmake-utils_src_install
+
+       if use songs; then
+               insinto "/usr/share/games/ultrastar"
+               doins -r "${S}/songs" || die "doins songs failed"
+       fi
+       doicon "${S}/data/${PN}.xpm"
+       domenu "${S}/data/${PN}.desktop"
+       prepgamesdirs
+}
diff --git a/portage-overlay/games-arcade/performous/performous-0.6.0.ebuild b/portage-overlay/games-arcade/performous/performous-0.6.0.ebuild
new file mode 100644 (file)
index 0000000..7eb426c
--- /dev/null
@@ -0,0 +1,111 @@
+# Copyright 1999-2006 Gentoo Foundation
+# Distributed under the terms of the GNU General Public License v2
+# $Header: /cvsroot/ultrastar-ng/UltraStar-ng/portage-overlay/games-arcade/performous/performous-9999.ebuild,v 1.10 2007/09/29 13:04:19 yoda-jm Exp $
+
+[[ ${PV} = 9999 ]] && GIT="git"
+EAPI=2
+
+inherit cmake-utils ${GIT} games
+
+SONGS_PN=ultrastar-songs
+
+DESCRIPTION="Party game similar to Singstar, RockBand, Guitar Hero and Stepmania"
+HOMEPAGE="http://performous.org"
+SRC_URI="songs? ( 
+       mirror://sourceforge/${PN}/${SONGS_PN}-jc-1.zip
+       mirror://sourceforge/${PN}/${SONGS_PN}-libre-3.zip
+       mirror://sourceforge/${PN}/${SONGS_PN}-restricted-3.zip
+       mirror://sourceforge/${PN}/${SONGS_PN}-shearer-1.zip
+       )"
+
+if [ "$PV" != "9999" ]; then
+       MY_PN=Performous
+       MY_P=${MY_PN}-${PV}-Source
+       SRC_URI=" mirror://sourceforge/${PN}/${MY_P}.tar.bz2
+               $SRC_URI"
+else
+       EGIT_REPO_URI="git://performous.git.sourceforge.net/gitroot/performous/performous"
+       EGIT_BRANCH="master"
+fi
+
+LICENSE="GPL-2
+       songs? (
+               CCPL-Attribution-ShareAlike-NonCommercial-2.5
+               CCPL-Attribution-NonCommercial-NoDerivs-2.5
+       )"
+SLOT="0"
+KEYWORDS="~amd64 ~x86"
+
+IUSE="debug midi songs tools webcam"
+
+RDEPEND="gnome-base/librsvg
+       >=dev-libs/boost-1.39.0
+       x11-libs/pango
+       dev-cpp/libxmlpp
+       media-libs/glew
+       media-libs/libsdl[joystick,opengl]
+       media-libs/libpng
+       media-libs/jpeg
+       tools? ( media-gfx/imagemagick[png] )
+       webcam? ( media-libs/opencv[v4l] )
+       >=media-video/ffmpeg-0.4.9_p20070616-r20
+       media-libs/portaudio
+       sys-apps/help2man
+       !games-arcade/ultrastar-ng"
+# Waiting for portmidi to enter portage (#90614)
+#RDEPEND="${RDEPEND}
+#      midi? ( media-libs/portmidi )"
+DEPEND="${RDEPEND}
+    >=dev-util/cmake-2.6.0"
+
+S=${WORKDIR}/${MY_P}
+
+src_unpack() {
+       if [ "${PV}" != "9999" ]; then
+               unpack "${MY_P}.tar.bz2"
+       else
+               git_src_unpack
+       fi
+       cd "${S}"
+       if use songs; then
+               unpack "${SONGS_PN}-jc-1.zip" "${SONGS_PN}-libre-3.zip" "${SONGS_PN}-restricted-3.zip" "${SONGS_PN}-shearer-1.zip"
+       fi
+}
+
+src_prepare() {
+       epatch "${FILESDIR}"/${PN}-gentoopaths.patch
+}
+
+src_configure() {
+       local mycmakeargs="
+               $(cmake-utils_use_enable tools TOOLS)
+               $(cmake-utils_use_no webcam WEBCAM)
+               -DCMAKE_INSTALL_PREFIX=${GAMES_PREFIX}
+               -DGENTOO_DATA_DIR=${GAMES_DATADIR}/${PN}
+               -DLOCALE_DIR=/usr/share
+               -DCMAKE_BUILD_TYPE=Release"
+#      local mycmakeargs="
+#              $(cmake-utils_use_no midi MIDI)
+#              ${mycmakeargs}"
+
+       cmake-utils_src_configure
+}
+
+src_compile() {
+       cmake-utils_src_compile
+}
+
+src_install() {
+       DOCS="docs/*.txt" cmake-utils_src_install
+       mv -f "${D}/${GAMES_PREFIX}/share/man" "${D}/usr/share/"
+       mkdir -p "${D}/${GAMES_DATADIR}/${PN}"
+       mv -f "${D}/${GAMES_PREFIX}/share/games/performous" "${D}/${GAMES_DATADIR}/"
+
+       if use songs; then
+               insinto "${GAMES_DATADIR}/${PN}"
+               doins -r "${S}/songs" || die "doins songs failed"
+       fi
+       doicon "${S}/data/${PN}.xpm"
+       domenu "${S}/data/${PN}.desktop"
+       prepgamesdirs
+}
diff --git a/portage-overlay/games-arcade/performous/performous-0.7.0.ebuild b/portage-overlay/games-arcade/performous/performous-0.7.0.ebuild
new file mode 100644 (file)
index 0000000..ff27dfa
--- /dev/null
@@ -0,0 +1,107 @@
+# Copyright 1999-2012 Gentoo Foundation
+# Distributed under the terms of the GNU General Public License v2
+# $Header: $
+
+EAPI=4
+
+[[ ${PV} = 9999 ]] && GIT="git-2"
+
+inherit cmake-utils ${GIT} games
+
+SONGS_PN=ultrastar-songs
+
+DESCRIPTION="Party game similar to Singstar, RockBand, Guitar Hero and Stepmania"
+HOMEPAGE="http://performous.org"
+SRC_URI="songs? ( 
+       mirror://sourceforge/${PN}/${SONGS_PN}-jc-1.zip
+       mirror://sourceforge/${PN}/${SONGS_PN}-libre-3.zip
+       mirror://sourceforge/${PN}/${SONGS_PN}-restricted-3.zip
+       mirror://sourceforge/${PN}/${SONGS_PN}-shearer-1.zip
+       )"
+
+if [ "$PV" != "9999" ]; then
+       SRC_URI=" mirror://sourceforge/${PN}/${P}.tar.bz2
+               $SRC_URI"
+else
+       EGIT_REPO_URI="git://performous.git.sourceforge.net/gitroot/performous/performous"
+       # git-2 default branch is master
+       #EGIT_BRANCH="master"
+       # use performous_LIVE_BRANCH env var to install another branch (for example
+       # legacy or torrent)
+fi
+
+LICENSE="GPL-2
+       songs? (
+               CCPL-Attribution-ShareAlike-NonCommercial-2.5
+               CCPL-Attribution-NonCommercial-NoDerivs-2.5
+       )"
+SLOT="0"
+KEYWORDS="~amd64 ~x86"
+
+IUSE="debug midi songs tools webcam"
+
+RDEPEND="gnome-base/librsvg
+       >=dev-libs/boost-1.39.0
+       x11-libs/pango
+       dev-cpp/libxmlpp
+       media-libs/glew
+       media-libs/libsdl[joystick,opengl]
+       media-libs/libpng
+       virtual/jpeg
+       tools? ( media-gfx/imagemagick[png] )
+       midi? ( media-libs/portmidi )
+       webcam? ( media-libs/opencv[v4l] )
+       >=media-video/ffmpeg-0.4.9_p20070616-r20
+       media-libs/portaudio
+       sys-apps/help2man
+       !games-arcade/ultrastar-ng"
+DEPEND="${RDEPEND}
+    >=dev-util/cmake-2.6.0"
+
+src_unpack() {
+       if [ "${PV}" != "9999" ]; then
+               unpack "${P}.tar.bz2"
+       else
+               git-2_src_unpack
+       fi
+       cd "${S}"
+       if use songs; then
+               unpack "${SONGS_PN}-jc-1.zip" "${SONGS_PN}-libre-3.zip" "${SONGS_PN}-restricted-3.zip" "${SONGS_PN}-shearer-1.zip"
+       fi
+}
+
+src_prepare() {
+       epatch "${FILESDIR}"/${PN}-gentoopaths.patch
+}
+
+src_configure() {
+       local mycmakeargs="
+               $(cmake-utils_use_enable tools TOOLS)
+               $(cmake-utils_use_no webcam WEBCAM)
+               $(cmake-utils_use_no midi PORTMIDI)
+               -DCMAKE_INSTALL_PREFIX=${GAMES_PREFIX}
+               -DGENTOO_DATA_DIR=${GAMES_DATADIR}/${PN}
+               -DLOCALE_DIR=/usr/share
+               -DCMAKE_BUILD_TYPE=Release"
+
+       cmake-utils_src_configure
+}
+
+src_compile() {
+       cmake-utils_src_compile
+}
+
+src_install() {
+       DOCS="docs/*.txt" cmake-utils_src_install
+       mv -f "${D}/${GAMES_PREFIX}/share/man" "${D}/usr/share/"
+       mkdir -p "${D}/${GAMES_DATADIR}/${PN}"
+       mv -f "${D}/${GAMES_PREFIX}/share/games/performous" "${D}/${GAMES_DATADIR}/"
+
+       if use songs; then
+               insinto "${GAMES_DATADIR}/${PN}"
+               doins -r "${S}/songs" || die "doins songs failed"
+       fi
+       doicon "${S}/data/${PN}.xpm"
+       domenu "${S}/data/${PN}.desktop"
+       prepgamesdirs
+}
diff --git a/portage-overlay/games-arcade/performous/performous-9999.ebuild b/portage-overlay/games-arcade/performous/performous-9999.ebuild
new file mode 100644 (file)
index 0000000..1fccb15
--- /dev/null
@@ -0,0 +1,109 @@
+# Copyright 1999-2012 Gentoo Foundation
+# Distributed under the terms of the GNU General Public License v2
+# $Header: $
+
+EAPI=4
+
+[[ ${PV} = 9999 ]] && GIT="git-2"
+
+inherit cmake-utils ${GIT} games
+
+SONGS_PN=ultrastar-songs
+
+DESCRIPTION="Party game similar to Singstar, RockBand, Guitar Hero and Stepmania"
+HOMEPAGE="http://performous.org"
+SRC_URI="songs? ( 
+       mirror://sourceforge/${PN}/${SONGS_PN}-jc-1.zip
+       mirror://sourceforge/${PN}/${SONGS_PN}-libre-3.zip
+       mirror://sourceforge/${PN}/${SONGS_PN}-restricted-3.zip
+       mirror://sourceforge/${PN}/${SONGS_PN}-shearer-1.zip
+       )"
+
+if [ "$PV" != "9999" ]; then
+       SRC_URI=" mirror://sourceforge/${PN}/${P}.tar.bz2
+               $SRC_URI"
+else
+       EGIT_REPO_URI="git://performous.git.sourceforge.net/gitroot/performous/performous"
+       # git-2 default branch is master
+       #EGIT_BRANCH="master"
+       # use performous_LIVE_BRANCH env var to install another branch (for example
+       # legacy or torrent)
+fi
+
+LICENSE="GPL-2
+       songs? (
+               CCPL-Attribution-ShareAlike-NonCommercial-2.5
+               CCPL-Attribution-NonCommercial-NoDerivs-2.5
+       )"
+SLOT="0"
+KEYWORDS="~amd64 ~x86"
+
+IUSE="debug bittorrent midi songs tools webcam"
+
+RDEPEND="gnome-base/librsvg
+       >=dev-libs/boost-1.39.0
+       x11-libs/pango
+       dev-cpp/libxmlpp
+       media-libs/glew
+       media-libs/libsdl[joystick,opengl]
+       media-libs/libpng
+       virtual/jpeg
+       tools? ( media-gfx/imagemagick[png] )
+       midi? ( media-libs/portmidi )
+       webcam? ( media-libs/opencv[v4l] )
+       bittorrent? ( >=net-libs/rb_libtorrent-0.16.3 )
+       >=media-video/ffmpeg-0.4.9_p20070616-r20
+       media-libs/portaudio
+       sys-apps/help2man
+       !games-arcade/ultrastar-ng"
+DEPEND="${RDEPEND}
+    >=dev-util/cmake-2.6.0"
+
+src_unpack() {
+       if [ "${PV}" != "9999" ]; then
+               unpack "${P}.tar.bz2"
+       else
+               git-2_src_unpack
+       fi
+       cd "${S}"
+       if use songs; then
+               unpack "${SONGS_PN}-jc-1.zip" "${SONGS_PN}-libre-3.zip" "${SONGS_PN}-restricted-3.zip" "${SONGS_PN}-shearer-1.zip"
+       fi
+}
+
+src_prepare() {
+       epatch "${FILESDIR}"/${PN}-gentoopaths.patch
+}
+
+src_configure() {
+       local mycmakeargs="
+               $(cmake-utils_use_enable tools TOOLS)
+               $(cmake-utils_use_no webcam WEBCAM)
+               $(cmake-utils_use_no bittorrent TORRENT)
+               $(cmake-utils_use_no midi PORTMIDI)
+               -DCMAKE_INSTALL_PREFIX=${GAMES_PREFIX}
+               -DGENTOO_DATA_DIR=${GAMES_DATADIR}/${PN}
+               -DLOCALE_DIR=/usr/share
+               -DCMAKE_BUILD_TYPE=Release"
+
+       cmake-utils_src_configure
+}
+
+src_compile() {
+       cmake-utils_src_compile
+}
+
+src_install() {
+       DOCS="docs/*.txt" cmake-utils_src_install
+       mv -f "${D}/${GAMES_PREFIX}/share/man" "${D}/usr/share/"
+       mkdir -p "${D}/${GAMES_DATADIR}/${PN}"
+       mv -f "${D}/${GAMES_PREFIX}/share/games/performous" "${D}/${GAMES_DATADIR}/"
+
+       if use songs; then
+               insinto "${GAMES_DATADIR}/${PN}"
+               doins -r "${S}/songs" || die "doins songs failed"
+       fi
+       doicon "${S}/data/${PN}.xpm"
+       domenu "${S}/data/${PN}.desktop"
+       prepgamesdirs
+}
diff --git a/portage-overlay/games-util/eof/eof-1.65.ebuild b/portage-overlay/games-util/eof/eof-1.65.ebuild
new file mode 100644 (file)
index 0000000..387898b
--- /dev/null
@@ -0,0 +1,45 @@
+# Copyright 1999-2010 Gentoo Foundation
+# Distributed under the terms of the GNU General Public License v2
+# $Header: $
+
+EAPI=3
+
+inherit games
+
+DESCRIPTION="Song editor for the game Frets On Fire"
+HOMEPAGE="http://www.t3-i.com/eof.htm"
+SRC_URI="http://www.t3-i.com/apps/${PN}/downloads/${PN}-${PV}-linux.tar.gz"
+
+LICENSE=""
+SLOT="0"
+KEYWORDS="~amd64"
+IUSE=""
+
+DEPEND="
+       media-libs/allegro
+       media-sound/vorbis-tools
+       media-sound/lame
+"
+RDEPEND="${DEPEND}"
+
+src_compile() {
+       cd "${WORKDIR}/src/"
+       emake -f makefile.linux || die "emake failed"
+}
+
+src_install() {
+       cd "${WORKDIR}"
+       cat >> bin/eof.script <<-EOF
+               #!/bin/bash
+               TMP_DIR=\`mktemp -d || echo "/tmp/falback"\`
+               echo ">> Using \\"\${TMP_DIR}\\" as temporary location"
+               cp /usr/share/eof/* "\${TMP_DIR}"
+               cd "\${TMP_DIR}"
+               eof.bin
+               rm -rf "\${TMP_DIR}"
+       EOF
+       newbin bin/eof eof.bin
+       newbin bin/eof.script eof
+       insinto "/usr/share/${PN}"
+       doins bin/eof.dat bin/check.wav
+}
diff --git a/portage-overlay/games-util/eof/eof-9999.ebuild b/portage-overlay/games-util/eof/eof-9999.ebuild
new file mode 100644 (file)
index 0000000..2f62604
--- /dev/null
@@ -0,0 +1,44 @@
+# Copyright 1999-2010 Gentoo Foundation
+# Distributed under the terms of the GNU General Public License v2
+# $Header: $
+
+EAPI=3
+
+inherit games subversion
+
+DESCRIPTION="Song editor for the game Frets On Fire"
+HOMEPAGE="http://code.google.com/p/editor-on-fire/"
+ESVN_REPO_URI="http://editor-on-fire.googlecode.com/svn/trunk/"
+
+LICENSE=""
+SLOT="0"
+KEYWORDS="~amd64 ~x86"
+IUSE=""
+
+DEPEND="
+       media-libs/allegro
+       media-sound/vorbis-tools
+       media-sound/lame"
+RDEPEND="${DEPEND}"
+
+src_compile() {
+       cd ${S}/src/
+       emake -f makefile.linux || die "emake failed"
+}
+
+src_install() {
+       cd ${S}
+       cat >> bin/eof.script <<-EOF
+               #!/bin/bash
+               TMP_DIR=\`mktemp -d || echo "/tmp/falback"\`
+               echo ">> Using \\"\${TMP_DIR}\\" as temporary location"
+               cp /usr/share/eof/* "\${TMP_DIR}"
+               cd "\${TMP_DIR}"
+               eof.bin
+               rm -rf "\${TMP_DIR}"
+       EOF
+       newbin bin/eof eof.bin
+       newbin bin/eof.script eof
+       insinto "/usr/share/${PN}"
+       doins bin/eof.dat bin/check.wav
+}
diff --git a/portage-overlay/games-util/foflc/foflc-9999.ebuild b/portage-overlay/games-util/foflc/foflc-9999.ebuild
new file mode 100644 (file)
index 0000000..5e95a85
--- /dev/null
@@ -0,0 +1,33 @@
+# Copyright 1999-2010 Gentoo Foundation
+# Distributed under the terms of the GNU General Public License v2
+# $Header: $
+
+EAPI=3
+
+inherit cmake-utils games subversion
+
+DESCRIPTION="Frets On Fire Lyrics Converter"
+HOMEPAGE="http://www.fretsonfire.net/forums/viewtopic.php?t=31765&f=11"
+ESVN_REPO_URI="http://editor-on-fire.googlecode.com/svn/trunk/src/foflc"
+
+LICENSE="ASIS"
+SLOT="0"
+KEYWORDS="~amd64 ~x86"
+IUSE=""
+
+DEPEND=""
+RDEPEND="${DEPEND}"
+
+src_configure() {
+       mycmakeargs="-DCMAKE_INSTALL_PREFIX=${GAMES_PREFIX}"
+       cmake-utils_src_configure
+}
+
+src_compile() {
+       cmake-utils_src_compile
+}
+
+src_install() {
+       DOCS="*.txt" cmake-utils_src_install
+       prepgamesdirs
+}
diff --git a/tools/CMakeLists.txt b/tools/CMakeLists.txt
new file mode 100644 (file)
index 0000000..50bdd6f
--- /dev/null
@@ -0,0 +1,104 @@
+cmake_minimum_required(VERSION 2.6)
+
+# Libraries
+
+find_package(Boost 1.34 REQUIRED COMPONENTS filesystem program_options system)
+include_directories(${Boost_INCLUDE_DIRS})
+
+# Find all the libs that don't require extra parameters
+
+if (APPLE)
+    foreach(lib LibXML++ Z Jpeg Tiff Png Freetype Z)
+       find_package(${lib})
+       if (${lib}_FOUND)
+               include_directories(${${lib}_INCLUDE_DIRS})
+                   add_definitions(${${lib}_DEFINITIONS})
+       endif (${lib}_FOUND)
+    endforeach(lib)
+
+    # CMake cannot properly detect Magick++ on Mac the other way.
+
+    find_package(ImageMagick COMPONENTS Magick++)
+    include_directories(${ImageMagick_INCLUDE_DIRS})
+else (APPLE)
+    foreach(lib LibXML++ Z Magick++ Jpeg Tiff Png Freetype Z)
+           find_package(${lib})
+       if (${lib}_FOUND)
+               include_directories(${${lib}_INCLUDE_DIRS})
+                   add_definitions(${${lib}_DEFINITIONS})
+       endif (${lib}_FOUND)
+    endforeach(lib)
+endif (APPLE)
+
+# Set default compile flags for GCC
+if(CMAKE_COMPILER_IS_GNUCXX)
+       message(STATUS "GCC detected, enabling warnings")
+       # Magick++ on OSX uses long long and thus cannot take -pedantic
+       set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++98 -Wall -Wextra")
+endif(CMAKE_COMPILER_IS_GNUCXX)
+
+if (LibXML++_FOUND)
+       if (Boost_FOUND)
+               if (ImageMagick_FOUND OR Magick++_FOUND) 
+                       if (Z_FOUND)
+                               add_executable(ss_extract ss_extract.cc pak.cc ipu_conv.cc ss_cover.cc)
+                               target_link_libraries(ss_extract ${LibXML++_LIBRARIES} ${Boost_LIBRARIES} ${Magick++_LIBRARIES} ${Z_LIBRARIES} ${Jpeg_LIBRARIES} ${Tiff_LIBRARIES} ${Png_LIBRARIES} ${Freetype_LIBRARY} ${ImageMagick_LIBRARIES})
+                               set(targets ${targets} ss_extract)
+                       else (Z_FOUND)
+                               message("No zlib found, not building ss_extract")
+                       endif (Z_FOUND)
+               else (ImageMagick_FOUND OR Magick++_FOUND)
+                       message("No Magick++ found, not building ss_extract")
+               endif (ImageMagick_FOUND OR Magick++_FOUND)
+       else (Boost_FOUND)
+               message("No Boost.Filesystem found, not building ss_extract")
+       endif (Boost_FOUND)
+
+       if (ImageMagick_FOUND OR Magick++_FOUND)
+               add_executable(ss_cover_conv cover_conv.cc pak.cc ss_cover.cc)
+               target_link_libraries(ss_cover_conv ${ImageMagick_LIBRARIES} ${LibXML++_LIBRARIES} ${Z_LIBRARIES} ${Jpeg_LIBRARIES} ${Tiff_LIBRARIES} ${Png_LIBRARIES} ${Freetype_LIBRARY} ${ImageMagick_LIBRARIES} ${Magick++_LIBRARIES})
+               set(targets ${targets} ss_cover_conv)
+       else (ImageMagick_FOUND OR Magick++_FOUND)
+               message("No Magick++ found, not building ss_cover_conv")
+       endif (ImageMagick_FOUND OR Magick++_FOUND)
+else (LibXML++_FOUND)
+       message("No LibXML++ found, not building ss_extract nor ss_cover_conv")
+endif (LibXML++_FOUND)
+
+if (Boost_FOUND AND Z_FOUND)
+       add_executable(ss_archive_extract archive_extract.cc)
+       target_link_libraries(ss_archive_extract ${Boost_LIBRARIES} ${Z_LIBRARIES})
+       set(targets ${targets} ss_archive_extract)
+
+       add_executable(ss_pak_extract pak_extract.cc pak.cc)
+       target_link_libraries(ss_pak_extract ${Boost_LIBRARIES} ${Z_LIBRARIES})
+       set(targets ${targets} ss_pak_extract)
+
+       add_executable(itg_pck itg_pck.cc)
+       target_link_libraries(itg_pck ${Boost_LIBRARIES} ${Z_LIBRARIES})
+       set(targets ${targets} itg_pck)
+
+       add_executable(ss_chc_decode ss_chc_decode.cc)
+       target_link_libraries(ss_chc_decode ${Boost_LIBRARIES} ${Z_LIBRARIES})
+       set(targets ${targets} ss_chc_decode)
+
+endif()
+
+if (Z_FOUND)
+       add_executable(ss_adpcm_decode adpcm_decode.cc pak.cc)
+       target_link_libraries(ss_adpcm_decode ${Z_LIBRARIES})
+       set(targets ${targets} ss_adpcm_decode)
+endif()
+
+add_executable(gh_fsb_decrypt gh_fsb/fsbext.c)
+add_executable(gh_xen_decrypt gh_xen_decrypt.cc)
+add_executable(ss_ipu_conv ipu_conv.cc ipuconvmain.cc pak.cc)
+set(targets ${targets} gh_fsb_decrypt gh_xen_decrypt ss_adpcm_decode ss_ipu_conv)
+
+# add install target:
+if(WIN32)
+       install(TARGETS ${targets} DESTINATION tools)
+else()
+       install(TARGETS ${targets} DESTINATION bin)
+endif()
+
diff --git a/tools/adpcm.h b/tools/adpcm.h
new file mode 100644 (file)
index 0000000..6cda020
--- /dev/null
@@ -0,0 +1,83 @@
+#ifndef USNG_ADPCM_H
+#define USNG_ADPCM_H
+
+#include <iostream>
+#include <stdexcept>
+#include <vector>
+
+class Adpcm {
+  public:
+       /** Initialize the decoder.
+       * Typical values for interleave are 0xB800 and 0xBB80. This information can
+       * be extracted from music.mih
+       **/
+       Adpcm(unsigned int interleave_, unsigned int channels_ = 2): m_interleave(interleave_), headers(channels_) {}
+
+       /** Decode 16 bytes of each channel, outputting 28 samples/ch. **/
+       template <typename OutIt> OutIt decodeBlock(char const* data, OutIt pcm) {
+               // Read headers
+               for (unsigned ch = 0; ch < headers.size(); ++ch) headers[ch].parse(data + ch * m_interleave);
+               for (unsigned n = 0; n < 28; ++n) {
+                       for (unsigned ch = 0; ch < headers.size(); ++ch) {
+                               Header& h = headers[ch];
+                               // Get a nibble and left-align it
+                               short sample = (data[2 + n / 2 + ch * m_interleave] << (n % 2 ? 8 : 12)) & 0xF000;
+                               int i_sample = sample;
+                               // Apply ADPCM exponent
+                               i_sample >>= h.shift;
+                               // Apply prediction
+                               i_sample += (h.pr1 * h.prev1 + h.pr2 * h.prev2 + 32) >> 6;
+                               if( i_sample > 32767 ) {
+                                       sample = 32767;
+                               } else if( i_sample < -32768 ) {
+                                       sample = -32768;
+                               } else {
+                                       sample = i_sample;
+                               }
+                               // Store history for prediction
+                               h.prev2 = h.prev1;
+                               h.prev1 = sample;
+                               // Output sample
+                               *pcm++ = sample;
+                       }
+               }
+               return pcm;
+       }
+
+       unsigned int chunkFrames() const { return m_interleave / 16 * 28; }
+       unsigned int chunkBytes() const { return m_interleave * 2; }
+       void interleave(unsigned int _interleave) {m_interleave = _interleave; }
+
+       /** Decode chunkBytes() bytes, outputting chunkFrames() samples/ch. **/
+       template <typename OutIt> OutIt decodeChunk(char const* data, OutIt pcm) {
+               for (unsigned pos = 0; pos < m_interleave; pos += 16) pcm = decodeBlock(data + pos, pcm);
+               return pcm;
+       }
+  private:
+       unsigned int m_interleave;
+       struct Header {
+               Header(): prev1(), prev2() {}
+               int shift;
+               int pr1;
+               int pr2;
+               char loopend;
+               char loop;
+               char loopstart;
+               short prev1;
+               short prev2;
+               void parse(char const* data) {
+                       static const int f[5][2] = { { 0, 0 }, { 60, 0 }, { 115, -52 }, { 98, -55 }, { 122, -60 } };
+                       shift = data[0] & 0xF;
+                       unsigned mode = (data[0] >> 4) & 0xF;
+                       if (mode >= 5) throw std::runtime_error("Invalid mode");
+                       pr1 = f[mode][0];
+                       pr2 = f[mode][1];
+                       loopend = data[1] & 1;
+                       loop = (data[1] >> 1) & 1;
+                       loopstart = (data[1] >> 2) & 1;
+               }
+       };
+       std::vector<Header> headers;
+};
+
+#endif
diff --git a/tools/adpcm_decode.cc b/tools/adpcm_decode.cc
new file mode 100644 (file)
index 0000000..39cb3e4
--- /dev/null
@@ -0,0 +1,72 @@
+#include "adpcm.h"
+#include "pak.h"
+#include <cstdlib>
+#include <fstream>
+#include <iostream>
+#include <vector>
+
+unsigned short decode_channels = 2;
+
+void process(Adpcm& adpcm, std::vector<char> const& data, std::ostream& outfile) {
+       std::vector<short> pcm(adpcm.chunkFrames() * decode_channels);
+       adpcm.decodeChunk(&data[0], &pcm[0]);
+       outfile.write(reinterpret_cast<char*>(&pcm[0]), pcm.size() * sizeof(short));
+}
+
+void writeWavHeader(std::ostream& outfile, unsigned ch, unsigned sr, unsigned samples) {
+       unsigned bps = ch * 2; // Bytes per sample
+       unsigned datasize = bps * samples;
+       unsigned size = datasize + 0x2C;
+       outfile.write("RIFF" ,4); // RIFF chunk
+       { unsigned int tmp=size-0x8 ; outfile.write((char*)(&tmp),4); } // RIFF chunk size
+       outfile.write("WAVEfmt ",8); // WAVEfmt header
+       { int   tmp=0x00000010 ; outfile.write((char*)(&tmp),4); } // Always 0x10
+       { short tmp=0x0001     ; outfile.write((char*)(&tmp),2); } // Always 1
+       { short tmp = ch; outfile.write((char*)(&tmp),2); } // Number of channels
+       { int   tmp = sr; outfile.write((char*)(&tmp),4); } // Sample rate
+       { int   tmp = bps * sr; outfile.write((char*)(&tmp),4); } // Bytes per second
+       { short tmp = bps; outfile.write((char*)(&tmp),2); } // Bytes per frame
+       { short tmp = 16; outfile.write((char*)(&tmp),2); } // Bits per sample
+       outfile.write("data",4); // data chunk
+       { int   tmp = datasize; outfile.write((char*)(&tmp),4); }
+}
+
+int main(int argc, char** argv) {
+       std::string in, out, pak;
+
+       if( argc == 3 ) {
+               in = argv[1];
+               out = argv[2];
+       } else if( argc == 4 ) {
+               pak = argv[1];
+               in = argv[2];
+               out = argv[3];
+       } else {
+               std::cout << "Usage: " << argv[0] << " [archive.pak] input.mib output.wav" << std::endl;
+               return EXIT_FAILURE;
+       }
+       // FIXME: read from music.mih
+       const unsigned sr = 48000;
+       const unsigned interleave = 0xB800;
+       Adpcm adpcm(interleave, decode_channels);
+       std::ofstream outf;
+       if (out != "-") outf.open(out.c_str(), std::ios::binary);
+       std::ostream& outfile = (out != "-" ? outf : std::cout);
+       std::vector<char> data(adpcm.chunkBytes());
+       if (pak.empty()) {
+               std::ifstream infile(in.c_str(), std::ios::binary);
+               writeWavHeader(outfile, 2, sr, sr * 1000 /* FIXME: calculate real length */);
+               while (infile.read(&data[0], adpcm.chunkBytes()) && infile.seekg(adpcm.chunkBytes(), std::ios::cur)) {
+                       process(adpcm, data, outfile);
+               }
+       } else {
+               Pak p(pak);
+               PakFile const& infile(p[in]);
+               writeWavHeader(outfile, 2, sr, infile.size / (adpcm.chunkBytes() * 2) * adpcm.chunkFrames());
+               for (unsigned pos = 0, end; (end = pos + 2 * adpcm.chunkBytes()) <= infile.size; pos = end) {
+                       infile.get(data, pos, end - pos);
+                       process(adpcm, data, outfile);
+               }
+       }
+}
+
diff --git a/tools/adpcm_play.cc b/tools/adpcm_play.cc
new file mode 100644 (file)
index 0000000..e2a89c6
--- /dev/null
@@ -0,0 +1,50 @@
+#include "adpcm.h"
+#include <portaudio.h>
+
+static int c_callback(void*, void* output, unsigned long framesPerBuffer, PaTimestamp, void* userdata) {
+       AudioFifo* audioQueue = static_cast<AudioFifo*>(userdata);
+       unsigned long size = 0;
+       unsigned char channels = 2;
+       std::vector<int16_t> buf;
+       while(size < framesPerBuffer*channels) {
+               size+=audioQueue->tryPop(buf, framesPerBuffer*channels-size);
+       }
+       int16_t* my_out = (int16_t*)output;
+       for( unsigned int i = 0 ; i < size ; i++ ) {
+               my_out[i] = buf[i];
+       }
+       return 0;
+}
+
+int main( int argc, char** argv) {
+       std::ifstream m_f1;
+       std::string in, out, fat;
+
+       if( argc == 2 ) {
+               fat = "none";
+               in = argv[1];
+       } else if( argc == 3 ) {
+               fat = argv[1];
+               in = argv[2];
+       } else {
+               std::cout << "Usage: " << argv[0] << " [fat_file] input_file" << std::endl;
+               return EXIT_FAILURE;
+       }
+
+       Adpcm file(in,fat);
+       PaError pa_err=Pa_Initialize();
+       PaStream *stream;
+       pa_err = Pa_OpenStream(&stream, paNoDevice, 0, paInt16, NULL, \
+                       Pa_GetDefaultOutputDeviceID(), \
+                       2, paInt16, NULL, 48000, 1234, 0, 0, \
+                       c_callback, &file.audioQueue);
+       pa_err=Pa_StartStream(stream);
+       while( !file.finished() || file.audioQueue.size() > 0) {
+               sleep(1);
+
+       }
+       pa_err=Pa_CloseStream(stream);
+       pa_err=Pa_Terminate();
+
+       return EXIT_SUCCESS;
+}
diff --git a/tools/archive_extract.cc b/tools/archive_extract.cc
new file mode 100644 (file)
index 0000000..1d6e412
--- /dev/null
@@ -0,0 +1,123 @@
+// @file Tool for extracting 'Disney Sing It' archive/archive.log files
+
+#include <boost/filesystem.hpp>
+#include <algorithm>
+#include <cstring>
+#include <fstream>
+#include <functional>
+#include <iomanip>
+#include <iostream>
+#include <iterator>
+#include <map>
+#include <sstream>
+#include <stdexcept>
+
+namespace {
+       void usage(char const* progname) {
+               std::cerr << "Usage: " << progname << " archive --extract [files]" << std::endl;
+               std::cerr << "       " << progname << " archive --dump file" << std::endl;
+               std::cerr << "       " << progname << " archive --list" << std::endl;
+       }
+
+       struct File {
+               size_t offset;
+               size_t size;
+       };
+
+       typedef std::map<std::string, File> Files;
+
+       Files readFiles(std::string archive) {
+               Files files;
+               archive += ".log";
+               std::ifstream archlog(archive.c_str(), std::ios::binary);
+               File f = { 4, 0 };
+               for (std::string name; archlog >> name >> f.size; f.offset += f.size) files[name] = f;
+               if (!archlog.eof()) throw std::runtime_error("Error reading " + archive);
+               return files;
+       }
+
+       void extract(std::ifstream& arch, Files::const_iterator it, std::ostream& output) {
+               File const& f = it->second;
+               std::vector<char> buf(f.size);
+               arch.seekg(f.offset);
+               arch.read(&buf[0], buf.size());
+               output.write(&buf[0], buf.size());
+       }
+
+       struct Extract {
+               Extract(std::ifstream& arch, Files const& files): m_arch(arch), m_files(files) {}
+               /// Extract one file
+               void operator()(std::string const& filename) {
+                       Files::const_iterator it = m_files.find(filename);
+                       if (it == m_files.end()) throw std::runtime_error("File not found in archive");
+                       operator()(it);
+               }
+               /// Extract all files
+               void operator()() {
+                       for (Files::const_iterator it = m_files.begin(); it != m_files.end(); ++it) operator()(it);
+               }
+               /// Extract one file by iterator
+               void operator()(Files::const_iterator it) {
+                       std::string filename = it->first;
+                       // Remove path elements from m_path until it matches the filename's beginning
+                       while (m_path != filename.substr(0, m_path.size())) {
+                               std::string::size_type pos = m_path.rfind('/');
+                               if (pos == std::string::npos) m_path.clear();
+                               else m_path.erase(pos);
+                       }
+                       // Try to create new folders as required
+                       for (std::string::size_type pos; (pos = filename.find('/', m_path.size() + 1)) != std::string::npos;) {
+                               m_path = filename.substr(0, pos);
+                               boost::filesystem::create_directory(m_path);
+                       }
+                       // Extract the file
+                       std::ofstream f(filename.c_str(), std::ios::binary);
+                       if (!f.is_open()) throw std::runtime_error("Unable to create file: " + filename);
+                       std::cout << filename << std::flush;
+                       extract(m_arch, it, f);
+                       std::cout << std::endl;
+               }
+         private:
+               std::ifstream& m_arch;
+               Files const& m_files;
+               std::string m_path;
+       };
+
+       std::ostream& operator<<(std::ostream& os, Files const& files) {
+               std::stringstream ss;
+               ss << std::setbase(16) << std::setfill('0');
+               for (Files::const_iterator it = files.begin(); it != files.end(); ++it) {
+                       File const& f = it->second;
+                       ss << "0x" << std::setw(8) << f.offset << ' ';
+                       ss << "0x" << std::setw(8) << f.size << ' ';
+                       ss << it->first << std::endl;
+               }
+               return os << ss.rdbuf() << std::flush;
+       }
+}
+
+int main(int argc, char** argv) {
+       std::ios::sync_with_stdio(false);
+       if( argc < 3 ) { usage(argv[0]); return EXIT_FAILURE; }
+       try {
+               std::ifstream arch(argv[1], std::ios::binary);
+               if (!arch) throw std::runtime_error("Unable to open " + std::string(argv[1]));
+               Files const files = readFiles(argv[1]);
+               if (files.empty()) throw std::runtime_error("No files found in archive");
+               if (!strcmp(argv[2],"--list")) std::cout << files;
+               else if (!strcmp(argv[2],"--dump")) {
+                       if (argc != 4) { usage(argv[0]); return EXIT_FAILURE; }
+                       Files::const_iterator it = files.find(argv[3]);
+                       if (it == files.end()) throw std::runtime_error("File not found in archive");
+                       extract(arch, it, std::cout);
+               } else if (!strcmp(argv[2],"--extract")) {
+                       Extract extractor(arch, files);
+                       if (argc == 3) extractor();
+                       else std::for_each(argv + 3, argv + argc, extractor);
+               } else { usage(argv[0]); return EXIT_FAILURE; }
+       } catch (std::exception& e) {
+               std::cerr << "Error: " << e.what() << std::endl;
+               return EXIT_FAILURE;
+       }
+}
+
diff --git a/tools/bitfiles.h b/tools/bitfiles.h
new file mode 100644 (file)
index 0000000..94dcec2
--- /dev/null
@@ -0,0 +1,183 @@
+#include <algorithm>
+#include <fstream>
+#include <vector>
+
+class outBitFile {
+  public:
+       outBitFile(const char* filename): outcnt(0), outfile(filename, std::ios::binary) {}
+       ~outBitFile() { putbuf(); }
+
+       void putbits(unsigned int data, unsigned int n) {
+               unsigned int mask = 1 << (n-1);
+               for( unsigned int i = 0 ; i < n; i++) {
+                       outbuf <<= 1;
+                       if (data & mask) outbuf |= 1;
+                       mask >>= 1;
+                       outcnt++;
+                       if (outcnt == 8) {
+                               outfile.put(outbuf);
+                               outcnt = 0;
+                       }
+               }
+       }
+
+       void putbuf() {
+               if (outcnt > 0) putbits(0, 8-outcnt);
+       }
+
+       void put_dcs_y(int len) {
+               switch (len) {
+                       case 0: putbits(4,3); break;
+                       case 1: putbits(0,2); break;
+                       case 2: putbits(1,2); break;
+                       case 3: putbits(5,3); break;
+                       case 4: putbits(6,3); break;
+                       case 5: putbits(14,4); break;
+                       case 6: putbits(30,5); break;
+                       case 7: putbits(62,6); break;
+                       case 8: putbits(126,7); break;
+                       case 9: putbits(254,8); break;
+                       case 10: putbits(510,9); break;
+                       case 11: putbits(511,9); break;
+               }
+       }
+
+       void put_dcs_c(int len) {
+               switch (len) {
+                       case 0: putbits(0,2); break;
+                       case 1: putbits(1,2); break;
+                       case 2: putbits(2,2); break;
+                       case 3: putbits(6,3); break;
+                       case 4: putbits(14,4); break;
+                       case 5: putbits(30,5); break;
+                       case 6: putbits(62,6); break;
+                       case 7: putbits(126,7); break;
+                       case 8: putbits(254,8); break;
+                       case 9: putbits(510,9); break;
+                       case 10: putbits(1022,10); break;
+                       case 11: putbits(1023,10); break;
+               }
+       }
+
+  private:
+       int outcnt;
+       std::ofstream outfile;
+       unsigned char outbuf;
+       std::vector<char> outdata;
+};
+
+#define BUFFER_SIZE 4096
+#define START_CODE 0x000001
+#define BYTE_ALIGN 0x80
+#define BYTE_START 0x80
+
+class inBitFile {
+  public:
+       inBitFile(std::vector<char> const& data): indata(data) {
+               wdMask = BYTE_START;
+               wdIndex = 0;
+       }
+
+       void setpos(long int byte, unsigned int bit) {
+               wdIndex = byte;
+               wdMask = BYTE_START;
+               get(bit);
+       }
+
+       void getpos( long int *byte, unsigned int *bit) {
+               unsigned wdMaskSave = wdMask;
+               unsigned count;
+               for(count = 0; wdMaskSave != 0x80; count++) wdMaskSave <<= 1;
+               *bit = count; // 0x80=0,0x40=1,0x20=2 usw
+               *byte = wdIndex;
+       }
+
+       int get(int num_bits) {
+               unsigned int buf;
+               if (!get_bits(&buf, num_bits)) return 0;
+               return buf;
+       }
+
+       int next_start_code() {
+               unsigned int buf;
+               /* locate next start code */
+               if (wdMask != BYTE_ALIGN) {
+                       /* not byte aligned */
+                       /* skip stuffed zero bits */
+                       wdMask = BYTE_ALIGN;
+                       wdIndex++;
+               }
+               if (!next_bits(&buf, 24)) return 0; /* end of bitstream */
+               while (buf != START_CODE) {
+                       if (!get_bits(&buf, 8)) return 0;/* zero byte */
+                       if (!next_bits(&buf, 24)) return 0;
+               }
+               return 1;
+       }
+
+       int get_dcs_y() {
+               int bits;
+               if(!(bits = get(2))) return 1; // 00
+               if(bits == 1)        return 2; // 01
+               bits <<= 1;
+               bits |= get(1);
+               if(bits == 4) return 0; // 100
+               if(bits == 5) return 3; // 101
+               if(bits == 6) return 4; // 110
+               if(!get(1)) return 5;
+               if(!get(1)) return 6;
+               if(!get(1)) return 7;
+               if(!get(1)) return 8;
+               if(!get(1)) return 9;
+               if(!get(1)) return 10;
+               return 11;
+       }
+
+       int get_dcs_c() {
+               int bits;
+               if(!(bits = get(2))) return 0; // 00
+               if(bits == 1) return 1; // 01
+               if(bits == 2) return 2; // 10
+               if(!get(1)) return 3;
+               if(!get(1)) return 4;
+               if(!get(1)) return 5;
+               if(!get(1)) return 6;
+               if(!get(1)) return 7;
+               if(!get(1)) return 8;
+               if(!get(1)) return 9;
+               if(!get(1)) return 10;
+               return 11;
+       }
+  private:
+       int get_bits(unsigned int *destBuf, unsigned int num_bits) {
+               *destBuf = 0;
+               for (unsigned int index = 0; index < num_bits; ++index) {
+                       if (wdIndex >= indata.size()) return 0;
+                       /* get next bit */
+                       *destBuf <<= 1;
+                       if (indata[wdIndex] & wdMask) *destBuf |= 1;
+                       /* update bit pointer */
+                       if (wdMask > 1) wdMask >>= 1;
+                       else {
+                               wdIndex++;
+                               wdMask = BYTE_START;
+                       }
+               }
+               return 1;
+       }
+       
+       int next_bits(unsigned int *destBuf, int num_bits) {
+               /* save current buffer state */
+               unsigned wdMaskSave = wdMask;
+               unsigned wdIndexSave = wdIndex;
+               int ret = get_bits(destBuf, num_bits);
+               /* restore previous buffer state */
+               wdMask = wdMaskSave;
+               wdIndex = wdIndexSave;
+               return ret;
+       }
+       
+       unsigned wdIndex;
+       unsigned wdMask;
+       std::vector<char> const& indata;
+};
diff --git a/tools/chc_decode.hh b/tools/chc_decode.hh
new file mode 100644 (file)
index 0000000..e3aef61
--- /dev/null
@@ -0,0 +1,73 @@
+#pragma once
+
+#include <boost/crc.hpp>
+#include <string>
+#include <stdexcept>
+#include <zlib.h>
+
+// Class freely inspired from ALLconv by Holger Kuhn (hawkear@gmx.de)
+// Thanks for its help
+
+class ChcDecode {
+  public:
+       ChcDecode() {
+               for( unsigned int i = 0 ; i < 4 ; i++ ) {
+                       key_crc[i] = 0;
+               }
+       }
+       // TODO: move buffer uncypher inside load instead of getMelody
+       void load(std::string key[4]) {
+               for( unsigned int i = 0 ; i < 4 ; i++ ) {
+                       boost::crc_32_type crc;
+                       crc.process_bytes(key[i].c_str(), key[i].size()+1);
+                       key_crc[i] = crc.checksum();
+               }
+       }
+       std::string getMelody(char *buffer, unsigned int buffer_size, unsigned int id) {
+               unsigned int *chc_buffer = (unsigned int*)buffer;
+
+               if( buffer_size%8 != 0 ) throw std::runtime_error("CHC file is not 8 bytes padded");
+
+               for(unsigned int i = 0 ; i < buffer_size/8 ; i++) {
+                       decrypt(&chc_buffer[i*2], key_crc);
+               }
+
+               unsigned int songs = chc_buffer[0];
+
+               if( songs > 100 ) throw std::runtime_error("CHC key probably wrong (too many songs)");
+
+               unsigned int start = 0;
+               uLongf packsize = 0;
+               uLong size = 0;
+               for( unsigned int i = 0 ; i < songs ; i++) {
+                       if( chc_buffer[1+i*4] == id ) {
+                               start = chc_buffer[2+i*4];
+                               packsize = chc_buffer[3+i*4];
+                               size = chc_buffer[4+i*4];
+                               break;
+                       }
+               }
+               if( packsize == 0 ) throw std::runtime_error("Melody not found in CHC file");
+
+               Bytef *dest = new Bytef[size];
+               uncompress(dest, &size, (Bytef*)buffer+start, packsize);
+               std::string result((char*)dest, (unsigned int)size);
+               delete[] dest;
+
+               return result;
+       }
+  private:
+       unsigned int key_crc[4];
+       void decrypt(unsigned int *v, unsigned int k[4]) {
+               unsigned int v0 = v[0], v1 = v[1], i;
+               unsigned int sum   = 0xC6EF3720;
+               unsigned int delta = 0x9e3779b9;
+
+               for(i = 0; i<32; i++) { // basic cycle start
+                       v1 -= (v0<<4) + (k[2] ^ v0) + (sum ^ (v0>>5)) + k[3];
+                       v0 -= (v1<<4) + (k[0] ^ v1) + (sum ^ (v1>>5)) + k[1];
+                       sum -= delta;
+               } // end cycle
+               v[0] = v0; v[1] = v1;
+       }
+};
diff --git a/tools/cover_conv.cc b/tools/cover_conv.cc
new file mode 100644 (file)
index 0000000..af70268
--- /dev/null
@@ -0,0 +1,20 @@
+#include <boost/lexical_cast.hpp>
+#include <iostream>
+#include <cstdlib>
+#ifdef __WIN32__
+#  include <windows.h>
+#endif
+
+#include "ss_cover.hh"
+
+int main( int argc, char **argv) {
+       if(argc != 4 ) {
+               std::cout << "Usage: " << argv[0] << " [-h|--help] pak_file track_id output_image" << std::endl;
+               return EXIT_FAILURE;
+       }
+
+       SingstarCover c = SingstarCover(argv[1], boost::lexical_cast<unsigned int>(argv[2]));
+       c.write(argv[3]);
+
+       return EXIT_SUCCESS;
+}
diff --git a/tools/gh_fsb/fsb.h b/tools/gh_fsb/fsb.h
new file mode 100644 (file)
index 0000000..8190e56
--- /dev/null
@@ -0,0 +1,177 @@
+/*
+from http://www.fmod.org/forum/viewtopic.php?t=1551
+*/
+
+#pragma pack(2)
+
+#define F_FLOAT     float
+
+#define FSOUND_FSB_NAMELEN  30
+
+/*
+    Defines for FSOUND_FSB_HEADER->mode field
+*/
+#define FSOUND_FSB_SOURCE_FORMAT        0x00000001  /* all samples stored in their original compressed format */
+#define FSOUND_FSB_SOURCE_BASICHEADERS  0x00000002  /* samples should use the basic header structure */
+
+/*
+    Defines for FSOUND_FSB_HEADER->version field
+*/
+#define FSOUND_FSB_VERSION_3_1          0x00030001  /* FSB version 3.1 */
+
+/*
+    16 byte header.
+*/
+typedef struct {
+    char        id[4];      /* 'FSB1' */
+    int32_t     numsamples; /* number of samples in the file */
+    int32_t     datasize;   /* size in bytes of compressed sample data */
+    int32_t     dunno_null;
+} FSOUND_FSB_HEADER_FSB1;
+
+/*
+    16 byte header.
+*/
+typedef struct {
+    char        id[4];      /* 'FSB2' */
+    int32_t     numsamples; /* number of samples in the file */
+    int32_t     shdrsize;   /* size in bytes of all of the sample headers including extended information */
+    int32_t     datasize;   /* size in bytes of compressed sample data */
+} FSOUND_FSB_HEADER_FSB2;
+
+/*
+    24 byte header.
+*/
+typedef struct {
+    char        id[4];      /* 'FSB3' */
+    int32_t     numsamples; /* number of samples in the file */
+    int32_t     shdrsize;   /* size in bytes of all of the sample headers including extended information */
+    int32_t     datasize;   /* size in bytes of compressed sample data */
+    uint32_t    version;    /* extended fsb version */
+    uint32_t    mode;       /* flags that apply to all samples in the fsb */
+} FSOUND_FSB_HEADER_FSB3;
+
+typedef struct {
+    char        id[4];      /* 'FSB4' */
+    int32_t     numsamples; /* number of samples in the file */
+    int32_t     shdrsize;   /* size in bytes of all of the sample headers including extended information */
+    int32_t     datasize;   /* size in bytes of compressed sample data */
+    uint32_t    version;    /* extended fsb version */
+    uint32_t    mode;       /* flags that apply to all samples in the fsb */
+    char        zero[8];    /* ??? */
+    uint8_t     hash[16];   /* hash??? */
+} FSOUND_FSB_HEADER_FSB4;
+
+/*
+    64 byte sample header.
+*/
+typedef struct {
+    char        name[32];
+
+    uint32_t    lengthsamples;
+    uint32_t    lengthcompressedbytes;
+    int32_t     deffreq;
+    uint16_t    defpri;
+    uint16_t    numchannels;    /* I'm not sure! */
+    uint16_t    defvol;
+    int16_t     defpan;
+    uint32_t    mode;
+    uint32_t    loopstart;
+    uint32_t    loopend;
+   
+} FSOUND_FSB_SAMPLE_HEADER_1;
+
+/*
+    64 byte sample header.
+*/
+typedef struct {
+    uint16_t    size;
+    char        name[FSOUND_FSB_NAMELEN];
+
+    uint32_t    lengthsamples;
+    uint32_t    lengthcompressedbytes;
+    uint32_t    loopstart;
+    uint32_t    loopend;
+
+    uint32_t    mode;
+    int32_t     deffreq;
+    uint16_t    defvol;
+    int16_t     defpan;
+    uint16_t    defpri;
+    uint16_t    numchannels;
+   
+} FSOUND_FSB_SAMPLE_HEADER_2;
+
+/*
+    80 byte sample header.
+*/
+typedef struct {
+    uint16_t    size;
+    char        name[FSOUND_FSB_NAMELEN];
+
+    uint32_t    lengthsamples;
+    uint32_t    lengthcompressedbytes;
+    uint32_t    loopstart;
+    uint32_t    loopend;
+
+    uint32_t    mode;
+    int32_t     deffreq;
+    uint16_t    defvol;
+    int16_t     defpan;
+    uint16_t    defpri;
+    uint16_t    numchannels;
+
+    F_FLOAT     mindistance;
+    F_FLOAT     maxdistance;
+    int32_t     varfreq;
+    uint16_t    varvol;
+    int16_t     varpan;
+
+} FSOUND_FSB_SAMPLE_HEADER_3_1;
+
+/*
+    8 byte sample header.
+*/
+typedef struct {
+    uint32_t    lengthsamples;
+    uint32_t    lengthcompressedbytes;   
+} FSOUND_FSB_SAMPLE_HEADER_BASIC; 
+
+
+
+#define FSOUND_LOOP_OFF         0x00000001 /* For non looping samples. */
+#define FSOUND_LOOP_NORMAL      0x00000002 /* For forward looping samples. */
+#define FSOUND_LOOP_BIDI        0x00000004 /* For bidirectional looping samples. (no effect if in hardware). */
+#define FSOUND_8BITS            0x00000008 /* For 8 bit samples. */
+#define FSOUND_16BITS           0x00000010 /* For 16 bit samples. */
+#define FSOUND_MONO             0x00000020 /* For mono samples. */
+#define FSOUND_STEREO           0x00000040 /* For stereo samples. */
+#define FSOUND_UNSIGNED         0x00000080 /* For user created source data containing unsigned samples. */
+#define FSOUND_SIGNED           0x00000100 /* For user created source data containing signed data. */
+#define FSOUND_DELTA            0x00000200 /* For user created source data stored as delta values. */
+#define FSOUND_IT214            0x00000400 /* For user created source data stored using IT214 compression. */
+#define FSOUND_IT215            0x00000800 /* For user created source data stored using IT215 compression. */
+#define FSOUND_HW3D             0x00001000 /* Attempts to make samples use 3d hardware acceleration. (if the card supports it) */
+#define FSOUND_2D               0x00002000 /* Tells software (not hardware) based sample not to be included in 3d processing. */
+#define FSOUND_STREAMABLE       0x00004000 /* For a streamimg sound where you feed the data to it. */
+#define FSOUND_LOADMEMORY       0x00008000 /* "name" will be interpreted as a pointer to data for streaming and samples. */
+#define FSOUND_LOADRAW          0x00010000 /* Will ignore file format and treat as raw pcm. */
+#define FSOUND_MPEGACCURATE     0x00020000 /* For FSOUND_Stream_Open - for accurate FSOUND_Stream_GetLengthMs/FSOUND_Stream_SetTime. WARNING, see FSOUND_Stream_Open for inital opening time performance issues. */
+#define FSOUND_FORCEMONO        0x00040000 /* For forcing stereo streams and samples to be mono - needed if using FSOUND_HW3D and stereo data - incurs a small speed hit for streams */
+#define FSOUND_HW2D             0x00080000 /* 2D hardware sounds. allows hardware specific effects */
+#define FSOUND_ENABLEFX         0x00100000 /* Allows DX8 FX to be played back on a sound. Requires DirectX 8 - Note these sounds cannot be played more than once, be 8 bit, be less than a certain size, or have a changing frequency */
+#define FSOUND_MPEGHALFRATE     0x00200000 /* For FMODCE only - decodes mpeg streams using a lower quality decode, but faster execution */
+#define FSOUND_IMAADPCM         0x00400000 /* Contents are stored compressed as IMA ADPCM */
+#define FSOUND_VAG              0x00800000 /* For PS2 only - Contents are compressed as Sony VAG format */
+//#define FSOUND_NONBLOCKING      0x01000000 /* For FSOUND_Stream_Open/FMUSIC_LoadSong - Causes stream or music to open in the background and not block the foreground app. See FSOUND_Stream_GetOpenState or FMUSIC_GetOpenState to determine when it IS ready. */
+#define FSOUND_XMA              0x01000000
+#define FSOUND_GCADPCM          0x02000000 /* For Gamecube only - Contents are compressed as Gamecube DSP-ADPCM format */
+#define FSOUND_MULTICHANNEL     0x04000000 /* For PS2 and Gamecube only - Contents are interleaved into a multi-channel (more than stereo) format */
+#define FSOUND_USECORE0         0x08000000 /* For PS2 only - Sample/Stream is forced to use hardware voices 00-23 */
+#define FSOUND_USECORE1         0x10000000 /* For PS2 only - Sample/Stream is forced to use hardware voices 24-47 */
+#define FSOUND_LOADMEMORYIOP    0x20000000 /* For PS2 only - "name" will be interpreted as a pointer to data for streaming and samples. The address provided will be an IOP address */
+#define FSOUND_IGNORETAGS       0x40000000 /* Skips id3v2 etc tag checks when opening a stream, to reduce seek/read overhead when opening files (helps with CD performance) */
+#define FSOUND_STREAM_NET       0x80000000 /* Specifies an internet stream */
+#define FSOUND_NORMAL           (FSOUND_16BITS | FSOUND_SIGNED | FSOUND_MONO)
+
+#pragma pack()
diff --git a/tools/gh_fsb/fsbext.c b/tools/gh_fsb/fsbext.c
new file mode 100644 (file)
index 0000000..ee561d8
--- /dev/null
@@ -0,0 +1,1829 @@
+/*
+    Copyright 2005,2006,2007,2008,2009,2010 Luigi Auriemma
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+
+    http://www.gnu.org/licenses/gpl-2.0.txt
+*/
+
+// File grabbed from here: http://aluigi.altervista.org/papers.htm
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdint.h>
+#include <sys/stat.h>
+#include <ctype.h>
+#include "show_dump.h"
+#include "fsb.h"
+#include "mywav.h"
+#include "xma_header.h"
+
+#ifdef WIN32
+    #include <direct.h>
+    #define PATHSLASH   '\\'
+    #define make_dir(x) mkdir(x)
+#else
+    #include <unistd.h>
+    #define strnicmp    strncasecmp
+    #define PATHSLASH   '/'
+    #define make_dir(x) mkdir(x, 0755)
+#endif
+
+typedef uint8_t     u8;
+typedef uint16_t    u16;
+typedef uint32_t    u32;
+
+
+
+#define VER         "0.2.8"
+#define HEXSIZE     176
+#define NULLNAME    "%08x.dat"
+
+#define MODEZ(x)    sprintf(name, "%.*s", (int)sizeof(x.name), x.name); \
+                    freq     = x.deffreq;                               \
+                    chans    = x.numchannels;                           \
+                    mode     = show_mode(x.mode, &codec, NULL, &bits);  \
+                    size     = x.lengthcompressedbytes;                 \
+                    samples  = x.lengthsamples;                         \
+                    moresize = x.size - sizeof(x);
+#define FDREB_INIT  if(fdreb) reboff = ftell(fd);
+#define REBBUFFCHK  if(rebsize > rebbuffsz) { \
+                        rebbuffsz = rebsize + 1000; \
+                        rebbuff = realloc(rebbuff, rebbuffsz); \
+                        if(!rebbuff) std_err(); \
+                    }
+
+
+
+void add_to_reb_file(FILE *fd);
+int rebuild_fsb(FILE *fd);
+
+void frch(FILE *fd, u8 *data, int size);
+void fwch(FILE *fd, u8 *data, int size);
+u16 (*fr16)(FILE *fd);
+u16 fri16(FILE *fd);
+u16 frb16(FILE *fd);
+u32 (*fr32)(FILE *fd);
+u32 fri32(FILE *fd);
+u32 frb32(FILE *fd);
+
+void fw08(FILE *fd, int num);
+void fwi16(FILE *fd, int num);
+void fwi32(FILE *fd, int num);
+void fwb16(FILE *fd, int num);
+void fwb32(FILE *fd, int num);
+
+void fr_FSOUND_FSB_HEADER_FSB1(FILE *fd, FSOUND_FSB_HEADER_FSB1 *fh);
+void fr_FSOUND_FSB_HEADER_FSB2(FILE *fd, FSOUND_FSB_HEADER_FSB2 *fh);
+void fr_FSOUND_FSB_HEADER_FSB3(FILE *fd, FSOUND_FSB_HEADER_FSB3 *fh);
+void fr_FSOUND_FSB_HEADER_FSB4(FILE *fd, FSOUND_FSB_HEADER_FSB4 *fh);
+
+void fr_FSOUND_FSB_SAMPLE_HEADER_1(FILE *fd, FSOUND_FSB_SAMPLE_HEADER_1 *fh);
+void fr_FSOUND_FSB_SAMPLE_HEADER_2(FILE *fd, FSOUND_FSB_SAMPLE_HEADER_2 *fh);
+void fr_FSOUND_FSB_SAMPLE_HEADER_3_1(FILE *fd, FSOUND_FSB_SAMPLE_HEADER_3_1 *fh);
+void fr_FSOUND_FSB_SAMPLE_HEADER_BASIC(FILE *fd, FSOUND_FSB_SAMPLE_HEADER_BASIC *fh, int moresize);
+
+void pcmwav_header(FILE *fd, int freq, u16 chans, u16 bits, u32 rawlen);
+void xbox_ima_header(FILE *fd, int freq, u16 chans, u32 rawlen);
+void its_header(FILE *fd, u8 *fname, u16 chans, u16 bits, u32 rawlen);
+void genh_header(FILE *fd, int freq, u16 chans, u32 rawlen, u8 *coeff, int coeffsz);
+void brstm_header(FILE *fd, int freq, u16 chans, u32 rawlen, u8 *coeff, int coeffsz);
+void adx_header(FILE *fd, int freq, u16 chans, u32 rawlen);
+void ss2_header(FILE *fd, int freq, u16 chans, u32 rawlen);
+void vag_header(FILE *fd, u8 *fname, int freq, u32 rawlen);
+
+int check_sign_endian(FILE *fd);
+char *show_mode(u32 mode, int *xcodec, u16 *chans, u16 *bits);
+void create_dir(u8 *fname);
+void add_extension(u8 *fname, int add, int extract, int add_guess);
+u32 putfile(FILE *fd, int num, u8 *fname);
+void extract_file(FILE *fd, u8 *fname, int freq, u16 chans, u16 bits, u32 len, u8 *moresize_dump, int moresize, int samples);
+void delimit(u8 *data);
+FILE *try_fsbdec(FILE *fd);
+u8 fsbdec(u8 t);
+int fsbdec1(u8 *data, int len, u8 *key, int keyc);
+int fsbdec2(u8 *data, int len, u8 *key, int keyc);
+u32 char_crc(u8 *data);
+
+void read_err(void);
+void write_err(void);
+void std_err(void);
+
+
+
+FILE    *fdreb      = NULL;
+u32     reboff,
+        rebsize;
+int     addhead     = 0,
+        codec       = 0,
+        head_ver    = 0,
+        verbose     = 0,
+        nullfiles   = 0,
+        force_ima   = 0,
+        rebbuffsz   = 0;
+u8      *rebbuff    = NULL;
+
+
+
+int main(int argc, char *argv[]) {
+    FSOUND_FSB_HEADER_FSB1          fh1;
+    FSOUND_FSB_HEADER_FSB2          fh2;
+    FSOUND_FSB_HEADER_FSB3          fh3;
+    FSOUND_FSB_HEADER_FSB4          fh4;
+    FSOUND_FSB_SAMPLE_HEADER_1      fs1;
+    FSOUND_FSB_SAMPLE_HEADER_2      fs2;
+    FSOUND_FSB_SAMPLE_HEADER_3_1    fs31;
+    FSOUND_FSB_SAMPLE_HEADER_BASIC  fsb;
+
+    FILE    *fd,
+            *fdlist         = NULL;
+    u32     nameoff         = 0,
+            fileoff         = 0,
+            size            = 0,
+            samples         = 0;
+    int     i,
+            num,
+            sign,
+            freq            = 44100,
+            head_mode       = 0,
+            list            = 0,
+            rebuild         = 0,
+            moresize_dumpsz = 0;
+    u16     chans           = 1,
+            bits            = 16,
+            moresize        = 0;
+    u8      name[256]       = "",
+            *fname,
+            *rebfile        = NULL,
+            *listfile       = NULL,
+            *folder         = NULL,
+            *mode           = NULL,
+            *moresize_dump  = NULL;
+
+    setbuf(stdout, NULL);
+    setbuf(stderr, NULL);
+
+    fputs("\n"
+        "FSB files extractor "VER"\n"
+        "by Luigi Auriemma\n"
+        "e-mail: aluigi@autistici.org\n"
+        "web:    aluigi.org\n"
+        "\n", stderr);
+
+    if(argc < 2) {
+        printf("\n"
+            "Usage: %s [options] <file.FSB>\n"
+            "\n"
+            "-d DIR   output folder where extracting the files\n"
+            "-l       list files without extracting them\n"
+            "-a       add header to the output files for making them directly playable,\n"
+            "         the extracted files are usually header-less (just as they are in the\n"
+            "         FSB archive) so this option IS very useful and suggested!\n"
+            "-s FILE  binary file containing the informations for rebuilding the FSB file\n"
+            "-r       rebuild the original file, in short:\n"
+            "         if you do NOT use -r will be created the binary file with the info\n"
+            "         if you use -r will be read the binary file (-s) and will be created a\n"
+            "         new FSB file (so it becomes the output and not the input)\n"
+            "         Example:   fsbext -s files.dat    input.fsb\n"
+            "                    fsbext -s files.dat -r output.fsb\n"
+            "-v       verbose output, debugging informations\n"
+            "-f FILE  dump the list of extracted/listed files in FILE\n"
+            "-A       option available only with -a, gives the ima_adpcm tag (0x0011)\n"
+            "         instead of the xbox adpcm one (0x0069) to the output adpcm files\n"
+            "\n"
+            "NOTE: use EVER an empty folder where placing the extracted files because this\n"
+            "      tool adds a sequential number if a file with same name already exists\n"
+            "      because filenames in FSB archives are truncated at 30 chars.\n"
+            "TIPS: -a option is VERY useful so the extracted files are ready to be played!\n"
+            "\n", argv[0]);
+        exit(1);
+    }
+
+    argc--;
+    for(i = 1; i < argc; i++) {
+        if(((argv[i][0] != '-') && (argv[i][0] != '/')) || (strlen(argv[i]) != 2)) {
+            fprintf(stderr, "\nError: wrong command-line argument (%s)\n\n", argv[i]);
+            exit(1);
+        }
+        switch(argv[i][1]) {
+            case 'd': folder    = argv[++i];    break;
+            case 'l': list      = 1;            break;
+            case 'a': addhead   = 1;            break;
+            case 's': rebfile   = argv[++i];    break;
+            case 'r': rebuild   = 1;            break;
+            case 'f': listfile  = argv[++i];    break;
+            case 'v': verbose   = 1;            break;
+            case 'A': force_ima = 1;            break;
+            default: {
+                fprintf(stderr, "\nError: wrong command-line argument (%s)\n\n", argv[i]);
+                exit(1);
+                }
+        }
+    }
+
+    fname = argv[argc];
+
+    if(rebfile) {
+        if(addhead) {
+            printf("\n"
+                "Error: you can't use the -a and -s options together or you can't rebuild\n"
+                "       the FSB file correctly because the files MUST be all headerless\n"
+                "\n");
+            exit(1);
+        }
+        printf("- reb file:     %s\n", rebfile);
+        fdreb = fopen(rebfile, "rb");
+        if(!rebuild) {
+            if(fdreb) {
+                fclose(fdreb);
+                printf("\n"
+                    "Error: you have selected -s but the output binary file already exists,\n"
+                    "       check if you want to recreate this file and delete it\n");
+                exit(1);
+            }
+            fdreb = fopen(rebfile, "wb");
+        }
+        if(!fdreb) std_err();
+    }
+
+    if(listfile) {
+        fdlist = fopen(listfile, "wb");
+        if(!fdlist) std_err();
+    }
+
+    if(!rebuild) {
+        printf("- input file:   %s\n", fname);
+        fd = fopen(fname, "rb");
+        if(!fd) std_err();
+    } else {
+        if(!fdreb) {
+            printf("\n"
+                "Error: you have selected the rebuild option but you have not specified the\n"
+                "       file with the rebuild informations using -s\n");
+            exit(1);
+        }
+
+        printf("- output file:  %s\n", fname);
+        fd = fopen(fname, "rb");
+        if(fd) {
+            fclose(fd);
+            printf("\n"
+                "Error: you have selected the rebuild option but the output FSB file already\n"
+                "       exists, check if you want to recreate this file and delete it\n");
+            exit(1);
+        }
+        fd = fopen(fname, "wb");
+        if(!fd) std_err();
+    }
+
+    if(folder) {
+        printf("- enter folder: %s\n", folder);
+        if(chdir(folder) < 0) std_err();
+    }
+
+    if(rebuild) {
+        i = rebuild_fsb(fd);
+        goto quit;
+    }
+
+    sign = check_sign_endian(fd);
+    if(sign < 0) {
+        fd = try_fsbdec(fd);
+    }
+
+    sign = check_sign_endian(fd);
+    if(sign < 0) {
+        printf("\nError: this tool doesn't support the format \"%.4s\"\n\n", (u8 *)&sign);
+        exit(1);
+    }
+
+    if(sign == '1') {
+        fr_FSOUND_FSB_HEADER_FSB1(fd, &fh1);
+        num       = fh1.numsamples;
+        nameoff   = sizeof(fh1);
+        fileoff   = sizeof(fh1) + (num * sizeof(fs1));
+        head_ver  = 1;
+        head_mode = 0;
+
+    } else if(sign == '2') {
+        fr_FSOUND_FSB_HEADER_FSB2(fd, &fh2);
+        num       = fh2.numsamples;
+        nameoff   = sizeof(fh2);
+        fileoff   = sizeof(fh2) + fh2.shdrsize;
+        head_ver  = 2;
+        head_mode = 0;
+
+    } else if(sign == '3') {
+        fr_FSOUND_FSB_HEADER_FSB3(fd, &fh3);
+        num       = fh3.numsamples;
+        nameoff   = sizeof(fh3);
+        fileoff   = sizeof(fh3) + fh3.shdrsize;
+        head_ver  = 3;
+        head_mode = fh3.mode;
+        printf("- FSB3 version %hu.%hu mode %u\n",
+            (fh3.version >> 16) & 0xffff, fh3.version & 0xffff,
+            fh3.mode);
+
+    } else if(sign == '4') {
+        fr_FSOUND_FSB_HEADER_FSB4(fd, &fh4);
+        num       = fh4.numsamples;
+        nameoff   = sizeof(fh4);
+        fileoff   = sizeof(fh4) + fh4.shdrsize;
+        head_ver  = 4;
+        head_mode = fh4.mode;
+        printf("- FSB4 version %hu.%hu mode %u\n",
+            (fh4.version >> 16) & 0xffff, fh4.version & 0xffff,
+            fh4.mode);
+
+    } else {
+        printf("\nError: this tool doesn't support FSB%c\n\n", sign & 0xff);
+        exit(1);
+    }
+
+    if(head_mode & FSOUND_FSB_SOURCE_BASICHEADERS) {
+        printf("- small sample headers\n");
+    }
+
+    if(verbose) {
+        printf(
+            "- names offset  %08x\n"
+            "- files offset  %08x\n",
+            nameoff, fileoff);
+    }
+
+    printf("\n"
+        "Filename                         Size       Mode frequency channels bits\n"
+        "========================================================================\n");
+
+    for(i = 0; i < num; i++) {
+        memset(name, 0, sizeof(name));  // I need to use it because filenames are truncated!
+
+        if(head_ver == 1) {
+            fr_FSOUND_FSB_SAMPLE_HEADER_1(fd, &fs1);
+            sprintf(name, "%.*s", (int)sizeof(fs1.name), fs1.name);
+            samples  = fs1.lengthsamples;
+            freq     = fs1.deffreq;
+            mode     = show_mode(fs1.mode, &codec, &chans, &bits);  // chans only here?
+            size     = fs1.lengthcompressedbytes;
+
+        } else if(head_ver == 2) {
+            fr_FSOUND_FSB_SAMPLE_HEADER_2(fd, &fs2);
+            MODEZ(fs2)
+
+        } else if(head_ver == 3) {
+            if((head_mode & FSOUND_FSB_SOURCE_BASICHEADERS) && i) {
+                fr_FSOUND_FSB_SAMPLE_HEADER_BASIC(fd, &fsb, moresize);
+                sprintf(name, NULLNAME, i);
+                size     = fsb.lengthcompressedbytes;
+                samples  = fsb.lengthsamples;
+                //freq, chans, mode and moresize are the same of the first file
+            } else {
+                if(fh3.version == FSOUND_FSB_VERSION_3_1) {         // 3.1
+                    fr_FSOUND_FSB_SAMPLE_HEADER_3_1(fd, &fs31);
+                    MODEZ(fs31)
+                } else {                                            // 3.0
+                    fr_FSOUND_FSB_SAMPLE_HEADER_2(fd, &fs2);
+                    MODEZ(fs2)
+                }
+            }
+
+        } else if(head_ver == 4) {
+            if((head_mode & FSOUND_FSB_SOURCE_BASICHEADERS) && i) {
+                fr_FSOUND_FSB_SAMPLE_HEADER_BASIC(fd, &fsb, moresize);
+                sprintf(name, NULLNAME, i);
+                size     = fsb.lengthcompressedbytes;
+                samples  = fsb.lengthsamples;
+                //freq, chans, mode and moresize are the same of the first file
+            } else {
+                fr_FSOUND_FSB_SAMPLE_HEADER_3_1(fd, &fs31);
+                MODEZ(fs31);
+            }
+        }
+
+        if(verbose) printf("  fh->file_offset %08x\n", fileoff);
+        if(moresize) {
+            if(fdreb) { // the rebuild file already contains moresize, so we need to "reload" it now
+                fseek(fd, -moresize, SEEK_CUR);
+            }
+            if(moresize > moresize_dumpsz) {
+                moresize_dumpsz = moresize + 100;
+                moresize_dump = realloc(moresize_dump, moresize_dumpsz);
+                if(!moresize_dump) std_err();
+            }
+            frch(fd, moresize_dump, moresize);
+            //if(fdreb) fwch(fdreb, moresize_dump, moresize);   // moresize is already saved
+            if(verbose) {
+                printf("  fh->moresize    %d:\n", moresize);
+                show_dump(moresize_dump, moresize, stdout);
+                printf("\n");
+            }
+        }
+        nameoff = ftell(fd);
+
+        if(!name[0]) {
+            //sprintf(name, NULLNAME, i);
+            nullfiles++;
+            printf("- NULL file skipped\n");
+            continue;
+        }
+
+        printf(
+            "%-32s %-10u %s %d %hu %hu\n",
+            name, size, mode, freq, chans, bits);
+        if(fdlist) {
+            fprintf(fdlist, "%s\r\n", name);
+        }
+
+        if(!list) {
+            if(fseek(fd, fileoff, SEEK_SET) < 0) std_err();
+            extract_file(fd, name, freq, chans, bits, size, moresize_dump, moresize, samples);
+            fileoff += size;
+            if(fseek(fd, nameoff, SEEK_SET) < 0) std_err();
+        }
+    }
+
+quit:
+    fclose(fd);
+    if(fdreb) fclose(fdreb);
+    if(fdlist) fclose(fdlist);
+    printf("\n- %d files %s\n\n", i - nullfiles, list ? "listed" : "processed");
+    return(0);
+}
+
+
+
+void add_to_reb_file(FILE *fd) {
+    if(!fdreb) return;
+    if(!rebsize) rebsize = ftell(fd) - reboff;
+    REBBUFFCHK
+    fseek(fd, reboff, SEEK_SET);
+    frch(fd, rebbuff, rebsize);
+    fwi32(fdreb, rebsize);              // size of the block
+    fwch(fdreb, rebbuff, rebsize);      // content of the block
+}
+
+
+
+int rebuild_fsb(FILE *fd) {
+    FSOUND_FSB_HEADER_FSB1          *fh1;
+    FSOUND_FSB_HEADER_FSB2          *fh2;
+    FSOUND_FSB_HEADER_FSB3          *fh3;
+    FSOUND_FSB_HEADER_FSB4          *fh4;
+    FSOUND_FSB_SAMPLE_HEADER_1      *fs1;
+    FSOUND_FSB_SAMPLE_HEADER_2      *fs2;
+    FSOUND_FSB_SAMPLE_HEADER_3_1    *fs31;
+    FSOUND_FSB_SAMPLE_HEADER_BASIC  *fsb;
+
+    double  val1,
+            val2,
+            val3;
+    u32     i,
+            j,
+            files,
+            head_off,
+            head_size,
+            real_head_size,
+            data_off,
+            data_size,
+            lengthsamples           = 0,
+            lengthcompressedbytes   = 0,
+            *already_read;
+    int     samename,
+            padding,
+            head_mode   = 0;
+    u8      name[256],
+            zero_padding[16] = "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0",
+            ver;
+
+    fr16 = fri16;
+    fr32 = fri32;
+
+    printf(
+        "- FSB rebuilding\n"
+        "  note that this option is experimental and doesn't work for all the\n"
+        "  versions of FSB files!!!\n");
+
+    rebsize = fr32(fdreb);              // we consider the input file in little endian, I'm lazy and it's the format used in the 99,9% of the files
+    REBBUFFCHK
+    frch(fdreb, rebbuff, rebsize);
+    reboff = ftell(fdreb);
+    fwch(fd, rebbuff, rebsize);
+
+    fh1  = (FSOUND_FSB_HEADER_FSB1 *)rebbuff;
+    fh2  = (FSOUND_FSB_HEADER_FSB2 *)rebbuff;
+    fh3  = (FSOUND_FSB_HEADER_FSB3 *)rebbuff;
+    fh4  = (FSOUND_FSB_HEADER_FSB4 *)rebbuff;
+    fs1  = (FSOUND_FSB_SAMPLE_HEADER_1 *)rebbuff;
+    fs2  = (FSOUND_FSB_SAMPLE_HEADER_2 *)rebbuff;
+    fs31 = (FSOUND_FSB_SAMPLE_HEADER_3_1 *)rebbuff;
+    fsb  = (FSOUND_FSB_SAMPLE_HEADER_BASIC *)rebbuff;
+
+    files  = *(u32 *)(rebbuff + 4);
+    ver    = rebbuff[3];
+
+#define X0(x,y,z)   if(ver == x) {                                              \
+                        printf("- FSB version %c\n", x);                        \
+                        real_head_size = y;                                     \
+                        head_mode      = z;                                     \
+                    }
+#define X1(x,y)     if(ver == x) {                                              \
+                        if((head_mode & FSOUND_FSB_SOURCE_BASICHEADERS) && i) { \
+                            sprintf(name, NULLNAME, i);                         \
+                            lengthsamples         = fsb->lengthsamples;         \
+                            lengthcompressedbytes = fsb->lengthcompressedbytes; \
+                        } else {                                                \
+                            memcpy(name, y->name, sizeof(y->name));             \
+                            lengthsamples         = y->lengthsamples;           \
+                            lengthcompressedbytes = y->lengthcompressedbytes;   \
+                        }                                                       \
+                    }
+#define X2(x,y)     if(ver == x) {                                              \
+                        if((head_mode & FSOUND_FSB_SOURCE_BASICHEADERS) && i) { \
+                            fsb->lengthsamples         = lengthsamples;         \
+                            fsb->lengthcompressedbytes = lengthcompressedbytes; \
+                        } else {                                                \
+                            y->lengthsamples           = lengthsamples;         \
+                            y->lengthcompressedbytes   = lengthcompressedbytes; \
+                        }                                                       \
+                    }
+#define X3(x,y)     if(ver == x) {                                              \
+                        y->datasize = data_size;                                \
+                    }
+
+         X0('1', 0,             0)
+    else X0('2', fh2->shdrsize, 0)
+    else X0('3', fh3->shdrsize, fh3->mode)
+    else X0('4', fh4->shdrsize, fh4->mode)
+    else {
+        printf("\nError: this version of FSB (%c) is not supported yet\n", ver);
+        exit(1);
+    }
+
+    head_off  = ftell(fd);
+    head_size = 0;
+    data_size = 0;
+
+    for(i = 0; i < files; i++) {
+        rebsize = fr32(fdreb);
+        REBBUFFCHK
+        frch(fdreb, rebbuff, rebsize);
+        head_size += rebsize;
+    }
+    if(head_size < real_head_size) head_size = real_head_size;
+
+    data_off = head_off + head_size;
+
+    fseek(fdreb, reboff, SEEK_SET);
+
+    already_read = malloc(files * sizeof(u32));
+    if(!already_read) std_err();
+
+    for(i = 0; i < files; i++) {
+        memset(name, 0, sizeof(name));
+
+        rebsize = fr32(fdreb);
+        REBBUFFCHK
+        frch(fdreb, rebbuff, rebsize);
+
+             X1('1', fs1)
+        else X1('2', fs2)
+        else X1('3', fs31)
+        else X1('4', fs31) // correct
+
+        val1 = lengthsamples;
+        val2 = lengthcompressedbytes;
+        val3 = val1 / val2;
+
+        if(!name[0]) {  // in this case if the file has no filename I handle it normally, putfile returns 0... this is the good way
+            //sprintf(name, NULLNAME, i);
+            nullfiles++;    // null files are something like loops inside the real files, probably used for dynamic music
+            printf("- NULL file skipped\n");
+            //continue;
+        } else {
+            printf("  %s\n", name);
+
+            already_read[i] = char_crc(name);
+            samename = 0;
+            for(j = 0; j < i; j++) {
+                if(already_read[i] == already_read[j]) samename++;
+            }
+            add_extension(name, samename, 0, 1);
+        }
+        fseek(fd, data_off, SEEK_SET);
+        lengthcompressedbytes = putfile(fd, i, name);
+
+        padding = (data_off + lengthcompressedbytes) & 15;
+        if(padding) {
+            padding = 16 - padding;
+            fwch(fd, zero_padding, padding);
+            lengthcompressedbytes += padding;
+        }
+
+        data_off  += lengthcompressedbytes;
+        data_size += lengthcompressedbytes;
+
+        val2          = lengthcompressedbytes;
+        val1          = val2 * val3;
+        lengthsamples = val1;
+
+        if(name[0]) {   // this is the correct way, NULL files will be left as they are
+                 X2('1', fs1)
+            else X2('2', fs2)
+            else X2('3', fs31)
+            else X2('4', fs31) // correct
+        }
+
+        fseek(fd, head_off, SEEK_SET);
+        fwch(fd, rebbuff, rebsize);
+        head_off += rebsize;
+    }
+
+    rewind(fd);
+    rewind(fdreb);
+    rebsize = fr32(fdreb);
+    REBBUFFCHK
+    frch(fdreb, rebbuff, rebsize);
+
+         X3('1', fh1)
+    else X3('2', fh2)
+    else X3('3', fh3)
+    else X3('4', fh4)
+
+    fwch(fd, rebbuff, rebsize);
+    return(files);
+
+#undef X0
+#undef X1
+#undef X2
+#undef X3
+}
+
+
+
+void frch(FILE *fd, u8 *data, int size) {
+    if(fread(data, 1, size, fd) != size) read_err();
+}
+
+
+
+void fwch(FILE *fd, u8 *data, int size) {
+    if(fwrite(data, 1, size, fd) != size) write_err();
+}
+
+
+
+u16 fri16(FILE *fd) {
+    int     t1,
+            t2;
+
+    t1 = fgetc(fd);
+    t2 = fgetc(fd);
+    if((t1 < 0) || (t2 < 0)) read_err();
+    return(t1 | (t2 << 8));
+}
+
+
+
+u16 frb16(FILE *fd) {
+    int     t1,
+            t2;
+
+    t1 = fgetc(fd);
+    t2 = fgetc(fd);
+    if((t1 < 0) || (t2 < 0)) read_err();
+    return(t2 | (t1 << 8));
+}
+
+
+
+u32 fri32(FILE *fd) {
+    int     t1,
+            t2,
+            t3,
+            t4;
+
+    t1 = fgetc(fd);
+    t2 = fgetc(fd);
+    t3 = fgetc(fd);
+    t4 = fgetc(fd);
+    if((t1 < 0) || (t2 < 0) || (t3 < 0) || (t4 < 0)) read_err();
+    return(t1 | (t2 << 8) | (t3 << 16) | (t4 << 24));
+}
+
+
+
+u32 frb32(FILE *fd) {
+    int     t1,
+            t2,
+            t3,
+            t4;
+
+    t1 = fgetc(fd);
+    t2 = fgetc(fd);
+    t3 = fgetc(fd);
+    t4 = fgetc(fd);
+    if((t1 < 0) || (t2 < 0) || (t3 < 0) || (t4 < 0)) read_err();
+    return(t4 | (t3 << 8) | (t2 << 16) | (t1 << 24));
+}
+
+
+
+void fw08(FILE *fd, int num) {
+    if(fputc((num      ) & 0xff, fd) < 0) write_err();
+}
+
+
+
+void fwi16(FILE *fd, int num) {
+    if(fputc((num      ) & 0xff, fd) < 0) write_err();
+    if(fputc((num >>  8) & 0xff, fd) < 0) write_err();
+}
+
+
+
+void fwi32(FILE *fd, int num) {
+    if(fputc((num      ) & 0xff, fd) < 0) write_err();
+    if(fputc((num >>  8) & 0xff, fd) < 0) write_err();
+    if(fputc((num >> 16) & 0xff, fd) < 0) write_err();
+    if(fputc((num >> 24) & 0xff, fd) < 0) write_err();
+}
+
+
+
+void fwb16(FILE *fd, int num) {
+    if(fputc((num >>  8) & 0xff, fd) < 0) write_err();
+    if(fputc((num      ) & 0xff, fd) < 0) write_err();
+}
+
+
+
+void fwb32(FILE *fd, int num) {
+    if(fputc((num >> 24) & 0xff, fd) < 0) write_err();
+    if(fputc((num >> 16) & 0xff, fd) < 0) write_err();
+    if(fputc((num >>  8) & 0xff, fd) < 0) write_err();
+    if(fputc((num      ) & 0xff, fd) < 0) write_err();
+}
+
+
+
+int check_sign_endian(FILE *fd) {
+    u8      sign[4];
+
+    rewind(fd);
+    frch(fd, sign, sizeof(sign));
+    rewind(fd);
+
+    if(
+         (sign[0] == 'F')
+      && (sign[1] == 'S')
+      && (sign[2] == 'B')) {
+        fr16 = fri16;
+        fr32 = fri32;
+        return(sign[3]);
+
+    } else if(
+         (sign[3] == 'F')
+      && (sign[2] == 'S')
+      && (sign[1] == 'B')) {
+        fr16 = frb16;
+        fr32 = frb32;
+        return(sign[0]);
+
+    } else {
+        fr16 = fri16;
+        fr32 = fri32;
+        return(-1);
+    }
+}
+
+
+void fr_FSOUND_FSB_HEADER_FSB1(FILE *fd, FSOUND_FSB_HEADER_FSB1 *fh) {
+    FDREB_INIT
+
+                     frch(fd, fh->id, 4);
+    fh->numsamples = fr32(fd);
+    fh->datasize   = fr32(fd);
+    fh->dunno_null = fr32(fd);
+
+    rebsize = 0;
+    add_to_reb_file(fd);
+
+    if(verbose) {
+        printf("\n"
+            "- %08x fr_FSOUND_FSB_HEADER_FSB1:\n"
+            "  fh->id         %.4s\n"
+            "  fh->numsamples %08x\n"
+            "  fh->datasize   %08x\n"
+            "  fh->dunno_null %08x\n",
+            (u32)(ftell(fd) - sizeof(*fh)),
+            fh->id,
+            fh->numsamples,
+            fh->datasize,
+            fh->dunno_null);
+    }
+}
+
+
+
+void fr_FSOUND_FSB_HEADER_FSB2(FILE *fd, FSOUND_FSB_HEADER_FSB2 *fh) {
+    FDREB_INIT
+
+                     frch(fd, fh->id, 4);
+    fh->numsamples = fr32(fd);
+    fh->shdrsize   = fr32(fd);
+    fh->datasize   = fr32(fd);
+
+    rebsize = 0;
+    add_to_reb_file(fd);
+
+    if(verbose) {
+        printf("\n"
+            "- %08x fr_FSOUND_FSB_HEADER_FSB2:\n"
+            "  fh->id         %.4s\n"
+            "  fh->numsamples %08x\n"
+            "  fh->shdrsize   %08x\n"
+            "  fh->datasize   %08x\n",
+            (u32)(ftell(fd) - sizeof(*fh)),
+            fh->id,
+            fh->numsamples,
+            fh->shdrsize,
+            fh->datasize);
+    }
+}
+
+
+
+void fr_FSOUND_FSB_HEADER_FSB3(FILE *fd, FSOUND_FSB_HEADER_FSB3 *fh) {
+    FDREB_INIT
+
+                     frch(fd, fh->id, 4);
+    fh->numsamples = fr32(fd);
+    fh->shdrsize   = fr32(fd);
+    fh->datasize   = fr32(fd);
+    fh->version    = fr32(fd);
+    fh->mode       = fr32(fd);
+
+    rebsize = 0;
+    add_to_reb_file(fd);
+
+    if(verbose) {
+        printf("\n"
+            "- %08x fr_FSOUND_FSB_HEADER_FSB3:\n"
+            "  fh->id         %.4s\n"
+            "  fh->numsamples %08x\n"
+            "  fh->shdrsize   %08x\n"
+            "  fh->datasize   %08x\n"
+            "  fh->version    %08x\n"
+            "  fh->mode       %08x\n",
+            (u32)(ftell(fd) - sizeof(*fh)),
+            fh->id,
+            fh->numsamples,
+            fh->shdrsize,
+            fh->datasize,
+            fh->version,
+            fh->mode);
+    }
+}
+
+
+
+void fr_FSOUND_FSB_HEADER_FSB4(FILE *fd, FSOUND_FSB_HEADER_FSB4 *fh) {
+    FDREB_INIT
+
+                     frch(fd, fh->id, 4);
+    fh->numsamples = fr32(fd);
+    fh->shdrsize   = fr32(fd);
+    fh->datasize   = fr32(fd);
+    fh->version    = fr32(fd);
+    fh->mode       = fr32(fd);
+                     frch(fd, fh->zero, sizeof(fh->zero));
+                     frch(fd, fh->hash, sizeof(fh->hash));
+
+    rebsize = 0;
+    add_to_reb_file(fd);
+
+    if(verbose) {
+        printf("\n"
+            "- %08x fr_FSOUND_FSB_HEADER_FSB4:\n"
+            "  fh->id         %.4s\n"
+            "  fh->numsamples %08x\n"
+            "  fh->shdrsize   %08x\n"
+            "  fh->datasize   %08x\n"
+            "  fh->version    %08x\n"
+            "  fh->mode       %08x\n",
+            (u32)(ftell(fd) - sizeof(*fh)),
+            fh->id,
+            fh->numsamples,
+            fh->shdrsize,
+            fh->datasize,
+            fh->version,
+            fh->mode);
+    }
+}
+
+
+
+void fr_FSOUND_FSB_SAMPLE_HEADER_1(FILE *fd, FSOUND_FSB_SAMPLE_HEADER_1 *fh) {
+    FDREB_INIT
+
+                                frch(fd, fh->name, sizeof(fh->name));
+    fh->lengthsamples         = fr32(fd);
+    fh->lengthcompressedbytes = fr32(fd);
+    fh->deffreq               = fr32(fd);
+    fh->defpri                = fr16(fd);
+    fh->numchannels           = fr16(fd);
+    fh->defvol                = fr16(fd);
+    fh->defpan                = fr16(fd);
+    fh->mode                  = fr32(fd);
+    fh->loopstart             = fr32(fd);
+    fh->loopend               = fr32(fd);
+
+    rebsize = 0;
+    add_to_reb_file(fd);
+
+    if(verbose) {
+        printf("\n"
+            "- %08x fr_FSOUND_FSB_SAMPLE_HEADER_1:\n"
+            "  fh->name                  %.*s\n"
+            "  fh->lengthsamples         %08x\n"
+            "  fh->lengthcompressedbytes %08x\n"
+            "  fh->deffreq               %08x\n"
+            "  fh->defpri                %04x\n"
+            "  fh->numchannels           %04x\n"
+            "  fh->defvol                %04x\n"
+            "  fh->defpan                %04x\n"
+            "  fh->mode                  %08x\n"
+            "  fh->loopstart             %08x\n"
+            "  fh->loopend               %08x\n",
+            (u32)(ftell(fd) - sizeof(*fh)),
+            (u32)sizeof(fh->name), fh->name,
+            fh->lengthsamples,
+            fh->lengthcompressedbytes,
+            fh->deffreq,
+            fh->defpri,
+            fh->numchannels,
+            fh->defvol,
+            fh->defpan,
+            fh->mode,
+            fh->loopstart,
+            fh->loopend);
+    }
+}
+
+
+
+void fr_FSOUND_FSB_SAMPLE_HEADER_2(FILE *fd, FSOUND_FSB_SAMPLE_HEADER_2 *fh) {
+    FDREB_INIT
+
+    fh->size                  = fr16(fd);
+                                frch(fd, fh->name, sizeof(fh->name));
+    fh->lengthsamples         = fr32(fd);
+    fh->lengthcompressedbytes = fr32(fd);
+    fh->loopstart             = fr32(fd);
+    fh->loopend               = fr32(fd);
+    fh->mode                  = fr32(fd);
+    fh->deffreq               = fr32(fd);
+    fh->defvol                = fr16(fd);
+    fh->defpan                = fr16(fd);
+    fh->defpri                = fr16(fd);
+    fh->numchannels           = fr16(fd);
+
+    rebsize = fh->size;
+    add_to_reb_file(fd);
+
+    if(verbose) {
+        printf("\n"
+            "- %08x fr_FSOUND_FSB_SAMPLE_HEADER_2:\n"
+            "  fh->size                  %04x\n"
+            "  fh->name                  %.*s\n"
+            "  fh->lengthsamples         %08x\n"
+            "  fh->lengthcompressedbytes %08x\n"
+            "  fh->loopstart             %08x\n"
+            "  fh->loopend               %08x\n"
+            "  fh->mode                  %08x\n"
+            "  fh->deffreq               %08x\n"
+            "  fh->defvol                %04x\n"
+            "  fh->defpan                %04x\n"
+            "  fh->defpri                %04x\n"
+            "  fh->numchannels           %04x\n",
+            (u32)(ftell(fd) - sizeof(*fh)),
+            fh->size,
+            (u32)sizeof(fh->name), fh->name,
+            fh->lengthsamples,
+            fh->lengthcompressedbytes,
+            fh->loopstart,
+            fh->loopend,
+            fh->mode,
+            fh->deffreq,
+            fh->defvol,
+            fh->defpan,
+            fh->defpri,
+            fh->numchannels);
+    }
+}
+
+
+
+void fr_FSOUND_FSB_SAMPLE_HEADER_3_1(FILE *fd, FSOUND_FSB_SAMPLE_HEADER_3_1 *fh) {
+    FDREB_INIT
+
+    fh->size                  = fr16(fd);
+                                frch(fd, fh->name, sizeof(fh->name));
+    fh->lengthsamples         = fr32(fd);
+    fh->lengthcompressedbytes = fr32(fd);
+    fh->loopstart             = fr32(fd);
+    fh->loopend               = fr32(fd);
+    fh->mode                  = fr32(fd);
+    fh->deffreq               = fr32(fd);
+    fh->defvol                = fr16(fd);
+    fh->defpan                = fr16(fd);
+    fh->defpri                = fr16(fd);
+    fh->numchannels           = fr16(fd);
+    fh->mindistance           = (F_FLOAT)fr32(fd);
+    fh->maxdistance           = (F_FLOAT)fr32(fd);
+    fh->varfreq               = fr32(fd);
+    fh->varvol                = fr16(fd);
+    fh->varpan                = fr16(fd);
+
+    rebsize = fh->size;
+    add_to_reb_file(fd);
+
+    if(verbose) {
+        printf("\n"
+            "- %08x fr_FSOUND_FSB_SAMPLE_HEADER_3_1:\n"
+            "  fh->size                  %04x\n"
+            "  fh->name                  %.*s\n"
+            "  fh->lengthsamples         %08x\n"
+            "  fh->lengthcompressedbytes %08x\n"
+            "  fh->loopstart             %08x\n"
+            "  fh->loopend               %08x\n"
+            "  fh->mode                  %08x\n"
+            "  fh->deffreq               %08x\n"
+            "  fh->defvol                %04x\n"
+            "  fh->defpan                %04x\n"
+            "  fh->defpri                %04x\n"
+            "  fh->numchannels           %04x\n"
+            "  fh->mindistance           %f\n"
+            "  fh->maxdistance           %f\n"
+            "  fh->varfreq               %08x\n"
+            "  fh->varvol                %04x\n"
+            "  fh->varpan                %04x\n",
+            (u32)(ftell(fd) - sizeof(*fh)),
+            fh->size,
+            (u32)sizeof(fh->name), fh->name,
+            fh->lengthsamples,
+            fh->lengthcompressedbytes,
+            fh->loopstart,
+            fh->loopend,
+            fh->mode,
+            fh->deffreq,
+            fh->defvol,
+            fh->defpan,
+            fh->defpri,
+            fh->numchannels,
+            fh->mindistance,
+            fh->maxdistance,
+            fh->varfreq,
+            fh->varvol,
+            fh->varpan);
+    }
+}
+
+
+
+void fr_FSOUND_FSB_SAMPLE_HEADER_BASIC(FILE *fd, FSOUND_FSB_SAMPLE_HEADER_BASIC *fh, int moresize) {
+    FDREB_INIT
+
+    fh->lengthsamples         = fr32(fd);
+    fh->lengthcompressedbytes = fr32(fd);
+
+    rebsize = sizeof(FSOUND_FSB_SAMPLE_HEADER_BASIC) + moresize;
+    add_to_reb_file(fd);
+
+    if(verbose) {
+        printf("\n"
+            "- %08x fr_FSOUND_FSB_SAMPLE_HEADER_BASIC:\n"
+            "  fh->lengthsamples         %08x\n"
+            "  fh->lengthcompressedbytes %08x\n",
+            (u32)(ftell(fd) - sizeof(*fh)),
+            fh->lengthsamples,
+            fh->lengthcompressedbytes);
+    }
+}
+
+
+
+void pcmwav_header(FILE *fd, int freq, u16 chans, u16 bits, u32 rawlen) {
+    mywav_fmtchunk  fmt;
+
+    fmt.wFormatTag       = 0x0001;
+    fmt.wChannels        = chans;
+    fmt.dwSamplesPerSec  = freq;
+    fmt.wBitsPerSample   = bits;
+    fmt.wBlockAlign      = (fmt.wBitsPerSample / 8) * fmt.wChannels;
+    fmt.dwAvgBytesPerSec = fmt.dwSamplesPerSec * fmt.wBlockAlign;
+    mywav_writehead(fd, &fmt, rawlen, NULL, 0);
+}
+
+
+
+void xbox_ima_header(FILE *fd, int freq, u16 chans, u32 rawlen) {
+    mywav_fmtchunk  fmt;
+
+    fmt.wFormatTag       = force_ima ? 0x0011 : 0x0069;
+    fmt.wChannels        = chans;
+    fmt.dwSamplesPerSec  = freq;
+    fmt.wBitsPerSample   = 4;
+    fmt.wBlockAlign      = 36 * fmt.wChannels;
+    fmt.dwAvgBytesPerSec = (689 * fmt.wBlockAlign) + 4; // boh, not important
+    //fmt.wBlockAlign      = fmt.wBitsPerSample * fmt.wChannels * 9;  // 9???
+    //fmt.dwAvgBytesPerSec = 49612;                                   // 49612???
+    mywav_writehead(fd, &fmt, rawlen, "\x02\x00" "\x40\x00", 4);
+}
+
+
+
+void its_header(FILE *fd, u8 *fname, u16 chans, u16 bits, u32 rawlen) {
+    u8      flags;
+
+    /* note that doesn't seem possible to know if the sample has been encoded with 2.14 or 2.15 */
+    flags = 1 | 8;  // 8 for compression
+    if(bits == 16)  flags |= 2;
+    if(chans == 2)  flags |= 4;
+
+    fwch(fd, "IMPS", 4);        // DWORD id
+    fwch(fd, fname, 12);        // CHAR filename[12]
+    fw08(fd,  0);               // BYTE zero
+    fw08(fd,  128);             // BYTE gvl
+    fw08(fd,  0);               // BYTE flags
+    fw08(fd,  64);              // BYTE vol
+    fwch(fd, fname, 26);        // CHAR name[26]
+    fw08(fd,  0xff);            // BYTE cvt
+    fw08(fd,  0x7f);            // BYTE dfp
+    fwi32(fd, rawlen);          // DWORD length
+    fwi32(fd, 0);               // DWORD loopbegin
+    fwi32(fd, 0);               // DWORD loopend
+    fwi32(fd, 8363);            // DWORD C5Speed
+    fwi32(fd, 0);               // DWORD susloopbegin
+    fwi32(fd, 0);               // DWORD susloopend
+    fwi32(fd, 0);               // DWORD samplepointer
+    fw08(fd,  0);               // BYTE vis
+    fw08(fd,  0);               // BYTE vid
+    fw08(fd,  0);               // BYTE vir
+    fw08(fd,  0);               // BYTE vit
+}
+
+
+
+void genh_header(FILE *fd, int freq, u16 chans, u32 rawlen, u8 *coeff, int coeffsz) {
+    static const int    genhsz  = 0x80; // in case of future additions to the format
+    int     i,
+            j;
+
+    fwb32(fd, 0x47454e48);              // 0    magic
+    fwi32(fd, chans);                   // 4    channel_count
+    fwi32(fd, 2);                       // 8    interleave
+    fwi32(fd, freq);                    // c    sample_rate
+    fwi32(fd, 0xffffffff);              // 10   loop_start
+    fwi32(fd, ((rawlen*14)/8)/chans);   // 14   loop_end
+    fwi32(fd, 12);                      // 18   codec
+    fwi32(fd, genhsz + (chans * 32));   // 1c   start_offset
+    fwi32(fd, genhsz + (chans * 32));   // 20   header_size
+    fwi32(fd, genhsz);                  // 24   coef[0]
+    fwi32(fd, genhsz + 32);             // 28   coef[1]
+    fwi32(fd, 1);                       // 2c   dsp_interleave_type
+    fwi32(fd, 0);                       // 30   coef_type
+    fwi32(fd, genhsz);                  // 34   coef_splitted[0]
+    fwi32(fd, genhsz + 32);             // 38   coef_splitted[1]
+    for(i = ftell(fd); i < genhsz; i++) fputc(0, fd);
+    for(i = 0; i < chans; i++) {
+        if(coeff && (coeffsz >= 0x2e)) {
+            fwch(fd, coeff, 32);
+            coeff   += 0x2e;
+            coeffsz -= 0x2e;
+        } else {
+            for(j = 0; j < 16; j++) fwi16(fd, 0);
+        }
+    }
+}
+
+
+
+void brstm_header(FILE *fd, int freq, u16 chans, u32 rawlen, u8 *coeff, int coeffsz) {
+    int     i,
+            j;
+
+    fwb32(fd, 0x5253544D);          // RSTM
+    fwb32(fd, 0xFEFF0100);
+    fwb32(fd, 0x40 + 0x80 + (chans * 0x38) + 0x10 + 0x20 + rawlen);
+    fwb16(fd, 0);
+    fwb16(fd, 0);
+    fwb32(fd, 0x40);                // head offset
+    fwb32(fd, 0x80 + (chans * 0x38) + 0x10);   // head length
+    fwb32(fd, 0);                   // ADPC offset
+    fwb32(fd, 0);                   // ADPC size
+    fwb32(fd, 0x40 + 0x80 + (chans * 0x38) + 0x10); // DATA offset
+    fwb32(fd, 0x20 + rawlen);       // DATA size
+    for(i = 0; i < 0x18; i++) fw08(fd, 0);
+    fwb32(fd, 0x48454144);          // HEAD
+    for(i = 0; i < 12; i++) fw08(fd, 0);
+    fwb32(fd, 0);
+    fwb32(fd, 0);
+    fwb32(fd, 0);
+    fwb32(fd, 0x5c);                // coef_offset1
+    fw08(fd,  2);                   // codec
+    fw08(fd,  0);
+    fw08(fd,  chans);
+    fw08(fd,  0);
+    fwb16(fd, freq);
+    fwb16(fd, 0);
+    fwb32(fd, 0);                   // loop start
+    fwb32(fd, ((rawlen*14)/8)/chans);   // num_samples
+    fwb32(fd, 0x40 + 0x80 + (chans * 0x38) + 0x10 + 0x20);
+    fwb32(fd, 0);
+    fwb32(fd, 0x2000);              // interleave block size, brstm are not good because there is no support for byte_interleaving!
+    for(i = 0; i < 12; i++) fw08(fd, 0);
+    fwb32(fd, 0x2000);              // interleave small block size
+    for(i = 0; i < 32; i++) fw08(fd, 0);
+    fwb32(fd, 0x70);                // coef_offset2
+    for(i = 0; i < 16; i++) fw08(fd, 0);
+    for(i = 0; i < chans; i++) {
+        if(coeff && (coeffsz >= 0x2e)) {
+            fwch(fd, coeff, 0x2e);
+            coeff   += 0x2e;
+            coeffsz -= 0x2e;
+        } else {
+            for(j = 0; j < 0x2e; j++) fw08(fd, 0);
+        }
+        fwb32(fd, 0);
+        fwb32(fd, 0);
+        fwb16(fd, 0);
+    }
+    for(i = 0; i < 16; i++) fw08(fd, 0);
+    fwb32(fd, 0x44415441);
+    fwb32(fd, ((rawlen*14)/8)/chans);
+    fwb32(fd, 0x18);
+    fwb32(fd, 0);
+    for(i = 0; i < 16; i++) fw08(fd, 0);
+}
+
+
+
+void adx_header(FILE *fd, int freq, u16 chans, u32 rawlen) {
+    fwb16(fd, 0x8000);  // 0x8000
+    fwb16(fd, 0x1a);    // copyright offset
+    fw08(fd,  3);       // encoding type
+    fw08(fd,  18);      // block size
+    fw08(fd,  4);       // sample bitdepth
+    fw08(fd,  chans);   // channel count
+    fwb32(fd, freq);    // sample rate
+    fwb32(fd, ((rawlen*32)/18)/chans);  // total samples
+    fwb16(fd, 500);     // highpass frequency
+    fw08(fd,  0x03);    // version
+    fw08(fd,  0x00);    // flags
+    fwb32(fd, 0);       // unknown
+    fwch(fd, "(c)CRI", 6);
+}
+
+
+
+void ss2_header(FILE *fd, int freq, u16 chans, u32 rawlen) {
+    fwb32(fd, 0x53536864);
+    fwi32(fd, 0x18);
+    fwi32(fd, 0x10);
+    fwi32(fd, freq);
+    fwi32(fd, chans);
+    fwi32(fd, rawlen / chans);  // seems to be the correct interleave value
+    fwi32(fd, 0);
+    fwi32(fd, 0xffffffff);
+    fwb32(fd, 0x53536264);
+    fwi32(fd, rawlen);
+}
+
+
+
+void vag_header(FILE *fd, u8 *fname, int freq, u32 rawlen) {
+    int     i;
+
+    fwch(fd, "VAGp", 4);
+    fwb32(fd, 32);
+    fwb32(fd, 0);
+    fwb32(fd, rawlen);
+    fwb32(fd, freq);
+    for(i = 0; i < 12; i++) fputc(0, fd);
+    fwch(fd, fname, 16);
+    for(i = 0; i < 16; i++) fputc(0, fd);
+}
+
+
+
+char *show_mode(u32 mode, int *xcodec, u16 *xchans, u16 *xbits) {
+    static char m[300];
+
+    m[0] = 0;
+    if(mode & FSOUND_LOOP_OFF)      strcat(m, "noloop,");
+    if(mode & FSOUND_LOOP_NORMAL)   strcat(m, "loop,");
+    if(mode & FSOUND_LOOP_BIDI)     strcat(m, "biloop,");
+    if(mode & FSOUND_8BITS)         strcat(m, "8,");
+    if(mode & FSOUND_16BITS)        strcat(m, "16,");
+    if(mode & FSOUND_MONO)          strcat(m, "mono,");
+    if(mode & FSOUND_STEREO)        strcat(m, "stereo,");
+    if(mode & FSOUND_UNSIGNED)      strcat(m, "unsign,");
+    if(mode & FSOUND_SIGNED)        strcat(m, "sign,");
+    if(mode & FSOUND_DELTA)         strcat(m, "delta,");
+    if(mode & FSOUND_IT214)         strcat(m, "IT_2.14,");
+    if(mode & FSOUND_IT215)         strcat(m, "IT_2.15,");
+    if(mode & FSOUND_HW3D)          strcat(m, "hw3d,");
+    if(mode & FSOUND_2D)            strcat(m, "2d,");
+    if(mode & FSOUND_STREAMABLE)    strcat(m, "stream,");
+    if(mode & FSOUND_LOADMEMORY)    strcat(m, "memory,");
+    if(mode & FSOUND_LOADRAW)       strcat(m, "raw,");
+    if(mode & FSOUND_MPEGACCURATE)  strcat(m, "acc_mpeg,");
+    if(mode & FSOUND_FORCEMONO)     strcat(m, "force_mono,");
+    if(mode & FSOUND_HW2D)          strcat(m, "hw2d,");
+    if(mode & FSOUND_ENABLEFX)      strcat(m, "effects,");
+    if(mode & FSOUND_MPEGHALFRATE)  strcat(m, "half_mpeg,");
+    if(mode & FSOUND_IMAADPCM)      strcat(m, "ima_adpcm,");
+    if(mode & FSOUND_VAG)           strcat(m, "vag,");
+    //if(mode & FSOUND_NONBLOCKING)   strcat(m, "non_block,");
+    if(mode & FSOUND_XMA)           strcat(m, "xma,");
+    if(mode & FSOUND_GCADPCM)       strcat(m, "GC_adpcm,");
+    if(mode & FSOUND_MULTICHANNEL)  strcat(m, "multichan,");
+    if(mode & FSOUND_USECORE0)      strcat(m, "00-23,");
+    if(mode & FSOUND_USECORE1)      strcat(m, "24-47,");
+    if(mode & FSOUND_LOADMEMORYIOP) strcat(m, "memory,");
+    if(mode & FSOUND_IGNORETAGS)    strcat(m, "notags,");
+    if(mode & FSOUND_STREAM_NET)    strcat(m, "netstream,");
+    // if(mode & FSOUND_NORMAL)        strcat(m, "normal,");
+    if(m[0]) m[strlen(m) - 1] = 0;
+
+    if(xcodec) {
+        *xcodec = 0;
+        if(mode & FSOUND_DELTA)     *xcodec = FSOUND_DELTA;
+        if(mode & FSOUND_IT214)     *xcodec = FSOUND_IT214;
+        if(mode & FSOUND_IT215)     *xcodec = FSOUND_IT215;
+        if(mode & FSOUND_IMAADPCM)  *xcodec = FSOUND_IMAADPCM;
+        if(mode & FSOUND_VAG)       *xcodec = FSOUND_VAG;
+        if(mode & FSOUND_GCADPCM)   *xcodec = FSOUND_GCADPCM;
+        if(mode & FSOUND_XMA)       *xcodec = FSOUND_XMA;
+    }
+    if(xchans) {
+        *xchans = 1;
+        if(mode & FSOUND_MONO)      *xchans = 1;
+        if(mode & FSOUND_STEREO)    *xchans = 2;
+    }
+    if(xbits) {
+        *xbits = 16;
+        if(mode & FSOUND_8BITS)     *xbits = 8;
+        if(mode & FSOUND_16BITS)    *xbits = 16;
+    }
+    return(m);
+}
+
+
+
+void create_dir(u8 *fname) {
+    u8      *p,
+            *l;
+
+    p = strchr(fname, ':');
+    if(p) *p = '_';
+    for(p = fname; *p && ((*p == '\\') || (*p == '/')); p++) *p = '_';
+
+    for(p = fname; ; p = l + 1) {
+        for(l = p; *l && (*l != '\\') && (*l != '/'); l++);
+        if(!*l) break;
+        *l = 0;
+
+        if(!strncmp(p, "..", 2)) memcpy(p, "__", 2);
+
+        make_dir(fname);
+        *l = PATHSLASH;
+    }
+}
+
+
+
+void tmp_extension(u8 *fname, u8 *ext) {
+    u8      *wavext;
+
+    wavext = strrchr(fname, '.');
+    if(!wavext || (wavext && (strlen(wavext + 1) > 3))) {
+        memmove(fname + strlen(fname), ext, strlen(ext) + 1);   // don't touch memmove!
+    } else if(wavext && (strlen(wavext + 1) < 3)) {
+        memmove(wavext, ext, strlen(ext) + 1);                  // don't touch memmove!
+    }
+}
+
+
+
+void put_extension(u8 *fname, u8 *ext) {
+    u8      *wavext;
+
+    wavext = strrchr(fname, '.');
+    if(wavext) strcpy(wavext + 1, ext);
+}
+
+
+
+int mylencmp(u8 *str1, u8 *str2) {
+    int     equal;
+
+    if(strlen(str1) > strlen(str2)) return(0);
+
+    for(equal = 0; *str1; str1++, str2++) {
+        if(tolower(*str1) != tolower(*str2)) break;
+        equal++;
+    }
+    return(equal);
+}
+
+
+
+void experimental_extension_guessing(u8 *fname, u8 *oldext, u8 *end) {
+    int     ext_wav = 0,
+            ext_wma = 0,
+            ext_xma = 0,
+            ext_vag = 0,
+            ext_mp3 = 0,
+            ext_ogg = 0,
+            maxnamelen = FSOUND_FSB_NAMELEN;
+    u8      *wavext;
+
+    if(head_ver == 1) maxnamelen = 32;
+    if((end - fname) < maxnamelen) return;
+
+    wavext = strrchr(fname, '.');
+    if(wavext) {
+        wavext++;
+        if(strlen(wavext) <= 3) strcpy(oldext, wavext - 1);
+        if((end - fname) < maxnamelen) return;
+
+        ext_wav = mylencmp(wavext, "wav");
+        ext_wma = mylencmp(wavext, "wma");
+        ext_xma = mylencmp(wavext, "xma");
+        ext_vag = mylencmp(wavext, "vag");
+        ext_mp3 = mylencmp(wavext, "mp3");
+        ext_ogg = mylencmp(wavext, "ogg");
+        // these are enough for the moment
+    }
+
+         if(ext_wav) strcpy(oldext, ".wav");
+    else if(ext_wma) strcpy(oldext, ".wma");
+    else if(ext_xma) strcpy(oldext, ".xma");
+    else if(ext_vag) strcpy(oldext, ".vag");
+    else if(ext_mp3) strcpy(oldext, ".mp3");
+    else if(ext_ogg) strcpy(oldext, ".ogg");
+    else if(!oldext[0] || !wavext[0]) strcpy(oldext, ".wav");
+}
+
+
+
+void add_extension(u8 *fname, int add, int extract, int add_guess) {
+    struct stat xstat;
+    int     i;
+    u8      oldext_buff[8],
+            *oldext,
+            *end;
+
+    end = fname + strlen(fname);
+
+    if(add) sprintf(end, "_%u", add);
+
+    oldext = oldext_buff;
+    oldext[0] = 0;
+    experimental_extension_guessing(fname, oldext, end);
+    if(add_guess && oldext[0]) {
+        tmp_extension(fname, oldext);
+    } else {
+        oldext = strrchr(fname, '.');
+        if(oldext) {
+            sprintf(oldext_buff, "%.*s", (u32)sizeof(oldext_buff), oldext);
+            end    = oldext;
+            oldext = oldext_buff;
+        } else {
+            oldext = oldext_buff;
+        }
+    }
+
+    if(!extract) return;
+
+    for(i = (add ? add : 1); !stat(fname, &xstat); i++) {
+        sprintf(end, "_%u", i);
+        tmp_extension(fname, oldext);
+    }
+}
+
+
+
+u32 putfile(FILE *fd, int num, u8 *fname) {
+    FILE    *fdi;
+    u32     size;
+    int     t;
+    u8      buff[4096];
+
+    if(!fname[0]) {
+        //sprintf(fname, NULLNAME, num);
+        return(0);
+    }
+    fdi = fopen(fname, "rb");
+    if(!fdi) {
+        printf("- open file \"%s\"\n", fname);
+        std_err();
+    }
+
+    for(size = 0; (t = fread(buff, 1, sizeof(buff), fdi)); size += t) {
+        fwch(fd, buff, t);
+    }
+
+    fclose(fdi);
+    return(size);
+}
+
+
+
+void extract_file(FILE *fd, u8 *fname, int freq, u16 chans, u16 bits, u32 len, u8 *moresize_dump, int moresize, int samples) {
+    FILE    *fdo;
+    int     t,
+            n;
+    u8      buff[4096];
+
+    create_dir(fname);  // most for security
+
+    add_extension(fname, 0, 1, 1);
+    if(addhead) {       // force the right extension, I think it's a good idea
+             if(codec & FSOUND_DELTA)       put_extension(fname, "mp3");
+        else if(codec & FSOUND_IT214)       put_extension(fname, "it");
+        else if(codec & FSOUND_IT215)       put_extension(fname, "it");
+        else if(codec & FSOUND_IMAADPCM)    put_extension(fname, "wav");
+        else if(codec & FSOUND_VAG)         put_extension(fname, "ss2");
+        else if(codec & FSOUND_GCADPCM)     put_extension(fname, "genh");
+        else if(codec & FSOUND_XMA)         put_extension(fname, "xma");
+        else                                put_extension(fname, "wav");
+    }
+    add_extension(fname, 0, 1, 0);
+
+    fdo = fopen(fname, "wb");
+    if(!fdo) std_err();
+
+    if(!chans) chans = 1;   // useless, should never happen
+
+    if(addhead) {
+             if(codec & FSOUND_DELTA)       /* mp3 files have no header */;
+        else if(codec & FSOUND_IT214)       its_header(fdo, fname, chans, bits, len);
+        else if(codec & FSOUND_IT215)       its_header(fdo, fname, chans, bits, len);
+        else if(codec & FSOUND_IMAADPCM)    xbox_ima_header(fdo, freq, chans, len);
+        else if(codec & FSOUND_VAG)         ss2_header(fdo, freq, chans, len);
+        else if(codec & FSOUND_GCADPCM)     genh_header(fdo, freq, chans, len, moresize_dump, moresize);
+        else if(codec & FSOUND_XMA)         xma2_header(fdo, freq, chans, bits, len, moresize_dump, moresize, samples);
+        else                                pcmwav_header(fdo, freq, chans, bits, len);
+    }
+
+    for(t = sizeof(buff); len; len -= t) {
+        if(t > len) t = len;
+        n = fread(buff, 1, t, fd);
+        fwch(fdo, buff, n);
+        if(n != t) {
+            printf("\n- Alert: the extracted file is incomplete! I continue\n");
+            break;
+        }
+    }
+
+    fclose(fdo);
+}
+
+
+
+void delimit(u8 *data) {
+    while(*data && (*data != '\n') && (*data != '\r')) data++;
+    *data = 0;
+}
+
+
+
+void xor(u8 *data, int len, u8 *key) {
+    int     i;
+    u8      *k;
+
+    k = key;
+    for(i = 0; i < len; i++) {
+        if(!*k) k = key;
+        data[i] ^= *k;
+        k++;
+    }
+}
+
+
+
+FILE *try_fsbdec(FILE *fd) {
+    FILE    *fdo;
+    int     len,
+            keyc,
+            enc_type;
+    u8      buff[256],
+            key[256];
+
+    for(;;) {
+        rewind(fd);
+
+        printf(
+            "- probably the file uses encryption, insert the needed keyword:\n"
+            "  type ? for viewing the hex dump of the first %d bytes of the file because\n"
+            "  it's possible to see part of the plain-text password in the encrypted file!\n"
+            "  ", HEXSIZE);
+        if (!fgets(key, sizeof(key), stdin)) exit(1);
+        delimit(key);
+        if(strcmp(key, "?")) break;
+
+        printf("- encryption type 1\n");
+        len = fread(buff, 1, HEXSIZE, fd);
+        show_dump(buff, len, stdout);
+        fputc('\n', stdout);
+
+        printf("- encryption type 2\n");
+        fsbdec2(buff, len, "", 0);
+        xor(buff, 4, "FSB4");
+        show_dump(buff, len, stdout);
+        fputc('\n', stdout);
+    }
+
+    for(enc_type = 0;; enc_type++) {
+        len = fread(buff, 1, 3, fd);
+        rewind(fd);
+        switch(enc_type) {
+            case 0: fsbdec1(buff, len, key, 0); break;
+            case 1: fsbdec2(buff, len, key, 0); break;
+            default: {
+                printf("\nError: your password seems wrong\n");
+                exit(1);
+            } break;
+        }
+        if(!memcmp(buff, "FSB", 3)) break;
+    }
+    printf("- use encryption type %d\n", enc_type);
+
+    fdo  = tmpfile();
+    keyc = 0;
+    while((len = fread(buff, 1, sizeof(buff), fd))) {
+        switch(enc_type) {
+            case 0: keyc = fsbdec1(buff, len, key, keyc);   break;
+            case 1: keyc = fsbdec2(buff, len, key, keyc);   break;
+            default: {
+                printf("\nError: unknown encryption type\n");
+                exit(1);
+            } break;
+        }
+        fwch(fdo, buff, len);
+    }
+    fclose(fd);
+    fd = fdo;
+    fflush(fd);
+    return(fd);
+}
+
+
+
+u8 fsbdec(u8 t) {
+    return((((((((t & 64) | (t >> 2)) >> 2) | (t & 32)) >> 2) | (t & 16)) >> 1) |
+           (((((((t &  2) | (t << 2)) << 2) | (t &  4)) << 2) | (t &  8)) << 1));
+}
+
+
+
+int fsbdec1(u8 *data, int len, u8 *key, int keyc) {
+    u8      *k;
+
+    for(k = key + keyc; len--; data++) {
+        if(!*k) k = key;
+        *data = fsbdec(*data ^ *k);
+        if(*k) k++;
+    }
+
+    return(k - key);
+}
+
+
+
+int fsbdec2(u8 *data, int len, u8 *key, int keyc) {
+    u8      *k;
+
+    for(k = key + keyc; len--; data++) {
+        if(!*k) k = key;
+        *data = fsbdec(*data) ^ *k;
+        if(*k) k++;
+    }
+
+    return(k - key);
+}
+
+
+
+u32 char_crc(u8 *data) {
+    static const u32   crctable[] = {
+        0x00000000, 0x77073096, 0xee0e612c, 0x990951ba,
+        0x076dc419, 0x706af48f, 0xe963a535, 0x9e6495a3,
+        0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988,
+        0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91,
+        0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de,
+        0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7,
+        0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec,
+        0x14015c4f, 0x63066cd9, 0xfa0f3d63, 0x8d080df5,
+        0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172,
+        0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b,
+        0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940,
+        0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59,
+        0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116,
+        0x21b4f4b5, 0x56b3c423, 0xcfba9599, 0xb8bda50f,
+        0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924,
+        0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d,
+        0x76dc4190, 0x01db7106, 0x98d220bc, 0xefd5102a,
+        0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433,
+        0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818,
+        0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01,
+        0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e,
+        0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457,
+        0x65b0d9c6, 0x12b7e950, 0x8bbeb8ea, 0xfcb9887c,
+        0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65,
+        0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2,
+        0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb,
+        0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0,
+        0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9,
+        0x5005713c, 0x270241aa, 0xbe0b1010, 0xc90c2086,
+        0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f,
+        0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4,
+        0x59b33d17, 0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad,
+        0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a,
+        0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683,
+        0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8,
+        0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1,
+        0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe,
+        0xf762575d, 0x806567cb, 0x196c3671, 0x6e6b06e7,
+        0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc,
+        0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5,
+        0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252,
+        0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b,
+        0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60,
+        0xdf60efc3, 0xa867df55, 0x316e8eef, 0x4669be79,
+        0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236,
+        0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f,
+        0xc5ba3bbe, 0xb2bd0b28, 0x2bb45a92, 0x5cb36a04,
+        0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d,
+        0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a,
+        0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713,
+        0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38,
+        0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21,
+        0x86d3d2d4, 0xf1d4e242, 0x68ddb3f8, 0x1fda836e,
+        0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777,
+        0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c,
+        0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45,
+        0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2,
+        0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db,
+        0xaed16a4a, 0xd9d65adc, 0x40df0b66, 0x37d83bf0,
+        0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9,
+        0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6,
+        0xbad03605, 0xcdd70693, 0x54de5729, 0x23d967bf,
+        0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94,
+        0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d };
+    u32     crc;
+
+    for(crc = 0xffffffff; *data; data++) {
+        crc = crctable[tolower(*data) ^ (crc & 0xff)] ^ (crc >> 8);
+    }
+    return(~crc);
+}
+
+
+
+void read_err(void) {
+    fprintf(stderr, "\nError: the file contains unexpected data\n\n");
+    exit(1);
+}
+
+
+
+void write_err(void) {
+    fprintf(stderr, "\nError: impossible to write the output file, probably your disk space is finished\n\n");
+    exit(1);
+}
+
+
+
+void std_err(void) {
+    perror("\nError");
+    exit(1);
+}
+
+
diff --git a/tools/gh_fsb/mywav.h b/tools/gh_fsb/mywav.h
new file mode 100644 (file)
index 0000000..f3f497e
--- /dev/null
@@ -0,0 +1,244 @@
+/*
+  MyWAV 0.1.1
+  by Luigi Auriemma
+  e-mail: aluigi@autistici.org
+  web:    aluigi.org
+
+    Copyright 2005,2006 Luigi Auriemma
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+
+    http://www.gnu.org/licenses/gpl.txt
+*/
+
+#include <string.h>
+#include <stdint.h>
+
+
+
+/*
+the functions return ever 0 if success, other values (-1) if error
+note that these functions have been written with compatibility in mind
+so don't worry if you see useless instructions
+*/
+
+
+
+typedef struct {
+    uint8_t     id[4];
+    uint32_t    size;
+} mywav_chunk;
+
+typedef struct {
+    int16_t     wFormatTag;
+    uint16_t    wChannels;
+    uint32_t    dwSamplesPerSec;
+    uint32_t    dwAvgBytesPerSec;
+    uint16_t    wBlockAlign;
+    uint16_t    wBitsPerSample;
+} mywav_fmtchunk;
+
+
+
+    /* FILE WRITING */
+
+    // 8 bit
+int mywav_fwi08(FILE *fd, int num) {
+    if(fputc((num      ) & 0xff, fd) < 0) return(-1);
+    return(0);
+}
+
+
+
+    // 16 bit
+int mywav_fwi16(FILE *fd, int num) {
+    if(fputc((num      ) & 0xff, fd) < 0) return(-1);
+    if(fputc((num >>  8) & 0xff, fd) < 0) return(-1);
+    return(0);
+}
+
+
+
+    // 32 bit
+int mywav_fwi32(FILE *fd, int num) {
+    if(fputc((num      ) & 0xff, fd) < 0) return(-1);
+    if(fputc((num >>  8) & 0xff, fd) < 0) return(-1);
+    if(fputc((num >> 16) & 0xff, fd) < 0) return(-1);
+    if(fputc((num >> 24) & 0xff, fd) < 0) return(-1);
+    return(0);
+}
+
+
+
+    // data
+int mywav_fwmem(FILE *fd, uint8_t *mem, int size) {
+    if(size) {
+        if(fwrite(mem, size, 1, fd) != 1) return(-1);
+    }
+    return(0);
+}
+
+
+
+    // chunk
+int mywav_fwchunk(FILE *fd, mywav_chunk *chunk) {
+    if(mywav_fwmem(fd, chunk->id, 4)) return(-1);
+    if(mywav_fwi32(fd, chunk->size))  return(-1);
+    return(0);
+}
+
+
+
+  // fmtchunk
+int mywav_fwfmtchunk(FILE *fd, mywav_fmtchunk *fmtchunk) {
+    if(mywav_fwi16(fd, fmtchunk->wFormatTag))       return(-1);
+    if(mywav_fwi16(fd, fmtchunk->wChannels))        return(-1);
+    if(mywav_fwi32(fd, fmtchunk->dwSamplesPerSec))  return(-1);
+    if(mywav_fwi32(fd, fmtchunk->dwAvgBytesPerSec)) return(-1);
+    if(mywav_fwi16(fd, fmtchunk->wBlockAlign))      return(-1);
+    if(mywav_fwi16(fd, fmtchunk->wBitsPerSample))   return(-1);
+    return(0);
+}
+
+
+
+    /* FILE READING */
+
+    // 8 bit
+int mywav_fri08(FILE *fd, uint8_t *num) {
+    if(fread(num, 1, 1, fd) != 1)  return(-1);
+    return(0);
+}
+
+
+
+    // 16 bit
+int mywav_fri16(FILE *fd, uint16_t *num) {
+    uint16_t    ret;
+    uint8_t     tmp;
+
+    if(fread(&tmp, 1, 1, fd) != 1) return(-1);  ret = tmp;
+    if(fread(&tmp, 1, 1, fd) != 1) return(-1);  ret |= (tmp << 8);
+    *num = ret;
+    return(0);
+}
+
+
+
+    // 32 bit
+int mywav_fri32(FILE *fd, uint32_t *num) {
+    uint32_t    ret;
+    uint8_t     tmp;
+
+    if(fread(&tmp, 1, 1, fd) != 1) return(-1);  ret = tmp;
+    if(fread(&tmp, 1, 1, fd) != 1) return(-1);  ret |= (tmp << 8);
+    if(fread(&tmp, 1, 1, fd) != 1) return(-1);  ret |= (tmp << 16);
+    if(fread(&tmp, 1, 1, fd) != 1) return(-1);  ret |= (tmp << 24);
+    *num = ret;
+    return(0);
+}
+
+
+
+    // data
+int mywav_frmem(FILE *fd, uint8_t *mem, int size) {
+    if(size) {
+        if(fread(mem, size, 1, fd) != 1) return(-1);
+    }
+    return(0);
+}
+
+
+
+    // chunk
+int mywav_frchunk(FILE *fd, mywav_chunk *chunk) {
+    if(mywav_frmem(fd, (void *)&chunk->id, 4)) return(-1);
+    if(mywav_fri32(fd, (void *)&chunk->size))  return(-1);
+    return(0);
+}
+
+
+
+  // fmtchunk
+int mywav_frfmtchunk(FILE *fd, mywav_fmtchunk *fmtchunk) {
+    if(mywav_fri16(fd, (void *)&fmtchunk->wFormatTag))       return(-1);
+    if(mywav_fri16(fd, (void *)&fmtchunk->wChannels))        return(-1);
+    if(mywav_fri32(fd, (void *)&fmtchunk->dwSamplesPerSec))  return(-1);
+    if(mywav_fri32(fd, (void *)&fmtchunk->dwAvgBytesPerSec)) return(-1);
+    if(mywav_fri16(fd, (void *)&fmtchunk->wBlockAlign))      return(-1);
+    if(mywav_fri16(fd, (void *)&fmtchunk->wBitsPerSample))   return(-1);
+    return(0);
+}
+
+
+    /* MYWAV MAIN FUNCTIONS */
+
+int mywav_seekchunk(FILE *fd, uint8_t *find) {
+    mywav_chunk chunk;
+
+    if(fseek(fd, sizeof(mywav_chunk) + 4, SEEK_SET) < 0) return(-1);
+
+    while(!mywav_frchunk(fd, &chunk)) {
+        if(!memcmp(chunk.id, find, 4)) return(chunk.size);
+        if(fseek(fd, chunk.size, SEEK_CUR) < 0) break;
+    }
+    return(-1);
+}
+
+
+
+int mywav_data(FILE *fd, mywav_fmtchunk *fmt) {
+    mywav_chunk chunk;
+    uint8_t     type[4];
+
+    if(mywav_frchunk(fd, &chunk)   < 0) return(-1);
+    if(mywav_frmem(fd, type, 4)    < 0) return(-1);
+    if(memcmp(type, "WAVE", 4))         return(-1);
+
+    if(mywav_seekchunk(fd, "fmt ") < 0) return(-1);
+    if(mywav_frfmtchunk(fd, fmt)   < 0) return(-1);
+
+    return(mywav_seekchunk(fd, "data"));
+}
+
+
+
+int mywav_writehead(FILE *fd, mywav_fmtchunk *fmt, uint32_t data_size, uint8_t *more, int morelen) {
+    mywav_chunk chunk;
+
+    memcpy(chunk.id, "RIFF", 4);
+    chunk.size =
+        4                      +
+        sizeof(mywav_chunk)    +
+        sizeof(mywav_fmtchunk) +
+        morelen                +
+        sizeof(mywav_chunk)    +
+        data_size;
+
+    if(mywav_fwchunk(fd, &chunk)      < 0) return(-1);
+    if(mywav_fwmem(fd, "WAVE", 4)     < 0) return(-1);
+
+    memcpy(chunk.id, "fmt ", 4);
+    chunk.size = sizeof(mywav_fmtchunk) + morelen;
+    if(mywav_fwchunk(fd, &chunk)      < 0) return(-1);
+    if(mywav_fwfmtchunk(fd, fmt)      < 0) return(-1);
+    if(mywav_fwmem(fd, more, morelen) < 0) return(-1);
+
+    memcpy(chunk.id, "data", 4);
+    chunk.size = data_size;
+    if(mywav_fwchunk(fd, &chunk)      < 0) return(-1);
+    return(0);
+}
+
diff --git a/tools/gh_fsb/show_dump.h b/tools/gh_fsb/show_dump.h
new file mode 100644 (file)
index 0000000..4336c6d
--- /dev/null
@@ -0,0 +1,69 @@
+/*
+
+Show_dump 0.1.1a
+
+    Copyright 2004,2005,2006 Luigi Auriemma
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+
+    http://www.gnu.org/licenses/gpl.txt
+
+This function, optimized for performace, shows the hex dump of a buffer and
+places it in a stream
+
+Usage:
+        show_dump(buffer, buffer_length, stdout);
+        show_dump(buffer, buffer_length, fd);
+*/
+
+#include <string.h>
+
+
+
+void show_dump(unsigned char *data, unsigned int len, FILE *stream) {
+    const static char       hex[] = "0123456789abcdef";
+    static unsigned char    buff[67];   /* HEX  CHAR\n */
+    unsigned char           chr,
+                            *bytes,
+                            *p,
+                            *limit,
+                            *glimit = data + len;
+
+    memset(buff + 2, ' ', 48);
+
+    while(data < glimit) {
+        limit = data + 16;
+        if(limit > glimit) {
+            limit = glimit;
+            memset(buff, ' ', 48);
+        }
+
+        p     = buff;
+        bytes = p + 50;
+        while(data < limit) {
+            chr = *data;
+            *p++ = hex[chr >> 4];
+            *p++ = hex[chr & 15];
+            p++;
+            *bytes++ = ((chr < ' ') || (chr >= 0x7f)) ? '.' : chr;
+            data++;
+        }
+        *bytes++ = '\n';
+
+       // TODO: test return value
+        fwrite(buff, bytes - buff, 1, stream);
+    }
+}
+
diff --git a/tools/gh_fsb/xma_header.h b/tools/gh_fsb/xma_header.h
new file mode 100644 (file)
index 0000000..24a1fe4
--- /dev/null
@@ -0,0 +1,349 @@
+/*
+  by Luigi Auriemma
+*/
+
+#ifdef WIN32
+    #include <windows.h>
+#else
+    typedef unsigned int    DWORD;
+    typedef unsigned short  WORD;
+    typedef unsigned char   BYTE;
+typedef struct tWAVEFORMATEX {
+       WORD wFormatTag;
+       WORD nChannels;
+       DWORD nSamplesPerSec;
+       DWORD nAvgBytesPerSec;
+       WORD nBlockAlign;
+       WORD wBitsPerSample;
+       WORD cbSize;
+} WAVEFORMATEX,*PWAVEFORMATEX,*LPWAVEFORMATEX;
+#endif
+
+typedef struct XMASTREAMFORMAT
+{
+    DWORD   PsuedoBytesPerSec;  // Used by encoder
+    DWORD   SampleRate;         // Sample rate for the stream.
+    DWORD   LoopStart;          // Loop start offset (in bits).
+    DWORD   LoopEnd;            // Loop end offset (in bits).
+
+    // Format for SubframeData: eeee ssss.
+    // e: Subframe number of loop end point [0,3].
+    // s: Number of subframes to skip before decoding and outputting at the loop start point [1,4].
+
+    BYTE    SubframeData;       // Data for decoding subframes.  See above.
+    BYTE    Channels;           // Number of channels in the stream (1 or 2).
+    WORD    ChannelMask;        // Channel assignments for the channels in the stream (same as
+                                // lower 16 bits of dwChannelMask in WAVEFORMATEXTENSIBLE).
+} XMASTREAMFORMAT, *PXMASTREAMFORMAT, *NPXMASTREAMFORMAT, *LPXMASTREAMFORMAT;
+typedef const XMASTREAMFORMAT *LPCXMASTREAMFORMAT;
+
+typedef struct XMAWAVEFORMAT
+{
+    WORD            FormatTag;     // Audio format type (always WAVE_FORMAT_XMA).
+    WORD            BitsPerSample; // Bit depth (currently required to be 16).
+    WORD            EncodeOptions; // Options for XMA encoder/decoder.
+    WORD            LargestSkip;   // Largest skip used in interleaving streams.
+    WORD            NumStreams;    // Number of interleaved audio streams.
+    BYTE            LoopCount;     // Number of loop repetitions (255 == infinite).
+    BYTE            Version;       // Version of the encoder that generated this.
+    XMASTREAMFORMAT XmaStreams[1]; // Format info for each stream (can grow based on wNumStreams).
+} XMAWAVEFORMAT, *PXMAWAVEFORMAT, *NPXMAWAVEFORMAT, *LPXMAWAVEFORMAT;
+typedef XMAWAVEFORMAT *LPCXMAWAVEFORMAT;
+
+typedef const WAVEFORMATEX *LPCWAVEFORMATEX;
+
+typedef struct XMA2WAVEFORMATEX
+{
+    WAVEFORMATEX wfx;
+    // Meaning of the WAVEFORMATEX fields here:
+    //    wFormatTag;        // Audio format type; always WAVE_FORMAT_XMA2
+    //    nChannels;         // Channel count of the decoded audio
+    //    nSamplesPerSec;    // Sample rate of the decoded audio
+    //    nAvgBytesPerSec;   // Used internally by the XMA encoder
+    //    nBlockAlign;       // Decoded sample size; channels * wBitsPerSample / 8
+    //    wBitsPerSample;    // Bits per decoded mono sample; always 16 for XMA
+    //    cbSize;            // Size in bytes of the rest of this structure (34)
+
+    WORD  NumStreams;        // Number of audio streams (1 or 2 channels each)
+    DWORD ChannelMask;       // Spatial positions of the channels in this file,
+                             // stored as SPEAKER_xxx values (see audiodefs.h)
+    DWORD SamplesEncoded;    // Total number of PCM samples the file decodes to
+    DWORD BytesPerBlock;     // XMA block size (but the last one may be shorter)
+    DWORD PlayBegin;         // First valid sample in the decoded audio
+    DWORD PlayLength;        // Length of the valid part of the decoded audio
+    DWORD LoopBegin;         // Beginning of the loop region in decoded sample terms
+    DWORD LoopLength;        // Length of the loop region in decoded sample terms
+    BYTE  LoopCount;         // Number of loop repetitions; 255 = infinite
+    BYTE  EncoderVersion;    // Version of XMA encoder that generated the file
+    WORD  BlockCount;        // XMA blocks in file (and entries in its seek table)
+} XMA2WAVEFORMATEX, *PXMA2WAVEFORMATEX;
+
+typedef struct XMA2STREAMFORMAT
+{
+    BYTE Channels;           // Number of channels in the stream (1 or 2)
+    BYTE RESERVED;           // Reserved for future use
+    WORD ChannelMask;        // Spatial positions of the channels in the stream
+} XMA2STREAMFORMAT;
+
+// Legacy XMA2 format structure (big-endian byte ordering)
+typedef struct XMA2WAVEFORMAT
+{
+    BYTE  Version;           // XMA encoder version that generated the file.
+                             // Always 3 or higher for XMA2 files.
+    BYTE  NumStreams;        // Number of interleaved audio streams
+    BYTE  RESERVED;          // Reserved for future use
+    BYTE  LoopCount;         // Number of loop repetitions; 255 = infinite
+    DWORD LoopBegin;         // Loop begin point, in samples
+    DWORD LoopEnd;           // Loop end point, in samples
+    DWORD SampleRate;        // The file's decoded sample rate
+    DWORD EncodeOptions;     // Options for the XMA encoder/decoder
+    DWORD PsuedoBytesPerSec; // Used internally by the XMA encoder
+    DWORD BlockSizeInBytes;  // Size in bytes of this file's XMA blocks (except
+                             // possibly the last one).  Always a multiple of
+                             // 2Kb, since XMA blocks are arrays of 2Kb packets.
+    DWORD SamplesEncoded;    // Total number of PCM samples encoded in this file
+    DWORD SamplesInSource;   // Actual number of PCM samples in the source
+                             // material used to generate this file
+    DWORD BlockCount;        // Number of XMA blocks in this file (and hence
+                             // also the number of entries in its seek table)
+    XMA2STREAMFORMAT Streams[1]; // Per-stream format information; the actual
+                                 // array length is in the NumStreams field.
+} XMA2WAVEFORMAT;
+
+
+
+inline unsigned xma_le16(unsigned n) {
+    static const int    endianess = 1;
+    if(*(char *)&endianess) return(n);
+    n = (((n & 0xff00) >> 8) |
+         ((n & 0x00ff) << 8));
+    return(n);
+}
+
+inline unsigned xma_le32(unsigned n) {
+    static const int    endianess = 1;
+    if(*(char *)&endianess) return(n);
+    n = (((n & 0xff000000) >> 24) |
+         ((n & 0x00ff0000) >>  8) |
+         ((n & 0x0000ff00) <<  8) |
+         ((n & 0x000000ff) << 24));
+    return(n);
+}
+
+inline unsigned xma_be16(unsigned n) {
+    static const int    endianess = 1;
+    if(!*(char *)&endianess) return(n);
+    n = (((n & 0xff00) >> 8) |
+         ((n & 0x00ff) << 8));
+    return(n);
+}
+
+inline unsigned xma_be32(unsigned n) {
+    static const int    endianess = 1;
+    if(!*(char *)&endianess) return(n);
+    n = (((n & 0xff000000) >> 24) |
+         ((n & 0x00ff0000) >>  8) |
+         ((n & 0x0000ff00) <<  8) |
+         ((n & 0x000000ff) << 24));
+    return(n);
+}
+
+int xma_quick_mask(int chans) { // made on the fly, not important and probably wrong
+    int     i,
+            mask;
+
+    //return(0x80000000);   // SPEAKER_ALL
+    mask = 0;
+    for(i = 0; i < chans; i++) {
+        mask = 1 << 1;
+    }
+    return(mask);
+}
+
+
+
+// XMA1:
+//  fmt
+//  data
+//  seek
+
+int xma1_header(FILE *fd, int freq, int chans, int bits, int rawlen, unsigned char *seek, int seeklen, int samples) {
+    XMAWAVEFORMAT   fmt;
+    mywav_chunk     chunk;
+
+    if(freq  <= 0) freq  = 44100;
+    if(chans <= 0) chans = 1;
+    if(bits  <= 0) bits  = 16;
+    //if(!seek || (seeklen <= 0)) { seek = &samples; seeklen = 4; }
+
+    fmt.FormatTag                       = xma_le16(0x0165);
+    fmt.BitsPerSample                   = xma_le16(bits);
+    fmt.EncodeOptions                   = xma_le16(0x10d6);
+    fmt.LargestSkip                     = xma_le16(0);
+    fmt.NumStreams                      = xma_le16(1);
+    fmt.LoopCount                       = 0;
+    fmt.Version                         = 2;
+
+    fmt.XmaStreams->PsuedoBytesPerSec   = xma_le32(rawlen); // used only by the encoder
+    fmt.XmaStreams->SampleRate          = xma_le32(freq);
+    fmt.XmaStreams->LoopStart           = xma_le32(0);
+    fmt.XmaStreams->LoopEnd             = xma_le32(0);
+    fmt.XmaStreams->SubframeData        = 0;
+    fmt.XmaStreams->Channels            = chans;
+    fmt.XmaStreams->ChannelMask         = xma_le16(xma_quick_mask(chans));
+
+    memcpy(chunk.id, "RIFF", 4);
+    chunk.size =
+        4 + sizeof(mywav_chunk)             // RIFF
+        + sizeof(fmt)                       // fmt
+        + sizeof(mywav_chunk) + rawlen      // data
+        + sizeof(mywav_chunk) + seeklen;    // seek
+
+    if(mywav_fwchunk(fd, &chunk)      < 0) return(-1);
+    if(mywav_fwmem(fd, "WAVE", 4)     < 0) return(-1);
+
+    memcpy(chunk.id, "fmt ", 4);
+    chunk.size = sizeof(fmt) + seeklen;
+    if(mywav_fwchunk(fd, &chunk)      < 0) return(-1);
+    //if(mywav_fwfmtchunk(fd, &fmt)     < 0) return(-1);
+    if(fwrite(&fmt, 1, sizeof(fmt), fd) != sizeof(fmt)) return(-1);
+
+    memcpy(chunk.id, "seek", 4);
+    chunk.size = seeklen;
+    if(mywav_fwchunk(fd, &chunk)      < 0) return(-1);
+    if(fwrite(seek, 1, seeklen, fd) != seeklen) return(-1);
+
+    // data must be placed at the end so that the main tool can write the data after it
+    memcpy(chunk.id, "data", 4);
+    chunk.size = rawlen;
+    if(mywav_fwchunk(fd, &chunk)      < 0) return(-1);
+    return(0);
+}
+
+
+
+// XMA2:
+//  fmt
+//  data
+//  seek
+
+int xma2_header(FILE *fd, int freq, int chans, int bits, int rawlen, unsigned char *seek, int seeklen, int samples) {
+    XMA2WAVEFORMATEX    fmt;
+    mywav_chunk     chunk;
+
+    if(freq  <= 0) freq  = 44100;
+    if(chans <= 0) chans = 1;
+    if(bits  <= 0) bits  = 16;
+    //if(!seek || (seeklen <= 0)) { seek = &samples; seeklen = 4; }
+
+    fmt.wfx.wFormatTag          = xma_le16(0x0166);
+       fmt.wfx.nChannels           = xma_le16(chans);
+       fmt.wfx.nSamplesPerSec      = xma_le32(freq);
+       fmt.wfx.nAvgBytesPerSec     = xma_le32(rawlen); // used only by the encoder
+       fmt.wfx.nBlockAlign         = xma_le16(4);
+       fmt.wfx.wBitsPerSample      = xma_le16(bits);
+       fmt.wfx.cbSize              = xma_le16(34);
+
+    fmt.NumStreams              = xma_le16(1);
+    fmt.ChannelMask             = xma_le32(xma_quick_mask(chans));
+    fmt.SamplesEncoded          = xma_le32(samples);
+    fmt.BytesPerBlock           = xma_le32(0x10000);
+    fmt.PlayBegin               = xma_le32(0);
+    fmt.PlayLength              = xma_le32(samples);
+    fmt.LoopBegin               = xma_le32(0);
+    fmt.LoopLength              = xma_le32(0);
+    fmt.LoopCount               = 0;
+    fmt.EncoderVersion          = 3;    // or 4
+    fmt.BlockCount              = xma_le16(1); 
+
+    memcpy(chunk.id, "RIFF", 4);
+    chunk.size =
+        4 + sizeof(mywav_chunk)             // RIFF
+        + sizeof(fmt)                       // fmt
+        + sizeof(mywav_chunk) + rawlen      // data
+        + sizeof(mywav_chunk) + seeklen;    // seek
+
+    if(mywav_fwchunk(fd, &chunk)      < 0) return(-1);
+    if(mywav_fwmem(fd, "WAVE", 4)     < 0) return(-1);
+
+    memcpy(chunk.id, "fmt ", 4);
+    chunk.size = sizeof(fmt) + seeklen;
+    if(mywav_fwchunk(fd, &chunk)      < 0) return(-1);
+    //if(mywav_fwfmtchunk(fd, &fmt)     < 0) return(-1);
+    if(fwrite(&fmt, 1, sizeof(fmt), fd) != sizeof(fmt)) return(-1);
+
+    memcpy(chunk.id, "seek", 4);
+    chunk.size = seeklen;
+    if(mywav_fwchunk(fd, &chunk)      < 0) return(-1);
+    if(fwrite(seek, 1, seeklen, fd) != seeklen) return(-1);
+
+    // data must be placed at the end so that the main tool can write the data after it
+    memcpy(chunk.id, "data", 4);
+    chunk.size = rawlen;
+    if(mywav_fwchunk(fd, &chunk)      < 0) return(-1);
+    return(0);
+}
+
+
+
+// XMA2xact:
+//  data
+//  XMA2
+//  seek
+
+int xma2xact_header(FILE *fd, int freq, int chans, int bits, int rawlen, unsigned char *seek, int seeklen, int samples) {
+    XMA2WAVEFORMAT  fmt;
+    mywav_chunk     chunk;
+
+    if(freq  <= 0) freq  = 44100;
+    if(chans <= 0) chans = 1;
+    if(bits  <= 0) bits  = 16;
+    //if(!seek || (seeklen <= 0)) { seek = &samples; seeklen = 4; }
+
+    fmt.Version                 = 3;    // or 4
+    fmt.NumStreams              = 1;
+    fmt.RESERVED                = 0;
+    fmt.LoopCount               = 255;
+    fmt.LoopBegin               = xma_be32(0);
+    fmt.LoopEnd                 = xma_be32(samples);
+    fmt.SampleRate              = xma_be32(freq);
+    fmt.EncodeOptions           = xma_be32(0x10d6);
+    fmt.PsuedoBytesPerSec       = xma_be32(rawlen); // used only by the encoder
+    fmt.BlockSizeInBytes        = xma_be32(0x10000);
+    fmt.SamplesEncoded          = xma_be32(samples);
+    fmt.SamplesInSource         = xma_be32(samples);
+    fmt.BlockCount              = xma_be32(1);
+
+    fmt.Streams->Channels       = chans;
+    fmt.Streams->RESERVED       = 0;
+    fmt.Streams->ChannelMask    = xma_be16(xma_quick_mask(chans));
+
+    memcpy(chunk.id, "RIFF", 4);
+    chunk.size =
+        4 + sizeof(mywav_chunk)             // RIFF
+        + sizeof(fmt)                       // fmt
+        + sizeof(mywav_chunk) + rawlen      // data
+        + sizeof(mywav_chunk) + seeklen;    // seek
+
+    if(mywav_fwchunk(fd, &chunk)      < 0) return(-1);
+    if(mywav_fwmem(fd, "WAVE", 4)     < 0) return(-1);
+
+    memcpy(chunk.id, "XMA2", 4);
+    chunk.size = sizeof(fmt) + seeklen;
+    if(mywav_fwchunk(fd, &chunk)      < 0) return(-1);
+    //if(mywav_fwfmtchunk(fd, &fmt)     < 0) return(-1);
+    if(fwrite(&fmt, 1, sizeof(fmt), fd) != sizeof(fmt)) return(-1);
+
+    memcpy(chunk.id, "seek", 4);
+    chunk.size = seeklen;
+    if(mywav_fwchunk(fd, &chunk)      < 0) return(-1);
+    if(fwrite(seek, 1, seeklen, fd) != seeklen) return(-1);
+
+    // data must be placed at the end so that the main tool can write the data after it
+    memcpy(chunk.id, "data", 4);
+    chunk.size = rawlen;
+    if(mywav_fwchunk(fd, &chunk)      < 0) return(-1);
+    return(0);
+}
+
+
diff --git a/tools/gh_xen_decrypt.cc b/tools/gh_xen_decrypt.cc
new file mode 100644 (file)
index 0000000..971c75b
--- /dev/null
@@ -0,0 +1,68 @@
+#include <cstdlib>
+#include <stdexcept>
+#include <fstream>
+#include <iostream>
+
+#define KEY_LEN 11
+
+// Code originaly credited by "Invo" and provided ASIS
+// found here: http://www.scorehero.com/forum/viewtopic.php?t=39923
+// This code code be use to "decrypt" ".xen" files used in at least GH3 PC
+// key should be guessed (xor)
+
+char SwapByteBits(unsigned char cInput) {
+       unsigned char nResult=0;
+
+       for(unsigned int i = 0 ; i < 8 ; i++) {
+               nResult = nResult << 1;
+               nResult |= (cInput & 1);
+               cInput = cInput >> 1;
+       }
+       return nResult;
+}
+
+
+// TODO: use boost iterator to decode in one line
+int main(int argc, char** argv) {
+       unsigned char cpKey[KEY_LEN] = "5atu6w4zaw";
+
+       // Check params
+       if (argc != 3) throw std::runtime_error(std::string("Usage: ") + argv[0] + " <Input> <Output>");
+
+       // Open files
+       std::ofstream outputFile(argv[2], std::ofstream::binary);
+       std::ifstream inputFile(argv[1], std::ios::binary);
+
+       // Get the file size
+       inputFile.seekg (0, std::ios::end);
+       unsigned int fileSize = inputFile.tellg();
+       inputFile.seekg (0, std::ios::beg);
+
+       // Allocate buffer
+       char *pBuffer = new char[fileSize];
+
+       // Reading inputfile
+       std::cout << "Reading input file (" << fileSize << " Bytes)... ";
+       inputFile.read(pBuffer, fileSize);
+       inputFile.close();
+       std::cout << "DONE!" << std::endl;
+
+       // Decrypt
+       std::cout << "Decrypting... ";
+       char *pInput = pBuffer;
+       for (unsigned int nLoopIdx = 0 ; nLoopIdx < fileSize ; nLoopIdx++) {
+               *pInput = SwapByteBits(*pInput ^ cpKey[nLoopIdx % (KEY_LEN-1)]);
+               pInput++;
+       }
+       std::cout << "DONE!" << std::endl;
+
+       // Write the output
+       std::cout << "Writing outpout file... ";
+       outputFile.write(pBuffer, fileSize);
+       outputFile.close();
+       delete [] pBuffer;
+       std::cout << "DONE!" << std::endl;
+
+       return EXIT_SUCCESS;
+}
+
diff --git a/tools/ipu_conv.cc b/tools/ipu_conv.cc
new file mode 100644 (file)
index 0000000..c71a23c
--- /dev/null
@@ -0,0 +1,368 @@
+#include "ipuconv.hh"
+#include <iostream>
+#include <stdexcept>
+
+IPUConv::IPUConv(std::vector<char> const& indata, std::string const& outfilename, bool pal): infile(indata), outfile(outfilename.c_str()) {
+       int sizex;
+       int sizey;
+       int frames;
+       int frame;
+       int dct_dc_y;
+       int dct_dc_cb;
+       int dct_dc_cr;
+       int quant;
+       int flag;
+       int mb;
+       int mb_source;
+       int intraquant;
+       int block;
+       int eob;
+       int size;
+       int diff = 0;
+       int absval;
+       long int FrameByte;
+       unsigned int FrameBit;
+
+       if (0x6970756d != infile.get(32)) throw std::runtime_error("Input data is no IPU");
+
+       infile.get(32); // Filesize
+
+       sizex=infile.get(8);
+       sizex=sizex+infile.get(8)*(1<<8);
+
+       sizey=infile.get(8);
+       sizey=sizey+infile.get(8)*(1<<8);
+
+       frames=infile.get(8);
+       frames=frames+infile.get(8)*(1<<8);
+       frames=frames+infile.get(8)*(1<<16);
+       frames=frames+infile.get(8)*(1<<24);
+
+       printf("%dx%d\n",sizex,sizey);
+       printf("%02d:%02d:%02d.%02d\n\n",frames/25/60/60,(frames%(25*60*60))/25/60,(frames%(25*60))/25,frames%25);
+
+       std::vector<t_MBData> MBData((sizex/16)*(sizey/16)+1);
+       for (frame=0;frame<frames;frame++){
+               if (frame % 100 == 0) std::cout << "Frame: " << frame << "/" << frames << "\r" << std::flush;
+               flag = infile.get(8);
+
+               if (flag & 32) {
+                       fprintf (stderr,"Intra VLC format not supported\n");
+                       exit(1);
+               }
+               if (frame==0) {
+                       // Write Sequence Header
+                       outfile.putbits(0x1b3,32);
+                       outfile.putbits(sizex,12);
+                       outfile.putbits(sizey,12);
+                       outfile.putbits(0x1,4);                 // Ascpect Ratio        1     1:1
+                                                                       //                                      2     4:3
+                                                                       //                                      3    16:9
+                                                                       //                                      4  2.21:1
+
+                       if(pal) {
+                               outfile.putbits(0x3,4);                 // Framerate            3  25 fps
+                       } else {
+                               outfile.putbits(0x4,4);                 // Framerate            4  29.97 fps
+                       }
+
+                       outfile.putbits(0x30d4,18);     // Bitrate ($3FFFF=Variabel)
+                       outfile.putbits(1,1);                   // Marker, soll immer 1 sein
+                       outfile.putbits(112,10);                // VBV
+                       outfile.putbits(0,1);                   // Constrained Parameter Flag
+                       outfile.putbits(0,1);                   // Intra Matrix Standard
+                       outfile.putbits(0,1);                   // Non-Intra Matrix Standard
+                       //outfile.putbits(0x2cee100,32);
+
+                       if (!(flag & 128)) {
+                               // Sequence Extension
+                               outfile.putbits(0x1b5,32);
+                               outfile.putbits(0x1,4);         // Start Code Identifier
+                               outfile.putbits(0x4,4);         // Main Profil
+                               outfile.putbits(0x8,4);         // Main Level
+                               outfile.putbits(0x1,1);         // Progressive Sequence
+                               outfile.putbits(0x1,2);         // Chroma Format 4:2:0
+                               outfile.putbits(0x0,2);         // Breite Extension
+                               outfile.putbits(0x0,2);         // Höhe Extension
+                               outfile.putbits(0x0,12);        // Bitrate Extension
+                               outfile.putbits(0x1,1);         // Marker
+                               outfile.putbits(0x0,8);         // VBV Buffer Extension
+                               outfile.putbits(0x0,1);         // Low Delay
+                               outfile.putbits(0x0,2);         // Framerate Extension Numerator
+                               outfile.putbits(0x0,5);         // Framerate Extension Denominator
+                               //outfile.putbits(0x148a0001,32);
+                               //outfile.putbits(0,16);
+
+                               // Sequence Display Extension
+                               /*
+                               outfile.putbits(0x1b5,32);
+                               outfile.putbits(0x2,4);         // Start Code Identifier
+                               outfile.putbits(0x1,3);         // Video Format         1 PAL
+                               outfile.putbits(0x0,1);         // Bit Color
+
+                               outfile.putbits(0x23050504,32);
+
+                               outfile.putbits(sizex,14);      // Display Breite
+                               outfile.putbits(1,1);           // Marker
+                               outfile.putbits(sizey,14);  // Display Höhe
+                               outfile.putbits(0,3);
+                               */
+                       }
+               }
+
+               // Write GOP Header
+               outfile.putbits(0x1b8,32);
+               outfile.putbits(0,1);                           // Drop Frame
+               outfile.putbits(frame/25/60/60,5);      // Stunden
+               outfile.putbits((frame%(25*60*60))/25/60,6); // Minuten
+               outfile.putbits(1,1);                           // Marker
+               outfile.putbits((frame%(25*60))/25,6);// Sekunden
+               outfile.putbits(frame%25,6);            // Frames
+               outfile.putbits(1,1);                           // Closed GOP
+               outfile.putbits(0,6);
+
+               // Write Picture Header
+               outfile.putbits(0x100,32);
+               outfile.putbits(0x0,10);                        // Temporal Reference
+               outfile.putbits(0x1,3);                         // Coding Type Intra
+               outfile.putbits(0xffff,16);                     // VBV Delay
+               outfile.putbits(0,3);
+//             outfile.putbits(0xffff8,32);
+
+               // Write Picture Coding Extension
+               if (!(flag & 128)) {
+                       outfile.putbits(0x1b5,32);
+                       outfile.putbits(0x8ffff,20);
+                       outfile.putbits(flag&3,2);                      // Intra DC Precision
+                       outfile.putbits(3,2);                           // Frame Picture
+                       outfile.putbits(2,3);
+                       outfile.putbits((flag&64)/64,1);        // QST
+                       outfile.putbits(0,1);                           // Intra VLC Format
+                       outfile.putbits((flag&16)/16,1);        // Alternate Scan
+                       outfile.putbits(1,2);
+                       outfile.putbits(0x80,8);
+               }
+               // Write Slice Header
+               outfile.putbits(0x1,24);
+               outfile.putbits(1,8);
+               outfile.putbits(1,5);           // Quantiser
+               outfile.putbits(0,1);           // Extra Bit clear
+
+               // infile.get Macroblock-infos
+               dct_dc_y = 0;
+               dct_dc_cb = 0;
+               dct_dc_cr = 0;
+               quant = 1;
+               for(mb=0;mb<(sizex/16)*(sizey/16);mb++) {
+                       if (mb>0 && !infile.get(1)) throw std::runtime_error("MBA_Incr wrong in IPU");
+                       // Save position (in IPU) of Macroblock
+                       infile.getpos(&MBData[mb].Byte,&MBData[mb].Bit);
+
+                       if (infile.get(1)) intraquant = 0;
+                       else {
+                               if (!infile.get(1)) throw std::runtime_error("MBT wrong in IPU");
+                               intraquant = 1;
+                       }
+
+                       if (flag & 4) infile.get(1);
+                       if (intraquant) quant = infile.get(5);
+                       MBData[mb].quant = quant;
+
+                       for(block=0;block<6;block++) {
+                               if (block<4) {
+                                       if ( (size = infile.get_dcs_y())) {
+                                               diff = infile.get(size);
+                                               if (!(diff & (1 << (size - 1)))) diff = (-1 << size) | (diff + 1);
+                                               dct_dc_y += diff;
+                                       }
+                                       if (block==0) MBData[mb].dct_dc_y = dct_dc_y;
+                               } else {
+                                       if ( (size = infile.get_dcs_c())) {
+                                               diff = infile.get(size);
+                                               if (!(diff & (1 << (size - 1)))) diff = (-1 << size) | (diff + 1);
+                                       }
+                                       if (block==4) {
+                                               if (size) dct_dc_cb += diff;
+                                               MBData[mb].dct_dc_cb = dct_dc_cb;
+                                       } else {
+                                               if (size) dct_dc_cr += diff;
+                                               MBData[mb].dct_dc_cr = dct_dc_cr;
+                                       }
+                               }
+                               do {
+                                       eob = vlc(0);
+                                       if (eob == 0) infile.get(1);
+                                       } while (eob!=1);
+                       }
+               }
+
+               infile.getpos(&FrameByte,&FrameBit);    // Position speichern
+
+               // Write Macroblocks
+               dct_dc_y = 0;
+               dct_dc_cb = 0;
+               dct_dc_cr = 0;
+               quant = 1;
+               for(mb=0;mb<(sizex/16)*(sizey/16);mb++) {
+                       mb_source = (mb % (sizex / 16)) * (sizey / 16)+ mb / (sizex / 16);      // Singstar
+                       // mb_source = mb;                                                      // Other IPUs
+
+                       outfile.putbits(1,1);           // MBA_Incr=1
+
+                       infile.setpos(MBData[mb_source].Byte,MBData[mb_source].Bit);
+
+                       if (infile.get(1)) intraquant = 0;
+                       else {
+                               if (!infile.get(1)) throw std::runtime_error("MBT wrong in IPU");
+                               intraquant = 1;
+                       }
+
+                       if (mb == 0 || (MBData[mb_source].quant != quant)) outfile.putbits(1,2);
+                       else outfile.putbits(1,1);
+
+                       if (flag & 4) outfile.putbits(infile.get(1),1);
+                       if (intraquant) quant = infile.get(5);
+
+                       if (mb == 0 || (MBData[mb_source].quant != quant)) {
+                               outfile.putbits(MBData[mb_source].quant,5);
+                               quant = MBData[mb_source].quant;
+                       }
+
+                       for(block=0;block<6;block++) {
+                               if (block==0) {
+                                       infile.get(infile.get_dcs_y()); // DCT_DC in Eingabestream überspringen
+                                       diff = MBData[mb_source].dct_dc_y - dct_dc_y;
+                                       dct_dc_y = MBData[mb_source].dct_dc_y;
+
+                                       absval = (diff<0) ? -diff : diff; /* abs(val) */
+                                       size = 0;
+                                       while (absval) {
+                                               absval >>= 1;
+                                               size++;
+                                       }
+                                       outfile.put_dcs_y(size);
+                                       absval = diff;
+                                       if (absval<=0)
+                                               absval += (1<<size) -1;
+                                       outfile.putbits(absval,size);
+                               } else if (block>3)     {
+                                       infile.get(infile.get_dcs_c()); // DCT_DC in Eingabestream überspringen
+                                       if (block==4) {
+                                               diff = MBData[mb_source].dct_dc_cb - dct_dc_cb;
+                                               dct_dc_cb = MBData[mb_source].dct_dc_cb;
+                                       } else {
+                                               diff = MBData[mb_source].dct_dc_cr - dct_dc_cr;
+                                               dct_dc_cr = MBData[mb_source].dct_dc_cr;
+                                       }
+                                       absval = (diff<0) ? -diff : diff; /* abs(val) */
+                                       size = 0;
+                                       while (absval) {
+                                               absval >>= 1;
+                                               size++;
+                                       }
+                                       outfile.put_dcs_c(size);
+                                       absval = diff;
+                                       if (absval<=0)
+                                               absval += (1<<size) -1;
+                                       outfile.putbits(absval,size);
+                               } else {
+                                       size = infile.get_dcs_y();
+                                       outfile.put_dcs_y(size);
+                                       diff = infile.get(size);
+                                       outfile.putbits(diff,size);             // DCT_DC kopieren (Blöcke 1,2,3)
+                                       if (size) {
+                                               if (!(diff&(1<<(size - 1))))
+                                                       diff = (-1 << size) | (diff + 1);
+                                               dct_dc_y += diff;
+                                       }
+                               }
+                               do {
+                                       eob = vlc(1);
+                                       if (eob == 0)
+                                               outfile.putbits(infile.get(1),1);
+                               } while (eob!=1);
+                       }
+               }
+               outfile.putbuf();
+
+               infile.setpos(FrameByte,FrameBit);
+
+               // Jump to End of Frame
+               if (!infile.next_start_code()) throw std::runtime_error("End of Stream");
+               if (infile.get(32) != 0x000001b0) throw std::runtime_error("No 1b0");
+       }
+
+       outfile.putbits(0x1b7,32);              // Ende
+}
+
+int IPUConv::vlc(int write){
+       int bits;
+       int level=0;
+
+       bits = infile.get(2);
+       if (write) outfile.putbits(bits,2);
+       if(bits ==      2)
+               return(1);              // 10 - EOB
+       if(bits ==      3)
+               return(0);              // 11
+       if(bits ==      1) {
+               bits = infile.get(1);
+               if (write) outfile.putbits(bits,1);
+               if (bits)
+                       return(0);
+               else {
+                       bits = infile.get(1);
+                       if (write) outfile.putbits(bits,1);
+                       return(0);
+               }
+       }
+       // 00
+       bits = infile.get(1);
+       if (write) outfile.putbits(bits,1);
+       if (bits) {
+               // 001
+               bits = infile.get(2);
+               if (write) outfile.putbits(bits,2);
+               if (bits < 1) {
+                       // 00100
+                       bits = infile.get(3);
+                       if (write) outfile.putbits(bits,3);
+               }
+               // 001xx
+               return(0);
+       } else {
+       // 000
+               bits = infile.get(3);
+               if (write) outfile.putbits(bits,3);
+               if(bits >=      4)
+                       return(0);
+               if(bits >=      2) {
+                       bits = infile.get(1);
+                       if (write) outfile.putbits(bits,1);
+                       return(0);
+               }
+               if(bits) {
+                       bits = infile.get(18);
+                       if (write) outfile.putbits(bits,18);
+                       return(2);      // Escape
+               }
+               bits = infile.get(1);
+               if (write) outfile.putbits(bits,1);
+               if(bits) {
+                       bits = infile.get(3);
+                       if (write) outfile.putbits(bits,3);
+                       return(0);
+               }
+               do {
+                       bits = infile.get(1);
+                       if (write) outfile.putbits(bits,1);
+                       level++;
+               } while (!bits && level<6);
+               if (level<6) {
+                       bits = infile.get(4);
+                       if (write) outfile.putbits(bits,4);
+                       return(0);
+               } else throw std::runtime_error("Invalid VLC");
+       }
+}
+
diff --git a/tools/ipuconv.hh b/tools/ipuconv.hh
new file mode 100644 (file)
index 0000000..da11a45
--- /dev/null
@@ -0,0 +1,20 @@
+#include "bitfiles.h"
+
+struct t_MBData                /*      Macroblock data */
+{
+       long int Byte;
+       unsigned int Bit;
+       int dct_dc_y;
+       int dct_dc_cb;
+       int dct_dc_cr;
+       int quant;
+};
+
+class IPUConv {
+       inBitFile infile;
+       outBitFile outfile;
+       int vlc(int write);
+  public:
+       IPUConv(std::vector<char> const& indata, std::string const& outfilename, bool pal = true);
+};
+
diff --git a/tools/ipuconvmain.cc b/tools/ipuconvmain.cc
new file mode 100644 (file)
index 0000000..b7d2152
--- /dev/null
@@ -0,0 +1,25 @@
+#include "ipuconv.hh"
+#include <cstdio>
+#include <iostream>
+#include <stdexcept>
+
+int main(int argc, char** argv) {
+       if (argc<3){
+               std::printf("\nConverts an Singstar IPU-movie into an MPEG-Video\n20080103 - hawkear@gmx.de\n\n"
+                       "Usage:     %s <INFILE> <OUTFILE>\n\n"
+                       "Example:   %s movie.ipu myvideo.m2v\n\n",argv[0],argv[0]);
+               exit(0);
+       }
+       std::vector<char> indata;
+       std::ifstream infile(argv[1], std::ios::binary);
+       infile.seekg(0, std::ios::end);
+       indata.resize(infile.tellg());
+       infile.seekg(0);
+       infile.read(&indata[0], indata.size());
+       try {
+               IPUConv(indata, argv[2]);
+       } catch (std::exception& e) {
+               std::cerr << "Error: " << e.what() << std::endl;
+       }
+}
+
diff --git a/tools/itg_pck.cc b/tools/itg_pck.cc
new file mode 100644 (file)
index 0000000..0dbe4cf
--- /dev/null
@@ -0,0 +1,115 @@
+#include <boost/filesystem.hpp>
+#include <algorithm>
+#include <fstream>
+#include <iostream>
+#include <sstream>
+#include <stdexcept>
+#include <string>
+
+template <typename It> void test(It it, std::string text) {
+       if (!std::equal(text.begin(), text.end(), it)) throw std::runtime_error("PCKF header missing");
+}
+
+template <typename It> std::string read(It it, unsigned chars) {
+       std::string ret;
+       while (chars--) ret += *it++;
+       return ret.substr(0, ret.find_last_not_of('\0') + 1);
+}
+
+template <typename It> unsigned read32(It it) {
+       unsigned ret = 0;
+       for (unsigned i = 0; i < 4; ++i) ret |= static_cast<unsigned char>(*it++) << i * 8;
+       return ret;
+}
+
+namespace fs = boost::filesystem;
+
+struct File {
+       fs::path name;
+       unsigned size;
+       unsigned sizeCompressed;
+       unsigned mode; // 0 = stored, 1 = compressed
+       unsigned offset;
+};
+
+#include <zlib.h>
+
+struct Extract {
+       std::ifstream& archive;
+       Extract(std::ifstream& archive): archive(archive) {}
+       void operator()(File const& file) {
+               std::cout << "  " << file.name << " " << file.size << " at " << file.offset << std::endl;
+               if (file.mode == 1) std::cout << "    " << file.size << "->" << file.sizeCompressed << std::endl;
+               std::vector<char> buffer(file.sizeCompressed);
+               archive.seekg(file.offset);
+               archive.read(&buffer[0], buffer.size());
+               std::string ext;
+               if (file.mode == 1) {
+                       std::vector<char> buf2(file.size);
+                       z_stream strm = z_stream();
+                       strm.avail_in = buffer.size();
+                       strm.next_in = reinterpret_cast<Bytef*>(&buffer[0]);
+                       strm.avail_out = buf2.size();
+                       strm.next_out = reinterpret_cast<Bytef*>(&buf2[0]);
+                       
+                       inflateInit2(&strm, -15);
+                       int ret = inflate(&strm, Z_SYNC_FLUSH);
+                       inflateEnd(&strm);
+                       std::cout << ret << std::endl;
+                       if (ret == Z_STREAM_END) buf2.swap(buffer);
+                       else {
+                               std::ostringstream oss;
+                               oss << ".comp-" << file.size;
+                               ext = oss.str();
+                       }
+                       if (strm.msg) std::cerr << "    Error: " << strm.msg << std::endl;
+               }
+               // Make directory
+               makeDir(file.name);
+               std::ofstream of((file.name.string() + ext).c_str(), std::ios::binary);
+               of.write(&buffer[0], buffer.size());
+       }
+       void makeDir(fs::path p) {
+               p.remove_filename();
+               if (p.empty()) return;
+               makeDir(p);
+               fs::create_directory(p);
+       }
+};
+
+int main(int argc, char** argv) {
+       if (argc != 2) throw std::logic_error("Need pck filename as argument");
+       std::ifstream f(argv[1], std::ios::binary);
+       f.exceptions(std::ios::failbit);
+       std::istreambuf_iterator<char> it(f), end;
+       // PCKF header:
+       // 17 bytes "PCKFdefault base "
+       // Name (title) of the package, padded with zeroes until offset 0x84
+       // Little-endian u32 file count
+       test(it, "PCKFdefault base ");
+       std::string title = read(it, 0x73);
+       std::cout << "Title: " << title << std::endl;
+       unsigned filecount = read32(it);
+       std::cout << filecount << " files:" << std::endl;
+       std::vector<File> files;
+       while (files.size() < filecount) {
+               // File entry: (array of filecount file entries)
+               // Little-endian u32: size of compressed/stored data
+               // Little-endian u32: size of uncompressed data
+               // Little-endian u32: position in pck file (in bytes)
+               // Little-endian u32: name length (in bytes)
+               // char[namelen]: file name with path, uses '/' as path separator
+               // Little-endian u32: compression mode (0 = stored, 1 = deflated)
+               File file;
+               file.sizeCompressed = read32(it);
+               file.size = read32(it);
+               file.offset = read32(it);
+               unsigned namelen = read32(it);
+               file.mode = read32(it);
+               file.name = fs::path(title) / read(it, namelen);
+               files.push_back(file);
+       }
+       std::cout << "Header ends at " << f.tellg() << std::endl;
+       std::for_each(files.begin(), files.end(), Extract(f));
+}
+
diff --git a/tools/pak.cc b/tools/pak.cc
new file mode 100644 (file)
index 0000000..988b8b9
--- /dev/null
@@ -0,0 +1,127 @@
+#include "pak.h"
+
+#include <algorithm>
+#include <cstring>
+#include <iomanip>
+#include <iostream>
+#include <iterator>
+#include <sstream>
+
+std::ostream& operator<<(std::ostream& os, std::pair<std::string, PakFile> const& f) {
+       std::stringstream ss;
+       ss << std::setbase(16) << std::setfill('0');
+       ss << "0x" << std::setw(8) << f.second.offset << ' ';
+       ss << "0x" << std::setw(8) << f.second.offset + f.second.size << ' ';
+       ss << f.first << "  " << std::setbase(10);
+       if (f.second.zlibmode) ss << f.second.zlibsize << " bytes compressed into "; 
+       ss << f.second.size << " bytes";
+       return os << ss.rdbuf() << std::endl;
+}
+
+std::ostream& operator<<(std::ostream& os, Pak::files_t const& files) {
+       std::copy(files.begin(), files.end(), std::ostream_iterator<std::pair<std::string, PakFile> >(os));
+       return os;
+}
+
+namespace {
+       template <unsigned Bytes> unsigned readLE(std::istream& is) {
+               unsigned val = 0;
+               for (unsigned i = 0; i < Bytes; ++i) val |= (unsigned char)is.get() << i * 8;
+               return val;
+       }
+       template <unsigned Bytes> unsigned readBE(std::istream& is) {
+               unsigned val = 0;
+               for (unsigned i = 0; i < Bytes; ++i) val = (val << 8) | (unsigned char)is.get();
+               return val;
+       }
+}
+
+Pak::Pak(std::string const& filename) {
+       std::ifstream f(filename.c_str(), std::ios::binary);
+       if (!f.is_open()) throw std::runtime_error("Could not open PAK file " + filename);
+       f.exceptions(std::ios::failbit);
+       enum Format { PAK, PAK_WITH_CRC, PKF, PKD } format;
+       {
+               char magic[8];
+               f.read(magic, sizeof(magic));
+               if (!std::memcmp(magic, "SceeWhPC", sizeof(magic))) format = PAK_WITH_CRC;
+               else if (!std::memcmp(magic, "SceeWhPk", sizeof(magic))) format = PAK;
+               else if (!std::memcmp(magic, "PACKAGE ", sizeof(magic))) format = PKD;
+               else if (!std::memcmp(magic, "\x7e\x26\x4c\x33\x24\x53\x9b\xd0", sizeof(magic))) format = PKF;
+               else throw std::runtime_error("Not a valid PAK/PKF/PKD file (" + std::string(magic) + ")");
+       }
+       switch (format) {
+               case PKF: throw std::runtime_error("SingStar PS3 encrypted pkd format is not yet supported.");
+               case PKD:
+               {
+                       // We do not know what these bytes stand for but they always seem to be the same
+                       if (readBE<4>(f) != 0x01000000 || readBE<2>(f) != 0x0007) throw std::runtime_error("Unexpected header bytes.");
+                       unsigned headerEnd = readBE<4>(f);
+                       while (f.tellg() < headerEnd) {
+                               PakFile file(filename);
+                               file.crc = readBE<4>(f);  // Random digits (maybe CRC32)
+                               std::string name;
+                               std::getline(f, name, '\0');
+                               file.offset = readBE<4>(f);
+                               file.size = readBE<4>(f);
+                               std::replace(name.begin(), name.end(), '\\', '/');
+                               std::size_t pos = f.tellg();
+                               if (file.size > 12) {
+                                       f.seekg(file.offset);
+                                       char magic[4];
+                                       f.read(magic, sizeof(magic));
+                                       if (!std::memcmp(magic, "ZLIB", sizeof(magic))) {
+                                               file.zlibmode = readBE<4>(f);
+                                               file.zlibsize = readBE<4>(f);
+                                               file.offset += 12;
+                                               file.size -= 12;
+                                       }
+                                       f.seekg(pos);
+                               }
+                               m_files.insert(std::make_pair(name, file));
+                       }
+                       break;
+               }
+               case PAK: case PAK_WITH_CRC:
+               {
+                       f.seekg(0x114);
+                       std::vector<std::string> ext;
+                       while(1) {
+                               char tmp[4];
+                               f.read(tmp,4);
+                               if(tmp[0] == '\0')
+                                       break;
+                               ext.push_back(std::string(tmp));
+                       }
+                       f.seekg(0x198);
+                       std::string name;
+                       PakFile file(filename);
+                       while ((file.offset = readLE<3>(f)) > 0) {
+                               name = name.substr(0, readLE<1>(f));  // Previous filename used as template
+                               file.offset *= 0x800;
+                               char string_length = readLE<1>(f);
+                               f.ignore(2);
+                               file.size = readLE<4>(f);
+                               if (format == PAK_WITH_CRC) file.crc = readLE<4>(f);
+                               char tmp[256];
+                               f.read(tmp, string_length - 1);
+                               name += std::string(tmp, string_length - 1);
+                               unsigned ext_idx = readLE<1>(f);
+                               char toto[2];
+                               toto[0] = '0' + ext.size();
+                               toto[1] = '\0';
+                               if (ext_idx) name += std::string(".") + (ext_idx <= ext.size() ? ext[ext_idx-1] : std::string(toto));
+                               std::replace(name.begin(), name.end(), '\\', '/');
+                               m_files.insert(std::make_pair(name, file));
+                       }
+                       break;
+               }
+       }
+}
+
+PakFile const& Pak::operator[](std::string const& filename) const {
+       files_t::const_iterator r = m_files.find(filename);
+       if (r == m_files.end()) throw std::runtime_error("File not found: " + filename);
+       return r->second;
+}
+
diff --git a/tools/pak.h b/tools/pak.h
new file mode 100644 (file)
index 0000000..5aba47f
--- /dev/null
@@ -0,0 +1,54 @@
+#pragma once
+
+#include "zlib.h"
+#include <boost/cstdint.hpp>
+#include <string>
+#include <fstream>
+#include <map>
+#include <vector>
+#include <stdexcept>
+
+struct PakFile {
+       PakFile(std::string const& pakfilename): pakname(pakfilename), offset(), size(), crc(), zlibmode(), zlibsize() {}
+       std::string pakname;
+       unsigned offset;
+       unsigned size;
+       unsigned crc;
+       unsigned zlibmode;
+       unsigned zlibsize;
+       void get(std::vector<char>& buf, unsigned int pos = 0, unsigned int s = 0) const {
+               if (!s) s = size - pos;
+               if (pos + s > size) throw std::logic_error("Trying to read past end of file");
+               buf.resize(s);
+               std::ifstream f(pakname.c_str(), std::ios::binary);
+               f.seekg(offset + pos);
+               f.read(&buf[0], s);
+               if (zlibmode) {
+                       if (pos != 0 || s != size) throw std::logic_error("Cannot seek in zlib deflated files");
+                       std::vector<char> buf2(zlibsize);
+                       z_stream strm = z_stream();
+                       strm.avail_in = buf.size(); strm.next_in = reinterpret_cast<Bytef*>(&buf[0]);
+                       strm.avail_out = buf2.size(); strm.next_out = reinterpret_cast<Bytef*>(&buf2[0]);
+                       inflateInit(&strm);
+                       int ret = inflate(&strm, Z_SYNC_FLUSH);
+                       inflateEnd(&strm);
+                       if (ret == Z_STREAM_END) buf2.swap(buf);
+                       else if (strm.msg) throw std::runtime_error(std::string("Zlib inflate failed: ") + strm.msg);
+               }
+               // TODO: Unduplicate code with itg_pck! (e.g. use PakFile structure there as well)
+       }
+};
+
+class Pak {
+  public:
+       typedef std::map<std::string, PakFile> files_t;
+       Pak(std::string const& filename);
+       files_t const& files() const { return m_files; }
+       PakFile const& operator[](std::string const& filename) const;
+  private:
+       files_t m_files;
+};
+
+std::ostream& operator<<(std::ostream& os, PakFile const& f);
+std::ostream& operator<<(std::ostream& os, Pak::files_t const& files);
+
diff --git a/tools/pak_extract.cc b/tools/pak_extract.cc
new file mode 100644 (file)
index 0000000..b29bd7d
--- /dev/null
@@ -0,0 +1,71 @@
+#include "pak.h"
+#include <boost/filesystem.hpp>
+#include <algorithm>
+#include <cstring>
+#include <functional>
+#include <iostream>
+#include <iterator>
+#include <stdexcept>
+
+namespace {
+       void usage(char const* progname) {
+               std::cerr << "Usage: " << progname << " file.pak --extract [files]" << std::endl;
+               std::cerr << "       " << progname << " file.pak --dump file" << std::endl;
+               std::cerr << "       " << progname << " file.pak --list" << std::endl;
+       }
+
+       struct Extract {
+               Extract(Pak& p): m_p(p) {}
+               void operator()(std::string const& filename) { operator()(make_pair(filename, m_p[filename])); }
+               void operator()() {
+                       for (Pak::files_t::const_iterator it = m_p.files().begin(); it != m_p.files().end(); ++it) operator()(*it);
+               }
+               void operator()(std::pair<std::string, PakFile> const& fp) {
+                       std::string filename = fp.first;
+                       // Remove path elements from m_path until it matches the filename's beginning
+                       while (m_path != filename.substr(0, m_path.size())) {
+                               std::string::size_type pos = m_path.rfind('/');
+                               if (pos == std::string::npos) m_path.clear();
+                               else m_path.erase(pos);
+                       }
+                       // Try to create new folders as required
+                       for (std::string::size_type pos; (pos = filename.find('/', m_path.size() + 1)) != std::string::npos;) {
+                               m_path = filename.substr(0, pos);
+                               boost::filesystem::create_directory(m_path);
+                       }
+                       // Extract the file
+                       std::ofstream f(filename.c_str(), std::ios::binary);
+                       if (!f.is_open()) throw std::runtime_error("Unable to create file: " + filename);
+                       std::cout << filename << std::flush;
+                       std::vector<char> buf;
+                       fp.second.get(buf);
+                       f.write(&buf[0], buf.size());
+                       std::cout << "  " << buf.size() << " bytes" << std::endl;
+               }
+         private:
+               Pak& m_p;
+               std::string m_path;
+       };
+}
+
+int main(int argc, char** argv) {
+       std::ios::sync_with_stdio(false);
+       if( argc < 3 ) { usage(argv[0]); return EXIT_FAILURE; }
+       try {
+               Pak p(argv[1]);
+               if (!strcmp(argv[2],"--list")) std::cout << p.files();
+               else if (!strcmp(argv[2],"--dump")) {
+                       if (argc != 4) { usage(argv[0]); return EXIT_FAILURE; }
+                       std::vector<char> buf;
+                       p[argv[3]].get(buf);
+                       std::cout.write(&buf[0], buf.size());
+               } else if (!strcmp(argv[2],"--extract")) {
+                       if (argc == 3) { (Extract(p))(); }
+                       else std::for_each(argv + 3, argv + argc, Extract(p));
+               } else { usage(argv[0]); return EXIT_FAILURE; }
+       } catch (std::exception& e) {
+               std::cerr << "Error: " << e.what() << std::endl;
+               return EXIT_FAILURE;
+       }
+}
+
diff --git a/tools/ppa/control.patch b/tools/ppa/control.patch
new file mode 100644 (file)
index 0000000..1de35d8
--- /dev/null
@@ -0,0 +1,6 @@
+--- debian/control
++++ debian/control
+@@ -7,2 +7,3 @@
+  cmake (>= 2.6), pkg-config, quilt, help2man, gettext,
++ libportmidi-dev, libcv-dev, libhighgui-dev,
+  libgl1-mesa-dev, libsdl1.2-dev, libcairo2-dev, librsvg2-dev,
diff --git a/tools/ppa/ppa.sh b/tools/ppa/ppa.sh
new file mode 100755 (executable)
index 0000000..34a01ba
--- /dev/null
@@ -0,0 +1,121 @@
+#!/bin/bash
+# This script fetches fresh git version, applies
+# the changes on top of the current source package
+# from the repositories, builds and signs the new
+# package and uploads it to Launchpad PPA.
+
+#TODO: better changelog (from git?)
+
+
+set -e   # Exit on fail
+
+# Assume default GPG key setup and use it for name & email.
+# Export the vars because the tools use these magic variables also.
+export DEBFULLNAME="`gpg --list-keys | grep uid | sed 's/ <.*//; s/.*uid *//'`"
+export DEBEMAIL="`gpg --list-keys | grep uid | sed 's/ *(.*)//; s/>.*//; s/.*[:<] *//'`"
+
+# Config
+PKG="performous"
+VERSIONCOMMON="0.6.1-99+git"`date '+%Y%m%d'`"~ppa1"
+BASEPKGVERSION="0.6.1" # base version of the base package
+BASEPKGADD="-1" # additional version suffix of the base package
+BASEURL="http://archive.ubuntu.com/ubuntu/pool/universe/p/performous"
+SUITES="lucid maverick natty"
+GITURL="git://git.performous.org/gitroot/performous/performous"
+DESTINATIONPPA="ppa:performous-team/ppa"
+
+TEMPDIR=`mktemp -dt $PKG-ppa.XXXXXXXXXX`
+SOURCEDIR="$TEMPDIR/git"
+PPAPATCHDIR="`pwd`"
+
+       # Print a status message
+       status()
+       {
+               echo -e "\e[0;31m"$@"\e[0m"
+       }
+
+       # Copy the new files for source package
+       CopyNewFiles()
+       {
+               COPYCMD="cp -r"
+               $COPYCMD "$1/CMakeLists.txt" "$2"
+               $COPYCMD "$1/README.txt" "$2"
+               $COPYCMD "$1/cmake" "$2"
+               $COPYCMD "$1/data" "$2"
+               $COPYCMD "$1/docs" "$2"
+               $COPYCMD "$1/game" "$2"
+               $COPYCMD "$1/lang" "$2"
+               $COPYCMD "$1/themes" "$2"
+               $COPYCMD "$1/tools" "$2"
+       }
+
+cd "$TEMPDIR"
+status "Tempdir: `pwd`"
+
+# Figure out the version of the "old" official package
+status "Working on $PKG ${BASEPKGVERSION}${BASEPKGADD}"
+
+mkdir -p $PKG-$BASEPKGVERSION
+cd $PKG-$BASEPKGVERSION
+
+# Download the "old" source package we use as a base
+wget $BASEURL/${PKG}_${BASEPKGVERSION}${BASEPKGADD}.dsc
+wget $BASEURL/${PKG}_${BASEPKGVERSION}.orig.tar.bz2
+wget $BASEURL/${PKG}_${BASEPKGVERSION}${BASEPKGADD}.debian.tar.bz2
+
+# Download fresh version from git
+status "Fetch from git..."
+git clone "$GITURL" "$SOURCEDIR"
+
+# Get some info from git for changelog
+(
+       cd "$SOURCEDIR"
+       # 10 chars from the HEAD commit hash
+       headcommit=`git log | head -n 1 | cut --delimiter=" " -f 2 | cut -c 1-10`
+)
+
+# Loop suites
+status "Do each suite..."
+for suite in $SUITES ; do
+       newversion="${VERSIONCOMMON}~${suite}"
+       rm -rf $suite; mkdir $suite
+       (
+               cd $suite
+               status "Extracting source for $suite..."
+               ln ../${PKG}_* .
+               dpkg-source -x ${PKG}_${BASEPKGVERSION}${BASEPKGADD}.dsc extracted
+               (
+                       cd extracted
+
+                       # Copy new files
+                       status "Copy new files..."
+                       CopyNewFiles "$SOURCEDIR" .
+
+                       # Apply patches
+                       status "Apply some patches..."
+                       cp "$PPAPATCHDIR/"*.patch .
+                       for p in *.patch; do
+                               patch -p0 < "$p"
+                       done
+                       rm *.patch
+
+                       # Hack hack
+                       #TODO: Get rid of these
+                       status "Apply some hacks..."
+                       rm -rf debian/patches # Delete troublesome patch
+
+                       # Do changelog
+                       # Dch complains about unknown suites
+                       yes '' | dch -b -v $newversion -D $suite "Upload development version from Git $headcommit to Ubuntu PPA for $suite."
+
+                       # Build package
+                       #dpkg-buildpackage -sa -S    # Full .orig.gz
+                       dpkg-buildpackage -sd -S    # Only .diff.gz
+               )
+               # Upload to PPA
+               dput $DESTINATIONPPA ${PKG}_${newversion}_source.changes
+       )
+done
+
+status "Files were kept in $TEMPDIR"
+
diff --git a/tools/ppa/ppastats.py b/tools/ppa/ppastats.py
new file mode 100755 (executable)
index 0000000..32aa5e3
--- /dev/null
@@ -0,0 +1,35 @@
+#!/usr/bin/python
+# -*- coding: utf-8 -*-
+
+# Licensed under the GPL v3
+# Written by arand, original: https://launchpadlibrarian.net/81374910/ppastats
+# Modified for Performous by Tapio Vierros
+# Inspired by Alex Mandel's script snippets at https://bugs.launchpad.net/launchpad/+bug/139855
+# This is my biggest project in python to date, it is KLUDGE beyond imagination.
+# On Debian-like systems the package python-launchpadlib is required
+
+import os
+from launchpadlib.launchpad import Launchpad
+
+archs = ["i386", "amd64"]
+releases = ["lucid", "maverick", "natty", "oneiric"]
+
+owner_name = "performous-team"
+ppas = ["ppa"]
+
+for individual_ppa in ppas:
+       print "Usage stats for PPA with owner \"" + owner_name + "\" named \"" + individual_ppa + "\""
+       print "#####"
+       cachedir = os.path.expanduser("~/.launchpadlib/cache/")
+
+       launchpad = Launchpad.login_anonymously('ppastats', 'production', cachedir, version='devel')
+       owner = launchpad.people[owner_name]
+       archive = owner.getPPAByName(name=individual_ppa)
+
+       for individual_arch in archs:
+               for individual_release in releases:
+                       individual_distro_arch_series = "https://api.launchpad.net/devel/ubuntu/" + individual_release + "/" + individual_arch
+                       print "\t" + individual_release + "/" + individual_arch + ":"
+                       for individual_archive in archive.getPublishedBinaries(status='Published',distro_arch_series=individual_distro_arch_series):
+                               print individual_archive.binary_package_name + "\t" + individual_archive.binary_package_version + "\t" + str(individual_archive.getDownloadCount())
+       print "#####"
diff --git a/tools/scripts/create-archive.sh b/tools/scripts/create-archive.sh
new file mode 100755 (executable)
index 0000000..98ff334
--- /dev/null
@@ -0,0 +1,10 @@
+#!/usr/bin/env sh
+
+NAME=performous-`git describe --tags`
+FILE=$NAME.tar.gz
+OUTDIR=`pwd`
+
+cd `dirname $0`/../..
+
+git archive --prefix="$NAME/" -o "$OUTDIR/$FILE" HEAD
+
diff --git a/tools/scripts/fix-songfiles.sh b/tools/scripts/fix-songfiles.sh
new file mode 100755 (executable)
index 0000000..599b2e7
--- /dev/null
@@ -0,0 +1,41 @@
+#/bin/sh
+# this script converts cp1252(windows) filenames+texts to utf8 and fixes wrong .mp3 filenames
+# usage ./fix-files.sh [songdir]
+
+cd "$1"
+
+function fenc {
+ convmv -f cp1252 -t utf8 --notest ./*
+ echo '- converted filenames to utf8'
+}
+
+function textenc {
+ find ./ | grep ".txt" | grep -v .cp1252 | while read txts; do
+  if [ -f "$txts.cp1252" ];
+  then
+   echo "- '$txts.cp1252' exists. skipping.."
+  else
+   mv "$txts" "$txts.cp1252"
+   iconv --from-code=ISO-8859-1 --to-code=UTF-8 "$txts.cp1252" > "$txts"
+   dos2unix "$txts"
+   echo "- converted $txts to utf8 and created backup $txts.cp1252"
+ fi
+ done
+}
+
+function mp3name {
+ txt=`find ./ | grep - | grep .txt | grep -v .txt.`
+ mp3name=`cat "$txt" | grep MP3 | sed -e s/#MP3:// -e s/"\r"//g`
+ oldfile=`find ./ | grep - | grep -i .mp3`
+  if [ -f "$mp3name" ];
+  then
+   echo "- '$mp3name already exists'. check usng log for errors if you still can't select it"
+  else
+   mv "$oldfile" "$mp3name"
+   echo "- moved '$oldfile' to '$mp3name'"
+  fi
+}
+
+fenc
+textenc
+mp3name
diff --git a/tools/scripts/setvocals.sh b/tools/scripts/setvocals.sh
new file mode 100644 (file)
index 0000000..96a3ab8
--- /dev/null
@@ -0,0 +1,20 @@
+#/bin/sh
+# this script guess which is the vocals track of a song and name it "vocals.ogg"
+# usage ./setvocals.sh [songdir]
+
+cd "$1" || exit
+
+function setvocals_rockband {
+       if [ -f "song.ogg" -a -f "drums.ogg" -a -f "rhythm.ogg" -a -f "guitar.ogg" ];
+       then mv song.ogg vocals.ogg;
+       fi
+}
+
+function setvocals_guitarhero {
+       if [ -f "song.ogg" -a -f "drumsFoFiX.ogg" -a -f "songFoFiX.ogg" -a -f "rhythm.ogg" -a -f "guitar.ogg" ];
+       then mv songFoFiX.ogg vocals.ogg;
+       fi
+}
+
+setvocals_rockband
+setvocals_guitarhero
diff --git a/tools/scripts/setvocals_recursively.sh b/tools/scripts/setvocals_recursively.sh
new file mode 100644 (file)
index 0000000..9483acb
--- /dev/null
@@ -0,0 +1,8 @@
+#/bin/sh
+# this script execute "./setvocals_one_song.sh" recursively
+# usage ./setvocals_recursively.sh [parentdir]
+# If you run it with no arguments, it will use the current dir as parent dir
+
+
+[ $# -gt 0 ] || set -- .;
+find "$@" -type d -exec sh ./setvocals.sh {} \;
diff --git a/tools/scripts/translation_wiki_helper.sh b/tools/scripts/translation_wiki_helper.sh
new file mode 100755 (executable)
index 0000000..e6c3107
--- /dev/null
@@ -0,0 +1,248 @@
+#!/bin/bash
+#
+# TODO: error handling, security, the usual suspects.
+
+# Keep these in the global scope
+TOT=
+UNT=
+FUZ=
+TPC=
+ISO_639_XML="/usr/share/xml/iso-codes/iso_639.xml"
+
+die(){
+    echo "$*" >&2
+    exit -1
+}
+
+show_usage(){
+    echo "USAGE: $0 <--overview|--infoboxes [lang]> [--iso-639 file]"
+    echo
+    echo " --overview           Generates the language overview table."
+    echo " --infoboxes [lang]   The two letter ISO-369-1 langauge code used in the PO"
+    echo "                       filename, or the 3-letter terminology code (ISO-639-2T),"
+    echo "                       if no two letter code exits. If none is given infoboxes"
+    echo "                       for all languages found is generated."
+    echo " [--iso-639 file]   Override the location of the ISO-639-1 XML database."
+    echo "                       This defaults to: /usr/share/xml/iso-codes/iso_639.xml"
+}
+
+if [[ "$(basename $PWD)" != "performous" ]] || [[ ! -d ".git" ]] ; then
+       echo "This script must be run from the perfourmous source folder"
+       die "Error: Not in the performous root dir!"
+fi
+
+# Colorize
+#   100 => green background + bold face
+#  >=95 => green background
+#  >=75 => orangeish background
+#  >=50 => orageish background
+#  >=25 => red background
+#   <25 => red background
+colorize(){
+       echo -n 'style="background-color: '
+       if [[ $1 -eq 100 ]] ; then
+               echo -n "#00FF00; font-weight: bold"
+       elif [[ $1 -ge 95 ]] ; then
+               echo -n "#00FF00"
+       elif [[ $1 -ge 75 ]] ; then
+               echo -n "#CCEE00"
+       elif [[ $1 -ge 50 ]] ; then
+               echo -n "#CC9900"
+       elif [[ $1 -ge 25 ]] ; then
+               echo -n "#CC0000"
+       else
+               echo -n "#990000"
+       fi
+       echo -n ';" |'
+}
+
+# This assumes the file /usr/share/xml/iso-codes/iso_639.xml exists
+# and has a very strict format (not only valid XML!)
+get_full_language_name(){
+       if [[ ! -f "$ISO_639_XML" ]] ; then
+               echo "<!> Missing file \"$(basename "$ISO_639_XML")\""
+               die "FATAL ERROR: Missing ISO-639 mappings."
+       fi
+
+       # Note assumptions about the XML file formatting:
+       # (lines marked with * are the important ones, -/... is ignored data)
+       # - <iso_639_entry                      - <iso_639_entry
+       # - ...                                 - ...
+       # * iso_639_1_code="xx"     -- XOR --   * iso_639_2T_code="xxx"
+       # * name="Xyzuvw; ..." />               * name="Xyzuvw; ..." />
+
+       # only pick the first name if many (see XML for examples on eg "nl")
+       NAME=$(grep -A1 "iso_639_1_code=\"$1\"" "$ISO_639_XML" | grep name | sed -re 's:[ \t]*name="([^;\"]+).*:\1:')
+       if [[ -z "$NAME" ]] ; then
+           # Try the 3-letter terminology form before giving up
+           # <http://www.opentag.com/xfaq_lang.htm>
+           NAME=$(grep -A1 "iso_639_2T_code=\"$1\"" "$ISO_639_XML" | grep name= | sed -re 's:[ \t]*name="([^;\"]+).*:\1:') 
+
+           if [[ -z "$NAME" ]] ; then
+                       # causes: no 2 or 3 letter code exists, or both exists and the 3 letter
+                       # version was used (causing -A1 to give the iso_639_1_code line, grepping
+                       # for name= will fail => NAME="")
+
+                       # Fall back to something other than an empty string
+                       NAME="Unkown"
+           fi
+       fi
+       echo "$NAME"
+}
+
+# get_translator_field: ISO-369-1 Lang × STRING -> STRING
+get_translator_fields(){
+       DB="lang/TRANSLATORS"
+       if [[ -f "$DB" ]] ; then
+               grep "$1:$2 " "$DB" | sed "s%$1:$2 %%"
+               return $?
+       fi
+       echo ""
+       return -1
+}
+
+get_translator_comment(){
+       get_translator_fields "$1" "COMMENT"
+       return $?
+}
+
+last_commit_date(){
+       # ci vs ai? author vs commit date? I'm guessing ci is what we want,
+       # when the commit was made, not when the autor made the edit.
+       # (thus the assumption is: %ci more recent or exactly equal to %ai)
+       git log --date-order -n1 --pretty=format:%ci --no-color --date=iso
+}
+last_commit_id(){
+       # %H = full commit hash
+       # %h = short commit hash
+       git log --date-order -n1 --pretty=format:%h --no-color --date=iso
+}
+last_commit_gitweb_uri(){
+       # SF_GIT_WEB_URI
+       SF_GIT_WEB_URI_BASE="http://performous.git.sourceforge.net/git/gitweb.cgi?p=performous/performous;a=commit"
+       SF_GIT_WEB_URI="${SF_GIT_WEB_URI_BASE};h=$(git log --date-order -n1 --pretty=format:%H --no-color --date=iso)"
+       echo "$SF_GIT_WEB_URI"
+}
+
+current_gitweb_uri(){
+       SF_GIT_WEB_URI_BASE="http://performous.git.sourceforge.net/git/gitweb.cgi?p=performous/performous;a=blob;hb=HEAD"
+       SF_GIT_WEB_URI="${SF_GIT_WEB_URI_BASE};f=$1"
+       echo "$SF_GIT_WEB_URI"
+}
+
+# update_vars : ISO-369-1 LANG -> Ø
+update_vars(){
+       OUT="$( LC_ALL=C msgfmt --statistics "lang/$1.po" 2>&1 )"
+
+       # Extract translated, fuzzy and untranslated counts
+       # Note: msgfmt has bad habits:
+       #  * stats are apparently errors, as they're sent to stderr
+       #  * it says "1 fuzzy translation" andt "2 fuzzy translations", thus
+       #    the "...s?..." to catch that case, I'm assuming this holds for
+       #    all three components.
+       #sed -re "s%^([0-9]+) translated messages?(, ([0-9]+) fuzzy translations?)?(, ([0-9]+) untranslated messages?)?\.%LANG=$1;T=\1;F=\3;U=\5%"
+       TOT=$(echo "$OUT" | sed -re "s%^([0-9]+) translated messages?(, ([0-9]+) fuzzy translations?)?(, ([0-9]+) untranslated messages?)?\.%\1%")
+       FUZ=$(echo "$OUT" | sed -re "s%^([0-9]+) translated messages?(, ([0-9]+) fuzzy translations?)?(, ([0-9]+) untranslated messages?)?\.%\3%")
+       UNT=$(echo "$OUT" | sed -re "s%^([0-9]+) translated messages?(, ([0-9]+) fuzzy translations?)?(, ([0-9]+) untranslated messages?)?\.%\5%")
+
+       # compute the % of translated strings
+       TPC="N/A"
+       if      [[ -z "$TOT" ]] || [[ "$TOT" == "0" ]] &&
+               [[ -z "$FUZ" ]] || [[ "$FUZ" == "0" ]] &&
+               [[ -z "$UNT" ]] || [[ "$UNT" == "0" ]] ; then
+               TPC="0"
+       else
+               [[ -z "$TOT" ]] && TOT=0
+               [[ -z "$FUZ" ]] && FUZ=0
+               [[ -z "$UNT" ]] && UNT=0
+               TPC="$(echo "100 * $TOT / (( $TOT + $UNT + $FUZ ))" | bc)"
+       fi
+}
+
+# internal use by generate_overview
+overview_wikify(){
+       I_LANG="$(echo "$1" | sed -re 's:lang/([a-z]+)\.po:\1:')"
+       YYYY_MM_DD="$(LC_ALL=C git log -1 --format="%ar" lang/$I_LANG.po)"
+       LONG_LANG="$(get_full_language_name "$I_LANG")"
+       [[ $? -eq 0 ]] || die "$LONG_LANG"
+       update_vars "$I_LANG"
+
+       # find overview translation comments (if any)
+       COMMENT="$(get_translator_comment $I_LANG)"
+       PC_COLOR=$(colorize $TPC)
+
+       echo "|-"
+       echo "|   [[Translations ($LONG_LANG)|$I_LANG]]  || $YYYY_MM_DD  || ${PC_COLOR} ${TPC} % || $TOT || $FUZ || ${UNT} || '''$(( $TOT + $UNT + $FUZ ))''' || [$(current_gitweb_uri "$1") $1] || ${COMMENT}"
+}
+
+generate_overview(){
+       cat <<EOH
+{| border="1" cellspacing="0" cellpadding="5"
+| rowspan="2" | '''Language'''                || rowspan="2" | '''Last update''' || colspan="5" align="center" | '''Progress''' || rowspan="2" | '''Current version''' || rowspan="2" | '''Comment'''
+|-
+|                                                                       '''%''' || '''Translated''' || '''Fuzzy''' || '''Untranslated''' || '''Total'''
+EOH
+       for a in $(ls -1 lang/*po) ; do
+               overview_wikify "$a"
+       done
+       echo "|}"
+
+       echo "Table last updated: $(date --rfc-3339=seconds) (based on git commit <tt>[$(last_commit_gitweb_uri) $(last_commit_id)]</tt> @ $(last_commit_date))"
+}
+
+generate_infoboxes(){
+       I_LANG="$(echo "$1" | sed -re 's:lang/([a-z]+)\.po:\1:')"
+       YYYY_MM_DD="$(LC_ALL=C git log -1 --format="%ci" lang/$I_LANG.po)"
+
+       OUT="$( LC_ALL=C msgfmt --statistics "$1" 2>&1 )"
+       LONG_LANG="$(get_full_language_name "$I_LANG")"
+       [[ $? -eq 0 ]] || die "$LONG_LANG"
+       update_vars "$I_LANG"
+
+       STATUS="$(get_translator_fields "$I_LANG" "STATUS")"
+       CONTACT="$(get_translator_fields "$I_LANG" "CONTACT")"
+
+       echo "{{Translation:TranslationInfo|Status=$STATUS|LANG=$I_LANG|PERCENT=$TPC|STRINGS=$TOT / $(( $TOT + $FUZ + $UNT ))|FUZZY=$FUZ|NOTRANS=$UNT|Updated=$YYYY_MM_DD|Contact=$CONTACT}}"
+}
+
+if [[ "$1" == "--overview" ]] ; then
+    if [[ "$2" == "--iso-639" ]] && [[ -n "$3" ]] ; then
+           [[ -f "$3" ]] || die "The <$3> doesn't exist!"
+           ISO_639_XML="$3"
+       elif [[ $# -ne 1 ]] ; then
+           show_usage
+           die "Error: Invalid commandline."
+       fi
+       generate_overview
+elif [[ "$1" == "--infoboxes" ]] ; then
+    L="$2"
+
+       shift # of the --infoboxes arg
+       if [[ "$L" == "--iso-639" ]] ; then
+           # lang to --infoboxes was omitted, clear it.
+           L=""
+       else
+           shift # of the lang argument
+       fi
+
+       if [[ $# -eq 2 ]] && [[ "$1" == "--iso-639" ]] && [[ -n "$1" ]] ; then
+           [[ -f "$2" ]] || die "The <$2> doesn't exist!"
+           ISO_639_XML="$2"
+       elif [[ $# -ne 0 ]] ; then
+           show_usage
+           die "Error: Invalid commandline."
+       fi
+
+       if [[ -z "$L" ]] ; then
+               for a in $(ls -1 lang/*po) ; do
+                       generate_infoboxes "$a"
+               done
+       else
+           if [[ -d lang ]] && [[ ! -f "lang/${L}.po" ]] ; then
+                       die "There is no translation (.po) file for <$L>!"
+               fi
+               generate_infoboxes "$L"
+       fi
+else
+    show_usage
+fi
diff --git a/tools/scripts/txts2duet b/tools/scripts/txts2duet
new file mode 100755 (executable)
index 0000000..de8c087
--- /dev/null
@@ -0,0 +1,239 @@
+#!/usr/bin/env python
+
+"""Ultrastar TXT file duet merger
+=================================
+
+This program merges Ultrastar TXT files into a duet. Preconditions are:
+
+* All metadata but TITLE and GAP match
+* The files match the author's highly subjective perception of well-formedness,
+  which is influenced by the documentation available on [1] and [2], but can
+  not be regardes as canonical for lack of proper documentation.
+
+[1] http://thebrickyblog.wordpress.com/2011/01/27/ultrastar-txt-files-in-more-depth/
+[2] http://www.ultrastarstuff.com/html/tutorialtxtfile.html
+"""
+
+# Copyright (C) 2013 chrysn <chrysn@fsfe.org>
+# 
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+# 
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+# 
+# You should have received a copy of the GNU General Public License along
+# with this program; if not, write to the Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+
+import sys
+import os.path
+from collections import OrderedDict
+import argparse
+
+class FileFormatViolation(Exception): "An input file is not formed as the author of this program expects it."
+
+class TXTFile(object):
+    """UltraStar TXT song description"""
+    def __init__(self, filelike):
+        self.headers = OrderedDict()
+
+        self.players = {}
+        self.unnamedplayer = []
+
+        current_player = self.unnamedplayer
+
+        done = False
+
+        for line in filelike:
+            line = line.rstrip('\n\r')
+
+            if done:
+                raise FileFormatViolation('Garbage after end of file ("E").')
+
+            if line.startswith('#') and ':' in line:
+                key, value = line[1:].split(':', 2)
+                if key in self.headers:
+                    raise FileFormatViolation('Duplicate header line.')
+                self.headers[key] = value
+            elif line.startswith('E'):
+                done = True
+            elif line.startswith('P'):
+                try:
+                    playernumber = int(line[1:].strip())
+                except ValueError:
+                    raise FileFormatViolation("Non-numeric player identity")
+                if playernumber in self.players:
+                    raise FileFormatViolation("Dupliate player identity")
+                current_player = []
+                self.players[playernumber] = current_player
+            elif line[0] in ':*F-':
+                parts = line.split(' ', 4)
+                current_player.append(parts)
+            else:
+                raise FileFormatViolation("Unknown line (%s)"%line)
+
+        if not done:
+            raise FileFormatViolation('Missing end of file ("E").')
+
+        if self.players and self.unnamedplayer:
+            raise FileFormatViolation('Contains both singleplayer and multiplayer data')
+
+    def to_multiplayer_first(self):
+        if self.players:
+            raise ValueError("Can not convert multiplayer file to multiplayer mode")
+
+        self.players[1] = self.unnamedplayer
+        self.unnamedplayer = []
+
+    def merge(self, other, new_headers):
+        if other.players:
+            raise ValueError("Can not merge multi-player files")
+
+        own_gap = self.get_float_header('GAP')
+        other_gap = other.get_float_header('GAP')
+
+        if own_gap > other_gap:
+            self.adjust_gap_transparent(other_gap)
+        if other_gap > own_gap:
+            other.adjust_gap_transparent(own_gap)
+
+        for k,v in self.headers.items():
+            if k in new_headers:
+                continue
+            if other.headers[k] != v:
+                raise ValueError("Can not merge files: header field %r differs (%r, %r)"%(k, v, other.headers[k]))
+
+        self.players[max(self.players) + 1] = other.unnamedplayer
+
+        self.headers.update(new_headers)
+
+    def get_float_header(self, name):
+        return float(self.headers.get(name, '0').replace(',', '.'))
+
+    def set_float_header(self, name, value):
+        # the limit of 16 digits is somewhat arbitrary, but the normal string
+        # formatter would go to exponential notation, and that's probably not
+        # compatible with txt files
+        self.headers[name] = "{:.8f}".format(value).rstrip('0').rstrip('.').replace('.', ',')
+
+    def adjust_gap_transparent(self, new_gap):
+        """Change the value of GAP, but modify all lines there is no change in
+        the song itself"""
+
+        old_gap = self.get_float_header('GAP')
+
+        summand = (old_gap - new_gap) / 60000 * self.get_float_header('BPM') * 4
+        if summand == 0:
+            return
+
+        rounded = int(round(summand))
+        error = max(summand / rounded, rounded / summand) - 1
+
+        if error >= 0.0001: # a reasonable epsilon
+            raise ValueError("Incompatible GAP values, would have to use finer BPM")
+
+        self.shift_lines(rounded)
+
+        self.set_float_header('GAP', new_gap)
+
+    def shift_lines(self, summand):
+        """Add summand to all start times of lines in a file"""
+
+        if self.headers.get('RELATIVE', 'NO') != 'NO':
+            raise ValueError("Can not shift around lines in relative mode")
+
+        for player in [self.unnamedplayer] + list(self.players.values()):
+            for line in player:
+                try:
+                    old_start = int(line[1])
+                except (KeyError, ValueError):
+                    raise FileFormatViolation("Can not determine start time of %r"%(line,))
+
+                new_start = old_start + summand
+                if new_start < 0:
+                    raise ValueError("Can not shift start times to negative values")
+                line[1] = str(old_start + summand)
+
+    def serialize(self, outfile):
+        for (k, v) in self.headers.items():
+            outfile.write('#%s:%s\r\n'%(k, v))
+        for line in self.unnamedplayer:
+            outfile.write(" ".join(line) + '\r\n')
+        for (player_id, lines) in self.players.items():
+            outfile.write('P%d\r\n'%player_id)
+            for line in lines:
+                outfile.write(" ".join(line) + '\r\n')
+        outfile.write('E\r\n')
+
+def merge(infiles, outfile, title):
+    indata = [TXTFile(open(i)) for i in infiles]
+
+    if title is None:
+        try:
+            title = mergeguesser(list(d.headers['TITLE'] for d in indata))
+        except (ValueError, KeyError):
+            raise ValueError("Can not guess shared title, please provide one")
+
+    if outfile is None:
+        filenames, exts = zip(*(os.path.splitext(f) for f in infiles))
+        try:
+            outfile = mergeguesser(filenames) + exts[0]
+        except ValueError:
+            raise ValueError("Can not guess output file name, please provide one")
+
+    original = indata[0]
+    original.to_multiplayer_first()
+    for m in indata[1:]:
+        original.merge(m, {'TITLE': title})
+
+    with open(outfile, 'w') as of:
+        original.serialize(of)
+
+def mergeguesser(strings):
+    """Given a number of strings, guess how a duet composed of all those files
+    could be called. Raises a ValueError if no reasonable guess can be made."""
+
+    parens = {'(':')', '[': ']', '{': '}', '<': '>'}
+
+    if len(strings) < 2:
+        raise ValueError("Not enough strings to guess")
+
+    for i in range(max(len(x) for x in strings), 4, -1): # 4 is the arbitrary minimum lenth of a common substring to be considered "reasonable"
+        subs = [x[:i] for x in strings]
+        if all(x == subs[0] for x in subs):
+            break
+    else:
+        raise ValueError("No reasonable common substring")
+
+    substring = subs[0]
+
+    if substring[-1] in parens:
+        return substring + 'Duet' + parens[substring[-1]]
+
+    return substring + ' (Duet)'
+
+def main():
+    p = argparse.ArgumentParser(description=__doc__.split('\n')[0].strip())
+    p.add_argument('--output', metavar='FILE', type=str, help='Name of the resulting file')
+    p.add_argument('--title', type=str, help='Title of the merged song')
+    p.add_argument('input', type=str, nargs='+', help='Files to be merged')
+    p.add_argument('--debug', help='Show backtraces instead of error messages')
+
+    args = p.parse_args()
+
+    if args.debug:
+        merge(args.input, args.output, args.title)
+    else:
+        try:
+            merge(args.input, args.output, args.title)
+        except (FileFormatViolation, ValueError), e:
+            sys.stderr.write("Could not complete merging: %s\n"%e)
+            sys.exit(1)
+
+if __name__ == "__main__":
+    main()
diff --git a/tools/scripts/usdb.sh b/tools/scripts/usdb.sh
new file mode 100755 (executable)
index 0000000..234b470
--- /dev/null
@@ -0,0 +1,272 @@
+#!/bin/bash
+#
+# this is revision 3
+#
+
+[ -z "$USDB_DEST_DIR" ] && USDB_DEST_DIR="${HOME}/.ultrastar/songs"
+[ ! -e "$USDB_DEST_DIR" ] && mkdir -p "$USDB_DEST_DIR"
+
+set -eu
+
+if [ $# != 1 ] ; then
+  echo " >>> This script should help you to import .txt files into your"
+  echo " >>> song repository or update .txt files currently in the repository"
+  echo " >>> by adding a video, cover or background image."
+  echo " >>> It will guide you to youtube/google image search, insert the"
+  echo " >>> proper tags and copy everything to your USDB_DEST_DIR."
+  echo " >>> "
+  echo " >>> usage: "`basename $0`" [songfile.txt]"
+  echo " >>> "
+  exit
+fi
+
+if [ ! -e "$1" ] ; then
+  echo " >>> error: file \"$1\" does not exist."
+  exit 1
+fi
+
+# testing dependencies
+if which wget > /dev/null 2>/dev/null ; then
+  DOWNLOAD_CMD="wget -O"
+elif which curl > /dev/null 2>/dev/null ; then
+  DOWNLOAD_CMD="curl -o"
+else
+  echo " >>> error: install either wget or curl."
+  exit 1
+fi
+if ! which youtube-dl > /dev/null 2>/dev/null ; then
+  echo " >>> error: youtube-dl not found in the path."
+  echo " >>> get ih here: http://www.arrakis.es/~rggi3/youtube-dl/"
+  exit 1
+fi
+
+function escape {
+  perl -MCGI -e \ 'print CGI->escape(@ARGV), "\n"' "$1"
+}
+
+echo " >>> USDB_DEST_DIR = $USDB_DEST_DIR"
+
+WORK_DIR=`dirname "$1"`
+
+cd "$WORK_DIR"
+TXT=`basename "$1"`
+
+# remove backslashes from the filename (beta)
+if echo "$TXT" | grep -q \\\\ ; then
+  NEWTXT=`echo "$TXT" | sed -e s:\\\\\\\\::g`
+  echo " >>> removing backslash from filename..."
+  mv "$TXT" "$NEWTXT"
+  TXT="$NEWTXT"
+fi
+
+PREFIX=`basename "$TXT" ".txt"`
+TMP="${PREFIX}.old"
+
+# convert \r\n --> \n
+if grep -q $'\r' "$TXT" ; then
+  echo " >>> converting from CRLF to LF"
+  mv "$TXT" "$TMP"
+  sed -e s:\\\r::g -- "$TMP" > "$TXT"
+  rm "$TMP"
+fi
+
+while file "$TXT" | grep -q ISO ; do
+  echo
+  echo " >>> the files is not UTF-8, it will be opened in gedit for inspection."
+  echo " >>> Save it as UTF-8, press return to continue, type 'no' to cancel."
+  echo -n " >>> any key ... "
+  read REPLY
+  if [ "x$REPLY" = "xno" ] ; then
+    break
+  else
+    gedit "$TXT"
+    [ -e "${TXT}~" ] && rm "${TXT}~"
+  fi
+done
+
+ARTIST=`grep     "#ARTIST:"     "$TXT" | cut -d : -f 2`
+TITLE=`grep      "#TITLE:"      "$TXT" | cut -d : -f 2`
+MP3=`grep        "#MP3:"        "$TXT" | cut -d : -f 2`
+BPM=`grep        "#BPM:"        "$TXT" | cut -d : -f 2`
+VIDEO=`grep      "#VIDEO:"      "$TXT" | cut -d : -f 2`
+COVER=`grep      "#COVER:"      "$TXT" | cut -d : -f 2`
+BACKGROUND=`grep "#BACKGROUND:" "$TXT" | cut -d : -f 2`
+
+if [ "x$ARTIST" = "x" -o "x$TITLE" = "x" -o "x$BPM" = "x" ] ; then
+  echo " >>> error: this does not seem to ba a valid ultrastar file."
+  exit 1
+fi
+
+if test -z "$MP3" || test ! -e "$MP3" ; then
+  GET_VIDEO=yes
+elif test -z "$VIDEO" || test ! -e "$VIDEO" ; then
+  echo
+  echo " >>> There is an MP3 that looks good, but no video."
+  echo " >>> If you want to delete the .mp3 and look for a video, enter yes."
+  echo -n " >>> delete the MP3? [no]: "
+  read DEL
+  if [ "x$DEL" = "xyes" ] ; then
+    rm "$MP3"
+    GET_VIDEO=yes
+  else
+    GET_VIDEO=no
+  fi
+else
+  GET_VIDEO=no
+fi
+
+# VIDEO not set/does not exist
+if [ $GET_VIDEO = yes ] ; then
+
+  echo
+
+  # remove MP3 VIDEO and VIDEOGAP
+  echo " >>> removing old #MP3 #VIDEO and #VIDEOGAP tags"
+  mv "$TXT" "$TMP"
+  grep -v "#MP3:" "$TMP" | grep -v "#VIDEO:" | grep -v "#VIDEOGAP:" > "$TXT"
+  rm "$TMP"
+
+  # download video
+  ESCAPED=`escape "\"$ARTIST\" \"$TITLE\""`
+  URL="http://www.youtube.com/results?search_query=$ESCAPED"
+  echo " >>> Please look for the song here, then enter the desired video url below"
+  echo " >>> $URL"
+  echo -n " >>> youtube url: "
+  read YOUTUBE_URL
+  [ -z "$YOUTUBE_URL" ] && echo " >>> canceled." && exit
+  MP3="${PREFIX}.mp4"
+  VIDEO="${PREFIX}.mp4"
+  echo " >>> running youtube-dl ..."
+  youtube-dl -b -o "$VIDEO" "$YOUTUBE_URL"
+  
+  echo " >>> adding new #MP3 and #VIDEO tags"
+  mv "$TXT" "$TMP"
+  echo "#MP3:${MP3}" > "$TXT"
+  echo "#VIDEO:${VIDEO}" >> "$TXT"
+  cat "$TMP" >> "$TXT"
+  rm "$TMP"
+  
+fi
+
+# COVER does not exist
+if test -z "$COVER" || test ! -e "$COVER" ; then
+
+  echo
+
+  # remove COVER
+  if [ -n "$COVER" ] ; then
+    echo " >>> removing old #COVER tag"
+    mv "$TXT" "$TMP"
+    grep -v "#COVER:" "$TMP" > "$TXT"
+    rm "$TMP"
+  fi
+
+  # download image
+  ESCAPED=`escape "\"$ARTIST\" \"$TITLE\" cover"`
+  URL="http://images.google.com/images?q=$ESCAPED"
+  echo " >>> Please look for the cover here, or press return to skip"
+  echo " >>> $URL"
+  echo -n " >>> image url: "
+  read COVER_URL
+  if [ -z "$COVER_URL" ] ; then
+    echo " >>> skipping."
+  else
+    COVER="${PREFIX} [CO].jpg"
+    echo " >>> downloading image ..."
+    $DOWNLOAD_CMD "$COVER" "$COVER_URL"
+
+    echo " >>> adding new #COVER tag"
+    mv "$TXT" "$TMP"
+    echo "#COVER:${COVER}" | cat - "$TMP" > "$TXT"
+    rm "$TMP"
+  fi
+
+fi
+
+# BACKGROUND does not exist
+if test -z "$BACKGROUND" || test ! -e "$BACKGROUND" ; then
+
+  echo
+
+  # remove BACKGROUND
+  if [ -n "$BACKGROUND" ] ; then
+    echo " >>> removing old #BACKGROUND tag"
+    mv "$TXT" "$TMP"
+    grep -v "#BACKGROUND:" "$TMP" > "$TXT"
+    rm "$TMP"
+  fi
+
+  # download image
+  ESCAPED=`escape "\"$ARTIST\" \"live performance\""`
+  URL="http://images.google.com/images?q=$ESCAPED"
+  echo " >>> Please look for an image of the band performing, or press return to skip"
+  echo " >>> $URL"
+  echo -n " >>> image url: "
+  read BG_URL
+  if [ -z "$BG_URL" ] ; then
+    echo " >>> skipping."
+  else
+    BACKGROUND="${PREFIX} [BG].jpg"
+    echo " >>> downloading image ..."
+    $DOWNLOAD_CMD "$BACKGROUND" "$BG_URL"
+
+    echo " >>> adding new #BACKGROUND tag"
+    mv "$TXT" "$TMP"
+    echo "#BACKGROUND:${BACKGROUND}" | cat - "$TMP" > "$TXT"
+    rm "$TMP"
+  fi
+
+fi
+
+# calculate first note offset
+FIRST=`grep -E '[\\:F\\*] [0-9]+ [0-9]+ [0-9]+ ' "$TXT" | head -n 1 | cut -d " " -f 2`
+BPM=`echo $BPM | sed -e s/,/./g`
+SUBSTRACT=`echo "$FIRST / $BPM / 4 * 60000" | bc -l | cut -d . -f 1`
+
+# check for overlapping notes
+ERRORLINES=""
+LASTTIME="-1000000"
+LINENUM="1"
+while read LINE ;do
+  TIME=`echo "$LINE" | grep -E '[\\:F\\*\\-] [0-9]+' | cut -d " " -f 2`
+  if [ -n "$TIME" ] ; then
+    [ $LASTTIME -gt $TIME ] && ERRORLINES="${ERRORLINES}${LINENUM} "
+    LASTTIME="$TIME"
+  fi
+  let "LINENUM++"
+done < "$TXT"
+
+# all done, move files to destination
+if [ "`cd .. ; pwd`" != "${USDB_DEST_DIR}" ] ; then
+  DIR="${USDB_DEST_DIR}/$ARTIST - $TITLE"
+  echo
+  echo " >>> moving files to ..."
+  echo " >>> $DIR/"
+  mkdir "$DIR"
+  mv "$TXT" "$MP3" "$DIR"
+  [ -e "$VIDEO" ] && mv "$VIDEO" "$DIR"
+  [ -e "$COVER" ] && mv "$COVER" "$DIR"
+  [ -e "$BACKGROUND" ] && mv "$BACKGROUND" "$DIR"
+else
+  DIR="$WORK_DIR"
+fi
+
+echo
+echo " >>> To get the timing right, you might want to do this:"
+echo
+echo "mplayer -ao pcm:file=/tmp/dump.wav -vo null \"$DIR/$MP3\""
+echo "audacity /tmp/dump.wav && rm /tmp/dump.wav"
+echo "gedit \"$DIR/$TXT\""
+echo
+
+if [ "x$SUBSTRACT" != "x0" ] ; then
+  echo " >>> Note that the first note does not start at zero."
+  echo " >>> You have to substract ${SUBSTRACT}ms from the #GAP meassured with audacity."
+  echo
+fi
+
+if [ -n "$ERRORLINES" ] ; then
+  echo " >>> Warning: This song will not work in Performous, because there are overlapping notes."
+  echo " >>> Please have a look at these lines: $ERRORLINES"
+  echo
+fi
diff --git a/tools/scripts/xml_gettext.sh b/tools/scripts/xml_gettext.sh
new file mode 100755 (executable)
index 0000000..2f59120
--- /dev/null
@@ -0,0 +1,117 @@
+#!/bin/bash
+#
+# This script is intended to be executed from Poedit
+# See instructions in lang/README.
+#
+# As long as the xml files are well-formed XML documents with
+# entry blocks like the following one (from scheme.xml) this
+# script should have no problems extracting the strings.
+#              <entry ...>
+#                      <short>Karaoke mode</short>
+#                      <long>Hide pitch wave, notes and scoring.</long>
+#              </entry>
+
+# adds a line to the temporary source file
+append_temp_src(){
+       echo "$*" >> "$TEMP_SRC"
+}
+
+# match <entry, ignoring allowed whitespace.
+match_entry_start(){
+       echo "$1" | grep -qE '^[[:space:]]*<[[:space:]]*entry.*>[[:space:]]*$'
+       return $?
+}
+
+# match </entry>, ignoring allowed whitespace.
+match_entry_end(){
+       echo "$1" | grep -qE '^[[:space:]]*<[[:space:]]*/[[:space:]]*entry>[[:space:]]*$'
+       return $?
+}
+
+# matches lines with <$1>...</$1>, ignoring allowed whitespace.
+match_simple_tag(){
+       echo "$2" | grep -qE "^[[:space:]]*<[[:space:]]*$1[[:space:]]*>.*</[[:space:]]*$1[[:space:]]*>[[:space:]]*$"
+       return $?
+}
+
+# <abc>def</abc> -> _("def")
+# Note: every " is automatically replaced by \". This is what you want, not
+# invalid C code.
+transform_simple_tag_to_keyworded_string(){
+       echo "$1" | sed -re 's:\":\\\":g' -e 's:^[[:space:]]*<[[:space:]]*([a-z]+)[[:space:]]*>(.*)<[[:space:]]*/[[:space:]]*\1[[:space:]]*>[[:space:]]*$:_("\2"):'
+}
+
+transform_and_add_string(){
+       append_temp_src "$(transform_simple_tag_to_keyworded_string "$1")"
+}
+
+# transform <short/> and <long/> lines to _() lines
+process_locale_block_line(){
+       match_simple_tag "short" "$1" && transform_and_add_string "$1"
+       match_simple_tag "long" "$1" && transform_and_add_string "$1"
+}
+
+process_xml(){
+       IN_BLOCK=0
+       line_no=0
+       cat "$1" | while read line
+       do
+               line_no=$(($line_no + 1))
+
+               # A simple 2-state automata, either we're in a <entry/>-block
+               # or we're not. Limited detection and bail-out on malformed XML
+               if [[ $IN_BLOCK -eq 1 ]] ; then
+                       match_entry_end "$line"
+                       if [[ $? -eq 0 ]] ; then
+                               IN_BLOCK=0
+                       else
+                               process_locale_block_line "$line"
+                       fi
+
+                       # <entry...> with out </entry> found:
+                       match_entry_start "$line" && (echo "Malformed XML $file:$line_no: Opening entry-tag found while already inside an entry block." >&2 ;exit -1)
+
+               else
+                       # </entry> with out <entry> found:
+                       match_entry_end "$line" && (echo "Malformed XML $file:$line_no:: Closing entry-tag without prior opening tag." >&2 ;exit -1)
+
+                       match_entry_start "$line"
+                       if [[ $? -eq 0 ]] ; then
+                               IN_BLOCK=1
+                       fi
+               fi
+       done 
+}
+
+
+if [[ $# -lt 2 ]] ; then
+       echo "USAGE: $0 <output file> <input encoding> [files...]"
+       exit -1 
+elif [[ $# -eq 2 ]] ; then
+       # no input files nothing to do
+       exit 0
+fi
+
+POEDIT_FILE="$1"
+ENC="$2"
+shift
+shift
+
+# create the temporary file securely.
+TEMP_SRC="$(mktemp -t xml2gettext.XXXXXXXXXX)"
+
+append_temp_src "/* This is a automatically generated temp file, it's safe to remove */"
+
+# Start the dirty work
+for file in $* ; do
+       process_xml "$file"
+done
+
+# Invoke xgettext, poedit will merge this with the rest of the strings
+xgettext --force-po --language=C -o "$POEDIT_FILE" --from-code="$ENC" -k_ "$TEMP_SRC"
+RV=$?
+
+# clean up
+rm "$TEMP_SRC"
+
+exit $RV
diff --git a/tools/ss_binary.hh b/tools/ss_binary.hh
new file mode 100644 (file)
index 0000000..0864d6b
--- /dev/null
@@ -0,0 +1,176 @@
+#include "adpcm.h"
+#include "ipuconv.hh"
+
+unsigned getLE16(char* buf) { unsigned char* b = reinterpret_cast<unsigned char*>(buf); return b[0] | (b[1] << 8); }
+unsigned getLE32(char* buf) { unsigned char* b = reinterpret_cast<unsigned char*>(buf); return b[0] | (b[1] << 8) | (b[2] << 16) | (b[3] << 24); }
+
+void writeWavHeader(std::ostream& outfile, unsigned ch, unsigned sr, unsigned samples) {
+       unsigned bps = ch * 2; // Bytes per sample
+       unsigned datasize = bps * samples;
+       unsigned size = datasize + 0x2C;
+       outfile.write("RIFF" ,4); // RIFF chunk
+       { unsigned int tmp=size-0x8 ; outfile.write((char*)(&tmp),4); } // RIFF chunk size
+       outfile.write("WAVEfmt ",8); // WAVEfmt header
+       { int   tmp=0x00000010 ; outfile.write((char*)(&tmp),4); } // Always 0x10
+       { short tmp=0x0001     ; outfile.write((char*)(&tmp),2); } // Always 1
+       { short tmp = ch; outfile.write((char*)(&tmp),2); } // Number of channels
+       { int   tmp = sr; outfile.write((char*)(&tmp),4); } // Sample rate
+       { int   tmp = bps * sr; outfile.write((char*)(&tmp),4); } // Bytes per second
+       { short tmp = bps; outfile.write((char*)(&tmp),2); } // Bytes per frame
+       { short tmp = 16; outfile.write((char*)(&tmp),2); } // Bits per sample
+       outfile.write("data",4); // data chunk
+       { int   tmp = datasize; outfile.write((char*)(&tmp),4); }
+}
+
+void writeMusic(fs::path const& filename, std::vector<short> const& buf, unsigned sr) {
+       std::ofstream f(filename.string().c_str(), std::ios::binary);
+       writeWavHeader(f, 2, sr, buf.size());
+       f.write(reinterpret_cast<char const*>(&buf[0]), buf.size() * sizeof(short));
+}
+
+void video_us(Song& song, PakFile const& iavFile, PakFile const& indFile, fs::path const& outPath) {
+       // Tracks on my example
+       // 0 => video (ipu)
+       // 1 and 2 => adpcm song (left/right)
+       // 3 and 4 => adpcm vocals (left/right)
+
+       std::vector<char> ipudata;
+       std::vector<char> data;
+       std::vector<char> ind_file;
+       indFile.get(ind_file);
+
+       unsigned int iav_offset = 0;
+       unsigned int frame = 0;
+       for( unsigned int ind_offset = 0x68 ; ind_offset < ind_file.size() ; ind_offset+=2) {
+               unsigned int size = getLE16(&ind_file[ind_offset]) << 4;
+               switch(frame % 5) {
+               case 0:
+                       // first 4 bytes are packet length
+                       iavFile.get(data, iav_offset, size);
+                       {
+                               unsigned int consumed = 0;
+                               while(consumed < size) {
+                                       unsigned int opaque_footer_size = 3 * sizeof(int);
+                                       unsigned int chunk = getLE32(&data[consumed]);
+                                       ipudata.insert(ipudata.end(), data.begin() + 4 + consumed, data.begin() + consumed + chunk - opaque_footer_size);
+                                       consumed += chunk;
+                               }
+                       }
+                       iav_offset += size;
+                       break;
+               case 1:
+               case 2:
+               case 3:
+               case 4:
+                       // audio
+                       iav_offset += size;
+                       break;
+               }
+               frame++;
+       }
+
+       IPUConv(ipudata, (outPath / "video.mpg").string(), song.pal);
+       song.video = outPath / "video.mpg";
+}
+
+void music_us(Song& song, PakFile const& iavFile, PakFile const& indFile, fs::path const& outPath) {
+       // Tracks on my example
+       // 0 => video (ipu)
+       // 1 and 2 => adpcm song (left/right)
+       // 3 and 4 => adpcm vocals (left/right)
+       // std::cout << "  >>> IAV file size: " << iavFile.size << std::endl;
+       // std::cout << "  >>> IND file size: " << indFile.size << std::endl;
+
+       std::vector<char> ind_file;
+       indFile.get(ind_file);
+       unsigned int sr = getLE32(&ind_file[0x60]);
+       // std::cout << "  >>> sample rate: " << sr << std::endl;
+
+       const unsigned decodeChannels = 4; // Do not change!
+       Adpcm adpcm(0, decodeChannels);
+       std::vector<short> pcm[2];
+
+       bool karaoke = false;
+       unsigned int iav_offset = 0;
+       unsigned int frame = 0;
+       unsigned int video_size, audio_size = 0;
+       for( unsigned int ind_offset = 0x68 ; ind_offset < ind_file.size() ; ind_offset+=2) {
+               unsigned int size = getLE16(&ind_file[ind_offset]) << 4;
+               switch(frame%5) {
+                       case 0:
+                               video_size = size;
+                               iav_offset += video_size;
+                               break;
+                       case 1:
+                               // song left
+                               audio_size = size;
+                               break;
+                       case 2:
+                               // song right
+                               audio_size += size;
+                               break;
+                       case 3:
+                               // vocals left
+                               audio_size += size;
+                               break;
+                       case 4:
+                               // vocals right
+                               audio_size += size;
+                               adpcm.interleave(size);
+                               for (unsigned pos = 0, end; (end = pos + 2 * adpcm.chunkBytes()) <= audio_size; pos = end) {
+                                       std::vector<char> data;
+                                       iavFile.get(data, iav_offset + pos, end - pos);
+                                       std::vector<short> pcmtmp(adpcm.chunkFrames() * decodeChannels);
+                                       adpcm.decodeChunk(&data[0], pcmtmp.begin());
+                                       for (size_t s = 0; s < pcmtmp.size(); s += 4) {
+                                               short l1 = pcmtmp[s];
+                                               short r1 = pcmtmp[s + 1];
+                                               short l2 = pcmtmp[s + 2];
+                                               short r2 = pcmtmp[s + 3];
+                                               pcm[0].push_back(l1);
+                                               pcm[0].push_back(r1);
+                                               pcm[1].push_back(l2);
+                                               pcm[1].push_back(r2);
+                                               if (l2 != 0 || r2 != 0) karaoke = true;
+                                       }
+                               }
+                               iav_offset += audio_size;
+                               break;
+               }
+               frame++;
+       }
+       std::string ext;
+       writeMusic(song.music = outPath / ("music.wav"), pcm[0], sr);
+       if (karaoke) writeMusic(song.vocals = outPath / ("vocals.wav"), pcm[1], sr);
+}
+
+void music(Song& song, PakFile const& dataFile, PakFile const& headerFile, fs::path const& outPath) {
+       std::vector<char> data;
+       headerFile.get(data);
+       unsigned sr = getLE16(&data[12]);
+       unsigned interleave = getLE16(&data[16]);
+       const unsigned decodeChannels = 4; // Do not change!
+       Adpcm adpcm(interleave, decodeChannels);
+       std::vector<short> pcm[2];
+       bool karaoke = false;
+       for (unsigned pos = 0, end; (end = pos + 2 * adpcm.chunkBytes()) <= dataFile.size; pos = end) {
+               dataFile.get(data, pos, end - pos);
+               std::vector<short> pcmtmp(adpcm.chunkFrames() * decodeChannels);
+               adpcm.decodeChunk(&data[0], pcmtmp.begin());
+               for (size_t s = 0; s < pcmtmp.size(); s += 4) {
+                       short l1 = pcmtmp[s];
+                       short r1 = pcmtmp[s + 1];
+                       short l2 = pcmtmp[s + 2];
+                       short r2 = pcmtmp[s + 3];
+                       pcm[0].push_back(l1);
+                       pcm[0].push_back(r1);
+                       pcm[1].push_back(l2);
+                       pcm[1].push_back(r2);
+                       if (l2 != 0 || r2 != 0) karaoke = true;
+               }
+       }
+       std::string ext;
+       writeMusic(song.music = outPath / ("music.wav"), pcm[0], sr);
+       if (karaoke) writeMusic(song.vocals = outPath / ("vocals.wav"), pcm[1], sr);
+}
+
diff --git a/tools/ss_chc_decode.cc b/tools/ss_chc_decode.cc
new file mode 100644 (file)
index 0000000..3d9d5aa
--- /dev/null
@@ -0,0 +1,38 @@
+#include <cstdlib>
+#include "chc_decode.hh"
+#include <string>
+#include <iostream>
+#include <fstream>
+#include <boost/lexical_cast.hpp>
+
+int main(int argc, char ** argv) {
+       if( argc != 7 ) {
+               std::cout << "Usage: " << argv[0] << " chc_file key0 key1 key2 key4 track_id" << std::endl;
+               return EXIT_FAILURE;
+       }
+       std::string key[4] = {argv[2], argv[3], argv[4], argv[5]};
+
+       std::ifstream chc_file;
+       chc_file.open(argv[1], std::ios_base::binary );
+
+       // Get the file size
+       chc_file.seekg(0, std::ios::end);
+       unsigned int fileSize = chc_file.tellg();
+       chc_file.seekg(0, std::ios::beg);
+
+       // Reading inputfile
+       char *buffer = new char[fileSize];
+       std::cout << "Reading input file \"" << argv[1] << "\" (" << fileSize << " Bytes)... " << std::endl;
+       chc_file.read(&buffer[0], fileSize);
+       chc_file.close();
+
+       ChcDecode chc_decoder;
+       chc_decoder.load(key);
+       std::string xmlMelody = chc_decoder.getMelody(buffer, fileSize, boost::lexical_cast<unsigned int>(argv[6]));
+
+       std::cout << xmlMelody << std::endl;
+
+       delete[] buffer;
+
+       return EXIT_SUCCESS;
+}
diff --git a/tools/ss_cover.cc b/tools/ss_cover.cc
new file mode 100644 (file)
index 0000000..3b85420
--- /dev/null
@@ -0,0 +1,130 @@
+#include <cstring>
+
+namespace TX2 {
+       unsigned short getWidth(char * buffer) {
+               return (*(unsigned short*)&buffer[0x0c])&0x7fff;
+       }
+       unsigned short getHeight(char * buffer) {
+               return (*(unsigned short*)&buffer[0x0e])&0x7fff;
+       }
+
+       unsigned char * getBuffer(char * src) {
+               unsigned int pixels = getWidth(src) * getHeight(src);
+               unsigned char *buffer = new unsigned char[pixels*4];
+
+               char * src_image = src+0x100;
+               char * src_palette = src+0x100+pixels+0x100;
+
+               for(unsigned int i = 0; i < pixels; i++){
+                       unsigned char id = src_image[i];
+                       buffer[i*4+0] = src_palette[id*4+0]; // blue
+                       buffer[i*4+1] = src_palette[id*4+1]; // green
+                       buffer[i*4+2] = src_palette[id*4+2]; // blue;
+                       //buffer[i*4+3] = src_palette[id*4+3]; // alpha
+                       buffer[i*4+3] = 0xff;
+               }
+               return buffer;
+       }
+
+       void transform( char *dst, char * src ) {
+               unsigned short width  = TX2::getWidth(src);
+               unsigned short height = TX2::getHeight(src);
+               char * src_image = src+0x100;
+               char * src_palette_header = src+0x100+width*height;
+               char * src_palette = src+0x100+width*height+0x100;
+               char * dst_image = dst+0x100;
+               char * dst_palette_header = dst+0x100+width*height;
+               char * dst_palette = dst+0x100+width*height+0x100;
+               // Recopy the header
+               memcpy(dst,src,0x100);
+               // unswizzle the texture
+               for (int y = 0; y < height; ++y) {
+                       for (int x = 0; x < width; ++x) {
+                               int block_location = (y&(~0xf))*width + (x&(~0xf))*2;
+                               unsigned int swap_selector = (((y+2)>>2)&0x1)*4;
+                               int posY = (((y&(~3))>>1) + (y&1))&0x7;
+                               int column_location = posY*width*2 + ((x+swap_selector)&0x7)*4;
+                               int byte_num = ((y>>1)&1) + ((x>>2)&2); // 0,1,2,3
+       
+                               unsigned char uPen = ((unsigned char *) src_image)[block_location + column_location + byte_num];
+                               // Bitshift the palette
+                               unsigned char l = (uPen&0x10)>>1;
+                               unsigned char m = (uPen&0x08)<<1;
+                               unsigned char o = (uPen&0xe7);
+                               ((unsigned char *) dst_image)[y*width+x] = o|l|m;
+                       }
+               }
+               // Recopy the palette header
+               memcpy(dst_palette_header,src_palette_header,0x100);
+               // Bitshift the palette
+               memcpy(dst_palette,src_palette,0x400);
+       }
+}
+
+#include <cstdlib>
+#include <iostream>
+#include <stdexcept>
+
+#include <Magick++.h>
+#include <boost/lexical_cast.hpp>
+#include <libxml++/libxml++.h>
+
+#include "ss_cover.hh"
+
+#include "pak.h"
+
+SingstarCover::SingstarCover(const std::string pak_file, unsigned int track_id) {
+       xmlpp::Node::PrefixNsMap nsmap;
+       nsmap["ss"] = "http://www.singstargame.com";
+       std::string filename("export/covers.xml");
+
+       // extract cover information from XML
+       Pak p(pak_file);
+       std::vector<char> buf;
+       p[filename].get(buf);
+       std::string id(std::string("cover_") + boost::lexical_cast<std::string>(track_id));
+       std::string xpath = std::string("/ss:TPAGE_BIT_SET/ss:TPAGE_BIT[@NAME='") + id + "']";
+       xmlpp::DomParser dom;
+       std::string tmp( buf.begin(), buf.end() );
+       dom.parse_memory(tmp);
+       xmlpp::NodeSet n = dom.get_document()->get_root_node()->find(xpath, nsmap);
+       if (n.empty()) {
+               std::string xpath_old = std::string("/TPAGE_BIT_SET/TPAGE_BIT[@NAME='") + id + "']";
+               n = dom.get_document()->get_root_node()->find(xpath_old, nsmap);
+               if (n.empty())
+                       throw std::runtime_error("Unable to find cover informations");
+       }
+       xmlpp::Element& e = dynamic_cast<xmlpp::Element&>(*n[0]);
+       m_u = boost::lexical_cast<unsigned int>(e.get_attribute("U")->get_value());
+       m_v = boost::lexical_cast<unsigned int>(e.get_attribute("V")->get_value());
+       m_width = boost::lexical_cast<unsigned int>(e.get_attribute("WIDTH")->get_value());
+       m_height = boost::lexical_cast<unsigned int>(e.get_attribute("HEIGHT")->get_value());
+       std::string texture_filename = std::string("export/textures/") + e.get_attribute("TEXTURE")->get_value() + ".tx2";
+
+       // extract and unswizzle image from pak
+       std::vector<char> buf_image;
+       p[texture_filename].get(buf_image);
+       m_image = buf_image;
+       TX2::transform(&m_image[0],&buf_image[0]);
+};
+
+SingstarCover::~SingstarCover() {};
+
+void SingstarCover::write(const std::string filename) {
+       // grab format from tx2 file
+       unsigned short width = TX2::getWidth(&m_image[0]);
+       unsigned short height = TX2::getHeight(&m_image[0]);
+       unsigned char * buffer = TX2::getBuffer(&m_image[0]);
+       Magick::Blob blob( buffer, width*height*4);
+       Magick::Image image;
+       char geometry[16];
+       sprintf(geometry,"%dx%d",width,height);
+       image.size(geometry);
+       image.depth(8);
+       image.magick( "RGBA" ); 
+       image.read(blob);
+       // crop image according to informations stored in xml
+       image.crop( Magick::Geometry(m_width, m_height, m_u, m_v) );
+       // write it
+       image.write(filename);
+};
diff --git a/tools/ss_cover.hh b/tools/ss_cover.hh
new file mode 100644 (file)
index 0000000..7a6920d
--- /dev/null
@@ -0,0 +1,14 @@
+#pragma once
+
+#include <string>
+#include <vector>
+
+class SingstarCover {
+  public:
+       SingstarCover(const std::string pak_file, unsigned int track_id);
+       ~SingstarCover();
+       void write(const std::string filename);
+  private:
+       std::vector<char> m_image;
+       unsigned int m_u, m_v , m_width, m_height;
+};
diff --git a/tools/ss_extract.cc b/tools/ss_extract.cc
new file mode 100644 (file)
index 0000000..2a94110
--- /dev/null
@@ -0,0 +1,425 @@
+#include <stdlib.h>
+#include <algorithm>
+#include <iostream>
+#include <stdexcept>
+#include <string>
+
+#include <sys/stat.h>
+#include <sys/types.h>
+
+#include <libxml/parser.h>
+#include <libxml/tree.h>
+
+#include <boost/filesystem.hpp>
+#include <boost/lexical_cast.hpp>
+#include <boost/program_options.hpp>
+
+#include "chc_decode.hh"
+#include "ss_cover.hh"
+
+#include "ss_helpers.hh"
+
+namespace fs = boost::filesystem;
+
+struct Song {
+       std::string dataPakName, title, artist, genre, edition, year;
+       fs::path path, music, vocals, video, background, cover;
+       unsigned samplerate;
+       double tempo;
+       bool pal;
+       Song(): samplerate(), tempo() {}
+};
+
+#include "ss_binary.hh"
+
+std::string dvdPath;
+std::ofstream txtfile;
+int ts = 0;
+int sleepts = -1;
+bool g_video = true;
+bool g_audio = true;
+bool g_mkvcompress = true;
+bool g_oggcompress = true;
+
+void parseNote(xmlpp::Node* node) {
+       xmlpp::Element& elem = dynamic_cast<xmlpp::Element&>(*node);
+       char type = ':';
+       std::string lyric = elem.get_attribute("Lyric")->get_value();
+       // Some extra formatting to make lyrics look better (hyphen removal & whitespace)
+       if (lyric.size() > 0 && lyric[lyric.size() - 1] == '-') {
+               if (lyric.size() > 1 && lyric[lyric.size() - 2] == ' ') lyric.erase(lyric.size() - 2);
+               else lyric[lyric.size() - 1] = '~';
+       } else {
+               lyric += ' ';
+       }
+       unsigned note = boost::lexical_cast<unsigned>(elem.get_attribute("MidiNote")->get_value().c_str());
+       unsigned duration = boost::lexical_cast<unsigned>(elem.get_attribute("Duration")->get_value().c_str());
+       if (elem.get_attribute("FreeStyle")) type = 'F';
+       if (elem.get_attribute("Bonus")) type = '*';
+       if (note) {
+               if (sleepts > 0) txtfile << "- " << sleepts << '\n';
+               sleepts = 0;
+               txtfile << type << ' ' << ts << ' ' << duration << ' ' << note << ' ' << lyric << '\n';
+       }
+       ts += duration;
+}
+
+void parseSentence(xmlpp::Node* node) {
+       xmlpp::Element& elem = dynamic_cast<xmlpp::Element&>(*node);
+       // FIXME: Get rid of this or use SSDom's find
+       xmlpp::Node::PrefixNsMap nsmap;
+       nsmap["ss"] = "http://www.singstargame.com";
+       xmlpp::NodeSet n = elem.find("ss:NOTE", nsmap);
+       if (n.empty()) n = elem.find("NOTE");
+       if (sleepts != -1) sleepts = ts;
+       std::for_each(n.begin(), n.end(), parseNote);
+}
+
+struct Match {
+       std::string left, right;
+       Match(std::string l, std::string r): left(l), right(r) {}
+       bool operator()(Pak::files_t::value_type const& f) {
+               std::string n = f.first;
+               return n.substr(0, left.size()) == left && n.substr(n.size() - right.size()) == right;
+       }
+};
+
+void saveTxtFile(xmlpp::NodeSet &sentence, const fs::path &path, const Song &song, const std::string singer = "") {
+       fs::path file_path;
+
+       if( singer.empty() ) {
+               file_path = path / "notes.txt";
+       } else {
+               file_path = path;
+               file_path /= safename(std::string("notes") + " (" + singer + ")" + ".txt");
+       }
+       txtfile.open(file_path.string().c_str());
+       if( singer.empty() )
+               txtfile << "#TITLE:" << song.title << std::endl;
+       else
+               txtfile << "#TITLE:" << song.title << " (" << singer << ")" << std::endl;
+       txtfile << "#ARTIST:" << song.artist << std::endl;
+       if (!song.genre.empty()) txtfile << "#GENRE:" << song.genre << std::endl;
+       if (!song.year.empty()) txtfile << "#YEAR:" << song.year << std::endl;
+       if (!song.edition.empty()) txtfile << "#EDITION:" << song.edition << std::endl;
+       //txtfile << "#LANGUAGE:English" << std::endl; // Detect instead of hardcoding?
+       if (!song.music.empty()) txtfile << "#MP3:" << filename(song.music) << std::endl;
+       if (!song.vocals.empty()) txtfile << "#VOCALS:" << filename(song.vocals) << std::endl;
+       if (!song.video.empty()) txtfile << "#VIDEO:" << filename(song.video) << std::endl;
+       if (!song.cover.empty()) txtfile << "#COVER:" << filename(song.cover) << std::endl;
+       //txtfile << "#BACKGROUND:background.jpg" << std::endl;
+       txtfile << "#BPM:" << song.tempo << std::endl;
+       ts = 0;
+       sleepts = -1;
+       std::for_each(sentence.begin(), sentence.end(), parseSentence);
+       txtfile << 'E' << std::endl;
+       txtfile.close();
+}
+
+ChcDecode chc_decoder;
+
+struct Process {
+       Pak const& pak;
+       Process(Pak const& p): pak(p) {}
+       void operator()(std::pair<std::string const, Song>& songpair) {
+               fs::path remove;
+               try {
+                       std::string const& id = songpair.first;
+                       Song& song = songpair.second;
+                       std::cerr << "\n[" << id << "] " << song.artist << " - " << song.title << std::endl;
+                       fs::path path = safename(song.edition);
+                       path /= safename(song.artist + " - " + song.title);
+                       SSDom dom;
+                       {
+                               std::vector<char> tmp;
+                               Pak::files_t::const_iterator it = std::find_if(pak.files().begin(), pak.files().end(), Match("export/" + id + "/melody", ".xml"));
+                               if (it == pak.files().end()) {
+                                       it = std::find_if(pak.files().begin(), pak.files().end(), Match("export/melodies_10", ".chc"));
+                                       if (it == pak.files().end()) throw std::runtime_error("Melody XML not found");
+                                       it->second.get(tmp);
+                                       dom.load(chc_decoder.getMelody(&tmp[0], tmp.size(), boost::lexical_cast<unsigned int>(id)));
+                               } else {
+                                       it->second.get(tmp);
+                                       dom.load(xmlFix(tmp));
+                               }
+                       }
+                       if (song.tempo == 0.0) {
+                               xmlpp::NodeSet n;
+                               dom.find("/ss:MELODY", n) || dom.find("/MELODY", n);
+                               if (n.empty()) throw std::runtime_error("Unable to find BPM info");
+                               xmlpp::Element& e = dynamic_cast<xmlpp::Element&>(*n[0]);
+                               std::string res = e.get_attribute("Resolution")->get_value();
+                               song.tempo = boost::lexical_cast<double>(e.get_attribute("Tempo")->get_value().c_str());
+                               if (res == "Semiquaver") {}
+                               else if (res == "Demisemiquaver") song.tempo *= 2.0;
+                               else throw std::runtime_error("Unknown tempo resolution: " + res);
+                       }
+                       fs::create_directories(path);
+                       remove = path;
+                       dom.get_document()->write_to_file((path / "notes.xml").string(), "UTF-8");
+                       Pak dataPak(song.dataPakName);
+                       if (g_audio) {
+                               std::cerr << ">>> Extracting and decoding music" << std::endl;
+                               try {
+                                       music(song, dataPak[id + "/music.mib"], pak["export/" + id + "/music.mih"], path);
+                               } catch (...) {
+                                       music_us(song, dataPak[id + "/mus+vid.iav"], dataPak[id + "/mus+vid.ind"], path);
+                               }
+                       }
+                       std::cerr << ">>> Extracting cover image" << std::endl;
+                       try {
+                               SingstarCover c = SingstarCover(dvdPath + "/pack_ee.pak", boost::lexical_cast<unsigned int>(id));
+                               c.write(path.string() + "/cover.jpg");
+                               song.cover = path / "cover.jpg";
+                       } catch (...) {}
+                       remove = "";
+                       // FIXME: use some library (preferrably ffmpeg):
+                       if (g_oggcompress) {
+                               if( !song.music.empty() ) {
+                                       std::cerr << ">>> Compressing audio into music.ogg" << std::endl;
+                                       std::string cmd = "oggenc \"" + song.music.string() + "\"";
+                                       std::cerr << cmd << std::endl;
+                                       if (std::system(cmd.c_str()) == 0) { // FIXME: std::system return value is not portable
+                                               fs::remove(song.music);
+                                               song.music = path / ("music.ogg");
+                                       }
+                               }
+                               if( !song.vocals.empty() ) {
+                                       std::cerr << ">>> Compressing audio into vocals.ogg" << std::endl;
+                                       std::string cmd = "oggenc \"" + song.vocals.string() + "\"";
+                                       std::cerr << cmd << std::endl;
+                                       if (std::system(cmd.c_str()) == 0) { // FIXME: std::system return value is not portable
+                                               fs::remove(song.vocals);
+                                               song.vocals = path / ("vocals.ogg");
+                                       }
+                               }
+                       }
+                       if (g_video) {
+                               std::cerr << ">>> Extracting video" << std::endl;
+                               try {
+                                       std::vector<char> ipudata;
+                                       dataPak[id + "/movie.ipu"].get(ipudata);
+                                       std::cerr << ">>> Converting video" << std::endl;
+                                       IPUConv(ipudata, (path / "video.mpg").string());
+                                       song.video = path / "video.mpg";
+                               } catch (...) {
+                                       std::cerr << "  >>> European DVD failed, trying American (WIP)" << std::endl;
+                                       try {
+                                               video_us(song, dataPak[id + "/mus+vid.iav"], dataPak[id + "/mus+vid.ind"], path);
+                                       } catch (std::exception& e) {
+                                               std::cerr << "!!! Unable to extract video: " << e.what() << std::endl;
+                                               song.video = "";
+                                       }
+                               }
+                               if (g_mkvcompress) {
+                                       std::cerr << ">>> Compressing video into video.m4v" << std::endl;
+                                       std::string cmd = "ffmpeg -i \"" + (path / "video.mpg").string() + "\" -vcodec libx264 -profile main -crf 25 -threads 0 -metadata album=\"" + song.edition + "\" -metadata author=\"" + song.artist + "\" -metadata comment=\"" + song.genre + "\" -metadata title=\"" + song.title + "\" \"" + (path / "video.m4v\"").string();
+                                       std::cerr << cmd << std::endl;
+                                       if (std::system(cmd.c_str()) == 0) { // FIXME: std::system return value is not portable
+                                               fs::remove(path / "video.mpg");
+                                               song.video = path / "video.m4v";
+                                       }
+                               }
+                       }
+
+                       std::cerr << ">>> Extracting lyrics" << std::endl;
+                       xmlpp::NodeSet sentences;
+                       if(dom.find("/ss:MELODY/ss:SENTENCE", sentences)) {
+                               // Sentences not inside tracks (normal songs)
+                               std::cerr << "  >>> Solo track" << std::endl;
+                               saveTxtFile(sentences, path, song);
+                       } else {
+                               xmlpp::NodeSet tracks;
+                               if (!dom.find("/ss:MELODY/ss:TRACK", tracks)) throw std::runtime_error("Unable to find any sentences in melody XML");
+                               for (xmlpp::NodeSet::iterator it = tracks.begin(); it != tracks.end(); ++it ) {
+                                       xmlpp::Element& elem = dynamic_cast<xmlpp::Element&>(**it);
+                                       std::string singer = elem.get_attribute("Artist")->get_value();
+                                       std::cerr << "  >>> Track from " << singer << std::endl;
+                                       dom.find(elem, "ss:SENTENCE", sentences);
+                                       saveTxtFile(sentences, path, song, singer);
+                               }
+                       }
+               } catch (std::exception& e) {
+                       std::cerr << e.what() << std::endl;
+                       if (!remove.empty()) {
+                               std::cerr << "!!! Removing " << remove.string() << std::endl;
+                               fs::remove_all(remove);
+                       }
+               }
+       }
+};
+
+void get_node(const xmlpp::Node* node, std::string& genre, std::string& year)
+{
+       const xmlpp::ContentNode* nodeContent = dynamic_cast<const xmlpp::ContentNode*>(node);
+       const xmlpp::TextNode* nodeText = dynamic_cast<const xmlpp::TextNode*>(node);
+       const xmlpp::CommentNode* nodeComment = dynamic_cast<const xmlpp::CommentNode*>(node);
+
+       if(nodeText && nodeText->is_white_space()) //Let's ignore the indenting - you don't always want to do this.
+               return;
+
+       //Treat the various node types differently:
+       if(nodeText || nodeComment || nodeContent)
+       {
+               // if any of these exist do nothing! :D
+       }
+       else if(const xmlpp::Element* nodeElement = dynamic_cast<const xmlpp::Element*>(node))
+       {
+               //A normal Element node:
+
+               //Print attributes:
+               const xmlpp::Element::AttributeList& attributes = nodeElement->get_attributes();
+               for(xmlpp::Element::AttributeList::const_iterator iter = attributes.begin(); iter != attributes.end(); ++iter)
+               {
+                       const xmlpp::Attribute* attribute = *iter;
+                       if (attribute->get_name() == "GENRE") genre = normalize(attribute->get_value());
+                       else if (attribute->get_name() == "YEAR") year = normalize(attribute->get_value());
+               }
+       }
+
+       if(!nodeContent)
+       {
+               //Recurse through child nodes:
+               xmlpp::Node::NodeList list = node->get_children();
+               for(xmlpp::Node::NodeList::iterator iter = list.begin(); iter != list.end(); ++iter)
+               {
+                       get_node(*iter, genre, year); //recursive
+               }
+       }
+}
+
+struct FindSongs {
+       std::string edition;
+       std::string language;
+       std::map<std::string, Song> songs;
+       FindSongs(std::string const& search = ""): m_search(search) {}
+       void operator()(Pak::files_t::value_type const& p) {
+               std::string name = p.first;
+               if (name.substr(0, 17) == "export/config.xml"){
+                       SSDom dom(p.second);  // Read config XML
+                       // Load decryption keys required for some SingStar games (since 2009 or so)
+                       std::string keys[4];
+                       dom.getValue("/ss:CONFIG/ss:PRODUCT_NAME", keys[0]);
+                       dom.getValue("/ss:CONFIG/ss:PRODUCT_CODE", keys[1]);
+                       dom.getValue("/ss:CONFIG/ss:TERRITORY", keys[2]);
+                       dom.getValue("/ss:CONFIG/ss:DEFAULT_LANG", keys[3]);
+                       chc_decoder.load(keys);
+                       // Get the singstar edition, use PRODUCT_NAME as fallback for SS Original and SS Party
+                       if (!dom.getValue("/ss:CONFIG/ss:PRODUCT_DESC", edition)) edition = keys[0];
+                       if (edition.empty()) throw std::runtime_error("No PRODUCT_DESC or PRODUCT_NAME found");
+                       edition = prettyEdition(edition);
+                       std::cout << "### " << edition << std::endl;
+                       // Get language if available
+                       language = keys[3];
+               }
+
+               if (name.substr(0, 12) != "export/songs" || name.substr(name.size() - 4) != ".xml") return;
+               SSDom dom(p.second);  // Read song XML
+
+
+               xmlpp::NodeSet n;
+               dom.find("/ss:SONG_SET/ss:SONG", n);
+               Song s;
+               s.dataPakName = dvdPath + "/pak_iop" + name[name.size() - 5] + ".pak";
+               s.edition = edition;
+               for (xmlpp::NodeSet::const_iterator it = n.begin(), end = n.end(); it != end; ++it) {
+                       // Extract song info
+                       xmlpp::Element& elem = dynamic_cast<xmlpp::Element&>(**it);
+                       s.title = elem.get_attribute("TITLE")->get_value();
+                       s.artist = elem.get_attribute("PERFORMANCE_NAME")->get_value();
+                       if (!m_search.empty() && m_search != elem.get_attribute("ID")->get_value() && (s.artist + " - " + s.title).find(m_search) == std::string::npos) continue;
+                       xmlpp::Node const* node = dynamic_cast<xmlpp::Node const*>(*it);
+                       get_node(node, s.genre, s.year); // get the values for genre and year
+                       // Get video FPS
+                       double fps = 25.0;
+                       xmlpp::NodeSet fr;
+                       if (dom.find(elem, "ss:VIDEO/@FRAME_RATE", fr))
+                         fps = boost::lexical_cast<double>(dynamic_cast<xmlpp::Attribute&>(*fr[0]).get_value().c_str());
+                       if (fps == 25.0) s.pal = true;
+                       // Store song info to songs container
+                       songs[elem.get_attribute("ID")->get_value()] = s;
+               }
+       }
+  private:
+       std::string m_search;
+};
+
+int main( int argc, char **argv) {
+       std::string video, audio, song;
+       namespace po = boost::program_options;
+       po::options_description opt("Options");
+       opt.add_options()
+         ("help,h", "you are viewing it")
+         ("dvd", po::value<std::string>(&dvdPath), "path to Singstar DVD root")
+         ("list,l", "list tracks only")
+         ("song", po::value<std::string>(&song), "only extract the given track (ID or partial name)")
+         ("video", po::value<std::string>(&video)->default_value("mkv"), "specify video format (none, mkv, mpeg2)")
+         ("audio", po::value<std::string>(&audio)->default_value("ogg"), "specify audio format (none, ogg, wav)")
+         ;
+       // Process the first flagless option as dvd, the second as song
+       po::positional_options_description pos;
+       pos.add("dvd", 1);
+       pos.add("song", 1);
+       po::options_description cmdline;
+       cmdline.add(opt);
+       po::variables_map vm;
+       // Load the arguments
+       try {
+               po::store(po::command_line_parser(argc, argv).options(opt).positional(pos).run(), vm);
+               po::notify(vm);
+               if (dvdPath.empty()) throw std::runtime_error("No Singstar DVD path specified. Enter a path to a folder with pack_ee.pak in it.");
+               // Process video flag
+               if (video == "none") {
+                       g_video = false;
+                       g_mkvcompress = false;
+               } else if (video == "mkv") {
+                       g_video = true;
+                       g_mkvcompress = true;
+               } else if (video == "mpeg2") {
+                       g_video = true;
+                       g_mkvcompress = false;
+               } else {
+                       throw std::runtime_error("Invalid video flag. Value must be {none, mkv, mpeg2}");
+               }
+               std::cerr << ">>> Using video flag: \"" << video << "\"" << std::endl;
+               // Process audio flag
+               if (audio == "none") {
+                       g_audio = false;
+                       g_oggcompress = false;
+               } else if (audio == "ogg") {
+                       g_audio = true;
+                       g_oggcompress = true;
+               } else if (audio == "wav") {
+                       g_audio = true;
+                       g_oggcompress = false;
+               } else {
+                       throw std::runtime_error("Invalid audio flag. Value must be {none, ogg, wav}");
+               }
+               std::cerr << ">>> Using audio flag: \"" << audio << "\"" << std::endl;
+       } catch (std::exception& e) {
+               std::cout << cmdline << std::endl;
+               std::cout << "ERROR: " << e.what() << std::endl;
+               return EXIT_FAILURE;
+       }
+       std::string pack_ee = dvdPath + "/pack_ee.pak"; // Note: lower case (ISO-9660)
+       if (!fs::exists(pack_ee)) {
+               if (fs::exists(dvdPath + "/Pack_EE.PAK")) { // Note: capitalization (UDF)
+                       std::cerr <<
+                         "Singstar DVDs have UDF and ISO-9660 filesystems on them. Your disc is mounted\n"
+                         "as UDF and this causes some garbled data files, making ripping it impossible.\n\n"
+                         "Please remount the disc as ISO-9660 and try again. E.g. on Linux:\n"
+                         "# mount -t iso9660 /dev/cdrom " << dvdPath << std::endl;
+               } else std::cerr << "No Singstar DVD found. Enter a path to a folder with pack_ee.pak in it." << std::endl;
+               return EXIT_FAILURE;
+       }
+       Pak p(pack_ee);
+       FindSongs f = std::for_each(p.files().begin(), p.files().end(), FindSongs(song));
+       std::cerr << f.songs.size() << " songs found" << std::endl;
+       if (vm.count("list")) {
+               for( std::map<std::string, Song>::const_iterator it = f.songs.begin() ; it != f.songs.end();  ++it) {
+                       std::cout << "[" << it->first << "] " << it->second.artist << " - " << it->second.title << std::endl;
+               }
+       }
+       else std::for_each(f.songs.begin(), f.songs.end(), Process(p));
+}
+
diff --git a/tools/ss_helpers.hh b/tools/ss_helpers.hh
new file mode 100644 (file)
index 0000000..8895d94
--- /dev/null
@@ -0,0 +1,124 @@
+/// @file Some uninteresting helper functions used by ss_extract.
+
+#include <boost/algorithm/string.hpp>
+#include <libxml++/libxml++.h>
+#include <glibmm/convert.h>
+#include "pak.h"
+
+// LibXML2 logging facility
+extern "C" void xmlLogger(void* logger, char const* msg, ...) { if (logger) *(std::ostream*)logger << msg; }
+void enableXMLLogger(std::ostream& os = std::cerr) { xmlSetGenericErrorFunc(&os, xmlLogger); }
+void disableXMLLogger() { xmlSetGenericErrorFunc(NULL, xmlLogger); }
+
+#if BOOST_FILESYSTEM_VERSION < 3
+std::string filename(boost::filesystem::path const& p) { return *--p.end(); }
+#else
+std::string filename(boost::filesystem::path const& p) { return p.filename().string(); }
+#endif
+
+/** Fix Singstar's b0rked XML **/
+std::string xmlFix(std::vector<char> const& data) {
+       std::string ret;
+       for(std::size_t i = 0; i < data.size(); ++i) {
+               if (data[i] != '&') ret += data[i]; else ret += "&amp;";
+       }
+       return ret;
+}
+
+struct SSDom: public xmlpp::DomParser {
+       xmlpp::Node::PrefixNsMap nsmap;
+       SSDom(PakFile const& file) {
+               std::vector<char> tmp;
+               file.get(tmp);
+               std::string buf = xmlFix(tmp);
+               load(buf);
+       }
+       SSDom() {}
+       void load(std::string const& buf) {
+               set_substitute_entities();
+               try {
+                       struct DisableLogger {
+                               DisableLogger() { disableXMLLogger(); }
+                               ~DisableLogger() { enableXMLLogger(); }
+                       } disabler;
+                       parse_memory(buf);
+               } catch (...) {
+                       std::string buf2 = Glib::convert(buf, "UTF-8", "ISO-8859-1"); // Convert to UTF-8
+                       parse_memory(buf2);
+               }
+               nsmap["ss"] = get_document()->get_root_node()->get_namespace_uri();
+       }
+       bool find(xmlpp::Element& elem, std::string xpath, xmlpp::NodeSet& n) {
+               if (nsmap["ss"].empty()) boost::erase_all(xpath, "ss:");
+               n = elem.find(xpath, nsmap);
+               return !n.empty();
+       }
+       bool find(std::string const& xpath, xmlpp::NodeSet& n) {
+               return find(*get_document()->get_root_node(), xpath, n);
+       }
+       bool getValue(std::string const& xpath, std::string& result) {
+               xmlpp::NodeSet n;
+               if (!find(xpath, n)) return false;
+               result = dynamic_cast<xmlpp::Element&>(*n[0]).get_child_text()->get_content();
+               return true;
+       }
+};
+
+/** Erase all occurences of del from str. **/
+void safeErase(Glib::ustring& str, Glib::ustring const& del) {
+       do {
+               Glib::ustring::size_type pos = str.find(del);
+               if (pos != Glib::ustring::npos) { str.erase(pos, del.size()); continue; }
+       } while (0);
+}
+
+/** Normalize whitespace **/
+Glib::ustring normalize(Glib::ustring const& str) {
+       Glib::ustring ret;
+       bool first = true;
+       bool ws = true;
+       for (Glib::ustring::const_iterator it = str.begin(); it != str.end(); ++it) {
+               if (std::isspace(*it)) { ws = true; continue; }
+               if (first) {
+                       first = false;
+                       ws = false;
+                       ret = Glib::ustring(1, *it).uppercase();
+                       continue;
+               }
+               if (ws) { ws = false; ret += ' '; }
+               ret += *it;
+       }
+       return ret;
+}
+
+/** Sanitize a string into a form that can be safely used as a filename. **/
+std::string safename(Glib::ustring const& str) {
+       Glib::ustring ret;
+       Glib::ustring forbidden("\"*/:;<>?\\^`|~");
+       for (Glib::ustring::const_iterator it = str.begin(); it != str.end(); ++it) {
+               bool first = it == str.begin();
+               if (*it < 0x20) continue; // Control characters
+               if (*it >= 0x7F && *it < 0xA0) continue; // Additional control characters
+               if (first && *it == '.') continue;
+               if (first && *it == '-') continue;
+               if (*it == '&') { ret += " and "; continue; }
+               if (*it == '%') { ret += " percent "; continue; }
+               if (*it == '$') { ret += " dollar "; continue; }
+               if (forbidden.find(*it) != Glib::ustring::npos) { ret += "_"; continue; }
+               ret += *it;
+       }
+       return normalize(ret);
+}
+
+/** Fix inconsistencies in SS edition names **/
+Glib::ustring prettyEdition(Glib::ustring str) {
+       str = normalize(str);
+       safeErase(str, "®");
+       safeErase(str, "™");
+       if (str == "SingStar") return "SingStar Original";
+       if (str == "SingStar '80s") return "SingStar 80s";
+       if (str == "SingStar Schlager") return "SingStar Svenska Hits Schlager";
+       if (str == "SingStar Suomi Rock") return "SingStar SuomiRock";
+       return str;
+}
+
diff --git a/win32/ConfigureSongDirectory.bat b/win32/ConfigureSongDirectory.bat
new file mode 100755 (executable)
index 0000000..7008a2d
--- /dev/null
@@ -0,0 +1,9 @@
+@echo off
+set /p songdir=Enter the path to your song dir: 
+
+echo Performous will now launch.
+echo Go to the song browser and verify you typed the path correctly.
+echo Then go to configuration menu and hit Ctrl+S to save the setting.
+pause
+
+performous.exe %songdir%
diff --git a/win32/cross-from-debian/.gitignore b/win32/cross-from-debian/.gitignore
new file mode 100644 (file)
index 0000000..b36ad51
--- /dev/null
@@ -0,0 +1,9 @@
+*.tar.gz
+*.tar.bz2
+*.tgz
+*.zip
+deps/*
+dist/*
+stage/*
+wine/*
+
diff --git a/win32/cross-from-debian/README b/win32/cross-from-debian/README
new file mode 100644 (file)
index 0000000..cebc77c
--- /dev/null
@@ -0,0 +1,59 @@
+These scripts were developed under Debian's mingw32 environment with the
+wine package (and associated binfmt_misc rule, which is part of the package)
+installed, so some programs do not detect that they are being cross-compiled
+and attempt to run just-compiled programs because this works when the scripts
+use the ".exe" suffix when they try to do so (as autoconf scripts do).  So
+we occasionally generate a shell script wrapper under the non-.exe name that
+execs wine to satisfy scripts that fail to use ".exe" (some scripts do this
+because it's perfectly OK to do this under Windows).
+
+For pkg-config handling, we simply wrap the *host* pkg-config in a shell
+script that execs it with options causing it to look absolutely nowhere other
+than deps/lib/pkgconfig for .pc files and we place that script earlier on the
+PATH.  This very neatly avoids the glib/pkg-config chicken-and-egg problem
+that exists under Windows, though we don't bother building a Windows
+pkg-config at all since we don't need it.
+
+The makedeps.sh script builds the dependencies under ./deps and places stamp
+files in deps/build-stamps so it doesn't have to keep rebuilding the same
+things if it is interrupted or experiences an error halfway through.  You can
+force a single package to be rebuilt by deleting the appropriate stamp file
+and re-running makedeps.sh.  (You might do this, for example, to get newer
+ffmpeg code, as makedeps.sh builds the latest SVN of ffmpeg at the time the
+script is run.)
+
+Once the dependencies are built, run makebuilddir.sh to invoke cmake with the
+appropriate arguments for cross-compilation.  (Arguments to makebuilddir.sh
+are passed intact to cmake after the arguments the script itself passes but
+before the final argument [the source directory], which the script provides
+for you.)  It is up to you to run "make" and "make install" in the ./build
+directory (installation will occur to ./stage) after running makebuilddir.sh
+to set up ./build appropriately.
+
+(Regarding installation, it is a good idea to delete or rename ./stage if it
+exists before running "make install" so obsolete files aren't accidentally
+included in the package you are building.)
+
+The copydlls.py script takes two directories as arguments and copies any DLLs
+it can find in the first directory that are needed by PE executables in the
+second directory into the second directory.
+
+The makepackage.py script creates an executable installer from the contents of
+./stage using NSIS (NSIS can be built under non-Windows systems for use as a
+cross-compiler, and many Linux distros package it in this form) and places it
+into ./dist for your testing and distributing pleasure.
+
+In summary:
+  $ ./makedeps.sh
+  $ ./makebuilddir.sh
+  $ cd build
+  $ make
+  $ make install
+  $ cd ..
+  $ ./copydlls.py ./deps/bin ./stage/bin
+    [strip the binaries in ./stage/bin if you want]
+  $ ./makepackage.py
+    [test the file generated in ./dist]
+    [distribute said file if everything looks good]
+
+Happy cross-building!
diff --git a/win32/cross-from-debian/Toolchain.cmake b/win32/cross-from-debian/Toolchain.cmake
new file mode 100644 (file)
index 0000000..41cf6f8
--- /dev/null
@@ -0,0 +1,18 @@
+# the name of the target operating system
+set(CMAKE_SYSTEM_NAME Windows)
+
+# which compilers to use for C and C++
+set(CMAKE_C_COMPILER i586-mingw32msvc-gcc)
+set(CMAKE_CXX_COMPILER i586-mingw32msvc-g++)
+
+# here is the target environment located
+set(CMAKE_FIND_ROOT_PATH /usr/i586-mingw32msvc ${CMAKE_CURRENT_SOURCE_DIR}/win32/cross-from-debian/deps)
+
+# adjust the default behaviour of the FIND_XXX() commands:
+# search headers and libraries in the target environment, search
+# programs in the host environment
+set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
+set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
+set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
+
+set(WINDRES i586-mingw32msvc-windres)
diff --git a/win32/cross-from-debian/copydlls.py b/win32/cross-from-debian/copydlls.py
new file mode 100755 (executable)
index 0000000..ac2b8b3
--- /dev/null
@@ -0,0 +1,116 @@
+#!/usr/bin/env python
+# DLL dependency resolution and copying script.
+# Copyright (C) 2010 John Stumpo
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+import os
+import shutil
+import struct
+import sys
+
+if len(sys.argv) != 3:
+    sys.stderr.write('''Usage: %s [source] [destination]
+Copies DLLs in source needed by PE executables in destination to destination.
+Both source and destination should be directories.
+''' % sys.argv[0])
+    sys.exit(1)
+
+def is_pe_file(file):
+    f = open(file, 'rb')
+    if f.read(2) != 'MZ':
+        return False  # DOS magic number not present
+    f.seek(60)
+    peoffset = struct.unpack('<L', f.read(4))[0]
+    f.seek(peoffset)
+    if f.read(4) != 'PE\0\0':
+        return False  # PE magic number not present
+    return True
+
+def get_imports(file):
+    f = open(file, 'rb')
+    # We already know it's a PE, so don't bother checking again.
+    f.seek(60)
+    pe_header_offset = struct.unpack('<L', f.read(4))[0]
+
+    # Get sizes of tables we need.
+    f.seek(pe_header_offset + 6)
+    number_of_sections = struct.unpack('<H', f.read(2))[0]
+    f.seek(pe_header_offset + 116)
+    number_of_data_directory_entries = struct.unpack('<L', f.read(4))[0]
+    data_directory_offset = f.tell()  # it's right after the number of entries
+
+    # Where is the import table?
+    f.seek(data_directory_offset + 8)
+    rva_of_import_table = struct.unpack('<L', f.read(4))[0]
+
+    # Get the section ranges so we can convert RVAs to file offsets.
+    f.seek(data_directory_offset + 8 * number_of_data_directory_entries)
+    sections = []
+    for i in range(number_of_sections):
+        section_descriptor_data = f.read(40)
+        name, size, va, rawsize, offset = struct.unpack('<8sLLLL', section_descriptor_data[:24])
+        sections.append({'min': va, 'max': va+rawsize, 'offset': offset})
+
+    def seek_to_rva(rva):
+        for s in sections:
+            if s['min'] <= rva and rva < s['max']:
+                f.seek(rva - s['min'] + s['offset'])
+                return
+        raise ValueError, 'Could not find section for RVA.'
+
+    # Walk the import table and get RVAs to the null-terminated names of DLLs this file uses.
+    # The table is terminated by an all-zero entry.
+    seek_to_rva(rva_of_import_table)
+    dll_rvas = []
+    while True:
+        import_descriptor = f.read(20)
+        if import_descriptor == '\0' * 20:
+            break
+        dll_rvas.append(struct.unpack('<L', import_descriptor[12:16])[0])
+
+    # Read the DLL names from the RVAs we found in the import table.
+    dll_names = []
+    for rva in dll_rvas:
+        seek_to_rva(rva)
+        name = ''
+        while True:
+            c = f.read(1)
+            if c == '\0':
+                break
+            name += c
+        dll_names.append(name)
+
+    return dll_names
+
+
+src_contents = os.listdir(sys.argv[1])
+dest_contents = os.listdir(sys.argv[2])
+for dest_name in dest_contents:
+    dest_fname = os.path.join(sys.argv[2], dest_name)
+    if os.path.isfile(dest_fname) and is_pe_file(dest_fname):
+        print dest_name
+        for dll in get_imports(dest_fname):
+            print '- %s' % dll,
+            if dll.lower() in [n.lower() for n in dest_contents]:
+                print '(already present)'
+            else:
+                for n in src_contents:
+                    if n.lower() == dll.lower():
+                        shutil.copyfile(os.path.join(sys.argv[1], n), os.path.join(sys.argv[2], n))
+                        dest_contents.append(n)
+                        print '(copied)'
+                        break
+                else:
+                    print '(assumed to be provided by operating system)'
diff --git a/win32/cross-from-debian/makebuilddir.sh b/win32/cross-from-debian/makebuilddir.sh
new file mode 100755 (executable)
index 0000000..e68eeb9
--- /dev/null
@@ -0,0 +1,4 @@
+#!/bin/sh -e
+mkdir -pv build
+cd build
+exec env PATH="`pwd`/../deps/bin:$PATH" cmake -DCMAKE_TOOLCHAIN_FILE=../Toolchain.cmake -DCMAKE_INSTALL_PREFIX="`pwd`/../stage" "$@" ../../..
diff --git a/win32/cross-from-debian/makedeps.sh b/win32/cross-from-debian/makedeps.sh
new file mode 100755 (executable)
index 0000000..8052d7a
--- /dev/null
@@ -0,0 +1,703 @@
+#!/bin/sh -e
+# Script to cross-compile Performous's dependency libraries for Win32.
+# Copyright (C) 2010 John Stumpo
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+die () { echo "$@" >&2 ; exit 1 ; }
+
+assert_binary_on_path () {
+  if which "$1" >/dev/null 2>&1; then
+    echo found program "$1"
+  else
+    echo did not find "$1", which is required
+    exit 1
+  fi
+}
+
+if test -z "$CROSS_TOOL_PREFIX"; then
+  export CROSS_TOOL_PREFIX=i586-mingw32msvc
+fi
+echo "Using cross compilers prefixed with '$CROSS_TOOL_PREFIX-'."
+echo "(Set CROSS_TOOL_PREFIX to change this; don't include the trailing hyphen.)"
+if test -z "$CROSS_GCC"; then
+  assert_binary_on_path "$CROSS_TOOL_PREFIX"-gcc
+  export CROSS_GCC="$CROSS_TOOL_PREFIX"-gcc
+  assert_binary_on_path "$CROSS_TOOL_PREFIX"-g++
+  export CROSS_GXX="$CROSS_TOOL_PREFIX"-g++
+  assert_binary_on_path "$CROSS_TOOL_PREFIX"-ar
+  export CROSS_AR="$CROSS_TOOL_PREFIX"-ar
+  assert_binary_on_path "$CROSS_TOOL_PREFIX"-ranlib
+  export CROSS_RANLIB="$CROSS_TOOL_PREFIX"-ranlib
+  assert_binary_on_path "$CROSS_TOOL_PREFIX"-ld
+  export CROSS_LD="$CROSS_TOOL_PREFIX"-ld
+  assert_binary_on_path "$CROSS_TOOL_PREFIX"-dlltool
+  export CROSS_DLLTOOL="$CROSS_TOOL_PREFIX"-dlltool
+  assert_binary_on_path "$CROSS_TOOL_PREFIX"-nm
+  export CROSS_NM="$CROSS_TOOL_PREFIX"-nm
+  assert_binary_on_path "$CROSS_TOOL_PREFIX"-windres
+  export CROSS_WINDRES="$CROSS_TOOL_PREFIX"-windres
+fi
+if test -z "$WINE"; then
+  assert_binary_on_path wine
+  export WINE=wine
+fi
+echo "wine: $WINE"
+
+assert_binary_on_path autoreconf
+assert_binary_on_path make
+assert_binary_on_path pkg-config
+assert_binary_on_path svn
+assert_binary_on_path tar
+assert_binary_on_path unzip
+assert_binary_on_path wget
+
+SCRIPTDIR="`pwd`"
+export PREFIX="`pwd`"/deps
+export WINEPREFIX="`pwd`"/wine
+mkdir -pv "$PREFIX"/bin "$PREFIX"/lib "$PREFIX"/include "$PREFIX"/lib/pkgconfig "$PREFIX"/build-stamps
+if test -n "$KEEPTEMP"; then
+  RM_RF=true
+  echo 'Keeping the built source trees, as you requested.'
+else
+  RM_RF="rm -rf"
+  echo 'Unpacked source trees will be removed after compilation.'
+  echo '(Set KEEPTEMP to any value to preserve them.)'
+fi
+
+echo 'setting up wine environment'
+$WINE reg add 'HKCU\Environment' /v PATH /d Z:"`echo "$PREFIX" | tr '/' '\\'`"\\bin
+
+echo 'creating pkg-config wrapper for cross-compiled environment'
+cat >"$PREFIX"/bin/pkg-config <<EOF
+#!/bin/sh -e
+exec env PKG_CONFIG_LIBDIR='$PREFIX'/lib/pkgconfig '`which pkg-config`' "\$@"
+EOF
+chmod -v 0755 "$PREFIX"/bin/pkg-config
+cat >"$PREFIX"/bin/wine-shwrap <<"EOF"
+#!/bin/sh -e
+path="`(cd $(dirname "$1") && pwd)`/`basename "$1"`"
+echo '#!/bin/bash -e' >"$1"
+echo '$WINE '"$path"'.exe "$@" | tr -d '"'\\\015'" >>"$1"
+echo 'exit ${PIPESTATUS[0]}' >>"$1"
+chmod 0755 "$1"
+EOF
+chmod 0755 $PREFIX/bin/wine-shwrap
+
+export PATH="$PREFIX"/bin:"$PATH"
+
+download () {
+  basename="`basename "$1"`"
+  if test ! -f "$basename"; then
+    wget -c -O "$basename".part "$1"
+    mv -v "$basename".part "$basename"
+  fi
+}
+
+# Copy the MinGW support DLL if it's in the Debian place.
+# (Why said place is what it is is beyond me...)
+if test -f /usr/share/doc/mingw32-runtime/mingwm10.dll.gz; then
+  gunzip -cf /usr/share/doc/mingw32-runtime/mingwm10.dll.gz >"$PREFIX"/bin/mingwm10.dll
+else
+  echo "mingwm10.dll is not in the Debian place."
+  echo "If it's needed (it's solely a run-time dependency), you'll have to track"
+  echo "it down yourself and copy it to $PREFIX/bin."
+fi
+
+# We use win-iconv instead of full-fledged GNU libiconv because it still does
+# everything the other deps need and is far smaller.
+WINICONV="win-iconv-0.0.1"
+if test ! -f "$PREFIX"/build-stamps/win-iconv; then
+  download http://win-iconv.googlecode.com/files/$WINICONV.tar.bz2
+  tar jxvf $WINICONV.tar.bz2
+  cd $WINICONV
+  make clean
+  make -n iconv.dll win_iconv.exe | sed -e 's/^/$CROSS_TOOL_PREFIX-/' | sh -ex
+  $CROSS_GCC -mdll -o iconv.dll -Wl,--out-implib,libiconv.a iconv.def win_iconv.o
+  cp -v iconv.dll win_iconv.exe "$PREFIX"/bin
+  cp -v iconv.h "$PREFIX"/include
+  echo '' >>"$PREFIX"/include/iconv.h  # squelch warnings about no newline at the end
+  sed -i -e 's://.*$::' "$PREFIX"/include/iconv.h  # squelch warnings about C++ comments
+  cp -v libiconv.a "$PREFIX"/lib
+  cd ..
+  touch "$PREFIX"/build-stamps/win-iconv
+  $RM_RF $WINICONV
+fi
+
+# zlib
+ZLIB="zlib-1.2.5"
+if test ! -f "$PREFIX"/build-stamps/zlib; then
+  download http://www.zlib.net/$ZLIB.tar.bz2
+  tar jxvf $ZLIB.tar.bz2
+  cd $ZLIB
+  make -f win32/Makefile.gcc PREFIX="$CROSS_TOOL_PREFIX"- zlib1.dll
+  cp -v zlib.h zconf.h "$PREFIX"/include
+  cp -v zlib1.dll "$PREFIX"/bin
+  cp -v libzdll.a "$PREFIX"/lib/libz.a
+  cd ..
+  touch "$PREFIX"/build-stamps/zlib
+  $RM_RF $ZLIB
+fi
+
+# libpng
+LIBPNG="libpng-1.4.4"
+if test ! -f "$PREFIX"/build-stamps/libpng; then
+  download http://download.sourceforge.net/libpng/$LIBPNG.tar.gz
+  tar zxvf $LIBPNG.tar.gz
+  cd $LIBPNG
+  make -f scripts/makefile.mingw prefix="$PREFIX" CC="$CROSS_GCC" AR="$CROSS_AR" RANLIB="$CROSS_RANLIB" ZLIBINC="$PREFIX"/include ZLIBLIB="$PREFIX"/lib install-shared
+  cd ..
+  touch "$PREFIX"/build-stamps/libpng
+  $RM_RF $LIBPNG
+fi
+
+# Flags passed to every dependency's ./configure script, for those deps that use autoconf and friends.
+COMMON_AUTOCONF_FLAGS="--prefix=$PREFIX --host=$CROSS_TOOL_PREFIX --disable-static --enable-shared CPPFLAGS=-I$PREFIX/include LDFLAGS=-L$PREFIX/lib"
+
+# libjpeg
+if test ! -f "$PREFIX"/build-stamps/libjpeg; then
+  download http://www.ijg.org/files/jpegsrc.v8b.tar.gz
+  tar zxvf jpegsrc.v8b.tar.gz
+  cd jpeg-8b
+  ./configure $COMMON_AUTOCONF_FLAGS
+  make
+  make install
+  cd ..
+  touch "$PREFIX"/build-stamps/libjpeg
+  $RM_RF jpeg-8b
+fi
+
+# Runtime (libintl) of GNU Gettext
+GETTEXT="gettext-0.18.1.1"
+if test ! -f "$PREFIX"/build-stamps/gettext-runtime; then
+  download http://ftp.gnu.org/gnu/gettext/$GETTEXT.tar.gz
+  tar zxvf $GETTEXT.tar.gz
+  cd $GETTEXT/gettext-runtime
+  ./configure $COMMON_AUTOCONF_FLAGS --enable-relocatable --disable-libasprintf --disable-java --disable-csharp
+  make
+  make install
+  cd ../..
+  touch "$PREFIX"/build-stamps/gettext-runtime
+  $RM_RF $GETTEXT
+fi
+
+# libxml2
+LIBXML2="libxml2-2.7.7"
+if test ! -f "$PREFIX"/build-stamps/libxml2; then
+  download ftp://xmlsoft.org/libxml2/$LIBXML2.tar.gz
+  tar zxvf $LIBXML2.tar.gz
+  cd $LIBXML2
+  ./configure $COMMON_AUTOCONF_FLAGS --without-python --without-readline
+  make
+  make install
+  cd ..
+  touch "$PREFIX"/build-stamps/libxml2
+  $RM_RF $LIBXML2
+fi
+
+# The bits of Boost that we need.
+BOOST="boost_1_43_0"
+if test ! -f "$PREFIX"/build-stamps/boost; then
+  download http://download.sourceforge.net/boost/$BOOST.tar.bz2
+  tar jxvf $BOOST.tar.bz2
+  cd $BOOST/tools/jam/src
+  ./build.sh
+  cp -v bin.linux*/bjam ../../..
+  cd ../../..
+  cat >>tools/build/v2/user-config.jam <<EOF
+using gcc : debian_mingw32_cross : $CROSS_GXX ;
+EOF
+  ./bjam --prefix="$PREFIX" --with-filesystem --with-system --with-thread --with-date_time --with-program_options --with-regex toolset=gcc-debian_mingw32_cross target-os=windows variant=release link=shared runtime-link=shared threading=multi threadapi=win32 stage
+  cp -av boost "$PREFIX"/include
+  cp -v stage/lib/*.dll "$PREFIX"/bin
+  cp -v stage/lib/*.a "$PREFIX"/lib
+  ln -svf libboost_thread_win32.dll.a "$PREFIX"/lib/libboost_thread.dll.a  # so the cmake scripts detect it correctly
+  cd ..
+  touch "$PREFIX"/build-stamps/boost
+  $RM_RF $BOOST
+fi
+
+# A package of DirectX headers and implibs kindly made available by the
+# SDL folks.  These are used by SDL (to access DirectDraw, DirectSound,
+# and DirectInput) and PortAudio (to access DirectSound).
+if test ! -f "$PREFIX"/build-stamps/directx; then
+  download http://www.libsdl.org/extras/win32/common/directx-source.tar.gz
+  tar zxvf directx-source.tar.gz
+  cd directx
+  sed -i -e "s/dlltool /$CROSS_DLLTOOL /" -e "s/ar /$CROSS_AR /" lib/Makefile
+  make -C lib distclean
+  make -C lib CC="$CROSS_GCC"
+  cp -v include/*.h "$PREFIX"/include
+  cp -v lib/*.a "$PREFIX"/lib
+  cd ..
+  touch "$PREFIX"/build-stamps/directx
+  $RM_RF directx
+fi
+
+# This is the latest svn revision that works with the SDL-provided
+# DirectX header package.
+if test ! -f "$PREFIX"/build-stamps/portaudio; then
+  if test ! -f portaudio/svn-stamp; then
+    svn co -r 1433 http://www.portaudio.com/repos/portaudio/trunk portaudio
+    echo 1433 >portaudio/svn-stamp
+  else
+    if test x"`svn info portaudio | grep '^Revision: '`" != x"Revision: `cat portaudio/svn-stamp`"; then
+      svn revert portaudio/configure portaudio/configure.in
+      svn up -r "`cat portaudio/svn-stamp`" portaudio
+    fi
+  fi
+  cd portaudio
+  echo 'Patching mingw host triplet pattern matching bug in configure.'
+  sed -i -e 's/\**mingw\*.*)/\*&/' configure.in
+  autoreconf
+  ./configure $COMMON_AUTOCONF_FLAGS --with-winapi=directx --with-dxdir="$PREFIX"
+  make
+  make install
+  cd ..
+  touch "$PREFIX"/build-stamps/portaudio
+  $RM_RF portaudio
+fi
+
+# PortMidi, which unfortunately lacks a decent build system.
+# (Yes, I do see the CMakeLists.txt there, but it insists on building
+# some things that won't fly in this environment.)
+if test ! -f "$PREFIX"/build-stamps/portmidi; then
+  download http://download.sourceforge.net/portmedia/portmidi-src-200.zip
+  unzip -o portmidi-src-200.zip
+  cd portmidi
+  $CROSS_GCC -g -O2 -W -Wall -Iporttime -DNDEBUG -D_WINDLL -mdll -o porttime.dll -Wl,--out-implib,libporttime.a porttime/ptwinmm.c -lwinmm
+  $CROSS_GCC -g -O2 -W -Wall -Ipm_common -Iporttime -DNDEBUG -D_WINDLL -mdll -o portmidi.dll -Wl,--out-implib,libportmidi.a pm_win/pmwin.c pm_win/pmwinmm.c pm_common/pmutil.c pm_common/portmidi.c -L. -lporttime -lwinmm
+  cp -v portmidi.dll porttime.dll "$PREFIX"/bin
+  cp -v libportmidi.a libporttime.a "$PREFIX"/lib
+  cp -v pm_common/portmidi.h porttime/porttime.h "$PREFIX"/include
+  cd ..
+  touch "$PREFIX"/build-stamps/portmidi
+  $RM_RF portmidi
+fi
+
+# SDL
+SDL="SDL-1.2.14"
+if test ! -f "$PREFIX"/build-stamps/sdl; then
+  download http://www.libsdl.org/release/$SDL.tar.gz
+  tar zxvf $SDL.tar.gz
+  cd $SDL
+  ./configure $COMMON_AUTOCONF_FLAGS --disable-stdio-redirect
+  make
+  make install
+  cd ..
+  touch "$PREFIX"/build-stamps/sdl
+  $RM_RF $SDL
+fi
+
+# Freetype
+FREETYPE="freetype-2.4.3"
+if test ! -f "$PREFIX"/build-stamps/freetype; then
+  download http://download.sourceforge.net/freetype/$FREETYPE.tar.bz2
+  tar jxvf $FREETYPE.tar.bz2
+  cd $FREETYPE
+  ./configure $COMMON_AUTOCONF_FLAGS
+  make
+  make install
+  cd ..
+  touch "$PREFIX"/build-stamps/freetype
+  $RM_RF $FREETYPE
+fi
+
+# GLib
+GLIB="glib-2.26.0"
+if test ! -f "$PREFIX"/build-stamps/glib; then
+  download http://ftp.gnome.org/pub/GNOME/sources/glib/2.26/$GLIB.tar.bz2
+  tar jxvf $GLIB.tar.bz2
+  cd $GLIB
+  ./configure $COMMON_AUTOCONF_FLAGS
+  make -C glib
+  make -C gthread
+  make -C gobject glib-genmarshal.exe
+  wine-shwrap gobject/glib-genmarshal
+  make
+  make install
+  cd ..
+  touch "$PREFIX"/build-stamps/glib
+  $RM_RF $GLIB
+fi
+
+# Fontconfig
+FONTCONFIG="fontconfig-2.8.0"
+if test ! -f "$PREFIX"/build-stamps/fontconfig; then
+  download http://fontconfig.org/release/$FONTCONFIG.tar.gz
+  tar zxvf $FONTCONFIG.tar.gz
+  cd $FONTCONFIG
+  ./configure $COMMON_AUTOCONF_FLAGS
+  make
+  # It tries to build its initial cache by invoking the installed binary, so make it happy.
+  wine-shwrap "$PREFIX"/bin/fc-cache
+  make install
+  rm -f "$PREFIX"/bin/fc-cache
+  cd ..
+  touch "$PREFIX"/build-stamps/fontconfig
+  $RM_RF $FONTCONFIG
+fi
+
+# Pixman
+PIXMAN="pixman-0.19.6"
+if test ! -f "$PREFIX"/build-stamps/pixman; then
+  download http://cairographics.org/releases/$PIXMAN.tar.gz
+  tar zxvf $PIXMAN.tar.gz
+  cd $PIXMAN
+  ./configure $COMMON_AUTOCONF_FLAGS
+  make
+  make install
+  cd ..
+  touch "$PREFIX"/build-stamps/pixman
+  $RM_RF $PIXMAN
+fi
+
+# Cairo
+CAIRO="cairo-1.8.10"
+if test ! -f "$PREFIX"/build-stamps/cairo; then
+  download http://cairographics.org/releases/$CAIRO.tar.gz
+  tar zxvf $CAIRO.tar.gz
+  cd $CAIRO
+  ./configure $COMMON_AUTOCONF_FLAGS --disable-xlib
+  make
+  make install
+  cd ..
+  touch "$PREFIX"/build-stamps/cairo
+  $RM_RF $CAIRO
+fi
+
+# Pango
+# For some reason, the libraries are installed in an extremely uncharacteristic
+# layout for libtool.  Luckily, we have all that we need to make it sane again.
+PANGO="pango-1.28.3"
+if test ! -f "$PREFIX"/build-stamps/pango; then
+  download http://ftp.gnome.org/pub/GNOME/sources/pango/1.28/$PANGO.tar.bz2
+  tar jxvf $PANGO.tar.bz2
+  cd $PANGO
+  ./configure $COMMON_AUTOCONF_FLAGS --with-included-modules=yes --with-dynamic-modules=no CXX="$CROSS_GXX \"-D__declspec(x)=__attribute__((x))\""
+  make
+  make install
+  for f in '' cairo ft2 win32; do
+    mv "$PREFIX"/lib/libpango$f-1.0-0.dll "$PREFIX"/bin
+    rm -f "$PREFIX"/lib/libpango$f-1.0.lib
+    $CROSS_DLLTOOL -D libpango$f-1.0-0.dll -d "$PREFIX"/lib/pango$f-1.0.def -l "$PREFIX"/lib/libpango$f-1.0.a
+    sed -i -e "s/libpango$f-1.0.lib/libpango$f-1.0.a/g" "$PREFIX"/lib/libpango$f-1.0.la
+  done
+  cd ..
+  touch "$PREFIX"/build-stamps/pango
+  $RM_RF $PANGO
+fi
+
+# ATK
+# We don't really need to build the parts of GTK that use ATK, but GTK's
+# configure script won't be happy otherwise.
+ATK="atk-1.32.0"
+if test ! -f "$PREFIX"/build-stamps/atk; then
+  download http://ftp.gnome.org/pub/GNOME/sources/atk/1.32/$ATK.tar.bz2
+  tar jxvf $ATK.tar.bz2
+  cd $ATK
+  ./configure $COMMON_AUTOCONF_FLAGS --disable-glibtest
+  make
+  make install
+  cd ..
+  touch "$PREFIX"/build-stamps/atk
+  $RM_RF $ATK
+fi
+
+# Gdk-pixbuf
+# New versions of GTK require this separately
+GDKPIXBUF="gdk-pixbuf-2.22.0"
+if test ! -f "$PREFIX"/build-stamps/gdkpixbuf; then
+  download http://ftp.gnome.org/pub/GNOME/sources/gdk-pixbuf/2.22/$GDKPIXBUF.tar.bz2
+  tar jxvf $GDKPIXBUF.tar.bz2
+  cd $GDKPIXBUF
+  ./configure $COMMON_AUTOCONF_FLAGS --without-libtiff
+  make
+  wine-shwrap gdk-pixbuf/gdk-pixbuf-csource
+  wine-shwrap gdk-pixbuf/gdk-pixbuf-query-loaders
+  make install
+  cd ..
+  touch "$PREFIX"/build-stamps/gdkpixbuf
+  $RM_RF $ATK
+fi
+
+# GTK
+# Even though Performous only needs libgdk_pixbuf (and then only because
+# that's how librsvg likes to play ball), having the rest of GTK around
+# lets other packages build some handy test programs that can be run
+# under Wine to sanity-check the dependency build.  The choice of included
+# pixbuf loaders is tailored to satisfy said programs.
+GTK="gtk+-2.22.0"
+if test ! -f "$PREFIX"/build-stamps/gtk; then
+  download http://ftp.gnome.org/pub/GNOME/sources/gtk+/2.22/$GTK.tar.bz2
+  tar jxvf $GTK.tar.bz2
+  cd $GTK
+  ./configure $COMMON_AUTOCONF_FLAGS --disable-glibtest --disable-modules --without-libtiff --with-included-loaders=png,jpeg,gif,xpm,xbm
+  make -C gdk
+  make -C gtk gtk-update-icon-cache.exe
+  wine-shwrap gtk/gtk-update-icon-cache
+  make -C gtk gtk-query-immodules-2.0.exe
+  wine-shwrap gtk/gtk-query-immodules-2.0
+  make
+  make install
+  find "$PREFIX"/lib/gtk-2.0 -name '*.la' -print0 | xargs -0 rm -f
+  find "$PREFIX"/lib/gtk-2.0 -name '*.dll.a' -print0 | xargs -0 rm -f
+  # Use the Wimp (native Windows widgets) theme.
+  cp "$PREFIX"/share/themes/MS-Windows/gtk-2.0/gtkrc "$PREFIX"/etc/gtk-2.0
+  cd ..
+  touch "$PREFIX"/build-stamps/gtk
+  $RM_RF $GTK
+fi
+
+# libcroco
+LIBCROCO="libcroco-0.6.2"
+if test ! -f "$PREFIX"/build-stamps/libcroco; then
+  download http://ftp.gnome.org/pub/GNOME/sources/libcroco/0.6/$LIBCROCO.tar.bz2
+  tar jxvf $LIBCROCO.tar.bz2
+  cd $LIBCROCO
+  # We bypass a file magick check here
+  lt_cv_deplibs_check_method=pass_all ./configure $COMMON_AUTOCONF_FLAGS
+  make
+  make install
+  cd ..
+  touch "$PREFIX"/build-stamps/libcroco
+  $RM_RF $LIBCROCO
+fi
+
+# libgsf
+# It will try to install a gconf schema on the host unless we tell it not to,
+# despite the fact that it doesn't have the GNOME libraries it would need to
+# make any use of it...
+LIBGSF="libgsf-1.14.19"
+if test ! -f "$PREFIX"/build-stamps/libgsf; then
+  download http://ftp.gnome.org/pub/GNOME/sources/libgsf/1.14/$LIBGSF.tar.bz2
+  tar jxvf $LIBGSF.tar.bz2
+  cd $LIBGSF
+  ./configure $COMMON_AUTOCONF_FLAGS --without-python --disable-schemas-install
+  make
+  make install
+  cd ..
+  touch "$PREFIX"/build-stamps/libgsf
+  $RM_RF $LIBGSF
+fi
+
+# librsvg
+LIBRSVG="librsvg-2.32.0"
+if test ! -f "$PREFIX"/build-stamps/librsvg; then
+  download http://ftp.gnome.org/pub/GNOME/sources/librsvg/2.32/$LIBRSVG.tar.bz2
+  tar jxvf $LIBRSVG.tar.bz2
+  cd $LIBRSVG
+  ./configure $COMMON_AUTOCONF_FLAGS --disable-pixbuf-loader --disable-gtk-theme
+  make
+  make install
+  cd ..
+  touch "$PREFIX"/build-stamps/librsvg
+  $RM_RF $LIBRSVG
+fi
+
+# libsigc++
+LIBSIGCPP="libsigc++-2.2.8"
+if test ! -f "$PREFIX"/build-stamps/libsigc++; then
+  download http://ftp.gnome.org/pub/GNOME/sources/libsigc++/2.2/$LIBSIGCPP.tar.bz2
+  tar jxvf $LIBSIGCPP.tar.bz2
+  cd $LIBSIGCPP
+  ./configure $COMMON_AUTOCONF_FLAGS
+  make
+  make install
+  cd ..
+  touch "$PREFIX"/build-stamps/libsigc++
+  $RM_RF $LIBSIGCPP
+fi
+
+# libglibmm
+GLIBMM="glibmm-2.25.2"
+if test ! -f "$PREFIX"/build-stamps/libglibmm; then
+  download http://ftp.gnome.org/pub/GNOME/sources/glibmm/2.25/$GLIBMM.tar.bz2
+  tar jxvf $GLIBMM.tar.bz2
+  cd $GLIBMM
+  ./configure $COMMON_AUTOCONF_FLAGS
+  make
+  make install
+  cd ..
+  touch "$PREFIX"/build-stamps/libglibmm
+  $RM_RF $GLIBMM
+fi
+
+# libxml++
+LIBXMLPP="libxml++-2.32.0"
+if test ! -f "$PREFIX"/build-stamps/libxml++; then
+  download http://ftp.gnome.org/pub/GNOME/sources/libxml++/2.32/$LIBXMLPP.tar.bz2
+  tar jxvf $LIBXMLPP.tar.bz2
+  cd $LIBXMLPP
+  ./configure $COMMON_AUTOCONF_FLAGS
+  make
+  make install
+  cd ..
+  touch "$PREFIX"/build-stamps/libxml++
+  $RM_RF $LIBXMLPP
+fi
+
+# GLEW, which lacks a build system amenable to cross-compilation.
+# glewinfo and visualinfo are handy if you ever need something
+# similar to glxinfo under Windows.
+GLEW="glew-1.5.6"
+if test ! -f "$PREFIX"/build-stamps/glew; then
+  download http://download.sourceforge.net/glew/$GLEW.tgz
+  tar zxvf $GLEW.tgz
+  cd $GLEW
+  $CROSS_WINDRES -o glewres.o build/vc6/glew.rc
+  $CROSS_GCC -g -O2 -W -Wall -Iinclude -DGLEW_BUILD -mdll -Wl,--out-implib,libGLEW.a -o glew32.dll src/glew.c glewres.o -lopengl32 -lglu32 -lgdi32
+  $CROSS_WINDRES -o glewinfores.o build/vc6/glewinfo.rc
+  $CROSS_GCC -g -O2 -W -Wall -Iinclude -o glewinfo.exe src/glewinfo.c glewinfores.o -L. -lGLEW -lopengl32 -lglu32 -lgdi32
+  $CROSS_WINDRES -o visualinfores.o build/vc6/visualinfo.rc
+  $CROSS_GCC -g -O2 -W -Wall -Iinclude -o visualinfo.exe src/visualinfo.c visualinfores.o -L. -lGLEW -lopengl32 -lglu32 -lgdi32
+  make GLEW_DEST="$PREFIX" glew.pc
+  cp -v glew32.dll glewinfo.exe visualinfo.exe "$PREFIX"/bin
+  cp -v libGLEW.a "$PREFIX"/lib
+  mkdir -pv "$PREFIX"/include/GL "$PREFIX"/lib/pkgconfig
+  cp -v include/GL/* "$PREFIX"/include/GL
+  cp -v glew.pc "$PREFIX"/lib/pkgconfig
+  cd ..
+  touch "$PREFIX"/build-stamps/glew
+  $RM_RF $GLEW
+fi
+
+# ImageMagick
+# Needed for tools (ss_extract) only.
+IM="ImageMagick-6.6.5-5"
+if test ! -f "$PREFIX"/build-stamps/imagemagick; then
+  download http://image_magick.veidrodis.com/image_magick/ImageMagick-6.6.5-5.tar.bz2
+  tar jxvf $IM.tar.bz2
+  cd $IM
+  ./configure $COMMON_AUTOCONF_FLAGS --without-rsvg --without-gslib --without-gvc --without-wmf --without-frozenpaths --without-x
+  make
+  make install
+  cd ..
+  touch "$PREFIX"/build-stamps/imagemagick
+  $RM_RF $IM
+fi
+
+# liborc
+LIBORC="orc-0.4.10"
+if test ! -f "$PREFIX"/build-stamps/liborc; then
+  download http://code.entropywave.com/download/orc/$LIBORC.tar.gz
+  tar zxvf $LIBORC.tar.gz
+  cd $LIBORC
+  ./configure $COMMON_AUTOCONF_FLAGS
+  make
+  make install
+  cd ..
+  touch "$PREFIX"/build-stamps/liborc
+  $RM_RF $LIBORC
+fi
+
+# libschroedinger
+LIBSCHROE="schroedinger-1.0.10"
+if test ! -f "$PREFIX"/build-stamps/libschroedinger; then
+  download http://diracvideo.org/download/schroedinger/$LIBSCHROE.tar.gz
+  tar zxvf $LIBSCHROE.tar.gz
+  cd $LIBSCHROE
+  ./configure $COMMON_AUTOCONF_FLAGS
+  # We don't want testsuite, so create a dummy Makefile
+  echo "all:\n\ninstall:" > testsuite/Makefile
+  make
+  make install
+  cd ..
+  touch "$PREFIX"/build-stamps/libschroedinger
+  $RM_RF $LIBSCHROE
+fi
+
+# FFmpeg
+# The only external library I have gone out of my way to add is
+# libschroedinger because it needs it to decode Dirac, and not having
+# at least decode support for all free formats would be sad.  (Speaking of
+# free format support, I skipped the Xiph libs and libvpx because they're
+# only needed for *encoding* the relevant formats; ffmpeg's native VP8
+# (WebM) decoding support is suboptimal but passable at the time of this
+# writing and can only improve from here, and since we use latest SVN at
+# time of build (as the ffmpeg developers suggest), we get the improvements
+# automatically with a dep rebuild.)
+if test ! -f "$PREFIX"/build-stamps/ffmpeg; then
+  if test ! -d ffmpeg; then
+    svn co svn://svn.ffmpeg.org/ffmpeg/trunk ffmpeg
+  else
+    svn up ffmpeg
+  fi
+  cd ffmpeg
+  ./configure --prefix="$PREFIX" --cc="$CROSS_GCC" --nm="$CROSS_NM" --target-os=mingw32 --arch=i386 --disable-static --enable-shared --enable-gpl --enable-postproc --enable-w32threads --enable-runtime-cpudetect --enable-memalign-hack --enable-zlib --enable-libschroedinger --extra-cflags="-I$PREFIX/include" --extra-ldflags="-L$PREFIX/lib"
+  sed -i -e 's/-Werror=[^ ]*//g' config.mak
+  make
+  make install
+  for lib in avcodec avdevice avfilter avformat avutil postproc swscale; do
+    # FFmpeg symlinks its DLLs to a few different names, differing in the level
+    # of detail of their version number, rather like what is done with ELF shared
+    # libraries.  Unfortunately, the real DLL for each one is *not* the one that
+    # the implibs reference (that is, the one that will be required at runtime),
+    # so we must rename it after we nuke the symlinks.
+    find "$PREFIX"/bin -type l -name "${lib}*.dll" -print0 | xargs -0 rm -f
+    libfile="`find "$PREFIX"/bin -name "${lib}*.dll" | sed -e 1q`"
+    mv -v "$libfile" "`echo "$libfile" | sed -e "s/\($lib-[0-9]*\)[.0-9]*\.dll/\1.dll/"`"
+  done
+  cd ..
+  touch "$PREFIX"/build-stamps/ffmpeg
+  $RM_RF ffmpeg
+fi
+
+# VideoInput
+# This is support library for OpenCV to get video input on Windows.
+# This is only needed if you want OpenCV.
+VIDEOINPUT="videoInput0.1995"
+if test ! -f "$PREFIX"/build-stamps/videoinput; then
+  download http://muonics.net/school/spring05/videoInput/files/$VIDEOINPUT.zip
+  unzip -o $VIDEOINPUT.zip
+  # We don't bother compiling this since it has precompiled lib and would
+  # probably be a pain in the ass.
+  cp -v $VIDEOINPUT/compiledLib/compiledByDevCpp/*.a "$PREFIX"/lib
+  cp -v $VIDEOINPUT/compiledLib/compiledByDevCpp/include/*.h "$PREFIX"/include
+  touch "$PREFIX"/build-stamps/videoinput
+  $RM_RF $VIDEOINPUT
+fi
+
+# OpenCV
+# This is optional and is used to enable webcam features.
+OPENCV="OpenCV-2.1.0"
+if test ! -f "$PREFIX"/build-stamps/opencv; then
+  download http://download.sourceforge.net/opencvlibrary/$OPENCV-win.zip
+  unzip -o $OPENCV-win.zip
+  cd $OPENCV
+  ln -s "$PREFIX/include/videoInput.h" src/highgui/videoinput.h
+  mkdir -pv build
+  cd build
+  cmake \
+    -DCMAKE_TOOLCHAIN_FILE="$SCRIPTDIR/Toolchain.cmake" \
+       -DBUILD_NEW_PYTHON_SUPPORT=OFF \
+       -DBUILD_TESTS=OFF \
+       -DWITH_JASPER=OFF -DWITH_JPEG=OFF -DWITH_PNG=OFF -DWITH_TBB=OFF -DWITH_TIFF=OFF \
+    -DCMAKE_INSTALL_PREFIX="$PREFIX" \
+    ..
+  make
+  make install
+  cp -v unix-install/opencv.pc "$PREFIX"/lib/pkgconfig  # No auto-install :(
+  cd "$PREFIX"/lib
+  # Create some symlinks so the cmake scripts detect it correctly
+  ln -svf libcv210.dll.a libcv.dll.a
+  ln -svf libcxcore210.dll.a libcxcore.dll.a
+  ln -svf libcvaux210.dll.a libcvaux.dll.a
+  ln -svf libhighgui210.dll.a libhighgui.dll.a
+  cd "$PREFIX/.."
+  touch "$PREFIX"/build-stamps/opencv
+  $RM_RF $OPENCV
+fi
+
+echo "All dependencies done."
diff --git a/win32/cross-from-debian/makepackage.py b/win32/cross-from-debian/makepackage.py
new file mode 100755 (executable)
index 0000000..2277820
--- /dev/null
@@ -0,0 +1,129 @@
+#!/usr/bin/env python
+# NSIS script generator for Performous.
+# Copyright (C) 2010 John Stumpo
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+import os
+import subprocess
+import sys
+
+try:
+    makensis = subprocess.Popen([os.environ['MAKENSIS'], '-'], stdin=subprocess.PIPE)
+except KeyError:
+    makensis = subprocess.Popen(['makensis', '-'], stdin=subprocess.PIPE)
+
+if not os.path.isdir('dist'):
+    os.mkdir('dist')
+os.chdir('stage')
+
+# Find the version number.
+try:
+    resources = subprocess.Popen([os.environ['WINDRES'], 'bin/performous.exe'], stdout=subprocess.PIPE)
+except:
+    try:
+        resources = subprocess.Popen(['windres', 'bin/performous.exe'], stdout=subprocess.PIPE)
+    except:
+        resources = subprocess.Popen(['i586-mingw32msvc-windres', 'bin/performous.exe'], stdout=subprocess.PIPE)
+for line in resources.stdout.readlines():
+    if not line.strip().startswith('VALUE'):
+        continue
+    if 'ProductVersion' in line:
+        version = line.strip().split('"')[-2]
+        break
+else:
+    version = 'unknown'
+
+
+makensis.stdin.write(r'''!include "MUI2.nsh"
+
+!define VERSION "%s"
+
+Name "Performous ${VERSION}"
+OutFile "dist\Performous-${VERSION}.exe"
+
+SetCompressor /SOLID lzma
+
+ShowInstDetails show
+ShowUninstDetails show
+
+InstallDir "$PROGRAMFILES\Performous"
+InstallDirRegKey HKLM "Software\Performous" ""
+
+RequestExecutionLevel admin
+
+!insertmacro MUI_PAGE_WELCOME
+!insertmacro MUI_PAGE_DIRECTORY
+!insertmacro MUI_PAGE_INSTFILES
+!insertmacro MUI_PAGE_FINISH
+
+!insertmacro MUI_UNPAGE_WELCOME
+!insertmacro MUI_UNPAGE_CONFIRM
+!insertmacro MUI_UNPAGE_INSTFILES
+!insertmacro MUI_UNPAGE_FINISH
+
+!insertmacro MUI_LANGUAGE "English"
+
+Section
+''' % version)
+
+for root, dirs, files in os.walk('.'):
+    makensis.stdin.write('  SetOutPath "$INSTDIR\\%s"\n' % root.replace('/', '\\'))
+    for file in files:
+        makensis.stdin.write('  File "%s"\n' % os.path.join('stage', root, file).replace('/', '\\'))
+
+makensis.stdin.write(r'''  WriteRegStr HKLM "Software\Performous" "" "$INSTDIR"
+  WriteUninstaller "$INSTDIR\uninst.exe"
+  SetShellVarContext all
+  CreateDirectory "$INSTDIR\songs"
+  CreateDirectory "$SMPROGRAMS\Performous"
+  CreateShortcut "$SMPROGRAMS\Performous\Performous.lnk" "$INSTDIR\bin\performous.exe"
+  CreateShortCut "$SMPROGRAMS\Performous\ConfigureSongDirectory.lnk" "$INSTDIR\bin\ConfigureSongDirectory.bat"
+  CreateShortCut "$SMPROGRAMS\Performous\Songs.lnk" "$INSTDIR\songs"
+  CreateShortcut "$SMPROGRAMS\Performous\Uninstall.lnk" "$INSTDIR\uninst.exe"
+  WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\Performous" "DisplayName" "Performous"
+  WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\Performous" "UninstallString" "$\"$INSTDIR\uninst.exe$\""
+  WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\Performous" "DisplayIcon" "$INSTDIR\bin\performous.exe"
+  WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\Performous" "DisplayVersion" "${VERSION}"
+SectionEnd
+
+Section Uninstall
+''')
+
+for root, dirs, files in os.walk('.', topdown=False):
+    for dir in dirs:
+        makensis.stdin.write('  RmDir "$INSTDIR\\%s"\n' % os.path.join(root, dir).replace('/', '\\'))
+    for file in files:
+        makensis.stdin.write('  Delete "$INSTDIR\\%s"\n' % os.path.join(root, file).replace('/', '\\'))
+    makensis.stdin.write('  RmDir "$INSTDIR\\%s"\n' % root.replace('/', '\\'))
+
+makensis.stdin.write(r'''  Delete "$INSTDIR\uninst.exe"
+  RmDir "$INSTDIR"
+  SetShellVarContext all
+  Delete "$SMPROGRAMS\Performous\Performous.lnk"
+  Delete "$SMPROGRAMS\Performous\ConfigureSongDirectory.lnk"
+  Delete "$SMPROGRAMS\Performous\Songs.lnk"
+  Delete "$SMPROGRAMS\Performous\Uninstall.lnk"
+  RmDir "$SMPROGRAMS\Performous"
+  DeleteRegKey HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\Performous"
+  DeleteRegKey /ifempty HKLM "Software\Performous"
+SectionEnd
+''')
+
+makensis.stdin.close()
+if makensis.wait() != 0:
+    print >>sys.stderr, 'Installer compilation failed.'
+    sys.exit(1)
+else:
+    print '\ndist/Performous-%s.exe is ready.' % version
diff --git a/win32/gcc/README b/win32/gcc/README
new file mode 100644 (file)
index 0000000..5206aa9
--- /dev/null
@@ -0,0 +1,40 @@
+This script automatically build dependencies of Performous (except Boost).
+
+To install boost libraries:
+       Boost libraries (http://www.boost.org/)
+               If you want, you can use the precompiled one, but I don't like it,
+               so I compiled it by myself (long, a lot of time and space, but not difficult)
+               To compile these libraries, you'll need bjam utility
+                 (http://sourceforge.net/projects/boost/files/boost-jam/3.1.9/bjam-3.1.9-1-ntx86.zip/download)
+               unzip bjam in you Boost sources, and run the command
+                 bjam --build-type=complete --toolset=gcc install (not sure, but think this is :))
+               And (by default) it will install Boost into C:\Boost (if you are using Vista, remember the UAC)
+
+Then, I suppose that you installed MinGW + MSYS
+Quick guide:
+       GCC compiler
+               MinGW suite (http://www.mingw.org) INSTALL ONLY GCC AND G++!!!
+       To run the ./configure scripts of libraries, the MSYS 
+               (http://sourceforge.net/projects/mingw/files/MSYS Base System/Current Release_ MSYS-1.0.11/MSYS-1.0.11.exe/download)
+       and the MSYSDTK
+               (http://sourceforge.net/projects/mingw/files/MSYS Supplementary Tools/msysDTK-1.0.1/msysDTK-1.0.1.exe/download).
+       
+       Upgrade to version 4.4.0 of GCC
+               https://sourceforge.net/projects/mingw/files/GCC%20Version%204/Current%20Release_%20gcc-4.4.0/gcc-ada-4.4.0-mingw32-dll.tar.gz/download
+               https://sourceforge.net/projects/mingw/files/GCC%20Version%204/Current%20Release_%20gcc-4.4.0/gcc-ada-4.4.0-mingw32-bin.tar.gz/download
+               https://sourceforge.net/projects/mingw/files/GCC%20Version%204/Current%20Release_%20gcc-4.4.0/gcc-c%2B%2B-4.4.0-mingw32-bin.tar.gz/download
+               https://sourceforge.net/projects/mingw/files/GCC%20Version%204/Current%20Release_%20gcc-4.4.0/gcc-c%2B%2B-4.4.0-mingw32-dll.tar.gz/download
+               https://sourceforge.net/projects/mingw/files/GCC%20Version%204/Current%20Release_%20gcc-4.4.0/gcc-core-4.4.0-mingw32-bin.tar.gz/download
+               https://sourceforge.net/projects/mingw/files/GCC%20Version%204/Current%20Release_%20gcc-4.4.0/gcc-core-4.4.0-mingw32-dll.tar.gz/download
+               
+       
+Launch MSYS, then move to performous folder
+       cd /where/performous/folder/win32
+       ./install.sh
+       
+       Wait about 3 hours
+       (maybe some problem with ImageMagick and rpcndrt.h, but I can't verify them. Google it if you get error about boolean typedef)
+       
+       Good! Now you can start to compile performous :)
+       
+For trouble, contact us at #performous on irc.freenode.net
\ No newline at end of file
diff --git a/win32/gcc/gettext-0.17-variables.patch b/win32/gcc/gettext-0.17-variables.patch
new file mode 100644 (file)
index 0000000..3e9cdcc
--- /dev/null
@@ -0,0 +1,12 @@
+--- gettext-tools/woe32dll/gettextlib-exports.c        2009-09-10 14:02:30 +0000
++++ gettext-tools/woe32dll/gettextlib-exports.c        2009-09-10 14:03:47 +0000
+@@ -26,7 +26,7 @@
+ VARIABLE(gl_array_list_implementation)
+ VARIABLE(gl_linkedhash_list_implementation)
+ VARIABLE(program_name)
+-VARIABLE(rpl_optarg)
+-VARIABLE(rpl_optind)
++/*VARIABLE(rpl_optarg)
++VARIABLE(rpl_optind)*/
+ VARIABLE(simple_backup_suffix)
+ VARIABLE(styled_ostream_typeinfo)
diff --git a/win32/gcc/install.sh b/win32/gcc/install.sh
new file mode 100644 (file)
index 0000000..69971d7
--- /dev/null
@@ -0,0 +1,349 @@
+#!/bin/sh 
+
+#The root of you build directory for dependencies
+BUILD_DIR=/build
+
+#Internal script variable
+INSTALL_DIR=
+
+#Each time we install a library, add the necessary paths
+add_paths(){
+       PATH=$PATH:$BUILD_DIR/$INSTALL_DIR/bin
+       CPATH=$CPATH:$BUILD_DIR/$INSTALL_DIR/include
+       LIBRARY_PATH=$LIBRARY_PATH:$BUILD_DIR/$INSTALL_DIR/lib
+       PKG_CONFIG_PATH=$PKG_CONFIG_PATH:$BUILD_DIR/$INSTALL_DIR/lib/pkgconfig
+}
+
+download(){
+       filename=$1
+       filename=${filename##*/}
+       if ! test -e filename #file not exists, download it
+       then
+               wget $1
+       fi
+}
+
+#Resolve the libstdc++.dll problem
+patch -p0 < mingw-libstdc++.patch
+patch -p0 < mingw-cwchar.patch
+
+#Install the pkg-config pre-built
+cp pkg-config.exe /mingw/bin/pkg-config.exe
+
+
+#****************
+#***   zlib   ***
+#****************
+download http://www.zlib.net/zlib-1.2.3.tar.gz
+tar xzf zlib-1.2.3.tar.gz
+cd zlib-1.2.3
+       INSTALL_DIR=zlib-1.2.3
+       
+       ./configure --prefix=$BUILD_DIR/$INSTALL_DIR && make && make install
+       mkdir -p $BUILD_DIR/$INSTALL_DIR/bin
+       gcc -shared -o $BUILD_DIR/$INSTALL_DIR/bin/zlib1.dll -Wl,--out-implib=$BUILD_DIR/$INSTALL_DIR/lib/libz.dll.a [!em]*.o
+       add_paths
+cd ..
+
+#****************
+#**  libiconv  **
+#****************
+download http://ftp.gnu.org/pub/gnu/libiconv/libiconv-1.13.1.tar.gz
+tar xzf libiconv-1.13.1.tar.gz
+cd libiconv-1.13.1
+       INSTALL_DIR=libiconv-1.13.1
+       
+       ./configure --prefix=$BUILD_DIR/$INSTALL_DIR && make && make install
+       add_paths
+cd ..
+
+#*****************
+#***  gettext  ***
+#*****************
+download http://ftp.gnu.org/pub/gnu/gettext/gettext-0.17.tar.gz
+tar xzf gettext-0.17.tar.gz
+cd gettext-0.17
+       INSTALL_DIR=gettext-0.17
+       
+       patch -p0 < ../gettext-0.17-variables.patch
+       ./configure --prefix=$BUILD_DIR/$INSTALL_DIR --enable-threads=win32 --enable-relocatable && make && make install
+       add_paths
+cd ..
+
+#******************
+#****   glib   ****
+#******************
+download http://ftp.gnome.org/pub/gnome/sources/glib/2.22/glib-2.22.2.tar.gz
+tar xzf glib-2.22.2.tar.gz
+cd glib-2.22.2
+       INSTALL_DIR=glib-2.22.2
+       
+       ./configure --prefix=$BUILD_DIR/$INSTALL_DIR --with-threads=win32 --with-pcre=internal && make && make install
+       add_paths
+cd ..
+
+#******************
+#****  libpng  ****
+#******************
+download http://freefr.dl.sourceforge.net/project/libpng/00-libpng-stable/1.2.40/libpng-1.2.40.tar.gz
+tar xzf libpng-1.2.40.tar.gz
+cd libpng-1.2.40
+       INSTALL_DIR=libpng-1.2.40
+       
+       ./configure --prefix=$BUILD_DIR/$INSTALL_DIR && make && make install
+       add_paths
+cd ..
+
+#*******************
+#****  libjpeg  ****
+#*******************
+download http://www.ijg.org/files/jpegsrc.v7.tar.gz
+tar xzf jpegsrc.v7.tar.gz
+cd jpeg-7
+       INSTALL_DIR=jpeg-7
+       
+       ./configure --prefix=$BUILD_DIR/$INSTALL_DIR && make && make install
+       add_paths
+cd ..
+
+#*******************
+#****  libtiff  ****
+#*******************
+download ftp://ftp.remotesensing.org/pub/libtiff/tiff-3.9.1.tar.gz
+tar xzf tiff-3.9.1.tar.gz
+cd tiff-3.9.1
+       INSTALL_DIR=tiff-3.9.1
+       
+       ./configure --prefix=$BUILD_DIR/$INSTALL_DIR && make && make install
+       add_paths
+cd ..
+
+#********************
+#****  freetype  ****
+#********************
+download http://ignum.dl.sourceforge.net/project/freetype/freetype2/2.3.11/freetype-2.3.11.tar.gz
+tar xzf freetype-2.3.11.tar.gz
+cd freetype-2.3.11
+       INSTALL_DIR=freetype-2.3.11
+       
+       ./configure --prefix=$BUILD_DIR/$INSTALL_DIR && make && make install
+       add_paths
+cd ..
+
+#******************
+#****  libxml  ****
+#******************
+# Don't use last version, seems broken. This is the last that works with libxml++
+download ftp://xmlsoft.org/libxml2/libxml2-2.7.3.tar.gz
+tar xzf libxml2-2.7.3.tar.gz
+cd libxml2-2.7.3
+       INSTALL_DIR=libxml2-2.7.3
+       
+       ./configure --prefix=$BUILD_DIR/$INSTALL_DIR --without-threads && make && make install
+       add_paths
+cd ..
+
+#********************
+#***  fontconfig  ***
+#********************
+download http://fontconfig.org/release/fontconfig-2.8.0.tar.gz
+tar xzf fontconfig-2.8.0.tar.gz
+cd fontconfig-2.8.0
+       INSTALL_DIR=fontconfig-2.8.0
+       
+       mkdir $BUILD_DIR/$INSTALL_DIR/lib
+       ./configure --prefix=$BUILD_DIR/$INSTALL_DIR --enable-libxml2 && make && make install
+       add_paths
+cd ..
+
+#*******************
+#*****   atk   *****
+#*******************
+download http://ftp.gnome.org/pub/gnome/sources/atk/1.29/atk-1.29.2.tar.gz
+tar xzf atk-1.29.2.tar.gz
+cd atk-1.29.2
+       INSTALL_DIR=atk-1.29.2
+       
+       mkdir $BUILD_DIR/$INSTALL_DIR/lib
+       ./configure --prefix=$BUILD_DIR/$INSTALL_DIR && make && make install
+       add_paths
+cd ..
+
+#******************
+#****  pixman  ****
+#******************
+download http://cairographics.org/releases/pixman-0.17.2.tar.gz
+tar xzf pixman-0.17.2.tar.gz
+cd pixman-0.17.2
+       INSTALL_DIR=pixman-0.17.2
+       
+       ./configure --prefix=$BUILD_DIR/$INSTALL_DIR && make && make install
+       add_paths
+cd ..
+
+#*****************
+#****  cairo  ****
+#*****************
+download http://cairographics.org/releases/cairo-1.8.8.tar.gz
+tar xzf cairo-1.8.8.tar.gz
+cd cairo-1.8.8
+       INSTALL_DIR=cairo-1.8.8
+       
+       ./configure --prefix=$BUILD_DIR/$INSTALL_DIR --disable-pthread && make && make install
+       add_paths
+cd ..
+
+#*****************
+#****  pango  ****
+#*****************
+download http://ftp.gnome.org/pub/GNOME/sources/pango/1.26/pango-1.26.1.tar.gz
+tar xzf pango-1.26.1.tar.gz
+cd pango-1.26.1
+       INSTALL_DIR=pango-1.26.1
+       
+       ./configure --prefix=$BUILD_DIR/$INSTALL_DIR --with-included-modules=yes && make && make install
+       add_paths
+cd ..
+
+#****************
+#****  gtk+  ****
+#****************
+download http://ftp.gnome.org/pub/gnome/sources/gtk+/2.19/gtk+-2.19.0.tar.gz
+tar xzf gtk+-2.19.0.tar.gz
+cd gtk+-2.19.0
+       INSTALL_DIR=gtk+-2.19.0
+       
+       ./configure --prefix=$BUILD_DIR/$INSTALL_DIR --with-gdktarget=win32 --disable-gdiplus --with-included-immodules --without-libjasper --enable-debug=yes --enable-explicit-deps=no --disable-gtk-doc --disable-static && make && make install
+       add_paths
+cd ..
+
+#*******************
+#****  librsvg  ****
+#*******************
+download http://ftp.gnome.org/pub/GNOME/sources/librsvg/2.26/librsvg-2.26.0.tar.gz
+tar xzf librsvg-2.26.0.tar.gz
+cd librsvg-2.26.0
+       INSTALL_DIR=librsvg-2.26.0
+       
+       ./configure --prefix=$BUILD_DIR/$INSTALL_DIR && make && make install
+       add_paths
+cd ..
+
+#*******************
+#******  sdl  ******
+#*******************
+download http://www.libsdl.org/release/SDL-1.2.14.tar.gz
+tar xzf SDL-1.2.14.tar.gz
+cd SDL-1.2.14
+       INSTALL_DIR=SDL-1.2.14
+       
+       ./configure --prefix=$BUILD_DIR/$INSTALL_DIR && make && make install
+       add_paths
+cd ..
+
+#*******************
+#***  libsigc++  ***
+#*******************
+download http://ftp.gnome.org/pub/GNOME/sources/libsigc++/2.2/libsigc++-2.2.4.tar.gz
+tar xzf libsigc++-2.2.4.tar.gz
+cd libsigc++-2.2.4
+       INSTALL_DIR=libsigc++-2.2.4
+       
+       ./configure --prefix=$BUILD_DIR/$INSTALL_DIR && make && make install
+       add_paths
+cd ..
+
+#******************
+#****  glibmm  ****
+#******************
+download http://ftp.gnome.org/pub/GNOME/sources/glibmm/2.22/glibmm-2.22.1.tar.gz
+tar xzf glibmm-2.22.1.tar.gz
+cd glibmm-2.22.1
+       INSTALL_DIR=glibmm-2.22.1
+       
+       ./configure --prefix=$BUILD_DIR/$INSTALL_DIR && make && make install
+       add_paths
+cd ..
+
+#******************
+#***  libxml++  ***
+#******************
+download http://ftp.gnome.org/pub/GNOME/sources/libxml++/2.26/libxml++-2.26.1.tar.gz
+tar xzf libxml++-2.26.1.tar.gz
+cd libxml++-2.26.1
+       INSTALL_DIR=libxml++-2.26.1
+       
+       ./configure --prefix=$BUILD_DIR/$INSTALL_DIR && make && make install
+       add_paths
+cd ..
+
+#*********************
+#***  ImageMagick  ***
+#*********************
+download ftp://ftp.imagemagick.org/pub/ImageMagick/ImageMagick-6.5.8-2.tar.gz
+tar xzf ImageMagick-6.5.8-2.tar.gz
+cd ImageMagick-6.5.8-2
+       INSTALL_DIR=ImageMagick-6.5.8-2
+       
+       LDFLAGS="-L/build/zlib-1.2.3/lib $LDFLAGS" ./configure --prefix=$BUILD_DIR/$INSTALL_DIR --disable-dependency-tracking --disable-installed --enable-delegate-build --disable-shared --enable-static --enable-libtool-verbose --without-rsvg --without-gslib --without-gvc --without-wmf --without-frozenpaths --without-x --disable-openmp && make && make install
+       add_paths
+cd ..
+
+#********************
+#***     GLEW     ***
+#********************
+download http://surfnet.dl.sourceforge.net/project/glew/glew/1.5.1/glew-1.5.1-src.tgz
+tar xzf glew-1.5.1-src.tgz
+cd glew
+       INSTALL_DIR=glew-1.5.1
+       
+       make
+       
+       mkdir -p $BUILD/$INSTALL_DIR/bin
+       mkdir -p $BUILD/$INSTALL_DIR/lib
+       mkdir -p $BUILD/$INSTALL_DIR/include
+       cp bin/*.exe /mingw/bin
+       cp lib/glew32.dll $BUILD/$INSTALL_DIR/bin/glew32.dll
+       cp lib/libglew32.a $BUILD/$INSTALL_DIR/lib/libglew32.a
+       cp lib/libglew32.dll.a $BUILD/$INSTALL_DIR/lib/libglew32.dll.a
+       cp include/* $BUILD/$INSTALL_DIR/include/
+       add_paths
+cd ..
+
+
+#********************
+#***    FFMPEG    ***
+#********************
+download http://ffmpeg.org/releases/ffmpeg-0.5.tar.bz2
+tar xjf ffmpeg-0.5.tar.bz2
+cd ffmpeg-0.5
+       INSTALL_DIR=ffmpeg-0.5
+       
+       #to check this line, maybe some options can be reactivated
+       ./configure --prefix=$BUILD/$INSTALL_DIR --enable-libopencore-amrnb --enable-libopencore-amrwb --enable-memalign-hack --enable-static --disable-shared --enable-gpl --disable-encoders --disable-muxers --disable-bsfs --disable-ffmpeg --disable-ffserver --disable-ffplay --disable-protocol=http --disable-protocol=rtp --disable-protocol=tcp --disable-protocol=udp && make && make install
+       add_paths
+cd ..
+
+#*********************
+#***   Portaudio   ***
+#*********************
+download http://www.portaudio.com/archives/pa_stable_v19_20071207.tar.gz
+tar xzf pa_stable_v19_20071207.tar.gz
+cd portaudio
+       INSTALL_DIR=portaudio
+       
+       ./configure --prefix=$BUILD_DIR/$INSTALL_DIR && make && make install
+       add_paths
+cd ..
+
+echo "export CPATH=$CPATH" > paths-to-add.sh
+echo "export PATH=$PATH" >> paths-to-add.sh
+echo "export PKG_CONFIG_PATH=$PKG_CONFIG_PATH" >> paths-to-add.sh
+echo "export LIBRARY_PATH=$LIBRARY_PATH" >> paths-to-add.sh
+echo
+echo "Enviroment variables exported to paths-to-add.sh. Run this file to get the changes of you Env variables"
+echo
+export CPATH
+export PATH
+export LIBRARY_PATH
+export PKG_CONFIG_PATH
diff --git a/win32/gcc/mingw-cwchar.patch b/win32/gcc/mingw-cwchar.patch
new file mode 100644 (file)
index 0000000..3a208f4
--- /dev/null
@@ -0,0 +1,21 @@
+--- /mingw/lib/gcc/mingw32/4.4.0/include/c++/cwchar    2009-06-17 09:37:48 +0000
++++ /mingw/lib/gcc/mingw32/4.4.0/include/c++/cwchar    2009-11-27 21:25:35 +0000
+@@ -156,14 +156,18 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
+   using ::mbsrtowcs;
+   using ::putwc;
+   using ::putwchar;
++#ifndef __STRICT_ANSI__ 
+   using ::swprintf;
++#endif
+   using ::swscanf;
+   using ::ungetwc;
+   using ::vfwprintf;
+ #if _GLIBCXX_HAVE_VFWSCANF
+   using ::vfwscanf;
+ #endif
++#ifndef __STRICT_ANSI__ 
+   using ::vswprintf;
++#endif
+ #if _GLIBCXX_HAVE_VSWSCANF
+   using ::vswscanf;
+ #endif
diff --git a/win32/gcc/mingw-libstdc++.patch b/win32/gcc/mingw-libstdc++.patch
new file mode 100644 (file)
index 0000000..35fdbbb
--- /dev/null
@@ -0,0 +1,15 @@
+--- /mingw/lib/gcc/mingw32/4.4.0/libstdc++.la  2009-11-27 11:37:38 +0000
++++ /mingw/lib/gcc/mingw32/4.4.0/libstdc++.la  2009-11-27 11:11:08 +0000
+@@ -5,10 +5,10 @@
+ # It is necessary for linking the library.
+ # The name that we can dlopen(3).
+-dlname='../bin/libstdc++-6.dll'
++#dlname='../bin/libstdc++-6.dll'
+ # Names of this library.
+-library_names='libstdc++.dll.a'
++#library_names='libstdc++.dll.a'
+ # The name of the static archive.
+ old_library='libstdc++.a'
diff --git a/win32/gcc/portaudio.patch b/win32/gcc/portaudio.patch
new file mode 100644 (file)
index 0000000..049ff91
--- /dev/null
@@ -0,0 +1,175 @@
+diff -rN -u configure configure
+--- configure  2007-09-16 20:46:15.000000000 +0200
++++ configure  2007-09-16 20:46:17.000000000 +0200
+@@ -1470,6 +1470,8 @@
+   --with-macapi ((asio/core/sm) default=core)
+   --with-asiodir (default=/usr/local/asiosdk2)
+   --with-dxdir (default=/usr/local/dx7sdk)
++  --with-dx-includes
++  --with-dx-libraries
+   --with-gnu-ld           assume the C compiler uses GNU ld [default=no]
+   --with-pic              try to use only PIC/non-PIC objects [default=use
+                           both]
+@@ -21288,24 +21309,49 @@
+   mingw* )
++        OTHER_OBJS="src/os/win/pa_win_hostapis.o src/os/win/pa_win_util.o";
++        LIBS="-lwinmm -lm"
++        PADLL="portaudio.dll";
++        THREAD_CFLAGS="-mthreads"
++        SHARED_FLAGS="-shared";
++        DLL_LIBS="-lwinmm $DLL_LIBS";
++        CFLAGS="$CFLAGS -I\$(top_srcdir)/src/os/win";
++
+         echo "WINAPI: $with_winapi"
+-        if [ $with_winapi = "directx" ] ; then
+-            if [ $with_dxdir ] ; then
+-              DXDIR="$with_dxdir";
+-            else
+-              DXDIR="/usr/local/dx7sdk";
+-            fi
+-            echo "DXDIR: $DXDIR"
+-            OTHER_OBJS="src/hostapi/dsound/pa_win_ds.o src/hostapi/dsound/pa_win_ds_dynlink.o src/os/win/pa_win_hostapis.o src/os/win/pa_win_util.o";
+-            LIBS="-lwinmm -lm -ldsound -lole32";
+-            PADLL="portaudio.dll";
+-          THREAD_CFLAGS="-mthreads"
+-            SHARED_FLAGS="-shared";
+-            DLL_LIBS="${DLL_LIBS} -lwinmm -lm -L./dx7sdk/lib -ldsound -lole32";
++
++        if [ $with_dx_includes ] ; then
++          DXINCDIR="$with_dx_includes"
++        elif [ $with_dxdir ] ; then
++          DXINCDIR="$with_dxdir/include";
++        else
++          DXINCDIR="/usr/local/dx7sdk/include"
++        fi
++
++        if [ $with_dx_libraries ] ; then
++          DXLIBDIR="$with_dx_libraries"
++        elif [ $with_dxdir ] ; then
++          DXLIBDIR="./dx7sdk/lib"
++        else
++          DXLIBDIR="./dx7sdk/lib"
++        fi
++
++        for winapi in $with_winapi
++        do
++        case "$winapi" in
++          directx)
++            echo "DXINCDIR: $DXINCDIR"
++            echo "DXLIBDIR: $DXLIBDIR"
++            OTHER_OBJS="$OTHER_OBJS src/hostapi/dsound/pa_win_ds.o src/hostapi/dsound/pa_win_ds_dynlink.o";
++            LIBS="-ldsound -lole32 $LIBS";
++            DLL_LIBS="${DLL_LIBS} -lm -L$DXLIBDIR -ldsound -lole32";
+             #VC98="\"/c/Program Files/Microsoft Visual Studio/VC98/Include\"";
+             #CFLAGS="$CFLAGS -I$VC98 -DPA_NO_WMME -DPA_NO_ASIO";
+-            CFLAGS="$CFLAGS -I\$(top_srcdir)/include -I$DXDIR/include -DPA_NO_WMME -DPA_NO_ASIO" -DPA_NO_WDMKS;
+-        elif [ $with_winapi = "asio" ] ; then
++            CFLAGS="$CFLAGS -I$DXINCDIR"
++            use_ds=yes
++          need_waveformat=yes
++            ;;
++
++          asio)
+             if [ $with_asiodir ] ; then
+               ASIODIR="$with_asiodir";
+             else
+@@ -21313,45 +21359,57 @@
+             fi
+             echo "ASIODIR: $ASIODIR"
+-            OTHER_OBJS="pa_asio/pa_asio.o src/os/win/pa_win_hostapis.o src/os/win/pa_win_util.o pa_asio/iasiothiscallresolver.o $ASIODIR/common/asio.o $ASIODIR/host/asiodrivers.o $ASIODIR/host/pc/asiolist.o";
+-            LIBS="-lwinmm -lm -lstdc++ -lole32 -luuid";
+-            PADLL="portaudio.dll";
+-          THREAD_CFLAGS="-mthreads"
+-            SHARED_FLAGS="-shared";
+-            DLL_LIBS="${DLL_LIBS} -lwinmm -lm -lstdc++ -lole32 -luuid";
+-            CFLAGS="$CFLAGS -ffast-math -fomit-frame-pointer -I\$(top_srcdir)/src/common -I\$(top_srcdir)/pa_asio -I$ASIODIR/host/pc -I$ASIODIR/common -I$ASIODIR/host -DPA_NO_WMME -DPA_NO_DS -DPA_NO_WDMKS -DWINDOWS";
+-            CXXFLAGS="$CFLAGS";
+-        elif [ $with_winapi = "wdmks" ] ; then
+-            if [ $with_dxdir ] ; then
+-              DXDIR="$with_dxdir";
+-            else
+-              DXDIR="/usr/local/dx7sdk";
+-            fi
+-            echo "DXDIR: $DXDIR"
+-            OTHER_OBJS="src/hostapi/wdmks/pa_win_wdmks.o src/os/win/pa_win_hostapis.o src/os/win/pa_win_util.o";
+-            LIBS="-lwinmm -lm -luuid -lsetupapi -lole32";
+-            PADLL="portaudio.dll";
+-          THREAD_CFLAGS="-mthreads"
+-            SHARED_FLAGS="-shared";
+-            DLL_LIBS="${DLL_LIBS} -lwinmm -lm -L./dx7sdk/lib -luuid -lsetupapi -lole32";
++            OTHER_OBJS="$OTHER_OBJS pa_asio/pa_asio.o pa_asio/iasiothiscallresolver.o $ASIODIR/common/asio.o $ASIODIR/host/asiodrivers.o $ASIODIR/host/pc/asiolist.o";
++            LIBS="-lstdc++ -lole32 -luuid $LIBS";
++            DLL_LIBS="${DLL_LIBS} -lm -lstdc++ -lole32 -luuid";
++            CFLAGS="$CFLAGS -ffast-math -fomit-frame-pointer -I\$(top_srcdir)/pa_asio -I$ASIODIR/host/pc -I$ASIODIR/common -I$ASIODIR/host -DWINDOWS";
++            CXXFLAGS="$CFLAGS"
++            use_asio=yes
++            ;;
++
++          wdmks)
++            echo "DXINCDIR: $DXINCDIR"
++            echo "DXLIBDIR: $DXLIBDIR"
++            OTHER_OBJS="$OTHER_OBJS src/hostapi/wdmks/pa_win_wdmks.o";
++            LIBS="-luuid -lsetupapi -lole32 $LIBS";
++            DLL_LIBS="${DLL_LIBS} -lm -L$DXLIBDIR -luuid -lsetupapi -lole32";
+             #VC98="\"/c/Program Files/Microsoft Visual Studio/VC98/Include\"";
+             #CFLAGS="$CFLAGS -I$VC98 -DPA_NO_WMME -DPA_NO_ASIO";
+-            CFLAGS="$CFLAGS -I\$(top_srcdir)/src/common -I$DXDIR/include -DPA_NO_WMME -DPA_NO_DS -DPA_NO_ASIO";
+-        else   # WMME default
+-            OTHER_OBJS="src/hostapi/wmme/pa_win_wmme.o src/os/win/pa_win_hostapis.o src/os/win/pa_win_util.o";
+-            LIBS="-lwinmm -lm -lstdc++ -lole32 -luuid";
+-            PADLL="portaudio.dll";
+-          THREAD_CFLAGS="-mthreads"
+-            SHARED_FLAGS="-shared";
+-            DLL_LIBS="${DLL_LIBS} -lwinmm";
+-            CFLAGS="$CFLAGS -I\$(top_srcdir)/src/common -DPA_NO_DS -DPA_NO_ASIO -DPA_NO_WDMKS";
++            CFLAGS="$CFLAGS -I$DXINCDIR -DPA_NO_WMME -DPA_NO_DS -DPA_NO_ASIO"
++            use_wdmks=yes
++            ;;
++
++          wmme)
++            OTHER_OBJS="$OTHER_OBJS src/hostapi/wmme/pa_win_wmme.o";
++            LIBS="-lstdc++ -lole32 -luuid $LIBS";
++            use_wmme=yes
++          need_waveformat=yes
++            ;;
++        esac
++        done
++
++        if [ "$use_ds" != "yes" ]; then
++            CFLAGS="$CFLAGS -DPA_NO_DS"
++        fi
++        if [ "$use_asio" != "yes" ]; then
++            CFLAGS="$CFLAGS -DPA_NO_ASIO"
++        fi
++        if [ "$use_wdmks" != "yes" ]; then
++            CFLAGS="$CFLAGS -DPA_NO_WDMKS"
++        fi
++        if [ "$use_wmme" != "yes" ]; then
++            CFLAGS="$CFLAGS -DPA_NO_WMME"
++        fi
++
++        if [ "$need_waveformat" = "yes" ]; then
++            OTHER_OBJS="$OTHER_OBJS src/os/win/pa_win_waveformat.o"
+         fi
+         ;;
+   cygwin* )
+       OTHER_OBJS="src/hostapi/wmme/pa_win_wmme.o src/os/win/pa_win_hostapis.o src/os/win/pa_win_util.o";
+-      CFLAGS="$CFLAGS -DPA_NO_DS -DPA_NO_WDMKS -DPA_NO_ASIO -DPA_NO_WASAPI"
++      CFLAGS="$CFLAGS -I\$(top_srcdir)/src/os/win -DPA_NO_DS -DPA_NO_WDMKS -DPA_NO_ASIO -DPA_NO_WASAPI"
+       LIBS="-lwinmm -lm";
+       PADLL="portaudio.dll";
+       THREAD_CFLAGS="-mthreads"
+@@ -21673,6 +21731,7 @@
+ fi
++        CFLAGS="$CFLAGS -I\$(top_srcdir)/src/os/unix"
+       if [ $have_alsa = "yes" ] && [ $with_alsa != "no" ] ; then
+               DLL_LIBS="$DLL_LIBS -lasound"
+               OTHER_OBJS="$OTHER_OBJS src/hostapi/alsa/pa_linux_alsa.o"
+
diff --git a/win32/msvc/fontconfig-cmake.patch b/win32/msvc/fontconfig-cmake.patch
new file mode 100644 (file)
index 0000000..bcce142
--- /dev/null
@@ -0,0 +1,24 @@
+--- cmake/modules/FindFreetype.cmake.old       2009-12-19 15:56:20 +0000
++++ cmake/modules/FindFreetype.cmake   2009-12-19 15:57:51 +0000
+@@ -18,6 +18,9 @@ if (FREETYPE_LIBRARIES AND FREETYPE_INCL
+ else (FREETYPE_LIBRARIES AND FREETYPE_INCLUDE_DIR)
++  FIND_PROGRAM(SH_EXECUTABLE NAMES sh PATHS
++      /bin
++  )
+   FIND_PROGRAM(FREETYPECONFIG_EXECUTABLE NAMES freetype-config PATHS
+      /opt/local/bin
+   )
+@@ -29,9 +32,9 @@ else (FREETYPE_LIBRARIES AND FREETYPE_IN
+   # if freetype-config has been found
+   if(FREETYPECONFIG_EXECUTABLE)
+-    EXEC_PROGRAM(${FREETYPECONFIG_EXECUTABLE} ARGS --libs RETURN_VALUE _return_VALUE OUTPUT_VARIABLE FREETYPE_LIBRARIES)
++    EXEC_PROGRAM(${SH_EXECUTABLE} ARGS ${FREETYPECONFIG_EXECUTABLE} --libs RETURN_VALUE _return_VALUE OUTPUT_VARIABLE FREETYPE_LIBRARIES)
+-    EXEC_PROGRAM(${FREETYPECONFIG_EXECUTABLE} ARGS --cflags RETURN_VALUE _return_VALUE OUTPUT_VARIABLE _freetype_pkgconfig_output)
++    EXEC_PROGRAM(${SH_EXECUTABLE} ARGS ${FREETYPECONFIG_EXECUTABLE} --cflags RETURN_VALUE _return_VALUE OUTPUT_VARIABLE _freetype_pkgconfig_output)
+     if(FREETYPE_LIBRARIES AND _freetype_pkgconfig_output)
+       set(FREETYPE_FOUND TRUE)
diff --git a/win32/msvc/install-msvc.sh b/win32/msvc/install-msvc.sh
new file mode 100644 (file)
index 0000000..f6faf59
--- /dev/null
@@ -0,0 +1,1391 @@
+#!/bin/sh -ex
+# Run this script under MSYS started from the VS2008 Command Prompt.
+# Perl, Python, and CMake must be installed and on the PATH.
+# Just a base installation of MSYS is needed - you don't need any
+# additional packages or any part of MinGW.
+#
+# If you don't have wget on your PATH, place a copy of the source code
+# for GNU Wget in the same folder as this script and it will do the rest ;)
+# (Note that this script is coded to specific versions of the upstream
+#  packages that I know work together - update them if you want, but the
+#  wget (which currently *must* be wget-1.11.4.tar.bz2) invocation will
+#  fetch said specific versions.)
+#
+# So grab yourself a wget.exe binary and stick it in your PATH, or just
+# download this, put it in the same folder as this script, and let this
+# script automatically build it for you:
+#
+#   http://ftp.gnu.org/pub/gnu/wget/wget-1.11.4.tar.bz2
+#
+# There must not be any spaces in the absolute path to the folder.
+
+echo "Stump's Performous MSVC dependency setup script"
+echo ''
+echo 'If you have issues, be sure that you are running this script'
+echo 'from an MSYS prompt that was started from a Visual Studio 2008'
+echo 'Command Prompt (type something like "start C:\\msys\\1.0\\msys.bat"'
+echo 'from such a prompt).  You must have Perl, Python, and CMake on your PATH.'
+echo ''
+
+# Allow the user to keep temporary files around.
+# (Set the KEEPTEMP environment variable to any value.)
+if test -n "$KEEPTEMP"; then
+  RM_RF=true
+else
+  RM_RF="rm -rf"
+fi
+
+echo 'Checking the environment.'
+
+if test x"$MACHTYPE" != xi686-pc-msys; then
+  echo 'This script must be run under MSYS.' >&2
+  exit 1
+fi
+
+# Check for spaces in the absolute path to us.
+set foo `pwd`
+if test "$#" -ne 2; then
+  echo 'There cannot be spaces in the absolute path to the ' >&2
+  echo 'folder from which this script is started.' >&2
+  exit 1
+fi
+
+echo 'Looking for the commands we need...'
+type basename
+type bzip2 #--version >/dev/null 2>&1 && echo 'bzip2 is working...'
+type cat
+type cl #'-?' </dev/null >/dev/null 2>&1 && echo 'cl is working...'
+type cmake #--version >/dev/null 2>&1 && echo 'cmake is working...'
+alias cmake="cmake -G \"NMake Makefiles\"" #to get cmake doing the right makefiles
+type cmd #//c echo cmd is working...
+type cp #--version >/dev/null 2>&1 && echo 'cp is working...'
+type cscript #'-?' </dev/null >/dev/null 2>&1 && echo 'cscript is working...'
+type dirname
+type expr
+type grep #--version >/dev/null 2>&1 && echo 'grep is working...'
+type gzip #--version >/dev/null 2>&1 && echo 'gzip is working...'
+type lib #'-?' </dev/null >/dev/null 2>&1 && echo 'lib is working...'
+type link #'-?' </dev/null >/dev/null 2>&1 && echo 'link is working...'
+type make #--version >/dev/null 2>&1 && echo 'make is working...'
+type mkdir #--version >/dev/null 2>&1 && echo 'mkdir is working...'
+type mt #'-?' </dev/null >/dev/null 2>&1 && echo 'mt is working...'
+type mv #--version >/dev/null 2>&1 && echo 'mv is working...'
+type nmake #'-?' </dev/null >/dev/null 2>&1 && echo 'nmake is working...'
+type patch #--version >/dev/null 2>&1 && echo 'patch is working...'
+type perl #-e '$_ = "perl is working...\n"; print'
+type python #-c 'msg = "python is working..."; print msg'
+type rc #'-?' </dev/null >/dev/null 2>&1 && echo 'rc is working...'
+type regsvr32
+type rm #--version >/dev/null 2>&1 && echo 'rm is working...'
+type sed #--version >/dev/null 2>&1 && echo 'sed is working...'
+type sh #--version >/dev/null 2>&1 && echo 'sh is working...'
+type sleep #--version >/dev/null 2>&1 && echo 'sleep is working...'
+type tar #--version >/dev/null 2>&1 && echo 'tar is working...'
+type touch #--version >/dev/null 2>&1 && echo 'touch is working...'
+type vcbuild #'-?' </dev/null >/dev/null 2>&1 && echo 'vcbuild is working...'
+type which
+
+# work around a bug in the VS2008 installer...
+regsvr32 -s "`which VCProjectEngine.dll`"
+
+# Embed manifests when the makefiles do it incorrectly.
+# See: http://msdn.microsoft.com/en-us/library/ms235591.aspx
+manifestify () {
+  if ! test -f "$1".manifest; then
+    # Link to MSVCR90 and run as an ordinary user.
+    cat >"$1".manifest <<"EOF"
+<?xml version='1.0' encoding='UTF-8' standalone='yes'?>
+<assembly xmlns='urn:schemas-microsoft-com:asm.v1' manifestVersion='1.0'>
+  <trustInfo xmlns="urn:schemas-microsoft-com:asm.v3">
+    <security>
+      <requestedPrivileges>
+        <requestedExecutionLevel level='asInvoker' uiAccess='false' />
+      </requestedPrivileges>
+    </security>
+  </trustInfo>
+  <dependency>
+    <dependentAssembly>
+      <assemblyIdentity type="win32" name="Microsoft.VC90.CRT" version="9.0.21022.8" processorArchitecture="x86" publicKeyToken="1fc8b3b9a1e18e3b" />
+    </dependentAssembly>
+  </dependency>
+</assembly>
+EOF
+  fi
+  if test "`expr "$1" : '.*\.dll$'`" -ne 0; then
+    mt -manifest "$1".manifest -outputresource:"$1"\;2
+  else
+    mt -manifest "$1".manifest -outputresource:"$1"\;1
+  fi
+}
+
+mkdir -pv ../bin ../include ../lib
+export PATH=`cd ../bin && pwd`:$PATH
+export INCLUDE=`cd ../include && cmd //c echo $(pwd)`\;$INCLUDE
+export LIB=`cd ../lib && cmd //c echo $(pwd)`\;$LIB
+
+if ! type wget >/dev/null 2>&1; then
+  if ! test -f wget-1.11.4.tar.bz2; then
+    echo 'Please place a wget.exe binary on your PATH.  Or you can go the' >&2
+    echo 'awesome boostrapping route and place a copy of wget-1.11.4.tar.bz2' >&2
+    echo '(get it from your favorite GNU mirror) in this directory, run this' >&2
+    echo 'script again, and watch the script build it for you ;)' >&2
+    echo '' >&2
+    echo '  http://ftp.gnu.org/pub/gnu/wget/wget-1.11.4.tar.bz2' >&2
+    exit 1
+  fi
+  tar jxvf wget-1.11.4.tar.bz2
+  cd wget-1.11.4
+  cmd //c configure.bat --msvc
+  nmake NO_SSL=1
+  cp -v src/wget.exe ../../bin
+  cd ..
+  $RM_RF wget-1.11.4
+fi
+
+# The list of source archives we need.
+cat >PACKAGES.wget <<"EOF"
+ftp://ftp.info-zip.org/pub/infozip/src/unzip60.tgz
+http://www.two-sdg.demon.co.uk/curbralan/code/dirent/dirent.h
+http://www.two-sdg.demon.co.uk/curbralan/code/dirent/dirent.c
+http://msinttypes.googlecode.com/files/msinttypes-r26.zip
+http://www.zlib.net/zlib-1.2.3.tar.bz2
+http://www.portaudio.com/archives/pa_stable_v19_20071207.tar.gz
+http://www.libsdl.org/release/SDL-1.2.14.tar.gz
+http://ftp.gnome.org/pub/GNOME/binaries/win32/dependencies/proxy-libintl-dev_20090911_win32.zip
+http://ftp.gnome.org/pub/GNOME/sources/glib/2.22/glib-2.22.3.tar.bz2
+http://prdownloads.sourceforge.net/sevenzip/7z465.tar.bz2
+http://prdownloads.sourceforge.net/boost/boost_1_41_0.7z
+http://prdownloads.sourceforge.net/libpng/libpng-1.2.41.tar.gz
+http://www.cairographics.org/releases/pixman-0.17.2.tar.gz
+http://www.cairographics.org/releases/cairo-1.8.8.tar.gz
+http://ftp.gnu.org/pub/gnu/libiconv/libiconv-1.11.1.tar.gz
+http://kde-mirror.freenux.org/stable/4.3.4/win32/freetype-vc90-2.3.7-1-src.tar.bz2
+#http://pkgconfig.freedesktop.org/releases/pkg-config-0.23.tar.gz
+ftp://xmlsoft.org/libxml2/libxml2-2.7.6.tar.gz
+http://kde-mirror.freenux.org/stable/4.3.4/win32/fontconfig-vc90-2.4.2-3-src.tar.bz2
+http://ftp.gnome.org/pub/GNOME/sources/pango/1.26/pango-1.26.1.tar.bz2
+http://ftp.gnome.org/pub/GNOME/sources/atk/1.28/atk-1.28.0.tar.bz2
+http://www.ijg.org/files/jpegsrc.v7.tar.gz
+ftp://ftp.remotesensing.org/pub/libtiff/tiff-3.9.2.tar.gz
+http://ftp.gnome.org/pub/GNOME/sources/gtk+/2.18/gtk+-2.18.5.tar.bz2
+http://ftp.gnome.org/pub/GNOME/sources/librsvg/2.26/librsvg-2.26.0.tar.bz2
+http://ftp.gnome.org/pub/GNOME/sources/libsigc++/2.2/libsigc++-2.2.4.2.tar.bz2
+http://ftp.gnome.org/pub/GNOME/sources/glibmm/2.22/glibmm-2.22.1.tar.bz2
+http://ftp.gnome.org/pub/GNOME/sources/libxml++/2.26/libxml++-2.26.1.tar.bz2
+http://prdownloads.sourceforge.net/glew/glew-1.5.1-src.tgz
+#ftp://ftp.imagemagick.org/pub/ImageMagick/windows/ImageMagick-6.5.8-6.7z
+http://ffmpeg.arrozcru.org/autobuilds/ffmpeg/dev/shared/ffmpeg-r20817-swscale-r29978-mingw32-shared-dev.7z
+http://ffmpeg.arrozcru.org/autobuilds/ffmpeg/mingw32/shared/ffmpeg-r20817-swscale-r29978-mingw32-shared.7z
+http://www.libsdl.org/projects/SDL_image/release/SDL_image-1.2.10.tar.gz
+EOF
+
+if test "$0" -nt download-stamp; then
+  ../wget -c -i PACKAGES.wget
+  sleep 2
+  touch download-stamp
+fi
+
+$RM_RF PACKAGES.wget
+
+# Placeholder vcproj for when slns refer to missing ones, like glib's does.
+cat >dummy.vcproj <<"EOF"
+<?xml version="1.0" encoding="iso-8859-1"?>
+<VisualStudioProject Version="9.00">
+ <Platforms><Platform Name="Win32" /></Platforms>
+ <Configurations>
+  <Configuration Name="@CONFIG@" ConfigurationType="10" />
+ </Configurations>
+</VisualStudioProject>
+EOF
+
+# Dummy implementation of the cygpath command that the autotools seem to like.
+cat >dummy-cygpath <<"EOF"
+#!/bin/sh -e
+for arg; do
+  case "$arg" in
+    -*)
+      ;;
+    *)
+      echo "$arg"
+      exit 0
+      ;;
+  esac
+done
+exit 1
+EOF
+
+if ! test -f ../bin/unzip.exe; then
+  tar zxvf unzip60.tgz
+  cd unzip60
+  nmake -f win32/Makefile unzip.exe
+  cp -v unzip.exe ../../bin
+  cd ..
+  $RM_RF unzip60
+fi
+
+if ! test -f ../lib/dirent.lib; then
+  cp -v dirent.h ../include
+  cl -MD -Fodirent.obj -c dirent.c
+  lib -verbose -out:dirent.lib dirent.obj
+  cl -MT -Fodirentmt.obj -c dirent.c
+  lib -verbose -out:direntmt.lib direntmt.obj
+  cp -v dirent.lib direntmt.lib ../lib
+  $RM_RF dirent.lib dirent.obj direntmt.lib direntmt.obj
+fi
+
+if ! test -f ../include/stdint.h; then
+  mkdir -pv msinttypes
+  cd msinttypes
+  unzip -o ../msinttypes-r26.zip
+  cp -v inttypes.h stdint.h ../../include
+  cd ..
+  $RM_RF msinttypes
+fi
+
+if ! test -f ../lib/z.lib; then
+  tar jxvf zlib-1.2.3.tar.bz2
+  cd zlib-1.2.3
+  sed -e 's/1,2,2,0/1,2,3,0/g' win32/zlib1.rc >win32/zlib1.rc.new
+  mv -v win32/zlib1.rc.new win32/zlib1.rc
+  nmake -f win32/Makefile.msc
+  cp -v zlib.h zconf.h ../../include
+  cp -v zlib1.dll ../../bin
+  cp -v zlib.lib zdll.lib ../../lib
+  cp -v ../../lib/zdll.lib ../../lib/z.lib
+  cd ..
+  $RM_RF zlib-1.2.3
+fi
+
+if ! test -f ../lib/portaudio.lib; then
+  tar zxvf pa_stable_v19_20071207.tar.gz
+  cd portaudio/build/msvc
+  # This python and sed remove all references to ASIO, which we don't feel
+  # like obtaining so we can build with it.
+  cat >fixasio.py <<"EOF"
+import xml.dom.minidom
+import sys
+vcproj = xml.dom.minidom.parse(sys.argv[1])
+for f in vcproj.getElementsByTagName('File'):
+  if f.attributes['RelativePath'].nodeValue.startswith(r'..\..\src\hostapi\asio'):
+    f.parentNode.removeChild(f)
+for t in vcproj.getElementsByTagName('Tool'):
+  if t.attributes['Name'].nodeValue == 'VCCLCompilerTool':
+    t.attributes['PreprocessorDefinitions'].nodeValue += ';PA_NO_ASIO'
+vcproj.writexml(sys.stdout)
+EOF
+  python fixasio.py portaudio.vcproj >portaudio.vcproj.new
+  mv -v portaudio.vcproj.new portaudio.vcproj
+  $RM_RF fixasio.py
+  sed -e '/^PaAsio/s/.*/;&/' portaudio.def >portaudio.def.new
+  mv -v portaudio.def.new portaudio.def
+  vcbuild -useenv portaudio.sln 'Release|Win32'
+  cp -v ../../include/portaudio.h ../../../../include
+  cp -v Win32/Release/portaudio_x86.dll ../../../../bin
+  cp -v Win32/Release/portaudio_x86.lib ../../../../lib/portaudio.lib
+  cd ../../..
+  $RM_RF portaudio
+fi
+
+if ! test -f ../lib/SDL.lib; then
+  tar zxvf SDL-1.2.14.tar.gz
+  cd SDL-1.2.14
+  unzip -o VisualC.zip
+  cd VisualC
+  # Upstream forgot this?
+  cat >fixversion.sed <<"EOF"
+/<\/Files>/i\
+<File RelativePath=".\\Version.rc" />
+EOF
+  sed -f fixversion.sed SDL/SDL.vcproj >SDL/SDL.vcproj.new
+  mv -v SDL/SDL.vcproj.new SDL/SDL.vcproj
+  $RM_RF fixversion.sed
+  vcbuild -useenv SDL.sln 'Release|Win32'
+  mkdir -pv ../../../include/SDL
+  cp -av ../include/*.h ../../../include/SDL
+  cp -v SDL/Release/SDL.dll ../../../bin
+  cp -v SDLmain/Release/SDLmain.lib SDL/Release/SDL.lib ../../../lib
+  cd ../..
+  $RM_RF SDL-1.2.14
+fi
+
+if ! test -f ../lib/libintl.lib; then
+  mkdir -pv proxy-libintl-dev
+  cd proxy-libintl-dev
+  unzip -o ../proxy-libintl-dev_20090911_win32.zip
+  cp -v include/libintl.h ../../include
+  cd src/proxy-libintl
+  cl -MD -Folibintl.obj -c libintl.c
+  lib -verbose -out:intl.lib libintl.obj
+  cl -MT -Folibintlmt.obj -c libintl.c
+  lib -verbose -out:intlmt.lib libintlmt.obj
+  cp -v intl.lib intlmt.lib ../../../../lib
+  cp -v ../../../../lib/intl.lib ../../../../lib/libintl.lib
+  cd ../../..
+  $RM_RF proxy-libintl-dev
+fi
+
+if ! test -f ../lib/glib-2.0.lib; then
+  tar jxvf glib-2.22.3.tar.bz2
+  cd glib-2.22.3/build/win32/vs9
+  # Upstream forgot these?
+  cat >fixgio.sed <<"EOF"
+/AdditionalDependencies/s/="/&Dnsapi.lib /
+/<\/Files>/i\
+<File RelativePath="..\\..\\..\\gio\\gio.rc" />
+EOF
+  sed -f fixgio.sed gio.vcproj >gio.vcproj.new
+  mv -v gio.vcproj.new gio.vcproj
+  $RM_RF fixgio.sed
+  sed -e '/FileDescription/s/GLib/GIO/' -e 's/libglib/libgio/g' ../../../glib/glib.rc >../../../gio/gio.rc
+  # Use our dummy vcproj since this one is missing.
+  sed -e 's/@CONFIG@/Release|Win32/' ../../../../dummy.vcproj >testglib.vcproj
+  vcbuild -useenv glib.sln 'Release|Win32'
+  cp -v Release/*.exe ../../../../dependencies/Win32/vs9/bin
+  cd ../../../..
+  # librsvg needs these
+  for file in gasyncinitable.h ginitable.h ginetaddress.h ginetsocketaddress.h \
+    gsocketaddress.h giostream.h gfileiostream.h gnetworkaddress.h \
+    gnetworkservice.h gresolver.h gsocket.h gsocketaddressenumerator.h \
+    gsocketclient.h gsocketconnectable.h gsocketconnection.h gsocketlistener.h \
+    gsocketcontrolmessage.h gsocketservice.h gtcpconnection.h gsrvtarget.h \
+    gthreadedsocketservice.h; do
+    cp -v glib-2.22.3/gio/"$file" dependencies/Win32/vs9/include/glib-2.0/gio
+  done
+  $RM_RF glib-2.22.3
+  mv -v dependencies/Win32/vs9/bin/* ../bin
+  if test -f ../bin/gspawn-win64-helper.exe; then
+    mv -v ../bin/gspawn-win64-helper.exe ../bin/gspawn-win32-helper.exe
+  fi
+  if test -d ../include/glib-2.0; then
+    rm -rf ../include/glib-2.0
+  fi
+  mv -v dependencies/Win32/vs9/include/* ../include
+  if test -d ../lib/glib-2.0; then
+    rm -rf ../lib/glib-2.0
+  fi
+  mv -v dependencies/Win32/vs9/lib/* ../lib
+  $RM_RF dependencies
+fi
+
+if ! test -f ../bin/7z.exe; then
+  mkdir -pv 7z465
+  tar -C 7z465 -jxvf 7z465.tar.bz2
+  cd 7z465/CPP/7zip/UI/Console
+  nmake
+  manifestify O/7z.exe
+  cp -v O/7z.exe ../../../../../../bin
+  cd ../../../../..
+  $RM_RF 7z465
+fi
+
+if ! test -f ../lib/boost_filesystem-vc90-mt-1_41.lib; then
+  7z x -y boost_1_41_0.7z
+  cd boost_1_41_0
+  for file in \
+    boost/program_options/detail/value_semantic.hpp \
+    boost/program_options/options_description.hpp \
+    libs/program_options/src/options_description.cpp \
+    libs/program_options/src/value_semantic.cpp; do
+      tr -d '\r' <"$file" >"$file".new
+      mv -v "$file".new "$file"
+  done
+  patch -Np0 <<"EOF"
+--- boost/program_options/detail/value_semantic.hpp.old        2009-12-14 02:32:44 -0500
++++ boost/program_options/detail/value_semantic.hpp    2009-12-14 02:35:08 -0500
+@@ -10,12 +10,11 @@
+ namespace boost { namespace program_options { 
+-    extern BOOST_PROGRAM_OPTIONS_DECL std::string arg;
+-    
+     template<class T, class charT>
+     std::string
+     typed_value<T, charT>::name() const
+     {
++        static std::string arg("arg");
+         if (!m_implicit_value.empty() && !m_implicit_value_as_text.empty()) {
+             std::string msg = "[=arg(=" + m_implicit_value_as_text + ")]";
+             if (!m_default_value.empty() && !m_default_value_as_text.empty())
+--- boost/program_options/options_description.hpp.old  2009-12-14 02:35:47 -0500
++++ boost/program_options/options_description.hpp      2009-12-14 02:52:54 -0500
+@@ -30,6 +30,8 @@
+ /** Namespace for the library. */
+ namespace program_options {
++    BOOST_STATIC_CONSTANT(unsigned, m_default_line_length, 80);
++        
+     /** Describes one possible command line/config file option. There are two
+         kinds of properties of an option. First describe it syntactically and
+         are used only to validate input. Second affect interpretation of the
+@@ -155,8 +157,6 @@
+     */
+     class BOOST_PROGRAM_OPTIONS_DECL options_description {
+     public:
+-        static const unsigned m_default_line_length;
+-        
+         /** Creates the instance. */
+         options_description(unsigned line_length = m_default_line_length);
+         /** Creates the instance. The 'caption' parameter gives the name of
+--- libs/program_options/src/options_description.cpp.old       2009-12-14 02:39:02 -0500
++++ libs/program_options/src/options_description.cpp   2009-12-14 02:40:06 -0500
+@@ -201,8 +201,6 @@
+         return *this;
+     }
+-    const unsigned options_description::m_default_line_length = 80;
+-
+     options_description::options_description(unsigned line_length)
+     : m_line_length(line_length)
+     {}
+--- libs/program_options/src/value_semantic.cpp.old    2009-12-14 02:40:19 -0500
++++ libs/program_options/src/value_semantic.cpp        2009-12-14 02:40:57 -0500
+@@ -64,12 +64,10 @@
+     }
+ #endif
+-    BOOST_PROGRAM_OPTIONS_DECL std::string arg("arg");
+-
+     std::string
+     untyped_value::name() const
+     {
+-        return arg;
++        return "arg";
+     }
+     
+     unsigned 
+EOF
+  if ! test -f ../../bin/bjam.exe; then
+    cd tools/jam/src
+    cmd //c build.bat
+    cp -v bin.ntx86/bjam.exe ../../../../../bin
+    cd ../../..
+  fi
+  bjam stage toolset=msvc --build-type=complete link=shared threading=multi runtime-link=shared
+  if test -d ../../include/boost; then
+    rm -rf ../../include/boost
+  fi
+  mv -v boost ../../include
+  cp -v stage/lib/*.dll ../../bin
+  for file in stage/lib/*.lib; do
+    if test "`expr "$file" : '.*-mt\.lib$'`" -eq 0; then
+      cp -v "$file" ../../lib/"`basename "$file"`"
+      cp -v "$file" ../../lib/lib"`basename "$file"`"
+    fi
+  done
+  cd ..
+  $RM_RF boost_1_41_0
+fi
+
+if ! test -f ../lib/png12.lib; then
+  tar zxvf libpng-1.2.41.tar.gz
+  cd libpng-1.2.41/scripts
+  # The former never actually gets defined by the code, and
+  # the latter is needed later on but is commented out.
+  sed -e '/png_set_strip_error_numbers/s/.*/;&/' -e '/; png_get_libpng_ver/s/; //' pngw32.def >pngw32.def.new
+  mv -v pngw32.def.new pngw32.def
+  cd ../projects/visualc71
+  vcbuild -upgrade libpng.vcproj
+  # Use the copy of zlib that we just built, not libpng's own copy.
+  sed -e '/Name="VCLinkerTool"/s/.*/& AdditionalDependencies="zdll.lib"/' libpng.vcproj >libpng.vcproj.new
+  mv -v libpng.vcproj.new libpng.vcproj
+  vcbuild -useenv libpng.vcproj 'DLL Release|Win32'
+  cp -v Win32_DLL_Release/libpng13.dll ../../../../bin
+  cp -v ../../png.h ../../pngconf.h ../../../../include
+  cp -v Win32_DLL_Release/libpng13.lib ../../../../lib/libpng.lib
+  cp -v ../../../../lib/libpng.lib ../../../../lib/png12.lib
+  cd ../../..
+  $RM_RF libpng-1.2.41
+fi
+
+if ! test -f ../lib/pixman-1.lib; then
+  tar zxvf pixman-0.17.2.tar.gz
+  cd pixman-0.17.2/pixman
+  make -f Makefile.win32 CFG=release SSE2=off
+  cp -v pixman.h pixman-version.h ../../../include
+  cp -v release/pixman-1.lib ../../../lib
+  cd ../..
+  $RM_RF pixman-0.17.2
+fi
+
+if ! test -f ../lib/cairo.lib; then
+  tar zxvf cairo-1.8.8.tar.gz
+  cd cairo-1.8.8
+  make -f Makefile.win32 CFG=release PIXMAN_LIBS=pixman-1.lib
+  cp -v cairo-version.h src/cairo-features.h src/cairo.h src/cairo-deprecated.h src/cairo-win32.h src/cairo-ps.h src/cairo-pdf.h src/cairo-svg.h ../../include
+  cp -v src/release/cairo.dll ../../bin
+  cp -v src/release/cairo.lib ../../lib
+  cd ..
+  $RM_RF cairo-1.8.8
+fi
+
+if ! test -f ../lib/iconv.lib; then
+  tar zxvf libiconv-1.11.1.tar.gz
+  cd libiconv-1.11.1
+  # TODO: Get it to link correctly with proxy-libintl.  TODO: version info, latest version
+  nmake -f Makefile.msvc PREFIX=`(cd ../.. && pwd)` NO_NLS=1 DLL=1
+  cp -v include/iconv.h ../../include
+  manifestify src/iconv.exe
+  cp -v src/iconv.exe ../../bin
+  cp -v lib/iconv.dll ../../bin
+  cp -v lib/iconv.lib ../../lib
+  cd ..
+  $RM_RF libiconv-1.11.1
+fi
+
+if ! test -f ../lib/freetype.lib; then
+#  tar jxvf freetype-2.3.11.tar.bz2
+##  cp -v dummy-cygpath ../bin/cygpath
+#  cd freetype-2.3.11
+##  ./configure CC='cl -nologo' LD='link -nologo' --prefix=/ --disable-static
+##  make
+##  make DESTDIR=`pwd`/_inst install
+#  cd builds/win32/vc2008
+#  vcbuild -useenv freetype.sln 'LIB Release|Win32'
+#  cd ../../..
+#  cp -av include/ft2build.h include/freetype ../../include
+#  rm -rf ../../include/freetype/internal
+#  cp -v objs/win32/vc2008/freetype2311.lib ../../lib/freetype.lib
+##  cp -v _inst/lib/libfreetype-6.dll ../../bin
+##  cp -v _inst/lib/libfreetype.lib ../../lib/freetype6.lib
+#  cd ..
+##  rm -vf ../bin/cygpath
+#  $RM_RF freetype-2.3.11
+#  cat >../bin/freetype-config <<"EOF"
+##!/bin/sh -e
+#if test x"$1" == x"--libs"; then echo freetype.lib; fi
+#exit 0
+#EOF
+  tar --strip-components=1 -jxvf freetype-vc90-2.3.7-1-src.tar.bz2
+  cd freetype-vc90-2.3.7-1
+  cmake -DCMAKE_BUILD_TYPE=Release .
+  nmake
+  cp -av include/ft2build.h include/freetype ../../include
+  rm -rf ../../include/freetype/internal
+  cp -v freetype.dll ../../bin
+  cp -v freetype.lib ../../lib
+  cd ..
+  $RM_RF freetype-vc90-2.3.7-1
+fi
+
+#if ! test -f ../bin/pkg-config.exe; then
+#  tar zxvf pkg-config-0.23.tar.gz
+#  cd pkg-config-0.23
+#  ./configure CC='cl -nologo -FI malloc.h' LD='link -nologo' LIBS='glib-2.0.lib dirent.lib advapi32.lib' --prefix=`(cd ../.. && pwd)`
+#  make
+#  cp -v pkg-config.exe ../../bin
+#  cd ..
+#  $RM_RF pkg-config-0.23
+#fi
+
+if ! test -f ../lib/xml2.lib; then
+  tar zxvf libxml2-2.7.6.tar.gz
+  cd libxml2-2.7.6/win32
+  cscript configure.js compiler=msvc vcmanifest=yes zlib=yes sodir='$(PREFIX)\bin'
+  nmake -f Makefile.msvc
+  nmake -f Makefile.msvc install
+  cp -av include/* ../../../include
+  cp -v ../include/win32config.h ../../../include
+  cp -v bin/libxml2.dll bin/xmllint.exe bin/xmlcatalog.exe ../../../bin
+  cp -v lib/libxml2.lib ../../../lib/xml2.lib
+  cd ../..
+  $RM_RF libxml2-2.7.6
+fi
+
+if ! test -f ../lib/fontconfig.lib; then
+  tar --strip-components=1 -jxvf fontconfig-vc90-2.4.2-3-src.tar.bz2
+  cd fontconfig-vc90-2.4.2-3
+  # End line problem, can't include in this file (strange problem, but work with an extern file), so fix with extern patch file
+  patch -Np0 < ../fontconfig-cmake.patch
+  # We're providing these ourselves...
+  cat >fixcml.sed <<"EOF"
+s/dirent.c//g
+s/unistd.c//g
+s/mmap.c//g
+/^install(/i\
+target_link_libraries( fontconfig dirent.lib )
+EOF
+  sed -f fixcml.sed src/CMakeLists.txt >src/CMakeLists.txt.new
+  mv -v src/CMakeLists.txt.new src/CMakeLists.txt
+  $RM_RF fixcml.sed
+  cat >fixcmlsubdir.sed <<"EOF"
+s%../src/dirent.c%%g
+s%../src/unistd.c%%g
+/^install(/i\
+target_link_libraries( ${sub_dir_name} dirent.lib )
+EOF
+  for dir in fc-cache fc-cat fc-list fc-match; do
+    sed -f fixcmlsubdir.sed "$dir"/CMakeLists.txt >"$dir"/CMakeLists.txt.new
+    mv -v "$dir"/CMakeLists.txt.new "$dir"/CMakeLists.txt
+  done
+  $RM_RF fixcmlsubdir.sed
+  cmake -DCMAKE_INSTALL_PREFIX=`(cd ../.. && pwd)` -DCMAKE_BUILD_TYPE=Release .
+#  tar zxvf fontconfig-2.8.0.tar.gz
+#  cp -v dummy-cygpath ../bin/cygpath
+#  cd fontconfig-2.8.0
+#  ./configure CC='cl -nologo -MD' LD='link -nologo' LIBXML2_CFLAGS=' ' LIBXML2_LIBS='xml2.lib' LIBS='iconv.lib zdll.lib dirent.lib' --prefix=/ --disable-shared
+  # Properly #ifdef all unistd.h inclusions.
+  cat >fixunistd.sed <<"EOF"
+/#include *<unistd.h>/ {i\
+#ifdef HAVE_UNISTD_H
+a\
+#endif
+}
+EOF
+  for file in src/fcint.h src/fcatomic.c fc-cache/fc-cache.c fc-cat/fc-cat.c fc-list/fc-list.c fc-match/fc-match.c; do
+    sed -f fixunistd.sed "$file" >"$file".new
+    mv -v "$file".new "$file"
+  done
+  $RM_RF fixunistd.sed
+  # Windows' access() is a bit different and doesn't define *_OK...
+  for file in src/fccache.c fc-cache/fc-cache.c; do
+    cat - "$file" >"$file".new <<"EOF"
+#define F_OK 0
+#define R_OK 4
+#define W_OK 2
+#define X_OK 0
+EOF
+    mv -v "$file".new "$file"
+  done
+  # Nor does Windows define this...
+  for file in src/fcdir.c fc-cache/fc-cache.c; do
+    cat - "$file" >"$file".new <<"EOF"
+#ifndef S_ISDIR
+#define S_ISDIR(x) (((x) & S_IFMT) == S_IFDIR)
+#endif
+EOF
+    mv -v "$file".new "$file"
+  done
+#  make V=1
+#  cd ..
+#  rm -vf ../bin/cygpath
+#  $RM_RF fontconfig-2.8.0
+  nmake
+  nmake install
+  cd ..
+  $RM_RF fontconfig-vc90-2.4.2-3
+fi
+
+setup_glib () {
+  if ! test -f glib/setup-for-msvc; then
+    mkdir -p glib
+    cd glib
+    tar --strip-components=1 -jxvf ../glib-2.22.3.tar.bz2
+    sed -e 's/@GLIB_VERSION@/2.22.3/g' gobject/glib-mkenums.in >gobject/glib-mkenums.new
+       sed -e 's/@PERL_PATH@/\/bin\/perl/g' gobject/glib-mkenums.new >gobject/glib-mkenums
+       rm gobject/glib-mkenums.new
+       sed -e 's/GLIB = $(TOP)\\glib/GLIB = $(TOP)\/glib/g' build/win32/make.msc >build/win32/make.msc.new
+       mv -v build/win32/make.msc.new build/win32/make.msc
+       cp -v glibconfig.h.win32 glibconfig.h
+    cp -v config.h.win32 config.h
+    cat >fixmakemsc.sed <<"EOF"
+/^ATK_LIBS/s/\$(ATK)\\[^\\]*\\//g
+/^CAIRO_CFLAGS/s/=.*/=/
+/^CAIRO_LIBS/s/=.*/= cairo.lib/
+/^FONTCONFIG_LIBS/s/=.*\\/= /
+/^FREETYPE2_LIBS/s/=.*/= freetype.lib/
+/^GLIB_LIBS/s/\$(GLIB)\\[^\\]*\\//g
+/^JPEG_LIBS/s/=.*/= jpeg.lib/
+/^INTL_LIBS/s/=.*/= intl.lib/
+/^LIBICONV_LIBS/s/\$(LIBICONV)\\[^\\]*\\//g
+/^PANGO[A-Z0-9]*_LIBS/s/\$(PANGO)\\pango\\//g
+/^PNG_LIBS/s/=.*/= libpng.lib/
+/^TIFF_LIBS/s/=.*/= tiff.lib/
+/^ZLIB_LIBS/s/=.*/= zdll.lib/
+EOF
+    sed -f fixmakemsc.sed build/win32/make.msc >build/win32/make.msc.new
+    mv -v build/win32/make.msc.new build/win32/make.msc
+    $RM_RF fixmakemsc.sed
+    touch setup-for-msvc
+    cd ..
+  fi
+}
+
+if ! test -f ../lib/pango-1.0.lib; then
+  setup_glib
+  tar jxvf pango-1.26.1.tar.bz2
+  cd pango-1.26.1/pango
+  # Unmaintained makefiles ftw...
+  cp -v module-defs-lang.c module-defs-lang.c.win32
+  cat >fixmakefile.sed <<"EOF"
+s/mapping.obj//g
+s/-DSYSCONFDIR/-DLIBDIR=\\"\/lib\\" &/g
+s/.exe : $(PKG_LINK)/.exe : /
+/^pango_headers=/a\
+pango-bidi-type.h \\
+/pango-enum-types.obj/a\
+pango-bidi-type.obj \\\
+pango.res \\
+/pangowin32.obj/a\
+pangowin32.res \\
+/pangocairo-context.obj/a\
+pangocairo.res \\
+/pangoft2.obj/a\
+pangoft2.res \\
+EOF
+  sed -f fixmakefile.sed makefile.msc >makefile.msc.new
+  mv -v makefile.msc.new makefile.msc
+  $RM_RF fixmakefile.sed
+  # Why doesn't this one have version info?
+  sed -e 's/Pango/&Cairo/g' -e 's/pango/&cairo/g' pango.rc >pangocairo.rc
+  # KDE-win32's fontconfig is too old to define extrablack.
+  patch -Np0 <<"EOF"
+--- pangofc-fontmap.c.old       2009-12-10 00:55:43 -0500
++++ pangofc-fontmap.c   2009-12-10 00:56:11 -0500
+@@ -1360,10 +1360,8 @@
+     return FC_WEIGHT_BOLD;
+   else if (pango_weight <= (PANGO_WEIGHT_ULTRABOLD + PANGO_WEIGHT_HEAVY) / 2)
+     return FC_WEIGHT_ULTRABOLD;
+-  else if (pango_weight <= (PANGO_WEIGHT_HEAVY + PANGO_WEIGHT_ULTRAHEAVY) / 2)
+-    return FC_WEIGHT_BLACK;
+   else
+-    return FC_WEIGHT_EXTRABLACK;
++    return FC_WEIGHT_BLACK;
+ }
+ static int
+@@ -2045,10 +2043,8 @@
+     return PANGO_WEIGHT_BOLD;
+   else if (fc_weight <= (FC_WEIGHT_EXTRABOLD + FC_WEIGHT_BLACK) / 2)
+     return PANGO_WEIGHT_ULTRABOLD;
+-  else if (fc_weight <= (FC_WEIGHT_BLACK + FC_WEIGHT_EXTRABLACK) / 2)
+-    return PANGO_WEIGHT_HEAVY;
+   else
+-    return PANGO_WEIGHT_ULTRAHEAVY;
++    return PANGO_WEIGHT_HEAVY;
+ }
+ static PangoStyle
+EOF
+  sed -e 's/$(PERL) $(GLIB)\\gobject\\glib-mkenums/$(PERL) $(GLIB)\/gobject\/glib-mkenums/g' makefile.msc > makefile.msc.new
+  mv -v makefile.msc.new makefile.msc
+  sed -e 's/opentype\\pango-ot.lib/opentype\/pango-ot.lib/g' makefile.msc > makefile.msc.new
+  mv -v makefile.msc.new makefile.msc
+  nmake -f makefile.msc
+  mkdir -pv ../../../include/pango
+  cp -v pango-attributes.h pango-bidi-type.h pango-break.h pangocairo.h pango-context.h pango-coverage.h pango-engine.h pango-enum-types.h pangofc-decoder.h pangofc-font.h pangofc-fontmap.h pango-features.h pango-font.h pango-fontmap.h pango-fontset.h pangoft2.h pango-glyph.h pango-glyph-item.h pango-gravity.h pango.h pango-item.h pango-language.h pango-layout.h pango-matrix.h pango-modules.h pango-ot.h pango-renderer.h pango-script.h pango-tabs.h pango-types.h pango-utils.h pangowin32.h pangoxft.h pangoxft-render.h pangox.h ../../../include/pango
+  cp -v libpango*.dll ../../../bin  # FIXME: pangoft is broken because opentype/ won't compile under MSVC
+  manifestify querymodules.exe
+  manifestify testfonts.exe
+  cp -v querymodules.exe ../../../bin/pango-querymodules.exe
+  cp -v testfonts.exe ../../../bin/pango-testfonts.exe
+  cp -v pango*-1.0.lib ../../../lib
+  cd ../..
+  $RM_RF pango-1.26.1
+fi
+
+if ! test -f ../lib/atk-1.0.lib; then
+  setup_glib
+  tar jxvf atk-1.28.0.tar.bz2
+  cd atk-1.28.0/atk
+
+# Since I don't feel like sitting through ./configure dozens of times and
+# praying that it will eventually work, I just ripped apart Makefile.am...
+# --- cut here ---
+#!/bin/sh -e
+
+ATK_SOURCES=`echo "atkaction.c atkcomponent.c atkdocument.c
+  atkeditabletext.c atkgobjectaccessible.c atkhyperlink.c
+  atkhyperlinkimpl.c atkhypertext.c atkimage.c atknoopobject.c
+  atknoopobjectfactory.c atkobject.c atkobjectfactory.c
+  atkregistry.c atkrelation.c atkrelationset.c atkselection.c
+  atkstate.c atkstateset.c atkstreamablecontent.c atktable.c
+  atktext.c atkutil.c atkmisc.c atkvalue.c atk-enum-types.c"`
+ATK_HEADERS=`echo "atk.h atkaction.h atkcomponent.h
+  atkdocument.h atkeditabletext.h atkgobjectaccessible.h
+  atkhyperlink.h atkhyperlinkimpl.h atkhypertext.h
+  atknoopobject.h atknoopobjectfactory.h atkobject.h
+  atkobjectfactory.h atkimage.h atkregistry.h atkrelation.h
+  atkrelationtype.h atkrelationset.h atkselection.h atkstate.h
+  atkstateset.h atkstreamablecontent.h atktable.h atktext.h
+  atkutil.h atkmisc.h atkvalue.h"`
+
+glib-genmarshal --prefix=atk_marshal atkmarshal.list --header >atkmarshal.h
+glib-genmarshal --prefix=atk_marshal atkmarshal.list --body >atkmarshal.c
+
+perl ../../glib/gobject/glib-mkenums \
+  --fhead "#if defined(ATK_DISABLE_SINGLE_INCLUDES) && !defined (__ATK_H_INSIDE__) && !defined (ATK_COMPILATION)\n#error \"Only <atk/atk.h> can be included directly.\"\n#endif\n\n#ifndef __ATK_ENUM_TYPES_H__\n#define __ATK_ENUM_TYPES_H__\n\n#include <glib-object.h>\n\nG_BEGIN_DECLS\n" \
+  --fprod " /* enumerations from \"@filename@\" */\n" \
+  --vhead "GType @enum_name@_get_type (void);\n#define ATK_TYPE_@ENUMSHORT@ (@enum_name@_get_type())\n" \
+  --ftail "G_END_DECLS\n\n#endif /* __ATK_ENUM_TYPES_H__ */" \
+    $ATK_HEADERS >atk-enum-types.h
+
+perl ../../glib/gobject/glib-mkenums \
+  --fhead "#include <atk.h>" \
+  --fprod "\n /* enumerations from \"@filename@\" */" \
+  --vhead "GType\n@enum_name@_get_type (void)\n{\n  static GType etype = 0;\n  if (etype == 0) {\n    static const G@Type@Value values[] = {" \
+  --vprod "      { @VALUENAME@, \"@VALUENAME@\", \"@valuenick@\" }," \
+  --vtail "      { 0, NULL, NULL }\n    };\n    etype = g_@type@_register_static (\"@EnumName@\", values);\n  }\n  return etype;\n}\n" \
+    $ATK_HEADERS >atk-enum-types.c
+
+sed -e 's/^#undef VERSION$/#define VERSION "1.28.0"/' ../config.h.in >../config.h
+sed -e 's/@ATK_MAJOR_VERSION@/1/g' \
+    -e 's/@ATK_MINOR_VERSION@/28/g' \
+    -e 's/@ATK_MICRO_VERSION@/0/g' \
+    -e 's/@ATK_VERSION@/1.28.0/g' \
+    -e 's/@LT_CURRENT_MINUS_AGE@/0/g' atk.rc.in >atk.rc
+rc atk.rc
+(echo EXPORTS; cl -EP -DINCLUDE_VARIABLES -DG_OS_WIN32 -DALL_FILES atk.symbols | sed -e '/^$$/d' -e 's/^/ /' -e 's/G_GNUC_[^ ]*//g') >atk.def
+cl -I . -I .. -I ../../../include/glib-2.0 -I ../../../lib/glib-2.0/include \
+  -DG_DISABLE_DEPRECATED -DATK_DISABLE_DEPRECATED -DATK_COMPILATION -DATK_LOCALEDIR="\"/build/share/locale\"" \
+  -Felibatk-1.0-0.dll $ATK_SOURCES atk.res -link -dll -def:atk.def -implib:atk-1.0.lib \
+  glib-2.0.lib gobject-2.0.lib
+cp -v libatk-1.0-0.dll ../../../bin
+mkdir -pv ../../../include/atk
+cp -v $ATK_HEADERS atk-enum-types.h ../../../include/atk
+cp -v atk-1.0.lib ../../../lib
+# --- cut here ---
+# (Note: I would have used cmake, but I didn't feel like trying to get it to
+#  cooperate with glib-genmarshal and glib-mkenums.  Trust me, I tried.)
+
+  cd ../..
+  $RM_RF atk-1.28.0
+fi
+
+if ! test -f ../lib/jpeg.lib; then
+  tar zxvf jpegsrc.v7.tar.gz
+  cd jpeg-7
+  # The build systems that come with libjpeg vehemently refuse to allow it to
+  # be compiled as a DLL, so we do so ourselves with cmake.
+  echo EXPORTS >libjpeg.def
+  echo jpeg_std_error >>libjpeg.def
+  grep -h '^EXTERN([a-zA-Z0-9_ *]*) j[a-zA-Z0-9_]*' jpeglib.h jpegint.h | sed -e 's/EXTERN([a-zA-Z0-9_ *]*) \(j[a-zA-Z0-9_]*\).*/\1/' >>libjpeg.def
+  cp -v jconfig.vc jconfig.h
+  cat >CMakeLists.txt <<"EOF"
+add_library(libjpeg SHARED jcapimin.c jcapistd.c jcarith.c jctrans.c
+        jcparam.c jdatadst.c jcinit.c jcmaster.c jcmarker.c jcmainct.c
+        jcprepct.c jccoefct.c jccolor.c jcsample.c jchuff.c jcdctmgr.c
+        jfdctfst.c jfdctflt.c jfdctint.c jdapimin.c jdapistd.c jdarith.c
+        jdtrans.c jdatasrc.c jdmaster.c jdinput.c jdmarker.c jdhuff.c
+        jdmainct.c jdcoefct.c jdpostct.c jddctmgr.c jidctfst.c jidctflt.c
+        jidctint.c jdsample.c jdcolor.c jquant1.c jquant2.c jdmerge.c
+        jaricom.c jcomapi.c jutils.c jerror.c jmemmgr.c jmemnobs.c libjpeg.def)
+add_executable(cjpeg cjpeg.c rdppm.c rdgif.c rdtarga.c rdrle.c rdbmp.c
+        rdswitch.c cdjpeg.c)
+add_executable(djpeg djpeg.c wrppm.c wrgif.c wrtarga.c wrrle.c wrbmp.c
+        rdcolmap.c cdjpeg.c)
+add_executable(jpegtran jpegtran.c rdswitch.c cdjpeg.c transupp.c)
+add_executable(rdjpgcom rdjpgcom.c)
+add_executable(wrjpgcom wrjpgcom.c)
+target_link_libraries(cjpeg libjpeg)
+target_link_libraries(djpeg libjpeg)
+target_link_libraries(jpegtran libjpeg)
+target_link_libraries(rdjpgcom libjpeg)
+target_link_libraries(wrjpgcom libjpeg)
+EOF
+  cmake -DCMAKE_BUILD_TYPE=Release .
+  nmake
+  cp -v jconfig.h jerror.h jmorecfg.h jpeglib.h ../../include
+  cp -v libjpeg.dll *.exe ../../bin
+  cp -v libjpeg.lib ../../lib/jpeg.lib
+  cd ..
+  $RM_RF jpeg-7
+fi
+
+if ! test -f ../lib/tiff.lib; then
+  tar zxvf tiff-3.9.2.tar.gz
+  cd tiff-3.9.2
+  cat >fixnmakeopt.sed <<"EOF"
+s/^#ZIP/ZIP/
+s/^#ZLIB/ZLIB/
+/^ZLIBDIR/d
+/^ZLIB_INCLUDE/s/=.*/=/
+/^ZLIB_LIB/s/=.*/= zdll.lib/
+s/^#JPEG/JPEG/
+/^JPEGDIR/d
+/^JPEG_INCLUDE/s/=.*/=/
+/^JPEG_LIB/s/=.*/= jpeg.lib/
+EOF
+  sed -f fixnmakeopt.sed nmake.opt >nmake.opt.new
+  mv -v nmake.opt.new nmake.opt
+  $RM_RF fixnmakeopt.sed
+  sed -e 's/libtiff\.lib/libtiff_i.lib/g' tools/Makefile.vc >tools/Makefile.vc.new
+  mv -v tools/Makefile.vc.new tools/Makefile.vc
+  echo _TIFFCheckMalloc >>libtiff/libtiff.def
+  nmake -f Makefile.vc
+  cp -v libtiff/tiff.h libtiff/tiffio.h libtiff/tiffvers.h libtiff/tiffconf.h ../../include
+  for file in tools/*.exe; do
+    manifestify "$file"
+  done
+  cp -v libtiff/libtiff.dll tools/*.exe ../../bin
+  cp -v libtiff/libtiff_i.lib ../../lib/tiff.lib
+  cd ..
+  $RM_RF tiff-3.9.2
+fi
+
+if ! test -f ../lib/gtk-win32-2.0.lib; then
+  setup_glib
+  tar jxvf gtk+-2.18.5.tar.bz2
+  cd gtk+-2.18.5
+  # Unmaintained makefiles ftw...
+  sed -e 's@.exe : ../gtk/gtk-win32-$(GTK_VER).lib @.exe : @' tests/makefile.msc >tests/makefile.msc.new
+  mv -v tests/makefile.msc.new tests/makefile.msc
+  sed -e '/\\wntab/d' -e '/\\wtkit/d' gdk/makefile.msc >gdk/makefile.msc.new
+  mv -v gdk/makefile.msc.new gdk/makefile.msc
+  OLDPATH="$PATH"
+  PATH="`pwd`/gdk-pixbuf:$PATH"  # so gtk-update-icon-cache can actually run during the build
+  nmake -f makefile.msc
+  PATH="$OLDPATH"
+  OLDPATH=
+  cd gdk-pixbuf
+  mkdir -pv ../../../include/gdk-pixbuf
+  cp -v gdk-pixbuf.h gdk-pixbuf-core.h gdk-pixbuf-transform.h gdk-pixbuf-io.h \
+    gdk-pixbuf-animation.h gdk-pixbuf-simple-anim.h gdk-pixbuf-loader.h \
+    gdk-pixbuf-enum-types.h gdk-pixbuf-marshal.h gdk-pixbuf-features.h \
+    gdk-pixdata.h ../../../include/gdk-pixbuf
+  manifestify gdk-pixbuf-csource.exe
+  cp -v libgdk_pixbuf-2.0-0.dll gdk-pixbuf-csource.exe ../../../bin
+  cp -v gdk_pixbuf-2.0.lib ../../../lib
+  cd ../gdk
+  mkdir -pv ../../../include/gdk
+  cp -v gdk.h gdkapplaunchcontext.h gdkcairo.h gdkcolor.h gdkcursor.h gdkdisplay.h \
+    gdkdisplaymanager.h gdkdnd.h gdkdrawable.h gdkevents.h gdkfont.h gdkgc.h \
+    gdki18n.h gdkimage.h gdkinput.h gdkkeys.h gdkkeysyms.h gdkpango.h gdkpixbuf.h \
+    gdkpixmap.h gdkprivate.h gdkproperty.h gdkregion.h gdkrgb.h gdkscreen.h \
+    gdkselection.h gdkspawn.h gdktestutils.h gdktypes.h gdkvisual.h gdkwindow.h \
+    win32/gdkwin32.h gdkenumtypes.h ../../../include/gdk
+  cp -v gdkconfig.h ../../../include
+  cp -v libgdk-win32-2.0-0.dll ../../../bin
+  cp -v gdk-win32-2.0.lib ../../../lib
+  cd ../gtk
+  mkdir -pv ../../../include/gtk
+  cp -v gtk.h gtkaboutdialog.h gtkaccelgroup.h gtkaccellabel.h gtkaccelmap.h \
+    gtkaccessible.h gtkaction.h gtkactiongroup.h gtkactivatable.h gtkadjustment.h \
+    gtkalignment.h gtkarrow.h gtkaspectframe.h gtkassistant.h gtkbbox.h gtkbin.h \
+    gtkbindings.h gtkbox.h gtkbuilder.h gtkbuildable.h gtkbutton.h gtkcalendar.h \
+    gtkcelleditable.h gtkcelllayout.h gtkcellrenderer.h gtkcellrendereraccel.h \
+    gtkcellrenderercombo.h gtkcellrendererpixbuf.h gtkcellrendererprogress.h \
+    gtkcellrendererspin.h gtkcellrenderertext.h gtkcellrenderertoggle.h \
+    gtkcellview.h gtkcheckbutton.h gtkcheckmenuitem.h gtkclipboard.h \
+    gtkcolorbutton.h gtkcolorsel.h gtkcolorseldialog.h gtkcombobox.h \
+    gtkcomboboxentry.h gtkcontainer.h gtkcurve.h gtkdebug.h gtkdialog.h gtkdnd.h \
+    gtkdrawingarea.h gtkeditable.h gtkentry.h gtkentrybuffer.h gtkentrycompletion.h \
+    gtkenums.h gtkeventbox.h gtkexpander.h gtkfilechooser.h gtkfilechooserbutton.h \
+    gtkfilechooserdialog.h gtkfilechooserwidget.h gtkfilefilter.h gtkfixed.h \
+    gtkfontbutton.h gtkfontsel.h gtkframe.h gtkgamma.h gtkgc.h gtkhandlebox.h \
+    gtkhbbox.h gtkhbox.h gtkhpaned.h gtkhruler.h gtkhscale.h gtkhscrollbar.h \
+    gtkhseparator.h gtkhsv.h gtkiconfactory.h gtkicontheme.h gtkiconview.h \
+    gtkimage.h gtkimagemenuitem.h gtkimcontext.h gtkimcontextsimple.h gtkimmodule.h \
+    gtkimmulticontext.h gtkinfobar.h gtkinputdialog.h gtkinvisible.h gtkitem.h \
+    gtklabel.h gtklayout.h gtklinkbutton.h gtkliststore.h gtkmain.h gtkmenu.h \
+    gtkmenubar.h gtkmenuitem.h gtkmenushell.h gtkmenutoolbutton.h \
+    gtkmessagedialog.h gtkmisc.h gtkmodules.h gtkmountoperation.h gtknotebook.h \
+    gtkobject.h gtkorientable.h gtkpagesetup.h gtkpaned.h gtkpapersize.h gtkplug.h \
+    gtkprintcontext.h gtkprintoperation.h gtkprintoperationpreview.h \
+    gtkprintsettings.h gtkprivate.h gtkprogressbar.h gtkradioaction.h \
+    gtkradiobutton.h gtkradiomenuitem.h gtkradiotoolbutton.h gtkrange.h gtkrc.h \
+    gtkrecentaction.h gtkrecentchooser.h gtkrecentchooserdialog.h \
+    gtkrecentchoosermenu.h gtkrecentchooserwidget.h gtkrecentfilter.h \
+    gtkrecentmanager.h gtkruler.h gtkscale.h gtkscalebutton.h gtkscrollbar.h \
+    gtkscrolledwindow.h gtkselection.h gtkseparator.h gtkseparatormenuitem.h \
+    gtkseparatortoolitem.h gtkshow.h gtksettings.h gtksizegroup.h gtksocket.h \
+    gtkspinbutton.h gtkstatusbar.h gtkstatusicon.h gtkstock.h gtkstyle.h gtktable.h \
+    gtktearoffmenuitem.h gtktestutils.h gtktextbuffer.h gtktextbufferrichtext.h \
+    gtktextchild.h gtktextdisplay.h gtktextiter.h gtktextmark.h gtktexttag.h \
+    gtktexttagtable.h gtktextview.h gtktoggleaction.h gtktogglebutton.h \
+    gtktoggletoolbutton.h gtktoolbar.h gtktoolbutton.h gtktoolitem.h gtktoolshell.h \
+    gtktooltip.h gtktreednd.h gtktreemodel.h gtktreemodelfilter.h \
+    gtktreemodelsort.h gtktreeselection.h gtktreesortable.h gtktreestore.h \
+    gtktreeview.h gtktreeviewcolumn.h gtktypeutils.h gtkuimanager.h gtkvbbox.h \
+    gtkvbox.h gtkviewport.h gtkvolumebutton.h gtkvpaned.h gtkvruler.h gtkvscale.h \
+    gtkvscrollbar.h gtkvseparator.h gtkwidget.h gtkwindow.h gtktext.h gtktree.h \
+    gtktreeitem.h gtkclist.h gtkcombo.h gtkctree.h gtkfilesel.h gtkitemfactory.h \
+    gtklist.h gtklistitem.h gtkoldeditable.h gtkoptionmenu.h gtkpixmap.h \
+    gtkpreview.h gtkprogress.h gtksignal.h gtktipsquery.h gtktooltips.h \
+    gtktextlayout.h gtkmarshal.h gtktypebuiltins.h gtkversion.h \
+      ../../../include/gtk
+  manifestify gtk-query-immodules-2.0.exe
+  manifestify gtk-update-icon-cache.exe
+  cp -v libgtk-win32-2.0-0.dll gtk-query-immodules-2.0.exe gtk-update-icon-cache.exe ../../../bin
+  cp -v gtk-win32-2.0.lib ../../../lib
+  cd ../..  # TODO: anything else, if necessary
+  $RM_RF gtk+-2.18.5
+fi
+
+$RM_RF glib
+
+if ! test -f ../lib/rsvg-2.lib; then
+  tar jxvf librsvg-2.26.0.tar.bz2
+  cd librsvg-2.26.0
+
+# Another autotools-only package, another shell script hack-o-rama.
+# TODO: libgsf/libcroco support?  some svgs might need it...
+# --- cut here ---
+#!/bin/sh -e
+RSVG_SOURCES="rsvg-affine.c librsvg-features.c rsvg-bpath-util.c \
+  rsvg-css.c rsvg-defs.c rsvg-image.c rsvg-paint-server.c rsvg-path.c \
+  rsvg-base-file-util.c rsvg-filter.c rsvg-marker.c rsvg-mask.c rsvg-shapes.c \
+  rsvg-structure.c rsvg-styles.c rsvg-text.c rsvg-cond.c rsvg-base.c \
+  librsvg-enum-types.c rsvg-cairo-draw.c rsvg-cairo-render.c rsvg-cairo-clip.c \
+  rsvg.c rsvg-gobject.c rsvg-file-util.c"
+
+RSVG_HEADERS="rsvg-css.h rsvg-defs.h rsvg-image.h rsvg-paint-server.h \
+  rsvg-path.h rsvg-private.h rsvg-filter.h rsvg-marker.h rsvg-mask.h \
+  rsvg-shapes.h rsvg-structure.h rsvg-styles.h rsvg-bpath-util.h rsvg-text.h \
+  rsvg-cairo-draw.h rsvg-cairo-render.h rsvg-cairo-clip.h"
+
+(echo EXPORTS; grep -v EXPORTS librsvg.def) >librsvg.def.new
+mv -v librsvg.def.new librsvg.def
+sed -e 's/#undef VERSION/#define VERSION "2.26.0"/' config.h.in >config.h
+cl -I . -I ../../include/glib-2.0 -I ../../lib/glib-2.0/include \
+  -Felibrsvg-2.0-0.dll $RSVG_SOURCES -link -dll -def:librsvg.def -implib:rsvg-2.lib \
+  glib-2.0.lib gobject-2.0.lib xml2.lib cairo.lib gdk_pixbuf-2.0.lib \
+  pango-1.0.lib pangocairo-1.0.lib
+cl -I . -I ../../include/glib-2.0 -I ../../lib/glib-2.0/include \
+  -Fersvg-convert.exe rsvg-convert.c rsvg-2.lib glib-2.0.lib \
+  gobject-2.0.lib gthread-2.0.lib cairo.lib
+manifestify rsvg-convert.exe
+cl -I . -I ../../include/glib-2.0 -I ../../lib/glib-2.0/include \
+  -Fersvg-view.exe test-display.c rsvg-2.lib gtk-win32-2.0.lib \
+  gdk-win32-2.0.lib gdk_pixbuf-2.0.lib gobject-2.0.lib \
+  gthread-2.0.lib glib-2.0.lib
+manifestify rsvg-view.exe
+mkdir -pv ../../include/librsvg
+cp -v rsvg.h rsvg-cairo.h librsvg-features.h librsvg-enum-types.h ../../include/librsvg
+cp -v librsvg-2.0-0.dll rsvg-convert.exe rsvg-view.exe ../../bin
+cp -v rsvg-2.lib ../../lib
+# --- cut here ---
+
+  cd ..
+  $RM_RF librsvg-2.26.0
+fi
+
+if ! test -f ../lib/sigc-2.0.lib; then
+  tar jxvf libsigc++-2.2.4.2.tar.bz2
+  cd libsigc++-2.2.4.2/MSVC_Net2008
+  cat >fixgccdef.sed <<"EOF"
+/^#define SIGC_GCC_TEMPLATE_SPECIALIZATION_OPERATOR_OVERLOAD/ {i\
+#ifdef __GNUC__
+a\
+#endif
+}
+EOF
+  sed -f fixgccdef.sed sigc++config.h >sigc++config.h.new
+  mv -v sigc++config.h.new sigc++config.h
+  $RM_RF fixgccdef.sed
+  vcbuild -useenv libsigc++2.vcproj 'Release|Win32'
+  mkdir -pv ../../../include/sigc++
+  cp -v sigc++config.h ../../../include
+  for file in sigc++.h bind.h bind_return.h connection.h object.h reference_wrapper.h \
+    retype_return.h signal_base.h trackable.h type_traits.h visit_each.h \
+    adaptors/adaptors.h adaptors/bound_argument.h adaptors/lambda/lambda.h \
+    functors/functors.h functors/slot_base.h signal.h slot.h method_slot.h \
+    object_slot.h class_slot.h hide.h retype.h limit_reference.h \
+    functors/functor_trait.h functors/slot.h functors/ptr_fun.h functors/mem_fun.h \
+    adaptors/deduce_result_type.h adaptors/adaptor_trait.h adaptors/bind.h \
+    adaptors/bind_return.h adaptors/retype_return.h adaptors/hide.h adaptors/retype.h \
+    adaptors/compose.h adaptors/exception_catch.h adaptors/lambda/base.h \
+    adaptors/lambda/select.h adaptors/lambda/operator.h adaptors/lambda/group.h; do
+      mkdir -pv ../../../include/sigc++/"`dirname "$file"`"
+      cp -v ../sigc++/"$file" ../../../include/sigc++/"`dirname "$file"`"
+  done
+  cp -v Release/sigc-vc90-2_0.dll ../../../bin
+  cp -v Release/sigc-vc90-2_0.lib ../../../lib/sigc-2.0.lib
+  cd ../..
+  $RM_RF libsigc++-2.2.4.2
+fi
+
+if ! test -f ../lib/glibmm-2.4.lib; then
+  tar jxvf glibmm-2.22.1.tar.bz2
+  cd glibmm-2.22.1/MSVC_Net2008
+  cat >fixrc.sed <<"EOF"
+s/@G[A-Z]*MM_MAJOR_VERSION@/2/g
+s/@G[A-Z]*MM_MINOR_VERSION@/22/g
+s/@G[A-Z]*MM_MICRO_VERSION@/1/g
+s/@PACKAGE_VERSION@/2.22.1/g
+s/@GLIBMM_MODULE_NAME@/glibmm-vc90-2_4/g
+s/@GIOMM_MODULE_NAME@/giomm-vc90-2_4/g
+EOF
+  for file in */*.rc.in; do
+    sed -f fixrc.sed "$file" >"`echo "$file" | sed -e 's/\.in$//'`"
+  done
+  $RM_RF fixrc.sed
+  for file in */*.vcproj */*/*.vcproj; do
+    sed -e 's/sigc-vc90-2_0.lib/sigc-2.0.lib/g' "$file" >"$file".new
+    mv -v "$file".new "$file"
+  done
+  cat >fixiostream.sed <<"EOF"
+/<\/Files>/i\
+<File RelativePath="..\\..\\gio\\giomm\\fileiostream.cc" />\
+<File RelativePath="..\\..\\gio\\giomm\\iostream.cc" />
+EOF
+  sed -f fixiostream.sed giomm/giomm.vcproj >giomm/giomm.vcproj.new
+  mv -v giomm/giomm.vcproj.new giomm/giomm.vcproj
+  $RM_RF fixiostream.sed
+  OLDINCLUDE="$INCLUDE"
+  INCLUDE="`cd ../../../include/glib-2.0 && cmd //c echo $(pwd)`;`cd ../../../lib/glib-2.0/include && cmd //c echo $(pwd)`;$INCLUDE"
+  vcbuild -useenv glibmm.sln 'Release|Win32'
+  INCLUDE="$OLDINCLUDE"
+  OLDINCLUDE=
+  cp -v glibmm/glibmmconfig.h giomm/giommconfig.h ../../../include
+  cp -v ../glib/glibmm.h ../gio/giomm.h ../../../include
+  mkdir -pv ../../../include/glibmm/private
+  cp -v ../glib/glibmm/*.h ../../../include/glibmm
+  cp -v ../glib/glibmm/private/*.h ../../../include/glibmm/private
+  mkdir -pv ../../../include/giomm/private
+  cp -v ../gio/giomm/*.h ../../../include/giomm
+  cp -v ../gio/giomm/private/*.h ../../../include/giomm/private
+  cp -v glibmm/Release/glibmm-vc90-2_4.dll giomm/Release/giomm-vc90-2_4.dll ../../../bin
+  cp -v giomm/Release/giomm-vc90-2_4.lib ../../../lib/giomm-2.4.lib
+  cp -v glibmm/Release/glibmm-vc90-2_4.lib ../../../lib/glibmm-2.4.lib
+  cd ../..
+  $RM_RF glibmm-2.22.1
+fi
+
+if ! test -f ../lib/xml++-2.6.lib; then
+  tar jxvf libxml++-2.26.1.tar.bz2
+  cd libxml++-2.26.1/MSVC_Net2008
+  for file in */*.vcproj */*/*.vcproj; do
+    sed -e 's/libxml2.lib/xml2.lib/g' -e 's/glibmm-vc90-2_4.lib/glibmm-2.4.lib/g' "$file" >"$file".new
+    mv -v "$file".new "$file"
+  done
+  sed -e 's@^#include "afxres.h"@#include <windows.h>@' libxml++/libxml++.rc >libxml++/libxml++.rc.new
+  mv -v libxml++/libxml++.rc.new libxml++/libxml++.rc
+  OLDINCLUDE="$INCLUDE"
+  INCLUDE="`cd ../../../include/glib-2.0 && cmd //c echo $(pwd)`;`cd ../../../lib/glib-2.0/include && cmd //c echo $(pwd)`;$INCLUDE"
+  vcbuild -useenv libxml++.sln 'Release|Win32'
+  INCLUDE="$OLDINCLUDE"
+  OLDINCLUDE=
+  cp -v libxml++/libxml++config.h ../../../include
+  cd ../libxml++
+  mkdir -pv ../../../include/libxml++
+  cp -v libxml++.h attribute.h dtd.h document.h noncopyable.h keepblanks.h schema.h ../../../include/libxml++
+  for dir in exceptions parsers nodes validators; do
+    mkdir -pv ../../../include/libxml++/"$dir"
+    cp -v "$dir"/*.h ../../../include/libxml++/"$dir"
+  done
+  cd ../MSVC_Net2008
+  cp -v libxml++/Release/xml++-vc90-2_6.dll ../../../bin
+  cp -v libxml++/Release/xml++-vc90-2_6.lib ../../../lib/xml++-2.6.lib
+  cd ../..
+  $RM_RF libxml++-2.26.1
+fi
+
+if ! test -f ../lib/glew32.lib; then
+  tar zxvf glew-1.5.1-src.tgz
+  cd glew
+  # VS2008 vcbuild doesn't like upgrading dsw/dsp projects...
+  cat >CMakeLists.txt <<"EOF"
+include_directories(include)
+add_library(glew32 SHARED src/glew.c build/vc6/glew.rc)
+target_link_libraries(glew32 opengl32 glu32)
+set_target_properties(glew32 PROPERTIES COMPILE_DEFINITIONS GLEW_BUILD)
+add_executable(glewinfo src/glewinfo.c build/vc6/glewinfo.rc)
+target_link_libraries(glewinfo glew32)
+add_executable(visualinfo src/visualinfo.c build/vc6/visualinfo.rc)
+target_link_libraries(visualinfo glew32)
+EOF
+  cmake -DCMAKE_BUILD_TYPE=Release .
+  nmake
+  cp -av include/GL ../../include
+  cp -v glew32.dll glewinfo.exe visualinfo.exe ../../bin
+  cp -v glew32.lib ../../lib
+  cd ..
+  $RM_RF glew
+fi
+
+#if ! test -f ../lib/Magick++.lib; then
+#  7z x -y ImageMagick-6.5.8-6.7z
+#  cd ImageMagick-6.5.8
+#  # The build system works, but requires GUI interaction, which we don't want.
+#  # (Also, let's use our own libraries rather than IM's internal copies!)
+#  # Be sure to alter this if extra libs are added to this environment that
+#  # IM can make use of.
+#  cat >magick-config.sed <<"EOF"
+#/MAGICKCORE_X11_DELEGATE/s@.*@// &@
+#/MAGICKCORE_BZLIB_DELEGATE/s@.*@// &@
+#/MAGICKCORE_JBIG_DELEGATE/s@.*@// &@
+#/MAGICKCORE_JP2_DELEGATE/s@.*@// &@
+#/MAGICKCORE_LCMS_DELEGATE/s@.*@// &@
+#/MAGICKCORE_WMFLITE_DELEGATE/s@.*@// &@
+#EOF
+#  sed -f magick-config.sed <VisualMagick/magick/magick-config.h.in >magick/magick-config.h
+#  $RM_RF magick-config.sed
+#  cat >CMakeLists.txt <<"EOF"
+#add_definitions(-DNDEBUG -D_WINDOWS -DWIN32 -D_VISUALC_ -DNeedFunctionPrototypes -D_DLL)
+#include_directories(.)
+#subdirs(coders magick Magick++/lib utilities wand)
+#EOF
+#  cat >coders/CMakeLists.txt <<"EOF"
+#macro(IM_CODER coder_name)
+#  add_library(IM_MOD_RL_${coder_name}_ MODULE ${coder_name}.c)
+#  target_link_libraries(IM_MOD_RL_${coder_name}_ MagickCore ${ARGN})
+#endmacro(IM_CODER)
+#
+## Coders that don't need any external libraries.
+#foreach(nolib_coder art avs bmp braille cals caption cin cip clip clipboard
+#  cmyk cut dcm dds dib djvu dng dot dps dpx emf ept exr fax fits fpx gif
+#  gradient gray hald histogram hrz html icon info inline ipl jbig jp2
+#  label magick map mat matte meta miff mono mpc mpeg mpr mtv mvg null otb
+#  palm pattern pcd pcl pcx pdb pdf pict pix plasma pnm preview ps2 ps3 ps
+#  psd pwp raw rgb rla rle scr sct sfw sgi stegano sun tga thumbnail
+#  tile tim ttf txt uil url uyvy vicar vid viff wbmp wmf wpg x xbm xc xcf xpm
+#  xps xtrn xwd ycbcr yuv)
+#    IM_CODER(${nolib_coder})
+#endforeach(nolib_coder)
+#
+## Ones that do need external libs.
+#IM_CODER(jpeg jpeg)
+#IM_CODER(msl xml2)
+#IM_CODER(png libpng)
+#IM_CODER(svg xml2)
+#IM_CODER(tiff tiff)
+#IM_CODER(url xml2)
+#EOF
+#  cat >magick/CMakeLists.txt <<"EOF"
+#add_definitions(-D_MT -D_MAGICKMOD_ -D_MAGICKLIB_)
+#add_library(MagickCore SHARED animate.c annotate.c artifact.c attribute.c
+#  blob.c cache.c cache-view.c cipher.c client.c coder.c color.c colormap.c
+#  colorspace.c compare.c composite.c compress.c configure.c constitute.c
+#  decorate.c delegate.c deprecate.c display.c distort.c draw.c effect.c
+#  enhance.c exception.c fourier.c fx.c gem.c geometry.c hashmap.c histogram.c
+#  identify.c image.c layer.c list.c locale.c log.c magic.c magick.c matrix.c
+#  memory.c mime.c module.c monitor.c montage.c morphology.c option.c paint.c
+#  pixel.c policy.c PreRvIcccm.c prepress.c property.c profile.c quantize.c
+#  quantum.c quantum-export.c quantum-import.c random.c registry.c resample.c
+#  resize.c resource.c segment.c semaphore.c shear.c signature.c splay-tree.c
+#  static.c statistic.c stream.c string.c thread.c timer.c token.c transform.c
+#  threshold.c type.c utility.c version.c widget.c xml-tree.c xwindow.c
+#  nt-base.c nt-feature.c
+#
+#  ImageMagick.h MagickCore.h animate.h animate-private.h annotate.h
+#  api.h artifact.h attribute.h blob.h blob-private.h cache.h cache-private.h
+#  cache-view.h cipher.h client.h coder.h color.h color-private.h colormap.h
+#  colormap-private.h colorspace.h colorspace-private.h compare.h compress.h
+#  configure.h constitute.h composite.h composite-private.h decorate.h
+#  delegate.h delegate-private.h deprecate.h display.h display-private.h
+#  distort.h draw.h draw-private.h effect.h enhance.h exception.h
+#  exception-private.h fourier.h fx.h fx-private.h gem.h geometry.h hashmap.h
+#  histogram.h identify.h image.h image-private.h layer.h list.h locale_.h
+#  log.h mac.h magic.h magick-config.h magick-type.h magick.h matrix.h
+#  memory_.h methods.h mime.h module.h monitor.h monitor-private.h montage.h
+#  morphology.h nt-base.h nt-feature.h option.h paint.h pixel.h pixel-private.h
+#  policy.h PreRvIcccm.h prepress.h property.h profile.h quantize.h quantum.h
+#  quantum-private.h random_.h random-private.h registry.h resample.h
+#  resample-private.h resize.h resize-private.h resource_.h segment.h
+#  semaphore.h shear.h signature.h signature-private.h splay-tree.h static.h
+#  statistic.h stream.h stream-private.h string_.h studio.h thread_.h
+#  thread-private.h timer.h token.h token-private.h transform.h threshold.h
+#  type.h utility.h version.h vms.h widget.h xml-tree.h xwindow.h nt-base.h
+#  nt-feature.h
+#
+#  ImageMagick.rc)
+#target_link_libraries(MagickCore zdll freetype)
+#EOF
+#  cat >Magick++/lib/CMakeLists.txt <<"EOF"
+#include_directories(.)
+#add_library(MagickPlusPlus SHARED Blob.cpp BlobRef.cpp CoderInfo.cpp Color.cpp
+#  Drawable.cpp Exception.cpp Functions.cpp Geometry.cpp Image.cpp ImageRef.cpp
+#  Montage.cpp Options.cpp Pixels.cpp STL.cpp Thread.cpp TypeMetric.cpp
+#
+#  Magick++.h Magick++/Blob.h Magick++/BlobRef.h Magick++/CoderInfo.h
+#  Magick++/Color.h Magick++/Drawable.h Magick++/Exception.h Magick++/Functions.h
+#  Magick++/Geometry.h Magick++/Image.h Magick++/ImageRef.h Magick++/Include.h
+#  Magick++/Montage.h Magick++/Options.h Magick++/Pixels.h Magick++/STL.h
+#  Magick++/Thread.h Magick++/TypeMetric.h
+#
+#  ../../magick/ImageMagick.rc)
+#target_link_libraries(MagickPlusPlus MagickCore MagickWand)
+#set_target_properties(MagickPlusPlus PROPERTIES OUTPUT_NAME Magick++)
+#EOF
+#  cat >utilities/CMakeLists.txt <<"EOF"
+#macro(IM_UTIL util_name)
+#  add_executable(${util_name} ${util_name}.c ../magick/ImageMagick.rc)
+#  target_link_libraries(${util_name} MagickCore MagickWand)
+#endmacro(IM_UTIL)
+#
+#foreach(util animate compare composite conjure convert display identify
+#  import mogrify montage stream)
+#    IM_UTIL(${util})
+#endforeach(util)
+#EOF
+#  cat >wand/CMakeLists.txt <<"EOF"
+#add_definitions(-D_MT -D_MAGICKMOD_ -D_MAGICKLIB_)
+#add_library(MagickWand SHARED animate.c compare.c composite.c conjure.c
+#  convert.c deprecate.c display.c drawing-wand.c identify.c import.c
+#  magick-image.c magick-property.c magick-wand.c mogrify.c montage.c
+#  pixel-iterator.c pixel-view.c pixel-wand.c stream.c wand.c
+#
+#  MagickWand.h animate.h compare.h composite.h conjure.h convert.h deprecate.h
+#  display.h drawing-wand.h identify.h import.h magick-image.h magick-property.h
+#  magick-wand.h magick-wand-private.h mogrify.h mogrify-private.h montage.h
+#  pixel-iterator.h pixel-view.h pixel-wand.h pixel-wand-private.h stream.h
+#  studio.h wand.h
+#
+#  ../VisualMagick/wand/wand.rc)
+#target_link_libraries(MagickWand MagickCore)
+#EOF
+#  cmake -DCMAKE_BUILD_TYPE=Release .
+#  nmake
+#  # TODO: Place the coders in their own folder so they don't clutter up bin.
+#  mkdir -pv ../../include/magick ../../include/wand ../../include/Magick++
+#  cp -v magick/ImageMagick.h magick/MagickCore.h magick/PreRvIcccm.h magick/animate.h \
+#  magick/annotate.h magick/api.h magick/artifact.h magick/attribute.h magick/blob.h \
+#  magick/cache.h magick/cache-view.h magick/cipher.h magick/client.h magick/coder.h \
+#  magick/color.h magick/colormap.h magick/colorspace.h magick/compare.h magick/composite.h \
+#  magick/compress.h magick/configure.h magick/constitute.h magick/decorate.h \
+#  magick/delegate.h magick/deprecate.h magick/display.h magick/distort.h magick/draw.h \
+#  magick/effect.h magick/enhance.h magick/exception.h magick/fourier.h magick/fx.h \
+#  magick/gem.h magick/geometry.h magick/hashmap.h magick/histogram.h magick/identify.h \
+#  magick/image.h magick/layer.h magick/list.h magick/locale_.h magick/log.h \
+#  magick/magic.h magick/magick.h magick/magick-config.h magick/magick-type.h \
+#  magick/matrix.h magick/memory_.h magick/methods.h magick/mime.h magick/module.h \
+#  magick/monitor.h magick/montage.h magick/morphology.h magick/option.h magick/paint.h \
+#  magick/pixel.h magick/policy.h magick/prepress.h magick/profile.h magick/property.h \
+#  magick/quantize.h magick/quantum.h magick/random_.h magick/registry.h magick/resample.h \
+#  magick/resize.h magick/resource_.h magick/segment.h magick/semaphore.h magick/shear.h \
+#  magick/signature.h magick/splay-tree.h magick/statistic.h magick/stream.h \
+#  magick/string_.h magick/timer.h magick/token.h magick/transform.h magick/threshold.h \
+#  magick/type.h magick/utility.h magick/version.h magick/widget.h magick/xml-tree.h \
+#  magick/xwindow.h ../../include/magick
+#  cp -v wand/MagickWand.h wand/animate.h wand/compare.h wand/composite.h wand/conjure.h \
+#  wand/convert.h wand/deprecate.h wand/display.h wand/drawing-wand.h wand/identify.h \
+#  wand/import.h wand/magick-image.h wand/magick-property.h wand/magick-wand.h \
+#  wand/magick_wand.h wand/mogrify.h wand/montage.h wand/pixel-iterator.h \
+#  wand/pixel-view.h wand/pixel-wand.h wand/stream.h ../../include/wand
+#  cp -v Magick++/lib/Magick++.h ../../include
+#  cp -v Magick++/lib/Magick++/Blob.h Magick++/lib/Magick++/CoderInfo.h \
+#  Magick++/lib/Magick++/Color.h Magick++/lib/Magick++/Drawable.h \
+#  Magick++/lib/Magick++/Exception.h Magick++/lib/Magick++/Geometry.h \
+#  Magick++/lib/Magick++/Image.h Magick++/lib/Magick++/Include.h \
+#  Magick++/lib/Magick++/Montage.h Magick++/lib/Magick++/Pixels.h \
+#  Magick++/lib/Magick++/STL.h Magick++/lib/Magick++/TypeMetric.h \
+#    ../../include/Magick++
+#  cp -v magick/MagickCore.dll wand/MagickWand.dll Magick++/lib/Magick++.dll coders/IM_MOD_RL_*_.dll utilities/*.exe ../../bin
+#  cp -v magick/MagickCore.lib wand/MagickWand.lib Magick++/lib/Magick++.lib ../../lib
+#  cd ..
+#  $RM_RF ImageMagick-6.5.8
+#fi
+
+# So we've dealt with horrible or uncooperative build systems, but now we've
+# come to the downright impossible.  Since ffmpeg is never going to compile
+# under MSVC for the foreseeable future, just bite the bullet and use binaries.
+if ! test -f ../lib/avcodec.lib; then
+  mkdir -pv ffbinaries
+  7z x -y -offbinaries ffmpeg-r20817-swscale-r29978-mingw32-shared.7z
+  7z x -y -offbinaries ffmpeg-r20817-swscale-r29978-mingw32-shared-dev.7z
+  cp -av ffbinaries/include/lib* ../include
+  cp -v ffbinaries/bin/* ../bin
+  cp -v ffbinaries/lib/*.lib ../lib
+  $RM_RF ffbinaries
+fi
+
+if ! test -f ../lib/SDL_image.lib; then
+  tar zxvf SDL_image-1.2.10.tar.gz
+  cd SDL_image-1.2.10
+  unzip -o VisualC.zip
+  cd VisualC
+  sed -e '/PreprocessorDefinitions/s/LOAD_[A-Z]*_DYNAMIC=\\&quot;[-a-z0-9.]*\\&quot;;//g' -e 's/SDL.lib/& jpeg.lib libpng.lib tiff.lib/g' SDL_image.vcproj >SDL_image.vcproj.new
+  mv -v SDL_image.vcproj.new SDL_image.vcproj
+  OLDINCLUDE="$INCLUDE"
+  INCLUDE="../../../include/SDL;$INCLUDE"
+  vcbuild -useenv SDL_image.sln 'Release|Win32'
+  INCLUDE="$OLDINCLUDE"
+  OLDINCLUDE=
+  cp -v ../SDL_image.h ../../../include/SDL
+  cp -v Release/SDL_image.dll ../../../bin
+  cp -v Release/SDL_image.lib ../../../lib
+  cd ../..
+  $RM_RF SDL_image-1.2.10
+fi
+
+$RM_RF dummy.vcproj dummy-cygpath
\ No newline at end of file
diff --git a/win32/mxe/.gitignore b/win32/mxe/.gitignore
new file mode 100644 (file)
index 0000000..0e26ecd
--- /dev/null
@@ -0,0 +1 @@
+stage
diff --git a/win32/mxe/copydlls.py b/win32/mxe/copydlls.py
new file mode 100755 (executable)
index 0000000..ac2b8b3
--- /dev/null
@@ -0,0 +1,116 @@
+#!/usr/bin/env python
+# DLL dependency resolution and copying script.
+# Copyright (C) 2010 John Stumpo
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+import os
+import shutil
+import struct
+import sys
+
+if len(sys.argv) != 3:
+    sys.stderr.write('''Usage: %s [source] [destination]
+Copies DLLs in source needed by PE executables in destination to destination.
+Both source and destination should be directories.
+''' % sys.argv[0])
+    sys.exit(1)
+
+def is_pe_file(file):
+    f = open(file, 'rb')
+    if f.read(2) != 'MZ':
+        return False  # DOS magic number not present
+    f.seek(60)
+    peoffset = struct.unpack('<L', f.read(4))[0]
+    f.seek(peoffset)
+    if f.read(4) != 'PE\0\0':
+        return False  # PE magic number not present
+    return True
+
+def get_imports(file):
+    f = open(file, 'rb')
+    # We already know it's a PE, so don't bother checking again.
+    f.seek(60)
+    pe_header_offset = struct.unpack('<L', f.read(4))[0]
+
+    # Get sizes of tables we need.
+    f.seek(pe_header_offset + 6)
+    number_of_sections = struct.unpack('<H', f.read(2))[0]
+    f.seek(pe_header_offset + 116)
+    number_of_data_directory_entries = struct.unpack('<L', f.read(4))[0]
+    data_directory_offset = f.tell()  # it's right after the number of entries
+
+    # Where is the import table?
+    f.seek(data_directory_offset + 8)
+    rva_of_import_table = struct.unpack('<L', f.read(4))[0]
+
+    # Get the section ranges so we can convert RVAs to file offsets.
+    f.seek(data_directory_offset + 8 * number_of_data_directory_entries)
+    sections = []
+    for i in range(number_of_sections):
+        section_descriptor_data = f.read(40)
+        name, size, va, rawsize, offset = struct.unpack('<8sLLLL', section_descriptor_data[:24])
+        sections.append({'min': va, 'max': va+rawsize, 'offset': offset})
+
+    def seek_to_rva(rva):
+        for s in sections:
+            if s['min'] <= rva and rva < s['max']:
+                f.seek(rva - s['min'] + s['offset'])
+                return
+        raise ValueError, 'Could not find section for RVA.'
+
+    # Walk the import table and get RVAs to the null-terminated names of DLLs this file uses.
+    # The table is terminated by an all-zero entry.
+    seek_to_rva(rva_of_import_table)
+    dll_rvas = []
+    while True:
+        import_descriptor = f.read(20)
+        if import_descriptor == '\0' * 20:
+            break
+        dll_rvas.append(struct.unpack('<L', import_descriptor[12:16])[0])
+
+    # Read the DLL names from the RVAs we found in the import table.
+    dll_names = []
+    for rva in dll_rvas:
+        seek_to_rva(rva)
+        name = ''
+        while True:
+            c = f.read(1)
+            if c == '\0':
+                break
+            name += c
+        dll_names.append(name)
+
+    return dll_names
+
+
+src_contents = os.listdir(sys.argv[1])
+dest_contents = os.listdir(sys.argv[2])
+for dest_name in dest_contents:
+    dest_fname = os.path.join(sys.argv[2], dest_name)
+    if os.path.isfile(dest_fname) and is_pe_file(dest_fname):
+        print dest_name
+        for dll in get_imports(dest_fname):
+            print '- %s' % dll,
+            if dll.lower() in [n.lower() for n in dest_contents]:
+                print '(already present)'
+            else:
+                for n in src_contents:
+                    if n.lower() == dll.lower():
+                        shutil.copyfile(os.path.join(sys.argv[1], n), os.path.join(sys.argv[2], n))
+                        dest_contents.append(n)
+                        print '(copied)'
+                        break
+                else:
+                    print '(assumed to be provided by operating system)'
diff --git a/win32/mxe/libs.sh b/win32/mxe/libs.sh
new file mode 100755 (executable)
index 0000000..e0ee408
--- /dev/null
@@ -0,0 +1,14 @@
+#!/bin/sh
+MXE_PREFIX=/opt/mxe
+PKG_CONFIG=$MXE_PREFIX/usr/bin/i686-pc-mingw32.static-pkg-config
+
+LIBS="atk gobject-2.0 libswscale cairo-fc gthread-2.0 libtiff-4 cairo-ft gtk+-2.0 libxml-2.0 cairo-gobject gtk+-win32-2.0 libxml++-2.6 cairo harfbuzz nettle cairo-pdf hogweed ogg cairo-png icu-i18n opencore-amrnb cairo-ps icu-io opencore-amrwb cairo-script icu-le opencv cairo-svg icu-lx OpenEXR cairo-win32-font icu-uc openssl cairo-win32 IlmBase opus dbus-1 lcms pangocairo eigen3 libavcodec pangoft2 expat libavdevice pango fontconfig libavfilter pangowin32 freetype2 libavformat pixman-1 gail libavutil portaudio-2.0 gdk-2.0 libcroco-0.6 samplerate gdk-pixbuf-2.0 libcrypto gdk-win32-2.0 libffi sigc++-2.0 gio-2.0 libgsf-1 speexdsp giomm-2.4 speex gio-windows-2.0 liblzma sqlite3 glewmx libodbc++ theoradec glew libpcre16 theoraenc glib-2.0 libpcre theora glibmm-2.4 libpcreposix vorbisenc gl libpng16 vorbisfile glu libpng vorbis gmodule-2.0 libpostproc vpx gmodule-export-2.0 librsvg-2.0 x264 gmodule-no-export-2.0 libssl zlib gnutls libswresample"
+
+LINK=`$PKG_CONFIG --libs --static $LIBS`
+
+# No pkgconfig for Boost :(
+#LINK="$LINK -L$MXE_PREFIX/usr/i686-pc-mingw32/lib"
+#LINK="$LINK -Wl,-Bstatic -lboost_thread_win32-mt -lboost_date_time-mt -lboost_filesystem-mt -lboost_program_options-mt -lboost_regex-mt -lboost_system-mt"
+
+echo -n $LINK
+
diff --git a/win32/mxe/make-installer.py b/win32/mxe/make-installer.py
new file mode 100755 (executable)
index 0000000..4d0490b
--- /dev/null
@@ -0,0 +1,130 @@
+#!/usr/bin/env python
+# NSIS script generator for Performous.
+# Copyright (C) 2010 John Stumpo
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+import os
+import subprocess
+import sys
+
+try:
+    makensis = subprocess.Popen([os.environ['MAKENSIS'], '-'], stdin=subprocess.PIPE)
+except KeyError:
+    makensis = subprocess.Popen(['makensis', '-'], stdin=subprocess.PIPE)
+
+if not os.path.isdir('dist'):
+    os.mkdir('dist')
+os.chdir('stage')
+
+# Find the version number.
+exepath = 'Performous.exe'
+try:
+    resources = subprocess.Popen([os.environ['WINDRES'], exepath], stdout=subprocess.PIPE)
+except:
+    try:
+        resources = subprocess.Popen(['windres', exepath], stdout=subprocess.PIPE)
+    except:
+        resources = subprocess.Popen(['i686-pc-mingw32-windres', exepath], stdout=subprocess.PIPE)
+for line in resources.stdout.readlines():
+    if not line.strip().startswith('VALUE'):
+        continue
+    if 'ProductVersion' in line:
+        version = line.strip().split('"')[-2]
+        break
+else:
+    version = 'unknown'
+
+
+makensis.stdin.write(r'''!include "MUI2.nsh"
+
+!define VERSION "%s"
+
+Name "Performous ${VERSION}"
+OutFile "dist\Performous-${VERSION}.exe"
+
+SetCompressor /SOLID lzma
+
+ShowInstDetails show
+ShowUninstDetails show
+
+InstallDir "$PROGRAMFILES\Performous"
+InstallDirRegKey HKLM "Software\Performous" ""
+
+RequestExecutionLevel admin
+
+!insertmacro MUI_PAGE_WELCOME
+!insertmacro MUI_PAGE_DIRECTORY
+!insertmacro MUI_PAGE_INSTFILES
+!insertmacro MUI_PAGE_FINISH
+
+!insertmacro MUI_UNPAGE_WELCOME
+!insertmacro MUI_UNPAGE_CONFIRM
+!insertmacro MUI_UNPAGE_INSTFILES
+!insertmacro MUI_UNPAGE_FINISH
+
+!insertmacro MUI_LANGUAGE "English"
+
+Section
+''' % version)
+
+for root, dirs, files in os.walk('.'):
+    makensis.stdin.write('  SetOutPath "$INSTDIR\\%s"\n' % root.replace('/', '\\'))
+    for file in files:
+        makensis.stdin.write('  File "%s"\n' % os.path.join('stage', root, file).replace('/', '\\'))
+
+makensis.stdin.write(r'''  WriteRegStr HKLM "Software\Performous" "" "$INSTDIR"
+  WriteUninstaller "$INSTDIR\uninst.exe"
+  SetShellVarContext all
+  CreateDirectory "$INSTDIR\songs"
+  CreateDirectory "$SMPROGRAMS\Performous"
+  CreateShortcut "$SMPROGRAMS\Performous\Performous.lnk" "$INSTDIR\Performous.exe"
+  CreateShortCut "$SMPROGRAMS\Performous\ConfigureSongDirectory.lnk" "$INSTDIR\ConfigureSongDirectory.bat"
+  CreateShortCut "$SMPROGRAMS\Performous\Songs.lnk" "$INSTDIR\songs"
+  CreateShortcut "$SMPROGRAMS\Performous\Uninstall.lnk" "$INSTDIR\uninst.exe"
+  WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\Performous" "DisplayName" "Performous"
+  WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\Performous" "UninstallString" "$\"$INSTDIR\uninst.exe$\""
+  WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\Performous" "DisplayIcon" "$INSTDIR\Performous.exe"
+  WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\Performous" "DisplayVersion" "${VERSION}"
+SectionEnd
+
+Section Uninstall
+''')
+
+for root, dirs, files in os.walk('.', topdown=False):
+    for dir in dirs:
+        makensis.stdin.write('  RmDir "$INSTDIR\\%s"\n' % os.path.join(root, dir).replace('/', '\\'))
+    for file in files:
+        makensis.stdin.write('  Delete "$INSTDIR\\%s"\n' % os.path.join(root, file).replace('/', '\\'))
+    makensis.stdin.write('  RmDir "$INSTDIR\\%s"\n' % root.replace('/', '\\'))
+
+makensis.stdin.write(r'''  Delete "$INSTDIR\uninst.exe"
+  RmDir "$INSTDIR"
+  SetShellVarContext all
+  Delete "$SMPROGRAMS\Performous\Performous.lnk"
+  Delete "$SMPROGRAMS\Performous\ConfigureSongDirectory.lnk"
+  Delete "$SMPROGRAMS\Performous\Songs.lnk"
+  Delete "$SMPROGRAMS\Performous\Uninstall.lnk"
+  RmDir "$SMPROGRAMS\Performous"
+  DeleteRegKey HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\Performous"
+  DeleteRegKey /ifempty HKLM "Software\Performous"
+SectionEnd
+''')
+
+makensis.stdin.close()
+if makensis.wait() != 0:
+    print >>sys.stderr, 'Installer compilation failed.'
+    sys.exit(1)
+else:
+    print '\ndist/Performous-%s.exe is ready.' % version
diff --git a/win32/mxe/make-performous.sh b/win32/mxe/make-performous.sh
new file mode 100755 (executable)
index 0000000..a672ed4
--- /dev/null
@@ -0,0 +1,38 @@
+#!/bin/bash -e
+
+MXE_PREFIX=/opt/mxe
+JOBS=`nproc 2>/dev/null`
+STAGE="`pwd`/stage"
+BUILD_TYPE="Release"
+if [ "$1" == "debug" ]; then
+       BUILD_TYPE="RelWithDebInfo"
+       echo "Building with debug symbols"
+       shift
+fi
+
+mkdir -p build
+cd build
+
+cmake ../../.. \
+       -DMXE_HACK=ON \
+       -DPKG_CONFIG_EXECUTABLE="$MXE_PREFIX/usr/bin/i686-pc-mingw32.static-pkg-config" \
+       -DCMAKE_TOOLCHAIN_FILE="$MXE_PREFIX/usr/i686-pc-mingw32.static/share/cmake/mxe-conf.cmake" \
+       -DBoost_THREAD_LIBRARY_RELEASE="$MXE_PREFIX/usr/i686-pc-mingw32.static/lib/libboost_thread_win32-mt.a" \
+       -DCMAKE_BUILD_TYPE=$BUILD_TYPE \
+       -DCMAKE_INSTALL_PREFIX="$STAGE" \
+       -DENABLE_WEBCAM=OFF \
+       -DENABLE_TOOLS=ON
+
+if [ "$1" != "config" ]; then
+       make -j $JOBS
+       make install
+       python ../copydlls.py "$MXE_PREFIX/usr/i686-pc-mingw32.static/bin" "$STAGE"
+
+       if [ "$BUILD_TYPE" == "Release" ]; then
+               echo "Stripping EXEs as this is a release build..."
+               strip "$STAGE/"*.exe "$STAGE/tools/"*.exe
+       fi
+fi
+
+echo "Done"
+
diff --git a/win32/performous.cmake.rc b/win32/performous.cmake.rc
new file mode 100644 (file)
index 0000000..322923f
--- /dev/null
@@ -0,0 +1,34 @@
+#include <winuser.h>
+#include <winver.h>
+
+LANGUAGE 9, 1
+
+1 ICON "@CMAKE_SOURCE_DIR@/win32/performous.ico"
+
+VS_VERSION_INFO VERSIONINFO
+@COMMENTS@ FILEVERSION @VERSION_MAJOR@, @VERSION_MINOR@, @VERSION_PATCH@, @VERSION_TWEAK@
+@COMMENTS@ PRODUCTVERSION @VERSION_MAJOR@, @VERSION_MINOR@, @VERSION_PATCH@, @VERSION_TWEAK@
+ FILEFLAGSMASK VS_FFI_FILEFLAGSMASK
+ FILEOS VOS_NT_WINDOWS32
+ FILETYPE VFT_APP
+ FILESUBTYPE VFT2_UNKNOWN
+BEGIN
+  BLOCK "StringFileInfo"
+  BEGIN
+    BLOCK "040904b0"
+    BEGIN
+      VALUE "CompanyName",  "@CMAKE_PROJECT_NAME@ Developers"
+      VALUE "FileDescription",  "@CMAKE_PROJECT_NAME@ Game"
+      VALUE "FileVersion", "@PROJECT_VERSION@"
+      VALUE "InternalName", "Performous.exe"
+      VALUE "LegalCopyright", "Copyright © 2009 @CMAKE_PROJECT_NAME@ Team - GNU GPL v2 or later"
+      VALUE "OriginalFilename", "Performous.exe"
+      VALUE "ProductName", "@CMAKE_PROJECT_NAME@"
+      VALUE "ProductVersion", "@PROJECT_VERSION@"
+    END
+  END
+  BLOCK "VarFileInfo"
+  BEGIN
+    VALUE "Translation", 0x409, 1200
+  END
+END
diff --git a/win32/performous.ico b/win32/performous.ico
new file mode 100644 (file)
index 0000000..efe4bf8
Binary files /dev/null and b/win32/performous.ico differ