diff --git a/.gitignore b/.gitignore index 372cb8af0..a61a25776 100644 --- a/.gitignore +++ b/.gitignore @@ -37,6 +37,5 @@ src/nhttpd/web/*.js.gz src/zapit/src/pzapit src/zapit/src/udpstreampes src/drivertool -src/gui/svn_version.h -src/gui/git_version.h +src/gui/version.h src/nhttpd/nhttpd.conf diff --git a/configure.ac b/configure.ac index ce1538d5a..e2803c65e 100644 --- a/configure.ac +++ b/configure.ac @@ -249,6 +249,7 @@ data/lcd/icons/Makefile data/lcd/clock/Makefile data/license/Makefile data/locale/Makefile +data/neutrino-scripts/Makefile data/scripts/Makefile data/themes/Makefile src/eitd/Makefile diff --git a/data/Makefile.am b/data/Makefile.am index 765f5960f..d701b459f 100644 --- a/data/Makefile.am +++ b/data/Makefile.am @@ -1,4 +1,4 @@ -SUBDIRS = fonts icons inetradio iso-codes license locale scripts themes +SUBDIRS = fonts icons inetradio iso-codes license locale scripts themes neutrino-scripts if BOXTYPE_TRIPLE SUBDIRS += lcd diff --git a/data/fonts/Makefile.am b/data/fonts/Makefile.am index 43637ecf2..7f822c6b1 100644 --- a/data/fonts/Makefile.am +++ b/data/fonts/Makefile.am @@ -10,3 +10,7 @@ install_DATA = \ DejaVuLGCSansMono-Bold.ttf \ tuxtxt.ttf \ tuxtxt.otb + +if BOXMODEL_APOLLO +install_DATA += UnDotum.ttf +endif diff --git a/data/fonts/UnDotum.ttf b/data/fonts/UnDotum.ttf new file mode 100644 index 000000000..31171981c Binary files /dev/null and b/data/fonts/UnDotum.ttf differ diff --git a/data/icons/Makefile.am b/data/icons/Makefile.am index 6c85adf37..67d8b603d 100644 --- a/data/icons/Makefile.am +++ b/data/icons/Makefile.am @@ -70,6 +70,8 @@ install_DATA += \ dd_avail.png \ dd_gray.png \ down.png \ + dummy.png \ + dummy_small.png \ error.png \ features.png \ file.png \ @@ -125,6 +127,7 @@ install_DATA += \ hint_tvradio_switch.png \ hint_vfd.png \ hint_video.png \ + hint_ytplay.png \ home.png \ icon_green.png \ icon_movieplayer.png \ diff --git a/data/icons/dummy.png b/data/icons/dummy.png new file mode 100644 index 000000000..284b9301b Binary files /dev/null and b/data/icons/dummy.png differ diff --git a/data/icons/dummy_small.png b/data/icons/dummy_small.png new file mode 100644 index 000000000..a4fb33314 Binary files /dev/null and b/data/icons/dummy_small.png differ diff --git a/data/icons/hint_ytplay.png b/data/icons/hint_ytplay.png new file mode 100644 index 000000000..0d687cca0 Binary files /dev/null and b/data/icons/hint_ytplay.png differ diff --git a/data/license/Makefile.am b/data/license/Makefile.am index d8d198554..1946a99bc 100644 --- a/data/license/Makefile.am +++ b/data/license/Makefile.am @@ -2,4 +2,5 @@ installdir = $(DATADIR)/neutrino/license install_DATA = \ deutsch.license \ - english.license + english.license \ + slovak.license diff --git a/data/license/deutsch.license b/data/license/deutsch.license index a1ae108d3..3f183d2b5 100644 --- a/data/license/deutsch.license +++ b/data/license/deutsch.license @@ -1,4 +1,4 @@ -Dieses Programm ist freie Software. Sie können es unter den Bedingungen der GNU General Public License, wie von der Free Software Foundation veröffentlicht, weitergeben und/oder modifizieren, entweder gemäß Version 2 der Lizenz oder (nach Ihrer Option) jeder späteren Version. +Dieses Programm ist freie Software. Sie können es unter den Bedingungen der GNU General Public License, wie von der Free Software Foundation veröffentlicht, weitergeben und/oder modifizieren, gemäß Version 2 der Lizenz. Die Veröffentlichung dieses Programms erfolgt in der Hoffnung, daß es Ihnen von Nutzen sein wird, aber OHNE IRGENDEINE GARANTIE, sogar ohne die implizite Garantie der MARKTREIFE oder der VERWENDBARKEIT FÜR EINEN BESTIMMTEN ZWECK. Details finden Sie in der GNU General Public License. diff --git a/data/license/english.license b/data/license/english.license index 1388ffb16..2a52a4285 100644 --- a/data/license/english.license +++ b/data/license/english.license @@ -1,4 +1,4 @@ -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 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; version 2 of the License. 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. diff --git a/data/license/slovak.license b/data/license/slovak.license new file mode 100644 index 000000000..fb94fcc56 --- /dev/null +++ b/data/license/slovak.license @@ -0,0 +1,5 @@ +Tento program je slobodný softvér: môžete ho šíriť a upravovať podľa ustanovení Všeobecnej verejnej licencie GNU (GNU General Public License), vydávanej nadáciou Free Software Foundation, a to buď podľa 2.verzie tejto Licencie, alebo (podľa vášho uváženia) ktorejkoľvek neskoršej verzie. + +Tento program je šírený v nádeji, že bude užitočný, avšak BEZ AKEJKOĽVEK ZÁRUKY. Neposkytujú sa ani odvodené záruky OBCHODOVATEĽNOSTI alebo VHODNOSTI PRE URČITÝ ÚČEL. Ďalšie podrobnosti hľadajte vo Všeobecnej verejnej licencii GNU. + +Kópiu Všeobecnej verejnej licencie GNU ste mali dostať spolu s týmto programom. Ak sa tak nestalo, napíšte na: Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. diff --git a/data/locale/Makefile.am b/data/locale/Makefile.am index c4afe84ff..7706a5c88 100644 --- a/data/locale/Makefile.am +++ b/data/locale/Makefile.am @@ -1,6 +1,7 @@ installdir = $(DATADIR)/neutrino/locale locale = \ + nederlands.locale \ deutsch.locale \ english.locale @@ -12,7 +13,6 @@ locale_unmaintained = \ unmaintained/czech.locale \ unmaintained/francais.locale \ unmaintained/italiano.locale \ - unmaintained/nederlands.locale \ unmaintained/polski.locale \ unmaintained/portugues.locale \ unmaintained/russkij.locale \ diff --git a/data/locale/deutsch.locale b/data/locale/deutsch.locale index 111456f90..642293ccd 100644 --- a/data/locale/deutsch.locale +++ b/data/locale/deutsch.locale @@ -98,6 +98,7 @@ GENRE.TRAVEL_HOBBIES.7 Garten GENRE.UNKNOWN Unbekannt apidselector.head Sprachauswahl audio.srs_algo Art +audio.srs_algo_heavy stark audio.srs_algo_light einfach audio.srs_algo_normal normal audio.srs_iq SRS TruVolume Technologie @@ -479,6 +480,8 @@ flashupdate.globalprogress Gesamtstatus: flashupdate.head Aktualisierung flashupdate.md5check Imageprüfung flashupdate.md5sumerror Das Image ist fehlerhaft +flashupdate.menu_apply_kernel Kernel flashen +flashupdate.menu_apply_settings Settingsübernahme erlauben flashupdate.msgbox Es wurde folgendes neues File gefunden:\nDatum: %s, %s\nBasisImage: %s\nTyp: %s\n\nWollen Sie diese Version jetzt herunterladen\nund installieren? flashupdate.msgbox_manual Es wurde ein neues Image gefunden:\nDatum: %s, %s\nBasisImage: %s\nImageTyp: %s\n\nWollen Sie diese Version jetzt installieren? flashupdate.mtdselector Partitions-Auswahl @@ -593,6 +596,7 @@ imageinfo.homepage Homepage: imageinfo.image Image: imageinfo.kernel Kernel: imageinfo.license Lizenz: +imageinfo.vcs Git: imageinfo.version Version: inetradio.name Internetradio infoviewer.epgnotload Informationen noch nicht geladen... @@ -778,6 +782,7 @@ menu.hint_epg_max_events Maxiale Anzahl der Events im Zwischenspeicher menu.hint_epg_old_events Veraltete EPG-Daten werden nach dieser Zeit (in Stunden) verworfen menu.hint_epg_save Speichert die EPG-Daten auf einem externen Datenträger und läd es von dort nach einen Neustart menu.hint_epg_save_standby Speichert die EPG-Daten auch im Standby-Modus +menu.hint_epg_scan Aktivieren Sie den Hintergrundscan der EPG-Daten, wenn ein freier Tuner vorhanden ist menu.hint_event_textcolor Ändern Sie die Farbe für farbige Events in der Kanalliste und der Infobar menu.hint_eventlist_additional Definiert, ob zusätzliche Informationen im Hauptfenster angezeigt werden sollen menu.hint_eventlist_fonts Ändern Sie die Schriftgröße in der Event-Liste @@ -856,6 +861,7 @@ menu.hint_key_mpplay Weisen Sie eine Taste zu, um die Wiedergabe zu starten menu.hint_key_mpplugin Weisen Sie eine Taste zu, um ein Plugin zu starten, wenn ihre Wiedergabe läuft menu.hint_key_mprewind Weisen Sie eine Taste zum Zurückspulen in ihren Aufnahmen zu menu.hint_key_mpstop Weisen Sie eine Taste zum Beenden der Wiedergabe zu +menu.hint_key_mpsubtitle Weisen Sie eine Taste für die Untertitel-Auswahl zu menu.hint_key_mptime Weisen Sie eine Taste für die Restzeitanzeige ihrer Aufnahmen zu menu.hint_key_mptimeshift Weisen Sie eine Taste für das Starten von Timeshift zu menu.hint_key_pagedown Weisen Sie eine Taste für das Herunterblättern zu @@ -1116,6 +1122,7 @@ menu.hint_video_scart_mode Wählen Sie den Modus des Ausgangssignals für den SC menu.hint_volume Wählen Sie die Anzeigeoptionen für die Lautstärke menu.hint_volume_digits Zifferndarstellung der Lautstärkeanzeige ein- oder ausschalten menu.hint_volume_pos Wählen Sie die Position der Lautstärkeanzeige aus +menu.hint_ytplay Wiedergabe von ausgewählten Youtube Feeds menu.hint_zap_cycle Wählen Sie, ob nur innerhalb des aktiven Bouquets umgeschaltet werden kann menu.next Weiter (Menü zum Beenden) messagebox.back Zurück @@ -1149,6 +1156,7 @@ miscsettings.epg_old_events_hint1 Wie lange abgelaufene EPG-Daten aufheben? miscsettings.epg_old_events_hint2 Angabe in Stunden miscsettings.epg_save EPG zwischenspeichern miscsettings.epg_save_standby EPG speichern in Standby-Modus +miscsettings.epg_scan Hintergrundscan EPG miscsettings.general Allgemein miscsettings.head Erweitert miscsettings.infobar Infobar @@ -1351,6 +1359,22 @@ moviebrowser.update_if_dest_empty_only Übernehmen nur wenn Ziel leer moviebrowser.use_dir Verzeichnis verwenden moviebrowser.use_movie_dir Wiedergabeverzeichnis verwenden moviebrowser.use_rec_dir Aufnahmeverzeichnis verwenden +moviebrowser.yt_error Fehler beim laden des Youtube Feed +moviebrowser.yt_max_results Max. Anzahl der zu holenden Feeds +moviebrowser.yt_most_discussed Am meisten diskutiert +moviebrowser.yt_most_popular Beliebteste Videos +moviebrowser.yt_most_resent Unbeliebteste Videos +moviebrowser.yt_most_responded Feeds mit den meisten Reaktionen +moviebrowser.yt_most_shared Am häufigsten wiedergegebe Videos +moviebrowser.yt_next_results Nächste Ergebnisse +moviebrowser.yt_on_the_web Trendvideos +moviebrowser.yt_prev_results Vorherige Ergebnisse +moviebrowser.yt_recently_featured Vor kurzem empfohlen +moviebrowser.yt_region Region +moviebrowser.yt_related Passende Videos +moviebrowser.yt_search Suche nach Stichwort +moviebrowser.yt_top_favorites Top Favoriten +moviebrowser.yt_top_rated Am besten bewertet movieplayer.bookmark Bookmarks movieplayer.bookmarkname Bookmark Name movieplayer.bookmarkname_hint1 Geben Sie den Namen für das neue Lesezeichen ein @@ -1372,6 +1396,7 @@ movieplayer.tshelp7 ca. 1 Minute vor movieplayer.tshelp8 ca. 5 Minuten zurück movieplayer.tshelp9 ca. 5 Minuten vor movieplayer.tsplayback TS Abspielen +movieplayer.ytplayback Youtube-Feed Wiedergabe mpkey.audio Audiotrack mpkey.bookmark Speichere Lesezeichen mpkey.forward Vorlauf @@ -1380,6 +1405,7 @@ mpkey.play Play mpkey.plugin Starte Plugin mpkey.rewind Rücklauf mpkey.stop Stopp +mpkey.subtitle Untertitel mpkey.time Zeitanzeige networkmenu.apply_settings Änderungen werden übernommen... networkmenu.apply_settings_now Änderungen jetzt zuweisen? @@ -1715,6 +1741,7 @@ settings.pos_bottom_center unten zentriert settings.pos_bottom_left unten links settings.pos_bottom_right unten rechts settings.pos_default_center zentriert +settings.pos_higher_center höher zentriert settings.pos_top_center oben zentriert settings.pos_top_left oben links settings.pos_top_right oben rechts @@ -1832,6 +1859,7 @@ timing.infobar_movieplayer Infobar (Filmwiedergabe) timing.infobar_radio Infobar (Radiobetrieb) timing.menu Menü timing.numericzap Umschalten mit Zifferntasten +timing.volumebar Lautstärkeanzeige unicable.lnb Unicable Eingang unicable.qrg Unicable Frequenz unicable.scr Unicable SCR diff --git a/data/locale/english.locale b/data/locale/english.locale index 65360c365..20f726d18 100644 --- a/data/locale/english.locale +++ b/data/locale/english.locale @@ -98,6 +98,7 @@ GENRE.TRAVEL_HOBBIES.7 gardening GENRE.UNKNOWN unknown apidselector.head Select language audio.srs_algo Type +audio.srs_algo_heavy Heavy audio.srs_algo_light Light audio.srs_algo_normal Normal audio.srs_iq SRS TruVolume algo @@ -325,7 +326,7 @@ eventfinder.search_all_epg whole eventfinder.search_within_epg Search within eventfinder.search_within_list Search within eventfinder.searching Search for keyword in EPG... -eventfinder.start_search Start Search +eventfinder.start_search Start Search eventlist.additional Additional informations eventlist.name Eventlist eventlistbar.channelswitch schedule @@ -479,6 +480,8 @@ flashupdate.globalprogress Global Progress: flashupdate.head Software Update flashupdate.md5check checking image flashupdate.md5sumerror image has errors +flashupdate.menu_apply_kernel Flashing kernel +flashupdate.menu_apply_settings Allow apply settings flashupdate.msgbox Found the following new file:\nDate: %s, %s\nBaseImage: %s\nType: %s\n\nDo you want to download and install this version now? flashupdate.msgbox_manual Found the following new image:\nDate: %s, %s\nBaseImage: %s\nImageType: %s\n\nDo you want to install this version now? flashupdate.mtdselector Partition-Selector @@ -593,6 +596,7 @@ imageinfo.homepage Home page: imageinfo.image Image: imageinfo.kernel Kernel: imageinfo.license License: +imageinfo.vcs Git: imageinfo.version Version: inetradio.name Internetradio infoviewer.epgnotload EPG not loaded.... @@ -778,6 +782,7 @@ menu.hint_epg_max_events Maximum events to cache. After reaching limit\nEPG cach menu.hint_epg_old_events Hours after event end time to consider\nevent old and remove it from cache menu.hint_epg_save Save cached EPG to harddisk or usb flash\nand load it after boot menu.hint_epg_save_standby Save EPG on soft standby mode +menu.hint_epg_scan Enable background epg scan using free tuner menu.hint_event_textcolor Change event color for colored-event options\nin channel list and infobar menu.hint_eventlist_additional Show additional informations\nin main box menu.hint_eventlist_fonts Change event list font sizes @@ -856,6 +861,7 @@ menu.hint_key_mpplay Assign button to resume record/file playback menu.hint_key_mpplugin Assign button to start selected plugin\nwhile playing record/file menu.hint_key_mprewind Assign button to rewind record playback menu.hint_key_mpstop Assign button to stop record/file playback +menu.hint_key_mpsubtitle Assign button to show subtitle selection menu.hint_key_mptime Assign button to show play time\nleft time menu.hint_key_mptimeshift Assign button to start timeshift menu.hint_key_pagedown Assign button to show next items page @@ -1116,6 +1122,7 @@ menu.hint_video_scart_mode Select analog output mode for SCART connectors menu.hint_volume Configure Volume GUI options menu.hint_volume_digits Numeric display of the volumebar on/off menu.hint_volume_pos Select volume indicator position +menu.hint_ytplay Play selected youtube feeds menu.hint_zap_cycle When swithing channels, stay in current bouquet menu.next Next (press Menu to quit) messagebox.back Back @@ -1149,6 +1156,7 @@ miscsettings.epg_old_events_hint1 How long will EPG-Data be stored after they ti miscsettings.epg_old_events_hint2 Set in hours miscsettings.epg_save Save/Restore epg on reboot miscsettings.epg_save_standby Save epg on soft standby +miscsettings.epg_scan EPG scan miscsettings.general General miscsettings.head Extended settings miscsettings.infobar Infobar @@ -1351,6 +1359,22 @@ moviebrowser.update_if_dest_empty_only Copy if destination is empty only moviebrowser.use_dir Use directory moviebrowser.use_movie_dir Use movie directory moviebrowser.use_rec_dir Use record directory +moviebrowser.yt_error Failed to load youtube feed +moviebrowser.yt_max_results Max results to fetch +moviebrowser.yt_most_discussed Most discussed +moviebrowser.yt_most_popular Most popular +moviebrowser.yt_most_resent Most resent +moviebrowser.yt_most_responded Most responded +moviebrowser.yt_most_shared Most shared +moviebrowser.yt_next_results Next results +moviebrowser.yt_on_the_web Trending videos +moviebrowser.yt_prev_results Previous results +moviebrowser.yt_recently_featured Recently featured +moviebrowser.yt_region Region +moviebrowser.yt_related Related videos +moviebrowser.yt_search Search keyword +moviebrowser.yt_top_favorites Top favorites +moviebrowser.yt_top_rated Top rated movieplayer.bookmark Bookmarks movieplayer.bookmarkname Bookmarkname movieplayer.bookmarkname_hint1 Enter a name for your new bookmark @@ -1372,6 +1396,7 @@ movieplayer.tshelp7 skip approx. 1 minute movieplayer.tshelp8 approx. 5 minutes back movieplayer.tshelp9 skip approx. 5 minutes movieplayer.tsplayback Play TS +movieplayer.ytplayback Youtube feeds playback mpkey.audio Audio track mpkey.bookmark save bookmark mpkey.forward Forward @@ -1380,6 +1405,7 @@ mpkey.play Play mpkey.plugin Run plugin mpkey.rewind Rewind mpkey.stop Stop +mpkey.subtitle Subtitles mpkey.time Show time networkmenu.apply_settings Changes are applied... networkmenu.apply_settings_now Do you want to apply settings now? @@ -1715,6 +1741,7 @@ settings.pos_bottom_center bottom center settings.pos_bottom_left bottom left settings.pos_bottom_right bottom right settings.pos_default_center center +settings.pos_higher_center higher center settings.pos_top_center top center settings.pos_top_left top left settings.pos_top_right top right @@ -1832,6 +1859,7 @@ timing.infobar_movieplayer Infobar (movie mode) timing.infobar_radio Infobar (radio mode) timing.menu Menu timing.numericzap Numeric Zap +timing.volumebar Volume bar unicable.lnb Unicable Input unicable.qrg Unicable Frequency unicable.scr Unicable SCR diff --git a/data/locale/unmaintained/dutch.locale b/data/locale/nederlands.locale similarity index 100% rename from data/locale/unmaintained/dutch.locale rename to data/locale/nederlands.locale diff --git a/data/locale/unmaintained/nederlands.locale b/data/locale/unmaintained/nederlands.locale deleted file mode 100644 index b23984063..000000000 --- a/data/locale/unmaintained/nederlands.locale +++ /dev/null @@ -1,667 +0,0 @@ -EPGMenu.epgplus Preview overzicht -EPGMenu.eventinfo Info over uitzending -EPGMenu.eventlist Preview programma -EPGMenu.head EPG - Programma Informatie -EPGMenu.streaminfo technische Informatie -EPGPlus.actions Aktie's -EPGPlus.head Preview (EPG Plus) -EPGPlus.next_bouquet Volgend Boeket -EPGPlus.options Optie's -EPGPlus.page_down Vorige pagina. -EPGPlus.page_up Volgende pagina. -EPGPlus.prev_bouquet Vorig Boeket. -EPGPlus.record Opname -EPGPlus.refresh_epg Aktualiseren -EPGPlus.remind Herinneren -EPGPlus.scroll_mode Scroll Mode -EPGPlus.select_font_name Lettertype kiezen -EPGPlus.stretch_mode Stretch Mode -EPGPlus.swap_mode Bladeren -EPGPlus.view_mode Mode -GENRE.ARTS.0 Kunst/ cultuur -GENRE.ARTS.1 Beeldende kunst -GENRE.ARTS.10 kunst/culturele magazines -GENRE.ARTS.11 mode -GENRE.ARTS.2 fijne kunst -GENRE.ARTS.3 religie -GENRE.ARTS.4 populair cultuur/traditionele kunst -GENRE.ARTS.5 literatuur -GENRE.ARTS.6 film/cinema -GENRE.ARTS.7 experimentele film/video -GENRE.ARTS.8 uitzendingen/pers -GENRE.ARTS.9 nieuwe media -GENRE.CHILDRENs_PROGRAMMES.0 Kinderprogramma/ animatie -GENRE.CHILDRENs_PROGRAMMES.1 Kleuterprogramma -GENRE.CHILDRENs_PROGRAMMES.2 Ontspanningsprogramma (leeftijd: 6 tot 14) -GENRE.CHILDRENs_PROGRAMMES.3 Ontspanningsprogramma (leeftijd: 10 tot 16) -GENRE.CHILDRENs_PROGRAMMES.4 informationeel/educationeel/schoolprogramma -GENRE.CHILDRENs_PROGRAMMES.5 tekenfilms/animatie -GENRE.DOCUS_MAGAZINES.0 documentatie/magazine -GENRE.DOCUS_MAGAZINES.1 natuur/dieren/omgeving -GENRE.DOCUS_MAGAZINES.2 technologie/natuurkunde -GENRE.DOCUS_MAGAZINES.3 Geneeskunde/psychologie/ -GENRE.DOCUS_MAGAZINES.4 Vreemde landen/expeditie's -GENRE.DOCUS_MAGAZINES.5 sociale- en spirituele wetenschappen -GENRE.DOCUS_MAGAZINES.6 andere opvoedingen -GENRE.DOCUS_MAGAZINES.7 Talen -GENRE.MOVIE.0 film/drama -GENRE.MOVIE.1 detectieve/thriller -GENRE.MOVIE.2 aventuren/western/oorlog -GENRE.MOVIE.3 science-fiction/fantasy/horror -GENRE.MOVIE.4 comedy -GENRE.MOVIE.5 soap/melodrama/folkloristisch -GENRE.MOVIE.6 romantiek -GENRE.MOVIE.7 ernstig/klassiek/religieus/historische film/drama -GENRE.MOVIE.8 +18 / drama -GENRE.MUSIC_DANCE.0 muziek / ballet / dance -GENRE.MUSIC_DANCE.1 rock/pop -GENRE.MUSIC_DANCE.2 klassieke music -GENRE.MUSIC_DANCE.3 folk/traditionele muziek -GENRE.MUSIC_DANCE.4 jazz -GENRE.MUSIC_DANCE.5 musical/opera -GENRE.MUSIC_DANCE.6 ballet -GENRE.NEWS.0 nieuws -GENRE.NEWS.1 nieuws/weerbulletin -GENRE.NEWS.2 nieuwsmagazine -GENRE.NEWS.3 documentaire -GENRE.NEWS.4 discussie/interview/debat -GENRE.SHOW.0 Show / Spelshow -GENRE.SHOW.1 game show/quiz/contest -GENRE.SHOW.2 varieteit show -GENRE.SHOW.3 talk show -GENRE.SOCIAL_POLITICAL.0 sociale en politieke evenementen/zaken -GENRE.SOCIAL_POLITICAL.1 magazines/verslagen/documentaire -GENRE.SOCIAL_POLITICAL.2 economische /sociale adviezen -GENRE.SOCIAL_POLITICAL.3 Opmerkzame personen -GENRE.SPORTS.0 sport -GENRE.SPORTS.1 speciale evenementen (Olympische spelen,Wereldbeker, etc.) -GENRE.SPORTS.10 paardensport -GENRE.SPORTS.11 gevechtsporten -GENRE.SPORTS.2 sportmagazine -GENRE.SPORTS.3 Voetbal -GENRE.SPORTS.4 tennis/squash -GENRE.SPORTS.5 teamsporten -GENRE.SPORTS.6 atletiek -GENRE.SPORTS.7 motorsport -GENRE.SPORTS.8 watersport -GENRE.SPORTS.9 wintersport -GENRE.TRAVEL_HOBBIES.0 reizen en ontspanning -GENRE.TRAVEL_HOBBIES.1 tourisme/reizen -GENRE.TRAVEL_HOBBIES.2 werk -GENRE.TRAVEL_HOBBIES.3 autotoerisme -GENRE.TRAVEL_HOBBIES.4 fitness & gezondheid -GENRE.TRAVEL_HOBBIES.5 koken -GENRE.TRAVEL_HOBBIES.6 adverteren/shopping -GENRE.TRAVEL_HOBBIES.7 tuinieren -GENRE.UNKNOWN Onbekend -apids.hint_1 Geef de te streamen APIDs in -apids.hint_2 in hex-weergave scheiden met ' ' -apidselector.head Kies taal -audiomenu.PCMOffset Volume Decrease PCM -audiomenu.analogout Analoge uitgang -audiomenu.avs avs -audiomenu.dolbydigital Dolby Digital -audiomenu.monoleft mono links -audiomenu.monoright mono rechts -audiomenu.stereo stereo -audioplayer.add Voeg toe -audioplayer.artist_title Artiest, Titel -audioplayer.defdir Startdirectory -audioplayer.delete Wis -audioplayer.deleteall Wis alles -audioplayer.display_order display order -audioplayer.fastforward Vooruitspoelen -audioplayer.follow auto Kies huidig -audioplayer.head Audio Speellijst -audioplayer.highprio Hoge decoderingsprioriteit -audioplayer.id3scan Scannen van ID3 tags -audioplayer.keylevel key level -audioplayer.name Audioplayer -audioplayer.pause pauze -audioplayer.play Play -audioplayer.playing Huidig nummer -audioplayer.rewind terugspoelen -audioplayer.screensaver_timeout screensaver timeout (min, 0=uit) -audioplayer.shuffle shuffle -audioplayer.stop Stop -audioplayer.title_artist Titel, Artiest -audioplayerpicsettings.general Audioplayer/ beeldviewer -bookmarkmanager.delete Verwijderen -bookmarkmanager.name Favorieten -bookmarkmanager.rename Hernoemen -bookmarkmanager.select Kiezen -bouqueteditor.add Voeg toe -bouqueteditor.bouquetname Naam van het boeket -bouqueteditor.delete Wis -bouqueteditor.discardingchanges Wegzetten van de wijzigingen, even geduld a.u.b... -bouqueteditor.hide Verberg -bouqueteditor.lock Slot -bouqueteditor.move Verzet -bouqueteditor.name Boeket-editor -bouqueteditor.newbouquetname Nieuwe naam van het boeket -bouqueteditor.rename Hernoem -bouqueteditor.return Klaar -bouqueteditor.savechanges? Wilt u de wijzigingen bewaren? -bouqueteditor.savingchanges Bewaren van wijzigingen, even geduld... -bouqueteditor.switch Toevoegen/verwijderen -bouqueteditor.switchmode TV/Radio -bouquetlist.head Boeket -cablesetup.provider Kabelprovider -channellist.head Alle Services -channellist.nonefound Geen kanalen gevonden!\nVoer aub een scan uit\n(dbox-toets -> service) -channellist.since sinds -colorchooser.alpha alpha -colorchooser.blue blauw -colorchooser.green groen -colorchooser.red rood -colormenu.background Achtergrond -colormenu.background_head Achtergrond -colormenu.fade Fade menu's -colormenu.font lettergrootte -colormenu.menucolors Menu kleuren -colormenu.statusbar Infobar -colormenu.textcolor Tekstkleur -colormenu.textcolor_head Tekstkleur -colormenu.themeselect selecteer onderwerp -colormenu.timing OSD Tijd -colormenusetup.menucontent Vensterinhoud -colormenusetup.menucontent_inactive Vensterinhoud niet actief -colormenusetup.menucontent_selected Vensterinhoud geactiveerd -colormenusetup.menuhead Menu bovenkant -colorstatusbar.head Infobar -colorstatusbar.text Infobar -colorthememenu.classic_theme Classic thema -colorthememenu.dblue_theme Donkerblauw thema -colorthememenu.dvb2k_theme DVB2000 thema -colorthememenu.head Themakeuze -colorthememenu.neutrino_theme Neutrino thema -date.Apr April -date.Aug Augustus -date.Dec December -date.Feb Februari -date.Fri vrijdag -date.Jan Januari -date.Jul Juli -date.Jun Juni -date.Mar Maart -date.May Mei -date.Mon maandag -date.Nov November -date.Oct Oktober -date.Sat zaterdag -date.Sep September -date.Sun zondag -date.Thu donderdag -date.Tue dinsdag -date.Wed woensdag -epglist.head Event-list - %s -epglist.noevents EPG is niet beschikbaar -epgviewer.More_Screenings Meerdere Screenings op dit kanaal -epgviewer.nodetailed Geen details beschikbaar -epgviewer.notfound Geen EPG gevonden -eventlistbar.channelswitch Planning -eventlistbar.eventsort Sorteren -eventlistbar.recordevent Opnemen -favorites.addchannel Huidig kanaal zal toegevoegd worden\naan het boeket "mijn favorieten".\nDit zal enkele seconden durens... -favorites.bouquetname Mijn favorieten -favorites.bqcreated Bouquet "Mijn favorieten" is gemaakt...\n -favorites.chadded Huidig kanaal is aan de favorieten toegevoegd...\n -favorites.chalreadyinbq Huidig kanaal staat reeds bij de favorieten...\n -favorites.finalhint \nGebruik de boeketeditor om de favorieten aan te passen.\n -favorites.menueadd Voeg kanaal aan favorieten toe. -favorites.nobouquets Favorieten zijn alleen beschikbaar met geactiveerde boeketten. -filebrowser.delete Verwijderen -filebrowser.dodelete1 Moet -filebrowser.dodelete2 gewist worden? -filebrowser.filter.active Filter aan -filebrowser.filter.inactive Filter uit -filebrowser.head Browser -filebrowser.mark Markeer -filebrowser.nextpage Volgende pagina -filebrowser.prevpage Vorige pagina -filebrowser.scan Folders doorzoeken -filebrowser.select Kies -filebrowser.showrights Toon rechten -filebrowser.sort.date (datum) -filebrowser.sort.name (bestandsname) -filebrowser.sort.namedirsfirst (Dateiname2) -filebrowser.sort.size (Grootte) -filebrowser.sort.type (Type) -flashupdate.actionreadflash lezen -flashupdate.cantopenfile Kan bestand niet openen -flashupdate.cantopenmtd Kan het mtd-device niet openen -flashupdate.checkupdate Zoek nieuwe versie -flashupdate.currentversion_sep Huidige versie -flashupdate.currentversiondate Datum -flashupdate.currentversiontime Tijd -flashupdate.erasefailed Wissen van de flash mislukt -flashupdate.erasing Wissen van de flash -flashupdate.experimentalimage De gekozen image is nog niet getest.D.w.z.dat\nuw ontvanger misschien niet opstart na de update.\n\nWilt u echt deze versie updaten? -flashupdate.expertfunctions Expert-functie's -flashupdate.fileis0bytes De grootte van het bestand is 0 Byte -flashupdate.fileselector File kiezen -flashupdate.flashreadyreboot De image is succesvol geflashed.\nDe DBox zal nu herstarten. -flashupdate.getinfofile Haalt info versie op -flashupdate.getinfofileerror Geen info van de versie gevonden -flashupdate.getupdatefile Krijgt een update -flashupdate.getupdatefileerror Krijgt geen update -flashupdate.globalprogress Globale vooruitgang: -flashupdate.head Software Update -flashupdate.md5check controleer image -flashupdate.md5sumerror Image heeft fouten -flashupdate.msgbox De volgende nieuwe image is gevonden:\nDatum: %s, %s\nBaseImage: %s\nImageType: %s\n\nWilt u de nieuwe image nu downloaden en installeren? -flashupdate.msgbox_manual De volgende nieuwe image is gevonden:\nDatum: %s, %s\nBaseImage: %s\nImageType: %s\n\nWilt u deze versie nu installeren? -flashupdate.mtdselector Partitie kiezen -flashupdate.programmingflash Programmeren van de flash -flashupdate.proxypassword Paswoord -flashupdate.proxypassword_hint1 Geef het paswoord voor de proxyserver -flashupdate.proxypassword_hint2 Leeg betekent geen proxy -flashupdate.proxyserver Hostnaam -flashupdate.proxyserver_hint1 Geef naam of IP proxyserver, Gebruik host: poort -flashupdate.proxyserver_hint2 Geen invoer = geen proxy -flashupdate.proxyserver_sep Proxyserver -flashupdate.proxyusername Gebruikersnaam -flashupdate.proxyusername_hint1 Geef de gebruikersnaam van de proxyserver -flashupdate.proxyusername_hint2 Geen invoer= geen proxy-auth -flashupdate.readflash Lees de hele image -flashupdate.readflashmtd Lees een partitie -flashupdate.ready Klaar -flashupdate.reallyflashmtd Wilt u echt flashen?\n\nAls er een fout optreed is de image niet\ngeldig, De Dbox zal niet starten na het flashen.\n\nImagename: %s\nTarget: %s -flashupdate.savesuccess De image is succesvol bewaard \nonder %s. -flashupdate.selectimage Beschikbare Images -flashupdate.squashfs.noversion Versiecontrole van SquashFS gaat momenteel enkel via webupdating -flashupdate.titlereadflash Lezen Flash -flashupdate.titlewriteflash Writing Flash -flashupdate.updatemode Updatemode -flashupdate.updatemode_internet Internet -flashupdate.updatemode_manual Manueel (ftp) -flashupdate.url_file config file -flashupdate.versioncheck Controleer versie -flashupdate.writeflash Schrijf de hele image -flashupdate.writeflashmtd Schrijf een partitie -flashupdate.wrongbase Your Release cycle differs, unable to update\nwithout having installed the right version! -fontmenu.channellist kanalenlijst -fontmenu.epg EPG -fontmenu.eventlist Eventlist -fontmenu.gamelist Spellijst -fontmenu.head Settings lettergrootte -fontmenu.infobar Infobar -fontsize.channel_num_zap Directe selectie -fontsize.channellist Kanalenlijst -fontsize.channellist_descr Omschrijving -fontsize.channellist_number Nummer -fontsize.epg_date EPG datum -fontsize.epg_info1 EPG Info 1 -fontsize.epg_info2 EPG Info 2 -fontsize.epg_title EPG Titel -fontsize.eventlist_datetime datum/tijd -fontsize.eventlist_itemlarge groot -fontsize.eventlist_itemsmall klein -fontsize.eventlist_title Titel -fontsize.filebrowser_item filebrowser item -fontsize.gamelist_itemlarge groot -fontsize.gamelist_itemsmall klein -fontsize.hint lettertype instellen,\ngeduld aub... -fontsize.infobar_channame Kanaalnaam -fontsize.infobar_info info -fontsize.infobar_number Nummer -fontsize.infobar_small klein -fontsize.menu Menutekst -fontsize.menu_info Menu Info -fontsize.menu_title Menu Titel -gtxalpha.alpha1 Alpha 1 -gtxalpha.alpha2 Alpha 2 -infoviewer.epgnotload EPG niet geladen.... -infoviewer.epgwait wachten op EPG... -infoviewer.eventlist Event-Lijst -infoviewer.languages Geluid -infoviewer.motor_moving Positionering van de antenne -infoviewer.nocurrent Geen info beschikbaar voor dit programma -infoviewer.noepg EPG is niet beschikbaar -infoviewer.notavailable Kanaal is niet beschikbaar -infoviewer.selecttime Tijdskeuze -infoviewer.streaminfo Kenmerken -infoviewer.subservice Subservices -infoviewer.waittime Wacht op de tijd... -ipsetup.hint_1 Gebruik 0 tot 9, of Use 0..9, of gebruik Up/Down, -ipsetup.hint_2 OK bewaar, Home afbreken -keybindingmenu.RC Key herhaal-blocker -keybindingmenu.addrecord Voeg record timer toe -keybindingmenu.addrecord_head Voeg record timer toe -keybindingmenu.addremind add zapto timer -keybindingmenu.addremind_head add zapto timer -keybindingmenu.allchannels_on_ok Alle services -keybindingmenu.bouquetchannels_on_ok Huidig boeket -keybindingmenu.bouquetdown vorig boeket -keybindingmenu.bouquetdown_head keysetup vorig boeket back -keybindingmenu.bouquethandling Boeket-control -keybindingmenu.bouquetlist_on_ok Boeketlijst -keybindingmenu.bouquetup Volgend boeket -keybindingmenu.bouquetup_head keysetup Volgend boeket -keybindingmenu.cancel Sluit kanalenlijst -keybindingmenu.cancel_head Kanalenlijst gesloten -keybindingmenu.channeldown Kanaal omlaag -keybindingmenu.channeldown_head Keysetup channel down -keybindingmenu.channellist Kanaallijst -keybindingmenu.channelup kanaal omhoog -keybindingmenu.channelup_head Keysetup channel up -keybindingmenu.head Keybinding Setup -keybindingmenu.modechange Modechange -keybindingmenu.pagedown Volgende pagina -keybindingmenu.pagedown_head Keysetup page down -keybindingmenu.pageup Vorige pagina -keybindingmenu.pageup_head Keysetup page up -keybindingmenu.quickzap Quickzap -keybindingmenu.repeatblock generic delay -keybindingmenu.repeatblockgeneric Herhaal delay -keybindingmenu.sort Verander sorteervolgorde -keybindingmenu.sort_head Verander sorteervolgorde -keybindingmenu.subchanneldown subchannel omlaag -keybindingmenu.subchanneldown_head key subkanaal omlaag -keybindingmenu.subchannelup subkanaal omhoog -keybindingmenu.subchannelup_head key subkanaal omhoog -keybindingmenu.tvradiomode TV/Radio-mode -keybindingmenu.tvradiomode_head TV/Radio-mode -keychooser.head Setup nieuwe Key -keychooser.text1 Geef de nieuwe key in -keychooser.text2 Wacht enkele sec. om af te breken -keychoosermenu.currentkey Huidige key -keychoosermenu.setnew setup nieuwe key -keychoosermenu.setnone Geen key -languagesetup.head Setup Taal -languagesetup.select Taalkeuze -lcdcontroler.brightness normale helderheid -lcdcontroler.brightnessstandby Standby helderheid -lcdcontroler.contrast Contrast -lcdcontroler.head Display-instellingen -lcdmenu.head LCD Settings -lcdmenu.lcdcontroler Contrast / Helderheid -lcdmenu.statusline status lijn -lcdmenu.statusline.both Volume/Speelduur -lcdmenu.statusline.playtime Speelduur -lcdmenu.statusline.volume Volume -mainmenu.audioplayer Audioplayer -mainmenu.games Spelletjes -mainmenu.head Hoofdmenu -mainmenu.movieplayer Filmspeler -mainmenu.pausesectionsd Lees EPG -mainmenu.pictureviewer Weergeven van afbeeldingen -mainmenu.radiomode Radio-Mode -mainmenu.recording Opnemen -mainmenu.recording_start Start opname -mainmenu.recording_stop Stop opname -mainmenu.service Service -mainmenu.settings Instellingen -mainmenu.shutdown Uitschakelen -mainmenu.sleeptimer SleepTimer -mainmenu.tvmode TV-Mode -mainsettings.audio Geluid -mainsettings.colors Kleuren/lettertype -mainsettings.head Settings -mainsettings.keybinding Key Setup -mainsettings.language Taal -mainsettings.lcd LCD-display -mainsettings.misc Overige settings -mainsettings.network Netwerk -mainsettings.recording Opnemen -mainsettings.savesettingsnow Bewaar de settings nu -mainsettings.savesettingsnow_hint Even geduld, settings worden bewaard -mainsettings.video Beeld -menu.back Terug -messagebox.back terug -messagebox.cancel Annuleren -messagebox.discard Bewaren van de wijzigingen? -messagebox.error Fout -messagebox.info Informatie -messagebox.no Neen -messagebox.yes Ja -miscsettings.general Algemeen -miscsettings.head Overige settings -miscsettings.infobar_sat_display Satelliet display in infobar -miscsettings.shutdown_real standby -miscsettings.shutdown_real_rcdelay vertraagde shutdown -miscsettings.startbhdriver load BH-Mode drivers -motorcontrol.head Motor-Setup -movieplayer.bookmark Favorieten -movieplayer.bookmarkname Bookmark Naam -movieplayer.bookmarkname_hint1 Geef de naam voor de -movieplayer.bookmarkname_hint2 nieuwe favoriet in -movieplayer.fileplayback Bestand via VLC -movieplayer.head Filmplayer -movieplayer.toomanybookmarks U heeft te veel favorieten.\nEr moet een andere favoriet gewist worden. -movieplayer.tshelp Rood/Home Stop\nGROEN Kies audio track\nGEEL Pause/Continue\nBLUE Create bookmark\nd-box Show progress\n1 approx. 1 minute back\n3 skip approx. 1 minute\n4 approx. 5 minuten terug\n6 sla over ongeveer 5 minuten\n7 ongeveer 10 minuten terug\n9 sla ongeveer 10 minutes\nHelp: http://www.giggo.de/dbox2/movieplayer.html\n -movieplayer.tsplayback Speel TS -movieplayer.vlchelp ROOD/Home Stop\nGROEN Resync\nGEEL Pause/verder\nBLAUW Favoriet instellen\n1 ca. 1 Minuut terug\n3 ca. 1 Minuut vooruit\n4 ca. 5 Minuten terug\n6 ca. 5 Minuten vooruit\n7 ca. 10 Minuten terug\n9 ca. 10 Minuten vooruit\nHelp: http://www.giggo.de/dbox2/movieplayer.html\n -networkmenu.broadcast Broadcast -networkmenu.dhcp DHCP -networkmenu.gateway Standaard Gateway -networkmenu.ipaddress IP-Addres -networkmenu.mount NFS/CIFS -networkmenu.nameserver Nameserver -networkmenu.netmask Netmasker -networkmenu.setupnow Netwerk nu activeren -networkmenu.setuponstartup Netwerk activeren bij opstarten -networkmenu.show Toon actieve netwerksettings -networkmenu.test Test nu het netwerk -nfs.alreadymounted directory reeds gemount -nfs.automount mount bij starten -nfs.dir directory/share -nfs.ip NFS/CIFS Server IP -nfs.localdir plaatselijke directory -nfs.mount Mount NFS/CIFS volume -nfs.mount_options mountoptie's -nfs.mounterror mountfout -nfs.mounterror_notsup Type filesysteem niet ondersteund -nfs.mountnow direct mounten -nfs.mounttimeout mountfout: timeout -nfs.password paswoord Common Internet File System (CIFS) -nfs.remount Lijst opnieuw mounten -nfs.type type -nfs.type_cifs Common Internet File System (CIFS) -nfs.type_nfs Network File System (NFS) -nfs.umount Umount NFS/CIFS volume -nfs.umounterror umountingfout: volume -nfs.username Gebruikersnaam Common Internet File System (CIFS) -nfsmenu.head NFS/CIFS instellingen -nvod.percentage (%d%% over) -nvod.starting (start binnen %d minuten) -nvodselector.directormode Direct-Mode -nvodselector.head Kies starttijd -nvodselector.subservice Kies Subservice -options.default Reset naar standaard -options.fb Framebuffer -options.null Null -options.off Uit -options.on Aan -options.serial Serieel -parentallock.changepin verander PIN code -parentallock.changepin_hint1 Geef hier de nieuwe PIN-code in! -parentallock.changetolocked on locked bouquets -parentallock.head Voer PIN-code v.h. kinderslot in -parentallock.lockage Programma op slot -parentallock.lockage12 Voor jonger dan 12j -parentallock.lockage16 Voor jonger dan 16j -parentallock.lockage18 Voor jonger dan 18j -parentallock.lockedprogram Gesloten programma (vanaf %d jaar en hoger) -parentallock.never nooit -parentallock.onsignal Bij uitzenden op slot -parentallock.parentallock Kinderslot -parentallock.prompt prompt voor PIN -pictureviewer.defdir startdirectory -pictureviewer.head Weergave van afbeeldingen -pictureviewer.resize.color_average Geavanceerd -pictureviewer.resize.none Geen -pictureviewer.resize.simple Eenvoudig -pictureviewer.scaling schaal -pictureviewer.show Toon -pictureviewer.slide_time toon tijd van slideshow -pictureviewer.slideshow slideshow -pictureviewer.sortorder verander volgorde -pictureviewer.sortorder.date (datum) -pictureviewer.sortorder.filename (bestandsnaam) -ping.ok Bereikbaar door Ping -ping.protocol Niet bereikbaar (fout bij host of protocol) -ping.socket Niet bereikbaar (socketfout) -ping.unreachable Onbereikbaar door Ping -pinprotection.head Voer PIN-code in -pinprotection.wrongcode Foute PIN-Code! Probeer opnieuw -rclock.lockmsg Uw afstandsbediening van de DBox2 zal vergrendeld worden.\nOm de DBox2 vrij te geven druk op \nen op uw afstandsbediening. -rclock.menueadd Vergrendelen afstandsbediening -rclock.title Vergrendel afstandsbediening -rclock.unlockmsg Afstandsbediening in werking. -recordingmenu.defdir Opnamefolder -recordingmenu.file Direct (file) -recordingmenu.filesettingsseparator Direct opnemen -recordingmenu.off Uit -recordingmenu.server server -recordingmenu.server_mac MAC adres -recordingmenu.setupnow Activeer veranderingen -recordingmenu.stream_all_audio_pids Alle audiopids opnemen -recordingmenu.vcr vcr -recordtimer.announce Opname start in enkele minuten -repeatblocker.hint_1 Kortste tijd (in ms) tussen 2 drukken op de knop -repeatblocker.hint_2 Druk op 0 om de blocker uit te zetten (rood is spatie) -satsetup.diseqc DiSEqC -satsetup.diseqc10 DiSEqC 1.0 -satsetup.diseqc11 DiSEqC 1.1 -satsetup.diseqc12 DiSEqC 1.2 -satsetup.diseqcrepeat DiSEqC-herhaling -satsetup.extended DiSEqC-Settings -satsetup.extended_motor Motorsettings -satsetup.minidiseqc Mini-DiSEqC -satsetup.nodiseqc Geen DiSEqC -satsetup.satellite Satelliet -satsetup.smatvremote SMATV Remote Tuning -scants.actcable Kabel: -scants.actsatellite Satelliet: -scants.bouquet Boeket -scants.bouquet_create Maak een nieuw -scants.bouquet_erase Wis alles -scants.bouquet_leave Verlaat huidig -scants.bouquet_satellite Satellietboeket -scants.bouquet_update update -scants.channel Kanaal: -scants.failed Faling transponderscan! -scants.finished Transponderscan succesvol! -scants.freqdata Frequentie -scants.head Scan transponder -scants.numberofdataservices Data: -scants.numberofradioservices Radio: -scants.numberoftotalservices Totaal: -scants.numberoftvservices TV: -scants.provider Provider: -scants.startnow Start scan -scants.transponders Transponders: -screensetup.lowerright groen = setup lower right -screensetup.upperleft rood = setup upper left -servicemenu.head Service -servicemenu.reload Herlaad Kanalenlijst -servicemenu.reload_hint Even geduld, herladen van kanalenlijst -servicemenu.scants Service scan -servicemenu.update Software Update -settings.missingoptionsconffile De neutrino-settings zijn geupdate.\nNew Opties worden standaard gezet. -settings.noconffile Geen neutrino-settings gevonden.\nStandaart in gebruik. -shutdowntimer.announce Box zal uitschakelen in 1 min.\nUitschakelen aflassen? -sleeptimerbox.announce Sleeptimer in 1 min -sleeptimerbox.hint1 Schakel uit in ...minuten. (000=uit) -sleeptimerbox.hint2 dbox2 zal uitgaan na deze tijd. -sleeptimerbox.title Sleeptimer -streaminfo.aratio Aspect Ratio -streaminfo.aratio_unknown Aspect Ratio: onbekend -streaminfo.audiotype Audiotype -streaminfo.bitrate Bitrate -streaminfo.framerate Framerate -streaminfo.framerate_unknown Framerate: onbekend -streaminfo.head Stream-Informatie -streaminfo.not_available Niet beschikbaar -streaminfo.resolution Resolutie -streaming.busy Een of meerdere opnames zijn bezig.\nAls U deze oodschap krijgt en er is geen opname\nbezig herstart dan Neutrino. -streaming.dir_not_writable De opnamefolder is niet bereikbaar.\nOpnemen zal niet gaan. -streaming.write_error De opname is afgebroken \nomdat er een schrijffout opgetreden is. -stringinput.caps caps/geen caps -stringinput.clear Wis alles -timer.eventrecord.msg OK, niet OK -timer.eventrecord.title Opname plannen -timer.eventtimed.msg Dit programma is opgeslagen.\ndbox2 zal opstarten en \nschakelt naar dit programma op het gegeven tijdstip. -timer.eventtimed.title Programmeren -timerbar.channelswitch Overzicht -timerbar.recordevent Opnemen -timerlist.alarmtime Alarm time -timerlist.apids Audio PIDs -timerlist.bouquetselect Kies boeket -timerlist.channel Kanaal -timerlist.channelselect Kies kanaal -timerlist.delete Wis -timerlist.menumodify Pas timer aan -timerlist.menunew nieuwe timer -timerlist.message Boodschap -timerlist.moderadio Radio-kanalen -timerlist.modeselect Mode selection -timerlist.modetv TV-kanalen -timerlist.modify Modify -timerlist.name Timer list -timerlist.new Nieuwe timer -timerlist.program.unknown Programma onbekend -timerlist.reload Herlaad -timerlist.repeat Herhaal -timerlist.repeat.biweekly Tweewekelijks -timerlist.repeat.byeventdescription Bekijk programmatie -timerlist.repeat.daily Dagelijks -timerlist.repeat.fourweekly Vierweekelijks -timerlist.repeat.friday Vr -timerlist.repeat.monday Ma -timerlist.repeat.monthly Maandelijks -timerlist.repeat.once Eenmalig -timerlist.repeat.saturday Za -timerlist.repeat.sunday Zo -timerlist.repeat.thursday Do -timerlist.repeat.tuesday Di -timerlist.repeat.unknown Onbekend -timerlist.repeat.wednesday Woe -timerlist.repeat.weekdays Op weekdagen -timerlist.repeat.weekly weekelijks -timerlist.save Bewaar timer -timerlist.standby SB mode -timerlist.standby.off Standby laten -timerlist.standby.on Enter standby -timerlist.stoptime Stop time -timerlist.type Timer typ -timerlist.type.nextprogram Volgend programma -timerlist.type.record Opnemen -timerlist.type.remind Herinnering -timerlist.type.shutdown Uitschakelen -timerlist.type.sleeptimer Sleeptimer -timerlist.type.standby Standby -timerlist.type.unknown Onbekend -timerlist.type.zapto Zap naar -timerlist.weekdays Weekdagen -timerlist.weekdays.hint_1 Ma Di Wo Do Vr Za Zo -timerlist.weekdays.hint_2 'X'=timer '-' geen timer -timersettings.record_safety_time_after Stop opname tijdscorrectie -timersettings.record_safety_time_after.hint_1 Correctie van tijd in min. (00=uit). Deze tijd -timersettings.record_safety_time_after.hint_2 wordt toegevoegd aan iedere stoptijd van de timer. -timersettings.record_safety_time_before Start opname tijdscorrectie -timersettings.record_safety_time_before.hint_1 Correctie van tijd in min. (00=uit). Deze tijd -timersettings.record_safety_time_before.hint_2 will be deducted of every record timer. -timersettings.separator Timer instellingen -timing.chanlist Kanalenlijst -timing.epg Epg -timing.filebrowser Browser voor bestanden -timing.head OSD Timeouts -timing.hint_1 Tijd in sec. Na deze tijd zal de -timing.hint_2 infobar verdwijnen. -timing.infobar Infobar -timing.menu Menu -videomenu.csync Sync.-correctie -videomenu.screensetup Scherm Setup -videomenu.videoformat Formaat -videomenu.videoformat_169 16:9 -videomenu.videoformat_43 4:3 (LB) -videomenu.videoformat_431 4:3 (PS) -videomenu.videosignal Video uit -videomenu.videosignal_composite CVBS -videomenu.videosignal_rgb RGB + CVBS -videomenu.videosignal_svideo S-Video -videomenu.videosignal_yuv_c YUV + CVBS -videomenu.videosignal_yuv_v YUV + VBS -zaptotimer.announce Zapto timer in 1 minuut. diff --git a/data/locale/unmaintained/slovak.locale b/data/locale/unmaintained/slovak.locale index f017fcf0c..f82ed1d3c 100644 --- a/data/locale/unmaintained/slovak.locale +++ b/data/locale/unmaintained/slovak.locale @@ -13,9 +13,9 @@ EPGPlus.options Možnosti EPGPlus.page_down Predchádzajúca strana EPGPlus.page_up Nasledujúca strana EPGPlus.prev_bouquet predch.buket -EPGPlus.record Záznam1 +EPGPlus.record Nahraj EPGPlus.refresh_epg Obnov -EPGPlus.remind Plánovač +EPGPlus.remind Pripomeň EPGPlus.scroll_mode pretáčanie EPGPlus.stretch_mode rozšírenie EPGPlus.swap_mode Zmena stránkovania @@ -98,6 +98,7 @@ GENRE.TRAVEL_HOBBIES.7 záhradkárstvo GENRE.UNKNOWN neznáme apidselector.head Výber jazyka audio.srs_algo Mód +audio.srs_algo_heavy Hrubý audio.srs_algo_light Jemný audio.srs_algo_normal Normálny audio.srs_iq SRS TruVolume @@ -312,14 +313,19 @@ epgextended.year_of_production Rok výroby epglist.noevents Programové informácie (EPG) sú nedostupné... epgviewer.More_Screenings Podobné relácie na tomto kanály epgviewer.More_Screenings_short Viacej relácií +epgviewer.age_rating Vekové obmedzenie +epgviewer.audio Zvuk +epgviewer.genre Žáner +epgviewer.length Dĺžka (min.) epgviewer.nodetailed Detailné informácie sú nedostupné epgviewer.notfound Nenájdené programové informácie (EPG) eventfinder.head Hľadaj v EPG -eventfinder.keyword Klávesnica +eventfinder.keyword Slovo eventfinder.search Hľadaj -eventfinder.search_within_epg Hľadaj s EPG -eventfinder.search_within_list Hľadaj so zoznamom -eventfinder.searching Hľadaj s klávesnicou v EPG... +eventfinder.search_all_epg Všade +eventfinder.search_within_epg Hľadaj v EPG +eventfinder.search_within_list Hľadaj v zozname +eventfinder.searching Hľadám slovo v EPG... eventfinder.start_search Spusti hľadanie eventlist.additional Podrobnejšie informácie eventlist.name Zoznam udalostí @@ -588,6 +594,7 @@ imageinfo.homepage Domov: imageinfo.image Image: imageinfo.kernel Jadro: imageinfo.license Licencia: +imageinfo.vcs Git: imageinfo.version Verzia: inetradio.name Internetové rádio infoviewer.epgnotload EPG informácie nie sú načítané... @@ -657,7 +664,7 @@ keychoosermenu.setnew Nastavenie nového klávesu keychoosermenu.setnone Zrušenie priradenia languagesetup.head Nastavenie jazyka languagesetup.osd Jazyk OSD -languagesetup.select Jazyk +languagesetup.select Jazyk1 lcd_info_line Zobrazenie v inforiadku lcd_info_line_channel Názov kanálu lcd_info_line_clock Hodiny @@ -705,7 +712,7 @@ mainmenu.tvradio_switch Prepnutie TV-Rádio mainsettings.audio Zvuk mainsettings.head Nastavenia mainsettings.keybinding Nastavenia kláves -mainsettings.language Jazyk +mainsettings.language Jazyk / Časové pásmo mainsettings.lcd Zobrazovač VFD mainsettings.manage Spravovanie nastavení mainsettings.misc Iné nastavenia @@ -850,6 +857,7 @@ menu.hint_key_mpplay Priradenie klávesy pre pokračovanie nahrávky menu.hint_key_mpplugin Priradenie klávesy pre spustenie vybraného doplnku\npočas nahrávky menu.hint_key_mprewind Priradenie klávesy pre pretáčanie vzad nahrávky menu.hint_key_mpstop Priradenie klávesy pre zastavenie nahrávky +menu.hint_key_mpsubtitle Priradenie klávesy pre zobrazenie titulkov menu.hint_key_mptime Priradenie klávesy pre zobrazenie časov nahrávky menu.hint_key_mptimeshift Priradenie klávesy pre spustenie časového posunu menu.hint_key_pagedown Priradenie klávesy pre zobrazenie nasledujúcej strany položiek @@ -891,6 +899,7 @@ menu.hint_media Prehrávanie filmov a hudby, prezeranie obrázkov menu.hint_menu_fonts Zmena veľkosti písma menu menu.hint_menu_hints Zobrazí túto radu. Taktiež môžno zmeniť\nkedykoľvek použitím ´HELP´ tlačítka menu.hint_menu_pos Výber umiestnenia menu +menu.hint_menus Konfigurácia volieb ponuky menu.hint_misc_cec HDMI-CEC voľby menu.hint_misc_channellist HD/Nové/Odstránené zoznamy kanálov, cyklické prepnutie menu.hint_misc_energy Použitie pripravenosti, oddialené vypnutie\nčasovače neaktivity @@ -1109,8 +1118,10 @@ menu.hint_video_modes VF klávesa bude cyklovať medzi zvolenými režimami menu.hint_video_pip Veľkosť a umiestneie obrazu v obraze menu.hint_video_saturation Zmena farebnosti obrázku menu.hint_video_scart_mode Výber režimu analógového výstupu pre SCART konektory +menu.hint_volume Konfigurácia volieb okna hlasitosti menu.hint_volume_digits Číselné zobrazenie ukazovateľa hlasitosti ZAP/VYP menu.hint_volume_pos Výber pozície indikátora hlasitosti +menu.hint_ytplay Prehranie vybraných youtube videí menu.hint_zap_cycle Pri prepínaní kanálov zotrvať v aktuálnom bukete menu.next ďaľej (MENU ukončí) messagebox.back späť @@ -1186,6 +1197,7 @@ miscsettings.shutdown_count_hint2 do hlbokého spánku (0=vypnuté) miscsettings.shutdown_real Umožnenie pripravenosti miscsettings.shutdown_real_rcdelay Oneskorenie vypnutia miscsettings.sleeptimer Čas vypnutia pri neaktivite +miscsettings.volume Hlasitosť miscsettings.zapto_pre_time Korekcia času pred prepnutím (minuty) motorcontrol.calc_positions Prepočítaj pozície motorcontrol.disable_limit Vypni (soft) limity @@ -1343,6 +1355,22 @@ moviebrowser.update_if_dest_empty_only Kopírovať len ak je cieľové miesto pr moviebrowser.use_dir Použi adresár moviebrowser.use_movie_dir Použi adresár filmov moviebrowser.use_rec_dir Použi adresár nahrávania +moviebrowser.yt_error Chyba načítania youtube videa +moviebrowser.yt_max_results Dosiahnuté maximum výsledkov +moviebrowser.yt_most_discussed Najdiskutovanejšie +moviebrowser.yt_most_popular Najpopulárnejšie +moviebrowser.yt_most_resent Najodmietanejšie +moviebrowser.yt_most_responded Najodpovedajšie +moviebrowser.yt_most_shared Najzdielanejšie +moviebrowser.yt_next_results Ďaľšie výsledky +moviebrowser.yt_on_the_web Trendové videá +moviebrowser.yt_prev_results Predchádzájúce výsledky +moviebrowser.yt_recently_featured Nedávno odporúčané +moviebrowser.yt_region Región +moviebrowser.yt_related Podobné videá +moviebrowser.yt_search Hľadať slovo +moviebrowser.yt_top_favorites Najobľúbenejšie +moviebrowser.yt_top_rated Najhodnotnejšie movieplayer.bookmark Záložky movieplayer.bookmarkname Názov záložky movieplayer.bookmarkname_hint1 Vloženie názvu @@ -1364,6 +1392,7 @@ movieplayer.tshelp7 asi 1 min dopredu movieplayer.tshelp8 asi 5 min dozadu movieplayer.tshelp9 asi 5 min dopredu movieplayer.tsplayback Prehrať TS +movieplayer.ytplayback Prehrávanie youtube mpkey.audio Zvuková stpopa mpkey.bookmark Ulož záložku mpkey.forward Dopredu @@ -1372,6 +1401,7 @@ mpkey.play Prehraj mpkey.plugin Spusti doplnok mpkey.rewind Dozadu mpkey.stop Zastav +mpkey.subtitle Titulky mpkey.time Zobrazenie času networkmenu.apply_settings Zmeny sa aplikujú... networkmenu.apply_settings_now Chcete teraz aplikovať zmeny? @@ -1699,12 +1729,14 @@ settings.backup_failed Chybná záloha! settings.help Nápoveda settings.menu_hints Zobrazí rady nápovedy settings.menu_pos Umiestnenie ponuky +settings.menus Ponuky settings.missingoptionsconffile Nastavenia Neutrino boli aktualizované.\nNové možosti budú mať prednastavené hodnoty. settings.noconffile Nenájdené nastavenia Neutrino.\nPoužité budú prednastavené hodnoty. +settings.pos_bottom_center spodný stred settings.pos_bottom_left ľavý spodok settings.pos_bottom_right pravý spodok settings.pos_default_center vrchný stred -settings.pos_higher_center spodný stred +settings.pos_top_center vrchný stred settings.pos_top_left ľavý vrch settings.pos_top_right pravý vrch settings.restore Obnovenie nastavení diff --git a/data/neutrino-scripts/Makefile.am b/data/neutrino-scripts/Makefile.am new file mode 100644 index 000000000..4083e81f3 --- /dev/null +++ b/data/neutrino-scripts/Makefile.am @@ -0,0 +1,6 @@ + +installdir = $(CONFIGDIR) +install_DATA = flash.start + +install-data-hook: + chmod 0755 $(DESTDIR)$(CONFIGDIR)/flash.start diff --git a/data/neutrino-scripts/flash.start b/data/neutrino-scripts/flash.start new file mode 100755 index 000000000..253e06d70 --- /dev/null +++ b/data/neutrino-scripts/flash.start @@ -0,0 +1,17 @@ +#!/bin/sh + +if pidof vsftpd > /dev/null; then + echo "Kill vsftpd" + killall vsftpd +fi + +if pidof ushare > /dev/null; then + echo "Kill ushare" + trap "" INT + kill -INT `pidof ushare` +fi + +if [ -e /var/etc/.djmount ]; then + echo "Kill djmount" + fusermount -u /media/00upnp +fi diff --git a/lib/libcoolstream/cnxtfb.h b/lib/libcoolstream/cnxtfb.h index 15a47afc1..b8f1b8149 100644 --- a/lib/libcoolstream/cnxtfb.h +++ b/lib/libcoolstream/cnxtfb.h @@ -39,7 +39,7 @@ typedef enum { CNXTFB_BLEND_MODE_GLOBAL_ALPHA = 0, /* Global / Region Alpha */ CNXTFB_BLEND_MODE_PIXEL_ALPHA, /* Alpha from pixel */ - CNXTFB_BLEND_MODE_ALPHA_MULTIPLIED, /* Global alpha multiplied with pixel alpha */ + CNXTFB_BLEND_MODE_ALPHA_MULTIPLIED /* Global alpha multiplied with pixel alpha */ } CNXTFB_BLEND_MODE; #define CNXTFB_IO(type) _IO('F', type) diff --git a/lib/libcoolstream/cs_frontpanel.h b/lib/libcoolstream/cs_frontpanel.h index 97c0f577a..e85c9f0e8 100644 --- a/lib/libcoolstream/cs_frontpanel.h +++ b/lib/libcoolstream/cs_frontpanel.h @@ -61,7 +61,7 @@ typedef enum { FP_FLAG_SCROLL_DELAY = 0x08, /* delayed scroll start */ FP_FLAG_ALIGN_LEFT = 0x10, /* align the text in display from the left (default) */ FP_FLAG_ALIGN_RIGHT = 0x20, /* align the text in display from the right (arabic) */ - FP_FLAG_UPDATE_SCROLL_POS = 0x40, /* update the current position for scrolling */ + FP_FLAG_UPDATE_SCROLL_POS = 0x40 /* update the current position for scrolling */ } fp_flag; typedef struct { @@ -79,7 +79,7 @@ typedef enum { FP_LED_3_ON = 0x83, FP_LED_1_OFF = 0x01, FP_LED_2_OFF = 0x02, - FP_LED_3_OFF = 0x03, + FP_LED_3_OFF = 0x03 } fp_led_ctrl_t; typedef struct { diff --git a/lib/libcoolstream/cs_vfd.h b/lib/libcoolstream/cs_vfd.h index 4da58296b..377263a85 100755 --- a/lib/libcoolstream/cs_vfd.h +++ b/lib/libcoolstream/cs_vfd.h @@ -60,7 +60,7 @@ typedef enum VFD_FLAG_SCROLL_DELAY = 0x08, /* delayed scroll start */ VFD_FLAG_ALIGN_LEFT = 0x10, /* align the text in display from the left (default) */ VFD_FLAG_ALIGN_RIGHT = 0x20, /* align the text in display from the right (arabic) */ - VFD_FLAG_UPDATE_SCROLL_POS = 0x40, /* update the current position for scrolling */ + VFD_FLAG_UPDATE_SCROLL_POS = 0x40 /* update the current position for scrolling */ } vfd_flag; typedef struct { @@ -78,7 +78,7 @@ typedef enum { VFD_LED_3_ON = 0x83, VFD_LED_1_OFF = 0x01, VFD_LED_2_OFF = 0x02, - VFD_LED_3_OFF = 0x03, + VFD_LED_3_OFF = 0x03 } vfd_led_ctrl_t; typedef struct { diff --git a/lib/libcoolstream/playback_cs.h b/lib/libcoolstream/playback_cs.h index a9192bfdc..f65bdc6f0 100644 --- a/lib/libcoolstream/playback_cs.h +++ b/lib/libcoolstream/playback_cs.h @@ -11,6 +11,8 @@ #define __PLAYBACK_CS_H_ #include +#include +#include typedef enum { PLAYMODE_TS = 0, @@ -61,7 +63,9 @@ public: bool IsEnabled(void) const { return enabled; } void FindAllPids(playback_audio_pid_info_t *audiopids, uint16_t size, uint16_t *numpida); void FindAllPids(uint16_t *apids, unsigned short *ac3flags, uint16_t *numpida, std::string *language); - + void FindAllSubs(uint16_t *pids, unsigned short *supported, uint16_t *numpida, std::string *language); + bool SelectSubtitles(int pid); + void GetChapters(std::vector &positions, std::vector &titles); }; #endif // __PLAYBACK_CS_H_ diff --git a/lib/libcoolstream2/ca_cs.h b/lib/libcoolstream2/ca_cs.h index d7afc535f..ab14441aa 100644 --- a/lib/libcoolstream2/ca_cs.h +++ b/lib/libcoolstream2/ca_cs.h @@ -23,7 +23,7 @@ enum CA_INIT_MASK { enum CA_SLOT_TYPE { CA_SLOT_TYPE_SMARTCARD, CA_SLOT_TYPE_CI, - CA_SLOT_TYPE_ALL, + CA_SLOT_TYPE_ALL }; enum CA_MESSAGE_FLAGS { @@ -49,7 +49,7 @@ enum CA_MESSAGE_FLAGS { CA_MESSAGE_HAS_PARAM1_LONG = (1 << 19), CA_MESSAGE_HAS_PARAM2_LONG = (1 << 20), CA_MESSAGE_HAS_PARAM3_LONG = (1 << 21), - CA_MESSAGE_HAS_PARAM4_LONG = (1 << 22), + CA_MESSAGE_HAS_PARAM4_LONG = (1 << 22) }; enum CA_MESSAGE_MSGID { @@ -72,7 +72,7 @@ enum CA_MESSAGE_MSGID { CA_MESSAGE_MSG_EMM_ARRIVED, CA_MESSAGE_MSG_CHANNEL_CHANGE, CA_MESSAGE_MSG_GUI_READY, - CA_MESSAGE_MSG_EXIT, + CA_MESSAGE_MSG_EXIT }; typedef struct CA_MESSAGE { @@ -117,13 +117,13 @@ private: /// Thread method virtual void run(void); public: - /// Returns the number of CI slots - u32 GetNumberCISlots(void); - /// Returns the number of Smartcard slots - u32 GetNumberSmartCardSlots(void); + /// Returns the number of CA slots (CI+SC, CI, SC) + u32 GetNumberSlots(enum CA_SLOT_TYPE SlotType = CA_SLOT_TYPE_ALL); + u32 GetNumberCISlots(void) { return GetNumberSlots(CA_SLOT_TYPE_CI); } + u32 GetNumberSmartCardSlots(void) { return GetNumberSlots(CA_SLOT_TYPE_SMARTCARD); } /// Singleton static cCA *GetInstance(void); - /// Send PMT to a individual or to all available modules + /// Send PMT to a individual or to all available modules (DEPRECATED) bool SendPMT(int Unit, unsigned char *Data, int Len, enum CA_SLOT_TYPE SlotType = CA_SLOT_TYPE_ALL); /// Sends a message to the CA thread bool SendMessage(const CA_MESSAGE *Msg); @@ -154,9 +154,9 @@ public: /// Notify the module we closed the menu void MenuClose(enum CA_SLOT_TYPE, u32 Slot); /// Get the supported CAIDs - int GetCAIDS(CaIdVector & Caids); + int GetCAIDS(CaIdVector & Caids, enum CA_SLOT_TYPE SlotType = CA_SLOT_TYPE_ALL); /// Send a CA-PMT object and Raw unparsed PMT to the CA layer - bool SendCAPMT(u64 Source, u8 DemuxSource, u8 DemuxMask, const unsigned char *CAPMT, u32 CAPMTLen, const unsigned char *RawPMT, u32 RawPMTLen); + bool SendCAPMT(u64 ChannelId, u8 DemuxSource, u8 DemuxMask, const unsigned char *CAPMT, u32 CAPMTLen, const unsigned char *RawPMT, u32 RawPMTLen, enum CA_SLOT_TYPE SlotType = CA_SLOT_TYPE_ALL); /// Virtual destructor virtual ~cCA(); }; diff --git a/lib/libcoolstream2/playback_cs.h b/lib/libcoolstream2/playback_cs.h index 80ecb4ccd..f65bdc6f0 100644 --- a/lib/libcoolstream2/playback_cs.h +++ b/lib/libcoolstream2/playback_cs.h @@ -12,6 +12,7 @@ #include #include +#include typedef enum { PLAYMODE_TS = 0, @@ -62,7 +63,9 @@ public: bool IsEnabled(void) const { return enabled; } void FindAllPids(playback_audio_pid_info_t *audiopids, uint16_t size, uint16_t *numpida); void FindAllPids(uint16_t *apids, unsigned short *ac3flags, uint16_t *numpida, std::string *language); - + void FindAllSubs(uint16_t *pids, unsigned short *supported, uint16_t *numpida, std::string *language); + bool SelectSubtitles(int pid); + void GetChapters(std::vector &positions, std::vector &titles); }; #endif // __PLAYBACK_CS_H_ diff --git a/lib/sectionsdclient/sectionsdMsg.h b/lib/sectionsdclient/sectionsdMsg.h index 4595a80ca..c9d7c88f0 100644 --- a/lib/sectionsdclient/sectionsdMsg.h +++ b/lib/sectionsdclient/sectionsdMsg.h @@ -81,6 +81,7 @@ struct sectionsd { t_channel_id channel_id; bool requestEvent; + int dnum; }; struct responseIsTimeSet diff --git a/lib/sectionsdclient/sectionsdclient.cpp b/lib/sectionsdclient/sectionsdclient.cpp index 795ad95a5..8cc6fc79e 100644 --- a/lib/sectionsdclient/sectionsdclient.cpp +++ b/lib/sectionsdclient/sectionsdclient.cpp @@ -155,13 +155,14 @@ bool CSectionsdClient::getIsScanningActive() } } -void CSectionsdClient::setServiceChanged(const t_channel_id channel_id, const bool requestEvent) +void CSectionsdClient::setServiceChanged(const t_channel_id channel_id, const bool requestEvent, int dnum) { sectionsd::commandSetServiceChanged msg; VALGRIND_PARANOIA(msg); msg.channel_id = channel_id; msg.requestEvent = requestEvent; + msg.dnum = dnum; send(sectionsd::serviceChanged, (char *)&msg, sizeof(msg)); diff --git a/lib/sectionsdclient/sectionsdclient.h b/lib/sectionsdclient/sectionsdclient.h index 5c1e52300..8ef0debc6 100644 --- a/lib/sectionsdclient/sectionsdclient.h +++ b/lib/sectionsdclient/sectionsdclient.h @@ -79,6 +79,7 @@ class CSectionsdClient : private CBasicClient { EVT_TIMESET, EVT_GOT_CN_EPG, + EVT_EIT_COMPLETE, #if 0 EVT_SERVICES_UPDATE, EVT_BOUQUETS_UPDATE, @@ -189,7 +190,7 @@ class CSectionsdClient : private CBasicClient bool getIsTimeSet(); void setPauseScanning(const bool doPause); - void setServiceChanged(const t_channel_id channel_id, const bool requestEvent); + void setServiceChanged(const t_channel_id channel_id, const bool requestEvent, int dnum = 0); bool getIsScanningActive(); diff --git a/src/driver/Makefile.am b/src/driver/Makefile.am index c6fb0138f..93d547edd 100644 --- a/src/driver/Makefile.am +++ b/src/driver/Makefile.am @@ -33,6 +33,7 @@ libneutrino_driver_a_SOURCES = \ rcinput.cpp \ record.cpp \ ringbuffer.c \ + scanepg.cpp \ screen_max.cpp \ screenshot.cpp \ shutdown_count.cpp \ diff --git a/src/driver/framebuffer.cpp b/src/driver/framebuffer.cpp index 2e52808d1..df56e51ea 100644 --- a/src/driver/framebuffer.cpp +++ b/src/driver/framebuffer.cpp @@ -161,9 +161,9 @@ void CFrameBuffer::waitForIdle(const char* func) if (count > 512) /* more than 100 are unlikely, */{ if (func != NULL) - fprintf(stderr, "CFrameBuffer::waitForIdle: count is big (%04d) [%s]!\n", count, func); + fprintf(stderr, "CFrameBuffer::waitForIdle: count is big (%04u) [%s]!\n", count, func); else - fprintf(stderr, "CFrameBuffer::waitForIdle: count is big (%d)!\n", count); + fprintf(stderr, "CFrameBuffer::waitForIdle: count is big (%u)!\n", count); } } #endif /* USE_NEVIS_GXA */ @@ -693,11 +693,11 @@ void CFrameBuffer::paintBoxRel(const int x, const int y, const int dx, const int _write_gxa(gxa_base, GXA_BG_COLOR_REG, (unsigned int) col); /* setup the drawing color */ #endif - int line = 0; if (type && radius) { setCornerFlags(type); radius = limitRadius(dx, dy, radius); + int line = 0; while (line < dy) { int ofl, ofr; if (calcCorners(NULL, &ofl, &ofr, dy, line, radius, type)) { @@ -758,6 +758,7 @@ void CFrameBuffer::paintBoxRel(const int x, const int y, const int dx, const int #else int swidth = stride / sizeof(fb_pixel_t); fb_pixel_t *fbp = getFrameBufferPointer() + (swidth * y); + int line = 0; while (line < dy) { for (int pos = x; pos < x + dx; pos++) *(fbp + pos) = col; @@ -946,11 +947,9 @@ bool CFrameBuffer::paintIcon(const std::string & filename, const int x, const in { struct rawHeader header; int width, height; - int lfd; fb_pixel_t * data; struct rawIcon tmpIcon; std::map::iterator it; - int dsize; if (!getActive()) return false; @@ -967,7 +966,7 @@ bool CFrameBuffer::paintIcon(const std::string & filename, const int x, const in data = g_PicViewer->getIcon(newname, &width, &height); if(data) { - dsize = width*height*sizeof(fb_pixel_t); + int dsize = width*height*sizeof(fb_pixel_t); //printf("CFrameBuffer::paintIcon: %s found, data %x size %d x %d\n", newname.c_str(), data, width, height);fflush(stdout); if(cache_size+dsize < ICON_CACHE_SIZE) { cache_size += dsize; @@ -982,7 +981,7 @@ bool CFrameBuffer::paintIcon(const std::string & filename, const int x, const in newname = iconBasePath + filename.c_str() + ".raw"; - lfd = open(newname.c_str(), O_RDONLY); + int lfd = open(newname.c_str(), O_RDONLY); if (lfd == -1) { //printf("paintIcon: error while loading icon: %s\n", newname.c_str()); @@ -993,7 +992,7 @@ bool CFrameBuffer::paintIcon(const std::string & filename, const int x, const in tmpIcon.width = width = (header.width_hi << 8) | header.width_lo; tmpIcon.height = height = (header.height_hi << 8) | header.height_lo; - dsize = width*height*sizeof(fb_pixel_t); + int dsize = width*height*sizeof(fb_pixel_t); tmpIcon.data = (fb_pixel_t*) cs_malloc_uncached(dsize); data = tmpIcon.data; @@ -1747,7 +1746,7 @@ void * CFrameBuffer::convertRGBA2FB(unsigned char *rgbbuff, unsigned long x, uns return int_convertRGB2FB(rgbbuff, x, y, 0, true); } -void CFrameBuffer::blit2FB(void *fbbuff, uint32_t width, uint32_t height, uint32_t xoff, uint32_t yoff, uint32_t xp, uint32_t yp, bool transp) +void CFrameBuffer::blit2FB(void *fbbuff, uint32_t width, uint32_t height, uint32_t xoff, uint32_t yoff, uint32_t xp, uint32_t yp, bool /*transp*/) { int xc, yc; @@ -1810,19 +1809,23 @@ void CFrameBuffer::blit2FB(void *fbbuff, uint32_t width, uint32_t height, uint32 d2 = (fb_pixel_t *) d; for (int count2 = 0; count2 < xc; count2++ ) { fb_pixel_t pix = *(pixpos + xp); - if (!transp || (pix != 0)) { + if ((pix & 0xff000000) == 0xff000000) *d2 = pix; + else { + uint8_t *in = (uint8_t *)(pixpos + xp); + uint8_t *out = (uint8_t *)d2; + int a = in[3]; /* TODO: big/little endian */ + *out = (*out + ((*in - *out) * a) / 256); + in++; out++; + *out = (*out + ((*in - *out) * a) / 256); + in++; out++; + *out = (*out + ((*in - *out) * a) / 256); } d2++; pixpos++; } d += stride; } -#if 0 - for(int i = 0; i < yc; i++){ - memmove(clfb + (i + yoff)*stride + xoff*4, ip + (i + yp)*width + xp, xc*4); - } -#endif } void CFrameBuffer::displayRGB(unsigned char *rgbbuff, int x_size, int y_size, int x_pan, int y_pan, int x_offs, int y_offs, bool clearfb, int transp) diff --git a/src/driver/framebuffer.h b/src/driver/framebuffer.h index b53ecda40..0dd097396 100644 --- a/src/driver/framebuffer.h +++ b/src/driver/framebuffer.h @@ -239,7 +239,7 @@ class CFrameBuffer void add_gxa_sync_marker(void); void waitForIdle(const char* func=NULL); #else - inline void waitForIdle(void) {}; + inline void waitForIdle(const char*) {}; #endif void* convertRGB2FB(unsigned char *rgbbuff, unsigned long x, unsigned long y, int transp = 0xFF); void* convertRGBA2FB(unsigned char *rgbbuff, unsigned long x, unsigned long y); diff --git a/src/driver/rcinput.cpp b/src/driver/rcinput.cpp index 710a772f1..1c95f0241 100644 --- a/src/driver/rcinput.cpp +++ b/src/driver/rcinput.cpp @@ -934,7 +934,7 @@ void CRCInput::getMsg_us(neutrino_msg_t * msg, neutrino_msg_data_t * data, uint6 break; } case CSectionsdClient::EVT_GOT_CN_EPG: -printf("[neutrino] CSectionsdClient::EVT_GOT_CN_EPG\n"); + printf("[neutrino] CSectionsdClient::EVT_GOT_CN_EPG\n"); *msg = NeutrinoMessages::EVT_CURRENTNEXT_EPG; *data = (neutrino_msg_data_t) p; dont_delete_p = true; @@ -943,6 +943,12 @@ printf("[neutrino] CSectionsdClient::EVT_GOT_CN_EPG\n"); *msg = NeutrinoMessages::EVT_SI_FINISHED; *data = 0; break; + case CSectionsdClient::EVT_EIT_COMPLETE: + printf("[neutrino] CSectionsdClient::EVT_EIT_COMPLETE\n"); + *msg = NeutrinoMessages::EVT_EIT_COMPLETE; + *data = (neutrino_msg_data_t) p; + dont_delete_p = true; + break; #if 0 case CSectionsdClient::EVT_SERVICES_UPDATE: *msg = NeutrinoMessages::EVT_SERVICES_UPD; @@ -1609,7 +1615,7 @@ int CRCInput::translate(int code, int /*num*/) if ((code >= 0) && (code <= KEY_MAX)) return code; else - return RC_nokey; + return ( unsigned int)RC_nokey; } void CRCInput::close_click() diff --git a/src/driver/record.cpp b/src/driver/record.cpp index 3584f0797..8a098ae94 100644 --- a/src/driver/record.cpp +++ b/src/driver/record.cpp @@ -677,8 +677,10 @@ void CRecordInstance::GetRecordString(std::string &str) int err = GetStatus(); strftime(stime, sizeof(stime), "%H:%M:%S ", localtime(&start_time)); time_t duration = time(0) - start_time; - char dtime[15]; - snprintf(dtime, sizeof(dtime), " (%02d:%02d)", (int) duration/3600, (int) duration/60); + char dtime[20]; + int h = duration/3600; + int m = duration/60; + snprintf(dtime, sizeof(dtime), " (%02d %s %02d min)", h, h == 1 ? "hour" : "hours", m); str = stime + channel->getName() + ": " + GetEpgTitle() + ((err & REC_STATUS_OVERFLOW) ? " [!]" : "") + dtime; } diff --git a/src/driver/scanepg.cpp b/src/driver/scanepg.cpp new file mode 100644 index 000000000..4b893648f --- /dev/null +++ b/src/driver/scanepg.cpp @@ -0,0 +1,136 @@ +/* + Copyright (C) 2013 CoolStream International Ltd + + License: GPLv2 + + 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; + + 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., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include +#include + +#include +#include +#include + +#include +#include +#include + +#include +#include + +#include + +extern CBouquetList * bouquetList; + +CEpgScan::CEpgScan() +{ + current_bnum = -1; +} + +CEpgScan::~CEpgScan() +{ +} + +CEpgScan * CEpgScan::getInstance() +{ + static CEpgScan * inst; + if (inst == NULL) + inst = new CEpgScan(); + return inst; +} + +void CEpgScan::Clear() +{ + scanmap.clear(); + current_bnum = -1; +} + +void CEpgScan::handleMsg(const neutrino_msg_t msg, neutrino_msg_data_t data) +{ + if (!g_settings.epg_scan || CFEManager::getInstance()->getEnabledCount() <= 1) + return; + + CZapitChannel * newchan; + if(msg == NeutrinoMessages::EVT_ZAP_COMPLETE) { + if(bouquetList->Bouquets.empty()) + return; + + if (current_bnum != bouquetList->getActiveBouquetNumber()) { + scanmap.clear(); + current_bnum = bouquetList->getActiveBouquetNumber(); + CChannelList * clist = bouquetList->Bouquets[current_bnum]->channelList; + int lsize = clist->Size(); + for (int i = 0; i < lsize; i++) { + CZapitChannel * chan = clist->getChannelFromIndex(i); + /* TODO: add interval check to clear scanned ? */ + if (scanned.find(chan->getTransponderId()) == scanned.end()) + scanmap.insert(eit_scanmap_pair_t(chan->getTransponderId(), chan->getChannelID())); + } + INFO("EVT_ZAP_COMPLETE, scan map size: %d\n", scanmap.size()); + } + } + else if (msg == NeutrinoMessages::EVT_EIT_COMPLETE) { + t_channel_id chid = *(t_channel_id *)data; + newchan = CServiceManager::getInstance()->FindChannel(chid); + if (newchan) { + scanned.insert(newchan->getTransponderId()); + scanmap.erase(newchan->getTransponderId()); + } + INFO("EIT read complete [" PRINTF_CHANNEL_ID_TYPE "], scan map size: %d", chid, scanmap.size()); + + if (scanmap.empty()) + return; + + t_channel_id live_channel_id = CZapit::getInstance()->GetCurrentChannelID(); + + CFrontend *live_fe = CZapit::getInstance()->GetLiveFrontend(); + CFEManager::getInstance()->lockFrontend(live_fe); +#ifdef ENABLE_PIP + CFrontend *pip_fe = CZapit::getInstance()->GetPipFrontend(); + if (pip_fe && pip_fe != live_fe) + CFEManager::getInstance()->lockFrontend(pip_fe); +#endif + for (eit_scanmap_iterator_t it = scanmap.begin(); it != scanmap.end(); /* ++it*/) { + newchan = CServiceManager::getInstance()->FindChannel(it->second); + if ((newchan == NULL) || SAME_TRANSPONDER(live_channel_id, newchan->getChannelID())) { + scanmap.erase(it++); + continue; + } + if (CFEManager::getInstance()->canTune(newchan)) { + INFO("try to scan [%s]", newchan->getName().c_str()); + bool ret = g_Zapit->zapTo_record(newchan->getChannelID()) > 0; + if (ret) { + g_Sectionsd->setServiceChanged(newchan->getChannelID(), false, newchan->getRecordDemux()); + break; + } else { + scanmap.erase(it++); + continue; + } + } else + INFO("skip [%s], cannot tune", newchan->getName().c_str()); + ++it; + } + CFEManager::getInstance()->unlockFrontend(live_fe); +#ifdef ENABLE_PIP + if (pip_fe && pip_fe != live_fe) + CFEManager::getInstance()->unlockFrontend(pip_fe); +#endif + } +} diff --git a/src/driver/scanepg.h b/src/driver/scanepg.h new file mode 100644 index 000000000..d3c74bc60 --- /dev/null +++ b/src/driver/scanepg.h @@ -0,0 +1,45 @@ +/* + Copyright (C) 2013 CoolStream International Ltd + + License: GPLv2 + + 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; + + 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., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#ifndef __SCAN_EPG__ +#define __SCAN_EPG__ + +#include + +typedef std::map eit_scanmap_t; +typedef std::pair eit_scanmap_pair_t; +typedef eit_scanmap_t::iterator eit_scanmap_iterator_t; + +class CEpgScan +{ + private: + int current_bnum; + eit_scanmap_t scanmap; + std::set scanned; + + CEpgScan(); + public: + ~CEpgScan(); + static CEpgScan * getInstance(); + + void handleMsg(const neutrino_msg_t _msg, neutrino_msg_data_t data); + void Clear(); +}; + +#endif diff --git a/src/driver/screenshot.h b/src/driver/screenshot.h index e28e1eab2..a4f348a8b 100644 --- a/src/driver/screenshot.h +++ b/src/driver/screenshot.h @@ -30,7 +30,7 @@ class CScreenShot : public OpenThreads::Thread typedef enum { FORMAT_PNG, FORMAT_JPG, - FORMAT_BMP, + FORMAT_BMP } screenshot_format_t; private: diff --git a/src/driver/volume.cpp b/src/driver/volume.cpp index c26b3b082..7acbb2484 100644 --- a/src/driver/volume.cpp +++ b/src/driver/volume.cpp @@ -80,7 +80,7 @@ void CVolume::setvol(int vol) CZapit::getInstance()->SetVolume(vol); } -void CVolume::setVolume(const neutrino_msg_t key, bool nowait) +void CVolume::setVolume(const neutrino_msg_t key) { if (!g_RCInput) /* don't die... */ return; @@ -187,10 +187,10 @@ void CVolume::setVolume(const neutrino_msg_t key, bool nowait) if (do_vol) setvol(g_settings.current_volume); - timeoutEnd = CRCInput::calcTimeoutEnd(nowait ? 1 : 3); + timeoutEnd = CRCInput::calcTimeoutEnd (g_settings.timing[SNeutrinoSettings::TIMING_VOLUMEBAR] == 0 ? 0xFFFF : g_settings.timing[SNeutrinoSettings::TIMING_VOLUMEBAR]); } else if (msg == NeutrinoMessages::EVT_VOLCHANGED) { - timeoutEnd = CRCInput::calcTimeoutEnd(3); + timeoutEnd = CRCInput::calcTimeoutEnd (g_settings.timing[SNeutrinoSettings::TIMING_VOLUMEBAR] == 0 ? 0xFFFF : g_settings.timing[SNeutrinoSettings::TIMING_VOLUMEBAR]); } else if (CNeutrinoApp::getInstance()->handleMsg(msg, data) & messages_return::unhandled) { g_RCInput->postMsg(msg, data); diff --git a/src/driver/volume.h b/src/driver/volume.h index 06fa956b6..4c901c779 100644 --- a/src/driver/volume.h +++ b/src/driver/volume.h @@ -47,7 +47,7 @@ class CVolume : public CChangeObserver static CVolume* getInstance(); void setvol(int vol); - void setVolume(const neutrino_msg_t key, bool nowait = false); + void setVolume(const neutrino_msg_t key); void SetCurrentPid(int pid) { apid = pid; } void SetCurrentChannel(t_channel_id id) { channel_id = id; } diff --git a/src/eitd/SIevents.cpp b/src/eitd/SIevents.cpp index eef45863e..ac473acb7 100644 --- a/src/eitd/SIevents.cpp +++ b/src/eitd/SIevents.cpp @@ -357,7 +357,22 @@ char SIevent::getFSK() const return (it->rating + 3); // 0x01 to 0x0F minimum age = rating + 3 years else return (it->rating == 0 ? 0 : 18); // return FSK 18 for : 0x10 to 0xFF defined by the broadcaster + }else if( it->countryCode == "FRA" && it->rating == 0x10)// workaround for ITA ESP FRA fsk. + { + return 0; + }else if(it->countryCode == "ITA" && it->rating == 1) + { + return 0; + }else if( it->countryCode == "ESP" ) + { + if(it->rating == 0x10 || it->rating == 0x11) + return 0; + else if(it->rating == 0x12) + return 18; + else + return (it->rating + 1); } + } if (!ratings.empty()) { diff --git a/src/eitd/dmx.cpp b/src/eitd/dmx.cpp index ee75a6e05..3850c3983 100644 --- a/src/eitd/dmx.cpp +++ b/src/eitd/dmx.cpp @@ -117,11 +117,13 @@ void DMX::close(void) void DMX::closefd(void) { #ifdef DEBUG_DEMUX - xprintf(" %s: DMX::closefd, isOpen %d\n", name.c_str(), isOpen()); + xcprintf(" %s: DMX::closefd, isOpen %d demux #%d", name.c_str(), isOpen(), dmx_num); #endif if (isOpen()) { - dmx->Stop(); + //dmx->Stop(); + delete dmx; + dmx = NULL; fd = -1; } } @@ -484,6 +486,9 @@ int DMX::immediate_start(void) } if(dmx == NULL) { +#ifdef DEBUG_DEMUX + xcprintf(" %s: open demux #%d", name.c_str(), dmx_num); +#endif dmx = new cDemux(dmx_num); dmx->Open(DMX_PSI_CHANNEL, NULL, dmxBufferSizeInKB*1024UL); } diff --git a/src/eitd/dmx.h b/src/eitd/dmx.h index a4eb19706..46d0b7167 100644 --- a/src/eitd/dmx.h +++ b/src/eitd/dmx.h @@ -126,6 +126,7 @@ public: unsigned char get_eit_version(void) { return eit_version; } // was useful for debugging... t_channel_id get_current_service(void) { return current_service; } + void setDemux(int dnum) { dmx_num = dnum; } }; #endif /* __sectionsd__dmx_h__ */ diff --git a/src/eitd/edvbstring.cpp b/src/eitd/edvbstring.cpp index 010c3eaa3..a896b8914 100644 --- a/src/eitd/edvbstring.cpp +++ b/src/eitd/edvbstring.cpp @@ -197,6 +197,1405 @@ static unsigned long iso6937[96]={ 0x0138, 0x00E6, 0x0111, 0x00F0, 0x0127, 0x0131, 0x0133, 0x0140, 0x0142, 0x00F8, 0x0153, 0x00DF, 0x00FE, 0x0167, 0x014B, 0x00AD }; +#ifdef BOXMODEL_APOLLO +const unsigned short cGB2312UNI[] = { + // Start at 0xA100.so index have to be reduced. Maybe this can be optimized by removing the starts but for + // now just 'make it work' :). + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x3000, 0x3001, 0x3002, 0x00B7, 0x02C9, 0x02C7, 0x00A8, 0x3003, 0x3005, 0x2014, 0xFF5E, 0x2016, 0x2026, 0x2018, 0x2019, + 0x201C, 0x201D, 0x3014, 0x3015, 0x3008, 0x3009, 0x300A, 0x300B, 0x300C, 0x300D, 0x300E, 0x300F, 0x3016, 0x3017, 0x3010, 0x3011, + 0x00B1, 0x00D7, 0x00F7, 0x2236, 0x2227, 0x2228, 0x2211, 0x220F, 0x222A, 0x2229, 0x2208, 0x2237, 0x221A, 0x22A5, 0x2225, 0x2220, + 0x2312, 0x2299, 0x222B, 0x222E, 0x2261, 0x224C, 0x2248, 0x223D, 0x221D, 0x2260, 0x226E, 0x226F, 0x2264, 0x2265, 0x221E, 0x2235, + 0x2234, 0x2642, 0x2640, 0x00B0, 0x2032, 0x2033, 0x2103, 0xFF04, 0x00A4, 0xFFE0, 0xFFE1, 0x2030, 0x00A7, 0x2116, 0x2606, 0x2605, + 0x25CB, 0x25CF, 0x25CE, 0x25C7, 0x25C6, 0x25A1, 0x25A0, 0x25B3, 0x25B2, 0x203B, 0x2192, 0x2190, 0x2191, 0x2193, 0x3013, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x2170, 0x2171, 0x2172, 0x2173, 0x2174, 0x2175, 0x2176, 0x2177, 0x2178, 0x2179, 0xE766, 0xE767, 0xE768, 0xE769, 0xE76A, + 0xE76B, 0x2488, 0x2489, 0x248A, 0x248B, 0x248C, 0x248D, 0x248E, 0x248F, 0x2490, 0x2491, 0x2492, 0x2493, 0x2494, 0x2495, 0x2496, + 0x2497, 0x2498, 0x2499, 0x249A, 0x249B, 0x2474, 0x2475, 0x2476, 0x2477, 0x2478, 0x2479, 0x247A, 0x247B, 0x247C, 0x247D, 0x247E, + 0x247F, 0x2480, 0x2481, 0x2482, 0x2483, 0x2484, 0x2485, 0x2486, 0x2487, 0x2460, 0x2461, 0x2462, 0x2463, 0x2464, 0x2465, 0x2466, + 0x2467, 0x2468, 0x2469, 0xE76C, 0xE76D, 0x3220, 0x3221, 0x3222, 0x3223, 0x3224, 0x3225, 0x3226, 0x3227, 0x3228, 0x3229, 0xE76E, + 0xE76F, 0x2160, 0x2161, 0x2162, 0x2163, 0x2164, 0x2165, 0x2166, 0x2167, 0x2168, 0x2169, 0x216A, 0x216B, 0xE770, 0xE771, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0xFF01, 0xFF02, 0xFF03, 0xFFE5, 0xFF05, 0xFF06, 0xFF07, 0xFF08, 0xFF09, 0xFF0A, 0xFF0B, 0xFF0C, 0xFF0D, 0xFF0E, 0xFF0F, + 0xFF10, 0xFF11, 0xFF12, 0xFF13, 0xFF14, 0xFF15, 0xFF16, 0xFF17, 0xFF18, 0xFF19, 0xFF1A, 0xFF1B, 0xFF1C, 0xFF1D, 0xFF1E, 0xFF1F, + 0xFF20, 0xFF21, 0xFF22, 0xFF23, 0xFF24, 0xFF25, 0xFF26, 0xFF27, 0xFF28, 0xFF29, 0xFF2A, 0xFF2B, 0xFF2C, 0xFF2D, 0xFF2E, 0xFF2F, + 0xFF30, 0xFF31, 0xFF32, 0xFF33, 0xFF34, 0xFF35, 0xFF36, 0xFF37, 0xFF38, 0xFF39, 0xFF3A, 0xFF3B, 0xFF3C, 0xFF3D, 0xFF3E, 0xFF3F, + 0xFF40, 0xFF41, 0xFF42, 0xFF43, 0xFF44, 0xFF45, 0xFF46, 0xFF47, 0xFF48, 0xFF49, 0xFF4A, 0xFF4B, 0xFF4C, 0xFF4D, 0xFF4E, 0xFF4F, + 0xFF50, 0xFF51, 0xFF52, 0xFF53, 0xFF54, 0xFF55, 0xFF56, 0xFF57, 0xFF58, 0xFF59, 0xFF5A, 0xFF5B, 0xFF5C, 0xFF5D, 0xFFE3, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x3041, 0x3042, 0x3043, 0x3044, 0x3045, 0x3046, 0x3047, 0x3048, 0x3049, 0x304A, 0x304B, 0x304C, 0x304D, 0x304E, 0x304F, + 0x3050, 0x3051, 0x3052, 0x3053, 0x3054, 0x3055, 0x3056, 0x3057, 0x3058, 0x3059, 0x305A, 0x305B, 0x305C, 0x305D, 0x305E, 0x305F, + 0x3060, 0x3061, 0x3062, 0x3063, 0x3064, 0x3065, 0x3066, 0x3067, 0x3068, 0x3069, 0x306A, 0x306B, 0x306C, 0x306D, 0x306E, 0x306F, + 0x3070, 0x3071, 0x3072, 0x3073, 0x3074, 0x3075, 0x3076, 0x3077, 0x3078, 0x3079, 0x307A, 0x307B, 0x307C, 0x307D, 0x307E, 0x307F, + 0x3080, 0x3081, 0x3082, 0x3083, 0x3084, 0x3085, 0x3086, 0x3087, 0x3088, 0x3089, 0x308A, 0x308B, 0x308C, 0x308D, 0x308E, 0x308F, + 0x3090, 0x3091, 0x3092, 0x3093, 0xE772, 0xE773, 0xE774, 0xE775, 0xE776, 0xE777, 0xE778, 0xE779, 0xE77A, 0xE77B, 0xE77C, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x30A1, 0x30A2, 0x30A3, 0x30A4, 0x30A5, 0x30A6, 0x30A7, 0x30A8, 0x30A9, 0x30AA, 0x30AB, 0x30AC, 0x30AD, 0x30AE, 0x30AF, + 0x30B0, 0x30B1, 0x30B2, 0x30B3, 0x30B4, 0x30B5, 0x30B6, 0x30B7, 0x30B8, 0x30B9, 0x30BA, 0x30BB, 0x30BC, 0x30BD, 0x30BE, 0x30BF, + 0x30C0, 0x30C1, 0x30C2, 0x30C3, 0x30C4, 0x30C5, 0x30C6, 0x30C7, 0x30C8, 0x30C9, 0x30CA, 0x30CB, 0x30CC, 0x30CD, 0x30CE, 0x30CF, + 0x30D0, 0x30D1, 0x30D2, 0x30D3, 0x30D4, 0x30D5, 0x30D6, 0x30D7, 0x30D8, 0x30D9, 0x30DA, 0x30DB, 0x30DC, 0x30DD, 0x30DE, 0x30DF, + 0x30E0, 0x30E1, 0x30E2, 0x30E3, 0x30E4, 0x30E5, 0x30E6, 0x30E7, 0x30E8, 0x30E9, 0x30EA, 0x30EB, 0x30EC, 0x30ED, 0x30EE, 0x30EF, + 0x30F0, 0x30F1, 0x30F2, 0x30F3, 0x30F4, 0x30F5, 0x30F6, 0xE77D, 0xE77E, 0xE77F, 0xE780, 0xE781, 0xE782, 0xE783, 0xE784, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0391, 0x0392, 0x0393, 0x0394, 0x0395, 0x0396, 0x0397, 0x0398, 0x0399, 0x039A, 0x039B, 0x039C, 0x039D, 0x039E, 0x039F, + 0x03A0, 0x03A1, 0x03A3, 0x03A4, 0x03A5, 0x03A6, 0x03A7, 0x03A8, 0x03A9, 0xE785, 0xE786, 0xE787, 0xE788, 0xE789, 0xE78A, 0xE78B, + 0xE78C, 0x03B1, 0x03B2, 0x03B3, 0x03B4, 0x03B5, 0x03B6, 0x03B7, 0x03B8, 0x03B9, 0x03BA, 0x03BB, 0x03BC, 0x03BD, 0x03BE, 0x03BF, + 0x03C0, 0x03C1, 0x03C3, 0x03C4, 0x03C5, 0x03C6, 0x03C7, 0x03C8, 0x03C9, 0xE78D, 0xE78E, 0xE78F, 0xE790, 0xE791, 0xE792, 0xE793, + 0xFE35, 0xFE36, 0xFE39, 0xFE3A, 0xFE3F, 0xFE40, 0xFE3D, 0xFE3E, 0xFE41, 0xFE42, 0xFE43, 0xFE44, 0xE794, 0xE795, 0xFE3B, 0xFE3C, + 0xFE37, 0xFE38, 0xFE31, 0xE796, 0xFE33, 0xFE34, 0xE797, 0xE798, 0xE799, 0xE79A, 0xE79B, 0xE79C, 0xE79D, 0xE79E, 0xE79F, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0410, 0x0411, 0x0412, 0x0413, 0x0414, 0x0415, 0x0401, 0x0416, 0x0417, 0x0418, 0x0419, 0x041A, 0x041B, 0x041C, 0x041D, + 0x041E, 0x041F, 0x0420, 0x0421, 0x0422, 0x0423, 0x0424, 0x0425, 0x0426, 0x0427, 0x0428, 0x0429, 0x042A, 0x042B, 0x042C, 0x042D, + 0x042E, 0x042F, 0xE7A0, 0xE7A1, 0xE7A2, 0xE7A3, 0xE7A4, 0xE7A5, 0xE7A6, 0xE7A7, 0xE7A8, 0xE7A9, 0xE7AA, 0xE7AB, 0xE7AC, 0xE7AD, + 0xE7AE, 0x0430, 0x0431, 0x0432, 0x0433, 0x0434, 0x0435, 0x0451, 0x0436, 0x0437, 0x0438, 0x0439, 0x043A, 0x043B, 0x043C, 0x043D, + 0x043E, 0x043F, 0x0440, 0x0441, 0x0442, 0x0443, 0x0444, 0x0445, 0x0446, 0x0447, 0x0448, 0x0449, 0x044A, 0x044B, 0x044C, 0x044D, + 0x044E, 0x044F, 0xE7AF, 0xE7B0, 0xE7B1, 0xE7B2, 0xE7B3, 0xE7B4, 0xE7B5, 0xE7B6, 0xE7B7, 0xE7B8, 0xE7B9, 0xE7BA, 0xE7BB, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0101, 0x00E1, 0x01CE, 0x00E0, 0x0113, 0x00E9, 0x011B, 0x00E8, 0x012B, 0x00ED, 0x01D0, 0x00EC, 0x014D, 0x00F3, 0x01D2, + 0x00F2, 0x016B, 0x00FA, 0x01D4, 0x00F9, 0x01D6, 0x01D8, 0x01DA, 0x01DC, 0x00FC, 0x00EA, 0x0251, 0xE7C7, 0x0144, 0x0148, 0xE7C8, + 0x0261, 0xE7C9, 0xE7CA, 0xE7CB, 0xE7CC, 0x3105, 0x3106, 0x3107, 0x3108, 0x3109, 0x310A, 0x310B, 0x310C, 0x310D, 0x310E, 0x310F, + 0x3110, 0x3111, 0x3112, 0x3113, 0x3114, 0x3115, 0x3116, 0x3117, 0x3118, 0x3119, 0x311A, 0x311B, 0x311C, 0x311D, 0x311E, 0x311F, + 0x3120, 0x3121, 0x3122, 0x3123, 0x3124, 0x3125, 0x3126, 0x3127, 0x3128, 0x3129, 0xE7CD, 0xE7CE, 0xE7CF, 0xE7D0, 0xE7D1, 0xE7D2, + 0xE7D3, 0xE7D4, 0xE7D5, 0xE7D6, 0xE7D7, 0xE7D8, 0xE7D9, 0xE7DA, 0xE7DB, 0xE7DC, 0xE7DD, 0xE7DE, 0xE7DF, 0xE7E0, 0xE7E1, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0xE7FE, 0xE7FF, 0xE800, 0x2500, 0x2501, 0x2502, 0x2503, 0x2504, 0x2505, 0x2506, 0x2507, 0x2508, 0x2509, 0x250A, 0x250B, + 0x250C, 0x250D, 0x250E, 0x250F, 0x2510, 0x2511, 0x2512, 0x2513, 0x2514, 0x2515, 0x2516, 0x2517, 0x2518, 0x2519, 0x251A, 0x251B, + 0x251C, 0x251D, 0x251E, 0x251F, 0x2520, 0x2521, 0x2522, 0x2523, 0x2524, 0x2525, 0x2526, 0x2527, 0x2528, 0x2529, 0x252A, 0x252B, + 0x252C, 0x252D, 0x252E, 0x252F, 0x2530, 0x2531, 0x2532, 0x2533, 0x2534, 0x2535, 0x2536, 0x2537, 0x2538, 0x2539, 0x253A, 0x253B, + 0x253C, 0x253D, 0x253E, 0x253F, 0x2540, 0x2541, 0x2542, 0x2543, 0x2544, 0x2545, 0x2546, 0x2547, 0x2548, 0x2549, 0x254A, 0x254B, + 0xE801, 0xE802, 0xE803, 0xE804, 0xE805, 0xE806, 0xE807, 0xE808, 0xE809, 0xE80A, 0xE80B, 0xE80C, 0xE80D, 0xE80E, 0xE80F, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0xE000, 0xE001, 0xE002, 0xE003, 0xE004, 0xE005, 0xE006, 0xE007, 0xE008, 0xE009, 0xE00A, 0xE00B, 0xE00C, 0xE00D, 0xE00E, + 0xE00F, 0xE010, 0xE011, 0xE012, 0xE013, 0xE014, 0xE015, 0xE016, 0xE017, 0xE018, 0xE019, 0xE01A, 0xE01B, 0xE01C, 0xE01D, 0xE01E, + 0xE01F, 0xE020, 0xE021, 0xE022, 0xE023, 0xE024, 0xE025, 0xE026, 0xE027, 0xE028, 0xE029, 0xE02A, 0xE02B, 0xE02C, 0xE02D, 0xE02E, + 0xE02F, 0xE030, 0xE031, 0xE032, 0xE033, 0xE034, 0xE035, 0xE036, 0xE037, 0xE038, 0xE039, 0xE03A, 0xE03B, 0xE03C, 0xE03D, 0xE03E, + 0xE03F, 0xE040, 0xE041, 0xE042, 0xE043, 0xE044, 0xE045, 0xE046, 0xE047, 0xE048, 0xE049, 0xE04A, 0xE04B, 0xE04C, 0xE04D, 0xE04E, + 0xE04F, 0xE050, 0xE051, 0xE052, 0xE053, 0xE054, 0xE055, 0xE056, 0xE057, 0xE058, 0xE059, 0xE05A, 0xE05B, 0xE05C, 0xE05D, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0xE05E, 0xE05F, 0xE060, 0xE061, 0xE062, 0xE063, 0xE064, 0xE065, 0xE066, 0xE067, 0xE068, 0xE069, 0xE06A, 0xE06B, 0xE06C, + 0xE06D, 0xE06E, 0xE06F, 0xE070, 0xE071, 0xE072, 0xE073, 0xE074, 0xE075, 0xE076, 0xE077, 0xE078, 0xE079, 0xE07A, 0xE07B, 0xE07C, + 0xE07D, 0xE07E, 0xE07F, 0xE080, 0xE081, 0xE082, 0xE083, 0xE084, 0xE085, 0xE086, 0xE087, 0xE088, 0xE089, 0xE08A, 0xE08B, 0xE08C, + 0xE08D, 0xE08E, 0xE08F, 0xE090, 0xE091, 0xE092, 0xE093, 0xE094, 0xE095, 0xE096, 0xE097, 0xE098, 0xE099, 0xE09A, 0xE09B, 0xE09C, + 0xE09D, 0xE09E, 0xE09F, 0xE0A0, 0xE0A1, 0xE0A2, 0xE0A3, 0xE0A4, 0xE0A5, 0xE0A6, 0xE0A7, 0xE0A8, 0xE0A9, 0xE0AA, 0xE0AB, 0xE0AC, + 0xE0AD, 0xE0AE, 0xE0AF, 0xE0B0, 0xE0B1, 0xE0B2, 0xE0B3, 0xE0B4, 0xE0B5, 0xE0B6, 0xE0B7, 0xE0B8, 0xE0B9, 0xE0BA, 0xE0BB, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0xE0BC, 0xE0BD, 0xE0BE, 0xE0BF, 0xE0C0, 0xE0C1, 0xE0C2, 0xE0C3, 0xE0C4, 0xE0C5, 0xE0C6, 0xE0C7, 0xE0C8, 0xE0C9, 0xE0CA, + 0xE0CB, 0xE0CC, 0xE0CD, 0xE0CE, 0xE0CF, 0xE0D0, 0xE0D1, 0xE0D2, 0xE0D3, 0xE0D4, 0xE0D5, 0xE0D6, 0xE0D7, 0xE0D8, 0xE0D9, 0xE0DA, + 0xE0DB, 0xE0DC, 0xE0DD, 0xE0DE, 0xE0DF, 0xE0E0, 0xE0E1, 0xE0E2, 0xE0E3, 0xE0E4, 0xE0E5, 0xE0E6, 0xE0E7, 0xE0E8, 0xE0E9, 0xE0EA, + 0xE0EB, 0xE0EC, 0xE0ED, 0xE0EE, 0xE0EF, 0xE0F0, 0xE0F1, 0xE0F2, 0xE0F3, 0xE0F4, 0xE0F5, 0xE0F6, 0xE0F7, 0xE0F8, 0xE0F9, 0xE0FA, + 0xE0FB, 0xE0FC, 0xE0FD, 0xE0FE, 0xE0FF, 0xE100, 0xE101, 0xE102, 0xE103, 0xE104, 0xE105, 0xE106, 0xE107, 0xE108, 0xE109, 0xE10A, + 0xE10B, 0xE10C, 0xE10D, 0xE10E, 0xE10F, 0xE110, 0xE111, 0xE112, 0xE113, 0xE114, 0xE115, 0xE116, 0xE117, 0xE118, 0xE119, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0xE11A, 0xE11B, 0xE11C, 0xE11D, 0xE11E, 0xE11F, 0xE120, 0xE121, 0xE122, 0xE123, 0xE124, 0xE125, 0xE126, 0xE127, 0xE128, + 0xE129, 0xE12A, 0xE12B, 0xE12C, 0xE12D, 0xE12E, 0xE12F, 0xE130, 0xE131, 0xE132, 0xE133, 0xE134, 0xE135, 0xE136, 0xE137, 0xE138, + 0xE139, 0xE13A, 0xE13B, 0xE13C, 0xE13D, 0xE13E, 0xE13F, 0xE140, 0xE141, 0xE142, 0xE143, 0xE144, 0xE145, 0xE146, 0xE147, 0xE148, + 0xE149, 0xE14A, 0xE14B, 0xE14C, 0xE14D, 0xE14E, 0xE14F, 0xE150, 0xE151, 0xE152, 0xE153, 0xE154, 0xE155, 0xE156, 0xE157, 0xE158, + 0xE159, 0xE15A, 0xE15B, 0xE15C, 0xE15D, 0xE15E, 0xE15F, 0xE160, 0xE161, 0xE162, 0xE163, 0xE164, 0xE165, 0xE166, 0xE167, 0xE168, + 0xE169, 0xE16A, 0xE16B, 0xE16C, 0xE16D, 0xE16E, 0xE16F, 0xE170, 0xE171, 0xE172, 0xE173, 0xE174, 0xE175, 0xE176, 0xE177, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0xE178, 0xE179, 0xE17A, 0xE17B, 0xE17C, 0xE17D, 0xE17E, 0xE17F, 0xE180, 0xE181, 0xE182, 0xE183, 0xE184, 0xE185, 0xE186, + 0xE187, 0xE188, 0xE189, 0xE18A, 0xE18B, 0xE18C, 0xE18D, 0xE18E, 0xE18F, 0xE190, 0xE191, 0xE192, 0xE193, 0xE194, 0xE195, 0xE196, + 0xE197, 0xE198, 0xE199, 0xE19A, 0xE19B, 0xE19C, 0xE19D, 0xE19E, 0xE19F, 0xE1A0, 0xE1A1, 0xE1A2, 0xE1A3, 0xE1A4, 0xE1A5, 0xE1A6, + 0xE1A7, 0xE1A8, 0xE1A9, 0xE1AA, 0xE1AB, 0xE1AC, 0xE1AD, 0xE1AE, 0xE1AF, 0xE1B0, 0xE1B1, 0xE1B2, 0xE1B3, 0xE1B4, 0xE1B5, 0xE1B6, + 0xE1B7, 0xE1B8, 0xE1B9, 0xE1BA, 0xE1BB, 0xE1BC, 0xE1BD, 0xE1BE, 0xE1BF, 0xE1C0, 0xE1C1, 0xE1C2, 0xE1C3, 0xE1C4, 0xE1C5, 0xE1C6, + 0xE1C7, 0xE1C8, 0xE1C9, 0xE1CA, 0xE1CB, 0xE1CC, 0xE1CD, 0xE1CE, 0xE1CF, 0xE1D0, 0xE1D1, 0xE1D2, 0xE1D3, 0xE1D4, 0xE1D5, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0xE1D6, 0xE1D7, 0xE1D8, 0xE1D9, 0xE1DA, 0xE1DB, 0xE1DC, 0xE1DD, 0xE1DE, 0xE1DF, 0xE1E0, 0xE1E1, 0xE1E2, 0xE1E3, 0xE1E4, + 0xE1E5, 0xE1E6, 0xE1E7, 0xE1E8, 0xE1E9, 0xE1EA, 0xE1EB, 0xE1EC, 0xE1ED, 0xE1EE, 0xE1EF, 0xE1F0, 0xE1F1, 0xE1F2, 0xE1F3, 0xE1F4, + 0xE1F5, 0xE1F6, 0xE1F7, 0xE1F8, 0xE1F9, 0xE1FA, 0xE1FB, 0xE1FC, 0xE1FD, 0xE1FE, 0xE1FF, 0xE200, 0xE201, 0xE202, 0xE203, 0xE204, + 0xE205, 0xE206, 0xE207, 0xE208, 0xE209, 0xE20A, 0xE20B, 0xE20C, 0xE20D, 0xE20E, 0xE20F, 0xE210, 0xE211, 0xE212, 0xE213, 0xE214, + 0xE215, 0xE216, 0xE217, 0xE218, 0xE219, 0xE21A, 0xE21B, 0xE21C, 0xE21D, 0xE21E, 0xE21F, 0xE220, 0xE221, 0xE222, 0xE223, 0xE224, + 0xE225, 0xE226, 0xE227, 0xE228, 0xE229, 0xE22A, 0xE22B, 0xE22C, 0xE22D, 0xE22E, 0xE22F, 0xE230, 0xE231, 0xE232, 0xE233, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x554A, 0x963F, 0x57C3, 0x6328, 0x54CE, 0x5509, 0x54C0, 0x7691, 0x764C, 0x853C, 0x77EE, 0x827E, 0x788D, 0x7231, 0x9698, + 0x978D, 0x6C28, 0x5B89, 0x4FFA, 0x6309, 0x6697, 0x5CB8, 0x80FA, 0x6848, 0x80AE, 0x6602, 0x76CE, 0x51F9, 0x6556, 0x71AC, 0x7FF1, + 0x8884, 0x50B2, 0x5965, 0x61CA, 0x6FB3, 0x82AD, 0x634C, 0x6252, 0x53ED, 0x5427, 0x7B06, 0x516B, 0x75A4, 0x5DF4, 0x62D4, 0x8DCB, + 0x9776, 0x628A, 0x8019, 0x575D, 0x9738, 0x7F62, 0x7238, 0x767D, 0x67CF, 0x767E, 0x6446, 0x4F70, 0x8D25, 0x62DC, 0x7A17, 0x6591, + 0x73ED, 0x642C, 0x6273, 0x822C, 0x9881, 0x677F, 0x7248, 0x626E, 0x62CC, 0x4F34, 0x74E3, 0x534A, 0x529E, 0x7ECA, 0x90A6, 0x5E2E, + 0x6886, 0x699C, 0x8180, 0x7ED1, 0x68D2, 0x78C5, 0x868C, 0x9551, 0x508D, 0x8C24, 0x82DE, 0x80DE, 0x5305, 0x8912, 0x5265, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x8584, 0x96F9, 0x4FDD, 0x5821, 0x9971, 0x5B9D, 0x62B1, 0x62A5, 0x66B4, 0x8C79, 0x9C8D, 0x7206, 0x676F, 0x7891, 0x60B2, + 0x5351, 0x5317, 0x8F88, 0x80CC, 0x8D1D, 0x94A1, 0x500D, 0x72C8, 0x5907, 0x60EB, 0x7119, 0x88AB, 0x5954, 0x82EF, 0x672C, 0x7B28, + 0x5D29, 0x7EF7, 0x752D, 0x6CF5, 0x8E66, 0x8FF8, 0x903C, 0x9F3B, 0x6BD4, 0x9119, 0x7B14, 0x5F7C, 0x78A7, 0x84D6, 0x853D, 0x6BD5, + 0x6BD9, 0x6BD6, 0x5E01, 0x5E87, 0x75F9, 0x95ED, 0x655D, 0x5F0A, 0x5FC5, 0x8F9F, 0x58C1, 0x81C2, 0x907F, 0x965B, 0x97AD, 0x8FB9, + 0x7F16, 0x8D2C, 0x6241, 0x4FBF, 0x53D8, 0x535E, 0x8FA8, 0x8FA9, 0x8FAB, 0x904D, 0x6807, 0x5F6A, 0x8198, 0x8868, 0x9CD6, 0x618B, + 0x522B, 0x762A, 0x5F6C, 0x658C, 0x6FD2, 0x6EE8, 0x5BBE, 0x6448, 0x5175, 0x51B0, 0x67C4, 0x4E19, 0x79C9, 0x997C, 0x70B3, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x75C5, 0x5E76, 0x73BB, 0x83E0, 0x64AD, 0x62E8, 0x94B5, 0x6CE2, 0x535A, 0x52C3, 0x640F, 0x94C2, 0x7B94, 0x4F2F, 0x5E1B, + 0x8236, 0x8116, 0x818A, 0x6E24, 0x6CCA, 0x9A73, 0x6355, 0x535C, 0x54FA, 0x8865, 0x57E0, 0x4E0D, 0x5E03, 0x6B65, 0x7C3F, 0x90E8, + 0x6016, 0x64E6, 0x731C, 0x88C1, 0x6750, 0x624D, 0x8D22, 0x776C, 0x8E29, 0x91C7, 0x5F69, 0x83DC, 0x8521, 0x9910, 0x53C2, 0x8695, + 0x6B8B, 0x60ED, 0x60E8, 0x707F, 0x82CD, 0x8231, 0x4ED3, 0x6CA7, 0x85CF, 0x64CD, 0x7CD9, 0x69FD, 0x66F9, 0x8349, 0x5395, 0x7B56, + 0x4FA7, 0x518C, 0x6D4B, 0x5C42, 0x8E6D, 0x63D2, 0x53C9, 0x832C, 0x8336, 0x67E5, 0x78B4, 0x643D, 0x5BDF, 0x5C94, 0x5DEE, 0x8BE7, + 0x62C6, 0x67F4, 0x8C7A, 0x6400, 0x63BA, 0x8749, 0x998B, 0x8C17, 0x7F20, 0x94F2, 0x4EA7, 0x9610, 0x98A4, 0x660C, 0x7316, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x573A, 0x5C1D, 0x5E38, 0x957F, 0x507F, 0x80A0, 0x5382, 0x655E, 0x7545, 0x5531, 0x5021, 0x8D85, 0x6284, 0x949E, 0x671D, + 0x5632, 0x6F6E, 0x5DE2, 0x5435, 0x7092, 0x8F66, 0x626F, 0x64A4, 0x63A3, 0x5F7B, 0x6F88, 0x90F4, 0x81E3, 0x8FB0, 0x5C18, 0x6668, + 0x5FF1, 0x6C89, 0x9648, 0x8D81, 0x886C, 0x6491, 0x79F0, 0x57CE, 0x6A59, 0x6210, 0x5448, 0x4E58, 0x7A0B, 0x60E9, 0x6F84, 0x8BDA, + 0x627F, 0x901E, 0x9A8B, 0x79E4, 0x5403, 0x75F4, 0x6301, 0x5319, 0x6C60, 0x8FDF, 0x5F1B, 0x9A70, 0x803B, 0x9F7F, 0x4F88, 0x5C3A, + 0x8D64, 0x7FC5, 0x65A5, 0x70BD, 0x5145, 0x51B2, 0x866B, 0x5D07, 0x5BA0, 0x62BD, 0x916C, 0x7574, 0x8E0C, 0x7A20, 0x6101, 0x7B79, + 0x4EC7, 0x7EF8, 0x7785, 0x4E11, 0x81ED, 0x521D, 0x51FA, 0x6A71, 0x53A8, 0x8E87, 0x9504, 0x96CF, 0x6EC1, 0x9664, 0x695A, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x7840, 0x50A8, 0x77D7, 0x6410, 0x89E6, 0x5904, 0x63E3, 0x5DDD, 0x7A7F, 0x693D, 0x4F20, 0x8239, 0x5598, 0x4E32, 0x75AE, + 0x7A97, 0x5E62, 0x5E8A, 0x95EF, 0x521B, 0x5439, 0x708A, 0x6376, 0x9524, 0x5782, 0x6625, 0x693F, 0x9187, 0x5507, 0x6DF3, 0x7EAF, + 0x8822, 0x6233, 0x7EF0, 0x75B5, 0x8328, 0x78C1, 0x96CC, 0x8F9E, 0x6148, 0x74F7, 0x8BCD, 0x6B64, 0x523A, 0x8D50, 0x6B21, 0x806A, + 0x8471, 0x56F1, 0x5306, 0x4ECE, 0x4E1B, 0x51D1, 0x7C97, 0x918B, 0x7C07, 0x4FC3, 0x8E7F, 0x7BE1, 0x7A9C, 0x6467, 0x5D14, 0x50AC, + 0x8106, 0x7601, 0x7CB9, 0x6DEC, 0x7FE0, 0x6751, 0x5B58, 0x5BF8, 0x78CB, 0x64AE, 0x6413, 0x63AA, 0x632B, 0x9519, 0x642D, 0x8FBE, + 0x7B54, 0x7629, 0x6253, 0x5927, 0x5446, 0x6B79, 0x50A3, 0x6234, 0x5E26, 0x6B86, 0x4EE3, 0x8D37, 0x888B, 0x5F85, 0x902E, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x6020, 0x803D, 0x62C5, 0x4E39, 0x5355, 0x90F8, 0x63B8, 0x80C6, 0x65E6, 0x6C2E, 0x4F46, 0x60EE, 0x6DE1, 0x8BDE, 0x5F39, + 0x86CB, 0x5F53, 0x6321, 0x515A, 0x8361, 0x6863, 0x5200, 0x6363, 0x8E48, 0x5012, 0x5C9B, 0x7977, 0x5BFC, 0x5230, 0x7A3B, 0x60BC, + 0x9053, 0x76D7, 0x5FB7, 0x5F97, 0x7684, 0x8E6C, 0x706F, 0x767B, 0x7B49, 0x77AA, 0x51F3, 0x9093, 0x5824, 0x4F4E, 0x6EF4, 0x8FEA, + 0x654C, 0x7B1B, 0x72C4, 0x6DA4, 0x7FDF, 0x5AE1, 0x62B5, 0x5E95, 0x5730, 0x8482, 0x7B2C, 0x5E1D, 0x5F1F, 0x9012, 0x7F14, 0x98A0, + 0x6382, 0x6EC7, 0x7898, 0x70B9, 0x5178, 0x975B, 0x57AB, 0x7535, 0x4F43, 0x7538, 0x5E97, 0x60E6, 0x5960, 0x6DC0, 0x6BBF, 0x7889, + 0x53FC, 0x96D5, 0x51CB, 0x5201, 0x6389, 0x540A, 0x9493, 0x8C03, 0x8DCC, 0x7239, 0x789F, 0x8776, 0x8FED, 0x8C0D, 0x53E0, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x4E01, 0x76EF, 0x53EE, 0x9489, 0x9876, 0x9F0E, 0x952D, 0x5B9A, 0x8BA2, 0x4E22, 0x4E1C, 0x51AC, 0x8463, 0x61C2, 0x52A8, + 0x680B, 0x4F97, 0x606B, 0x51BB, 0x6D1E, 0x515C, 0x6296, 0x6597, 0x9661, 0x8C46, 0x9017, 0x75D8, 0x90FD, 0x7763, 0x6BD2, 0x728A, + 0x72EC, 0x8BFB, 0x5835, 0x7779, 0x8D4C, 0x675C, 0x9540, 0x809A, 0x5EA6, 0x6E21, 0x5992, 0x7AEF, 0x77ED, 0x953B, 0x6BB5, 0x65AD, + 0x7F0E, 0x5806, 0x5151, 0x961F, 0x5BF9, 0x58A9, 0x5428, 0x8E72, 0x6566, 0x987F, 0x56E4, 0x949D, 0x76FE, 0x9041, 0x6387, 0x54C6, + 0x591A, 0x593A, 0x579B, 0x8EB2, 0x6735, 0x8DFA, 0x8235, 0x5241, 0x60F0, 0x5815, 0x86FE, 0x5CE8, 0x9E45, 0x4FC4, 0x989D, 0x8BB9, + 0x5A25, 0x6076, 0x5384, 0x627C, 0x904F, 0x9102, 0x997F, 0x6069, 0x800C, 0x513F, 0x8033, 0x5C14, 0x9975, 0x6D31, 0x4E8C, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x8D30, 0x53D1, 0x7F5A, 0x7B4F, 0x4F10, 0x4E4F, 0x9600, 0x6CD5, 0x73D0, 0x85E9, 0x5E06, 0x756A, 0x7FFB, 0x6A0A, 0x77FE, + 0x9492, 0x7E41, 0x51E1, 0x70E6, 0x53CD, 0x8FD4, 0x8303, 0x8D29, 0x72AF, 0x996D, 0x6CDB, 0x574A, 0x82B3, 0x65B9, 0x80AA, 0x623F, + 0x9632, 0x59A8, 0x4EFF, 0x8BBF, 0x7EBA, 0x653E, 0x83F2, 0x975E, 0x5561, 0x98DE, 0x80A5, 0x532A, 0x8BFD, 0x5420, 0x80BA, 0x5E9F, + 0x6CB8, 0x8D39, 0x82AC, 0x915A, 0x5429, 0x6C1B, 0x5206, 0x7EB7, 0x575F, 0x711A, 0x6C7E, 0x7C89, 0x594B, 0x4EFD, 0x5FFF, 0x6124, + 0x7CAA, 0x4E30, 0x5C01, 0x67AB, 0x8702, 0x5CF0, 0x950B, 0x98CE, 0x75AF, 0x70FD, 0x9022, 0x51AF, 0x7F1D, 0x8BBD, 0x5949, 0x51E4, + 0x4F5B, 0x5426, 0x592B, 0x6577, 0x80A4, 0x5B75, 0x6276, 0x62C2, 0x8F90, 0x5E45, 0x6C1F, 0x7B26, 0x4F0F, 0x4FD8, 0x670D, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x6D6E, 0x6DAA, 0x798F, 0x88B1, 0x5F17, 0x752B, 0x629A, 0x8F85, 0x4FEF, 0x91DC, 0x65A7, 0x812F, 0x8151, 0x5E9C, 0x8150, + 0x8D74, 0x526F, 0x8986, 0x8D4B, 0x590D, 0x5085, 0x4ED8, 0x961C, 0x7236, 0x8179, 0x8D1F, 0x5BCC, 0x8BA3, 0x9644, 0x5987, 0x7F1A, + 0x5490, 0x5676, 0x560E, 0x8BE5, 0x6539, 0x6982, 0x9499, 0x76D6, 0x6E89, 0x5E72, 0x7518, 0x6746, 0x67D1, 0x7AFF, 0x809D, 0x8D76, + 0x611F, 0x79C6, 0x6562, 0x8D63, 0x5188, 0x521A, 0x94A2, 0x7F38, 0x809B, 0x7EB2, 0x5C97, 0x6E2F, 0x6760, 0x7BD9, 0x768B, 0x9AD8, + 0x818F, 0x7F94, 0x7CD5, 0x641E, 0x9550, 0x7A3F, 0x544A, 0x54E5, 0x6B4C, 0x6401, 0x6208, 0x9E3D, 0x80F3, 0x7599, 0x5272, 0x9769, + 0x845B, 0x683C, 0x86E4, 0x9601, 0x9694, 0x94EC, 0x4E2A, 0x5404, 0x7ED9, 0x6839, 0x8DDF, 0x8015, 0x66F4, 0x5E9A, 0x7FB9, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x57C2, 0x803F, 0x6897, 0x5DE5, 0x653B, 0x529F, 0x606D, 0x9F9A, 0x4F9B, 0x8EAC, 0x516C, 0x5BAB, 0x5F13, 0x5DE9, 0x6C5E, + 0x62F1, 0x8D21, 0x5171, 0x94A9, 0x52FE, 0x6C9F, 0x82DF, 0x72D7, 0x57A2, 0x6784, 0x8D2D, 0x591F, 0x8F9C, 0x83C7, 0x5495, 0x7B8D, + 0x4F30, 0x6CBD, 0x5B64, 0x59D1, 0x9F13, 0x53E4, 0x86CA, 0x9AA8, 0x8C37, 0x80A1, 0x6545, 0x987E, 0x56FA, 0x96C7, 0x522E, 0x74DC, + 0x5250, 0x5BE1, 0x6302, 0x8902, 0x4E56, 0x62D0, 0x602A, 0x68FA, 0x5173, 0x5B98, 0x51A0, 0x89C2, 0x7BA1, 0x9986, 0x7F50, 0x60EF, + 0x704C, 0x8D2F, 0x5149, 0x5E7F, 0x901B, 0x7470, 0x89C4, 0x572D, 0x7845, 0x5F52, 0x9F9F, 0x95FA, 0x8F68, 0x9B3C, 0x8BE1, 0x7678, + 0x6842, 0x67DC, 0x8DEA, 0x8D35, 0x523D, 0x8F8A, 0x6EDA, 0x68CD, 0x9505, 0x90ED, 0x56FD, 0x679C, 0x88F9, 0x8FC7, 0x54C8, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x9AB8, 0x5B69, 0x6D77, 0x6C26, 0x4EA5, 0x5BB3, 0x9A87, 0x9163, 0x61A8, 0x90AF, 0x97E9, 0x542B, 0x6DB5, 0x5BD2, 0x51FD, + 0x558A, 0x7F55, 0x7FF0, 0x64BC, 0x634D, 0x65F1, 0x61BE, 0x608D, 0x710A, 0x6C57, 0x6C49, 0x592F, 0x676D, 0x822A, 0x58D5, 0x568E, + 0x8C6A, 0x6BEB, 0x90DD, 0x597D, 0x8017, 0x53F7, 0x6D69, 0x5475, 0x559D, 0x8377, 0x83CF, 0x6838, 0x79BE, 0x548C, 0x4F55, 0x5408, + 0x76D2, 0x8C89, 0x9602, 0x6CB3, 0x6DB8, 0x8D6B, 0x8910, 0x9E64, 0x8D3A, 0x563F, 0x9ED1, 0x75D5, 0x5F88, 0x72E0, 0x6068, 0x54FC, + 0x4EA8, 0x6A2A, 0x8861, 0x6052, 0x8F70, 0x54C4, 0x70D8, 0x8679, 0x9E3F, 0x6D2A, 0x5B8F, 0x5F18, 0x7EA2, 0x5589, 0x4FAF, 0x7334, + 0x543C, 0x539A, 0x5019, 0x540E, 0x547C, 0x4E4E, 0x5FFD, 0x745A, 0x58F6, 0x846B, 0x80E1, 0x8774, 0x72D0, 0x7CCA, 0x6E56, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x5F27, 0x864E, 0x552C, 0x62A4, 0x4E92, 0x6CAA, 0x6237, 0x82B1, 0x54D7, 0x534E, 0x733E, 0x6ED1, 0x753B, 0x5212, 0x5316, + 0x8BDD, 0x69D0, 0x5F8A, 0x6000, 0x6DEE, 0x574F, 0x6B22, 0x73AF, 0x6853, 0x8FD8, 0x7F13, 0x6362, 0x60A3, 0x5524, 0x75EA, 0x8C62, + 0x7115, 0x6DA3, 0x5BA6, 0x5E7B, 0x8352, 0x614C, 0x9EC4, 0x78FA, 0x8757, 0x7C27, 0x7687, 0x51F0, 0x60F6, 0x714C, 0x6643, 0x5E4C, + 0x604D, 0x8C0E, 0x7070, 0x6325, 0x8F89, 0x5FBD, 0x6062, 0x86D4, 0x56DE, 0x6BC1, 0x6094, 0x6167, 0x5349, 0x60E0, 0x6666, 0x8D3F, + 0x79FD, 0x4F1A, 0x70E9, 0x6C47, 0x8BB3, 0x8BF2, 0x7ED8, 0x8364, 0x660F, 0x5A5A, 0x9B42, 0x6D51, 0x6DF7, 0x8C41, 0x6D3B, 0x4F19, + 0x706B, 0x83B7, 0x6216, 0x60D1, 0x970D, 0x8D27, 0x7978, 0x51FB, 0x573E, 0x57FA, 0x673A, 0x7578, 0x7A3D, 0x79EF, 0x7B95, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x808C, 0x9965, 0x8FF9, 0x6FC0, 0x8BA5, 0x9E21, 0x59EC, 0x7EE9, 0x7F09, 0x5409, 0x6781, 0x68D8, 0x8F91, 0x7C4D, 0x96C6, + 0x53CA, 0x6025, 0x75BE, 0x6C72, 0x5373, 0x5AC9, 0x7EA7, 0x6324, 0x51E0, 0x810A, 0x5DF1, 0x84DF, 0x6280, 0x5180, 0x5B63, 0x4F0E, + 0x796D, 0x5242, 0x60B8, 0x6D4E, 0x5BC4, 0x5BC2, 0x8BA1, 0x8BB0, 0x65E2, 0x5FCC, 0x9645, 0x5993, 0x7EE7, 0x7EAA, 0x5609, 0x67B7, + 0x5939, 0x4F73, 0x5BB6, 0x52A0, 0x835A, 0x988A, 0x8D3E, 0x7532, 0x94BE, 0x5047, 0x7A3C, 0x4EF7, 0x67B6, 0x9A7E, 0x5AC1, 0x6B7C, + 0x76D1, 0x575A, 0x5C16, 0x7B3A, 0x95F4, 0x714E, 0x517C, 0x80A9, 0x8270, 0x5978, 0x7F04, 0x8327, 0x68C0, 0x67EC, 0x78B1, 0x7877, + 0x62E3, 0x6361, 0x7B80, 0x4FED, 0x526A, 0x51CF, 0x8350, 0x69DB, 0x9274, 0x8DF5, 0x8D31, 0x89C1, 0x952E, 0x7BAD, 0x4EF6, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x5065, 0x8230, 0x5251, 0x996F, 0x6E10, 0x6E85, 0x6DA7, 0x5EFA, 0x50F5, 0x59DC, 0x5C06, 0x6D46, 0x6C5F, 0x7586, 0x848B, + 0x6868, 0x5956, 0x8BB2, 0x5320, 0x9171, 0x964D, 0x8549, 0x6912, 0x7901, 0x7126, 0x80F6, 0x4EA4, 0x90CA, 0x6D47, 0x9A84, 0x5A07, + 0x56BC, 0x6405, 0x94F0, 0x77EB, 0x4FA5, 0x811A, 0x72E1, 0x89D2, 0x997A, 0x7F34, 0x7EDE, 0x527F, 0x6559, 0x9175, 0x8F7F, 0x8F83, + 0x53EB, 0x7A96, 0x63ED, 0x63A5, 0x7686, 0x79F8, 0x8857, 0x9636, 0x622A, 0x52AB, 0x8282, 0x6854, 0x6770, 0x6377, 0x776B, 0x7AED, + 0x6D01, 0x7ED3, 0x89E3, 0x59D0, 0x6212, 0x85C9, 0x82A5, 0x754C, 0x501F, 0x4ECB, 0x75A5, 0x8BEB, 0x5C4A, 0x5DFE, 0x7B4B, 0x65A4, + 0x91D1, 0x4ECA, 0x6D25, 0x895F, 0x7D27, 0x9526, 0x4EC5, 0x8C28, 0x8FDB, 0x9773, 0x664B, 0x7981, 0x8FD1, 0x70EC, 0x6D78, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x5C3D, 0x52B2, 0x8346, 0x5162, 0x830E, 0x775B, 0x6676, 0x9CB8, 0x4EAC, 0x60CA, 0x7CBE, 0x7CB3, 0x7ECF, 0x4E95, 0x8B66, + 0x666F, 0x9888, 0x9759, 0x5883, 0x656C, 0x955C, 0x5F84, 0x75C9, 0x9756, 0x7ADF, 0x7ADE, 0x51C0, 0x70AF, 0x7A98, 0x63EA, 0x7A76, + 0x7EA0, 0x7396, 0x97ED, 0x4E45, 0x7078, 0x4E5D, 0x9152, 0x53A9, 0x6551, 0x65E7, 0x81FC, 0x8205, 0x548E, 0x5C31, 0x759A, 0x97A0, + 0x62D8, 0x72D9, 0x75BD, 0x5C45, 0x9A79, 0x83CA, 0x5C40, 0x5480, 0x77E9, 0x4E3E, 0x6CAE, 0x805A, 0x62D2, 0x636E, 0x5DE8, 0x5177, + 0x8DDD, 0x8E1E, 0x952F, 0x4FF1, 0x53E5, 0x60E7, 0x70AC, 0x5267, 0x6350, 0x9E43, 0x5A1F, 0x5026, 0x7737, 0x5377, 0x7EE2, 0x6485, + 0x652B, 0x6289, 0x6398, 0x5014, 0x7235, 0x89C9, 0x51B3, 0x8BC0, 0x7EDD, 0x5747, 0x83CC, 0x94A7, 0x519B, 0x541B, 0x5CFB, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x4FCA, 0x7AE3, 0x6D5A, 0x90E1, 0x9A8F, 0x5580, 0x5496, 0x5361, 0x54AF, 0x5F00, 0x63E9, 0x6977, 0x51EF, 0x6168, 0x520A, + 0x582A, 0x52D8, 0x574E, 0x780D, 0x770B, 0x5EB7, 0x6177, 0x7CE0, 0x625B, 0x6297, 0x4EA2, 0x7095, 0x8003, 0x62F7, 0x70E4, 0x9760, + 0x5777, 0x82DB, 0x67EF, 0x68F5, 0x78D5, 0x9897, 0x79D1, 0x58F3, 0x54B3, 0x53EF, 0x6E34, 0x514B, 0x523B, 0x5BA2, 0x8BFE, 0x80AF, + 0x5543, 0x57A6, 0x6073, 0x5751, 0x542D, 0x7A7A, 0x6050, 0x5B54, 0x63A7, 0x62A0, 0x53E3, 0x6263, 0x5BC7, 0x67AF, 0x54ED, 0x7A9F, + 0x82E6, 0x9177, 0x5E93, 0x88E4, 0x5938, 0x57AE, 0x630E, 0x8DE8, 0x80EF, 0x5757, 0x7B77, 0x4FA9, 0x5FEB, 0x5BBD, 0x6B3E, 0x5321, + 0x7B50, 0x72C2, 0x6846, 0x77FF, 0x7736, 0x65F7, 0x51B5, 0x4E8F, 0x76D4, 0x5CBF, 0x7AA5, 0x8475, 0x594E, 0x9B41, 0x5080, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x9988, 0x6127, 0x6E83, 0x5764, 0x6606, 0x6346, 0x56F0, 0x62EC, 0x6269, 0x5ED3, 0x9614, 0x5783, 0x62C9, 0x5587, 0x8721, + 0x814A, 0x8FA3, 0x5566, 0x83B1, 0x6765, 0x8D56, 0x84DD, 0x5A6A, 0x680F, 0x62E6, 0x7BEE, 0x9611, 0x5170, 0x6F9C, 0x8C30, 0x63FD, + 0x89C8, 0x61D2, 0x7F06, 0x70C2, 0x6EE5, 0x7405, 0x6994, 0x72FC, 0x5ECA, 0x90CE, 0x6717, 0x6D6A, 0x635E, 0x52B3, 0x7262, 0x8001, + 0x4F6C, 0x59E5, 0x916A, 0x70D9, 0x6D9D, 0x52D2, 0x4E50, 0x96F7, 0x956D, 0x857E, 0x78CA, 0x7D2F, 0x5121, 0x5792, 0x64C2, 0x808B, + 0x7C7B, 0x6CEA, 0x68F1, 0x695E, 0x51B7, 0x5398, 0x68A8, 0x7281, 0x9ECE, 0x7BF1, 0x72F8, 0x79BB, 0x6F13, 0x7406, 0x674E, 0x91CC, + 0x9CA4, 0x793C, 0x8389, 0x8354, 0x540F, 0x6817, 0x4E3D, 0x5389, 0x52B1, 0x783E, 0x5386, 0x5229, 0x5088, 0x4F8B, 0x4FD0, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x75E2, 0x7ACB, 0x7C92, 0x6CA5, 0x96B6, 0x529B, 0x7483, 0x54E9, 0x4FE9, 0x8054, 0x83B2, 0x8FDE, 0x9570, 0x5EC9, 0x601C, + 0x6D9F, 0x5E18, 0x655B, 0x8138, 0x94FE, 0x604B, 0x70BC, 0x7EC3, 0x7CAE, 0x51C9, 0x6881, 0x7CB1, 0x826F, 0x4E24, 0x8F86, 0x91CF, + 0x667E, 0x4EAE, 0x8C05, 0x64A9, 0x804A, 0x50DA, 0x7597, 0x71CE, 0x5BE5, 0x8FBD, 0x6F66, 0x4E86, 0x6482, 0x9563, 0x5ED6, 0x6599, + 0x5217, 0x88C2, 0x70C8, 0x52A3, 0x730E, 0x7433, 0x6797, 0x78F7, 0x9716, 0x4E34, 0x90BB, 0x9CDE, 0x6DCB, 0x51DB, 0x8D41, 0x541D, + 0x62CE, 0x73B2, 0x83F1, 0x96F6, 0x9F84, 0x94C3, 0x4F36, 0x7F9A, 0x51CC, 0x7075, 0x9675, 0x5CAD, 0x9886, 0x53E6, 0x4EE4, 0x6E9C, + 0x7409, 0x69B4, 0x786B, 0x998F, 0x7559, 0x5218, 0x7624, 0x6D41, 0x67F3, 0x516D, 0x9F99, 0x804B, 0x5499, 0x7B3C, 0x7ABF, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x9686, 0x5784, 0x62E2, 0x9647, 0x697C, 0x5A04, 0x6402, 0x7BD3, 0x6F0F, 0x964B, 0x82A6, 0x5362, 0x9885, 0x5E90, 0x7089, + 0x63B3, 0x5364, 0x864F, 0x9C81, 0x9E93, 0x788C, 0x9732, 0x8DEF, 0x8D42, 0x9E7F, 0x6F5E, 0x7984, 0x5F55, 0x9646, 0x622E, 0x9A74, + 0x5415, 0x94DD, 0x4FA3, 0x65C5, 0x5C65, 0x5C61, 0x7F15, 0x8651, 0x6C2F, 0x5F8B, 0x7387, 0x6EE4, 0x7EFF, 0x5CE6, 0x631B, 0x5B6A, + 0x6EE6, 0x5375, 0x4E71, 0x63A0, 0x7565, 0x62A1, 0x8F6E, 0x4F26, 0x4ED1, 0x6CA6, 0x7EB6, 0x8BBA, 0x841D, 0x87BA, 0x7F57, 0x903B, + 0x9523, 0x7BA9, 0x9AA1, 0x88F8, 0x843D, 0x6D1B, 0x9A86, 0x7EDC, 0x5988, 0x9EBB, 0x739B, 0x7801, 0x8682, 0x9A6C, 0x9A82, 0x561B, + 0x5417, 0x57CB, 0x4E70, 0x9EA6, 0x5356, 0x8FC8, 0x8109, 0x7792, 0x9992, 0x86EE, 0x6EE1, 0x8513, 0x66FC, 0x6162, 0x6F2B, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x8C29, 0x8292, 0x832B, 0x76F2, 0x6C13, 0x5FD9, 0x83BD, 0x732B, 0x8305, 0x951A, 0x6BDB, 0x77DB, 0x94C6, 0x536F, 0x8302, + 0x5192, 0x5E3D, 0x8C8C, 0x8D38, 0x4E48, 0x73AB, 0x679A, 0x6885, 0x9176, 0x9709, 0x7164, 0x6CA1, 0x7709, 0x5A92, 0x9541, 0x6BCF, + 0x7F8E, 0x6627, 0x5BD0, 0x59B9, 0x5A9A, 0x95E8, 0x95F7, 0x4EEC, 0x840C, 0x8499, 0x6AAC, 0x76DF, 0x9530, 0x731B, 0x68A6, 0x5B5F, + 0x772F, 0x919A, 0x9761, 0x7CDC, 0x8FF7, 0x8C1C, 0x5F25, 0x7C73, 0x79D8, 0x89C5, 0x6CCC, 0x871C, 0x5BC6, 0x5E42, 0x68C9, 0x7720, + 0x7EF5, 0x5195, 0x514D, 0x52C9, 0x5A29, 0x7F05, 0x9762, 0x82D7, 0x63CF, 0x7784, 0x85D0, 0x79D2, 0x6E3A, 0x5E99, 0x5999, 0x8511, + 0x706D, 0x6C11, 0x62BF, 0x76BF, 0x654F, 0x60AF, 0x95FD, 0x660E, 0x879F, 0x9E23, 0x94ED, 0x540D, 0x547D, 0x8C2C, 0x6478, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x6479, 0x8611, 0x6A21, 0x819C, 0x78E8, 0x6469, 0x9B54, 0x62B9, 0x672B, 0x83AB, 0x58A8, 0x9ED8, 0x6CAB, 0x6F20, 0x5BDE, + 0x964C, 0x8C0B, 0x725F, 0x67D0, 0x62C7, 0x7261, 0x4EA9, 0x59C6, 0x6BCD, 0x5893, 0x66AE, 0x5E55, 0x52DF, 0x6155, 0x6728, 0x76EE, + 0x7766, 0x7267, 0x7A46, 0x62FF, 0x54EA, 0x5450, 0x94A0, 0x90A3, 0x5A1C, 0x7EB3, 0x6C16, 0x4E43, 0x5976, 0x8010, 0x5948, 0x5357, + 0x7537, 0x96BE, 0x56CA, 0x6320, 0x8111, 0x607C, 0x95F9, 0x6DD6, 0x5462, 0x9981, 0x5185, 0x5AE9, 0x80FD, 0x59AE, 0x9713, 0x502A, + 0x6CE5, 0x5C3C, 0x62DF, 0x4F60, 0x533F, 0x817B, 0x9006, 0x6EBA, 0x852B, 0x62C8, 0x5E74, 0x78BE, 0x64B5, 0x637B, 0x5FF5, 0x5A18, + 0x917F, 0x9E1F, 0x5C3F, 0x634F, 0x8042, 0x5B7D, 0x556E, 0x954A, 0x954D, 0x6D85, 0x60A8, 0x67E0, 0x72DE, 0x51DD, 0x5B81, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x62E7, 0x6CDE, 0x725B, 0x626D, 0x94AE, 0x7EBD, 0x8113, 0x6D53, 0x519C, 0x5F04, 0x5974, 0x52AA, 0x6012, 0x5973, 0x6696, + 0x8650, 0x759F, 0x632A, 0x61E6, 0x7CEF, 0x8BFA, 0x54E6, 0x6B27, 0x9E25, 0x6BB4, 0x85D5, 0x5455, 0x5076, 0x6CA4, 0x556A, 0x8DB4, + 0x722C, 0x5E15, 0x6015, 0x7436, 0x62CD, 0x6392, 0x724C, 0x5F98, 0x6E43, 0x6D3E, 0x6500, 0x6F58, 0x76D8, 0x78D0, 0x76FC, 0x7554, + 0x5224, 0x53DB, 0x4E53, 0x5E9E, 0x65C1, 0x802A, 0x80D6, 0x629B, 0x5486, 0x5228, 0x70AE, 0x888D, 0x8DD1, 0x6CE1, 0x5478, 0x80DA, + 0x57F9, 0x88F4, 0x8D54, 0x966A, 0x914D, 0x4F69, 0x6C9B, 0x55B7, 0x76C6, 0x7830, 0x62A8, 0x70F9, 0x6F8E, 0x5F6D, 0x84EC, 0x68DA, + 0x787C, 0x7BF7, 0x81A8, 0x670B, 0x9E4F, 0x6367, 0x78B0, 0x576F, 0x7812, 0x9739, 0x6279, 0x62AB, 0x5288, 0x7435, 0x6BD7, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x5564, 0x813E, 0x75B2, 0x76AE, 0x5339, 0x75DE, 0x50FB, 0x5C41, 0x8B6C, 0x7BC7, 0x504F, 0x7247, 0x9A97, 0x98D8, 0x6F02, + 0x74E2, 0x7968, 0x6487, 0x77A5, 0x62FC, 0x9891, 0x8D2B, 0x54C1, 0x8058, 0x4E52, 0x576A, 0x82F9, 0x840D, 0x5E73, 0x51ED, 0x74F6, + 0x8BC4, 0x5C4F, 0x5761, 0x6CFC, 0x9887, 0x5A46, 0x7834, 0x9B44, 0x8FEB, 0x7C95, 0x5256, 0x6251, 0x94FA, 0x4EC6, 0x8386, 0x8461, + 0x83E9, 0x84B2, 0x57D4, 0x6734, 0x5703, 0x666E, 0x6D66, 0x8C31, 0x66DD, 0x7011, 0x671F, 0x6B3A, 0x6816, 0x621A, 0x59BB, 0x4E03, + 0x51C4, 0x6F06, 0x67D2, 0x6C8F, 0x5176, 0x68CB, 0x5947, 0x6B67, 0x7566, 0x5D0E, 0x8110, 0x9F50, 0x65D7, 0x7948, 0x7941, 0x9A91, + 0x8D77, 0x5C82, 0x4E5E, 0x4F01, 0x542F, 0x5951, 0x780C, 0x5668, 0x6C14, 0x8FC4, 0x5F03, 0x6C7D, 0x6CE3, 0x8BAB, 0x6390, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x6070, 0x6D3D, 0x7275, 0x6266, 0x948E, 0x94C5, 0x5343, 0x8FC1, 0x7B7E, 0x4EDF, 0x8C26, 0x4E7E, 0x9ED4, 0x94B1, 0x94B3, + 0x524D, 0x6F5C, 0x9063, 0x6D45, 0x8C34, 0x5811, 0x5D4C, 0x6B20, 0x6B49, 0x67AA, 0x545B, 0x8154, 0x7F8C, 0x5899, 0x8537, 0x5F3A, + 0x62A2, 0x6A47, 0x9539, 0x6572, 0x6084, 0x6865, 0x77A7, 0x4E54, 0x4FA8, 0x5DE7, 0x9798, 0x64AC, 0x7FD8, 0x5CED, 0x4FCF, 0x7A8D, + 0x5207, 0x8304, 0x4E14, 0x602F, 0x7A83, 0x94A6, 0x4FB5, 0x4EB2, 0x79E6, 0x7434, 0x52E4, 0x82B9, 0x64D2, 0x79BD, 0x5BDD, 0x6C81, + 0x9752, 0x8F7B, 0x6C22, 0x503E, 0x537F, 0x6E05, 0x64CE, 0x6674, 0x6C30, 0x60C5, 0x9877, 0x8BF7, 0x5E86, 0x743C, 0x7A77, 0x79CB, + 0x4E18, 0x90B1, 0x7403, 0x6C42, 0x56DA, 0x914B, 0x6CC5, 0x8D8B, 0x533A, 0x86C6, 0x66F2, 0x8EAF, 0x5C48, 0x9A71, 0x6E20, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x53D6, 0x5A36, 0x9F8B, 0x8DA3, 0x53BB, 0x5708, 0x98A7, 0x6743, 0x919B, 0x6CC9, 0x5168, 0x75CA, 0x62F3, 0x72AC, 0x5238, + 0x529D, 0x7F3A, 0x7094, 0x7638, 0x5374, 0x9E4A, 0x69B7, 0x786E, 0x96C0, 0x88D9, 0x7FA4, 0x7136, 0x71C3, 0x5189, 0x67D3, 0x74E4, + 0x58E4, 0x6518, 0x56B7, 0x8BA9, 0x9976, 0x6270, 0x7ED5, 0x60F9, 0x70ED, 0x58EC, 0x4EC1, 0x4EBA, 0x5FCD, 0x97E7, 0x4EFB, 0x8BA4, + 0x5203, 0x598A, 0x7EAB, 0x6254, 0x4ECD, 0x65E5, 0x620E, 0x8338, 0x84C9, 0x8363, 0x878D, 0x7194, 0x6EB6, 0x5BB9, 0x7ED2, 0x5197, + 0x63C9, 0x67D4, 0x8089, 0x8339, 0x8815, 0x5112, 0x5B7A, 0x5982, 0x8FB1, 0x4E73, 0x6C5D, 0x5165, 0x8925, 0x8F6F, 0x962E, 0x854A, + 0x745E, 0x9510, 0x95F0, 0x6DA6, 0x82E5, 0x5F31, 0x6492, 0x6D12, 0x8428, 0x816E, 0x9CC3, 0x585E, 0x8D5B, 0x4E09, 0x53C1, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x4F1E, 0x6563, 0x6851, 0x55D3, 0x4E27, 0x6414, 0x9A9A, 0x626B, 0x5AC2, 0x745F, 0x8272, 0x6DA9, 0x68EE, 0x50E7, 0x838E, + 0x7802, 0x6740, 0x5239, 0x6C99, 0x7EB1, 0x50BB, 0x5565, 0x715E, 0x7B5B, 0x6652, 0x73CA, 0x82EB, 0x6749, 0x5C71, 0x5220, 0x717D, + 0x886B, 0x95EA, 0x9655, 0x64C5, 0x8D61, 0x81B3, 0x5584, 0x6C55, 0x6247, 0x7F2E, 0x5892, 0x4F24, 0x5546, 0x8D4F, 0x664C, 0x4E0A, + 0x5C1A, 0x88F3, 0x68A2, 0x634E, 0x7A0D, 0x70E7, 0x828D, 0x52FA, 0x97F6, 0x5C11, 0x54E8, 0x90B5, 0x7ECD, 0x5962, 0x8D4A, 0x86C7, + 0x820C, 0x820D, 0x8D66, 0x6444, 0x5C04, 0x6151, 0x6D89, 0x793E, 0x8BBE, 0x7837, 0x7533, 0x547B, 0x4F38, 0x8EAB, 0x6DF1, 0x5A20, + 0x7EC5, 0x795E, 0x6C88, 0x5BA1, 0x5A76, 0x751A, 0x80BE, 0x614E, 0x6E17, 0x58F0, 0x751F, 0x7525, 0x7272, 0x5347, 0x7EF3, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x7701, 0x76DB, 0x5269, 0x80DC, 0x5723, 0x5E08, 0x5931, 0x72EE, 0x65BD, 0x6E7F, 0x8BD7, 0x5C38, 0x8671, 0x5341, 0x77F3, + 0x62FE, 0x65F6, 0x4EC0, 0x98DF, 0x8680, 0x5B9E, 0x8BC6, 0x53F2, 0x77E2, 0x4F7F, 0x5C4E, 0x9A76, 0x59CB, 0x5F0F, 0x793A, 0x58EB, + 0x4E16, 0x67FF, 0x4E8B, 0x62ED, 0x8A93, 0x901D, 0x52BF, 0x662F, 0x55DC, 0x566C, 0x9002, 0x4ED5, 0x4F8D, 0x91CA, 0x9970, 0x6C0F, + 0x5E02, 0x6043, 0x5BA4, 0x89C6, 0x8BD5, 0x6536, 0x624B, 0x9996, 0x5B88, 0x5BFF, 0x6388, 0x552E, 0x53D7, 0x7626, 0x517D, 0x852C, + 0x67A2, 0x68B3, 0x6B8A, 0x6292, 0x8F93, 0x53D4, 0x8212, 0x6DD1, 0x758F, 0x4E66, 0x8D4E, 0x5B70, 0x719F, 0x85AF, 0x6691, 0x66D9, + 0x7F72, 0x8700, 0x9ECD, 0x9F20, 0x5C5E, 0x672F, 0x8FF0, 0x6811, 0x675F, 0x620D, 0x7AD6, 0x5885, 0x5EB6, 0x6570, 0x6F31, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x6055, 0x5237, 0x800D, 0x6454, 0x8870, 0x7529, 0x5E05, 0x6813, 0x62F4, 0x971C, 0x53CC, 0x723D, 0x8C01, 0x6C34, 0x7761, + 0x7A0E, 0x542E, 0x77AC, 0x987A, 0x821C, 0x8BF4, 0x7855, 0x6714, 0x70C1, 0x65AF, 0x6495, 0x5636, 0x601D, 0x79C1, 0x53F8, 0x4E1D, + 0x6B7B, 0x8086, 0x5BFA, 0x55E3, 0x56DB, 0x4F3A, 0x4F3C, 0x9972, 0x5DF3, 0x677E, 0x8038, 0x6002, 0x9882, 0x9001, 0x5B8B, 0x8BBC, + 0x8BF5, 0x641C, 0x8258, 0x64DE, 0x55FD, 0x82CF, 0x9165, 0x4FD7, 0x7D20, 0x901F, 0x7C9F, 0x50F3, 0x5851, 0x6EAF, 0x5BBF, 0x8BC9, + 0x8083, 0x9178, 0x849C, 0x7B97, 0x867D, 0x968B, 0x968F, 0x7EE5, 0x9AD3, 0x788E, 0x5C81, 0x7A57, 0x9042, 0x96A7, 0x795F, 0x5B59, + 0x635F, 0x7B0B, 0x84D1, 0x68AD, 0x5506, 0x7F29, 0x7410, 0x7D22, 0x9501, 0x6240, 0x584C, 0x4ED6, 0x5B83, 0x5979, 0x5854, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x736D, 0x631E, 0x8E4B, 0x8E0F, 0x80CE, 0x82D4, 0x62AC, 0x53F0, 0x6CF0, 0x915E, 0x592A, 0x6001, 0x6C70, 0x574D, 0x644A, + 0x8D2A, 0x762B, 0x6EE9, 0x575B, 0x6A80, 0x75F0, 0x6F6D, 0x8C2D, 0x8C08, 0x5766, 0x6BEF, 0x8892, 0x78B3, 0x63A2, 0x53F9, 0x70AD, + 0x6C64, 0x5858, 0x642A, 0x5802, 0x68E0, 0x819B, 0x5510, 0x7CD6, 0x5018, 0x8EBA, 0x6DCC, 0x8D9F, 0x70EB, 0x638F, 0x6D9B, 0x6ED4, + 0x7EE6, 0x8404, 0x6843, 0x9003, 0x6DD8, 0x9676, 0x8BA8, 0x5957, 0x7279, 0x85E4, 0x817E, 0x75BC, 0x8A8A, 0x68AF, 0x5254, 0x8E22, + 0x9511, 0x63D0, 0x9898, 0x8E44, 0x557C, 0x4F53, 0x66FF, 0x568F, 0x60D5, 0x6D95, 0x5243, 0x5C49, 0x5929, 0x6DFB, 0x586B, 0x7530, + 0x751C, 0x606C, 0x8214, 0x8146, 0x6311, 0x6761, 0x8FE2, 0x773A, 0x8DF3, 0x8D34, 0x94C1, 0x5E16, 0x5385, 0x542C, 0x70C3, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x6C40, 0x5EF7, 0x505C, 0x4EAD, 0x5EAD, 0x633A, 0x8247, 0x901A, 0x6850, 0x916E, 0x77B3, 0x540C, 0x94DC, 0x5F64, 0x7AE5, + 0x6876, 0x6345, 0x7B52, 0x7EDF, 0x75DB, 0x5077, 0x6295, 0x5934, 0x900F, 0x51F8, 0x79C3, 0x7A81, 0x56FE, 0x5F92, 0x9014, 0x6D82, + 0x5C60, 0x571F, 0x5410, 0x5154, 0x6E4D, 0x56E2, 0x63A8, 0x9893, 0x817F, 0x8715, 0x892A, 0x9000, 0x541E, 0x5C6F, 0x81C0, 0x62D6, + 0x6258, 0x8131, 0x9E35, 0x9640, 0x9A6E, 0x9A7C, 0x692D, 0x59A5, 0x62D3, 0x553E, 0x6316, 0x54C7, 0x86D9, 0x6D3C, 0x5A03, 0x74E6, + 0x889C, 0x6B6A, 0x5916, 0x8C4C, 0x5F2F, 0x6E7E, 0x73A9, 0x987D, 0x4E38, 0x70F7, 0x5B8C, 0x7897, 0x633D, 0x665A, 0x7696, 0x60CB, + 0x5B9B, 0x5A49, 0x4E07, 0x8155, 0x6C6A, 0x738B, 0x4EA1, 0x6789, 0x7F51, 0x5F80, 0x65FA, 0x671B, 0x5FD8, 0x5984, 0x5A01, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x5DCD, 0x5FAE, 0x5371, 0x97E6, 0x8FDD, 0x6845, 0x56F4, 0x552F, 0x60DF, 0x4E3A, 0x6F4D, 0x7EF4, 0x82C7, 0x840E, 0x59D4, + 0x4F1F, 0x4F2A, 0x5C3E, 0x7EAC, 0x672A, 0x851A, 0x5473, 0x754F, 0x80C3, 0x5582, 0x9B4F, 0x4F4D, 0x6E2D, 0x8C13, 0x5C09, 0x6170, + 0x536B, 0x761F, 0x6E29, 0x868A, 0x6587, 0x95FB, 0x7EB9, 0x543B, 0x7A33, 0x7D0A, 0x95EE, 0x55E1, 0x7FC1, 0x74EE, 0x631D, 0x8717, + 0x6DA1, 0x7A9D, 0x6211, 0x65A1, 0x5367, 0x63E1, 0x6C83, 0x5DEB, 0x545C, 0x94A8, 0x4E4C, 0x6C61, 0x8BEC, 0x5C4B, 0x65E0, 0x829C, + 0x68A7, 0x543E, 0x5434, 0x6BCB, 0x6B66, 0x4E94, 0x6342, 0x5348, 0x821E, 0x4F0D, 0x4FAE, 0x575E, 0x620A, 0x96FE, 0x6664, 0x7269, + 0x52FF, 0x52A1, 0x609F, 0x8BEF, 0x6614, 0x7199, 0x6790, 0x897F, 0x7852, 0x77FD, 0x6670, 0x563B, 0x5438, 0x9521, 0x727A, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x7A00, 0x606F, 0x5E0C, 0x6089, 0x819D, 0x5915, 0x60DC, 0x7184, 0x70EF, 0x6EAA, 0x6C50, 0x7280, 0x6A84, 0x88AD, 0x5E2D, + 0x4E60, 0x5AB3, 0x559C, 0x94E3, 0x6D17, 0x7CFB, 0x9699, 0x620F, 0x7EC6, 0x778E, 0x867E, 0x5323, 0x971E, 0x8F96, 0x6687, 0x5CE1, + 0x4FA0, 0x72ED, 0x4E0B, 0x53A6, 0x590F, 0x5413, 0x6380, 0x9528, 0x5148, 0x4ED9, 0x9C9C, 0x7EA4, 0x54B8, 0x8D24, 0x8854, 0x8237, + 0x95F2, 0x6D8E, 0x5F26, 0x5ACC, 0x663E, 0x9669, 0x73B0, 0x732E, 0x53BF, 0x817A, 0x9985, 0x7FA1, 0x5BAA, 0x9677, 0x9650, 0x7EBF, + 0x76F8, 0x53A2, 0x9576, 0x9999, 0x7BB1, 0x8944, 0x6E58, 0x4E61, 0x7FD4, 0x7965, 0x8BE6, 0x60F3, 0x54CD, 0x4EAB, 0x9879, 0x5DF7, + 0x6A61, 0x50CF, 0x5411, 0x8C61, 0x8427, 0x785D, 0x9704, 0x524A, 0x54EE, 0x56A3, 0x9500, 0x6D88, 0x5BB5, 0x6DC6, 0x6653, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x5C0F, 0x5B5D, 0x6821, 0x8096, 0x5578, 0x7B11, 0x6548, 0x6954, 0x4E9B, 0x6B47, 0x874E, 0x978B, 0x534F, 0x631F, 0x643A, + 0x90AA, 0x659C, 0x80C1, 0x8C10, 0x5199, 0x68B0, 0x5378, 0x87F9, 0x61C8, 0x6CC4, 0x6CFB, 0x8C22, 0x5C51, 0x85AA, 0x82AF, 0x950C, + 0x6B23, 0x8F9B, 0x65B0, 0x5FFB, 0x5FC3, 0x4FE1, 0x8845, 0x661F, 0x8165, 0x7329, 0x60FA, 0x5174, 0x5211, 0x578B, 0x5F62, 0x90A2, + 0x884C, 0x9192, 0x5E78, 0x674F, 0x6027, 0x59D3, 0x5144, 0x51F6, 0x80F8, 0x5308, 0x6C79, 0x96C4, 0x718A, 0x4F11, 0x4FEE, 0x7F9E, + 0x673D, 0x55C5, 0x9508, 0x79C0, 0x8896, 0x7EE3, 0x589F, 0x620C, 0x9700, 0x865A, 0x5618, 0x987B, 0x5F90, 0x8BB8, 0x84C4, 0x9157, + 0x53D9, 0x65ED, 0x5E8F, 0x755C, 0x6064, 0x7D6E, 0x5A7F, 0x7EEA, 0x7EED, 0x8F69, 0x55A7, 0x5BA3, 0x60AC, 0x65CB, 0x7384, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x9009, 0x7663, 0x7729, 0x7EDA, 0x9774, 0x859B, 0x5B66, 0x7A74, 0x96EA, 0x8840, 0x52CB, 0x718F, 0x5FAA, 0x65EC, 0x8BE2, + 0x5BFB, 0x9A6F, 0x5DE1, 0x6B89, 0x6C5B, 0x8BAD, 0x8BAF, 0x900A, 0x8FC5, 0x538B, 0x62BC, 0x9E26, 0x9E2D, 0x5440, 0x4E2B, 0x82BD, + 0x7259, 0x869C, 0x5D16, 0x8859, 0x6DAF, 0x96C5, 0x54D1, 0x4E9A, 0x8BB6, 0x7109, 0x54BD, 0x9609, 0x70DF, 0x6DF9, 0x76D0, 0x4E25, + 0x7814, 0x8712, 0x5CA9, 0x5EF6, 0x8A00, 0x989C, 0x960E, 0x708E, 0x6CBF, 0x5944, 0x63A9, 0x773C, 0x884D, 0x6F14, 0x8273, 0x5830, + 0x71D5, 0x538C, 0x781A, 0x96C1, 0x5501, 0x5F66, 0x7130, 0x5BB4, 0x8C1A, 0x9A8C, 0x6B83, 0x592E, 0x9E2F, 0x79E7, 0x6768, 0x626C, + 0x4F6F, 0x75A1, 0x7F8A, 0x6D0B, 0x9633, 0x6C27, 0x4EF0, 0x75D2, 0x517B, 0x6837, 0x6F3E, 0x9080, 0x8170, 0x5996, 0x7476, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x6447, 0x5C27, 0x9065, 0x7A91, 0x8C23, 0x59DA, 0x54AC, 0x8200, 0x836F, 0x8981, 0x8000, 0x6930, 0x564E, 0x8036, 0x7237, + 0x91CE, 0x51B6, 0x4E5F, 0x9875, 0x6396, 0x4E1A, 0x53F6, 0x66F3, 0x814B, 0x591C, 0x6DB2, 0x4E00, 0x58F9, 0x533B, 0x63D6, 0x94F1, + 0x4F9D, 0x4F0A, 0x8863, 0x9890, 0x5937, 0x9057, 0x79FB, 0x4EEA, 0x80F0, 0x7591, 0x6C82, 0x5B9C, 0x59E8, 0x5F5D, 0x6905, 0x8681, + 0x501A, 0x5DF2, 0x4E59, 0x77E3, 0x4EE5, 0x827A, 0x6291, 0x6613, 0x9091, 0x5C79, 0x4EBF, 0x5F79, 0x81C6, 0x9038, 0x8084, 0x75AB, + 0x4EA6, 0x88D4, 0x610F, 0x6BC5, 0x5FC6, 0x4E49, 0x76CA, 0x6EA2, 0x8BE3, 0x8BAE, 0x8C0A, 0x8BD1, 0x5F02, 0x7FFC, 0x7FCC, 0x7ECE, + 0x8335, 0x836B, 0x56E0, 0x6BB7, 0x97F3, 0x9634, 0x59FB, 0x541F, 0x94F6, 0x6DEB, 0x5BC5, 0x996E, 0x5C39, 0x5F15, 0x9690, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x5370, 0x82F1, 0x6A31, 0x5A74, 0x9E70, 0x5E94, 0x7F28, 0x83B9, 0x8424, 0x8425, 0x8367, 0x8747, 0x8FCE, 0x8D62, 0x76C8, + 0x5F71, 0x9896, 0x786C, 0x6620, 0x54DF, 0x62E5, 0x4F63, 0x81C3, 0x75C8, 0x5EB8, 0x96CD, 0x8E0A, 0x86F9, 0x548F, 0x6CF3, 0x6D8C, + 0x6C38, 0x607F, 0x52C7, 0x7528, 0x5E7D, 0x4F18, 0x60A0, 0x5FE7, 0x5C24, 0x7531, 0x90AE, 0x94C0, 0x72B9, 0x6CB9, 0x6E38, 0x9149, + 0x6709, 0x53CB, 0x53F3, 0x4F51, 0x91C9, 0x8BF1, 0x53C8, 0x5E7C, 0x8FC2, 0x6DE4, 0x4E8E, 0x76C2, 0x6986, 0x865E, 0x611A, 0x8206, + 0x4F59, 0x4FDE, 0x903E, 0x9C7C, 0x6109, 0x6E1D, 0x6E14, 0x9685, 0x4E88, 0x5A31, 0x96E8, 0x4E0E, 0x5C7F, 0x79B9, 0x5B87, 0x8BED, + 0x7FBD, 0x7389, 0x57DF, 0x828B, 0x90C1, 0x5401, 0x9047, 0x55BB, 0x5CEA, 0x5FA1, 0x6108, 0x6B32, 0x72F1, 0x80B2, 0x8A89, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x6D74, 0x5BD3, 0x88D5, 0x9884, 0x8C6B, 0x9A6D, 0x9E33, 0x6E0A, 0x51A4, 0x5143, 0x57A3, 0x8881, 0x539F, 0x63F4, 0x8F95, + 0x56ED, 0x5458, 0x5706, 0x733F, 0x6E90, 0x7F18, 0x8FDC, 0x82D1, 0x613F, 0x6028, 0x9662, 0x66F0, 0x7EA6, 0x8D8A, 0x8DC3, 0x94A5, + 0x5CB3, 0x7CA4, 0x6708, 0x60A6, 0x9605, 0x8018, 0x4E91, 0x90E7, 0x5300, 0x9668, 0x5141, 0x8FD0, 0x8574, 0x915D, 0x6655, 0x97F5, + 0x5B55, 0x531D, 0x7838, 0x6742, 0x683D, 0x54C9, 0x707E, 0x5BB0, 0x8F7D, 0x518D, 0x5728, 0x54B1, 0x6512, 0x6682, 0x8D5E, 0x8D43, + 0x810F, 0x846C, 0x906D, 0x7CDF, 0x51FF, 0x85FB, 0x67A3, 0x65E9, 0x6FA1, 0x86A4, 0x8E81, 0x566A, 0x9020, 0x7682, 0x7076, 0x71E5, + 0x8D23, 0x62E9, 0x5219, 0x6CFD, 0x8D3C, 0x600E, 0x589E, 0x618E, 0x66FE, 0x8D60, 0x624E, 0x55B3, 0x6E23, 0x672D, 0x8F67, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x94E1, 0x95F8, 0x7728, 0x6805, 0x69A8, 0x548B, 0x4E4D, 0x70B8, 0x8BC8, 0x6458, 0x658B, 0x5B85, 0x7A84, 0x503A, 0x5BE8, + 0x77BB, 0x6BE1, 0x8A79, 0x7C98, 0x6CBE, 0x76CF, 0x65A9, 0x8F97, 0x5D2D, 0x5C55, 0x8638, 0x6808, 0x5360, 0x6218, 0x7AD9, 0x6E5B, + 0x7EFD, 0x6A1F, 0x7AE0, 0x5F70, 0x6F33, 0x5F20, 0x638C, 0x6DA8, 0x6756, 0x4E08, 0x5E10, 0x8D26, 0x4ED7, 0x80C0, 0x7634, 0x969C, + 0x62DB, 0x662D, 0x627E, 0x6CBC, 0x8D75, 0x7167, 0x7F69, 0x5146, 0x8087, 0x53EC, 0x906E, 0x6298, 0x54F2, 0x86F0, 0x8F99, 0x8005, + 0x9517, 0x8517, 0x8FD9, 0x6D59, 0x73CD, 0x659F, 0x771F, 0x7504, 0x7827, 0x81FB, 0x8D1E, 0x9488, 0x4FA6, 0x6795, 0x75B9, 0x8BCA, + 0x9707, 0x632F, 0x9547, 0x9635, 0x84B8, 0x6323, 0x7741, 0x5F81, 0x72F0, 0x4E89, 0x6014, 0x6574, 0x62EF, 0x6B63, 0x653F, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x5E27, 0x75C7, 0x90D1, 0x8BC1, 0x829D, 0x679D, 0x652F, 0x5431, 0x8718, 0x77E5, 0x80A2, 0x8102, 0x6C41, 0x4E4B, 0x7EC7, + 0x804C, 0x76F4, 0x690D, 0x6B96, 0x6267, 0x503C, 0x4F84, 0x5740, 0x6307, 0x6B62, 0x8DBE, 0x53EA, 0x65E8, 0x7EB8, 0x5FD7, 0x631A, + 0x63B7, 0x81F3, 0x81F4, 0x7F6E, 0x5E1C, 0x5CD9, 0x5236, 0x667A, 0x79E9, 0x7A1A, 0x8D28, 0x7099, 0x75D4, 0x6EDE, 0x6CBB, 0x7A92, + 0x4E2D, 0x76C5, 0x5FE0, 0x949F, 0x8877, 0x7EC8, 0x79CD, 0x80BF, 0x91CD, 0x4EF2, 0x4F17, 0x821F, 0x5468, 0x5DDE, 0x6D32, 0x8BCC, + 0x7CA5, 0x8F74, 0x8098, 0x5E1A, 0x5492, 0x76B1, 0x5B99, 0x663C, 0x9AA4, 0x73E0, 0x682A, 0x86DB, 0x6731, 0x732A, 0x8BF8, 0x8BDB, + 0x9010, 0x7AF9, 0x70DB, 0x716E, 0x62C4, 0x77A9, 0x5631, 0x4E3B, 0x8457, 0x67F1, 0x52A9, 0x86C0, 0x8D2E, 0x94F8, 0x7B51, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x4F4F, 0x6CE8, 0x795D, 0x9A7B, 0x6293, 0x722A, 0x62FD, 0x4E13, 0x7816, 0x8F6C, 0x64B0, 0x8D5A, 0x7BC6, 0x6869, 0x5E84, + 0x88C5, 0x5986, 0x649E, 0x58EE, 0x72B6, 0x690E, 0x9525, 0x8FFD, 0x8D58, 0x5760, 0x7F00, 0x8C06, 0x51C6, 0x6349, 0x62D9, 0x5353, + 0x684C, 0x7422, 0x8301, 0x914C, 0x5544, 0x7740, 0x707C, 0x6D4A, 0x5179, 0x54A8, 0x8D44, 0x59FF, 0x6ECB, 0x6DC4, 0x5B5C, 0x7D2B, + 0x4ED4, 0x7C7D, 0x6ED3, 0x5B50, 0x81EA, 0x6E0D, 0x5B57, 0x9B03, 0x68D5, 0x8E2A, 0x5B97, 0x7EFC, 0x603B, 0x7EB5, 0x90B9, 0x8D70, + 0x594F, 0x63CD, 0x79DF, 0x8DB3, 0x5352, 0x65CF, 0x7956, 0x8BC5, 0x963B, 0x7EC4, 0x94BB, 0x7E82, 0x5634, 0x9189, 0x6700, 0x7F6A, + 0x5C0A, 0x9075, 0x6628, 0x5DE6, 0x4F50, 0x67DE, 0x505A, 0x4F5C, 0x5750, 0x5EA7, 0xE810, 0xE811, 0xE812, 0xE813, 0xE814, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x4E8D, 0x4E0C, 0x5140, 0x4E10, 0x5EFF, 0x5345, 0x4E15, 0x4E98, 0x4E1E, 0x9B32, 0x5B6C, 0x5669, 0x4E28, 0x79BA, 0x4E3F, + 0x5315, 0x4E47, 0x592D, 0x723B, 0x536E, 0x6C10, 0x56DF, 0x80E4, 0x9997, 0x6BD3, 0x777E, 0x9F17, 0x4E36, 0x4E9F, 0x9F10, 0x4E5C, + 0x4E69, 0x4E93, 0x8288, 0x5B5B, 0x556C, 0x560F, 0x4EC4, 0x538D, 0x539D, 0x53A3, 0x53A5, 0x53AE, 0x9765, 0x8D5D, 0x531A, 0x53F5, + 0x5326, 0x532E, 0x533E, 0x8D5C, 0x5366, 0x5363, 0x5202, 0x5208, 0x520E, 0x522D, 0x5233, 0x523F, 0x5240, 0x524C, 0x525E, 0x5261, + 0x525C, 0x84AF, 0x527D, 0x5282, 0x5281, 0x5290, 0x5293, 0x5182, 0x7F54, 0x4EBB, 0x4EC3, 0x4EC9, 0x4EC2, 0x4EE8, 0x4EE1, 0x4EEB, + 0x4EDE, 0x4F1B, 0x4EF3, 0x4F22, 0x4F64, 0x4EF5, 0x4F25, 0x4F27, 0x4F09, 0x4F2B, 0x4F5E, 0x4F67, 0x6538, 0x4F5A, 0x4F5D, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x4F5F, 0x4F57, 0x4F32, 0x4F3D, 0x4F76, 0x4F74, 0x4F91, 0x4F89, 0x4F83, 0x4F8F, 0x4F7E, 0x4F7B, 0x4FAA, 0x4F7C, 0x4FAC, + 0x4F94, 0x4FE6, 0x4FE8, 0x4FEA, 0x4FC5, 0x4FDA, 0x4FE3, 0x4FDC, 0x4FD1, 0x4FDF, 0x4FF8, 0x5029, 0x504C, 0x4FF3, 0x502C, 0x500F, + 0x502E, 0x502D, 0x4FFE, 0x501C, 0x500C, 0x5025, 0x5028, 0x507E, 0x5043, 0x5055, 0x5048, 0x504E, 0x506C, 0x507B, 0x50A5, 0x50A7, + 0x50A9, 0x50BA, 0x50D6, 0x5106, 0x50ED, 0x50EC, 0x50E6, 0x50EE, 0x5107, 0x510B, 0x4EDD, 0x6C3D, 0x4F58, 0x4F65, 0x4FCE, 0x9FA0, + 0x6C46, 0x7C74, 0x516E, 0x5DFD, 0x9EC9, 0x9998, 0x5181, 0x5914, 0x52F9, 0x530D, 0x8A07, 0x5310, 0x51EB, 0x5919, 0x5155, 0x4EA0, + 0x5156, 0x4EB3, 0x886E, 0x88A4, 0x4EB5, 0x8114, 0x88D2, 0x7980, 0x5B34, 0x8803, 0x7FB8, 0x51AB, 0x51B1, 0x51BD, 0x51BC, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x51C7, 0x5196, 0x51A2, 0x51A5, 0x8BA0, 0x8BA6, 0x8BA7, 0x8BAA, 0x8BB4, 0x8BB5, 0x8BB7, 0x8BC2, 0x8BC3, 0x8BCB, 0x8BCF, + 0x8BCE, 0x8BD2, 0x8BD3, 0x8BD4, 0x8BD6, 0x8BD8, 0x8BD9, 0x8BDC, 0x8BDF, 0x8BE0, 0x8BE4, 0x8BE8, 0x8BE9, 0x8BEE, 0x8BF0, 0x8BF3, + 0x8BF6, 0x8BF9, 0x8BFC, 0x8BFF, 0x8C00, 0x8C02, 0x8C04, 0x8C07, 0x8C0C, 0x8C0F, 0x8C11, 0x8C12, 0x8C14, 0x8C15, 0x8C16, 0x8C19, + 0x8C1B, 0x8C18, 0x8C1D, 0x8C1F, 0x8C20, 0x8C21, 0x8C25, 0x8C27, 0x8C2A, 0x8C2B, 0x8C2E, 0x8C2F, 0x8C32, 0x8C33, 0x8C35, 0x8C36, + 0x5369, 0x537A, 0x961D, 0x9622, 0x9621, 0x9631, 0x962A, 0x963D, 0x963C, 0x9642, 0x9649, 0x9654, 0x965F, 0x9667, 0x966C, 0x9672, + 0x9674, 0x9688, 0x968D, 0x9697, 0x96B0, 0x9097, 0x909B, 0x909D, 0x9099, 0x90AC, 0x90A1, 0x90B4, 0x90B3, 0x90B6, 0x90BA, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x90B8, 0x90B0, 0x90CF, 0x90C5, 0x90BE, 0x90D0, 0x90C4, 0x90C7, 0x90D3, 0x90E6, 0x90E2, 0x90DC, 0x90D7, 0x90DB, 0x90EB, + 0x90EF, 0x90FE, 0x9104, 0x9122, 0x911E, 0x9123, 0x9131, 0x912F, 0x9139, 0x9143, 0x9146, 0x520D, 0x5942, 0x52A2, 0x52AC, 0x52AD, + 0x52BE, 0x54FF, 0x52D0, 0x52D6, 0x52F0, 0x53DF, 0x71EE, 0x77CD, 0x5EF4, 0x51F5, 0x51FC, 0x9B2F, 0x53B6, 0x5F01, 0x755A, 0x5DEF, + 0x574C, 0x57A9, 0x57A1, 0x587E, 0x58BC, 0x58C5, 0x58D1, 0x5729, 0x572C, 0x572A, 0x5733, 0x5739, 0x572E, 0x572F, 0x575C, 0x573B, + 0x5742, 0x5769, 0x5785, 0x576B, 0x5786, 0x577C, 0x577B, 0x5768, 0x576D, 0x5776, 0x5773, 0x57AD, 0x57A4, 0x578C, 0x57B2, 0x57CF, + 0x57A7, 0x57B4, 0x5793, 0x57A0, 0x57D5, 0x57D8, 0x57DA, 0x57D9, 0x57D2, 0x57B8, 0x57F4, 0x57EF, 0x57F8, 0x57E4, 0x57DD, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x580B, 0x580D, 0x57FD, 0x57ED, 0x5800, 0x581E, 0x5819, 0x5844, 0x5820, 0x5865, 0x586C, 0x5881, 0x5889, 0x589A, 0x5880, + 0x99A8, 0x9F19, 0x61FF, 0x8279, 0x827D, 0x827F, 0x828F, 0x828A, 0x82A8, 0x8284, 0x828E, 0x8291, 0x8297, 0x8299, 0x82AB, 0x82B8, + 0x82BE, 0x82B0, 0x82C8, 0x82CA, 0x82E3, 0x8298, 0x82B7, 0x82AE, 0x82CB, 0x82CC, 0x82C1, 0x82A9, 0x82B4, 0x82A1, 0x82AA, 0x829F, + 0x82C4, 0x82CE, 0x82A4, 0x82E1, 0x8309, 0x82F7, 0x82E4, 0x830F, 0x8307, 0x82DC, 0x82F4, 0x82D2, 0x82D8, 0x830C, 0x82FB, 0x82D3, + 0x8311, 0x831A, 0x8306, 0x8314, 0x8315, 0x82E0, 0x82D5, 0x831C, 0x8351, 0x835B, 0x835C, 0x8308, 0x8392, 0x833C, 0x8334, 0x8331, + 0x839B, 0x835E, 0x832F, 0x834F, 0x8347, 0x8343, 0x835F, 0x8340, 0x8317, 0x8360, 0x832D, 0x833A, 0x8333, 0x8366, 0x8365, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x8368, 0x831B, 0x8369, 0x836C, 0x836A, 0x836D, 0x836E, 0x83B0, 0x8378, 0x83B3, 0x83B4, 0x83A0, 0x83AA, 0x8393, 0x839C, + 0x8385, 0x837C, 0x83B6, 0x83A9, 0x837D, 0x83B8, 0x837B, 0x8398, 0x839E, 0x83A8, 0x83BA, 0x83BC, 0x83C1, 0x8401, 0x83E5, 0x83D8, + 0x5807, 0x8418, 0x840B, 0x83DD, 0x83FD, 0x83D6, 0x841C, 0x8438, 0x8411, 0x8406, 0x83D4, 0x83DF, 0x840F, 0x8403, 0x83F8, 0x83F9, + 0x83EA, 0x83C5, 0x83C0, 0x8426, 0x83F0, 0x83E1, 0x845C, 0x8451, 0x845A, 0x8459, 0x8473, 0x8487, 0x8488, 0x847A, 0x8489, 0x8478, + 0x843C, 0x8446, 0x8469, 0x8476, 0x848C, 0x848E, 0x8431, 0x846D, 0x84C1, 0x84CD, 0x84D0, 0x84E6, 0x84BD, 0x84D3, 0x84CA, 0x84BF, + 0x84BA, 0x84E0, 0x84A1, 0x84B9, 0x84B4, 0x8497, 0x84E5, 0x84E3, 0x850C, 0x750D, 0x8538, 0x84F0, 0x8539, 0x851F, 0x853A, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x8556, 0x853B, 0x84FF, 0x84FC, 0x8559, 0x8548, 0x8568, 0x8564, 0x855E, 0x857A, 0x77A2, 0x8543, 0x8572, 0x857B, 0x85A4, + 0x85A8, 0x8587, 0x858F, 0x8579, 0x85AE, 0x859C, 0x8585, 0x85B9, 0x85B7, 0x85B0, 0x85D3, 0x85C1, 0x85DC, 0x85FF, 0x8627, 0x8605, + 0x8629, 0x8616, 0x863C, 0x5EFE, 0x5F08, 0x593C, 0x5941, 0x8037, 0x5955, 0x595A, 0x5958, 0x530F, 0x5C22, 0x5C25, 0x5C2C, 0x5C34, + 0x624C, 0x626A, 0x629F, 0x62BB, 0x62CA, 0x62DA, 0x62D7, 0x62EE, 0x6322, 0x62F6, 0x6339, 0x634B, 0x6343, 0x63AD, 0x63F6, 0x6371, + 0x637A, 0x638E, 0x63B4, 0x636D, 0x63AC, 0x638A, 0x6369, 0x63AE, 0x63BC, 0x63F2, 0x63F8, 0x63E0, 0x63FF, 0x63C4, 0x63DE, 0x63CE, + 0x6452, 0x63C6, 0x63BE, 0x6445, 0x6441, 0x640B, 0x641B, 0x6420, 0x640C, 0x6426, 0x6421, 0x645E, 0x6484, 0x646D, 0x6496, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x647A, 0x64B7, 0x64B8, 0x6499, 0x64BA, 0x64C0, 0x64D0, 0x64D7, 0x64E4, 0x64E2, 0x6509, 0x6525, 0x652E, 0x5F0B, 0x5FD2, + 0x7519, 0x5F11, 0x535F, 0x53F1, 0x53FD, 0x53E9, 0x53E8, 0x53FB, 0x5412, 0x5416, 0x5406, 0x544B, 0x5452, 0x5453, 0x5454, 0x5456, + 0x5443, 0x5421, 0x5457, 0x5459, 0x5423, 0x5432, 0x5482, 0x5494, 0x5477, 0x5471, 0x5464, 0x549A, 0x549B, 0x5484, 0x5476, 0x5466, + 0x549D, 0x54D0, 0x54AD, 0x54C2, 0x54B4, 0x54D2, 0x54A7, 0x54A6, 0x54D3, 0x54D4, 0x5472, 0x54A3, 0x54D5, 0x54BB, 0x54BF, 0x54CC, + 0x54D9, 0x54DA, 0x54DC, 0x54A9, 0x54AA, 0x54A4, 0x54DD, 0x54CF, 0x54DE, 0x551B, 0x54E7, 0x5520, 0x54FD, 0x5514, 0x54F3, 0x5522, + 0x5523, 0x550F, 0x5511, 0x5527, 0x552A, 0x5567, 0x558F, 0x55B5, 0x5549, 0x556D, 0x5541, 0x5555, 0x553F, 0x5550, 0x553C, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x5537, 0x5556, 0x5575, 0x5576, 0x5577, 0x5533, 0x5530, 0x555C, 0x558B, 0x55D2, 0x5583, 0x55B1, 0x55B9, 0x5588, 0x5581, + 0x559F, 0x557E, 0x55D6, 0x5591, 0x557B, 0x55DF, 0x55BD, 0x55BE, 0x5594, 0x5599, 0x55EA, 0x55F7, 0x55C9, 0x561F, 0x55D1, 0x55EB, + 0x55EC, 0x55D4, 0x55E6, 0x55DD, 0x55C4, 0x55EF, 0x55E5, 0x55F2, 0x55F3, 0x55CC, 0x55CD, 0x55E8, 0x55F5, 0x55E4, 0x8F94, 0x561E, + 0x5608, 0x560C, 0x5601, 0x5624, 0x5623, 0x55FE, 0x5600, 0x5627, 0x562D, 0x5658, 0x5639, 0x5657, 0x562C, 0x564D, 0x5662, 0x5659, + 0x565C, 0x564C, 0x5654, 0x5686, 0x5664, 0x5671, 0x566B, 0x567B, 0x567C, 0x5685, 0x5693, 0x56AF, 0x56D4, 0x56D7, 0x56DD, 0x56E1, + 0x56F5, 0x56EB, 0x56F9, 0x56FF, 0x5704, 0x570A, 0x5709, 0x571C, 0x5E0F, 0x5E19, 0x5E14, 0x5E11, 0x5E31, 0x5E3B, 0x5E3C, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x5E37, 0x5E44, 0x5E54, 0x5E5B, 0x5E5E, 0x5E61, 0x5C8C, 0x5C7A, 0x5C8D, 0x5C90, 0x5C96, 0x5C88, 0x5C98, 0x5C99, 0x5C91, + 0x5C9A, 0x5C9C, 0x5CB5, 0x5CA2, 0x5CBD, 0x5CAC, 0x5CAB, 0x5CB1, 0x5CA3, 0x5CC1, 0x5CB7, 0x5CC4, 0x5CD2, 0x5CE4, 0x5CCB, 0x5CE5, + 0x5D02, 0x5D03, 0x5D27, 0x5D26, 0x5D2E, 0x5D24, 0x5D1E, 0x5D06, 0x5D1B, 0x5D58, 0x5D3E, 0x5D34, 0x5D3D, 0x5D6C, 0x5D5B, 0x5D6F, + 0x5D5D, 0x5D6B, 0x5D4B, 0x5D4A, 0x5D69, 0x5D74, 0x5D82, 0x5D99, 0x5D9D, 0x8C73, 0x5DB7, 0x5DC5, 0x5F73, 0x5F77, 0x5F82, 0x5F87, + 0x5F89, 0x5F8C, 0x5F95, 0x5F99, 0x5F9C, 0x5FA8, 0x5FAD, 0x5FB5, 0x5FBC, 0x8862, 0x5F61, 0x72AD, 0x72B0, 0x72B4, 0x72B7, 0x72B8, + 0x72C3, 0x72C1, 0x72CE, 0x72CD, 0x72D2, 0x72E8, 0x72EF, 0x72E9, 0x72F2, 0x72F4, 0x72F7, 0x7301, 0x72F3, 0x7303, 0x72FA, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x72FB, 0x7317, 0x7313, 0x7321, 0x730A, 0x731E, 0x731D, 0x7315, 0x7322, 0x7339, 0x7325, 0x732C, 0x7338, 0x7331, 0x7350, + 0x734D, 0x7357, 0x7360, 0x736C, 0x736F, 0x737E, 0x821B, 0x5925, 0x98E7, 0x5924, 0x5902, 0x9963, 0x9967, 0x9968, 0x9969, 0x996A, + 0x996B, 0x996C, 0x9974, 0x9977, 0x997D, 0x9980, 0x9984, 0x9987, 0x998A, 0x998D, 0x9990, 0x9991, 0x9993, 0x9994, 0x9995, 0x5E80, + 0x5E91, 0x5E8B, 0x5E96, 0x5EA5, 0x5EA0, 0x5EB9, 0x5EB5, 0x5EBE, 0x5EB3, 0x8D53, 0x5ED2, 0x5ED1, 0x5EDB, 0x5EE8, 0x5EEA, 0x81BA, + 0x5FC4, 0x5FC9, 0x5FD6, 0x5FCF, 0x6003, 0x5FEE, 0x6004, 0x5FE1, 0x5FE4, 0x5FFE, 0x6005, 0x6006, 0x5FEA, 0x5FED, 0x5FF8, 0x6019, + 0x6035, 0x6026, 0x601B, 0x600F, 0x600D, 0x6029, 0x602B, 0x600A, 0x603F, 0x6021, 0x6078, 0x6079, 0x607B, 0x607A, 0x6042, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x606A, 0x607D, 0x6096, 0x609A, 0x60AD, 0x609D, 0x6083, 0x6092, 0x608C, 0x609B, 0x60EC, 0x60BB, 0x60B1, 0x60DD, 0x60D8, + 0x60C6, 0x60DA, 0x60B4, 0x6120, 0x6126, 0x6115, 0x6123, 0x60F4, 0x6100, 0x610E, 0x612B, 0x614A, 0x6175, 0x61AC, 0x6194, 0x61A7, + 0x61B7, 0x61D4, 0x61F5, 0x5FDD, 0x96B3, 0x95E9, 0x95EB, 0x95F1, 0x95F3, 0x95F5, 0x95F6, 0x95FC, 0x95FE, 0x9603, 0x9604, 0x9606, + 0x9608, 0x960A, 0x960B, 0x960C, 0x960D, 0x960F, 0x9612, 0x9615, 0x9616, 0x9617, 0x9619, 0x961A, 0x4E2C, 0x723F, 0x6215, 0x6C35, + 0x6C54, 0x6C5C, 0x6C4A, 0x6CA3, 0x6C85, 0x6C90, 0x6C94, 0x6C8C, 0x6C68, 0x6C69, 0x6C74, 0x6C76, 0x6C86, 0x6CA9, 0x6CD0, 0x6CD4, + 0x6CAD, 0x6CF7, 0x6CF8, 0x6CF1, 0x6CD7, 0x6CB2, 0x6CE0, 0x6CD6, 0x6CFA, 0x6CEB, 0x6CEE, 0x6CB1, 0x6CD3, 0x6CEF, 0x6CFE, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x6D39, 0x6D27, 0x6D0C, 0x6D43, 0x6D48, 0x6D07, 0x6D04, 0x6D19, 0x6D0E, 0x6D2B, 0x6D4D, 0x6D2E, 0x6D35, 0x6D1A, 0x6D4F, + 0x6D52, 0x6D54, 0x6D33, 0x6D91, 0x6D6F, 0x6D9E, 0x6DA0, 0x6D5E, 0x6D93, 0x6D94, 0x6D5C, 0x6D60, 0x6D7C, 0x6D63, 0x6E1A, 0x6DC7, + 0x6DC5, 0x6DDE, 0x6E0E, 0x6DBF, 0x6DE0, 0x6E11, 0x6DE6, 0x6DDD, 0x6DD9, 0x6E16, 0x6DAB, 0x6E0C, 0x6DAE, 0x6E2B, 0x6E6E, 0x6E4E, + 0x6E6B, 0x6EB2, 0x6E5F, 0x6E86, 0x6E53, 0x6E54, 0x6E32, 0x6E25, 0x6E44, 0x6EDF, 0x6EB1, 0x6E98, 0x6EE0, 0x6F2D, 0x6EE2, 0x6EA5, + 0x6EA7, 0x6EBD, 0x6EBB, 0x6EB7, 0x6ED7, 0x6EB4, 0x6ECF, 0x6E8F, 0x6EC2, 0x6E9F, 0x6F62, 0x6F46, 0x6F47, 0x6F24, 0x6F15, 0x6EF9, + 0x6F2F, 0x6F36, 0x6F4B, 0x6F74, 0x6F2A, 0x6F09, 0x6F29, 0x6F89, 0x6F8D, 0x6F8C, 0x6F78, 0x6F72, 0x6F7C, 0x6F7A, 0x6FD1, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x6FC9, 0x6FA7, 0x6FB9, 0x6FB6, 0x6FC2, 0x6FE1, 0x6FEE, 0x6FDE, 0x6FE0, 0x6FEF, 0x701A, 0x7023, 0x701B, 0x7039, 0x7035, + 0x704F, 0x705E, 0x5B80, 0x5B84, 0x5B95, 0x5B93, 0x5BA5, 0x5BB8, 0x752F, 0x9A9E, 0x6434, 0x5BE4, 0x5BEE, 0x8930, 0x5BF0, 0x8E47, + 0x8B07, 0x8FB6, 0x8FD3, 0x8FD5, 0x8FE5, 0x8FEE, 0x8FE4, 0x8FE9, 0x8FE6, 0x8FF3, 0x8FE8, 0x9005, 0x9004, 0x900B, 0x9026, 0x9011, + 0x900D, 0x9016, 0x9021, 0x9035, 0x9036, 0x902D, 0x902F, 0x9044, 0x9051, 0x9052, 0x9050, 0x9068, 0x9058, 0x9062, 0x905B, 0x66B9, + 0x9074, 0x907D, 0x9082, 0x9088, 0x9083, 0x908B, 0x5F50, 0x5F57, 0x5F56, 0x5F58, 0x5C3B, 0x54AB, 0x5C50, 0x5C59, 0x5B71, 0x5C63, + 0x5C66, 0x7FBC, 0x5F2A, 0x5F29, 0x5F2D, 0x8274, 0x5F3C, 0x9B3B, 0x5C6E, 0x5981, 0x5983, 0x598D, 0x59A9, 0x59AA, 0x59A3, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x5997, 0x59CA, 0x59AB, 0x599E, 0x59A4, 0x59D2, 0x59B2, 0x59AF, 0x59D7, 0x59BE, 0x5A05, 0x5A06, 0x59DD, 0x5A08, 0x59E3, + 0x59D8, 0x59F9, 0x5A0C, 0x5A09, 0x5A32, 0x5A34, 0x5A11, 0x5A23, 0x5A13, 0x5A40, 0x5A67, 0x5A4A, 0x5A55, 0x5A3C, 0x5A62, 0x5A75, + 0x80EC, 0x5AAA, 0x5A9B, 0x5A77, 0x5A7A, 0x5ABE, 0x5AEB, 0x5AB2, 0x5AD2, 0x5AD4, 0x5AB8, 0x5AE0, 0x5AE3, 0x5AF1, 0x5AD6, 0x5AE6, + 0x5AD8, 0x5ADC, 0x5B09, 0x5B17, 0x5B16, 0x5B32, 0x5B37, 0x5B40, 0x5C15, 0x5C1C, 0x5B5A, 0x5B65, 0x5B73, 0x5B51, 0x5B53, 0x5B62, + 0x9A75, 0x9A77, 0x9A78, 0x9A7A, 0x9A7F, 0x9A7D, 0x9A80, 0x9A81, 0x9A85, 0x9A88, 0x9A8A, 0x9A90, 0x9A92, 0x9A93, 0x9A96, 0x9A98, + 0x9A9B, 0x9A9C, 0x9A9D, 0x9A9F, 0x9AA0, 0x9AA2, 0x9AA3, 0x9AA5, 0x9AA7, 0x7E9F, 0x7EA1, 0x7EA3, 0x7EA5, 0x7EA8, 0x7EA9, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x7EAD, 0x7EB0, 0x7EBE, 0x7EC0, 0x7EC1, 0x7EC2, 0x7EC9, 0x7ECB, 0x7ECC, 0x7ED0, 0x7ED4, 0x7ED7, 0x7EDB, 0x7EE0, 0x7EE1, + 0x7EE8, 0x7EEB, 0x7EEE, 0x7EEF, 0x7EF1, 0x7EF2, 0x7F0D, 0x7EF6, 0x7EFA, 0x7EFB, 0x7EFE, 0x7F01, 0x7F02, 0x7F03, 0x7F07, 0x7F08, + 0x7F0B, 0x7F0C, 0x7F0F, 0x7F11, 0x7F12, 0x7F17, 0x7F19, 0x7F1C, 0x7F1B, 0x7F1F, 0x7F21, 0x7F22, 0x7F23, 0x7F24, 0x7F25, 0x7F26, + 0x7F27, 0x7F2A, 0x7F2B, 0x7F2C, 0x7F2D, 0x7F2F, 0x7F30, 0x7F31, 0x7F32, 0x7F33, 0x7F35, 0x5E7A, 0x757F, 0x5DDB, 0x753E, 0x9095, + 0x738E, 0x7391, 0x73AE, 0x73A2, 0x739F, 0x73CF, 0x73C2, 0x73D1, 0x73B7, 0x73B3, 0x73C0, 0x73C9, 0x73C8, 0x73E5, 0x73D9, 0x987C, + 0x740A, 0x73E9, 0x73E7, 0x73DE, 0x73BA, 0x73F2, 0x740F, 0x742A, 0x745B, 0x7426, 0x7425, 0x7428, 0x7430, 0x742E, 0x742C, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x741B, 0x741A, 0x7441, 0x745C, 0x7457, 0x7455, 0x7459, 0x7477, 0x746D, 0x747E, 0x749C, 0x748E, 0x7480, 0x7481, 0x7487, + 0x748B, 0x749E, 0x74A8, 0x74A9, 0x7490, 0x74A7, 0x74D2, 0x74BA, 0x97EA, 0x97EB, 0x97EC, 0x674C, 0x6753, 0x675E, 0x6748, 0x6769, + 0x67A5, 0x6787, 0x676A, 0x6773, 0x6798, 0x67A7, 0x6775, 0x67A8, 0x679E, 0x67AD, 0x678B, 0x6777, 0x677C, 0x67F0, 0x6809, 0x67D8, + 0x680A, 0x67E9, 0x67B0, 0x680C, 0x67D9, 0x67B5, 0x67DA, 0x67B3, 0x67DD, 0x6800, 0x67C3, 0x67B8, 0x67E2, 0x680E, 0x67C1, 0x67FD, + 0x6832, 0x6833, 0x6860, 0x6861, 0x684E, 0x6862, 0x6844, 0x6864, 0x6883, 0x681D, 0x6855, 0x6866, 0x6841, 0x6867, 0x6840, 0x683E, + 0x684A, 0x6849, 0x6829, 0x68B5, 0x688F, 0x6874, 0x6877, 0x6893, 0x686B, 0x68C2, 0x696E, 0x68FC, 0x691F, 0x6920, 0x68F9, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x6924, 0x68F0, 0x690B, 0x6901, 0x6957, 0x68E3, 0x6910, 0x6971, 0x6939, 0x6960, 0x6942, 0x695D, 0x6984, 0x696B, 0x6980, + 0x6998, 0x6978, 0x6934, 0x69CC, 0x6987, 0x6988, 0x69CE, 0x6989, 0x6966, 0x6963, 0x6979, 0x699B, 0x69A7, 0x69BB, 0x69AB, 0x69AD, + 0x69D4, 0x69B1, 0x69C1, 0x69CA, 0x69DF, 0x6995, 0x69E0, 0x698D, 0x69FF, 0x6A2F, 0x69ED, 0x6A17, 0x6A18, 0x6A65, 0x69F2, 0x6A44, + 0x6A3E, 0x6AA0, 0x6A50, 0x6A5B, 0x6A35, 0x6A8E, 0x6A79, 0x6A3D, 0x6A28, 0x6A58, 0x6A7C, 0x6A91, 0x6A90, 0x6AA9, 0x6A97, 0x6AAB, + 0x7337, 0x7352, 0x6B81, 0x6B82, 0x6B87, 0x6B84, 0x6B92, 0x6B93, 0x6B8D, 0x6B9A, 0x6B9B, 0x6BA1, 0x6BAA, 0x8F6B, 0x8F6D, 0x8F71, + 0x8F72, 0x8F73, 0x8F75, 0x8F76, 0x8F78, 0x8F77, 0x8F79, 0x8F7A, 0x8F7C, 0x8F7E, 0x8F81, 0x8F82, 0x8F84, 0x8F87, 0x8F8B, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x8F8D, 0x8F8E, 0x8F8F, 0x8F98, 0x8F9A, 0x8ECE, 0x620B, 0x6217, 0x621B, 0x621F, 0x6222, 0x6221, 0x6225, 0x6224, 0x622C, + 0x81E7, 0x74EF, 0x74F4, 0x74FF, 0x750F, 0x7511, 0x7513, 0x6534, 0x65EE, 0x65EF, 0x65F0, 0x660A, 0x6619, 0x6772, 0x6603, 0x6615, + 0x6600, 0x7085, 0x66F7, 0x661D, 0x6634, 0x6631, 0x6636, 0x6635, 0x8006, 0x665F, 0x6654, 0x6641, 0x664F, 0x6656, 0x6661, 0x6657, + 0x6677, 0x6684, 0x668C, 0x66A7, 0x669D, 0x66BE, 0x66DB, 0x66DC, 0x66E6, 0x66E9, 0x8D32, 0x8D33, 0x8D36, 0x8D3B, 0x8D3D, 0x8D40, + 0x8D45, 0x8D46, 0x8D48, 0x8D49, 0x8D47, 0x8D4D, 0x8D55, 0x8D59, 0x89C7, 0x89CA, 0x89CB, 0x89CC, 0x89CE, 0x89CF, 0x89D0, 0x89D1, + 0x726E, 0x729F, 0x725D, 0x7266, 0x726F, 0x727E, 0x727F, 0x7284, 0x728B, 0x728D, 0x728F, 0x7292, 0x6308, 0x6332, 0x63B0, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x643F, 0x64D8, 0x8004, 0x6BEA, 0x6BF3, 0x6BFD, 0x6BF5, 0x6BF9, 0x6C05, 0x6C07, 0x6C06, 0x6C0D, 0x6C15, 0x6C18, 0x6C19, + 0x6C1A, 0x6C21, 0x6C29, 0x6C24, 0x6C2A, 0x6C32, 0x6535, 0x6555, 0x656B, 0x724D, 0x7252, 0x7256, 0x7230, 0x8662, 0x5216, 0x809F, + 0x809C, 0x8093, 0x80BC, 0x670A, 0x80BD, 0x80B1, 0x80AB, 0x80AD, 0x80B4, 0x80B7, 0x80E7, 0x80E8, 0x80E9, 0x80EA, 0x80DB, 0x80C2, + 0x80C4, 0x80D9, 0x80CD, 0x80D7, 0x6710, 0x80DD, 0x80EB, 0x80F1, 0x80F4, 0x80ED, 0x810D, 0x810E, 0x80F2, 0x80FC, 0x6715, 0x8112, + 0x8C5A, 0x8136, 0x811E, 0x812C, 0x8118, 0x8132, 0x8148, 0x814C, 0x8153, 0x8174, 0x8159, 0x815A, 0x8171, 0x8160, 0x8169, 0x817C, + 0x817D, 0x816D, 0x8167, 0x584D, 0x5AB5, 0x8188, 0x8182, 0x8191, 0x6ED5, 0x81A3, 0x81AA, 0x81CC, 0x6726, 0x81CA, 0x81BB, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x81C1, 0x81A6, 0x6B24, 0x6B37, 0x6B39, 0x6B43, 0x6B46, 0x6B59, 0x98D1, 0x98D2, 0x98D3, 0x98D5, 0x98D9, 0x98DA, 0x6BB3, + 0x5F40, 0x6BC2, 0x89F3, 0x6590, 0x9F51, 0x6593, 0x65BC, 0x65C6, 0x65C4, 0x65C3, 0x65CC, 0x65CE, 0x65D2, 0x65D6, 0x7080, 0x709C, + 0x7096, 0x709D, 0x70BB, 0x70C0, 0x70B7, 0x70AB, 0x70B1, 0x70E8, 0x70CA, 0x7110, 0x7113, 0x7116, 0x712F, 0x7131, 0x7173, 0x715C, + 0x7168, 0x7145, 0x7172, 0x714A, 0x7178, 0x717A, 0x7198, 0x71B3, 0x71B5, 0x71A8, 0x71A0, 0x71E0, 0x71D4, 0x71E7, 0x71F9, 0x721D, + 0x7228, 0x706C, 0x7118, 0x7166, 0x71B9, 0x623E, 0x623D, 0x6243, 0x6248, 0x6249, 0x793B, 0x7940, 0x7946, 0x7949, 0x795B, 0x795C, + 0x7953, 0x795A, 0x7962, 0x7957, 0x7960, 0x796F, 0x7967, 0x797A, 0x7985, 0x798A, 0x799A, 0x79A7, 0x79B3, 0x5FD1, 0x5FD0, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x603C, 0x605D, 0x605A, 0x6067, 0x6041, 0x6059, 0x6063, 0x60AB, 0x6106, 0x610D, 0x615D, 0x61A9, 0x619D, 0x61CB, 0x61D1, + 0x6206, 0x8080, 0x807F, 0x6C93, 0x6CF6, 0x6DFC, 0x77F6, 0x77F8, 0x7800, 0x7809, 0x7817, 0x7818, 0x7811, 0x65AB, 0x782D, 0x781C, + 0x781D, 0x7839, 0x783A, 0x783B, 0x781F, 0x783C, 0x7825, 0x782C, 0x7823, 0x7829, 0x784E, 0x786D, 0x7856, 0x7857, 0x7826, 0x7850, + 0x7847, 0x784C, 0x786A, 0x789B, 0x7893, 0x789A, 0x7887, 0x789C, 0x78A1, 0x78A3, 0x78B2, 0x78B9, 0x78A5, 0x78D4, 0x78D9, 0x78C9, + 0x78EC, 0x78F2, 0x7905, 0x78F4, 0x7913, 0x7924, 0x791E, 0x7934, 0x9F9B, 0x9EF9, 0x9EFB, 0x9EFC, 0x76F1, 0x7704, 0x770D, 0x76F9, + 0x7707, 0x7708, 0x771A, 0x7722, 0x7719, 0x772D, 0x7726, 0x7735, 0x7738, 0x7750, 0x7751, 0x7747, 0x7743, 0x775A, 0x7768, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x7762, 0x7765, 0x777F, 0x778D, 0x777D, 0x7780, 0x778C, 0x7791, 0x779F, 0x77A0, 0x77B0, 0x77B5, 0x77BD, 0x753A, 0x7540, + 0x754E, 0x754B, 0x7548, 0x755B, 0x7572, 0x7579, 0x7583, 0x7F58, 0x7F61, 0x7F5F, 0x8A48, 0x7F68, 0x7F74, 0x7F71, 0x7F79, 0x7F81, + 0x7F7E, 0x76CD, 0x76E5, 0x8832, 0x9485, 0x9486, 0x9487, 0x948B, 0x948A, 0x948C, 0x948D, 0x948F, 0x9490, 0x9494, 0x9497, 0x9495, + 0x949A, 0x949B, 0x949C, 0x94A3, 0x94A4, 0x94AB, 0x94AA, 0x94AD, 0x94AC, 0x94AF, 0x94B0, 0x94B2, 0x94B4, 0x94B6, 0x94B7, 0x94B8, + 0x94B9, 0x94BA, 0x94BC, 0x94BD, 0x94BF, 0x94C4, 0x94C8, 0x94C9, 0x94CA, 0x94CB, 0x94CC, 0x94CD, 0x94CE, 0x94D0, 0x94D1, 0x94D2, + 0x94D5, 0x94D6, 0x94D7, 0x94D9, 0x94D8, 0x94DB, 0x94DE, 0x94DF, 0x94E0, 0x94E2, 0x94E4, 0x94E5, 0x94E7, 0x94E8, 0x94EA, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x94E9, 0x94EB, 0x94EE, 0x94EF, 0x94F3, 0x94F4, 0x94F5, 0x94F7, 0x94F9, 0x94FC, 0x94FD, 0x94FF, 0x9503, 0x9502, 0x9506, + 0x9507, 0x9509, 0x950A, 0x950D, 0x950E, 0x950F, 0x9512, 0x9513, 0x9514, 0x9515, 0x9516, 0x9518, 0x951B, 0x951D, 0x951E, 0x951F, + 0x9522, 0x952A, 0x952B, 0x9529, 0x952C, 0x9531, 0x9532, 0x9534, 0x9536, 0x9537, 0x9538, 0x953C, 0x953E, 0x953F, 0x9542, 0x9535, + 0x9544, 0x9545, 0x9546, 0x9549, 0x954C, 0x954E, 0x954F, 0x9552, 0x9553, 0x9554, 0x9556, 0x9557, 0x9558, 0x9559, 0x955B, 0x955E, + 0x955F, 0x955D, 0x9561, 0x9562, 0x9564, 0x9565, 0x9566, 0x9567, 0x9568, 0x9569, 0x956A, 0x956B, 0x956C, 0x956F, 0x9571, 0x9572, + 0x9573, 0x953A, 0x77E7, 0x77EC, 0x96C9, 0x79D5, 0x79ED, 0x79E3, 0x79EB, 0x7A06, 0x5D47, 0x7A03, 0x7A02, 0x7A1E, 0x7A14, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x7A39, 0x7A37, 0x7A51, 0x9ECF, 0x99A5, 0x7A70, 0x7688, 0x768E, 0x7693, 0x7699, 0x76A4, 0x74DE, 0x74E0, 0x752C, 0x9E20, + 0x9E22, 0x9E28, 0x9E29, 0x9E2A, 0x9E2B, 0x9E2C, 0x9E32, 0x9E31, 0x9E36, 0x9E38, 0x9E37, 0x9E39, 0x9E3A, 0x9E3E, 0x9E41, 0x9E42, + 0x9E44, 0x9E46, 0x9E47, 0x9E48, 0x9E49, 0x9E4B, 0x9E4C, 0x9E4E, 0x9E51, 0x9E55, 0x9E57, 0x9E5A, 0x9E5B, 0x9E5C, 0x9E5E, 0x9E63, + 0x9E66, 0x9E67, 0x9E68, 0x9E69, 0x9E6A, 0x9E6B, 0x9E6C, 0x9E71, 0x9E6D, 0x9E73, 0x7592, 0x7594, 0x7596, 0x75A0, 0x759D, 0x75AC, + 0x75A3, 0x75B3, 0x75B4, 0x75B8, 0x75C4, 0x75B1, 0x75B0, 0x75C3, 0x75C2, 0x75D6, 0x75CD, 0x75E3, 0x75E8, 0x75E6, 0x75E4, 0x75EB, + 0x75E7, 0x7603, 0x75F1, 0x75FC, 0x75FF, 0x7610, 0x7600, 0x7605, 0x760C, 0x7617, 0x760A, 0x7625, 0x7618, 0x7615, 0x7619, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x761B, 0x763C, 0x7622, 0x7620, 0x7640, 0x762D, 0x7630, 0x763F, 0x7635, 0x7643, 0x763E, 0x7633, 0x764D, 0x765E, 0x7654, + 0x765C, 0x7656, 0x766B, 0x766F, 0x7FCA, 0x7AE6, 0x7A78, 0x7A79, 0x7A80, 0x7A86, 0x7A88, 0x7A95, 0x7AA6, 0x7AA0, 0x7AAC, 0x7AA8, + 0x7AAD, 0x7AB3, 0x8864, 0x8869, 0x8872, 0x887D, 0x887F, 0x8882, 0x88A2, 0x88C6, 0x88B7, 0x88BC, 0x88C9, 0x88E2, 0x88CE, 0x88E3, + 0x88E5, 0x88F1, 0x891A, 0x88FC, 0x88E8, 0x88FE, 0x88F0, 0x8921, 0x8919, 0x8913, 0x891B, 0x890A, 0x8934, 0x892B, 0x8936, 0x8941, + 0x8966, 0x897B, 0x758B, 0x80E5, 0x76B2, 0x76B4, 0x77DC, 0x8012, 0x8014, 0x8016, 0x801C, 0x8020, 0x8022, 0x8025, 0x8026, 0x8027, + 0x8029, 0x8028, 0x8031, 0x800B, 0x8035, 0x8043, 0x8046, 0x804D, 0x8052, 0x8069, 0x8071, 0x8983, 0x9878, 0x9880, 0x9883, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x9889, 0x988C, 0x988D, 0x988F, 0x9894, 0x989A, 0x989B, 0x989E, 0x989F, 0x98A1, 0x98A2, 0x98A5, 0x98A6, 0x864D, 0x8654, + 0x866C, 0x866E, 0x867F, 0x867A, 0x867C, 0x867B, 0x86A8, 0x868D, 0x868B, 0x86AC, 0x869D, 0x86A7, 0x86A3, 0x86AA, 0x8693, 0x86A9, + 0x86B6, 0x86C4, 0x86B5, 0x86CE, 0x86B0, 0x86BA, 0x86B1, 0x86AF, 0x86C9, 0x86CF, 0x86B4, 0x86E9, 0x86F1, 0x86F2, 0x86ED, 0x86F3, + 0x86D0, 0x8713, 0x86DE, 0x86F4, 0x86DF, 0x86D8, 0x86D1, 0x8703, 0x8707, 0x86F8, 0x8708, 0x870A, 0x870D, 0x8709, 0x8723, 0x873B, + 0x871E, 0x8725, 0x872E, 0x871A, 0x873E, 0x8748, 0x8734, 0x8731, 0x8729, 0x8737, 0x873F, 0x8782, 0x8722, 0x877D, 0x877E, 0x877B, + 0x8760, 0x8770, 0x874C, 0x876E, 0x878B, 0x8753, 0x8763, 0x877C, 0x8764, 0x8759, 0x8765, 0x8793, 0x87AF, 0x87A8, 0x87D2, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x87C6, 0x8788, 0x8785, 0x87AD, 0x8797, 0x8783, 0x87AB, 0x87E5, 0x87AC, 0x87B5, 0x87B3, 0x87CB, 0x87D3, 0x87BD, 0x87D1, + 0x87C0, 0x87CA, 0x87DB, 0x87EA, 0x87E0, 0x87EE, 0x8816, 0x8813, 0x87FE, 0x880A, 0x881B, 0x8821, 0x8839, 0x883C, 0x7F36, 0x7F42, + 0x7F44, 0x7F45, 0x8210, 0x7AFA, 0x7AFD, 0x7B08, 0x7B03, 0x7B04, 0x7B15, 0x7B0A, 0x7B2B, 0x7B0F, 0x7B47, 0x7B38, 0x7B2A, 0x7B19, + 0x7B2E, 0x7B31, 0x7B20, 0x7B25, 0x7B24, 0x7B33, 0x7B3E, 0x7B1E, 0x7B58, 0x7B5A, 0x7B45, 0x7B75, 0x7B4C, 0x7B5D, 0x7B60, 0x7B6E, + 0x7B7B, 0x7B62, 0x7B72, 0x7B71, 0x7B90, 0x7BA6, 0x7BA7, 0x7BB8, 0x7BAC, 0x7B9D, 0x7BA8, 0x7B85, 0x7BAA, 0x7B9C, 0x7BA2, 0x7BAB, + 0x7BB4, 0x7BD1, 0x7BC1, 0x7BCC, 0x7BDD, 0x7BDA, 0x7BE5, 0x7BE6, 0x7BEA, 0x7C0C, 0x7BFE, 0x7BFC, 0x7C0F, 0x7C16, 0x7C0B, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x7C1F, 0x7C2A, 0x7C26, 0x7C38, 0x7C41, 0x7C40, 0x81FE, 0x8201, 0x8202, 0x8204, 0x81EC, 0x8844, 0x8221, 0x8222, 0x8223, + 0x822D, 0x822F, 0x8228, 0x822B, 0x8238, 0x823B, 0x8233, 0x8234, 0x823E, 0x8244, 0x8249, 0x824B, 0x824F, 0x825A, 0x825F, 0x8268, + 0x887E, 0x8885, 0x8888, 0x88D8, 0x88DF, 0x895E, 0x7F9D, 0x7F9F, 0x7FA7, 0x7FAF, 0x7FB0, 0x7FB2, 0x7C7C, 0x6549, 0x7C91, 0x7C9D, + 0x7C9C, 0x7C9E, 0x7CA2, 0x7CB2, 0x7CBC, 0x7CBD, 0x7CC1, 0x7CC7, 0x7CCC, 0x7CCD, 0x7CC8, 0x7CC5, 0x7CD7, 0x7CE8, 0x826E, 0x66A8, + 0x7FBF, 0x7FCE, 0x7FD5, 0x7FE5, 0x7FE1, 0x7FE6, 0x7FE9, 0x7FEE, 0x7FF3, 0x7CF8, 0x7D77, 0x7DA6, 0x7DAE, 0x7E47, 0x7E9B, 0x9EB8, + 0x9EB4, 0x8D73, 0x8D84, 0x8D94, 0x8D91, 0x8DB1, 0x8D67, 0x8D6D, 0x8C47, 0x8C49, 0x914A, 0x9150, 0x914E, 0x914F, 0x9164, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x9162, 0x9161, 0x9170, 0x9169, 0x916F, 0x917D, 0x917E, 0x9172, 0x9174, 0x9179, 0x918C, 0x9185, 0x9190, 0x918D, 0x9191, + 0x91A2, 0x91A3, 0x91AA, 0x91AD, 0x91AE, 0x91AF, 0x91B5, 0x91B4, 0x91BA, 0x8C55, 0x9E7E, 0x8DB8, 0x8DEB, 0x8E05, 0x8E59, 0x8E69, + 0x8DB5, 0x8DBF, 0x8DBC, 0x8DBA, 0x8DC4, 0x8DD6, 0x8DD7, 0x8DDA, 0x8DDE, 0x8DCE, 0x8DCF, 0x8DDB, 0x8DC6, 0x8DEC, 0x8DF7, 0x8DF8, + 0x8DE3, 0x8DF9, 0x8DFB, 0x8DE4, 0x8E09, 0x8DFD, 0x8E14, 0x8E1D, 0x8E1F, 0x8E2C, 0x8E2E, 0x8E23, 0x8E2F, 0x8E3A, 0x8E40, 0x8E39, + 0x8E35, 0x8E3D, 0x8E31, 0x8E49, 0x8E41, 0x8E42, 0x8E51, 0x8E52, 0x8E4A, 0x8E70, 0x8E76, 0x8E7C, 0x8E6F, 0x8E74, 0x8E85, 0x8E8F, + 0x8E94, 0x8E90, 0x8E9C, 0x8E9E, 0x8C78, 0x8C82, 0x8C8A, 0x8C85, 0x8C98, 0x8C94, 0x659B, 0x89D6, 0x89DE, 0x89DA, 0x89DC, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x89E5, 0x89EB, 0x89EF, 0x8A3E, 0x8B26, 0x9753, 0x96E9, 0x96F3, 0x96EF, 0x9706, 0x9701, 0x9708, 0x970F, 0x970E, 0x972A, + 0x972D, 0x9730, 0x973E, 0x9F80, 0x9F83, 0x9F85, 0x9F86, 0x9F87, 0x9F88, 0x9F89, 0x9F8A, 0x9F8C, 0x9EFE, 0x9F0B, 0x9F0D, 0x96B9, + 0x96BC, 0x96BD, 0x96CE, 0x96D2, 0x77BF, 0x96E0, 0x928E, 0x92AE, 0x92C8, 0x933E, 0x936A, 0x93CA, 0x938F, 0x943E, 0x946B, 0x9C7F, + 0x9C82, 0x9C85, 0x9C86, 0x9C87, 0x9C88, 0x7A23, 0x9C8B, 0x9C8E, 0x9C90, 0x9C91, 0x9C92, 0x9C94, 0x9C95, 0x9C9A, 0x9C9B, 0x9C9E, + 0x9C9F, 0x9CA0, 0x9CA1, 0x9CA2, 0x9CA3, 0x9CA5, 0x9CA6, 0x9CA7, 0x9CA8, 0x9CA9, 0x9CAB, 0x9CAD, 0x9CAE, 0x9CB0, 0x9CB1, 0x9CB2, + 0x9CB3, 0x9CB4, 0x9CB5, 0x9CB6, 0x9CB7, 0x9CBA, 0x9CBB, 0x9CBC, 0x9CBD, 0x9CC4, 0x9CC5, 0x9CC6, 0x9CC7, 0x9CCA, 0x9CCB, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x9CCC, 0x9CCD, 0x9CCE, 0x9CCF, 0x9CD0, 0x9CD3, 0x9CD4, 0x9CD5, 0x9CD7, 0x9CD8, 0x9CD9, 0x9CDC, 0x9CDD, 0x9CDF, 0x9CE2, + 0x977C, 0x9785, 0x9791, 0x9792, 0x9794, 0x97AF, 0x97AB, 0x97A3, 0x97B2, 0x97B4, 0x9AB1, 0x9AB0, 0x9AB7, 0x9E58, 0x9AB6, 0x9ABA, + 0x9ABC, 0x9AC1, 0x9AC0, 0x9AC5, 0x9AC2, 0x9ACB, 0x9ACC, 0x9AD1, 0x9B45, 0x9B43, 0x9B47, 0x9B49, 0x9B48, 0x9B4D, 0x9B51, 0x98E8, + 0x990D, 0x992E, 0x9955, 0x9954, 0x9ADF, 0x9AE1, 0x9AE6, 0x9AEF, 0x9AEB, 0x9AFB, 0x9AED, 0x9AF9, 0x9B08, 0x9B0F, 0x9B13, 0x9B1F, + 0x9B23, 0x9EBD, 0x9EBE, 0x7E3B, 0x9E82, 0x9E87, 0x9E88, 0x9E8B, 0x9E92, 0x93D6, 0x9E9D, 0x9E9F, 0x9EDB, 0x9EDC, 0x9EDD, 0x9EE0, + 0x9EDF, 0x9EE2, 0x9EE9, 0x9EE7, 0x9EE5, 0x9EEA, 0x9EEF, 0x9F22, 0x9F2C, 0x9F2F, 0x9F39, 0x9F37, 0x9F3D, 0x9F3E, 0x9F44, +}; +#endif + // Two Char Mapping ( many polish services and UPC Direct/HBO services) // get from http://mitglied.lycos.de/buran/charsets/videotex-suppl.html //static inline unsigned int doVideoTexSuppl(int c1, int c2) @@ -620,6 +2019,9 @@ std::string convertDVBUTF8(const char *data, int len, int table, int tsidonid) { int newtable = 0; bool twochar = false; +#ifdef BOXMODEL_APOLLO + bool gb2312 = false; +#endif if (!len) return ""; @@ -667,7 +2069,10 @@ std::string convertDVBUTF8(const char *data, int len, int table, int tsidonid) break; case 0x13: ++i; - {} //eDebug("unsup. GB-2312-1980 enc."); +#ifdef BOXMODEL_APOLLO + //printf("GB-2312-1980 enc.\n"); + gb2312 = true; +#endif break; case 0x14: ++i; @@ -707,6 +2112,16 @@ std::string convertDVBUTF8(const char *data, int len, int table, int tsidonid) //dprintf("recode:::: doVideoTexSuppl code %lX\n", code); } +#ifdef BOXMODEL_APOLLO + // GB2312 -> Unicode + if (gb2312 && !code) { + if (data[i] >= 0xA1) { + code = cGB2312UNI[((data[i] << 8) | data[i + 1]) - 0xA100]; + i += 2; + } + } +#endif + if (!code) { if (table == 65) { // unicode if (i+1 < len) { diff --git a/src/eitd/sectionsd.cpp b/src/eitd/sectionsd.cpp index 0e00656e3..c9e379b8c 100644 --- a/src/eitd/sectionsd.cpp +++ b/src/eitd/sectionsd.cpp @@ -486,7 +486,7 @@ xprintf("addEvent: ch %012" PRIx64 " running %d (%s) got_CN %d\n", evt.get_chann #else time_t now = time(NULL); bool back = false; - if ((*lastEvent)->times.size() == 1) + if (*lastEvent!=NULL && (*lastEvent)->times.size() == 1) { if ((*lastEvent)->times.begin()->startzeit + (long)(*lastEvent)->times.begin()->dauer >= now - oldEventsAre) back = true; @@ -508,7 +508,8 @@ xprintf("addEvent: ch %012" PRIx64 " running %d (%s) got_CN %d\n", evt.get_chann unlockMessaging(); } // else fprintf(stderr, ">"); - deleteEvent((*lastEvent)->uniqueKey()); + if(*lastEvent!=NULL) + deleteEvent((*lastEvent)->uniqueKey()); } // Pruefen ob es ein Meta-Event ist MySIeventUniqueKeysMetaOrderServiceUniqueKey::iterator i = mySIeventUniqueKeysMetaOrderServiceUniqueKey.find(e->get_channel_id()); @@ -899,9 +900,19 @@ static void commandserviceChanged(int connfd, char *data, const unsigned dataLen if (dataLength != sizeof(sectionsd::commandSetServiceChanged)) return; - t_channel_id uniqueServiceKey = (((sectionsd::commandSetServiceChanged *)data)->channel_id); + sectionsd::commandSetServiceChanged * cmd = (sectionsd::commandSetServiceChanged *)data; + t_channel_id uniqueServiceKey = cmd->channel_id; - xprintf("[sectionsd] commandserviceChanged: Service change to " PRINTF_CHANNEL_ID_TYPE "\n", uniqueServiceKey); + xprintf("[sectionsd] commandserviceChanged: Service change to " PRINTF_CHANNEL_ID_TYPE " demux #%d\n", uniqueServiceKey, cmd->dnum); + /* assume live demux always 0, other means background scan */ + if (cmd->dnum) { + /* dont wakeup EIT, if we have max events allready */ + if (max_events && (mySIeventsOrderUniqueKey.size() < max_events)) { + threadEIT.setDemux(cmd->dnum); + threadEIT.setCurrentService(uniqueServiceKey); + } + return; + } static t_channel_id time_trigger_last = 0; @@ -929,7 +940,8 @@ static void commandserviceChanged(int connfd, char *data, const unsigned dataLen unlockMessaging(); threadCN.setCurrentService(messaging_current_servicekey); - threadEIT.setCurrentService(messaging_current_servicekey); + threadEIT.setDemux(cmd->dnum); + threadEIT.setCurrentService(uniqueServiceKey /*messaging_current_servicekey*/); #ifdef ENABLE_FREESATEPG threadFSEIT.setCurrentService(messaging_current_servicekey); #endif @@ -1701,6 +1713,10 @@ void CEitThread::beforeSleep() writeLockMessaging(); messaging_zap_detected = false; unlockMessaging(); + eventServer->sendEvent(CSectionsdClient::EVT_EIT_COMPLETE, + CEventServer::INITID_SECTIONSD, + ¤t_service, + sizeof(messaging_current_servicekey)); if(notify_complete) system(CONFIGDIR "/epgdone.sh"); } @@ -2273,27 +2289,23 @@ void CEitManager::getEventsServiceKey(t_channel_id serviceUniqueKey, CChannelEve bool copy = true; if(search){ - if((search == 1) || (search == 5)) {//SEARCH_EPG_TITLE == 1 SEARCH_EPG_ALL == 5 defined in eventlist.h + if ((search == 1 /*EventList::SEARCH_EPG_TITLE*/) || (search == 5 /*EventList::SEARCH_EPG_ALL*/)) + { std::string eName = (*e)->getName(); std::transform(eName.begin(), eName.end(), eName.begin(), tolower); - if(eName.find(search_text) == std::string::npos) - copy = false; + copy = (eName.find(search_text) != std::string::npos); } - if((search == 2) || (!copy && search == 5)) {//SEARCH_EPG_INFO1 == 2 + if ((search == 2 /*EventList::SEARCH_EPG_INFO1*/) || (!copy && (search == 5 /*EventList::SEARCH_EPG_ALL*/))) + { std::string eText = (*e)->getText(); std::transform(eText.begin(), eText.end(), eText.begin(), tolower); - if(eText.find(search_text) == std::string::npos) - copy = false; - else if(search == 5) - copy = true; + copy = (eText.find(search_text) != std::string::npos); } - if((search == 3) || (!copy && search == 5)) {//SEARCH_EPG_INFO2 == 3 + if ((search == 3 /*EventList::SEARCH_EPG_INFO2*/) || (!copy && (search == 5 /*EventList::SEARCH_EPG_ALL*/))) + { std::string eExtendedText = (*e)->getExtendedText(); std::transform(eExtendedText.begin(), eExtendedText.end(), eExtendedText.begin(), tolower); - if(eExtendedText.find(search_text) == std::string::npos) - copy = false; - else if(search == 5) - copy = true; + copy = (eExtendedText.find(search_text) != std::string::npos); } } if(copy) { diff --git a/src/global.h b/src/global.h index af6d5ea91..5f7c0858b 100644 --- a/src/global.h +++ b/src/global.h @@ -73,6 +73,7 @@ #define NEUTRINO_LEAVE_DEEPSTANDBY_SCRIPT CONFIGDIR "/deepstandby.off" #define MOVIEPLAYER_START_SCRIPT CONFIGDIR "/movieplayer.start" #define MOVIEPLAYER_END_SCRIPT CONFIGDIR "/movieplayer.end" +#define NEUTRINO_ENTER_FLASH_SCRIPT CONFIGDIR "/flash.start" #define NEUTRINO_SCAN_SETTINGS_FILE CONFIGDIR "/scan.conf" #define NEUTRINO_PARENTALLOCKED_FILE DATADIR "/neutrino/.plocked" @@ -102,4 +103,8 @@ NEUTRINO_CPP CLocaleManager *g_Locale; NEUTRINO_CPP CVideoSettings *g_videoSettings; NEUTRINO_CPP CRadioText *g_Radiotext; +#ifndef DISABLE_GUI_MOUNT +#define ENABLE_GUI_MOUNT +#endif + #endif /* __neutrino_global_h__ */ diff --git a/src/gui/Makefile.am b/src/gui/Makefile.am index 5a4e8578a..0f510d108 100644 --- a/src/gui/Makefile.am +++ b/src/gui/Makefile.am @@ -1,23 +1,17 @@ AM_CPPFLAGS = -fno-rtti -fno-exceptions -D__STDC_FORMAT_MACROS #AM_CPPFLAGS = -fno-rtti -BUILT_SOURCES = git_version.h -git_version.h: +BUILT_SOURCES = version.h +version.h: + @rm -f $@; \ + echo '#define BUILT_DATE "'`date`'"' > $@ @if test -d $(top_srcdir)/.git ; then \ pushd $(top_srcdir) ; \ - GITDESCRIBE=$$(git describe --always --dirty || echo `date`) ; \ + GITDESCRIBE=$$(git describe --always --dirty || echo 'VCS failed') ; \ popd ; \ - echo "#define GITVERSION \"$${GITDESCRIBE}\" " > git_version.h.tmp ; \ - if diff -q git_version.h git_version.h.tmp >/dev/null 2>&1 ; then \ - rm -f git_version.h.tmp ; \ - else \ - rm -f git_version.h ; \ - mv git_version.h.tmp git_version.h ; \ - fi; \ - else \ - rm -f git_version.h; \ - echo '#define BUILT_DATE "'`date`'"' > git_version.h ; \ + echo '#define VCS "'$${GITDESCRIBE}'"' >> $@ ; \ fi -noinst_HEADERS = git_version.h +noinst_HEADERS = version.h +.PHONY: version.h SUBDIRS = bedit components widget @@ -87,6 +81,7 @@ libneutrino_gui_a_SOURCES = \ personalize.cpp \ pictureviewer.cpp \ pictureviewer_setup.cpp \ + pipsetup.cpp \ pluginlist.cpp \ plugins.cpp \ proxyserver_setup.cpp \ @@ -111,7 +106,6 @@ libneutrino_gui_a_SOURCES = \ vfd_setup.cpp \ videosettings.cpp \ volumebar.cpp \ - pipsetup.cpp \ zapit_setup.cpp if ENABLE_EXTUPDATE diff --git a/src/gui/audio_select.cpp b/src/gui/audio_select.cpp index cabf99de6..c2a5f4a3c 100644 --- a/src/gui/audio_select.cpp +++ b/src/gui/audio_select.cpp @@ -179,8 +179,11 @@ int CAudioSelectMenuHandler::doMenu () } } - if(sep_added) - AudioSelector.addItem(new CMenuForwarder(LOCALE_SUBTITLES_STOP, true, NULL, &SubtitleChanger, "off", CRCInput::RC_stop)); + if(sep_added) { + CMenuForwarder * item = new CMenuForwarder(LOCALE_SUBTITLES_STOP, true, NULL, &SubtitleChanger, "off", CRCInput::RC_stop); + item->setItemButton(NEUTRINO_ICON_BUTTON_STOP, false); + AudioSelector.addItem(item); + } } AudioSelector.addItem(new CMenuSeparator(CMenuSeparator::LINE | CMenuSeparator::STRING, LOCALE_AUDIOMENU_VOLUME_ADJUST)); diff --git a/src/gui/audio_setup.cpp b/src/gui/audio_setup.cpp index 080041cf6..1e4748f55 100644 --- a/src/gui/audio_setup.cpp +++ b/src/gui/audio_setup.cpp @@ -87,11 +87,18 @@ const CMenuOptionChooser::keyval AUDIOMENU_ANALOGOUT_OPTIONS[AUDIOMENU_ANALOGOUT { 2, LOCALE_AUDIOMENU_MONORIGHT } }; +#ifdef BOXMODEL_APOLLO +#define AUDIOMENU_SRS_OPTION_COUNT 3 +#else #define AUDIOMENU_SRS_OPTION_COUNT 2 +#endif const CMenuOptionChooser::keyval AUDIOMENU_SRS_OPTIONS[AUDIOMENU_SRS_OPTION_COUNT] = { { 0 , LOCALE_AUDIO_SRS_ALGO_LIGHT }, - { 1 , LOCALE_AUDIO_SRS_ALGO_NORMAL } + { 1 , LOCALE_AUDIO_SRS_ALGO_NORMAL }, +#ifdef BOXMODEL_APOLLO + { 2 , LOCALE_AUDIO_SRS_ALGO_HEAVY } +#endif }; #define AUDIOMENU_AVSYNC_OPTION_COUNT 3 diff --git a/src/gui/audiomute.h b/src/gui/audiomute.h index 406483f18..2c2310c0e 100644 --- a/src/gui/audiomute.h +++ b/src/gui/audiomute.h @@ -27,7 +27,7 @@ #ifndef __CAUDIOMUTE__ #define __CAUDIOMUTE__ -#include +#include class CAudioMute : public CComponentsPicture { diff --git a/src/gui/audioplayer.cpp b/src/gui/audioplayer.cpp index ff513bcd6..a9b13d291 100644 --- a/src/gui/audioplayer.cpp +++ b/src/gui/audioplayer.cpp @@ -54,11 +54,11 @@ #include #include -#define ENABLE_GUI_MOUNT #ifdef ENABLE_GUI_MOUNT #include #endif +#include #include #include #include @@ -1647,40 +1647,22 @@ void CAudioPlayerGui::paintHead() if (!m_show_playlist || m_screensaver) return; - int c_rad_mid = RADIUS_MID; - std::string strCaption; + CComponentsHeader header(m_x, m_y + m_title_height, m_width, m_theight, LOCALE_AUDIOPLAYER_HEAD, NEUTRINO_ICON_MP3); + header.setCornerRadius(RADIUS_MID); + if (m_inetmode) - strCaption = g_Locale->getText(LOCALE_INETRADIO_NAME); - else - strCaption = g_Locale->getText(LOCALE_AUDIOPLAYER_HEAD); + header.setCaption(LOCALE_INETRADIO_NAME); - m_frameBuffer->paintBoxRel(m_x, m_y + m_title_height, m_width, m_theight, COL_MENUHEAD_PLUS_0, c_rad_mid, CORNER_TOP); - - //m_frameBuffer->paintIcon(NEUTRINO_ICON_MP3,m_x + 7, m_y + m_title_height + 10); - int iw, ih; - m_frameBuffer->getIconSize(NEUTRINO_ICON_MP3, &iw, &ih); - m_frameBuffer->paintIcon(NEUTRINO_ICON_MP3, m_x + 10, m_y + m_title_height, m_theight); - g_Font[SNeutrinoSettings::FONT_TYPE_MENU_TITLE]->RenderString(m_x + 20 + iw, m_y + m_theight + m_title_height + 0, - m_width - 20 - iw, strCaption, COL_MENUHEAD, 0, true); // UTF-8 - int ypos = m_y + m_title_height; - //if (m_theight > 26) - // ypos = (m_theight - 26) / 2 + m_y + m_title_height; - int xpos = m_x + m_width - 10; + if (CNeutrinoApp::getInstance()->isMuted()) + header.addButtonIcon(NEUTRINO_ICON_BUTTON_MUTE_SMALL); #ifdef ENABLE_GUI_MOUNT - if (!m_inetmode) { - m_frameBuffer->getIconSize(NEUTRINO_ICON_BUTTON_MENU, &iw, &ih); - m_frameBuffer->paintIcon(NEUTRINO_ICON_BUTTON_MENU, xpos - iw, ypos, m_theight); - xpos -= (iw + 10); - } - //m_frameBuffer->paintIcon(NEUTRINO_ICON_BUTTON_MENU, m_x + m_width - 30, ypos); + if (!m_inetmode) + header.addButtonIcon(NEUTRINO_ICON_BUTTON_MENU); #endif - if ( CNeutrinoApp::getInstance()->isMuted() ) - { - m_frameBuffer->getIconSize(NEUTRINO_ICON_BUTTON_MUTE, &iw, &ih); - m_frameBuffer->paintIcon(NEUTRINO_ICON_BUTTON_MUTE, xpos - iw, ypos, m_theight); - } - m_frameBuffer->blit(); + + header.paint(CC_SAVE_SCREEN_NO); + //m_frameBuffer->blit(); // ?? } //------------------------------------------------------------------------ @@ -1949,6 +1931,7 @@ void CAudioPlayerGui::paintItemID3DetailsLine (int pos) ibox = new CComponentsInfoBox(m_x, ypos2, m_width, m_info_height); ibox->setCornerRadius(RADIUS_LARGE); ibox->setYPos(ypos2); + ibox->setColorBody(COL_MENUCONTENTDARK_PLUS_0); ibox->paint(false); g_Font[SNeutrinoSettings::FONT_TYPE_MENU]->RenderString(m_x + 10, ypos2 + 2 + 1*m_fheight, m_width- 80, diff --git a/src/gui/bedit/bouqueteditor_bouquets.cpp b/src/gui/bedit/bouqueteditor_bouquets.cpp index 52c2d6e44..537576955 100644 --- a/src/gui/bedit/bouqueteditor_bouquets.cpp +++ b/src/gui/bedit/bouqueteditor_bouquets.cpp @@ -40,6 +40,7 @@ #include #include +#include #include #include #include @@ -130,34 +131,26 @@ void CBEBouquetWidget::paint() void CBEBouquetWidget::paintHead() { - frameBuffer->paintBoxRel(x,y, width,theight+0, COL_MENUHEAD_PLUS_0, RADIUS_LARGE, CORNER_TOP); - g_Font[SNeutrinoSettings::FONT_TYPE_MENU_TITLE]->RenderString(x+10,y+theight+0, width, g_Locale->getText(LOCALE_BOUQUETLIST_HEAD), COL_MENUHEAD, 0, true); // UTF-8 + CComponentsHeader header(x, y, width, theight, LOCALE_BOUQUETLIST_HEAD, NULL /*no header icon*/, CComponentsHeader::CC_BTN_MENU); + header.paint(CC_SAVE_SCREEN_NO); } -const struct button_label CBEBouquetWidgetButtons[3] = +const struct button_label CBEBouquetWidgetButtons[4] = { { NEUTRINO_ICON_BUTTON_RED , LOCALE_BOUQUETEDITOR_DELETE }, { NEUTRINO_ICON_BUTTON_GREEN , LOCALE_BOUQUETEDITOR_ADD }, - { NEUTRINO_ICON_BUTTON_YELLOW, LOCALE_BOUQUETEDITOR_MOVE } + { NEUTRINO_ICON_BUTTON_YELLOW, LOCALE_BOUQUETEDITOR_MOVE }, + { NEUTRINO_ICON_BUTTON_BLUE , NONEXISTANT_LOCALE /*dummy*/} }; void CBEBouquetWidget::paintFoot() { - int icol_w, icol_h, h2; - struct button_label Button[5]; + struct button_label Button[4]; Button[0] = CBEBouquetWidgetButtons[0]; Button[1] = CBEBouquetWidgetButtons[1]; Button[2] = CBEBouquetWidgetButtons[2]; - Button[3].button = NEUTRINO_ICON_BUTTON_BLUE; - -/* I have a more elegant solution in buttons.cpp - const neutrino_locale_t button_ids[] = {LOCALE_BOUQUETEDITOR_RENAME,LOCALE_BOUQUETEDITOR_HIDE,LOCALE_BOUQUETEDITOR_LOCK}; - const std::vector buttonID_rest (button_ids, button_ids + sizeof(button_ids) / sizeof(neutrino_locale_t) ); -*/ - - frameBuffer->getIconSize(NEUTRINO_ICON_BUTTON_RED, &icol_w, &icol_h); - frameBuffer->getIconSize(NEUTRINO_ICON_BUTTON_MENU, &icol_w, &h2); + Button[3] = CBEBouquetWidgetButtons[3]; switch( blueFunction) { @@ -171,9 +164,8 @@ void CBEBouquetWidget::paintFoot() Button[3].locale = LOCALE_BOUQUETEDITOR_LOCK; break; } - Button[4].button = NEUTRINO_ICON_BUTTON_MENU; - Button[4].locale = NONEXISTANT_LOCALE; - ::paintButtons(x, y+height, width, 5, Button, width, ButtonHeight); + + ::paintButtons(x, y+height, width, 4, Button, width, ButtonHeight); } void CBEBouquetWidget::hide() diff --git a/src/gui/bedit/bouqueteditor_channels.cpp b/src/gui/bedit/bouqueteditor_channels.cpp index fd8d99687..79c261784 100644 --- a/src/gui/bedit/bouqueteditor_channels.cpp +++ b/src/gui/bedit/bouqueteditor_channels.cpp @@ -44,6 +44,7 @@ #include #include #include "bouqueteditor_chanselect.h" +#include #include #include @@ -168,8 +169,8 @@ void CBEChannelWidget::paint() void CBEChannelWidget::paintHead() { - frameBuffer->paintBoxRel(x,y, width,theight+0, COL_MENUHEAD_PLUS_0, RADIUS_LARGE, CORNER_TOP); - g_Font[SNeutrinoSettings::FONT_TYPE_MENU_TITLE]->RenderString(x+10,y+theight+0, width, caption.c_str() , COL_MENUHEAD, 0, true); + CComponentsHeader header(x, y, width, theight, caption.c_str(), NULL /*no header icon*/); + header.paint(CC_SAVE_SCREEN_NO); } const struct button_label CBEChannelWidgetButtons[4] = @@ -198,7 +199,7 @@ std::string CBEChannelWidget::getInfoText(int index) else desc = desc + " (" + satname + ")"; - res = satname + "\n" + desc; + res = satname + " " + desc; return res; } @@ -212,6 +213,7 @@ void CBEChannelWidget::paintDetails(int index) //info box ibox->setText(str, CTextBox::AUTO_WIDTH | CTextBox::NO_AUTO_LINEBREAK, g_Font[SNeutrinoSettings::FONT_TYPE_CHANNELLIST]); + ibox->setColorBody(COL_MENUCONTENTDARK_PLUS_0); ibox->paint(CC_SAVE_SCREEN_YES); } diff --git a/src/gui/bedit/bouqueteditor_channels.h b/src/gui/bedit/bouqueteditor_channels.h index 90d4d03d4..afc74a4b1 100644 --- a/src/gui/bedit/bouqueteditor_channels.h +++ b/src/gui/bedit/bouqueteditor_channels.h @@ -35,7 +35,8 @@ #include #include -#include +#include +#include #include #include diff --git a/src/gui/bedit/bouqueteditor_chanselect.cpp b/src/gui/bedit/bouqueteditor_chanselect.cpp index 4ffee27ec..bda31cea5 100644 --- a/src/gui/bedit/bouqueteditor_chanselect.cpp +++ b/src/gui/bedit/bouqueteditor_chanselect.cpp @@ -221,7 +221,7 @@ std::string CBEChannelSelectWidget::getInfoText(int index) else desc = desc + " (" + satname + ")"; - res = satname + "\n" + desc; + res = satname + " " + desc; return res; } @@ -235,6 +235,7 @@ void CBEChannelSelectWidget::paintDetails(int index) //info box ibox->setText(str, CTextBox::AUTO_WIDTH | CTextBox::NO_AUTO_LINEBREAK, g_Font[SNeutrinoSettings::FONT_TYPE_CHANNELLIST]); + ibox->setColorBody(COL_MENUCONTENTDARK_PLUS_0); ibox->paint(false); } diff --git a/src/gui/bedit/bouqueteditor_chanselect.h b/src/gui/bedit/bouqueteditor_chanselect.h index 729c3d7af..6ae293c87 100644 --- a/src/gui/bedit/bouqueteditor_chanselect.h +++ b/src/gui/bedit/bouqueteditor_chanselect.h @@ -34,7 +34,8 @@ #include #include -#include +#include +#include #include #include diff --git a/src/gui/bookmarkmanager.cpp b/src/gui/bookmarkmanager.cpp index 8453f1ff4..00c10abcd 100644 --- a/src/gui/bookmarkmanager.cpp +++ b/src/gui/bookmarkmanager.cpp @@ -37,6 +37,7 @@ #include #include #include +#include #include #include #include @@ -429,10 +430,8 @@ void CBookmarkManager::hide() //------------------------------------------------------------------------ void CBookmarkManager::paintHead() { - frameBuffer->paintBoxRel(x,y, width,theight+0, COL_MENUHEAD_PLUS_0); - frameBuffer->paintIcon(NEUTRINO_ICON_BOOKMARK_MANAGER,x+5,y+4); - g_Font[SNeutrinoSettings::FONT_TYPE_MENU_TITLE]->RenderString(x+35,y+theight+0, width- 45, g_Locale->getText(LOCALE_BOOKMARKMANAGER_NAME), COL_MENUHEAD, 0, true); // UTF-8 - frameBuffer->paintIcon(NEUTRINO_ICON_BUTTON_HELP, x+ width- 30, y+ 5 ); + CComponentsHeader header(x, y, width, theight, LOCALE_BOOKMARKMANAGER_NAME, NEUTRINO_ICON_BOOKMARK_MANAGER, CComponentsHeader::CC_BTN_HELP); + header.paint(CC_SAVE_SCREEN_NO); } const struct button_label BookmarkmanagerButtons[2] = diff --git a/src/gui/bouquetlist.cpp b/src/gui/bouquetlist.cpp index 7d798ec19..f9a955d27 100644 --- a/src/gui/bouquetlist.cpp +++ b/src/gui/bouquetlist.cpp @@ -41,6 +41,7 @@ #include #include +#include #include #include #include @@ -578,8 +579,8 @@ void CBouquetList::paintItem(int pos) void CBouquetList::paintHead() { - frameBuffer->paintBoxRel(x,y, width,theight+0, COL_MENUHEAD_PLUS_0, RADIUS_LARGE, CORNER_TOP); - g_Font[SNeutrinoSettings::FONT_TYPE_MENU_TITLE]->RenderString(x+10,y+theight+0, width, name, COL_MENUHEAD, 0, true); // UTF-8 + CComponentsHeader header(x, y, width, theight, name, NULL /*no header icon*/); + header.paint(CC_SAVE_SCREEN_NO); } void CBouquetList::paint() diff --git a/src/gui/channellist.cpp b/src/gui/channellist.cpp index 01468a858..f4d9ee9bd 100644 --- a/src/gui/channellist.cpp +++ b/src/gui/channellist.cpp @@ -57,6 +57,7 @@ #include #include #include +#include #include #include @@ -95,6 +96,9 @@ extern int old_b_id; extern cVideo * videoDecoder; +static CComponentsFrmClock *headerClock = NULL; +static int headerClockWidth = 0; + CChannelList::CChannelList(const char * const pName, bool phistoryMode, bool _vlist) { frameBuffer = CFrameBuffer::getInstance(); @@ -118,6 +122,7 @@ CChannelList::CChannelList(const char * const pName, bool phistoryMode, bool _vl previous_channellist_additional = -1; eventFont = SNeutrinoSettings::FONT_TYPE_CHANNELLIST_EVENT; dline = NULL; + logo_off = 0; //printf("************ NEW LIST %s : %x\n", name.c_str(), (int) this);fflush(stdout); } @@ -126,6 +131,15 @@ CChannelList::~CChannelList() //printf("************ DELETE LIST %s : %x\n", name.c_str(), this);fflush(stdout); chanlist.clear(); delete dline; + if (headerClock) { + headerClock->Stop(); + if (headerClock->isPainted()) + headerClock->hide(); + if (headerClock->isClockRun()) + headerClock->stopThread(); + delete headerClock; + headerClock = NULL; + } } void CChannelList::ClearList(void) @@ -571,6 +585,11 @@ bool CChannelList::updateSelection(int newpos) /* return: >= 0 to zap, -1 on cancel, -3 on list mode change, -4 list edited, -2 zap but no restore old list/chan ?? */ int CChannelList::show() { + int res = -1; + if (chanlist.empty()) { + return res; + } + /* temporary debugging stuff */ struct timeval t1, t2; gettimeofday(&t1, NULL); @@ -578,10 +597,6 @@ int CChannelList::show() neutrino_msg_t msg; neutrino_msg_data_t data; bool actzap = 0; - int res = -1; - if (chanlist.empty()) { - return res; - } new_zap_mode = g_settings.channellist_new_zap_mode; @@ -927,13 +942,14 @@ int CChannelList::show() } frameBuffer->blit(); } - if (g_settings.channellist_new_zap_mode != new_zap_mode) - g_settings.channellist_new_zap_mode = new_zap_mode; - new_zap_mode = 0; if (bouquet_changed) res = -5; /* in neutrino.cpp: -5 == "don't change bouquet after adding a channel to fav" */ if(!dont_hide){ + if (new_zap_mode && (g_settings.channellist_new_zap_mode != new_zap_mode)) + g_settings.channellist_new_zap_mode = new_zap_mode; + new_zap_mode = 0; + hide(); fader.Stop(); } @@ -943,6 +959,9 @@ int CChannelList::show() printf("CChannelList:: bouquetList->exec res %d\n", res); } + if (headerClock) + headerClock->Stop(); + if(NeutrinoMessages::mode_ts == CNeutrinoApp::getInstance()->getMode()) return -1; @@ -961,6 +980,11 @@ void CChannelList::hide() { videoDecoder->Pig(-1, -1, -1, -1); } + if (headerClock) { + headerClock->Stop(); + if (headerClock->isPainted()) + headerClock->hide(); + } frameBuffer->paintBackgroundBoxRel(x, y, full_width, height + info_height); clearItem2DetailsLine(); frameBuffer->blit(); @@ -1261,11 +1285,7 @@ void CChannelList::zapToChannel(CZapitChannel *channel, bool force) /* Called only from "all" channel list */ int CChannelList::numericZap(int key) { - neutrino_msg_t msg; - neutrino_msg_data_t data; - int res = -1; - if(showEmptyError()) return res; @@ -1341,6 +1361,8 @@ int CChannelList::numericZap(int key) int lastchan= -1; bool doZap = false; bool showEPG = false; + neutrino_msg_t msg; + neutrino_msg_data_t data; while(1) { if (lastchan != chn) { @@ -1482,12 +1504,12 @@ CZapitChannel* CChannelList::getPrevNextChannel(int key, unsigned int &sl) void CChannelList::virtual_zap_mode(bool up) { - neutrino_msg_t msg; - neutrino_msg_data_t data; - if(showEmptyError()) return; + neutrino_msg_t msg; + neutrino_msg_data_t data; + unsigned int sl = selected; int old_bactive = bouquetList->getActiveBouquetNumber(); int bactive = old_bactive; @@ -1544,17 +1566,21 @@ void CChannelList::virtual_zap_mode(bool up) } } -void CChannelList::quickZap(int key, bool /* cycle */) +bool CChannelList::quickZap(int key, bool /* cycle */) { if(chanlist.empty()) - return; + return true; unsigned int sl = selected; /* here selected value doesnt matter, zap will do adjust */ CZapitChannel* channel = getPrevNextChannel(key, sl); - if(channel) + bool ret = false; + if(channel && SameTP(channel)) { CNeutrinoApp::getInstance()->channelList->zapToChannel(channel); + ret = true; + } g_RCInput->clearRCMsg(); //FIXME test for n.103 + return ret; } void CChannelList::paintDetails(int index) @@ -1729,8 +1755,8 @@ struct button_label SChannelListButtons_SMode[NUM_LIST_BUTTONS_SORT] = { NEUTRINO_ICON_BUTTON_BLUE, LOCALE_INFOVIEWER_NEXT}, { NEUTRINO_ICON_BUTTON_RECORD_INACTIVE, NONEXISTANT_LOCALE}, { NEUTRINO_ICON_BUTTON_PLAY, LOCALE_EXTRA_KEY_PIP_CLOSE}, - { NEUTRINO_ICON_BUTTON_INFO, NONEXISTANT_LOCALE}, - { NEUTRINO_ICON_BUTTON_MENU, NONEXISTANT_LOCALE}, + { NEUTRINO_ICON_BUTTON_INFO_SMALL, NONEXISTANT_LOCALE}, + { NEUTRINO_ICON_BUTTON_MENU_SMALL, NONEXISTANT_LOCALE}, { NEUTRINO_ICON_BUTTON_MUTE_ZAP_ACTIVE, NONEXISTANT_LOCALE} }; @@ -2055,53 +2081,31 @@ void CChannelList::paintItem(int pos, const bool firstpaint) void CChannelList::paintHead() { - int timestr_len = 0; - char timestr[10] = {0}; - time_t now = time(NULL); - struct tm *tm = localtime(&now); + CComponentsHeader header(x, y, full_width, theight, name, NULL /*no header icon*/); + header.paint(CC_SAVE_SCREEN_NO); - bool gotTime = g_Sectionsd->getIsTimeSet(); + if (g_Sectionsd->getIsTimeSet()) { + if (headerClock == NULL) { + headerClock = new CComponentsFrmClock(0, 0, 0, 0, "%H:%M"); + headerClock->setClockIntervall(10); + headerClock->setClockFontType(SNeutrinoSettings::FONT_TYPE_MENU_TITLE); + headerClock->setCornerRadius(RADIUS_LARGE); + headerClock->setCornerType(CORNER_TOP_RIGHT); + } + headerClock->setYPos(y); + headerClock->setHeight(theight); + headerClock->setTextColor(COL_MENUHEAD); + headerClock->setColorBody(COL_MENUHEAD_PLUS_0); + headerClock->refresh(); + headerClockWidth = headerClock->getWidth(); + headerClock->setXPos(x + full_width - headerClockWidth - 10); + headerClockWidth += 6; - if(gotTime) { - strftime(timestr, 10, "%H:%M", tm); - timestr_len = g_Font[SNeutrinoSettings::FONT_TYPE_MENU_TITLE]->getRenderWidth(timestr, true); // UTF-8 + headerClock->Start(); } -#if 0 - int iw1, iw2, iw3, ih = 0; - frameBuffer->getIconSize(NEUTRINO_ICON_BUTTON_INFO, &iw1, &ih); - frameBuffer->getIconSize(NEUTRINO_ICON_BUTTON_MENU, &iw2, &ih); - if (new_zap_mode) - frameBuffer->getIconSize(NEUTRINO_ICON_BUTTON_MUTE_ZAP_ACTIVE, &iw3, &ih); - - // head - frameBuffer->paintBoxRel(x,y, full_width,theight+0, COL_MENUHEAD_PLUS_0, RADIUS_LARGE, CORNER_TOP);//round - - frameBuffer->paintIcon(NEUTRINO_ICON_BUTTON_INFO, x + full_width - iw1 - 10, y, theight); //y+ 5 ); - frameBuffer->paintIcon(NEUTRINO_ICON_BUTTON_MENU, x + full_width - iw1 - iw2 - 14, y, theight);//y + 5); // icon for bouquet list button - if (new_zap_mode) - frameBuffer->paintIcon((new_zap_mode == 2 /* active */) ? - NEUTRINO_ICON_BUTTON_MUTE_ZAP_ACTIVE : NEUTRINO_ICON_BUTTON_MUTE_ZAP_INACTIVE, - x + full_width - iw1 - iw2 - iw3 - 18, y, theight); - - if (gotTime) { - int iw3x = (new_zap_mode) ? iw3 : -10; - g_Font[SNeutrinoSettings::FONT_TYPE_MENU_TITLE]->RenderString(x + full_width - iw1 - iw2 - iw3x - 28 -timestr_len, - y+theight, timestr_len, timestr, COL_MENUHEAD, 0, true); // UTF-8 - timestr_len += 4; - } - - timestr_len += iw1 + iw2 + 12; - if (new_zap_mode) - timestr_len += iw3 + 10; -#endif - frameBuffer->paintBoxRel(x,y, full_width,theight+0, COL_MENUHEAD_PLUS_0, RADIUS_LARGE, CORNER_TOP);//round - if (gotTime) { - g_Font[SNeutrinoSettings::FONT_TYPE_MENU_TITLE]->RenderString(x + full_width - timestr_len - 10, - y+theight, timestr_len, timestr, COL_MENUHEAD, 0, true); // UTF-8 - timestr_len += 4; - } - logo_off = timestr_len + 10; - g_Font[SNeutrinoSettings::FONT_TYPE_MENU_TITLE]->RenderString(x+10,y+theight+0, full_width - timestr_len, name, COL_MENUHEAD, 0, true); // UTF-8 + else + headerClockWidth = 0; + logo_off = headerClockWidth + 10; } void CChannelList::paint() diff --git a/src/gui/channellist.h b/src/gui/channellist.h index a44e8d417..2f8d309f4 100644 --- a/src/gui/channellist.h +++ b/src/gui/channellist.h @@ -36,6 +36,7 @@ #include #include #include +#include #include #include @@ -76,8 +77,8 @@ private: std::string name; ZapitChannelList chanlist; CZapProtection* zapProtection; - CComponentsDetailLine *dline; - + CComponentsDetailLine *dline; + int full_width; int width; int height; @@ -162,7 +163,7 @@ public: int numericZap(int key); int show(); int exec(); - void quickZap(int key, bool cycle = false); + bool quickZap(int key, bool cycle = false); //int hasChannel(int nChannelNr); int hasChannelID(t_channel_id channel_id); void setSelected( int nChannelNr); // for adjusting bouquet's channel list after numzap or quickzap @@ -194,6 +195,7 @@ public: SORT_CH_NUMBER, SORT_MAX }; + unsigned Size() { return chanlist.size(); } }; #endif diff --git a/src/gui/components/Makefile.am b/src/gui/components/Makefile.am index 6f2420463..eaab0d0e4 100644 --- a/src/gui/components/Makefile.am +++ b/src/gui/components/Makefile.am @@ -31,11 +31,12 @@ libneutrino_gui_components_a_SOURCES = \ cc_detailsline.cpp \ cc_frm_button.cpp \ cc_frm.cpp \ + cc_frm_clock.cpp \ + cc_frm_footer.cpp \ cc_frm_header.cpp \ cc_frm_icons.cpp \ cc_frm_window.cpp \ cc_item.cpp \ - cc_item_box.cpp \ cc_item_infobox.cpp \ cc_item_picture.cpp \ cc_item_progressbar.cpp \ diff --git a/src/gui/components/cc.h b/src/gui/components/cc.h index 248bc2be0..39b8909d6 100644 --- a/src/gui/components/cc.h +++ b/src/gui/components/cc.h @@ -34,68 +34,174 @@ //#define DEBUG_CC +/// Basic component class. +/*! +Basic attributes and member functions for component sub classes +*/ + class CComponents { - protected: - int x, y, height, width, corner_type, shadow_w; - int corner_rad, fr_thickness, fr_thickness_sel; - CFrameBuffer * frameBuffer; - std::vector v_fbdata; - fb_pixel_t col_body, col_shadow, col_frame, col_frame_sel; - bool firstPaint, shadow, is_painted, paint_bg; + private: + ///pixel buffer handling, returns pixel buffer depends of given parameters + fb_pixel_t* getScreen(int ax, int ay, int dx, int dy); - void initVarBasic(); - void paintFbItems(bool do_save_bg = true); - virtual fb_pixel_t* getScreen(int ax, int ay, int dx, int dy); - comp_screen_data_t saved_screen; + protected: + ///object: framebuffer object, usable in all sub classes + CFrameBuffer * frameBuffer; + ///container: for frambuffer properties and pixel buffer + std::vector v_fbdata; - void clearSavedScreen(); + ///property: x-position on screen + int x; + ///property: y-position on screen + int y; + ///property: contains real x-position on screen + int cc_xr; + ///property: contains real y-position on screen + int cc_yr; + ///property: height-dimension on screen + int height; + ///property: width-dimension on screen + int width; + ///property: has corners with definied type, types are defined in /driver/frambuffer.h, without effect, if corner_radius=0 + int corner_type; + ///property: defined radius of corner, without effect, if corner_type=0 + int corner_rad; + + ///property: color of body + fb_pixel_t col_body; + ///property: color of shadow + fb_pixel_t col_shadow; + ///property: color of frame + fb_pixel_t col_frame; + ///property: color of frame if component is selected, Note: fr_thickness_sel must be set + fb_pixel_t col_frame_sel; + + ///property: true=component has shadow + bool shadow; + ///property: width of shadow + int shadow_w; + + ///property: frame thickness + int fr_thickness; + ///property: frame thickness of selected component + int fr_thickness_sel; + + ///status: true=component was painted for 1st time + bool firstPaint; + ///status: true=component was rendered + bool is_painted; + ///mode: true=activate rendering of basic elements (frame, shadow and body) + bool paint_bg; + + ///initialize of basic attributes, no parameters required + void initVarBasic(); + ///rendering of framebuffer elements at once, + ///elements are contained in v_fbdata, presumes added frambuffer elements with paintInit(), + ///parameter do_save_bg=true, saves background of element to pixel buffer, this can be restore with hide() + void paintFbItems(bool do_save_bg = true); + + ///clean up old screen buffer saved in v_fbdata virtual void clear(); + + ///container: contains saved pixel buffer with position and dimensions + comp_screen_data_t saved_screen; + ///cleans saved pixel buffer + void clearSavedScreen(); + public: + ///basic component class constructor. CComponents(); virtual~CComponents(); + ///set screen x-position inline virtual void setXPos(const int& xpos){x = xpos;}; + ///set screen y-position, inline virtual void setYPos(const int& ypos){y = ypos;}; + ///set x and y position + ///Note: position of bound components (items) means position related within parent form, not for screen! + ///to set the real screen position, look at setRealPos() inline virtual void setPos(const int& xpos, const int& ypos){x = xpos; y = ypos;}; - inline virtual void setHeight(const int& h){height = h;}; - inline virtual void setWidth(const int& w){width = w;}; - inline virtual void setDimensionsAll(const int& xpos, const int& ypos, const int& w, const int& h){x = xpos; y = ypos; width = w; height = h;}; + + ///sets real x position on screen. Use this, if item is added to a parent form + virtual void setRealXPos(const int& xr){cc_xr = xr;}; + ///sets real y position on screen. Use this, if item is added to a parent form + virtual void setRealYPos(const int& yr){cc_yr = yr;}; + ///sets real x and y position on screen at once. Use this, if item is added to a parent form + virtual void setRealPos(const int& xr, const int& yr){cc_xr = xr; cc_yr = yr;}; + ///get real x-position on screen. Use this, if item contains own render methods and item is bound to a form + virtual int getRealXPos(){return cc_xr;}; + ///get real y-position on screen. Use this, if item contains own render methods and item is bound to a form + virtual int getRealYPos(){return cc_yr;}; + ///set height of component on screen + inline virtual void setHeight(const int& h){height = h;}; + ///set width of component on screen + inline virtual void setWidth(const int& w){width = w;}; + ///set all positions and dimensions of component at once + inline virtual void setDimensionsAll(const int& xpos, const int& ypos, const int& w, const int& h){x = xpos; y = ypos; width = w; height = h;}; + + ///return screen x-position of component + ///Note: position of bound components (items) means position related within parent form, not for screen! + ///to get the real screen position, use getRealXPos(), to find in CComponentsItem sub classes inline virtual int getXPos(){return x;}; + ///return screen y-position of component + ///Note: position of bound components (items) means position related within parent form, not for screen! + ///to get the real screen position, use getRealYPos(), to find in CComponentsItem sub classes inline virtual int getYPos(){return y;}; + ///return height of component inline virtual int getHeight(){return height;}; + ///return width of component inline virtual int getWidth(){return width;}; + ///return of frame thickness + inline virtual int getFrameThickness(){return fr_thickness;}; + + ///return/set (pass through) width and height of component inline virtual void getSize(int* w, int* h){*w=width; *h=height;}; + ///return/set (pass through) position and dimensions of component at once inline virtual void getDimensions(int* xpos, int* ypos, int* w, int* h){*xpos=x; *ypos=y; *w=width; *h=height;}; - ///set colors: Possible color values are defined in "gui/color.h" and "gui/customcolor.h" + ///set frame color inline virtual void setColorFrame(fb_pixel_t color){col_frame = color;}; + ///set body color inline virtual void setColorBody(fb_pixel_t color){col_body = color;}; + ///set shadow color inline virtual void setColorShadow(fb_pixel_t color){col_shadow = color;}; + ///set all basic framebuffer element colors at once + ///Note: Possible color values are defined in "gui/color.h" and "gui/customcolor.h" inline virtual void setColorAll(fb_pixel_t color_frame, fb_pixel_t color_body, fb_pixel_t color_shadow){col_frame = color_frame; col_body = color_body; col_shadow = color_shadow;}; - ///get colors + + ///get frame color inline virtual fb_pixel_t getColorFrame(){return col_frame;}; + ///get body color inline virtual fb_pixel_t getColorBody(){return col_body;}; + ///get shadow color inline virtual fb_pixel_t getColorShadow(){return col_shadow;}; - ///set corner types: Possible corner types are defined in CFrameBuffer (see: driver/framebuffer.h). + ///set corner types + ///Possible corner types are defined in CFrameBuffer (see: driver/framebuffer.h) + ///Note: default values are given from settings inline virtual void setCornerType(const int& type){corner_type = type;}; + ///set corner radius inline virtual void setCornerRadius(const int& radius){corner_rad = radius;}; - ///get corner types: + ///get corner types inline virtual int getCornerType(){return corner_type;}; + ///get corner radius inline virtual int getCornerRadius(){return corner_rad;}; - + + ///set frame thickness inline virtual void setFrameThickness(const int& thickness){fr_thickness = thickness;}; + ///switch shadow on/off + ///Note: it's recommended to use #defines: CC_SHADOW_ON=true or CC_SHADOW_OFF=false as parameter, see also cc_types.h inline virtual void setShadowOnOff(bool has_shadow){shadow = has_shadow;}; ///hide current screen and restore background virtual void hide(); - ///erase current screen without restore of background, as similar to paintBackgroundBoxRel() from CFrameBuffer + ///erase current screen without restore of background, it's similar to paintBackgroundBoxRel() from CFrameBuffer virtual void kill(); ///returns paint mode, true=item was painted virtual bool isPainted(){return is_painted;} - ///allows paint of elemetary item parts (shadow, frame and body), similar as background, set it usually to false, if item used in a form + ///allows paint of elementary item parts (shadow, frame and body), similar as background, set it usually to false, if item used in a form virtual void doPaintBg(bool do_paint){paint_bg = do_paint;}; }; @@ -103,254 +209,64 @@ class CComponents class CComponentsItem : public CComponents { protected: + ///property: define of item type, see cc_types.h for possible types int cc_item_type; + ///property: define of item index, all bound items get an index, + ///default: CC_NO_INDEX as identifer for not embedded item and default index=0 for form as main parent + ///see also getIndex(), setIndex() int cc_item_index; - bool cc_item_enabled, cc_item_selected; + ///property: default enabled + bool cc_item_enabled; + ///property: default not selected + bool cc_item_selected; ///Pointer to the form object in which this item is embedded. ///Is typically the type CComponentsForm or derived classes, default intialized with NULL - CComponents *cc_parent; + CComponentsItem *cc_parent; - ///contains real position and dimensions on screen, - int cc_item_xr, cc_item_yr; - + ///hides item, arg: no_restore=true causes no restore of background, but clean up pixel buffer if required void hideCCItem(bool no_restore = false); + + ///initialze of basic framebuffer elements with shadow, background and frame. + ///must be called first in all paint() members before paint any item, + ///If backround is not required, it's possible to override this with variable paint_bg=false, use doPaintBg(true/false) to set this! + ///arg do_save_bg=false avoids using of unnecessary pixel memory, eg. if no hide with restore is provided. This is mostly the case whenever + ///an item will be hide or overpainted with other methods, or it's embedded (bound) in a parent form. void paintInit(bool do_save_bg); + + ///initialize all required attributes void initVarItem(); public: CComponentsItem(); ///sets pointer to the form object in which this item is embedded. - virtual void setParent(CComponents *parent){cc_parent = parent;}; + virtual void setParent(CComponentsItem *parent){cc_parent = parent;}; - ///sets real position on screen. Use this, if item contains own render methods and item is added to a form - virtual void setRealPos(const int& xr, const int& yr){cc_item_xr = xr; cc_item_yr = yr;}; - virtual int getRealXPos(){return cc_item_xr;}; - virtual int getRealYPos(){return cc_item_yr;}; - + ///abstract: paint item, arg: do_save_bg see paintInit() above virtual void paint(bool do_save_bg = CC_SAVE_SCREEN_YES) = 0; + ///hides item, arg: no_restore see hideCCItem() above virtual void hide(bool no_restore = false); + + ///get the current item type, see attribute cc_item_type above virtual int getItemType(); + ///syncronizes item colors with current color settings if required, NOTE: overwrites internal values! virtual void syncSysColors(); - ///setters for item select stats + ///set select mode, see also col_frame_sel virtual void setSelected(bool selected){cc_item_selected = selected;}; + ///set enable mode, see also cc_item_enabled virtual void setEnable(bool enabled){cc_item_enabled = enabled;}; - ///getters for item enable stats + + ///get select mode, see also setSelected() above virtual bool isSelected(){return cc_item_selected;}; + ///get enable mode, see also setEnable() above virtual bool isEnabled(){return cc_item_enabled;}; -}; -class CComponentsPicture : public CComponentsItem -{ - protected: - void initVarPicture(); - - enum - { - CC_PIC_IMAGE_MODE_OFF = 0, //paint pictures in icon mode, mainly not scaled - CC_PIC_IMAGE_MODE_ON = 1, //paint pictures in image mode, paint scaled if required - CC_PIC_IMAGE_MODE_AUTO = 2 - }; - - std::string pic_name; - unsigned char pic_offset; - bool pic_paint, pic_paintBg, pic_painted, do_paint; - int pic_align, pic_x, pic_y, pic_width, pic_height; - int pic_max_w, pic_max_h, pic_paint_mode; - - void init( const int x_pos, const int y_pos, const std::string& image_name, const int alignment, bool has_shadow, - fb_pixel_t color_frame, fb_pixel_t color_background, fb_pixel_t color_shadow); - - public: - CComponentsPicture( const int x_pos, const int y_pos, const int w, const int h, - const std::string& image_name, const int alignment = CC_ALIGN_HOR_CENTER | CC_ALIGN_VER_CENTER, bool has_shadow = CC_SHADOW_OFF, - fb_pixel_t color_frame = COL_MENUCONTENT_PLUS_6, fb_pixel_t color_background = 0, fb_pixel_t color_shadow = COL_MENUCONTENTDARK_PLUS_0); - - virtual inline void setPictureOffset(const unsigned char offset){pic_offset = offset;}; - virtual inline void setPicturePaint(bool paint_p){pic_paint = paint_p;}; - virtual inline void setPicturePaintBackground(bool paintBg){pic_paintBg = paintBg;}; - virtual void setPicture(const std::string& picture_name); - virtual void setPictureAlign(const int alignment); - - virtual inline bool isPicPainted(){return pic_painted;}; - virtual void paint(bool do_save_bg = CC_SAVE_SCREEN_YES); - virtual void hide(bool no_restore = false); - virtual inline void getPictureSize(int *pwidth, int *pheight){*pwidth=pic_width; *pheight=pic_height;}; - virtual void setMaxWidth(const int w_max){pic_max_w = w_max;}; - virtual void setMaxHeight(const int h_max){pic_max_h = h_max;}; -}; - -class CComponentsText : public CComponentsItem -{ - protected: - CTextBox * ct_textbox; - CBox * ct_box; - Font * ct_font; - - fb_pixel_t ct_col_text; - int ct_text_mode; //see textbox.h for possible modes - std::string ct_text, ct_old_text; - bool ct_text_sent, ct_paint_textbg, ct_force_text_paint; - - static std::string iToString(int int_val); //helper to convert int to string - - void initVarText(); - void clearCCText(); - void initCCText(); - void paintText(bool do_save_bg = CC_SAVE_SCREEN_YES); - public: - CComponentsText(); - CComponentsText( const int x_pos, const int y_pos, const int w, const int h, - std::string text = "", const int mode = CTextBox::AUTO_WIDTH, Font* font_text = NULL, - bool has_shadow = CC_SHADOW_OFF, - fb_pixel_t color_text = COL_MENUCONTENT, fb_pixel_t color_frame = COL_MENUCONTENT_PLUS_6, fb_pixel_t color_body = COL_MENUCONTENT_PLUS_0, fb_pixel_t color_shadow = COL_MENUCONTENTDARK_PLUS_0); - virtual ~CComponentsText(); - - //default members to paint a text box and hide painted text - //hide textbox - void hide(bool no_restore = false); - //paint text box, parameter do_save_bg: default = true, causes fill of backckrond pixel buffer - void paint(bool do_save_bg = CC_SAVE_SCREEN_YES); - - //send options for text font (size and type), color and mode (allignment) - virtual inline void setTextFont(Font* font_text){ct_font = font_text;}; - virtual inline void setTextColor(fb_pixel_t color_text){ ct_col_text = color_text;}; - //see textbox.h for possible allignment modes - virtual inline void setTextMode(const int mode){ct_text_mode = mode;}; - - //send option to CTextBox object to paint background box behind text or not - virtual inline void doPaintTextBoxBg(bool do_paintbox_bg){ ct_paint_textbg = do_paintbox_bg;}; - - //sets text mainly with string also possible with overloades members for loacales, const char and text file - virtual void setText(const std::string& stext, const int mode = ~CTextBox::AUTO_WIDTH, Font* font_text = NULL); - - virtual void setText(const char* ctext, const int mode = ~CTextBox::AUTO_WIDTH, Font* font_text = NULL); - virtual void setText(neutrino_locale_t locale_text, const int mode = ~CTextBox::AUTO_WIDTH, Font* font_text = NULL); - virtual void setText(const int digit, const int mode = ~CTextBox::AUTO_WIDTH, Font* font_text = NULL); - virtual bool setTextFromFile(const std::string& path_to_textfile, const int mode = ~CTextBox::AUTO_WIDTH, Font* font_text = NULL); - - //helper to remove linebreak chars from a string if needed - virtual void removeLineBreaks(std::string& str); - - //returns true, if text was changed - virtual bool textChanged(){return ct_old_text != ct_text;}; - //force paint of text even if text was changed or not - virtual void forceTextPaint(bool force_text_paint = true){ct_force_text_paint = force_text_paint;}; - - //gets the embedded CTextBox object, so it's possible to get access directly to its methods and properties - virtual CTextBox* getCTextBoxObject() { return ct_textbox; }; -}; - -class CComponentsLabel : public CComponentsText -{ - public: - CComponentsLabel( const int x_pos, const int y_pos, const int w, const int h, - std::string text = "", const int mode = CTextBox::AUTO_WIDTH, Font* font_text = NULL, - bool has_shadow = CC_SHADOW_OFF, - fb_pixel_t color_text = COL_MENUCONTENTINACTIVE, fb_pixel_t color_frame = COL_MENUCONTENT_PLUS_6, fb_pixel_t color_body = COL_MENUCONTENT_PLUS_0, fb_pixel_t color_shadow = COL_MENUCONTENTDARK_PLUS_0) - :CComponentsText(x_pos, y_pos, w, h, text, mode, font_text, has_shadow, color_text, color_frame, color_body, color_shadow) - { - cc_item_type = CC_ITEMTYPE_LABEL; - }; - CComponentsLabel():CComponentsText() - { - initVarText(); - cc_item_type = CC_ITEMTYPE_LABEL; - ct_col_text = COL_MENUCONTENTINACTIVE; - }; -}; - -#define INFO_BOX_Y_OFFSET 2 -class CComponentsInfoBox : public CComponentsText -{ - private: - int x_text, x_offset; - CComponentsPicture * pic; - std::string pic_default_name; - - void paintPicture(); - void initVarInfobox(); - std::string pic_name; - - public: - CComponentsText * cctext; - - CComponentsInfoBox(); - CComponentsInfoBox( const int x_pos, const int y_pos, const int w, const int h, - std::string info_text = "", const int mode = CTextBox::AUTO_WIDTH, Font* font_text = NULL, - bool has_shadow = CC_SHADOW_OFF, - fb_pixel_t color_text = COL_MENUCONTENT, fb_pixel_t color_frame = COL_MENUCONTENT_PLUS_6, fb_pixel_t color_body = COL_MENUCONTENT_PLUS_0, fb_pixel_t color_shadow = COL_MENUCONTENTDARK_PLUS_0); - - ~CComponentsInfoBox(); - - inline void setSpaceOffset(const int offset){x_offset = offset;}; - inline void setPicture(const std::string& picture_name){pic_name = picture_name;}; - - void paint(bool do_save_bg = CC_SAVE_SCREEN_YES); -}; - - -class CComponentsShapeCircle : public CComponentsItem -{ - private: - int d; - public: - CComponentsShapeCircle( const int x_pos, const int y_pos, const int diam, bool has_shadow = CC_SHADOW_ON, - fb_pixel_t color_frame = COL_MENUCONTENT_PLUS_6, fb_pixel_t color_body = COL_MENUCONTENT_PLUS_0, fb_pixel_t color_shadow = COL_MENUCONTENTDARK_PLUS_0); - - inline void setDiam(const int& diam){d=width=height=diam, corner_rad=d/2;}; - inline int getDiam(){return d;}; - void paint(bool do_save_bg = CC_SAVE_SCREEN_YES); -}; - -class CComponentsShapeSquare : public CComponentsItem -{ - public: - CComponentsShapeSquare( const int x_pos, const int y_pos, const int w, const int h, bool has_shadow = CC_SHADOW_ON, - fb_pixel_t color_frame = COL_MENUCONTENT_PLUS_6, fb_pixel_t color_body = COL_MENUCONTENT_PLUS_0, fb_pixel_t color_shadow = COL_MENUCONTENTDARK_PLUS_0); - - void paint(bool do_save_bg = CC_SAVE_SCREEN_YES); -}; - -class CComponentsPIP : public CComponentsItem -{ - private: - int screen_w, screen_h; - std::string pic_name; //alternate picture if is no tv picture available - public: - CComponentsPIP( const int x_pos, const int y_pos, const int percent = 30, bool has_shadow = CC_SHADOW_OFF); - ~CComponentsPIP(); - - void paint(bool do_save_bg = CC_SAVE_SCREEN_YES); - void hide(bool no_restore = false); - void setScreenWidth(int screen_width){screen_w = screen_width;}; - void setScreenHeight(int screen_heigth){screen_h = screen_heigth;}; - void setPicture(const std::string& image){pic_name = image;}; -}; - - -class CComponentsDetailLine : public CComponents -{ - private: - int thickness, y_down, h_mark_top, h_mark_down; - - void initVarDline(); - - public: - CComponentsDetailLine(); - CComponentsDetailLine( const int x_pos,const int y_pos_top, const int y_pos_down, - const int h_mark_up = CC_HEIGHT_MIN , const int h_mark_down = CC_HEIGHT_MIN, - fb_pixel_t color_line = COL_MENUCONTENT_PLUS_6, fb_pixel_t color_shadow = COL_MENUCONTENTDARK_PLUS_0); - ~CComponentsDetailLine(); - - void paint(bool do_save_bg = CC_SAVE_SCREEN_YES); - inline void setColors(fb_pixel_t color_line, fb_pixel_t color_shadow){col_body = color_line; col_shadow = color_shadow;}; - void syncSysColors(); - inline void setYPosDown(const int& y_pos_down){y_down = y_pos_down;}; - inline void setHMarkTop(const int& h_mark_top_){h_mark_top = h_mark_top_;}; - inline void setHMarkDown(const int& h_mark_down_){h_mark_down = h_mark_down_;}; + ///get current index of item, see also attribut cc_item_index + virtual int getIndex(){return cc_item_index;}; + ///set index to item, see also attribut cc_item_index + virtual void setIndex(const int& index){cc_item_index = index;}; }; #endif diff --git a/src/gui/components/cc_base.cpp b/src/gui/components/cc_base.cpp index 8e0d7a5da..bbebf1cd6 100644 --- a/src/gui/components/cc_base.cpp +++ b/src/gui/components/cc_base.cpp @@ -58,6 +58,8 @@ void CComponents::initVarBasic() { x = saved_screen.x = 0; y = saved_screen.y = 0; + cc_xr = x; + cc_yr = y; height = saved_screen.dy = CC_HEIGHT_MIN; width = saved_screen.dx = CC_WIDTH_MIN; @@ -133,6 +135,25 @@ void CComponents::paintFbItems(bool do_save_bg) } else if (fbtype == CC_FBDATA_TYPE_BACKGROUND) frameBuffer->paintBackgroundBoxRel(x, y, v_fbdata[i].dx, v_fbdata[i].dy); + else if (fbtype == CC_FBDATA_TYPE_SHADOW_BOX) { + if (shadow) { + int sw = shadow_w; + int sw_cur = sw; + int x_sh = v_fbdata[i].x + v_fbdata[i].dx - sw; + int y_sh = v_fbdata[i].y + v_fbdata[i].dy - sw; + if (corner_type && v_fbdata[i].r) { + //calculate positon of shadow areas + x_sh += sw - 2*v_fbdata[i].r; + y_sh += sw - 2*v_fbdata[i].r; + //calculate current shadow width depends of current corner_rad + sw_cur = max(2*v_fbdata[i].r, sw); + } + // shadow right + frameBuffer->paintBoxRel(x_sh, v_fbdata[i].y, sw_cur, v_fbdata[i].dy-sw_cur, v_fbdata[i].color, v_fbdata[i].r, corner_type & CORNER_TOP_RIGHT); + // shadow bottom + frameBuffer->paintBoxRel(v_fbdata[i].x, y_sh, v_fbdata[i].dx, sw_cur, v_fbdata[i].color, v_fbdata[i].r, corner_type & CORNER_BOTTOM); + } + } else frameBuffer->paintBoxRel(v_fbdata[i].x, v_fbdata[i].y, v_fbdata[i].dx, v_fbdata[i].dy, v_fbdata[i].color, v_fbdata[i].r, corner_type); } diff --git a/src/gui/components/cc_detailsline.cpp b/src/gui/components/cc_detailsline.cpp index 10f6f96a3..646b0292e 100644 --- a/src/gui/components/cc_detailsline.cpp +++ b/src/gui/components/cc_detailsline.cpp @@ -30,7 +30,7 @@ #include #include -#include "cc.h" +#include "cc_detailsline.h" using namespace std; diff --git a/src/gui/components/cc_detailsline.h b/src/gui/components/cc_detailsline.h new file mode 100644 index 000000000..f35cbf745 --- /dev/null +++ b/src/gui/components/cc_detailsline.h @@ -0,0 +1,77 @@ +/* + Based up Neutrino-GUI - Tuxbox-Project + Copyright (C) 2001 by Steffen Hehn 'McClean' + + Classes for generic GUI-related components. + Copyright (C) 2012, 2013, Thilo Graf 'dbt' + + License: GPL + + 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. +*/ + +#ifndef __CC_DETAIL_LINE_H__ +#define __CC_DETAIL_LINE_H__ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include "cc.h" + +//! Sub class of CComponents. Shows a connectline with given dimensions and color on screen. +/*! +Not usable as CCItem! +*/ + +class CComponentsDetailLine : public CComponents +{ + private: + ///property: line thickness + int thickness; + ///property: lowest y position + int y_down; + ///property: height of top marker + int h_mark_top; + ///property: height of bottom marker + int h_mark_down; + + ///initialize all internal attributes + void initVarDline(); + + public: + CComponentsDetailLine(); + CComponentsDetailLine( const int x_pos,const int y_pos_top, const int y_pos_down, + const int h_mark_up = CC_HEIGHT_MIN , const int h_mark_down = CC_HEIGHT_MIN, + fb_pixel_t color_line = COL_MENUCONTENT_PLUS_6, fb_pixel_t color_shadow = COL_MENUCONTENTDARK_PLUS_0); + ~CComponentsDetailLine(); + + ///set colors + inline void setColors(fb_pixel_t color_line, fb_pixel_t color_shadow){col_body = color_line; col_shadow = color_shadow;}; + ///set colors with system settings + void syncSysColors(); + ///set property: lowest y position + inline void setYPosDown(const int& y_pos_down){y_down = y_pos_down;}; + ///set property: height of top marker + inline void setHMarkTop(const int& h_mark_top_){h_mark_top = h_mark_top_;}; + ///property: height of bottom marker + inline void setHMarkDown(const int& h_mark_down_){h_mark_down = h_mark_down_;}; + + ///paint all to screen + void paint(bool do_save_bg = CC_SAVE_SCREEN_YES); +}; + +#endif diff --git a/src/gui/components/cc_frm.cpp b/src/gui/components/cc_frm.cpp index 34c1e4d25..5040f7d47 100644 --- a/src/gui/components/cc_frm.cpp +++ b/src/gui/components/cc_frm.cpp @@ -31,6 +31,8 @@ #include #include #include "cc_frm.h" +#include +#include using namespace std; @@ -51,6 +53,8 @@ CComponentsForm::CComponentsForm(const int x_pos, const int y_pos, const int w, //CComponents x = x_pos; y = y_pos; + cc_xr = x; + cc_yr = y; width = w; height = h; @@ -70,7 +74,7 @@ void CComponentsForm::cleanCCForm() #ifdef DEBUG_CC printf("[CComponentsForm] [%s - %d] clean up...\n", __FUNCTION__, __LINE__); #endif -// hide(); + clearCCItems(); clearSavedScreen(); clear(); @@ -117,20 +121,37 @@ void CComponentsForm::initVarForm() col_shadow = COL_MENUCONTENTDARK_PLUS_0; corner_rad = RADIUS_LARGE; corner_type = CORNER_ALL; - + cc_item_index = 0; + //CComponentsForm v_cc_items.clear(); - + cc_item_type = CC_ITEMTYPE_FRM; + append_h_offset = 0; + append_v_offset = 0; } void CComponentsForm::addCCItem(CComponentsItem* cc_Item) { if (cc_Item){ #ifdef DEBUG_CC - printf(" [CComponentsForm] %s-%d add cc_Item [type %d] [current count %d] \n", __FUNCTION__, __LINE__, cc_Item->getItemType(), v_cc_items.size()); + printf(" [CComponentsForm] %s-%d try to add cc_Item [type %d] to form [current index=%d] \n", __FUNCTION__, __LINE__, cc_Item->getItemType(), cc_item_index); #endif cc_Item->setParent(this); v_cc_items.push_back(cc_Item); +#ifdef DEBUG_CC + printf(" added cc_Item [type %d] to form [current index=%d] \n", cc_Item->getItemType(), cc_item_index); +#endif + + //assign item index + int count = v_cc_items.size(); + char buf[64]; + snprintf(buf, sizeof(buf), "%d%d", cc_item_index, count); + buf[63] = '\0'; + int new_index = atoi(buf); + cc_Item->setIndex(new_index); +#ifdef DEBUG_CC + printf(" %s-%d parent index = %d, assigned index ======> %d\n", __FUNCTION__, __LINE__, cc_item_index, new_index); +#endif } #ifdef DEBUG_CC else @@ -140,12 +161,23 @@ void CComponentsForm::addCCItem(CComponentsItem* cc_Item) int CComponentsForm::getCCItemId(CComponentsItem* cc_Item) { - for (size_t i= 0; i< v_cc_items.size(); i++) - if (v_cc_items[i] == cc_Item) - return i; + if (cc_Item){ + for (size_t i= 0; i< v_cc_items.size(); i++) + if (v_cc_items[i] == cc_Item) + return i; + } return -1; } +bool CComponentsForm::isAdded(CComponentsItem* cc_item) +{ + bool ret = false; + if (getCCItemId(cc_item) != -1) + ret = true; + return ret; +} + + CComponentsItem* CComponentsForm::getCCItem(const uint& cc_item_id) { if (v_cc_items[cc_item_id]) @@ -208,6 +240,17 @@ void CComponentsForm::removeCCItem(const uint& cc_item_id) #endif } +void CComponentsForm::exchangeCCItem(const uint& cc_item_id_a, const uint& cc_item_id_b) +{ + if (!v_cc_items.empty()) + swap(v_cc_items[cc_item_id_a], v_cc_items[cc_item_id_b]); +} + +void CComponentsForm::exchangeCCItem(CComponentsItem* item_a, CComponentsItem* item_b) +{ + exchangeCCItem(getCCItemId(item_a), getCCItemId(item_b)); +} + void CComponentsForm::paintForm(bool do_save_bg) { //paint body @@ -222,65 +265,78 @@ void CComponentsForm::paint(bool do_save_bg) paintForm(do_save_bg); } + void CComponentsForm::paintCCItems() -{ - size_t items_count = v_cc_items.size(); - int x_frm_left = x+fr_thickness; //left form border - int y_frm_top = y+fr_thickness; //top form border - int x_frm_right = x+width-fr_thickness; //right form border - int y_frm_bottom = y+height-fr_thickness; //bottom form border - - for(size_t i=0; igetDimensions(&x_item, &y_item, &w_item, &h_item); +{ + size_t items_count = v_cc_items.size(); - int xy_ref = 0+fr_thickness; //allowed minimal x and y start position - if (x_item < xy_ref){ -#ifdef DEBUG_CC - printf("[CComponentsForm] %s: item %d position is out of form dimensions\ndefinied x=%d\nallowed x>=%d\n", __FUNCTION__, i, x_item, xy_ref); -#endif - x_item = xy_ref; - } - if (y_item < xy_ref){ -#ifdef DEBUG_CC - printf("[CComponentsForm] %s: item %d position is out of form dimensions\ndefinied y=%d\nallowed y>=%d\n", __FUNCTION__, i, y_item, xy_ref); -#endif - y_item = xy_ref; - } - - //set adapted position onto form - v_cc_items[i]->setXPos(x_frm_left+x_item); - v_cc_items[i]->setYPos(y_frm_top+y_item); + //using of real x/y values to paint items if this text object is bound in a parent form + int this_x = x, auto_x = x, this_y = y, auto_y = y; + if (cc_parent){ + this_x = auto_x = cc_xr; + this_y = auto_y = cc_yr; + } - //watch horizontal x dimensions of items - int x_item_right = v_cc_items[i]->getXPos()+w_item; //right item border - if (x_item_right > x_frm_right){ - v_cc_items[i]->setWidth(w_item-(x_item_right-x_frm_right)); -#ifdef DEBUG_CC - printf("[CComponentsForm] %s: item %d too large, definied width=%d, possible width=%d \n", __FUNCTION__, i, w_item, v_cc_items[i]->getWidth()); -#endif + for(size_t i=0; igetWidth(); + int h_item = cc_item->getHeight(); + + //get current position of item + int xpos = cc_item->getXPos(); + int ypos = cc_item->getYPos(); + + //set required x-position to item + if (xpos == CC_APPEND){ + auto_x += append_h_offset; + cc_item->setRealXPos(auto_x + xpos + 1); + auto_x += w_item; + } + else{ + cc_item->setRealXPos(this_x + xpos); + auto_x = (cc_item->getRealXPos() + w_item); + } + + //set required y-position to item + if (ypos == CC_APPEND){ + auto_y += append_v_offset; + cc_item->setRealYPos(auto_y + ypos + 1); + auto_y += h_item; + } + else{ + cc_item->setRealYPos(this_y + ypos); + auto_y = (cc_item->getRealYPos() + h_item); + } + + + //These steps check whether the element can be painted into the container. + //Is it too wide or too high, it will be shortened and displayed in the log. + //This should be avoid! + //checkwidth and adapt if required + int right_frm = (cc_parent ? cc_xr : x) + width - 2*fr_thickness; + int right_item = cc_item->getRealXPos() + w_item; + int w_diff = right_item - right_frm; + int new_w = w_item - w_diff; + if (right_item > right_frm){ + printf("[CComponentsForm] %s: item %d width is too large, definied width=%d, possible width=%d \n", __FUNCTION__, i, w_item, new_w); + cc_item->setWidth(new_w); } - //watch vertical y dimensions - int y_item_bottom = v_cc_items[i]->getYPos()+h_item; //bottom item border - if (y_item_bottom > y_frm_bottom){ - v_cc_items[i]->setHeight(h_item-(y_item_bottom-y_frm_bottom)); -#ifdef DEBUG_CC - printf("[CComponentsForm] %s: item %d too large, definied height=%d, possible height=%d \n", __FUNCTION__, i, h_item, v_cc_items[i]->getHeight()); -#endif + //check height and adapt if required + int bottom_frm = (cc_parent ? cc_yr : y) + height - 2*fr_thickness; + int bottom_item = cc_item->getRealYPos() + h_item; + int h_diff = bottom_item - bottom_frm; + int new_h = h_item - h_diff; + if (bottom_item > bottom_frm){ + printf("[CComponentsForm] %s: item %d height is too large, definied height=%d, possible height=%d \n", __FUNCTION__, i, h_item, new_h); + cc_item->setHeight(new_h); } - //set real position dimension to item - int real_x = v_cc_items[i]->getXPos(); - int real_y = v_cc_items[i]->getYPos(); - v_cc_items[i]->setRealPos(real_x, real_y); - - //paint element without saved screen! - v_cc_items[i]->paint(CC_SAVE_SCREEN_NO); - - //restore dimensions and position - v_cc_items[i]->setDimensionsAll(x_item, y_item, w_item, h_item); + //finally paint current item + cc_item->paint(CC_SAVE_SCREEN_NO); } } diff --git a/src/gui/components/cc_frm.h b/src/gui/components/cc_frm.h index 3a916298a..38a2bd348 100644 --- a/src/gui/components/cc_frm.h +++ b/src/gui/components/cc_frm.h @@ -29,6 +29,8 @@ #include "config.h" #include +#include +#include #include #include @@ -39,6 +41,9 @@ class CComponentsForm : public CComponentsItem std::vector v_cc_items; void initVarForm(); void paintForm(bool do_save_bg); + + int append_h_offset; + int append_v_offset; public: CComponentsForm(); @@ -53,11 +58,16 @@ class CComponentsForm : public CComponentsItem virtual void removeCCItem(const uint& cc_item_id); virtual void replaceCCItem(const uint& cc_item_id, CComponentsItem* new_cc_Item); virtual void replaceCCItem(CComponentsItem* old_cc_Item, CComponentsItem* new_cc_Item); + virtual void exchangeCCItem(const uint& item_id_a, const uint& item_id_b); + virtual void exchangeCCItem(CComponentsItem* item_a, CComponentsItem* item_b); virtual int getCCItemId(CComponentsItem* cc_Item); virtual CComponentsItem* getCCItem(const uint& cc_item_id); virtual void paintCCItems(); virtual void clearCCItems(); virtual void cleanCCForm(); + virtual void setAppendOffset(const int &h_offset, const int& v_offset){append_h_offset = h_offset; append_v_offset = v_offset;}; + ///property: returns true, if item already added to form + virtual bool isAdded(CComponentsItem *cc_item); }; class CComponentsIconForm : public CComponentsForm @@ -101,25 +111,23 @@ class CComponentsIconForm : public CComponentsForm class CComponentsHeader : public CComponentsForm { - private: + protected: CComponentsPicture * cch_icon_obj; CComponentsText * cch_text_obj; CComponentsIconForm * cch_btn_obj; std::string cch_text; const char* cch_icon_name; - neutrino_locale_t cch_locale_text; fb_pixel_t cch_col_text; Font* cch_font; - int cch_icon_x, cch_items_y, cch_text_x, ccif_width, cch_icon_w, cch_buttons, cch_btn_offset; + int cch_items_y, cch_icon_x, cch_icon_w, cch_text_x, cch_buttons, cch_buttons_w, cch_buttons_h, cch_buttons_space, cch_offset; std::vector v_cch_btn; - void initCCHeaderIcon(); - void initCCHeaderText(); - void initCCHeaderButtons(); - void initCCHDefaultButtons(); - void initCCButtonFormSize(); + void initIcon(); + void initCaption(); + void initButtons(); + void initDefaultButtons(); + void initButtonFormSize(); - protected: void initVarHeader(); public: @@ -143,33 +151,87 @@ class CComponentsHeader : public CComponentsForm fb_pixel_t color_frame = COL_MENUCONTENT_PLUS_6, fb_pixel_t color_body = COL_MENUHEAD_PLUS_0, fb_pixel_t color_shadow = COL_MENUCONTENTDARK_PLUS_0); CComponentsHeader(const int x_pos, const int y_pos, const int w, const int h = 0, neutrino_locale_t caption_locale = NONEXISTANT_LOCALE, const char* icon_name = NULL, const int buttons = 0,bool has_shadow = CC_SHADOW_OFF, fb_pixel_t color_frame = COL_MENUCONTENT_PLUS_6, fb_pixel_t color_body = COL_MENUHEAD_PLUS_0, fb_pixel_t color_shadow = COL_MENUCONTENTDARK_PLUS_0); - ~CComponentsHeader(); + virtual ~CComponentsHeader(); - void paint(bool do_save_bg = CC_SAVE_SCREEN_YES); - void setHeaderText(const std::string& caption); - void setHeaderText(neutrino_locale_t caption_locale); - void setColorHeaderBody(fb_pixel_t text_color){cch_col_text = text_color;}; - void setHeaderButtonOffset(const int offset){cch_btn_offset = offset;}; - void setHeaderIcon(const char* icon_name); - void addHeaderButton(const std::string& button_name); - void removeHeaderButtons(); - void setHeaderDefaultButtons(const int buttons); - void initCCHeaderItems(); + + virtual void setCaption(const std::string& caption); + virtual void setCaption(neutrino_locale_t caption_locale); + virtual void setCaptionFont(Font* font_name); + virtual void setCaptionColor(fb_pixel_t text_color){cch_col_text = text_color;}; + virtual void setOffset(const int offset){cch_offset = offset;}; + virtual void setIcon(const char* icon_name); + virtual void addButtonIcon(const std::string& button_name); + virtual void removeButtonIcons(); + virtual void setDefaultButtons(const int buttons); + virtual void setButtonsSpace(const int buttons_space){cch_buttons_space = buttons_space;}; + virtual void initCCItems(); + + virtual void paint(bool do_save_bg = CC_SAVE_SCREEN_YES); }; + +class CComponentsFooter : public CComponentsHeader +{ + protected: + void initVarFooter(); + public: + CComponentsFooter(); + CComponentsFooter( const int x_pos, const int y_pos, const int w, const int h = 0, + const int buttons = 0, + bool has_shadow = CC_SHADOW_OFF, + fb_pixel_t color_frame = COL_MENUCONTENT_PLUS_6, fb_pixel_t color_body = COL_INFOBAR_SHADOW_PLUS_1, fb_pixel_t color_shadow = COL_MENUCONTENTDARK_PLUS_0); +}; + +//! Sub class of CComponentsForm. Shows a window with prepared items. +/*! +CComponentsWindow provides prepared items like header, footer and a container for +items like text, labels, pictures ... +*/ +/* + x + y+-------------------------------------------------------+ + |icon caption buttons |header (ccw_head) + +-x-----------------------------------------------------+ + |cc_item0 | + |cc_item1 |body (ccw_body) + | add items here directly with | + | addWindowItem() or | + y with ccw_body->addCCItem() | + | Note: x/y related to body object | + | | + +-------------------------------------------------------+ + | add cc_items with ccw_footer->addCCItem() |footer(ccw_footer) + +-------------------------------------------------------+ + +*/ + class CComponentsWindow : public CComponentsForm { private: + ///object: header object, to get access to header properties see also getHeaderObject() CComponentsHeader * ccw_head; + ///object: body object, this is the container for all needed items, to add with addWindowItem() + CComponentsForm * ccw_body; + ///object: footer object, to get access to header properties see also getFooterObject( + CComponentsForm * ccw_footer; + ///property: caption in header, see also getHeaderObject() std::string ccw_caption; + ///property: icon name in header, see also getHeaderObject() const char* ccw_icon_name; - int ccw_start_y; + ///property: assigned default icon buttons in header, see also getHeaderObject() int ccw_buttons; + ///initialze header object void initHeader(); + ///initialze body object + void initBody(); + ///initialze footer object + void initFooter(); + ///initialze all window objects at once void initCCWItems(); protected: + ///initialize all attributes void initVarWindow(); public: @@ -177,17 +239,64 @@ class CComponentsWindow : public CComponentsForm { CC_WINDOW_ITEM_HEADER = 0 }; + ///simple constructor for CComponentsWindow CComponentsWindow(); + + ///advanced constructor for CComponentsWindow, provides parameters for the most required properties, and caption as string + CComponentsWindow( const int x_pos, const int y_pos, const int w, const int h, + const std::string& caption, + const char* iconname = NULL, + bool has_shadow = CC_SHADOW_OFF, + fb_pixel_t color_frame = COL_MENUCONTENT_PLUS_6, + fb_pixel_t color_body = COL_MENUCONTENT_PLUS_0, + fb_pixel_t color_shadow = COL_MENUCONTENTDARK_PLUS_0); + + ///advanced constructor for CComponentsWindow, provides parameters for the most required properties, and caption from locales + CComponentsWindow( const int x_pos, const int y_pos, const int w, const int h, + neutrino_locale_t locale_caption, + const char* iconname = NULL, + bool has_shadow = CC_SHADOW_OFF, + fb_pixel_t color_frame = COL_MENUCONTENT_PLUS_6, + fb_pixel_t color_body = COL_MENUCONTENT_PLUS_0, + fb_pixel_t color_shadow = COL_MENUCONTENTDARK_PLUS_0); + + ///simple constructor for CComponentsWindow, provides parameters for caption as string and icon, position of window is general centered and bound + ///to current screen settings, this shows a window over full screen CComponentsWindow(const std::string& caption, const char* iconname = NULL); + + ///simple constructor for CComponentsWindow, provides parameters for caption from locales and icon, position of window is general centered and bound + ///to current screen settings, this shows a window over full screen CComponentsWindow(neutrino_locale_t locale_caption, const char* iconname = NULL); + ~CComponentsWindow(); + ///paint window void paint(bool do_save_bg = CC_SAVE_SCREEN_YES); + + ///add item to body object, also usable is addCCItem() to add items to the windo object + void addWindowItem(CComponentsItem* cc_Item); + + ///set caption in header with string, see also getHeaderObject() void setWindowCaption(const std::string& text){ccw_caption = text;}; + + ///set caption in header from locales, see also getHeaderObject() void setWindowCaption(neutrino_locale_t locale_text); + + ///set icon name in header, see also getHeaderObject() void setWindowIcon(const char* iconname){ccw_icon_name = iconname;}; + + ///set default header icon buttons, see also getHeaderObject() void setWindowHeaderButtons(const int& buttons){ccw_buttons = buttons;}; + ///returns a pointer to the internal header object, use this to get access to header properities + CComponentsHeader* getHeaderObject(){return ccw_head;}; + + ///returns a pointer to the internal body object, use this to get access to body properities + CComponentsForm* getBodyObject(){return ccw_body;}; + + ///returns a pointer to the internal footer object, use this to get access to footer properities + CComponentsForm* getFooterObject(){return ccw_footer;}; + int getStartY(); //y value for start of the area below header }; diff --git a/src/gui/components/cc_frm_button.cpp b/src/gui/components/cc_frm_button.cpp index b9478d334..b302caee5 100644 --- a/src/gui/components/cc_frm_button.cpp +++ b/src/gui/components/cc_frm_button.cpp @@ -33,6 +33,7 @@ #include "cc_frm_button.h" #define FRAME_TH 3 +#define H_SPACE 4 using namespace std; @@ -84,18 +85,28 @@ void CComponentsButton::initIcon() cc_btn_icon_obj = NULL; return; } - + + //initialize icon object if (cc_btn_icon_obj == NULL){ cc_btn_icon_obj = new CComponentsPicture(0, 0, 0, 0, cc_btn_icon); - addCCItem(cc_btn_icon_obj); } + //get first icon dimensions + int icon_w = cc_btn_icon_obj->getWidth(); + int icon_h = cc_btn_icon_obj->getHeight(); + + //position of icon default centered + int icon_x = width/2-icon_w/2; + int icon_y = height/2-icon_h/2; + + //set properties to picture object if (cc_btn_icon_obj){ - cc_btn_icon_obj->setDimensionsAll(this->getRealXPos(), this->getRealYPos(), height/*-2*fr_thickness*/, height-2*fr_thickness); + cc_btn_icon_obj->setPos(icon_x, icon_y); cc_btn_icon_obj->setPictureAlign(CC_ALIGN_HOR_CENTER | CC_ALIGN_VER_CENTER); cc_btn_icon_obj->doPaintBg(false); } + } void CComponentsButton::initCaption() @@ -105,16 +116,22 @@ void CComponentsButton::initCaption() addCCItem(cc_btn_capt_obj); } - - int cap_x = this->getRealXPos()+(width/2)-(cc_btn_text_w/2); - int cap_h = height/*-2*fr_thickness*/; - int cap_y = this->getRealYPos(); - - if (cc_btn_icon_obj) - cap_x = this->getRealXPos()+cc_btn_icon_obj->getWidth(); + //text position is default centere + int cap_x = (width/2)-(cc_btn_text_w/2); + int cap_y = (height/2)-(cc_btn_text_h/2); + + //if we have a icon, then we must calculate centered position for booth items together + if (cc_btn_icon_obj){ + int face_w = cc_btn_icon_obj->getWidth() + H_SPACE + cc_btn_text_w + 2*fr_thickness; + int face_x = width/2 - face_w/2; + cc_btn_icon_obj->setXPos(face_x); + cap_x = face_x + cc_btn_icon_obj->getWidth() + H_SPACE; + } + + //set properties to label object if (cc_btn_capt_obj){ - cc_btn_capt_obj->setDimensionsAll(cap_x, cap_y, width-cap_x, cap_h); + cc_btn_capt_obj->setDimensionsAll(cap_x, cap_y, width-cap_x, height); cc_btn_capt_obj->setTextColor(this->cc_item_enabled ? COL_MENUCONTENT : COL_MENUCONTENTINACTIVE); cc_btn_capt_obj->setText(cc_btn_capt, CTextBox::NO_AUTO_LINEBREAK, cc_btn_font); cc_btn_capt_obj->forceTextPaint(); //here required; diff --git a/src/gui/components/cc_frm_button.h b/src/gui/components/cc_frm_button.h index b7cac5f2c..915288498 100644 --- a/src/gui/components/cc_frm_button.h +++ b/src/gui/components/cc_frm_button.h @@ -31,26 +31,42 @@ #include "cc_frm.h" #include - +//! Sub class of CComponentsForm. +/*! +Shows a button box with caption and optional icon. +*/ class CComponentsButton : public CComponentsForm { protected: - void initVarButton(); - - ///caption and icon properties - std::string cc_btn_capt; //text - std::string cc_btn_icon; //icon name, only icons supported, to find in gui/widget/icons.h - fb_pixel_t cc_btn_capt_col; //text color - Font* cc_btn_font; //text font - int cc_btn_text_w, cc_btn_text_h; //width and height of text, too long text will be truncated - - ///icon and text objects + ///object: picture object CComponentsPicture *cc_btn_icon_obj; + ///object: label object CComponentsLabel *cc_btn_capt_obj; - ///initialize of objects + ///initialize all required attributes and objects + void initVarButton(); + + ///property: button text + std::string cc_btn_capt; + ///property: icon name, only icons supported, to find in gui/widget/icons.h + std::string cc_btn_icon; + + ///property: text color + fb_pixel_t cc_btn_capt_col; + ///object: text font + Font* cc_btn_font; + ///property: label object width, too long text will be truncated + int cc_btn_text_w; + ///property: label object heigth + int cc_btn_text_h; + + + ///initialize picture object void initIcon(); + ///initialize label object void initCaption(); + + ///initialize picture and label object void initCCBtnItems(); public: @@ -59,12 +75,18 @@ class CComponentsButton : public CComponentsForm const std::string& caption, const std::string& icon_name, bool selected = false, bool enabled = true, bool has_shadow = CC_SHADOW_OFF, fb_pixel_t color_frame = COL_LIGHT_GRAY, fb_pixel_t color_body = COL_MENUCONTENT_PLUS_0, fb_pixel_t color_shadow = COL_MENUCONTENTDARK_PLUS_0); - + + ///set text color virtual void setButtonTextColor(fb_pixel_t caption_color){cc_btn_capt_col = caption_color;}; + + ///paint button object void paint(bool do_save_bg = CC_SAVE_SCREEN_YES); }; -///sub classes for button objects with most needed params, and predefined color buttons, but functionality is the same as in CComponentsButton +//! Sub class of CComponentsButton. +/*! +Shows a button box with caption and prepared red icon. +*/ class CComponentsButtonRed : public CComponentsButton { public: @@ -78,6 +100,10 @@ class CComponentsButtonRed : public CComponentsButton }; }; +//! Sub class of CComponentsButton. +/*! +Shows a button box with caption and prepared green icon. +*/ class CComponentsButtonGreen : public CComponentsButton { public: @@ -91,6 +117,10 @@ class CComponentsButtonGreen : public CComponentsButton }; }; +//! Sub class of CComponentsButton. +/*! +Shows a button box with caption and prepared yellow icon. +*/ class CComponentsButtonYellow : public CComponentsButton { public: @@ -104,6 +134,10 @@ class CComponentsButtonYellow : public CComponentsButton }; }; +//! Sub class of CComponentsButton. +/*! +Shows a button box with caption and prepared blue icon. +*/ class CComponentsButtonBlue : public CComponentsButton { public: diff --git a/src/gui/components/cc_frm_clock.cpp b/src/gui/components/cc_frm_clock.cpp new file mode 100644 index 000000000..3636c7a34 --- /dev/null +++ b/src/gui/components/cc_frm_clock.cpp @@ -0,0 +1,333 @@ +/* + Based up Neutrino-GUI - Tuxbox-Project + Copyright (C) 2001 by Steffen Hehn 'McClean' + + Generic GUI-related component. + Copyright (C) 2013, Thilo Graf 'dbt' + + License: GPL + + 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. +*/ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include +#include + +#include "cc_frm_clock.h" +#include +#include +#include +#include + +using namespace std; + +CComponentsFrmClock::CComponentsFrmClock( const int x_pos, const int y_pos, const int w, const int h, + const char* format_str, bool activ, bool has_shadow, + fb_pixel_t color_frame, fb_pixel_t color_body, fb_pixel_t color_shadow) + +{ + initVarClock(); + + x = x_pos; + y = y_pos; + width = w; + height = h; + shadow = has_shadow; + shadow_w = SHADOW_OFFSET; + col_frame = color_frame; + col_body = color_body; + col_shadow = color_shadow; + + paintClock = false; + activeClock = activ; + if (activeClock) + startThread(); + + cl_format_str = format_str; +} + +void CComponentsFrmClock::initVarClock() +{ + initVarForm(); + cc_item_type = CC_ITEMTYPE_FRM_CLOCK; + corner_rad = RADIUS_SMALL; + + cl_font_type = SNeutrinoSettings::FONT_TYPE_INFOBAR_INFO; + cl_font = NULL; + cl_col_text = COL_MENUCONTENT; + cl_format_str = "%H:%M"; + cl_align = CC_ALIGN_VER_CENTER | CC_ALIGN_HOR_CENTER; +// cl_force_segment_paint = false; + + cl_thread = 0; + cl_interval = 1; +} + +CComponentsFrmClock::~CComponentsFrmClock() +{ + cleanCCForm(); + if (activeClock) + stopThread(); +} + +void CComponentsFrmClock::initTimeString() +{ + time_t tm = time(0); + strftime((char*) &cl_timestr, sizeof(cl_timestr), cl_format_str, localtime(&tm)); +} + +// How does it works? +// We don't paint complete date or time string at once, because of individual possible formats, +// so we split timestring and assign only one char to one lable (segment) + +// x/y width +// +--------------------------+ +// ||lbl0|lbl1|lbl2|lbl3|lbl4|| +// || | | | | ||height +// || | | | | || +// +--------------------------+ + +// So every item (lable or segment) contains only one char depending on specified format. eg: format %H:%M gives 5 items. +// The effort is slightly greater and it's necessary to avoid flicker effect, but it's more flexible. + +void CComponentsFrmClock::initCCLockItems() +{ + initTimeString(); + string s_time = cl_timestr; + + cl_font = g_Font[cl_font_type]; + + //get minimal required height, width from raw text + int min_text_w = cl_font->getRenderWidth(s_time, true);; + int min_text_h = cl_font->getHeight(); + height = max(height, min_text_h); + width = max(width, min_text_w); + + int cl_x = 0; + int cl_h = min_text_h; + int cl_y = 0; + int w_lbl_tmp = 0; + + //create label objects and add to container, ensure count of items = count of chars (one char = one segment) + if (v_cc_items.size() != s_time.size()){ + + //clean up possible old items before add new items + clearCCItems(); + + //create new empty label objects, set some general properties and add to container + for (size_t i = 0; i < s_time.size(); i++){ + CComponentsLabel * lbl = new CComponentsLabel(); + addCCItem(lbl); + + //background paint of item is not required + lbl->doPaintBg(false); + + //set corner properties of label item + lbl->setCornerRadius(corner_rad-fr_thickness); + lbl->setCornerType(corner_type); + + //set text border to 0 + lbl->setTextBorderWidth(0); + } + } + + //modifie available lable items with current segment chars + for (size_t i = 0; i < v_cc_items.size(); i++) + { + //v_cc_items are only available as CComponent-items here, so we must cast them before + CComponentsLabel *lbl = static_cast (v_cc_items[i]); + + //add rounded corners only to 1st and last segment + if (corner_type) { + if (i == 0) + lbl->setCornerType(corner_type & CORNER_LEFT);// 1st label item + else if (i == v_cc_items.size()-1) + lbl->setCornerType(corner_type & CORNER_RIGHT);// last label item + else + lbl->setCornerType(0);// inner items + } + + //extract timestring segment (char) + string stmp = s_time.substr(i, 1); + + //get width of current segment + int wtmp = cl_font->getRenderWidth(stmp, true); + + //set size, text, color of current item + lbl->setDimensionsAll(cl_x, cl_y, wtmp, cl_h); + lbl->setTextColor(cl_col_text); + lbl->setColorAll(col_frame, col_body, col_shadow); + lbl->setText(stmp, CTextBox::CENTER, cl_font); + + //use matching height for digits for better vertical centerring into form + CTextBox* ctb = lbl->getCTextBoxObject(); + if (ctb) + ctb->setFontUseDigitHeight(); + + //ensure paint of text and label bg on changed text or painted form background + bool force_txt_and_bg = (lbl->textChanged() || this->paint_bg); + lbl->forceTextPaint(force_txt_and_bg); + lbl->doPaintTextBoxBg(force_txt_and_bg); + + //set xpos of item + cl_x += wtmp; + + lbl->setWidth(wtmp); + + //set current width for form + w_lbl_tmp += wtmp; + } + + //set required width + width = max(width, w_lbl_tmp); + + initSegmentAlign(&w_lbl_tmp, &min_text_h); +} + +//handle alignment +void CComponentsFrmClock::initSegmentAlign(int* segment_width, int* segment_height) +{ + int wadd = 0; + int hadd = 0; + int* w_lbl_tmp = segment_width; + int* min_text_h = segment_height; + + //use first item as reference and set x and y position to the 1st segement item with definied alignment + if (cl_align & CC_ALIGN_RIGHT){ + wadd = width-*w_lbl_tmp; + v_cc_items[0]->setXPos(wadd); + } + else if (cl_align & CC_ALIGN_LEFT){ + v_cc_items[0]->setXPos(wadd); + } + else if (cl_align & CC_ALIGN_HOR_CENTER){ + hadd = height/2-*min_text_h/2; + v_cc_items[0]->setYPos(hadd); + } + + if (cl_align & CC_ALIGN_TOP){ + v_cc_items[0]->setYPos(hadd); + } + else if (cl_align & CC_ALIGN_BOTTOM){ + hadd = height-*min_text_h; + v_cc_items[0]->setYPos(hadd); + } + else if (cl_align & CC_ALIGN_VER_CENTER){ + wadd = width/2-*w_lbl_tmp/2; + v_cc_items[0]->setXPos(wadd); + } + + //set all evaluated position values to all other segement items + for (size_t i = 1; i < v_cc_items.size(); i++){ + wadd += v_cc_items[i-1]->getWidth(); + v_cc_items[i]->setPos(wadd, hadd); + } +} + +//thread handle +void* CComponentsFrmClock::initClockThread(void *arg) +{ + pthread_setcancelstate(PTHREAD_CANCEL_ENABLE,0); + pthread_setcanceltype (PTHREAD_CANCEL_ASYNCHRONOUS,0); + + CComponentsFrmClock *clock = static_cast(arg); + time_t count = time(0); + //start loop for paint + while(1) { + sleep(clock->cl_interval); + + if (clock->paintClock) { + //paint segements, but wihtout saved backgrounds + clock->paint(CC_SAVE_SCREEN_NO); + count = time(0); + } + if (time(0) >= count+30) { + clock->cl_thread = 0; + break; + } + } + return 0; +} + +//start up ticking clock with own thread, return true on succses +bool CComponentsFrmClock::startThread() +{ + void *ptr = static_cast(this); + + if(!cl_thread) { + int res = pthread_create (&cl_thread, NULL, initClockThread, ptr) ; + if (res != 0){ + printf("[CComponentsFrmClock] [%s] pthread_create %s\n", __FUNCTION__, strerror(errno)); + return false; + } + } + return true; +} + +//stop ticking clock and kill thread, return true on succses +bool CComponentsFrmClock::stopThread() +{ + if(cl_thread) { + int res = pthread_cancel(cl_thread); + if (res != 0){ + printf("[CComponentsFrmClock] [%s] pthread_cancel %s\n", __FUNCTION__, strerror(errno)); + return false; + } + + res = pthread_join(cl_thread, NULL); + if (res != 0){ + printf("[CComponentsFrmClock] [%s] pthread_join %s\n", __FUNCTION__, strerror(errno)); + return false; + } + } + cl_thread = 0; + return true; +} + +bool CComponentsFrmClock::Start() +{ + if (!activeClock) + return false; + if (!cl_thread) + startThread(); + if (cl_thread) { + //ensure paint of segements on first paint + paint(); + paintClock = true; + } + return cl_thread == 0 ? false : true; +} + +bool CComponentsFrmClock::Stop() +{ + if (!activeClock) + return false; + paintClock = false; + return cl_thread == 0 ? false : true; +} + +void CComponentsFrmClock::paint(bool do_save_bg) +{ + //prepare items before paint + initCCLockItems(); + + //paint form contents + paintForm(do_save_bg); +} diff --git a/src/gui/components/cc_frm_clock.h b/src/gui/components/cc_frm_clock.h new file mode 100644 index 000000000..e67fecdee --- /dev/null +++ b/src/gui/components/cc_frm_clock.h @@ -0,0 +1,122 @@ +/* + Based up Neutrino-GUI - Tuxbox-Project + Copyright (C) 2001 by Steffen Hehn 'McClean' + + Classes for generic GUI-related components. + Copyright (C) 2012, 2013, Thilo Graf 'dbt' + + License: GPL + + 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. +*/ + +#ifndef __CC_CLOCK__ +#define __CC_CLOCK__ + + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include "cc.h" +#include "cc_frm.h" + + +//! Sub class of CComponents. Show clock with digits on screen. +/*! +Usable as simple fixed display or as ticking clock. +*/ + +class CComponentsFrmClock : public CComponentsForm +{ + private: + +// bool cl_force_segment_paint; + + protected: + ///thread + pthread_t cl_thread; + ///refresh interval in seconds + int cl_interval; + ///init function to start clock in own thread + static void* initClockThread(void *arg); + + ///raw time chars + char cl_timestr[20]; + + bool paintClock; + bool activeClock; + + ///font + int cl_font_type; + ///fontrenderer object + Font *cl_font; + ///text color + int cl_col_text; + ///time format + const char* cl_format_str; + ///time string align, default allign is ver and hor centered + int cl_align; + + ///initialize all attributes and required objects + void initVarClock(); + + ///initialize clock contents + void initCCLockItems(); + ///initialize timestring, called in initCCLockItems() + void initTimeString(); + ///initialize of general alignment of timestring segments within form area + void initSegmentAlign(int* segment_width, int* segment_height); + + public: + CComponentsFrmClock( const int x_pos, const int y_pos, const int w, const int h, + const char* format_str = "%H:%M", bool activ=true, bool has_shadow = CC_SHADOW_OFF, + fb_pixel_t color_frame = COL_LIGHT_GRAY, fb_pixel_t color_body = COL_MENUCONTENT_PLUS_0, fb_pixel_t color_shadow = COL_MENUCONTENTDARK_PLUS_0); + ~CComponentsFrmClock(); + + ///set font type for segments + void setClockFontType(const int& font_type){cl_font_type = font_type;}; + + ///set text color + void setTextColor(fb_pixel_t color_text){ cl_col_text = color_text;}; + + ///set alignment of timestring, possible modes see align types in cc_types.h + void setClockAlignment(int align_type){cl_align = align_type;}; + + ///use string expession: "%H:%M" = 12:22, "%H:%M:%S" = 12:22:12 + void setClockFormat(const char* format_str){cl_format_str = format_str;}; + + ///start ticking clock thread, returns true on success, if false causes log output + bool startThread(); + ///stop ticking clock thread, returns true on success, if false causes log output + bool stopThread(); + + bool Start(); + bool Stop(); + + ///returns true, if clock is running in thread + bool isClockRun() const {return cl_thread == 0 ? false:true;}; + ///set refresh interval in seconds, default value=1 (=1 sec) + void setClockIntervall(const int& seconds){cl_interval = seconds;}; + + ///show clock on screen + void paint(bool do_save_bg = CC_SAVE_SCREEN_YES); + + ///reinitialize clock contents + void refresh() { initCCLockItems(); } +}; + +#endif diff --git a/src/gui/components/cc_frm_footer.cpp b/src/gui/components/cc_frm_footer.cpp new file mode 100644 index 000000000..0a07cbf5e --- /dev/null +++ b/src/gui/components/cc_frm_footer.cpp @@ -0,0 +1,74 @@ +/* + Based up Neutrino-GUI - Tuxbox-Project + Copyright (C) 2001 by Steffen Hehn 'McClean' + + Classes for generic GUI-related components. + Copyright (C) 2013, Thilo Graf 'dbt' + + License: GPL + + 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. +*/ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include +#include +#include "cc_frm.h" + +using namespace std; + +//------------------------------------------------------------------------------------------------------- +//sub class CComponentsFooter inherit from CComponentsHeader +CComponentsFooter::CComponentsFooter() +{ + //CComponentsFooter + initVarFooter(); +} + +CComponentsFooter::CComponentsFooter( const int x_pos, const int y_pos, const int w, const int h, const int buttons, bool has_shadow, + fb_pixel_t color_frame, fb_pixel_t color_body, fb_pixel_t color_shadow ) +{ + //CComponentsFooter + initVarFooter(); + + x = x_pos; + y = y_pos; + width = w; + height = h; + shadow = has_shadow; + col_frame = color_frame; + col_body = color_body; + col_shadow = color_shadow; + + cch_buttons = buttons; + + initDefaultButtons(); + initCCItems(); +} + + +void CComponentsFooter::initVarFooter() +{ + //CComponentsHeader + initVarHeader(); + + cc_item_type = CC_ITEMTYPE_FOOTER; + corner_rad = RADIUS_LARGE; + corner_type = CORNER_BOTTOM; +} diff --git a/src/gui/components/cc_frm_header.cpp b/src/gui/components/cc_frm_header.cpp index 1f5694919..4e9067f3a 100644 --- a/src/gui/components/cc_frm_header.cpp +++ b/src/gui/components/cc_frm_header.cpp @@ -51,7 +51,7 @@ CComponentsHeader::CComponentsHeader( const int x_pos, const int y_pos, const in x = x_pos; y = y_pos; width = w; - height = h > 0 ? h : g_Font[SNeutrinoSettings::FONT_TYPE_MENU_TITLE]->getHeight(); + height = h > 0 ? h : height; shadow = has_shadow; col_frame = color_frame; col_body = color_body; @@ -60,8 +60,9 @@ CComponentsHeader::CComponentsHeader( const int x_pos, const int y_pos, const in cch_text = caption; cch_icon_name = icon_name; cch_buttons = buttons; - initCCHDefaultButtons(); - initCCHeaderItems(); + + initDefaultButtons(); + initCCItems(); } CComponentsHeader::CComponentsHeader( const int x_pos, const int y_pos, const int w, const int h, neutrino_locale_t caption_locale, const char* icon_name, const int buttons, bool has_shadow, @@ -73,18 +74,18 @@ CComponentsHeader::CComponentsHeader( const int x_pos, const int y_pos, const in x = x_pos; y = y_pos; width = w; - height = h; + height = h > 0 ? h : height; shadow = has_shadow; col_frame = color_frame; col_body = color_body; col_shadow = color_shadow; - cch_locale_text = caption_locale; + cch_text = g_Locale->getText(caption_locale); cch_icon_name = icon_name; cch_buttons = buttons; - initCCHDefaultButtons(); - initCCHeaderItems(); + initDefaultButtons(); + initCCItems(); } void CComponentsHeader::initVarHeader() @@ -105,19 +106,18 @@ void CComponentsHeader::initVarHeader() cch_text_obj = NULL; cch_icon_name = NULL; cch_btn_obj = NULL; - cch_text = "header"; - cch_locale_text = NONEXISTANT_LOCALE; + cch_text = ""; cch_col_text = COL_MENUHEAD; cch_items_y = 0; - cch_icon_x = 0; - cch_icon_w = 5; - cch_text_x = 0; - ccif_width = 0; + cch_offset = 8; + cch_icon_x = cch_offset; + cch_icon_w = 0; + cch_text_x = cch_offset; cch_buttons = 0; - cch_btn_offset = 8; + cch_buttons_w = 0; + cch_buttons_h = 0; + cch_buttons_space = cch_offset; v_cch_btn.clear(); - - } CComponentsHeader::~CComponentsHeader() @@ -129,29 +129,32 @@ CComponentsHeader::~CComponentsHeader() cleanCCForm(); } -void CComponentsHeader::setHeaderText(const std::string& caption) +void CComponentsHeader::setCaption(const std::string& caption) { cch_text = caption; } -void CComponentsHeader::setHeaderText(neutrino_locale_t caption_locale) +void CComponentsHeader::setCaption(neutrino_locale_t caption_locale) { cch_text = g_Locale->getText(caption_locale); } -void CComponentsHeader::setHeaderIcon(const char* icon_name) +void CComponentsHeader::setCaptionFont(Font* font_name) +{ + cch_font = font_name; + height = std::max(height, cch_font->getHeight()); +} + +void CComponentsHeader::setIcon(const char* icon_name) { cch_icon_name = icon_name; } -void CComponentsHeader::initCCHeaderIcon() +void CComponentsHeader::initIcon() { - //reset cch_icon_w - cch_icon_w = cch_btn_offset; - //init cch_icon_obj only if an icon available if (cch_icon_name == NULL) { - cch_icon_w = cch_btn_offset; + cch_icon_w = 0; if (cch_icon_obj) delete cch_icon_obj; cch_icon_obj = NULL; @@ -163,17 +166,21 @@ void CComponentsHeader::initCCHeaderIcon() #ifdef DEBUG_CC printf(" [CComponentsHeader]\n [%s - %d] init header icon: %s\n", __FUNCTION__, __LINE__, cch_icon_name); #endif - cch_icon_obj = new CComponentsPicture(cch_icon_x, cch_items_y, 0, 0, cch_icon_name); + cch_icon_obj = new CComponentsPicture(cch_icon_x, cch_items_y, 0, 0, cch_icon_name); //add item only one time addCCItem(cch_icon_obj); //icon } + //get dimensions of header icon + int iw, ih; + frameBuffer->getIconSize(cch_icon_name, &iw, &ih); + //set properties for icon object if (cch_icon_obj){ - cch_icon_obj->setWidth(height-2*fr_thickness); - cch_icon_obj->setHeight(height); - cch_icon_obj->setPictureAlign(CC_ALIGN_HOR_CENTER | CC_ALIGN_VER_CENTER); + cch_icon_obj->setWidth(iw); + cch_icon_obj->setHeight(ih); cch_icon_obj->doPaintBg(false); + cch_icon_obj->setPictureAlign(CC_ALIGN_HOR_CENTER | CC_ALIGN_VER_CENTER); //set corner mode of icon item cch_icon_obj->setCornerRadius(corner_rad-fr_thickness); @@ -184,29 +191,31 @@ void CComponentsHeader::initCCHeaderIcon() cc_icon_corner_type = CORNER_LEFT; cch_icon_obj->setCornerType(cc_icon_corner_type); - //set width of icon object + //global set width of icon object cch_icon_w = cch_icon_obj->getWidth(); - //adapt height - height = max(height, cch_icon_obj->getHeight()); + //global adapt height + height = max(height, cch_icon_obj->getHeight()); + + //re-align height of icon object + cch_icon_obj->setHeight(height); } } -void CComponentsHeader::addHeaderButton(const std::string& button_name) +void CComponentsHeader::addButtonIcon(const std::string& button_name) { v_cch_btn.push_back(button_name); - initCCHeaderButtons(); + initButtons(); } -void CComponentsHeader::removeHeaderButtons() +void CComponentsHeader::removeButtonIcons() { v_cch_btn.clear(); cch_btn_obj->removeAllIcons(); - initCCHeaderButtons(); - + initButtons(); } -void CComponentsHeader::initCCHDefaultButtons() +void CComponentsHeader::initDefaultButtons() { if (cch_buttons & CC_BTN_EXIT) v_cch_btn.push_back(NEUTRINO_ICON_BUTTON_HOME); @@ -221,31 +230,34 @@ void CComponentsHeader::initCCHDefaultButtons() #endif } -void CComponentsHeader::setHeaderDefaultButtons(const int buttons) +void CComponentsHeader::setDefaultButtons(const int buttons) { cch_buttons = buttons; v_cch_btn.clear(); - initCCHDefaultButtons(); + initDefaultButtons(); } // calculate minimal width of icon form -void CComponentsHeader::initCCButtonFormSize() +void CComponentsHeader::initButtonFormSize() { - ccif_width = 0; + cch_buttons_w = 0; + cch_buttons_h = 0; for(size_t i=0; igetIconSize(v_cch_btn[i].c_str(), &bw, &bh); - ccif_width += (bw + cch_btn_offset); + cch_buttons_w += (bw + cch_buttons_space); + cch_buttons_h = std::max(cch_buttons_h, bh); } + cch_buttons_w -= cch_buttons_space; } -void CComponentsHeader::initCCHeaderButtons() +void CComponentsHeader::initButtons() { //exit if no button defined if (v_cch_btn.empty()) return; - initCCButtonFormSize(); + initButtonFormSize(); if (cch_btn_obj == NULL){ cch_btn_obj = new CComponentsIconForm(); @@ -258,25 +270,50 @@ void CComponentsHeader::initCCHeaderButtons() //set button form properties if (cch_btn_obj){ - cch_btn_obj->setDimensionsAll(0+width-ccif_width, 0, ccif_width-cch_btn_offset, height); + cch_btn_obj->setDimensionsAll(width-cch_offset-cch_buttons_w, cch_items_y, cch_buttons_w, cch_buttons_h); cch_btn_obj->doPaintBg(false); - cch_btn_obj->setIconOffset(cch_btn_offset); + cch_btn_obj->setIconOffset(cch_buttons_space); cch_btn_obj->setIconAlign(CComponentsIconForm::CC_ICONS_FRM_ALIGN_RIGHT); cch_btn_obj->removeAllIcons(); cch_btn_obj->addIcon(v_cch_btn); - height = max(height, cch_btn_obj->getHeight()); + + //set corner mode of button item + cch_btn_obj->setCornerRadius(corner_rad-fr_thickness); + int cc_btn_corner_type = corner_type; + if (corner_type == CORNER_TOP_RIGHT || corner_type == CORNER_TOP) + cc_btn_corner_type = CORNER_TOP_RIGHT; + else + cc_btn_corner_type = CORNER_RIGHT; + cch_btn_obj->setCornerType(cc_btn_corner_type); + + //global adapt height + height = max(height, cch_btn_obj->getHeight()); + + //re-align height of button object + cch_btn_obj->setHeight(height); + + //re-align height of icon object + if (cch_icon_obj) + cch_icon_obj->setHeight(height); } } -void CComponentsHeader::initCCHeaderText() +void CComponentsHeader::initCaption() { - //reset header text position first - cch_text_x = cch_icon_x+cch_icon_w; + //recalc header text position if header icon is defined + if (cch_icon_name != NULL){ + cch_text_x = cch_icon_x+cch_icon_w+cch_offset; + } + + //calc width of text object in header + int cc_text_w = width-cch_text_x-cch_offset; + if (cch_buttons_w) + cc_text_w -= cch_buttons_w-cch_offset; //create cch_text_obj and add to collection if (cch_text_obj == NULL){ #ifdef DEBUG_CC - printf(" [CComponentsHeader]\n [%s - %d] init header text: %s\n", __FUNCTION__, __LINE__, cch_text.c_str()); + printf(" [CComponentsHeader]\n [%s - %d] init header text: %s [ x %d w %d ]\n", __FUNCTION__, __LINE__, cch_text.c_str(), cch_text_x, cc_text_w); #endif cch_text_obj = new CComponentsText(); //add text item @@ -285,38 +322,41 @@ void CComponentsHeader::initCCHeaderText() //set header text properties if (cch_text_obj){ - cch_text_obj->setText(cch_text, CTextBox::AUTO_WIDTH, cch_font); + cch_text_obj->setDimensionsAll(cch_text_x, cch_items_y, cc_text_w, height); + cch_text_obj->doPaintBg(false); + cch_text_obj->setText(cch_text, CTextBox::TOP | CTextBox::NO_AUTO_LINEBREAK, cch_font); cch_text_obj->forceTextPaint(); //here required - cch_text_obj->setDimensionsAll(cch_text_x, cch_items_y, width-cch_icon_w-fr_thickness, height-2*fr_thickness); cch_text_obj->setTextColor(cch_col_text); cch_text_obj->setColorBody(col_body); - cch_text_obj->doPaintBg(false); //corner of text item cch_text_obj->setCornerRadius(corner_rad-fr_thickness); cch_text_obj->setCornerType(corner_type); - //get height - height = max(height, cch_text_obj->getHeight()); + /* + global adapt height not needed here again + because this object is initialized at last + */ + //height = max(height, cch_text_obj->getHeight()); } } -void CComponentsHeader::initCCHeaderItems() +void CComponentsHeader::initCCItems() { //init icon - initCCHeaderIcon(); - - //init text - initCCHeaderText(); + initIcon(); //init buttons - initCCHeaderButtons(); + initButtons(); + + //init text + initCaption(); } void CComponentsHeader::paint(bool do_save_bg) { //prepare items - initCCHeaderItems(); + initCCItems(); //paint form contents paintForm(do_save_bg); diff --git a/src/gui/components/cc_frm_window.cpp b/src/gui/components/cc_frm_window.cpp index 05a6e222d..2b1fb257f 100644 --- a/src/gui/components/cc_frm_window.cpp +++ b/src/gui/components/cc_frm_window.cpp @@ -40,6 +40,8 @@ using namespace std; CComponentsWindow::CComponentsWindow() { initVarWindow(); + + initCCWItems(); } CComponentsWindow::CComponentsWindow(const std::string& caption, const char* iconname) @@ -48,6 +50,9 @@ CComponentsWindow::CComponentsWindow(const std::string& caption, const char* ico ccw_caption = caption; ccw_icon_name = iconname; + + initHeader(); + initBody(); } CComponentsWindow::CComponentsWindow(neutrino_locale_t locale_caption, const char* iconname) @@ -56,6 +61,58 @@ CComponentsWindow::CComponentsWindow(neutrino_locale_t locale_caption, const cha ccw_caption = g_Locale->getText(locale_caption); ccw_icon_name = iconname; + + initCCWItems(); +} + +CComponentsWindow::CComponentsWindow( const int x_pos, const int y_pos, const int w, const int h, + neutrino_locale_t locale_caption, + const char* iconname, + bool has_shadow, + fb_pixel_t color_frame, + fb_pixel_t color_body, + fb_pixel_t color_shadow) +{ + initVarWindow(); + + x = x_pos; + y = y_pos; + width = w; + height = h; + shadow = has_shadow; + col_frame = color_frame; + col_body = color_body; + col_shadow = color_shadow; + + ccw_caption = g_Locale->getText(locale_caption); + ccw_icon_name = iconname; + + initCCWItems(); +} + +CComponentsWindow::CComponentsWindow( const int x_pos, const int y_pos, const int w, const int h, + const std::string& caption, + const char* iconname, + bool has_shadow, + fb_pixel_t color_frame, + fb_pixel_t color_body, + fb_pixel_t color_shadow) +{ + initVarWindow(); + + x = x_pos; + y = y_pos; + width = w; + height = h; + shadow = has_shadow; + col_frame = color_frame; + col_body = color_body; + col_shadow = color_shadow; + + ccw_caption = caption;; + ccw_icon_name = iconname; + + initCCWItems(); } CComponentsWindow::~CComponentsWindow() @@ -79,9 +136,10 @@ void CComponentsWindow::initVarWindow() y=getScreenStartY(height); ccw_head = NULL; + ccw_body = NULL; + ccw_footer = NULL; ccw_caption = ""; ccw_icon_name = NULL; - ccw_start_y = 0; ccw_buttons = 0; //no header buttons setShadowOnOff(true); @@ -97,27 +155,68 @@ void CComponentsWindow::initHeader() if (ccw_head == NULL){ ccw_head = new CComponentsHeader(); initHeader(); - //add header item only one time - addCCItem(ccw_head); + //add of header item happens initCCWItems() } //set header properties if (ccw_head){ - ccw_head->setXPos(0); - ccw_head->setYPos(0); + ccw_head->setPos(0, 0); ccw_head->setWidth(width); - ccw_head->setHeaderIcon(ccw_icon_name); - ccw_head->setHeaderText(ccw_caption); - ccw_head->initCCHeaderItems(); - ccw_start_y = ccw_head->getHeight(); - ccw_head->setHeaderDefaultButtons(ccw_buttons); + ccw_head->setIcon(ccw_icon_name); + ccw_head->setCaption(ccw_caption); + ccw_head->initCCItems(); + ccw_head->setDefaultButtons(ccw_buttons); } } +void CComponentsWindow::initBody() +{ + if (ccw_body== NULL){ + ccw_body = new CComponentsForm(); + initBody(); + //add of body item happens initCCWItems() + } + + //set body properties + if (ccw_body){ + ccw_body->setCornerType(0); + int fh = ccw_footer->getHeight(); + int hh = ccw_head->getHeight(); + int h_body = height - hh - fh; + ccw_body->setDimensionsAll(0, CC_APPEND, width, h_body); + ccw_body->doPaintBg(false); + } +} + +void CComponentsWindow::initFooter() +{ + if (ccw_footer== NULL){ + + ccw_footer= new CComponentsFooter(); + initFooter(); + //add of footer item happens initCCWItems() + } + + //set footer properties + if (ccw_footer){ + ccw_footer->setPos(0, CC_APPEND); + ccw_footer->setWidth(width); + ccw_footer->setShadowOnOff(shadow); + } +} + +void CComponentsWindow::addWindowItem(CComponentsItem* cc_Item) +{ + if (ccw_body) + ccw_body->addCCItem(cc_Item); +} + int CComponentsWindow::getStartY() { - initHeader(); - return ccw_start_y; + if (ccw_head) + return ccw_head->getHeight(); + + return 0; } void CComponentsWindow::initCCWItems() @@ -126,6 +225,16 @@ void CComponentsWindow::initCCWItems() printf("[CComponentsWindow] [%s - %d] init items...\n", __FUNCTION__, __LINE__); #endif initHeader(); + initFooter(); + initBody(); + + //add header, body and footer items only one time + if (!isAdded(ccw_head)) + addCCItem(ccw_head); + if (!isAdded(ccw_body)) + addCCItem(ccw_body); + if (!isAdded(ccw_footer)) + addCCItem(ccw_footer); } void CComponentsWindow::paint(bool do_save_bg) diff --git a/src/gui/components/cc_item.cpp b/src/gui/components/cc_item.cpp index d621b0cae..7f9362bb1 100644 --- a/src/gui/components/cc_item.cpp +++ b/src/gui/components/cc_item.cpp @@ -54,7 +54,6 @@ void CComponentsItem::initVarItem() //CComponents initVarBasic(); cc_item_index = CC_NO_INDEX; - cc_item_xr = cc_item_yr = -1; cc_item_enabled = true; cc_item_selected = false; cc_parent = NULL; @@ -78,33 +77,29 @@ void CComponentsItem::paintInit(bool do_save_bg) //calculate current needed corner radius for body box, depends of frame thickness int rad = (corner_rad>th) ? corner_rad-th : corner_rad; + int sw = (shadow) ? shadow_w : 0; - int sw = 0, sw_cur = 0; - int x_sh = x + width; - int y_sh = y + height; - if (shadow) { - sw = shadow_w; - sw_cur = sw; - if (corner_type && corner_rad) { - //calculate positon of shadow areas - x_sh += sw - 2*corner_rad; - y_sh += sw - 2*corner_rad; - //calculate current shadow width depends of current corner_rad - sw_cur = max(2*corner_rad, sw); - } + //if item is bound on a parent form, we must use real x/y values and from parent form as reference + int ix = x, iy = y; + if (cc_parent){ + ix = cc_xr + cc_parent->getFrameThickness(); + iy = cc_yr + cc_parent->getFrameThickness(); } - + comp_fbdata_t fbdata[] = { - {CC_FBDATA_TYPE_BGSCREEN, x, y, width+sw, height+sw, 0, 0, 0, NULL, NULL}, - {CC_FBDATA_TYPE_BOX, x_sh, y+sw, sw_cur, height, col_shadow, corner_rad, 0, NULL, NULL},//shadow right - {CC_FBDATA_TYPE_BOX, x+sw, y_sh, width, sw_cur, col_shadow, corner_rad, 0, NULL, NULL},//shadow bottom - {CC_FBDATA_TYPE_FRAME, x, y, width, height, col_frame_cur, corner_rad, th, NULL, NULL},//frame - {CC_FBDATA_TYPE_BOX, x+th, y+th, width-2*th, height-2*th, col_body, rad, 0, NULL, NULL},//body + {CC_FBDATA_TYPE_BGSCREEN, ix, iy, width+sw, height+sw, 0, 0, 0, NULL, NULL}, + {CC_FBDATA_TYPE_SHADOW_BOX, ix+sw, iy+sw, width, height, col_shadow, corner_rad, 0, NULL, NULL},//shadow + {CC_FBDATA_TYPE_FRAME, ix, iy, width, height, col_frame_cur, corner_rad, th, NULL, NULL},//frame + {CC_FBDATA_TYPE_BOX, ix+th, iy+th, width-2*th, height-2*th, col_body, rad, 0, NULL, NULL},//body }; - for(size_t i =0; i< (sizeof(fbdata) / sizeof(fbdata[0])) ;i++) + for(size_t i =0; i< (sizeof(fbdata) / sizeof(fbdata[0])) ;i++) { + if (((fbdata[i].fbdata_type == CC_FBDATA_TYPE_SHADOW_BOX) && !shadow) || + ((fbdata[i].fbdata_type == CC_FBDATA_TYPE_FRAME) && !fr_thickness)) + continue; v_fbdata.push_back(fbdata[i]); + } #ifdef DEBUG_CC printf("[CComponentsItem] %s:\ncc_item_type: %d\ncc_item_index = %d\nheight = %d\nwidth = %d\n", __FUNCTION__, cc_item_type, cc_item_index, height, width); #endif diff --git a/src/gui/components/cc_item_infobox.cpp b/src/gui/components/cc_item_infobox.cpp index 2cf17427d..0ea76cd27 100644 --- a/src/gui/components/cc_item_infobox.cpp +++ b/src/gui/components/cc_item_infobox.cpp @@ -30,7 +30,7 @@ #include #include -#include "cc.h" +#include "cc_item_infobox.h" using namespace std; @@ -85,8 +85,6 @@ void CComponentsInfoBox::initVarInfobox() cctext = NULL; pic_name = ""; x_offset = 10; - x_text = x+fr_thickness+x_offset;; - } void CComponentsInfoBox::paintPicture() @@ -101,7 +99,7 @@ void CComponentsInfoBox::paintPicture() return; //init pic object and set icon paint position - pic = new CComponentsPicture(x+fr_thickness+x_offset, y+fr_thickness/*+y_offset*/, 0, 0, ""); + pic = new CComponentsPicture(x+fr_thickness+x_offset, y+fr_thickness, 0, 0, ""); //define icon pic->setPicture(pic_name); @@ -109,7 +107,6 @@ void CComponentsInfoBox::paintPicture() //fit icon into infobox pic->setHeight(height-2*fr_thickness); pic->setColorBody(col_body); - pic->paint(CC_SAVE_SCREEN_NO); } @@ -119,15 +116,16 @@ void CComponentsInfoBox::paint(bool do_save_bg) paintPicture(); //define text x position - x_text = x+fr_thickness+x_offset; + //NOTE: real values are reqiured, if we paint this item within a form as embedded cc-item + int x_text = (cc_parent ? cc_xr : x) + fr_thickness; + int y_text = (cc_parent ? cc_yr : y) + fr_thickness; //set text to the left border if picture is not painted - if ((pic) && (pic->isPicPainted())){ - int pic_w = pic->getWidth(); - x_text += pic_w+x_offset; - } + int pic_w = 0; + if ((pic) && (pic->isPicPainted())) + pic_w = pic->getWidth() + x_offset; - //set text and paint text lines + //set text properties and paint text lines if (!ct_text.empty()){ if (cctext) delete cctext; @@ -137,7 +135,13 @@ void CComponentsInfoBox::paint(bool do_save_bg) cctext->doPaintTextBoxBg(ct_paint_textbg); cctext->doPaintBg(false); cctext->setTextColor(ct_col_text); - cctext->setDimensionsAll(x_text, y+fr_thickness, width-(x_text-x+x_offset+fr_thickness), height-2*fr_thickness); + + //calculate vars for x-position and dimensions + int tx = x_offset + x_text + pic_w; + int tw = width - x_offset - pic_w - 2*fr_thickness; + int th = height-2*fr_thickness; + cctext->setDimensionsAll(tx, y_text, tw, th); + cctext->paint(CC_SAVE_SCREEN_NO); } } diff --git a/src/gui/components/cc_item_infobox.h b/src/gui/components/cc_item_infobox.h new file mode 100644 index 000000000..3e23de78f --- /dev/null +++ b/src/gui/components/cc_item_infobox.h @@ -0,0 +1,83 @@ +/* + Based up Neutrino-GUI - Tuxbox-Project + Copyright (C) 2001 by Steffen Hehn 'McClean' + + Classes for generic GUI-related components. + Copyright (C) 2012, 2013, Thilo Graf 'dbt' + + License: GPL + + 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. +*/ + +#ifndef __CC_ITEM_INFOBOX__ +#define __CC_ITEM_INFOBOX__ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include "cc_item_text.h" +#include "cc_item_picture.h" +#include + +//! Sub class of CComponentsItem. Shows box with text and optional icon on screen. +/*! +InfoBox has been originally intended for displaying text information or menue hints, +but is also usable like each other CCItems. +*/ + +#define INFO_BOX_Y_OFFSET 2 +class CComponentsInfoBox : public CComponentsText +{ + private: + ///property: property: space around fram and beetween picture and textbox, see also setSpaceOffset() + int x_offset; + + ///object: picture object + CComponentsPicture * pic; + ///property: path or default name of displayed image + std::string pic_default_name; + + ///initialize all needed default attributes + void initVarInfobox(); + ///paint picture, used in initVarInfobox() + void paintPicture(); + ///property: path or name of displayed image + std::string pic_name; + + public: + ///object: internal used CTextBox object + CComponentsText * cctext; + + CComponentsInfoBox(); + CComponentsInfoBox( const int x_pos, const int y_pos, const int w, const int h, + std::string info_text = "", const int mode = CTextBox::AUTO_WIDTH, Font* font_text = NULL, + bool has_shadow = CC_SHADOW_OFF, + fb_pixel_t color_text = COL_MENUCONTENT, fb_pixel_t color_frame = COL_MENUCONTENT_PLUS_6, fb_pixel_t color_body = COL_MENUCONTENT_PLUS_0, fb_pixel_t color_shadow = COL_MENUCONTENTDARK_PLUS_0); + + ~CComponentsInfoBox(); + + ///set property: space around fram and beetween picture and textbox + inline void setSpaceOffset(const int offset){x_offset = offset;}; + ///set property: path or name of displayed image + inline void setPicture(const std::string& picture_name){pic_name = picture_name;}; + + ///paint item + void paint(bool do_save_bg = CC_SAVE_SCREEN_YES); +}; + +#endif diff --git a/src/gui/components/cc_item_picture.cpp b/src/gui/components/cc_item_picture.cpp index 215039324..3243247ab 100644 --- a/src/gui/components/cc_item_picture.cpp +++ b/src/gui/components/cc_item_picture.cpp @@ -30,7 +30,7 @@ #include #include -#include "cc.h" +#include "cc_item_picture.h" #include extern CPictureViewer * g_PicViewer; @@ -142,48 +142,63 @@ void CComponentsPicture::initVarPicture() printf("[CComponentsPicture] %s file: %s, no icon dimensions found! width = %d, height = %d\n", __FUNCTION__, pic_name.c_str(), pic_width, pic_height); #endif - pic_x += fr_thickness; - pic_y += fr_thickness; - - if (pic_height>0 && pic_width>0){ - if (pic_align & CC_ALIGN_LEFT) - pic_x = x+fr_thickness; - if (pic_align & CC_ALIGN_RIGHT) - pic_x = x+width-pic_width-fr_thickness; - if (pic_align & CC_ALIGN_TOP) - pic_y = y+fr_thickness; - if (pic_align & CC_ALIGN_BOTTOM) - pic_y = y+height-pic_height-fr_thickness; - if (pic_align & CC_ALIGN_HOR_CENTER) - pic_x = x+width/2-pic_width/2; - if (pic_align & CC_ALIGN_VER_CENTER) - pic_y = y+height/2-pic_height/2; - - do_paint = true; - } + initPosition(); int sw = (shadow ? shadow_w :0); width = max(max(pic_width, pic_max_w), width) + sw ; height = max(max(pic_height, pic_max_h), height) + sw ; } -void CComponentsPicture::paint(bool do_save_bg) +void CComponentsPicture::initPosition() +{ + //using of real x/y values to paint images if this picture object is bound in a parent form + int px = x, py = y; + if (cc_parent){ + px = cc_xr; + py = cc_yr; + } + + if (pic_height>0 && pic_width>0){ + if (pic_align & CC_ALIGN_LEFT) + pic_x = px+fr_thickness; + if (pic_align & CC_ALIGN_RIGHT) + pic_x = px+width-pic_width-fr_thickness; + if (pic_align & CC_ALIGN_TOP) + pic_y = py+fr_thickness; + if (pic_align & CC_ALIGN_BOTTOM) + pic_y = py+height-pic_height-fr_thickness; + if (pic_align & CC_ALIGN_HOR_CENTER) + pic_x = px+width/2-pic_width/2; + if (pic_align & CC_ALIGN_VER_CENTER) + pic_y = py+height/2-pic_height/2; + + do_paint = true; + } +} + +void CComponentsPicture::paintPicture() { - initVarPicture(); - paintInit(do_save_bg); pic_painted = false; - + + if (do_paint){ #ifdef DEBUG_CC printf(" [CComponentsPicture] %s: paint image: %s (do_paint=%d)\n", __FUNCTION__, pic_name.c_str(), do_paint); #endif - - if (do_paint){ if (pic_paint_mode == CC_PIC_IMAGE_MODE_OFF) pic_painted = frameBuffer->paintIcon(pic_name, pic_x, pic_y, 0 /*pic_max_h*/, pic_offset, pic_paint, pic_paintBg, col_body); else if (pic_paint_mode == CC_PIC_IMAGE_MODE_ON) pic_painted = g_PicViewer->DisplayImage(pic_name, pic_x, pic_y, pic_width, pic_height); - do_paint = false; } + + if (pic_painted) + do_paint = false; +} + +void CComponentsPicture::paint(bool do_save_bg) +{ + initVarPicture(); + paintInit(do_save_bg); + paintPicture(); } void CComponentsPicture::hide(bool no_restore) diff --git a/src/gui/components/cc_item_picture.h b/src/gui/components/cc_item_picture.h new file mode 100644 index 000000000..a70534898 --- /dev/null +++ b/src/gui/components/cc_item_picture.h @@ -0,0 +1,92 @@ +/* + Based up Neutrino-GUI - Tuxbox-Project + Copyright (C) 2001 by Steffen Hehn 'McClean' + + Classes for generic GUI-related components. + Copyright (C) 2012, 2013, Thilo Graf 'dbt' + Copyright (C) 2012, Michael Liebmann 'micha-bbg' + + License: GPL + + 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. +*/ + +#ifndef __CC_ITEM_PICTURE_H__ +#define __CC_ITEM_PICTURE_H__ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include "cc.h" +#include +#include + +//! Sub class of CComponentsItem. Shows box with image with assigned attributes. +/*! +Picture is usable like each other CCItems. +*/ + +class CComponentsPicture : public CComponentsItem +{ + protected: + ///initialize all required attributes + void initVarPicture(); + + ///some internal modes for icon and image handling + enum + { + CC_PIC_IMAGE_MODE_OFF = 0, //paint pictures in icon mode, mainly not scaled + CC_PIC_IMAGE_MODE_ON = 1, //paint pictures in image mode, paint scaled if required + CC_PIC_IMAGE_MODE_AUTO = 2 + }; + + ///property: path or name of image, icon names to find in /widget/icons.h, icons will paint never scaled + std::string pic_name; + ///property: interface to CFrameBuffer::paintIcon() arg 5 + unsigned char pic_offset; + + bool pic_paint, pic_paintBg, pic_painted, do_paint; + int pic_align, pic_x, pic_y, pic_width, pic_height; + int pic_max_w, pic_max_h, pic_paint_mode; + + void init( const int x_pos, const int y_pos, const std::string& image_name, const int alignment, bool has_shadow, + fb_pixel_t color_frame, fb_pixel_t color_background, fb_pixel_t color_shadow); + + ///initialize position of picture object dependendly from settings + void initPosition(); + void paintPicture(); + + public: + CComponentsPicture( const int x_pos, const int y_pos, const int w, const int h, + const std::string& image_name, const int alignment = CC_ALIGN_HOR_CENTER | CC_ALIGN_VER_CENTER, bool has_shadow = CC_SHADOW_OFF, + fb_pixel_t color_frame = COL_MENUCONTENT_PLUS_6, fb_pixel_t color_background = 0, fb_pixel_t color_shadow = COL_MENUCONTENTDARK_PLUS_0); + + virtual inline void setPictureOffset(const unsigned char offset){pic_offset = offset;}; + virtual inline void setPicturePaint(bool paint_p){pic_paint = paint_p;}; + virtual inline void setPicturePaintBackground(bool paintBg){pic_paintBg = paintBg;}; + virtual void setPicture(const std::string& picture_name); + virtual void setPictureAlign(const int alignment); + + virtual inline bool isPicPainted(){return pic_painted;}; + virtual void paint(bool do_save_bg = CC_SAVE_SCREEN_YES); + virtual void hide(bool no_restore = false); + virtual inline void getPictureSize(int *pwidth, int *pheight){*pwidth=pic_width; *pheight=pic_height;}; + virtual void setMaxWidth(const int w_max){pic_max_w = w_max;}; + virtual void setMaxHeight(const int h_max){pic_max_h = h_max;}; +}; + +#endif diff --git a/src/gui/components/cc_item_progressbar.cpp b/src/gui/components/cc_item_progressbar.cpp index c589b5953..d2b77720e 100644 --- a/src/gui/components/cc_item_progressbar.cpp +++ b/src/gui/components/cc_item_progressbar.cpp @@ -31,7 +31,7 @@ #include #include "cc_item_progressbar.h" - +#include "cc_item_shapes.h" #define ITEMW 4 #define POINT 2 @@ -112,9 +112,10 @@ void CProgressBar::initDimensions() if (pb_value > pb_max_value) pb_max_value = pb_value; - // start positions x/y active bar - pb_x = (cc_item_xr > -1 ? cc_item_xr : x) + fr_thickness; - pb_y = (cc_item_yr > -1 ? cc_item_yr : y) + fr_thickness; + //assign start positions x/y active bar + //NOTE: real values are only reqiured, if we paint active/passive bar with own render methodes or not embedded cc-items + pb_x = (cc_parent ? cc_xr : x) + fr_thickness; + pb_y = (cc_parent ? cc_yr : y) + fr_thickness; // width for active bar with current value pb_active_width = max(0, pb_last_width); @@ -136,16 +137,23 @@ void CProgressBar::initDimensions() col_frame = pb_active_col; } +void CProgressBar::paintShapes(int &shx, int ­, int &shw, int &shh, fb_pixel_t &col) +{ + CComponentsShapeSquare shape(shx, shy, shw, shh, false); + shape.setColorBody(col); + shape.paint(false); +} + void CProgressBar::paintSimple() { // progress value if (pb_active_width != pb_last_width){ - frameBuffer->paintBoxRel(pb_x, pb_y, pb_active_width, pb_height, pb_active_col); // active bar - frameBuffer->paintBoxRel(pb_start_x_passive, pb_y, pb_passive_width, pb_height, pb_passive_col); // passive bar + paintShapes(pb_x, pb_y, pb_active_width, pb_height, pb_active_col); // active bar + paintShapes(pb_start_x_passive, pb_y, pb_passive_width, pb_height, pb_passive_col); // passive bar } - if (pb_paint_zero && pb_value == 0) + if (pb_paint_zero && pb_value == 0) //TODO: use shape cc-item, not available for lines yet frameBuffer->paintLine(pb_x , pb_y, pb_x+width-3, pb_y+height-3, pb_active_col); // zero line } @@ -202,8 +210,11 @@ void CProgressBar::paintAdvanced() else rgb = RED + (diff << 8); // adding green color = make16color(rgb); - for (j = 0; j < hcnt; j++) - frameBuffer->paintBoxRel(pb_x + i * itemw, py + j * itemh, pointx, pointy, color); + for (j = 0; j < hcnt; j++) { + int sh_x = pb_x + i * itemw; + int sh_y = py + j * itemh; + paintShapes(sh_x, sh_y, pointx, pointy, color); + } } step = yw - rd - 1; if (step < 1) @@ -215,8 +226,11 @@ void CProgressBar::paintAdvanced() else rgb = YELLOW - (diff << 16); // removing red color = make16color(rgb); - for (j = 0; j < hcnt; j++) - frameBuffer->paintBoxRel(pb_x + i * itemw, py + j * itemh, pointx, pointy, color); + for (j = 0; j < hcnt; j++) { + int sh_x = pb_x + i * itemw; + int sh_y = py + j * itemh; + paintShapes(sh_x, sh_y, pointx, pointy, color); + } } off = diff; b = 0; @@ -230,13 +244,19 @@ void CProgressBar::paintAdvanced() else rgb = YELLOW - (diff << 16); // removing red color = make16color(rgb); - for (j = 0; j < hcnt; j++) - frameBuffer->paintBoxRel(pb_x + i * itemw, py + j * itemh, pointx, pointy, color); + for (j = 0; j < hcnt; j++) { + int sh_x = pb_x + i * itemw; + int sh_y = py + j * itemh; + paintShapes(sh_x, sh_y, pointx, pointy, color); + } } } for(i = maxi; i < total; i++) { - for (j = 0; j < hcnt; j++) - frameBuffer->paintBoxRel(pb_x + i * itemw, py + j * itemh, pointx, pointy, pb_passive_col); //fill passive + for (j = 0; j < hcnt; j++) {//TODO: use shape cc-item + int sh_x = pb_x + i * itemw; + int sh_y = py + j * itemh; + paintShapes(sh_x, sh_y, pointx, pointy, pb_passive_col); //fill passive + } } } } diff --git a/src/gui/components/cc_item_progressbar.h b/src/gui/components/cc_item_progressbar.h index 36bb4d26c..ad8e6d274 100644 --- a/src/gui/components/cc_item_progressbar.h +++ b/src/gui/components/cc_item_progressbar.h @@ -91,6 +91,8 @@ class CProgressBar : public CComponentsItem void paintSimple(); ///paint version of progressbar with color and advanced display modifications void paintAdvanced(); + ///painting of activ/passive bars via shape object + void paintShapes(int &shx, int ­, int &shw, int &shh, fb_pixel_t &col); void initDimensions(); diff --git a/src/gui/components/cc_item_shapes.cpp b/src/gui/components/cc_item_shapes.cpp index abe5826d2..758622401 100644 --- a/src/gui/components/cc_item_shapes.cpp +++ b/src/gui/components/cc_item_shapes.cpp @@ -30,7 +30,7 @@ #include #include -#include "cc.h" +#include "cc_item_shapes.h" using namespace std; diff --git a/src/gui/components/cc_item_shapes.h b/src/gui/components/cc_item_shapes.h new file mode 100644 index 000000000..ffde992f4 --- /dev/null +++ b/src/gui/components/cc_item_shapes.h @@ -0,0 +1,67 @@ +/* + Based up Neutrino-GUI - Tuxbox-Project + Copyright (C) 2001 by Steffen Hehn 'McClean' + + Classes for generic GUI-related components. + Copyright (C) 2012, 2013, Thilo Graf 'dbt' + + License: GPL + + 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. +*/ + +#ifndef __CC_ITEM_SHAPES_H__ +#define __CC_ITEM_SHAPES_H__ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include "cc.h" + +//! Sub class of CComponentsItem. Shows a shape with given dimensions and color on screen. +/*! +Paint of simple shapes on screen. +*/ + +class CComponentsShapeCircle : public CComponentsItem +{ + private: + ///property: diam + int d; + public: + CComponentsShapeCircle( const int x_pos, const int y_pos, const int diam, bool has_shadow = CC_SHADOW_ON, + fb_pixel_t color_frame = COL_MENUCONTENT_PLUS_6, fb_pixel_t color_body = COL_MENUCONTENT_PLUS_0, fb_pixel_t color_shadow = COL_MENUCONTENTDARK_PLUS_0); + + ///set property: diam + inline void setDiam(const int& diam){d=width=height=diam, corner_rad=d/2;}; + ///get property: diam + inline int getDiam(){return d;}; + + ///paint item + void paint(bool do_save_bg = CC_SAVE_SCREEN_YES); +}; + +class CComponentsShapeSquare : public CComponentsItem +{ + public: + CComponentsShapeSquare( const int x_pos, const int y_pos, const int w, const int h, bool has_shadow = CC_SHADOW_ON, + fb_pixel_t color_frame = COL_MENUCONTENT_PLUS_6, fb_pixel_t color_body = COL_MENUCONTENT_PLUS_0, fb_pixel_t color_shadow = COL_MENUCONTENTDARK_PLUS_0); + + void paint(bool do_save_bg = CC_SAVE_SCREEN_YES); +}; + +#endif diff --git a/src/gui/components/cc_item_text.cpp b/src/gui/components/cc_item_text.cpp index 38d5e8d90..d93836488 100644 --- a/src/gui/components/cc_item_text.cpp +++ b/src/gui/components/cc_item_text.cpp @@ -30,7 +30,7 @@ #include #include -#include "cc.h" +#include "cc_item_text.h" #include #include #include @@ -67,6 +67,8 @@ CComponentsText::CComponentsText( const int x_pos, const int y_pos, const int w, ct_text = text; ct_text_mode = mode; ct_col_text = color_text; + + initCCText(); } @@ -93,6 +95,12 @@ void CComponentsText::initVarText() ct_text = ""; ct_old_text = ct_text; ct_text_mode = CTextBox::AUTO_WIDTH; + + /* we need a minimal borderwith of 1px because the edge-smoothing + (or fontrenderer?) otherwise will paint single pixels outside the + defined area. e.g. 'j' is leaving such residues */ + ct_text_border = 1; + ct_col_text = COL_MENUCONTENT; ct_text_sent = false; ct_paint_textbg = false; @@ -115,9 +123,16 @@ void CComponentsText::initCCText() delete ct_box; ct_box = NULL; } + + //using of real x/y values to paint images if this text object is bound in a parent form + int tx = x, ty = y; + if (cc_parent){ + tx = cc_xr; + ty = cc_yr; + } ct_box = new CBox(); - ct_box->iX = x+fr_thickness; - ct_box->iY = y+fr_thickness; + ct_box->iX = tx+fr_thickness; + ct_box->iY = ty+fr_thickness; ct_box->iWidth = width-2*fr_thickness; ct_box->iHeight = height-2*fr_thickness; @@ -129,7 +144,7 @@ void CComponentsText::initCCText() ct_textbox->setTextFont(ct_font); ct_textbox->setTextMode(ct_text_mode); ct_textbox->setWindowPos(ct_box); - ct_textbox->setTextBorderWidth(0); + ct_textbox->setTextBorderWidth(ct_text_border); ct_textbox->enableBackgroundPaint(ct_paint_textbg); ct_textbox->setBackGroundColor(col_body); ct_textbox->setBackGroundRadius(corner_rad-fr_thickness, corner_type); @@ -142,7 +157,7 @@ void CComponentsText::initCCText() ct_text_sent = ct_textbox->setText(&ct_text, ct_box->iWidth); ct_old_text = ct_text; #ifdef DEBUG_CC - printf(" [CComponentsText] [%s - %d] init text: %s [x %d, y %d, h %d, w %d]\n", __FUNCTION__, __LINE__, ct_text.c_str(), ct_box->iX, ct_box->iY, height, width); + printf(" [CComponentsText] [%s - %d] init text: %s [x %d, y %d, w %d, h %d]\n", __FUNCTION__, __LINE__, ct_text.c_str(), ct_box->iX, ct_box->iY, ct_box->iWidth, ct_box->iHeight); #endif } diff --git a/src/gui/components/cc_item_text.h b/src/gui/components/cc_item_text.h new file mode 100644 index 000000000..0496f6d22 --- /dev/null +++ b/src/gui/components/cc_item_text.h @@ -0,0 +1,160 @@ +/* + Based up Neutrino-GUI - Tuxbox-Project + Copyright (C) 2001 by Steffen Hehn 'McClean' + + Classes for generic GUI-related components. + Copyright (C) 2012, 2013, Thilo Graf 'dbt' + + License: GPL + + 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. +*/ + +#ifndef __CC_ITEM_TEXT_H__ +#define __CC_ITEM_TEXT_H__ + +#include "cc.h" +#include +#include + +//! Sub class of CComponentsItem. Shows a text box. +/*! +Usable like all other CCItems and provides paint of text with different properties for format, alignment, color, fonts etc. +The basic background of textboxes based on frame, body and shadow, known from othe CCItems. +Handling of text parts based up CTextBox attributes and methodes. +CComponentsText provides a interface to the embedded CTextBox object. +*/ + +class CComponentsText : public CComponentsItem +{ + protected: + ///object: CTextBox object + CTextBox * ct_textbox; + ///object: CBox object + CBox * ct_box; + ///object: Fontrenderer object + Font * ct_font; + + ///property: CTextBox object + fb_pixel_t ct_col_text; + ///property: text display modes, see textbox.h for possible modes + int ct_text_mode; + ///property: text border width + int ct_text_border; + ///property: current text string + std::string ct_text; + ///status: cached text string, mainly required to compare with current text + std::string ct_old_text; + + ///status: current text string is sent to CTextBox object + bool ct_text_sent; + ///property: send to CTextBox object enableBackgroundPaint(true) + bool ct_paint_textbg; + + ///property: force sending text to the CTextBox object, false= text only sended, if text was changed, see also textChanged() + bool ct_force_text_paint; + + ///helper: convert int to string + static std::string iToString(int int_val); //helper to convert int to string + + ///initialize all required default attributes + void initVarText(); + + ///destroy current CTextBox and CBox objects + void clearCCText(); + + ///initialize all required attributes for text and send to the CTextBox object + void initCCText(); + ///paint CCItem backckrond (if paint_bg=true), apply initCCText() and send paint() to the CTextBox object + void paintText(bool do_save_bg = CC_SAVE_SCREEN_YES); + public: + CComponentsText(); + CComponentsText( const int x_pos, const int y_pos, const int w, const int h, + std::string text = "", const int mode = CTextBox::AUTO_WIDTH, Font* font_text = NULL, + bool has_shadow = CC_SHADOW_OFF, + fb_pixel_t color_text = COL_MENUCONTENT, fb_pixel_t color_frame = COL_MENUCONTENT_PLUS_6, fb_pixel_t color_body = COL_MENUCONTENT_PLUS_0, fb_pixel_t color_shadow = COL_MENUCONTENTDARK_PLUS_0); + virtual ~CComponentsText(); + + ///default members to paint a text box and hide painted text + ///hide textbox + void hide(bool no_restore = false); + ///paint text box, parameter do_save_bg: default = true, causes fill of backckrond pixel buffer + void paint(bool do_save_bg = CC_SAVE_SCREEN_YES); + + ///send options for text font (size and type), color and mode (allignment) + virtual inline void setTextFont(Font* font_text){ct_font = font_text;}; + ///set text color + virtual inline void setTextColor(fb_pixel_t color_text){ ct_col_text = color_text;}; + ///set text alignment, also see textbox.h for possible alignment modes + virtual inline void setTextMode(const int mode){ct_text_mode = mode;}; + ///set text border width + virtual inline void setTextBorderWidth(const int border){ct_text_border = border;}; + + ///send option to CTextBox object to paint background box behind text or not + virtual inline void doPaintTextBoxBg(bool do_paintbox_bg){ ct_paint_textbg = do_paintbox_bg;}; + + ///set text as string also possible with overloades members for loacales, const char and text file + virtual void setText(const std::string& stext, const int mode = ~CTextBox::AUTO_WIDTH, Font* font_text = NULL); + ///set text with const char* + virtual void setText(const char* ctext, const int mode = ~CTextBox::AUTO_WIDTH, Font* font_text = NULL); + ///set text from locale + virtual void setText(neutrino_locale_t locale_text, const int mode = ~CTextBox::AUTO_WIDTH, Font* font_text = NULL); + ///set text from digit, digit is integer + virtual void setText(const int digit, const int mode = ~CTextBox::AUTO_WIDTH, Font* font_text = NULL); + ///set text directly from a textfile, path as string is required + virtual bool setTextFromFile(const std::string& path_to_textfile, const int mode = ~CTextBox::AUTO_WIDTH, Font* font_text = NULL); + + ///helper to remove linebreak chars from a string if needed + virtual void removeLineBreaks(std::string& str); + + ///returns true, if text was changed + virtual bool textChanged(){return ct_old_text != ct_text;}; + ///force paint of text even if text was changed or not + virtual void forceTextPaint(bool force_text_paint = true){ct_force_text_paint = force_text_paint;}; + + ///gets the embedded CTextBox object, so it's possible to get access directly to its methods and properties + virtual CTextBox* getCTextBoxObject() { return ct_textbox; }; +}; + + +//! Sub class of CComponentsText. Shows text as label, text color=inactive mode, depending from color settings. +/*! +Usable like all other CCItems and provides paint of text with different properties for format, alignment, color, fonts etc. +The basic background of textboxes based on frame, body and shadow, known from othe CCItems. +Handling of text parts based up CTextBox attributes and methodes. +CComponentsLbel provides a interface to the embedded CTextBox object. +*/ + +class CComponentsLabel : public CComponentsText +{ + public: + CComponentsLabel( const int x_pos, const int y_pos, const int w, const int h, + std::string text = "", const int mode = CTextBox::AUTO_WIDTH, Font* font_text = NULL, + bool has_shadow = CC_SHADOW_OFF, + fb_pixel_t color_text = COL_MENUCONTENTINACTIVE, fb_pixel_t color_frame = COL_MENUCONTENT_PLUS_6, fb_pixel_t color_body = COL_MENUCONTENT_PLUS_0, fb_pixel_t color_shadow = COL_MENUCONTENTDARK_PLUS_0) + :CComponentsText(x_pos, y_pos, w, h, text, mode, font_text, has_shadow, color_text, color_frame, color_body, color_shadow) + { + cc_item_type = CC_ITEMTYPE_LABEL; + }; + CComponentsLabel():CComponentsText() + { + initVarText(); + cc_item_type = CC_ITEMTYPE_LABEL; + ct_col_text = COL_MENUCONTENTINACTIVE; + }; +}; + +#endif diff --git a/src/gui/components/cc_item_tvpic.cpp b/src/gui/components/cc_item_tvpic.cpp index eedc4e65e..e06b7fb97 100644 --- a/src/gui/components/cc_item_tvpic.cpp +++ b/src/gui/components/cc_item_tvpic.cpp @@ -30,7 +30,7 @@ #include #include -#include "cc.h" +#include "cc_item_tvpic.h" #include @@ -74,13 +74,20 @@ CComponentsPIP::~CComponentsPIP() void CComponentsPIP::paint(bool do_save_bg) { - int pig_x = x+fr_thickness; - int pig_y = y+fr_thickness; + //NOTE: real values are reqiured, if we paint not bound items or an own render methodes + int pig_x = (cc_parent ? cc_xr : x) + fr_thickness; + int pig_y = (cc_parent ? cc_yr : y) + fr_thickness; int pig_w = width-2*fr_thickness; int pig_h = height-2*fr_thickness; paintInit(do_save_bg); - + + if (videoDecoder->getAspectRatio() == 1){ + int tmpw = pig_w; + pig_w -= pig_w*25/100; + pig_x += tmpw/2-pig_w/2; + } + if(CNeutrinoApp::getInstance()->getMode() == NeutrinoMessages::mode_tv){ videoDecoder->Pig(pig_x+2, pig_y, pig_w, pig_h, screen_w, screen_h); } diff --git a/src/gui/components/cc_item_tvpic.h b/src/gui/components/cc_item_tvpic.h new file mode 100644 index 000000000..6634b15b2 --- /dev/null +++ b/src/gui/components/cc_item_tvpic.h @@ -0,0 +1,69 @@ +/* + Based up Neutrino-GUI - Tuxbox-Project + Copyright (C) 2001 by Steffen Hehn 'McClean' + + Classes for generic GUI-related components. + Copyright (C) 2012, 2013, Thilo Graf 'dbt' + + License: GPL + + 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. +*/ + +#ifndef __CC_ITEM_TVPIC_H__ +#define __CC_ITEM_TVPIC_H__ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include "cc.h" +#include + +//! Sub class of CComponentsItem. Shows a mini tv box, similar to a PIP-Feature with current tv-channel. +/*! +Usable like all other CCItems and provides a simple display of a mini tv box on screen. +A real PIP-Feature is only provided with correct hardware support and in soon in newer versions. +*/ + +class CComponentsPIP : public CComponentsItem +{ + private: + ///property: width of tv box + int screen_w; + ///property: height of tv box + int screen_h; + ///property: path to image that displayed, if no tv-mode is active, default: start.jpg + std::string pic_name; + public: + ///constructor: initialize of position like all other items with x and y values, but dimensions in percent + CComponentsPIP( const int x_pos, const int y_pos, const int percent = 30, bool has_shadow = CC_SHADOW_OFF); + ~CComponentsPIP(); + + ///set property: width of tv box in pixel + void setScreenWidth(int screen_width){screen_w = screen_width;}; + ///set property: height of tv box in pixel + void setScreenHeight(int screen_heigth){screen_h = screen_heigth;}; + ///property: path to image that displayed, if no tv-mode is active + void setPicture(const std::string& image){pic_name = image;}; + + ///show tv box + void paint(bool do_save_bg = CC_SAVE_SCREEN_YES); + ///remove tv box from screen + void hide(bool no_restore = false); +}; + +#endif diff --git a/src/gui/components/cc_types.h b/src/gui/components/cc_types.h index bcc5b9ad3..76c4b12b6 100644 --- a/src/gui/components/cc_types.h +++ b/src/gui/components/cc_types.h @@ -40,7 +40,9 @@ typedef enum CC_ITEMTYPE_SHAPE_CIRCLE, CC_ITEMTYPE_PIP, CC_ITEMTYPE_FRM, + CC_ITEMTYPE_FRM_CLOCK, CC_ITEMTYPE_FRM_HEADER, + CC_ITEMTYPE_FOOTER, CC_ITEMTYPE_FRM_ICONFORM, CC_ITEMTYPE_FRM_WINDOW, CC_ITEMTYPE_LABEL, @@ -74,6 +76,7 @@ typedef enum { CC_FBDATA_TYPE_BGSCREEN, CC_FBDATA_TYPE_BOX, + CC_FBDATA_TYPE_SHADOW_BOX, CC_FBDATA_TYPE_FRAME, CC_FBDATA_TYPE_LINE, CC_FBDATA_TYPE_BACKGROUND, @@ -131,6 +134,7 @@ typedef struct comp_element_data_t #define CC_SAVE_SCREEN_NO false #define CC_NO_INDEX -1 +#define CC_APPEND -1 diff --git a/src/gui/components/cc_item_box.cpp b/src/gui/components/unmaintained/cc_item_box.cpp similarity index 100% rename from src/gui/components/cc_item_box.cpp rename to src/gui/components/unmaintained/cc_item_box.cpp diff --git a/src/gui/components/cc_misc.h b/src/gui/components/unmaintained/cc_misc.h similarity index 100% rename from src/gui/components/cc_misc.h rename to src/gui/components/unmaintained/cc_misc.h diff --git a/src/gui/epgview.cpp b/src/gui/epgview.cpp index 67855cda3..d09346172 100644 --- a/src/gui/epgview.cpp +++ b/src/gui/epgview.cpp @@ -592,7 +592,7 @@ int CEpgData::show(const t_channel_id channel_id, uint64_t a_id, time_t* a_start if (!audioInfo.empty()) { audioInfo.erase(audioInfo.size()-2); - processTextToArray(std::string(g_Locale->getText(LOCALE_EPGVIEWER_AUDIO)) + ": " + ZapitTools::Latin1_to_UTF8(audioInfo)); // UTF-8 + processTextToArray(std::string(g_Locale->getText(LOCALE_EPGVIEWER_AUDIO)) + ": " + audioInfo); // UTF-8 } } diff --git a/src/gui/eventlist.cpp b/src/gui/eventlist.cpp index 42ae1709f..0da91b20a 100644 --- a/src/gui/eventlist.cpp +++ b/src/gui/eventlist.cpp @@ -1078,17 +1078,16 @@ bool CNeutrinoEventList::findEvents(void) } CEitManager::getInstance()->getEventsServiceKey(0,evtlist, m_search_epg_item,m_search_keyword, true);//all_chann - std::map::iterator map_it; - CChannelEventList::iterator e; if(!evtlist.empty()){ - for ( e=evtlist.begin(); e!=evtlist.end();){ + std::map::iterator map_it; + CChannelEventList::iterator e; + for ( e=evtlist.begin(); e!=evtlist.end();++e){ map_it = ch_id_map.find(e->channelID); if (map_it != ch_id_map.end()){ e->channelID = map_it->second;//map channelID48 to channelID - ++e; } else{ - evtlist.erase(e);// remove event for not found channels in channelList + evtlist.erase(e--);// remove event for not found channels in channelList } } } diff --git a/src/gui/eventlist.h b/src/gui/eventlist.h index 8eff085db..621581fbc 100644 --- a/src/gui/eventlist.h +++ b/src/gui/eventlist.h @@ -34,7 +34,7 @@ #include #include #include -#include +#include #include "color.h" #include "infoviewer.h" diff --git a/src/gui/filebrowser.cpp b/src/gui/filebrowser.cpp index ab3de69d7..2127119de 100644 --- a/src/gui/filebrowser.cpp +++ b/src/gui/filebrowser.cpp @@ -28,6 +28,7 @@ /* include before to enable 64 bit file offsets */ #include +#include #include #include #include @@ -249,13 +250,12 @@ void SMSKeyInput::setTimeout(int timeout) } -//------------------------------------------------------------------------ //------------------------------------------------------------------------ bool comparetolower(const char a, const char b) { return tolower(a) < tolower(b); -}; +} // sort operators bool sortByName (const CFile& a, const CFile& b) @@ -362,7 +362,7 @@ CFileBrowser::CFileBrowser(const char * const _base, const tFileBrowserMode mode void CFileBrowser::commonInit() { frameBuffer = CFrameBuffer::getInstance(); - fnt_title = g_Font[SNeutrinoSettings::FONT_TYPE_EVENTLIST_TITLE]; + fnt_title = g_Font[SNeutrinoSettings::FONT_TYPE_MENU_TITLE]; fnt_item = g_Font[SNeutrinoSettings::FONT_TYPE_FILEBROWSER_ITEM]; fnt_small = g_Font[SNeutrinoSettings::FONT_TYPE_INFOBAR_SMALL]; //shoutcast @@ -1379,7 +1379,6 @@ void CFileBrowser::paintHead() char *l_name; int i = 0; int l; - frameBuffer->paintBoxRel(x,y, width,theight+0, COL_MENUHEAD_PLUS_0, RADIUS_MID, CORNER_TOP); #ifdef ENABLE_INTERNETRADIO if(m_Mode == ModeSC) l = asprintf(&l_name, "%s %s", g_Locale->getText(LOCALE_AUDIOPLAYER_ADD_SC), FILESYSTEM_ENCODING_TO_UTF8_STRING(name).c_str()); @@ -1401,11 +1400,12 @@ void CFileBrowser::paintHead() l_name[--l] = '\0'; /* still too long? the last part is probably more interesting than the first part... */ - while ((fnt_title->getRenderWidth(&l_name[i]) > width - 11) - && (i < l)) + while ((fnt_title->getRenderWidth(&l_name[i]) > width - 20) && (i < l)) i++; - fnt_title->RenderString(x+10,y+theight+1, width-11, &l_name[i], COL_MENUHEAD, 0, true); + CComponentsHeader header(x, y, width, theight, &l_name[i], NULL /*no header icon*/); + header.paint(CC_SAVE_SCREEN_NO); + free(l_name); } @@ -1455,9 +1455,9 @@ void CFileBrowser::paintFoot() const struct button_label FileBrowserButtons2[3] = { - { NEUTRINO_ICON_BUTTON_OKAY , LOCALE_FILEBROWSER_SELECT }, - { NEUTRINO_ICON_BUTTON_HELP_SMALL , sortByNames[g_settings.filebrowser_sortmethod] }, - { NEUTRINO_ICON_BUTTON_MUTE_SMALL, LOCALE_FILEBROWSER_DELETE }, + { NEUTRINO_ICON_BUTTON_OKAY , LOCALE_FILEBROWSER_SELECT }, + { NEUTRINO_ICON_BUTTON_HELP , sortByNames[g_settings.filebrowser_sortmethod] }, + { NEUTRINO_ICON_BUTTON_MUTE_SMALL , LOCALE_FILEBROWSER_DELETE }, }; // int iw = 0, ih = 0; diff --git a/src/gui/imageinfo.cpp b/src/gui/imageinfo.cpp index ad33f0d8e..d0754dee8 100644 --- a/src/gui/imageinfo.cpp +++ b/src/gui/imageinfo.cpp @@ -38,10 +38,9 @@ #include #include #include +#include +#include "version.h" -#include "git_version.h" -#define GIT_DESC "GIT Desc.:" -#define GIT_REV "GIT Build:" #define LICENSEDIR DATADIR "/neutrino/license/" using namespace std; @@ -57,10 +56,10 @@ CImageInfo::CImageInfo(): config ('\t') void CImageInfo::Init(void) { cc_win = NULL; + cc_info = NULL; cc_tv = NULL; cc_lic = NULL; - item_offset = 20; - item_top = item_offset; + item_offset = 10; license_txt = ""; v_info.clear(); config.loadConfig("/.version"); @@ -68,17 +67,34 @@ void CImageInfo::Init(void) CImageInfo::~CImageInfo() { + hide(); //deallocate window object, deletes also added cc_items delete cc_win; } +void CImageInfo::Clean() +{ + //deallocate of the window object causes also deallocate added items, + if (cc_win){ + delete cc_win; + //it's important to set here a null pointer + cc_win = NULL; + cc_info = NULL; + cc_tv = NULL; + cc_lic = NULL; + } +} + int CImageInfo::exec(CMenuTarget* parent, const std::string &) { int res = menu_return::RETURN_REPAINT; if (parent) parent->hide(); - //init window object and add cc_items + //clean up before, because we could have a current instance with already initialized contents + Clean(); + + //init window object, add cc-items and paint all ShowWindow(); neutrino_msg_t msg; @@ -112,14 +128,8 @@ int CImageInfo::exec(CMenuTarget* parent, const std::string &) } } - //hide window - cc_win->hide(); - - //deallocate of the window object causes also deallocate added items, - delete cc_win; - //it's important to set here a null pointer - cc_win = NULL; - + hide(); + return res; } @@ -128,11 +138,10 @@ void CImageInfo::ShowWindow() { if (cc_win == NULL){ cc_win = new CComponentsWindow(LOCALE_IMAGEINFO_HEAD, NEUTRINO_ICON_INFO); - item_top = cc_win->getStartY() + item_offset; cc_win->setWindowHeaderButtons(CComponentsHeader::CC_BTN_MENU | CComponentsHeader::CC_BTN_EXIT); } - //prepare minitv: important! init the minitv object as first + //prepare minitv InitMinitv(); //prepare infos @@ -149,18 +158,21 @@ void CImageInfo::ShowWindow() void CImageInfo::InitMinitv() { //init the minitv object - cc_tv = new CComponentsPIP (0, item_top); - + if (cc_tv == NULL) + cc_tv = new CComponentsPIP (0, item_offset); + +#if 0 //static assign of dimensions are distorting ratio of mini tv picture //init width and height cc_tv->setWidth(cc_win->getWidth()/3); cc_tv->setHeight(cc_win->getHeight()/3); +#endif //init x pos and use as parameter for setXPos int cc_tv_x = (cc_win->getWidth() - cc_tv->getWidth()) - item_offset; cc_tv->setXPos(cc_tv_x); //add minitv to container - cc_win->addCCItem(cc_tv); + cc_win->addWindowItem(cc_tv); } //prepare distribution infos @@ -168,28 +180,35 @@ void CImageInfo::InitInfos() { v_info.clear(); -#ifdef GITVERSION - const char * builddate = GITVERSION; +#ifdef BUILT_DATE + const char * builddate = BUILT_DATE; #else - const char * builddate = config.getString("builddate", BUILT_DATE).c_str(); + const char * builddate = config.getString("builddate", "n/a").c_str(); #endif - const char * _version = config.getString("version", "no version").c_str(); + const char * _version = config.getString("version", "n/a").c_str(); static CFlashVersionInfo versionInfo(_version); std::string version_string; version_string = versionInfo.getReleaseCycle(); version_string += " "; version_string += versionInfo.getType(); + version_string += " ("; + version_string += versionInfo.getDate(); + version_string += ")"; struct utsname uts_info; image_info_t imagename = {LOCALE_IMAGEINFO_IMAGE, config.getString("imagename", "Neutrino-HD")}; v_info.push_back(imagename); - image_info_t date = {LOCALE_IMAGEINFO_DATE, builddate}; - v_info.push_back(date); image_info_t version = {LOCALE_IMAGEINFO_VERSION, version_string}; v_info.push_back(version); +#ifdef VCS + image_info_t vcs = {LOCALE_IMAGEINFO_VCS, VCS}; + v_info.push_back(vcs); +#endif + image_info_t date = {LOCALE_IMAGEINFO_DATE, builddate}; + v_info.push_back(date); if (uname(&uts_info) == 0) { image_info_t kernel = {LOCALE_IMAGEINFO_KERNEL, uts_info.release}; v_info.push_back(kernel); @@ -202,52 +221,66 @@ void CImageInfo::InitInfos() v_info.push_back(doc); image_info_t forum = {LOCALE_IMAGEINFO_FORUM, config.getString("forum", "http://forum.tuxbox.org")}; v_info.push_back(forum); - image_info_t license = {LOCALE_IMAGEINFO_LICENSE, "GPL"}; + image_info_t license = {LOCALE_IMAGEINFO_LICENSE, "GPL v2"}; v_info.push_back(license); Font * item_font = g_Font[SNeutrinoSettings::FONT_TYPE_MENU]; - //calculate max width of caption and info_text - int w_caption = 0, w_info_text = 0, w = 0; + //initialize container for infos + if (cc_info == NULL) + cc_info = new CComponentsForm(); + cc_win->addWindowItem(cc_info); + cc_info->setPos(item_offset, item_offset); + cc_info->setWidth((cc_win->getWidth()/3*2)-2*item_offset); + + + //calculate max width of label and info_text + int w_label = 0, w_text = 0, w = 0; for (size_t i = 0; i < v_info.size(); i++) { w = item_font->getRenderWidth(g_Locale->getText(v_info[i].caption), true); - w_caption = std::max(w_caption, w); + w_label = std::max(w_label, w); w = item_font->getRenderWidth(v_info[i].info_text.c_str(), true); - w_info_text = std::max(w_info_text, w); + w_text = std::max(w_text, w); } - int x_caption = item_offset; - int x_info_text = x_caption + w_caption + item_offset; + int x_label = 0, y_text = 0; + int x_text = x_label + w_label + item_offset; int item_height = item_font->getHeight(); - //recalc w_info_text to avoid an overlap with pip - w_info_text = std::min(w_info_text, cc_win->getWidth() - x_info_text - cc_tv->getWidth() - 2*item_offset); + //recalc w_text to avoid an overlap with pip TODO: calculate within cc_info itself + w_text = std::min(w_text, cc_win->getWidth() - x_text - /*cc_tv->getWidth() - */2*item_offset); //create label and text items - for (size_t i = 0; i < v_info.size(); i++) { - // add an offset before homepage and license - if (v_info[i].caption == LOCALE_IMAGEINFO_HOMEPAGE || v_info[i].caption == LOCALE_IMAGEINFO_LICENSE) - item_top += item_offset; - + int h_tmp = 0; + size_t i = 0; + for (i = 0; i < v_info.size(); i++) { CComponentsLabel *cc_label = new CComponentsLabel(); - cc_label->setDimensionsAll(x_caption, item_top, w_caption, item_height); + cc_label->setDimensionsAll(x_label, y_text, w_label, item_height); cc_label->setText(v_info[i].caption, CTextBox::NO_AUTO_LINEBREAK, item_font); - //add label to container - cc_win->addCCItem(cc_label); + //add label object to window body + cc_info->addCCItem(cc_label); CComponentsText *cc_text = new CComponentsText(); - cc_text->setDimensionsAll(x_info_text, item_top, w_info_text, item_height); + cc_text->setDimensionsAll(x_text, y_text, w_text, item_height); cc_text->setText(v_info[i].info_text.c_str(), CTextBox::NO_AUTO_LINEBREAK, item_font); + y_text += item_height/*CC_APPEND*/; - //add text to container - cc_win->addCCItem(cc_text); + //add text object to window body + cc_info->addCCItem(cc_text); - item_top += item_height; + // add an offset before homepage and license + if (v_info[i].caption == LOCALE_IMAGEINFO_CREATOR|| v_info[i].caption == LOCALE_IMAGEINFO_FORUM){ + h_tmp += item_offset; + y_text += item_offset; + } + + //set height for info form + h_tmp += item_height; } - - item_top += item_offset; + //assign height of info form + cc_info->setHeight(h_tmp); } //prepare license infos @@ -257,13 +290,34 @@ void CImageInfo::InitLicenseText() file += g_settings.language; file += ".license"; - //calc y pos of license box to avoid an overlap with pip - int y_lic = std::max(item_top, cc_tv->getHeight() + 2*item_offset); - cc_lic = new CComponentsInfoBox(item_offset, y_lic, cc_win->getWidth()-2*item_offset, cc_win->getHeight()-item_top-item_offset); + //get window body object + CComponentsForm *winbody = cc_win->getBodyObject(); + int h_body = winbody->getHeight(); + int w_body = winbody->getWidth(); + + + int y_lic = item_offset + cc_info->getHeight() + item_offset; + int h_lic = h_body - y_lic - item_offset; + + if (cc_lic == NULL) + cc_lic = new CComponentsInfoBox(item_offset, cc_info->getYPos()+cc_info->getHeight()+item_offset, w_body-2*item_offset, h_lic); + cc_lic->setSpaceOffset(0); cc_lic->setTextFromFile(file, CTextBox::AUTO_WIDTH | CTextBox::SCROLL, g_Font[SNeutrinoSettings::FONT_TYPE_MENU_HINT]); +#if 0 + //calc y pos of license box to avoid an overlap with pip + int h_info = cc_info->getHeight(); + int y_lic = std::max(h_info, cc_tv->getHeight() + 2*item_offset); + CComponentsForm *winbody = cc_win->getBodyObject(); + int h_lic = 0; + if (winbody) + h_lic = winbody->getHeight(); + cc_lic = new CComponentsInfoBox(item_offset, /*y_lic*/CC_APPEND, cc_win->getWidth()-2*item_offset, h_lic - h_info -item_offset); + cc_lic->setTextFromFile(file, CTextBox::AUTO_WIDTH | CTextBox::SCROLL, g_Font[SNeutrinoSettings::FONT_TYPE_MENU_HINT]); +#endif + //add text to container - cc_win->addCCItem(cc_lic); + cc_win->addWindowItem(cc_lic); } //scroll licens text @@ -287,5 +341,9 @@ void CImageInfo::ScrollLic(bool scrollDown) void CImageInfo::hide() { - cc_win->hide(); + printf("[CImageInfo] [%s - %d] hide...\n", __FUNCTION__, __LINE__); + if (cc_win){ + cc_win->hide(); + Clean(); + } } diff --git a/src/gui/imageinfo.h b/src/gui/imageinfo.h index a26399fbf..f412b1cb4 100644 --- a/src/gui/imageinfo.h +++ b/src/gui/imageinfo.h @@ -27,8 +27,13 @@ #ifndef __imageinfo__ #define __imageinfo__ +#ifdef HAVE_CONFIG_H +#include +#endif + #include #include +#include #include typedef struct image_info_t @@ -42,11 +47,11 @@ class CImageInfo : public CMenuTarget { private: int item_offset; //distance between items and to boarder - int item_top; //start line in y below header std::string license_txt; std::vector v_info; - + + void Clean(); void Init(); void InitMinitv(); void InitInfos(); @@ -55,6 +60,7 @@ class CImageInfo : public CMenuTarget void ScrollLic(bool scrollDown); CComponentsWindow *cc_win; + CComponentsForm *cc_info; CComponentsPIP *cc_tv; CComponentsInfoBox *cc_lic; CConfigFile config; diff --git a/src/gui/keybind_setup.cpp b/src/gui/keybind_setup.cpp index bc0dad1b4..f832932c5 100644 --- a/src/gui/keybind_setup.cpp +++ b/src/gui/keybind_setup.cpp @@ -180,6 +180,7 @@ const key_settings_struct_t key_settings[CKeybindSetup::KEYBINDS_COUNT] = {LOCALE_MPKEY_STOP, &g_settings.mpkey_stop, LOCALE_MENU_HINT_KEY_MPSTOP }, {LOCALE_MPKEY_PLAY, &g_settings.mpkey_play, LOCALE_MENU_HINT_KEY_MPPLAY }, {LOCALE_MPKEY_AUDIO, &g_settings.mpkey_audio, LOCALE_MENU_HINT_KEY_MPAUDIO }, + {LOCALE_MPKEY_SUBTITLE, &g_settings.mpkey_subtitle, LOCALE_MENU_HINT_KEY_MPSUBTITLE }, {LOCALE_MPKEY_TIME, &g_settings.mpkey_time, LOCALE_MENU_HINT_KEY_MPTIME }, {LOCALE_MPKEY_BOOKMARK, &g_settings.mpkey_bookmark, LOCALE_MENU_HINT_KEY_MPBOOKMARK }, {LOCALE_EXTRA_KEY_TIMESHIFT, &g_settings.key_timeshift, LOCALE_MENU_HINT_KEY_MPTIMESHIFT }, diff --git a/src/gui/keybind_setup.h b/src/gui/keybind_setup.h index 2a4c15ae1..fcbb47a8c 100644 --- a/src/gui/keybind_setup.h +++ b/src/gui/keybind_setup.h @@ -69,6 +69,7 @@ class CKeybindSetup : public CMenuTarget, public CChangeObserver MPKEY_STOP, MPKEY_PLAY, MPKEY_AUDIO, + MPKEY_SUBTITLE, MPKEY_TIME, MPKEY_BOOKMARK, KEY_TIMESHIFT, diff --git a/src/gui/mediaplayer.cpp b/src/gui/mediaplayer.cpp index b120e528d..50e0a72b0 100644 --- a/src/gui/mediaplayer.cpp +++ b/src/gui/mediaplayer.cpp @@ -252,6 +252,8 @@ void CMediaPlayerMenu::showMoviePlayer(CMenuWidget *moviePlayer, CPersonalizeGui fw_mbrowser->setHint(NEUTRINO_ICON_HINT_MB, LOCALE_MENU_HINT_MB); CMenuForwarder *fw_file = new CMenuForwarder(LOCALE_MOVIEPLAYER_FILEPLAYBACK, true, NULL, &CMoviePlayerGui::getInstance(), "fileplayback", CRCInput::RC_green, NEUTRINO_ICON_BUTTON_GREEN); fw_file->setHint(NEUTRINO_ICON_HINT_FILEPLAY, LOCALE_MENU_HINT_FILEPLAY); + CMenuForwarder *fw_yt = new CMenuForwarder(LOCALE_MOVIEPLAYER_YTPLAYBACK, true, NULL, &CMoviePlayerGui::getInstance(), "ytplayback", CRCInput::RC_yellow, NEUTRINO_ICON_BUTTON_YELLOW); + fw_yt->setHint(NEUTRINO_ICON_HINT_YTPLAY, LOCALE_MENU_HINT_YTPLAY); p->addIntroItems(moviePlayer); @@ -260,6 +262,8 @@ void CMediaPlayerMenu::showMoviePlayer(CMenuWidget *moviePlayer, CPersonalizeGui //fileplayback p->addItem(moviePlayer, fw_file, &g_settings.personalize[SNeutrinoSettings::P_MPLAYER_FILEPLAY]); + //ytplayback + p->addItem(moviePlayer, fw_yt, &g_settings.personalize[SNeutrinoSettings::P_MPLAYER_YTPLAY]); // #if 0 // //moviePlayer->addItem(new CMenuForwarder(LOCALE_MOVIEPLAYER_PESPLAYBACK, true, NULL, moviePlayerGui, "pesplayback")); diff --git a/src/gui/miscsettings_menu.cpp b/src/gui/miscsettings_menu.cpp index e1ebed087..88b3526e6 100644 --- a/src/gui/miscsettings_menu.cpp +++ b/src/gui/miscsettings_menu.cpp @@ -353,6 +353,10 @@ void CMiscMenue::showMiscSettingsMenuEpg(CMenuWidget *ms_epg) CMenuOptionChooser * mc = new CMenuOptionChooser(LOCALE_MISCSETTINGS_EPG_SAVE, &g_settings.epg_save, OPTIONS_OFF0_ON1_OPTIONS, OPTIONS_OFF0_ON1_OPTION_COUNT, true,miscEpgNotifier); mc->setHint("", LOCALE_MENU_HINT_EPG_SAVE); + CMenuOptionChooser * mc2 = new CMenuOptionChooser(LOCALE_MISCSETTINGS_EPG_SCAN, &g_settings.epg_scan, OPTIONS_OFF0_ON1_OPTIONS, OPTIONS_OFF0_ON1_OPTION_COUNT, + CFEManager::getInstance()->getEnabledCount() > 1); + mc2->setHint("", LOCALE_MENU_HINT_EPG_SCAN); + ms_epg->addItem(mc); ms_epg->addItem(mc1); ms_epg->addItem(mf); @@ -360,7 +364,7 @@ void CMiscMenue::showMiscSettingsMenuEpg(CMenuWidget *ms_epg) ms_epg->addItem(mf2); ms_epg->addItem(mf3); ms_epg->addItem(mf4); - + ms_epg->addItem(mc2); } //filebrowser settings diff --git a/src/gui/motorcontrol.cpp b/src/gui/motorcontrol.cpp index 86cc50c2e..506e7b9d3 100644 --- a/src/gui/motorcontrol.cpp +++ b/src/gui/motorcontrol.cpp @@ -38,6 +38,7 @@ #include #include #include +#include #include #include #include @@ -171,7 +172,7 @@ int CMotorControl::exec(CMenuTarget* parent, const std::string &) g_Zapit->tune_TP(TP); - paint(); + paintHead(); paintMenu(); paintStatus(); frameBuffer->blit(); @@ -598,20 +599,17 @@ void CMotorControl::paintStatus() paintSeparator(xpos1, &ypos, width, g_Locale->getText(LOCALE_MOTORCONTROL_SETTINGS)); } -void CMotorControl::paint() +void CMotorControl::paintHead() { - ypos = y; - frameBuffer->paintBoxRel(x, ypos, width, hheight, COL_MENUHEAD_PLUS_0, RADIUS_LARGE, CORNER_TOP); - g_Font[SNeutrinoSettings::FONT_TYPE_MENU_TITLE]->RenderString(x + 10, ypos + hheight, width, g_Locale->getText(LOCALE_MOTORCONTROL_HEAD), COL_MENUHEAD, 0, true); // UTF-8 - frameBuffer->paintBoxRel(x, ypos + hheight, width, height - hheight, COL_MENUCONTENT_PLUS_0, RADIUS_LARGE, CORNER_BOTTOM); - - ypos += hheight + (mheight >> 1) - 10; - ypos_menue = ypos; + CComponentsHeader header(x, y, width, hheight, LOCALE_MOTORCONTROL_HEAD, NULL /*no header icon*/); + header.paint(CC_SAVE_SCREEN_NO); } void CMotorControl::paintMenu() { - ypos = ypos_menue; + frameBuffer->paintBoxRel(x, y + hheight, width, height - hheight, COL_MENUCONTENT_PLUS_0, RADIUS_LARGE, CORNER_BOTTOM); + + ypos = y + hheight + (mheight >> 1) - 10; int xpos1 = x + 10; int xpos2 = xpos1 + 10 + g_Font[SNeutrinoSettings::FONT_TYPE_MENU]->getRenderWidth("(7/yellow)"); diff --git a/src/gui/motorcontrol.h b/src/gui/motorcontrol.h index b69ad427f..84ffae7ba 100644 --- a/src/gui/motorcontrol.h +++ b/src/gui/motorcontrol.h @@ -68,7 +68,7 @@ class CMotorControl : public CMenuTarget int satfindpid; int lastsnr, lastsig; CProgressBar *snrscale, *sigscale; - void paint(); + void paintHead(void); void paintMenu(void); void paintStatus(void); void paintLine(int x, int *y, int width, const char *txt); diff --git a/src/gui/moviebrowser.cpp b/src/gui/moviebrowser.cpp index 221ae07b1..cf43fc5e2 100644 --- a/src/gui/moviebrowser.cpp +++ b/src/gui/moviebrowser.cpp @@ -176,12 +176,12 @@ const neutrino_locale_t m_localizedItemName[MB_INFO_MAX_NUMBER+1] = #define MB_ROW_WIDTH_FILEPATH 22 #define MB_ROW_WIDTH_TITLE 35 #define MB_ROW_WIDTH_SERIE 15 -#define MB_ROW_WIDTH_INFO1 25 +#define MB_ROW_WIDTH_INFO1 15 #define MB_ROW_WIDTH_MAJOR_GENRE 15 #define MB_ROW_WIDTH_MINOR_GENRE 8 #define MB_ROW_WIDTH_INFO2 25 #define MB_ROW_WIDTH_PARENTAL_LOCKAGE 4 -#define MB_ROW_WIDTH_CHANNEL 12 +#define MB_ROW_WIDTH_CHANNEL 15 #define MB_ROW_WIDTH_BOOKMARK 4 #define MB_ROW_WIDTH_QUALITY 10 #define MB_ROW_WIDTH_PREVPLAYDATE 12 @@ -190,8 +190,8 @@ const neutrino_locale_t m_localizedItemName[MB_INFO_MAX_NUMBER+1] = #define MB_ROW_WIDTH_COUNTRY 8 #define MB_ROW_WIDTH_GEOMETRIE 8 #define MB_ROW_WIDTH_AUDIO 8 -#define MB_ROW_WIDTH_LENGTH 6 -#define MB_ROW_WIDTH_SIZE 10 +#define MB_ROW_WIDTH_LENGTH 10 +#define MB_ROW_WIDTH_SIZE 12 const int m_defaultRowWidth[MB_INFO_MAX_NUMBER+1] = { @@ -228,7 +228,7 @@ bool sortDirection = 0; bool compare_to_lower(const char a, const char b) { return tolower(a) < tolower(b); -}; +} // sort operators bool sortByTitle (const MI_MOVIE_INFO* a, const MI_MOVIE_INFO* b) @@ -403,7 +403,7 @@ void CMovieBrowser::fileInfoStale(void) m_FilterLines.lineArray[i].clear(); } m_browserListLines.Icon.clear(); -}; +} void CMovieBrowser::init(void) { @@ -480,7 +480,7 @@ void CMovieBrowser::init(void) break; } } - +#if 0 /***** Browser List **************/ if(m_settings.browserRowNr == 0) { @@ -495,7 +495,7 @@ void CMovieBrowser::init(void) m_settings.browserRowItem[5] = MB_INFO_QUALITY; reinit_rows = true; } - +#endif if (reinit_rows) { for (i = 0; i < m_settings.browserRowNr; i++) @@ -514,7 +514,8 @@ void CMovieBrowser::init(void) refreshLastRecordList(); refreshBrowserList(); refreshFilterList(); - g_PicViewer->getSupportedImageFormats(PicExts); + g_PicViewer->getSupportedImageFormats(PicExts); + show_mode = MB_SHOW_RECORDS; //FIXME #if 0 TRACE_1("Frames\r\n\tScren:\t%3d,%3d,%3d,%3d\r\n\tMain:\t%3d,%3d,%3d,%3d\r\n\tTitle:\t%3d,%3d,%3d,%3d \r\n\tBrowsr:\t%3d,%3d,%3d,%3d \r\n\tPlay:\t%3d,%3d,%3d,%3d \r\n\tRecord:\t%3d,%3d,%3d,%3d\r\n\r\n", g_settings.screen_StartX, @@ -583,12 +584,21 @@ void CMovieBrowser::initGlobalSettings(void) m_settings.browserFrameHeight = 50; /* percent */ m_settings.browserRowNr = 6; +#if 0 m_settings.browserRowItem[0] = MB_INFO_TITLE; m_settings.browserRowItem[1] = MB_INFO_INFO1; m_settings.browserRowItem[2] = MB_INFO_RECORDDATE; m_settings.browserRowItem[3] = MB_INFO_SIZE; m_settings.browserRowItem[4] = MB_INFO_PARENTAL_LOCKAGE; m_settings.browserRowItem[5] = MB_INFO_QUALITY; +#endif + m_settings.browserRowItem[0] = MB_INFO_CHANNEL; + m_settings.browserRowItem[1] = MB_INFO_TITLE; + m_settings.browserRowItem[2] = MB_INFO_RECORDDATE; + m_settings.browserRowItem[3] = MB_INFO_SIZE; + m_settings.browserRowItem[4] = MB_INFO_LENGTH; + m_settings.browserRowItem[5] = MB_INFO_INFO1; + m_settings.browserRowWidth[0] = m_defaultRowWidth[m_settings.browserRowItem[0]]; //300; m_settings.browserRowWidth[1] = m_defaultRowWidth[m_settings.browserRowItem[1]]; //100; m_settings.browserRowWidth[2] = m_defaultRowWidth[m_settings.browserRowItem[2]]; //80; @@ -596,6 +606,9 @@ void CMovieBrowser::initGlobalSettings(void) m_settings.browserRowWidth[4] = m_defaultRowWidth[m_settings.browserRowItem[4]]; //30; m_settings.browserRowWidth[5] = m_defaultRowWidth[m_settings.browserRowItem[5]]; //30; + m_settings.ytmode = cYTFeedParser::MOST_POPULAR; + m_settings.ytresults = 10; + m_settings.ytregion = "default"; } void CMovieBrowser::initFrames(void) @@ -758,6 +771,11 @@ bool CMovieBrowser::loadSettings(MB_SETTINGS* settings) snprintf(cfg_key, sizeof(cfg_key), "mb_browserRowWidth_%d", i); settings->browserRowWidth[i] = configfile.getInt32(cfg_key, 50); } + settings->ytmode = configfile.getInt32("mb_ytmode", cYTFeedParser::MOST_POPULAR); + settings->ytresults = configfile.getInt32("mb_ytresults", 10); + settings->ytregion = configfile.getString("mb_ytregion", "default"); + settings->ytsearch = configfile.getString("mb_ytsearch", ""); + settings->ytvid = configfile.getString("mb_ytvid", ""); return (result); } @@ -807,6 +825,11 @@ bool CMovieBrowser::saveSettings(MB_SETTINGS* settings) snprintf(cfg_key, sizeof(cfg_key), "mb_browserRowWidth_%d", i); configfile.setInt32(cfg_key, settings->browserRowWidth[i]); } + configfile.setInt32("mb_ytmode", settings->ytmode); + configfile.setInt32("mb_ytresults", settings->ytresults); + configfile.setString("mb_ytregion", settings->ytregion); + configfile.setString("mb_ytsearch", settings->ytsearch); + configfile.setString("mb_ytvid", settings->ytvid); if (configfile.getModifiedFlag()) configfile.saveConfig(MOVIEBROWSER_SETTINGS_FILE); @@ -960,6 +983,7 @@ int CMovieBrowser::exec(const char* path) if(m_file_info_stale == true) { TRACE("[mb] reload\r\n"); + loadMovies(); } else @@ -1230,11 +1254,18 @@ void CMovieBrowser::refreshMovieInfo(void) bool logo_ok = false; int picw = m_cBoxFrameInfo.iHeight * 16 / 9; int pich = m_cBoxFrameInfo.iHeight; - std::string fname = getScreenshotName(m_movieSelectionHandler->file.Name); - if(fname.empty()) { - std::string cover = m_movieSelectionHandler->file.Name; - cover.replace((cover.length()-18),15,""); //covername without yyyymmdd_hhmmss - fname = getScreenshotName(cover); + + std::string fname; +printf("CMovieBrowser::refreshMovieInfo\n"); + if (show_mode == MB_SHOW_YT) { + fname = m_movieSelectionHandler->tfile; + } else { + fname = getScreenshotName(m_movieSelectionHandler->file.Name); + if((fname.empty()) && (m_movieSelectionHandler->file.Name.length() > 18)) { + std::string cover = m_movieSelectionHandler->file.Name; + cover.replace((cover.length()-18),15,""); //covername without yyyymmdd_hhmmss + fname = getScreenshotName(cover); + } } logo_ok = (!fname.empty()); int flogo_w = 0, flogo_h = 0; @@ -1273,6 +1304,7 @@ void CMovieBrowser::refreshMovieInfo(void) } m_pcWindow->blit(); } + void CMovieBrowser::info_hdd_level(bool paint_hdd) { struct statfs s; @@ -1580,7 +1612,15 @@ void CMovieBrowser::refreshBookmarkList(void) // P3 void CMovieBrowser::refreshTitle(void) { //Paint Text Background - TRACE("[mb]->refreshTitle : %s\r\n",m_textTitle.c_str()); + std::string title = m_textTitle.c_str(); + if (show_mode == MB_SHOW_YT) { + title = g_Locale->getText(LOCALE_MOVIEPLAYER_YTPLAYBACK); + title += " : "; + title += g_Locale->getText(getFeedLocale()); + } + + TRACE("[mb]->refreshTitle : %s\r\n", title.c_str()); + const short text_border_width = 8; int start_y = m_cBoxFrame.iY+ m_cBoxFrameTitleRel.iY; @@ -1591,7 +1631,7 @@ void CMovieBrowser::refreshTitle(void) CFrameBuffer::getInstance()->getIconSize(NEUTRINO_ICON_MOVIEPLAYER, &iconw, &iconh); m_pcWindow->paintIcon(NEUTRINO_ICON_MOVIEPLAYER, m_cBoxFrame.iX+m_cBoxFrameTitleRel.iX+6, start_y+ m_cBoxFrameTitleRel.iHeight/2 - iconh/2); - m_pcFontTitle->RenderString(m_cBoxFrame.iX+m_cBoxFrameTitleRel.iX + iconw + text_border_width, start_y + m_cBoxFrameTitleRel.iHeight, m_cBoxFrameTitleRel.iWidth - (text_border_width << 1), m_textTitle.c_str(), TITLE_FONT_COLOR, 0, true); // UTF-8 + m_pcFontTitle->RenderString(m_cBoxFrame.iX+m_cBoxFrameTitleRel.iX + iconw + text_border_width, start_y + m_cBoxFrameTitleRel.iHeight, m_cBoxFrameTitleRel.iWidth - (text_border_width << 1), title.c_str(), TITLE_FONT_COLOR, 0, true); // UTF-8 info_hdd_level(true); } @@ -1739,6 +1779,9 @@ bool CMovieBrowser::onButtonPressMainFrame(neutrino_msg_t msg) } else if (msg == CRCInput::RC_blue) { + if (show_mode == MB_SHOW_YT) + ytparser.Cleanup(); + loadMovies(); refresh(); } @@ -1801,10 +1844,15 @@ bool CMovieBrowser::onButtonPressMainFrame(neutrino_msg_t msg) else if (msg == CRCInput::RC_setup) { //if(m_movieSelectionHandler != NULL) - showMenu(m_movieSelectionHandler); + if (show_mode == MB_SHOW_YT) + showYTMenu(); + else + showMenu(m_movieSelectionHandler); + } else if (msg == CRCInput::RC_text || msg == CRCInput::RC_radio) { - if(ShowMsgUTF (LOCALE_MESSAGEBOX_INFO, msg == CRCInput::RC_radio ? "Copy jumps from movie to new file ?" : "Copy jumps from movie to new files ?", CMessageBox::mbrNo, CMessageBox::mbYes | CMessageBox::mbNo) == CMessageBox::mbrYes) { + if((show_mode == MB_SHOW_RECORDS) && + (ShowMsgUTF (LOCALE_MESSAGEBOX_INFO, msg == CRCInput::RC_radio ? "Copy jumps from movie to new file ?" : "Copy jumps from movie to new files ?", CMessageBox::mbrNo, CMessageBox::mbYes | CMessageBox::mbNo) == CMessageBox::mbrYes)) { CHintBox * hintBox = new CHintBox(LOCALE_MESSAGEBOX_INFO, "Coping, please wait"); hintBox->paint(); sleep(1); @@ -1826,7 +1874,8 @@ bool CMovieBrowser::onButtonPressMainFrame(neutrino_msg_t msg) ShowMsgUTF(LOCALE_MESSAGEBOX_ERROR, "Impossible to cut playing movie.", CMessageBox::mbrCancel, CMessageBox::mbCancel, NEUTRINO_ICON_ERROR); else #endif - if(ShowMsgUTF (LOCALE_MESSAGEBOX_INFO, "Cut jumps from movie ?", CMessageBox::mbrNo, CMessageBox::mbYes | CMessageBox::mbNo) == CMessageBox::mbrYes) { + if((show_mode == MB_SHOW_RECORDS) && + (ShowMsgUTF (LOCALE_MESSAGEBOX_INFO, "Cut jumps from movie ?", CMessageBox::mbrNo, CMessageBox::mbYes | CMessageBox::mbNo) == CMessageBox::mbrYes)) { CHintBox * hintBox = new CHintBox(LOCALE_MESSAGEBOX_INFO, "Cutting, please wait"); hintBox->paint(); sleep(1); @@ -1844,26 +1893,28 @@ bool CMovieBrowser::onButtonPressMainFrame(neutrino_msg_t msg) } } else if (msg == CRCInput::RC_games) { - if((m_movieSelectionHandler == playing_info) && (NeutrinoMessages::mode_ts == CNeutrinoApp::getInstance()->getMode())) - ShowMsgUTF(LOCALE_MESSAGEBOX_ERROR, "Impossible to truncate playing movie.", CMessageBox::mbrCancel, CMessageBox::mbCancel, NEUTRINO_ICON_ERROR); - else if(m_movieSelectionHandler->bookmarks.end == 0) - ShowMsgUTF(LOCALE_MESSAGEBOX_ERROR, "No End bookmark defined!", CMessageBox::mbrCancel, CMessageBox::mbCancel, NEUTRINO_ICON_ERROR); - else { - if(ShowMsgUTF (LOCALE_MESSAGEBOX_INFO, "Truncate movie ?", CMessageBox::mbrNo, CMessageBox::mbYes | CMessageBox::mbNo) == CMessageBox::mbrYes) { - CHintBox * hintBox = new CHintBox(LOCALE_MESSAGEBOX_INFO, "Truncating, please wait"); - hintBox->paint(); - off64_t res = truncate_movie(m_movieSelectionHandler); - hintBox->hide(); - delete hintBox; - g_RCInput->clearRCMsg(); - if(res == 0) - ShowMsgUTF(LOCALE_MESSAGEBOX_ERROR, "Truncate failed.", CMessageBox::mbrCancel, CMessageBox::mbCancel, NEUTRINO_ICON_ERROR); - else { -//printf("New movie info: size %lld len %d\n", res, m_movieSelectionHandler->bookmarks.end/60); - m_movieInfo.saveMovieInfo( *m_movieSelectionHandler); - loadMovies(); + if((show_mode == MB_SHOW_RECORDS) && m_movieSelectionHandler != NULL) { + if((m_movieSelectionHandler == playing_info) && (NeutrinoMessages::mode_ts == CNeutrinoApp::getInstance()->getMode())) + ShowMsgUTF(LOCALE_MESSAGEBOX_ERROR, "Impossible to truncate playing movie.", CMessageBox::mbrCancel, CMessageBox::mbCancel, NEUTRINO_ICON_ERROR); + else if(m_movieSelectionHandler->bookmarks.end == 0) + ShowMsgUTF(LOCALE_MESSAGEBOX_ERROR, "No End bookmark defined!", CMessageBox::mbrCancel, CMessageBox::mbCancel, NEUTRINO_ICON_ERROR); + else { + if(ShowMsgUTF (LOCALE_MESSAGEBOX_INFO, "Truncate movie ?", CMessageBox::mbrNo, CMessageBox::mbYes | CMessageBox::mbNo) == CMessageBox::mbrYes) { + CHintBox * hintBox = new CHintBox(LOCALE_MESSAGEBOX_INFO, "Truncating, please wait"); + hintBox->paint(); + off64_t res = truncate_movie(m_movieSelectionHandler); + hintBox->hide(); + delete hintBox; + g_RCInput->clearRCMsg(); + if(res == 0) + ShowMsgUTF(LOCALE_MESSAGEBOX_ERROR, "Truncate failed.", CMessageBox::mbrCancel, CMessageBox::mbCancel, NEUTRINO_ICON_ERROR); + else { + //printf("New movie info: size %lld len %d\n", res, m_movieSelectionHandler->bookmarks.end/60); + m_movieInfo.saveMovieInfo( *m_movieSelectionHandler); + loadMovies(); + } + refresh(); } - refresh(); } } } else if (msg == CRCInput::RC_topleft) { @@ -2813,22 +2864,26 @@ void CMovieBrowser::loadMovies(bool doRefresh) TRACE("[mb] loadMovies: \n"); - CHintBox loadBox(LOCALE_MOVIEBROWSER_HEAD,g_Locale->getText(LOCALE_MOVIEBROWSER_SCAN_FOR_MOVIES)); + CHintBox loadBox((show_mode == MB_SHOW_YT)?LOCALE_MOVIEPLAYER_YTPLAYBACK:LOCALE_MOVIEBROWSER_HEAD,g_Locale->getText(LOCALE_MOVIEBROWSER_SCAN_FOR_MOVIES)); loadBox.paint(); //clock_act = clock()/10000;TRACE("[mb] *1: time %9ld clock %6ld dclock %6ld*\n",(long)time(NULL),clock_act,clock_act - clock_prev);clock_prev = clock_act; - loadAllTsFileNamesFromStorage(); // P1 -//clock_act = clock()/10000;TRACE("[mb] *2: time %9ld clock %6ld dclock %6ld*\n",(long)time(NULL),clock_act,clock_act - clock_prev);clock_prev = clock_act; - //loadAllMovieInfo(); // P1 -//clock_act = clock()/10000;TRACE("[mb] *3: time %9ld clock %6ld dclock %6ld*\n",(long)time(NULL),clock_act,clock_act - clock_prev);clock_prev = clock_act; m_file_info_stale = false; - m_seriename_stale = true; // we reloded the movie info, so make sure the other list are updated later on as well - updateSerienames(); -//clock_act = clock()/10000;TRACE("[mb] *4: time %9ld clock %6ld dclock %6ld*\n",(long)time(NULL),clock_act,clock_act - clock_prev);clock_prev = clock_act; - if(m_settings.serie_auto_create == 1) - { - autoFindSerie(); - } + if (show_mode == MB_SHOW_YT) { + loadYTitles(m_settings.ytmode, m_settings.ytsearch, m_settings.ytvid); + } else { + loadAllTsFileNamesFromStorage(); // P1 + //clock_act = clock()/10000;TRACE("[mb] *2: time %9ld clock %6ld dclock %6ld*\n",(long)time(NULL),clock_act,clock_act - clock_prev);clock_prev = clock_act; + //loadAllMovieInfo(); // P1 + //clock_act = clock()/10000;TRACE("[mb] *3: time %9ld clock %6ld dclock %6ld*\n",(long)time(NULL),clock_act,clock_act - clock_prev);clock_prev = clock_act; + m_seriename_stale = true; // we reloded the movie info, so make sure the other list are updated later on as well + updateSerienames(); + //clock_act = clock()/10000;TRACE("[mb] *4: time %9ld clock %6ld dclock %6ld*\n",(long)time(NULL),clock_act,clock_act - clock_prev);clock_prev = clock_act; + if(m_settings.serie_auto_create == 1) + { + autoFindSerie(); + } + } loadBox.hide(); @@ -3333,10 +3388,15 @@ bool CMovieBrowser::getMovieInfoItem(MI_MOVIE_INFO& movie_info, MB_INFO_ITEM ite snprintf(str_tmp,MAX_STR_TMP,"%02d.%02d.%02d",tm_tmp->tm_mday,(tm_tmp->tm_mon)+ 1, tm_tmp->tm_year >= 100 ? tm_tmp->tm_year-100 : tm_tmp->tm_year); *item_string = str_tmp; break; + case MB_INFO_RECORDDATE: // = 13, - tm_tmp = localtime(&movie_info.file.Time); - snprintf(str_tmp,MAX_STR_TMP,"%02d.%02d.%02d",tm_tmp->tm_mday,(tm_tmp->tm_mon) + 1,tm_tmp->tm_year >= 100 ? tm_tmp->tm_year-100 : tm_tmp->tm_year); - *item_string = str_tmp; + if (show_mode == MB_SHOW_YT) { + *item_string = movie_info.ytdate; + } else { + tm_tmp = localtime(&movie_info.file.Time); + snprintf(str_tmp,MAX_STR_TMP,"%02d.%02d.%02d",tm_tmp->tm_mday,(tm_tmp->tm_mon) + 1,tm_tmp->tm_year >= 100 ? tm_tmp->tm_year-100 : tm_tmp->tm_year); + *item_string = str_tmp; + } break; case MB_INFO_PRODDATE: // = 14, snprintf(str_tmp,MAX_STR_TMP,"%d",movie_info.productionDate); @@ -3425,7 +3485,8 @@ bool CMovieBrowser::getMovieInfoItem(MI_MOVIE_INFO& movie_info, MB_INFO_ITEM ite #endif // MB_INFO_AUDIO test break; case MB_INFO_LENGTH: // = 18, - snprintf(str_tmp,MAX_STR_TMP,"%4d",movie_info.length); + //snprintf(str_tmp,MAX_STR_TMP,"%4d",movie_info.length); + snprintf(str_tmp,MAX_STR_TMP,"%dh %dm", movie_info.length/60, movie_info.length%60); *item_string = str_tmp; break; case MB_INFO_SIZE: // = 19, @@ -3496,6 +3557,189 @@ void CMovieBrowser::autoFindSerie(void) } } +void CMovieBrowser::loadYTitles(int mode, std::string search, std::string id) +{ + printf("CMovieBrowser::loadYTitles: parsed %d old mode %d new mode %d region %s\n", ytparser.Parsed(), ytparser.GetFeedMode(), m_settings.ytmode, m_settings.ytregion.c_str()); + if (m_settings.ytregion == "default") + ytparser.SetRegion(""); + else + ytparser.SetRegion(m_settings.ytregion); + + ytparser.SetMaxResults(m_settings.ytresults); + + if (!ytparser.Parsed() || (ytparser.GetFeedMode() != mode)) { + if (ytparser.ParseFeed((cYTFeedParser::yt_feed_mode_t)mode, search, id)) { + ytparser.DownloadThumbnails(); + } else { + //FIXME show error + DisplayErrorMessage(g_Locale->getText(LOCALE_MOVIEBROWSER_YT_ERROR)); + return; + } + } + m_vMovieInfo.clear(); + yt_video_list_t &ylist = ytparser.GetVideoList(); + for (unsigned i = 0; i < ylist.size(); i++) { + MI_MOVIE_INFO movieInfo; + m_movieInfo.clearMovieInfo(&movieInfo); // refresh structure + movieInfo.epgChannel = ylist[i].author; + movieInfo.epgTitle = ylist[i].title; + movieInfo.epgInfo1 = ylist[i].category; + movieInfo.epgInfo2 = ylist[i].description; + movieInfo.length = ylist[i].duration/60 ; + movieInfo.tfile = ylist[i].tfile; + movieInfo.ytdate = ylist[i].published; + movieInfo.ytid = ylist[i].id; + + movieInfo.file.Name = ylist[i].title; + movieInfo.file.Url = ylist[i].GetUrl(); + m_vMovieInfo.push_back(movieInfo); + } + m_currentBrowserSelection = 0; + m_currentRecordSelection = 0; + m_currentPlaySelection = 0; + m_pcBrowser->setSelectedLine(m_currentBrowserSelection); + m_pcLastRecord->setSelectedLine(m_currentRecordSelection); + m_pcLastPlay->setSelectedLine(m_currentPlaySelection); +} + +const CMenuOptionChooser::keyval YT_FEED_OPTIONS[] = +{ + { cYTFeedParser::TOP_RATED, LOCALE_MOVIEBROWSER_YT_TOP_RATED }, + { cYTFeedParser::TOP_FAVORITES, LOCALE_MOVIEBROWSER_YT_TOP_FAVORITES }, + { cYTFeedParser::MOST_SHARED, LOCALE_MOVIEBROWSER_YT_MOST_SHARED }, + { cYTFeedParser::MOST_POPULAR, LOCALE_MOVIEBROWSER_YT_MOST_POPULAR }, + { cYTFeedParser::MOST_RESENT, LOCALE_MOVIEBROWSER_YT_MOST_RESENT }, + { cYTFeedParser::MOST_DISCUSSED, LOCALE_MOVIEBROWSER_YT_MOST_DISCUSSED }, + { cYTFeedParser::MOST_RESPONDED, LOCALE_MOVIEBROWSER_YT_MOST_RESPONDED }, + { cYTFeedParser::RECENTLY_FEATURED, LOCALE_MOVIEBROWSER_YT_RECENTLY_FEATURED }, + { cYTFeedParser::ON_THE_WEB, LOCALE_MOVIEBROWSER_YT_ON_THE_WEB }, +}; + +#define YT_FEED_OPTION_COUNT (sizeof(YT_FEED_OPTIONS)/sizeof(CMenuOptionChooser::keyval)) + +neutrino_locale_t CMovieBrowser::getFeedLocale(void) +{ + neutrino_locale_t ret = LOCALE_MOVIEBROWSER_YT_MOST_POPULAR; + + if (m_settings.ytmode == cYTFeedParser::RELATED) + return LOCALE_MOVIEBROWSER_YT_RELATED; + + if (m_settings.ytmode == cYTFeedParser::SEARCH) + return LOCALE_MOVIEBROWSER_YT_SEARCH; + + for (unsigned i = 0; i < YT_FEED_OPTION_COUNT; i++) { + if (m_settings.ytmode == YT_FEED_OPTIONS[i].key) + return YT_FEED_OPTIONS[i].value; + } + return ret; +} + +bool CMovieBrowser::showYTMenu() +{ + m_pcWindow->paintBackground(); + + CMenuWidget mainMenu(LOCALE_MOVIEPLAYER_YTPLAYBACK, NEUTRINO_ICON_MOVIEPLAYER); + mainMenu.addIntroItems(LOCALE_MOVIEBROWSER_OPTION_BROWSER); + + int select = -1; + CMenuSelectorTarget * selector = new CMenuSelectorTarget(&select); + + char cnt[5]; + for (unsigned i = 0; i < YT_FEED_OPTION_COUNT; i++) { + sprintf(cnt, "%d", YT_FEED_OPTIONS[i].key); + mainMenu.addItem(new CMenuForwarder(YT_FEED_OPTIONS[i].value, true, NULL, selector, cnt, CRCInput::convertDigitToKey(i + 1)), m_settings.ytmode == (int) YT_FEED_OPTIONS[i].key); + } + mainMenu.addItem(GenericMenuSeparatorLine); + + bool enabled = (!m_vMovieInfo.empty()) && (m_movieSelectionHandler != NULL); + sprintf(cnt, "%d", cYTFeedParser::RELATED); + mainMenu.addItem(new CMenuForwarder(LOCALE_MOVIEBROWSER_YT_RELATED, enabled, NULL, selector, cnt, CRCInput::RC_red, NEUTRINO_ICON_BUTTON_RED)); + + sprintf(cnt, "%d", cYTFeedParser::NEXT); + mainMenu.addItem(new CMenuForwarder(LOCALE_MOVIEBROWSER_YT_NEXT_RESULTS, ytparser.HaveNext(), NULL, selector, cnt, CRCInput::RC_green, NEUTRINO_ICON_BUTTON_GREEN)); + sprintf(cnt, "%d", cYTFeedParser::PREV); + mainMenu.addItem(new CMenuForwarder(LOCALE_MOVIEBROWSER_YT_PREV_RESULTS, ytparser.HavePrev(), NULL, selector, cnt, CRCInput::RC_yellow, NEUTRINO_ICON_BUTTON_YELLOW)); + + mainMenu.addItem(GenericMenuSeparatorLine); + + std::string search = m_settings.ytsearch; + CStringInputSMS stringInput(LOCALE_MOVIEBROWSER_YT_SEARCH, &search, 20, NONEXISTANT_LOCALE, NONEXISTANT_LOCALE, "abcdefghijklmnopqrstuvwxyz0123456789 -_/()<>=+.,:!?\\'"); + mainMenu.addItem(new CMenuForwarder(LOCALE_MOVIEBROWSER_YT_SEARCH, true, search, &stringInput, NULL, CRCInput::RC_nokey, "")); + sprintf(cnt, "%d", cYTFeedParser::SEARCH); + mainMenu.addItem(new CMenuForwarder(LOCALE_EVENTFINDER_START_SEARCH, true, NULL, selector, cnt, CRCInput::RC_blue, NEUTRINO_ICON_BUTTON_BLUE)); + + mainMenu.addItem(GenericMenuSeparatorLine); + mainMenu.addItem(new CMenuOptionNumberChooser(LOCALE_MOVIEBROWSER_YT_MAX_RESULTS, &m_settings.ytresults, true, 10, 50, NULL)); + + char rstr[20]; + sprintf(rstr, "%s", m_settings.ytregion.c_str()); + CMenuOptionStringChooser * region = new CMenuOptionStringChooser(LOCALE_MOVIEBROWSER_YT_REGION, rstr, true, NULL, CRCInput::RC_nokey, "", true); + region->addOption("default"); + region->addOption("DE"); + region->addOption("PL"); + region->addOption("RU"); + region->addOption("NL"); + region->addOption("CZ"); + region->addOption("FR"); + region->addOption("HU"); + region->addOption("US"); + mainMenu.addItem(region); + + mainMenu.exec(NULL, ""); + delete selector; + + bool reload = false; + printf("MovieBrowser::showYTMenu(): selected: %d\n", select); + int newmode = -1; + if (select >= 0) { + newmode = select; + if (newmode == cYTFeedParser::NEXT || newmode == cYTFeedParser::PREV) { + reload = true; + } + else if (select == cYTFeedParser::RELATED) { + if (m_settings.ytvid != m_movieSelectionHandler->ytid) { + printf("get related for: %s\n", m_movieSelectionHandler->ytid.c_str()); + m_settings.ytvid = m_movieSelectionHandler->ytid; + m_settings.ytmode = newmode; + reload = true; + } + } + else if (select == cYTFeedParser::SEARCH) { + printf("search for: %s\n", search.c_str()); + if (!search.empty()) { + reload = true; + m_settings.ytsearch = search; + m_settings.ytmode = newmode; + } + } + else if (m_settings.ytmode != newmode) { + m_settings.ytmode = newmode; + reload = true; + } + } + if(rstr != m_settings.ytregion) { + m_settings.ytregion = rstr; + if (newmode < 0) + newmode = m_settings.ytmode; + reload = true; + printf("change region to %s\n", m_settings.ytregion.c_str()); + } + if (reload) { + CHintBox loadBox(LOCALE_MOVIEPLAYER_YTPLAYBACK, g_Locale->getText(LOCALE_MOVIEBROWSER_SCAN_FOR_MOVIES)); + loadBox.paint(); + ytparser.Cleanup(); + loadYTitles(newmode, m_settings.ytsearch, m_settings.ytvid); + loadBox.hide(); + } + refreshBrowserList(); + refreshLastPlayList(); + refreshLastRecordList(); + refreshFilterList(); + //refreshMovieInfo(); + refresh(); + return true; +} + CMenuSelector::CMenuSelector(const char * OptionName, const bool Active , char * OptionValue, int* ReturnInt ,int ReturnIntValue ) : CMenuItem() { height = g_Font[SNeutrinoSettings::FONT_TYPE_MENU]->getHeight(); @@ -3505,7 +3749,7 @@ CMenuSelector::CMenuSelector(const char * OptionName, const bool Active , char * active = Active; returnIntValue = ReturnIntValue; returnInt = ReturnInt; -}; +} CMenuSelector::CMenuSelector(const char * OptionName, const bool Active , std::string& OptionValue, int* ReturnInt ,int ReturnIntValue ) : CMenuItem() { @@ -3518,7 +3762,7 @@ CMenuSelector::CMenuSelector(const char * OptionName, const bool Active , std::s active = Active; returnIntValue = ReturnIntValue; returnInt = ReturnInt; -}; +} int CMenuSelector::exec(CMenuTarget* /*parent*/) { @@ -3533,7 +3777,7 @@ int CMenuSelector::exec(CMenuTarget* /*parent*/) *optionValueString = optionName; } return menu_return::RETURN_EXIT; -}; +} int CMenuSelector::paint(bool selected) { @@ -3633,7 +3877,7 @@ printf("[CDirMenu] (nfs%d) %s == (mb%d) %s (%d)\n",nfs,g_settings.network_nfs_lo } } } -}; +} int CDirMenu::exec(CMenuTarget* parent, const std::string & actionKey) { @@ -3762,7 +4006,6 @@ printf("updateDirState: %d: state %d nfs %d\n", i, dirState[i], dirNfsMountNr[i] } } - int CDirMenu::show(void) { if(dirList->empty()) diff --git a/src/gui/moviebrowser.h b/src/gui/moviebrowser.h index a4df89ba4..1126404a8 100644 --- a/src/gui/moviebrowser.h +++ b/src/gui/moviebrowser.h @@ -80,6 +80,7 @@ #include #include #include +#include #define MAX_NUMBER_OF_BOOKMARK_ITEMS MI_MOVIE_BOOK_USER_MAX // we just use the same size as used in Movie info (MAX_NUMBER_OF_BOOKMARK_ITEMS is used for the number of menu items) #define MOVIEBROWSER_SETTINGS_FILE CONFIGDIR "/moviebrowser.conf" @@ -181,6 +182,13 @@ typedef struct int* used; }MB_DIR; +typedef enum +{ + MB_SHOW_RECORDS, + MB_SHOW_FILES, + MB_SHOW_YT +} MB_SHOW_MODE; + #define MB_MAX_ROWS 6 #define MB_MAX_DIRS 5 /* MB_SETTINGS to be stored in g_settings anytime ....*/ @@ -219,6 +227,11 @@ typedef struct int lastRecordRowNr; MB_INFO_ITEM lastRecordRow[MB_MAX_ROWS]; int lastRecordRowWidth[MB_MAX_ROWS]; + int ytmode; + int ytresults; + std::string ytregion; + std::string ytvid; + std::string ytsearch; } MB_SETTINGS; // Priorities for Developmemt: P1: critical feature, P2: important feature, P3: for next release, P4: looks nice, lets see @@ -303,6 +316,11 @@ class CMovieBrowser : public CMenuTarget //bool restart_mb_timeout; int menu_ret; + cYTFeedParser ytparser; + int show_mode; + void loadYTitles(int mode, std::string search = "", std::string id = ""); + bool showYTMenu(void); + public: // Functions //////////////////////////////////////////////////////////7 CMovieBrowser(const char* path); //P1 CMovieBrowser(); //P1 @@ -324,6 +342,8 @@ class CMovieBrowser : public CMenuTarget bool delFile_vlc(CFile& file); bool delFile_std(CFile& file); int getMenuRet() { return menu_ret; } + int getMode() { return show_mode; } + void setMode(int mode) { show_mode = mode; } private: //Functions ///// MovieBrowser init /////////////// @@ -402,6 +422,8 @@ class CMovieBrowser : public CMenuTarget void autoFindSerie(void); void info_hdd_level(bool paint_hdd=false); + + neutrino_locale_t getFeedLocale(void); }; // Class to show Moviebrowser Information, to be used by menu diff --git a/src/gui/movieinfo.cpp b/src/gui/movieinfo.cpp index a8b46c4b3..106536ef5 100644 --- a/src/gui/movieinfo.cpp +++ b/src/gui/movieinfo.cpp @@ -922,6 +922,9 @@ void CMovieInfo::clearMovieInfo(MI_MOVIE_INFO * movie_info) movie_info->bookmarks.user[i].length = 0; movie_info->bookmarks.user[i].name = ""; } + movie_info->tfile.clear(); + movie_info->ytdate.clear(); + movie_info->ytid.clear(); } /************************************************************************ diff --git a/src/gui/movieinfo.h b/src/gui/movieinfo.h index d90369b63..cc4d6683d 100644 --- a/src/gui/movieinfo.h +++ b/src/gui/movieinfo.h @@ -169,7 +169,10 @@ typedef struct int epgVideoPid; // currently not used, we just do not want to loose this info if movie info is saved backed int VideoType; int epgVTXPID; // currently not used, we just do not want to loose this info if movie info is saved backed -}MI_MOVIE_INFO; + std::string tfile; // thumbnail/cover file name + std::string ytdate; // yt published + std::string ytid; // yt published +} MI_MOVIE_INFO; class CMovieInfo diff --git a/src/gui/movieplayer.cpp b/src/gui/movieplayer.cpp index 7891ee078..aaa621990 100644 --- a/src/gui/movieplayer.cpp +++ b/src/gui/movieplayer.cpp @@ -28,6 +28,7 @@ #include #endif +#define __STDC_CONSTANT_MACROS #include #include @@ -41,6 +42,7 @@ #include #include #include +#include #include #include @@ -210,6 +212,12 @@ int CMoviePlayerGui::exec(CMenuTarget * parent, const std::string & actionKey) timeshift = 0; if (actionKey == "tsmoviebrowser") { isMovieBrowser = true; + moviebrowser->setMode(MB_SHOW_RECORDS); + } + else if (actionKey == "ytplayback") { + CAudioMute::getInstance()->enableMuteIcon(false); + isMovieBrowser = true; + moviebrowser->setMode(MB_SHOW_YT); } else if (actionKey == "fileplayback") { } @@ -245,6 +253,9 @@ int CMoviePlayerGui::exec(CMenuTarget * parent, const std::string & actionKey) CVFD::getInstance()->setMode(CVFD::MODE_TVRADIO); + if (moviebrowser->getMode() == MB_SHOW_YT) + CAudioMute::getInstance()->enableMuteIcon(true); + if (timeshift){ timeshift = 0; return menu_return::RETURN_EXIT_ALL; @@ -328,6 +339,8 @@ bool CMoviePlayerGui::SelectFile() language[i].clear(); } numpida = 0; currentapid = 0; + currentspid = -1; + numsubs = 0; is_file_player = false; p_movie_info = NULL; @@ -363,15 +376,17 @@ bool CMoviePlayerGui::SelectFile() Path_local = moviebrowser->getCurrentDir(); CFile *file; if ((file = moviebrowser->getSelectedFile()) != NULL) { - full_name = file->Name.c_str(); - // get the movie info handle (to be used for e.g. bookmark handling) p_movie_info = moviebrowser->getCurrentMovieInfo(); -#if 0 - bool recfile = CRecordManager::getInstance()->RecordingStatus(p_movie_info->epgId) && - CRecordManager::getInstance()->GetFileName(p_movie_info->epgId) == file->Name; -#endif + if (moviebrowser->getMode() == MB_SHOW_RECORDS) { + full_name = file->Name; + } + else if (moviebrowser->getMode() == MB_SHOW_YT) { + full_name = file->Url; + is_file_player = true; + } fillPids(); + // get the start position for the movie startposition = 1000 * moviebrowser->getCurrentStartPos(); printf("CMoviePlayerGui::SelectFile: file %s start %d apid %X atype %d vpid %x vtype %d\n", full_name.c_str(), startposition, currentapid, currentac3, vpid, vtype); @@ -380,7 +395,7 @@ bool CMoviePlayerGui::SelectFile() } } else menu_ret = moviebrowser->getMenuRet(); - } + } else { // filebrowser CAudioMute::getInstance()->enableMuteIcon(false); if (filebrowser->exec(Path_local.c_str()) == true) { @@ -456,6 +471,8 @@ void CMoviePlayerGui::PlayFile(void) handleMovieBrowser(CRCInput::RC_nokey, position); cutNeutrino(); + clearSubtitle(); + playback->Open(is_file_player ? PLAYMODE_FILE : PLAYMODE_TS); printf("IS FILE PLAYER: %s\n", is_file_player ? "true": "false" ); @@ -556,6 +573,7 @@ void CMoviePlayerGui::PlayFile(void) handleMovieBrowser(0, position); FileTime.update(position, duration); } + showSubtitle(0); if (msg == (neutrino_msg_t) g_settings.mpkey_plugin) { //g_PluginList->start_plugin_by_name (g_settings.movieplayer_plugin.c_str (), pidt); @@ -593,29 +611,37 @@ void CMoviePlayerGui::PlayFile(void) callInfoViewer(/*duration, position*/); } else if (msg == (neutrino_msg_t) g_settings.mpkey_bookmark) { - handleMovieBrowser((neutrino_msg_t) g_settings.mpkey_bookmark, position); + if (is_file_player) + selectChapter(); + else + handleMovieBrowser((neutrino_msg_t) g_settings.mpkey_bookmark, position); + update_lcd = true; + clearSubtitle(); } else if (msg == (neutrino_msg_t) g_settings.mpkey_audio) { selectAudioPid(is_file_player); update_lcd = true; + clearSubtitle(); + } else if ( msg == (neutrino_msg_t) g_settings.mpkey_subtitle) { + selectSubtitle(); + clearSubtitle(); + update_lcd = true; } else if (msg == (neutrino_msg_t) g_settings.mpkey_time) { FileTime.switchMode(position, duration); - } else if ((msg == (neutrino_msg_t) g_settings.mpkey_rewind) || - (msg == (neutrino_msg_t) g_settings.mpkey_forward)) { + } else if (/*!is_file_player &&*/ ((msg == (neutrino_msg_t) g_settings.mpkey_rewind) || + (msg == (neutrino_msg_t) g_settings.mpkey_forward))) { int newspeed; if (msg == (neutrino_msg_t) g_settings.mpkey_rewind) { newspeed = (speed >= 0) ? -1 : speed - 1; - if (playstate != CMoviePlayerGui::PAUSE) - playstate = CMoviePlayerGui::REW; } else { newspeed = (speed <= 0) ? 2 : speed + 1; - if (playstate != CMoviePlayerGui::PAUSE) - playstate = CMoviePlayerGui::FF; } /* if paused, playback->SetSpeed() start slow motion */ if (playback->SetSpeed(newspeed)) { printf("SetSpeed: update speed\n"); speed = newspeed; + if (playstate != CMoviePlayerGui::PAUSE) + playstate = msg == (neutrino_msg_t) g_settings.mpkey_rewind ? CMoviePlayerGui::REW : CMoviePlayerGui::FF; updateLcd(); } //update_lcd = true; @@ -628,32 +654,44 @@ void CMoviePlayerGui::PlayFile(void) time_forced = true; } } else if (msg == CRCInput::RC_1) { // Jump Backwards 1 minute + clearSubtitle(); playback->SetPosition(-60 * 1000); } else if (msg == CRCInput::RC_3) { // Jump Forward 1 minute + clearSubtitle(); playback->SetPosition(60 * 1000); } else if (msg == CRCInput::RC_4) { // Jump Backwards 5 minutes + clearSubtitle(); playback->SetPosition(-5 * 60 * 1000); } else if (msg == CRCInput::RC_6) { // Jump Forward 5 minutes + clearSubtitle(); playback->SetPosition(5 * 60 * 1000); } else if (msg == CRCInput::RC_7) { // Jump Backwards 10 minutes + clearSubtitle(); playback->SetPosition(-10 * 60 * 1000); } else if (msg == CRCInput::RC_9) { // Jump Forward 10 minutes + clearSubtitle(); playback->SetPosition(10 * 60 * 1000); } else if (msg == CRCInput::RC_2) { // goto start + clearSubtitle(); playback->SetPosition(0, true); } else if (msg == CRCInput::RC_5) { // goto middle + clearSubtitle(); playback->SetPosition(duration/2, true); } else if (msg == CRCInput::RC_8) { // goto end + clearSubtitle(); playback->SetPosition(duration - 60 * 1000, true); } else if (msg == CRCInput::RC_page_up) { + clearSubtitle(); playback->SetPosition(10 * 1000); } else if (msg == CRCInput::RC_page_down) { + clearSubtitle(); playback->SetPosition(-10 * 1000); } else if (msg == CRCInput::RC_0) { // cancel bookmark jump handleMovieBrowser(CRCInput::RC_0, position); } else if (msg == CRCInput::RC_help || msg == CRCInput::RC_info) { callInfoViewer(/*duration, position*/); update_lcd = true; + clearSubtitle(); //showHelpTS(); } else if(timeshift && (msg == CRCInput::RC_text || msg == CRCInput::RC_epg || msg == NeutrinoMessages::SHOW_EPG)) { bool restore = FileTime.IsVisible(); @@ -702,6 +740,8 @@ void CMoviePlayerGui::PlayFile(void) sc->Start(); #endif + } else if ( msg == NeutrinoMessages::EVT_SUBT_MESSAGE) { + showSubtitle(data); } else if ( msg == NeutrinoMessages::ANNOUNCE_RECORD || msg == NeutrinoMessages::RECORD_START) { CNeutrinoApp::getInstance()->handleMsg(msg, data); @@ -727,6 +767,7 @@ void CMoviePlayerGui::PlayFile(void) } else if ( msg <= CRCInput::RC_MaxRC ) { update_lcd = true; + clearSubtitle(); } } @@ -738,6 +779,7 @@ void CMoviePlayerGui::PlayFile(void) } FileTime.hide(); + clearSubtitle(); playback->SetSpeed(1); playback->Close(); @@ -789,13 +831,13 @@ bool CMoviePlayerGui::getAudioName(int apid, std::string &apidtitle) return false; } -void CMoviePlayerGui::addAudioFormat(int count, std::string &apidtitle, bool file_player, bool& enabled) +void CMoviePlayerGui::addAudioFormat(int count, std::string &apidtitle, bool& enabled) { enabled = true; switch(ac3flags[count]) { case 1: /*AC3,EAC3*/ - if (apidtitle.find("AC3") == std::string::npos || file_player) + if (apidtitle.find("AC3") == std::string::npos) apidtitle.append(" (AC3)"); break; case 2: /*teletext*/ @@ -813,6 +855,8 @@ void CMoviePlayerGui::addAudioFormat(int count, std::string &apidtitle, bool fil break; case 6: /*DTS*/ apidtitle.append(" (DTS)"); + if (apidtitle.find("DTS") == std::string::npos) + apidtitle.append(" (DTS)"); #if ! defined(HAVE_SPARK_HARDWARE) && ! defined (BOXMODEL_APOLLO) enabled = false; #endif @@ -834,14 +878,13 @@ void CMoviePlayerGui::getCurrentAudioName( bool file_player, std::string &audion } bool dumm = true; for (unsigned int count = 0; count < numpida; count++) { - if(currentapid == apids[count]){ if(!file_player){ getAudioName(apids[count], audioname); return ; - }else if (!language[count].empty()){ + } else if (!language[count].empty()){ audioname = language[count]; - addAudioFormat(count, audioname, file_player, dumm); + addAudioFormat(count, audioname, dumm); if(!dumm && (count < numpida)){ currentapid = apids[count+1]; continue; @@ -851,7 +894,7 @@ void CMoviePlayerGui::getCurrentAudioName( bool file_player, std::string &audion char apidnumber[20]; sprintf(apidnumber, "Stream %d %X", count + 1, apids[count]); audioname = apidnumber; - addAudioFormat(count, audioname, file_player, dumm); + addAudioFormat(count, audioname, dumm); if(!dumm && (count < numpida)){ currentapid = apids[count+1]; continue; @@ -892,7 +935,7 @@ void CMoviePlayerGui::selectAudioPid(bool file_player) sprintf(apidnumber, "Stream %d %X", count + 1, apids[count]); apidtitle = apidnumber; } - addAudioFormat(count, apidtitle, file_player, enabled); + addAudioFormat(count, apidtitle, enabled); if(defpid && !enabled && (count < numpida)){ currentapid = apids[count+1]; defpid = false; @@ -904,7 +947,7 @@ void CMoviePlayerGui::selectAudioPid(bool file_player) APIDSelector.addItem(item, defpid); } - if (p_movie_info) { + if (p_movie_info && numpida <= p_movie_info->audioPids.size()) { APIDSelector.addItem(new CMenuSeparator(CMenuSeparator::LINE | CMenuSeparator::STRING, LOCALE_AUDIOMENU_VOLUME_ADJUST)); CVolume::getInstance()->SetCurrentChannel(p_movie_info->epgId); @@ -1084,7 +1127,7 @@ void CMoviePlayerGui::handleMovieBrowser(neutrino_msg_t msg, int /*position*/) jump_not_until = (position / 1000) + 10; // avoid bookmark jumping for the next 10 seconds, , TODO: might be moved to another key } return; - } + } else if (msg == (neutrino_msg_t) g_settings.mpkey_bookmark) { if (newComHintBox.isPainted() == true) { // yes, let's get the end pos of the jump forward @@ -1144,7 +1187,7 @@ void CMoviePlayerGui::handleMovieBrowser(neutrino_msg_t msg, int /*position*/) DisplayErrorMessage(g_Locale->getText(LOCALE_MOVIEPLAYER_TOOMANYBOOKMARKS)); // UTF-8 } cSelectedMenuBookStart[0].selected = false; // clear for next bookmark menu - } else + } else #endif if (cSelectedMenuBookStart[1].selected == true) { /* Moviebrowser plain bookmark */ @@ -1213,3 +1256,234 @@ void CMoviePlayerGui::showHelpTS() helpbox.addLine(g_Locale->getText(LOCALE_MOVIEPLAYER_TSHELP12)); helpbox.show(LOCALE_MESSAGEBOX_INFO); } + +void CMoviePlayerGui::selectChapter() +{ + if (!is_file_player) + return; + + std::vector positions; std::vector titles; + playback->GetChapters(positions, titles); + if (positions.empty()) + return; + + CMenuWidget ChSelector(LOCALE_MOVIEBROWSER_MENU_MAIN_BOOKMARKS, NEUTRINO_ICON_AUDIO); + ChSelector.addIntroItems(); + + int select = -1; + CMenuSelectorTarget * selector = new CMenuSelectorTarget(&select); + char cnt[5]; + for (unsigned i = 0; i < positions.size(); i++) { + sprintf(cnt, "%d", i); + CMenuForwarderNonLocalized * item = new CMenuForwarderNonLocalized(titles[i].c_str(), true, NULL, selector, cnt, CRCInput::convertDigitToKey(i + 1)); + ChSelector.addItem(item, position > positions[i]); + } + ChSelector.exec(NULL, ""); + delete selector; + printf("CMoviePlayerGui::selectChapter: selected %d (%d)\n", select, (select >= 0) ? positions[select] : -1); + if(select >= 0) + playback->SetPosition(positions[select], true); +} + +void CMoviePlayerGui::selectSubtitle() +{ + if (!is_file_player) + return; + + CMenuWidget APIDSelector(LOCALE_SUBTITLES_HEAD, NEUTRINO_ICON_AUDIO); + APIDSelector.addIntroItems(); + + int select = -1; + CMenuSelectorTarget * selector = new CMenuSelectorTarget(&select); + if(!numsubs) { + playback->FindAllSubs(spids, sub_supported, &numsubs, slanguage); + } + char cnt[5]; + unsigned int count; + for (count = 0; count < numsubs; count++) { + bool enabled = sub_supported[count]; + bool defpid = currentspid >= 0 ? (currentspid == spids[count]) : (count == 0); + std::string title = slanguage[count]; + if (title.empty()) { + char pidnumber[20]; + sprintf(pidnumber, "Stream %d %X", count + 1, spids[count]); + title = pidnumber; + } + sprintf(cnt, "%d", count); + CMenuForwarderNonLocalized * item = new CMenuForwarderNonLocalized(title.c_str(), enabled, NULL, selector, cnt, CRCInput::convertDigitToKey(count + 1)); + item->setItemButton(NEUTRINO_ICON_BUTTON_STOP, false); + APIDSelector.addItem(item, defpid); + } + sprintf(cnt, "%d", count); + APIDSelector.addItem(new CMenuForwarder(LOCALE_SUBTITLES_STOP, true, NULL, selector, cnt, CRCInput::RC_stop), currentspid < 0); + + APIDSelector.exec(NULL, ""); + delete selector; + printf("CMoviePlayerGui::selectSubtitle: selected %d (%x) current %x\n", select, (select >= 0) ? spids[select] : -1, currentspid); + if((select >= 0) && (select < numsubs) && (currentspid != spids[select])) { + currentspid = spids[select]; + playback->SelectSubtitles(currentspid); + printf("[movieplayer] spid changed to %d\n", currentspid); + } else if ( select > 0) { + currentspid = -1; + playback->SelectSubtitles(currentspid); + printf("[movieplayer] spid changed to %d\n", currentspid); + } +} + +extern "C" { +#include +#include +} + +void CMoviePlayerGui::clearSubtitle() +{ + if ((max_x-min_x > 0) && (max_y-min_y > 0)) + frameBuffer->paintBackgroundBoxRel(min_x, min_y, max_x-min_x, max_y-min_y); + + min_x = CFrameBuffer::getInstance()->getScreenWidth(); + min_y = CFrameBuffer::getInstance()->getScreenHeight(); + max_x = CFrameBuffer::getInstance()->getScreenX(); + max_y = CFrameBuffer::getInstance()->getScreenY(); + end_time = 0; +} + +fb_pixel_t * simple_resize32(uint8_t * orgin, uint32_t * colors, int nb_colors, int ox, int oy, int dx, int dy); + +void CMoviePlayerGui::showSubtitle(neutrino_msg_data_t data) +{ + if (!data) { + if (end_time && time_monotonic_ms() > end_time) { + printf("************************* hide subs *************************\n"); + clearSubtitle(); + } + return; + } + AVSubtitle * sub = (AVSubtitle *) data; + + printf("************************* EVT_SUBT_MESSAGE: num_rects %d fmt %d *************************\n", sub->num_rects, sub->format); + if (!sub->num_rects) + return; + + if (sub->format == 0) { + int xres = 0, yres = 0, framerate; + videoDecoder->getPictureInfo(xres, yres, framerate); + + double xc = (double) CFrameBuffer::getInstance()->getScreenWidth(/*true*/)/(double) xres; + double yc = (double) CFrameBuffer::getInstance()->getScreenHeight(/*true*/)/(double) yres; + + clearSubtitle(); + + for (unsigned i = 0; i < sub->num_rects; i++) { + uint32_t * colors = (uint32_t *) sub->rects[i]->pict.data[1]; + + int nw = (double) sub->rects[i]->w * xc; + int nh = (double) sub->rects[i]->h * yc; + int xoff = (double) sub->rects[i]->x * xc; + int yoff = (double) sub->rects[i]->y * yc; + + printf("Draw: #%d at %d,%d size %dx%d colors %d (x=%d y=%d w=%d h=%d) \n", i+1, + sub->rects[i]->x, sub->rects[i]->y, sub->rects[i]->w, sub->rects[i]->h, + sub->rects[i]->nb_colors, xoff, yoff, nw, nh); + + fb_pixel_t * newdata = simple_resize32 (sub->rects[i]->pict.data[0], colors, + sub->rects[i]->nb_colors, sub->rects[i]->w, sub->rects[i]->h, nw, nh); + frameBuffer->blit2FB(newdata, nw, nh, xoff, yoff); + free(newdata); + + min_x = std::min(min_x, xoff); + max_x = std::max(max_x, xoff + nw); + min_y = std::min(min_y, yoff); + max_y = std::max(max_y, yoff + nh); + } + end_time = sub->end_display_time + time_monotonic_ms(); + avsubtitle_free(sub); + delete sub; + return; + } + std::vector subtext; + for (unsigned i = 0; i < sub->num_rects; i++) { + char * txt = NULL; + if (sub->rects[i]->type == SUBTITLE_TEXT) + txt = sub->rects[i]->text; + else if (sub->rects[i]->type == SUBTITLE_ASS) + txt = sub->rects[i]->ass; + printf("subt[%d] type %d [%s]\n", i, sub->rects[i]->type, txt ? txt : ""); + if (txt) { + int len = strlen(txt); + if (len > 10 && memcmp(txt, "Dialogue: ", 10) == 0) { + char* p = txt; + int skip_commas = 4; + /* skip ass times */ + for (int j = 0; j < skip_commas && *p != '\0'; p++) + if (*p == ',') + j++; + /* skip ass tags */ + if (*p == '{') { + char * d = strchr(p, '}'); + if (d) + p += d - p + 1; + } + char * d = strchr(p, '{'); + if (d && strchr(d, '}')) + *d = 0; + + len = strlen(p); + /* remove newline */ + for (int j = len-1; j > 0; j--) { + if (p[j] == '\n' || p[j] == '\r') + p[j] = 0; + else + break; + } + if (*p == '\0') + continue; + txt = p; + } + //printf("title: [%s]\n", txt); + std::string str(txt); + unsigned int start = 0, end = 0; + /* split string with \N as newline */ + std::string delim("\\N"); + while ((end = str.find(delim, start)) != string::npos) { + subtext.push_back(str.substr(start, end - start)); + start = end + 2; + } + subtext.push_back(str.substr(start)); + + } + } + for (unsigned i = 0; i < subtext.size(); i++) + printf("subtext %d: [%s]\n", i, subtext[i].c_str()); + printf("********************************************************************\n"); + + if (!subtext.empty()) { + int sh = frameBuffer->getScreenHeight(); + int sw = frameBuffer->getScreenWidth(); + int h = g_Font[SNeutrinoSettings::FONT_TYPE_MENU]->getHeight(); + int height = h*subtext.size(); + + clearSubtitle(); + + int x[subtext.size()]; + int y[subtext.size()]; + for (unsigned i = 0; i < subtext.size(); i++) { + int w = g_Font[SNeutrinoSettings::FONT_TYPE_MENU]->getRenderWidth (subtext[i].c_str(), true); + x[i] = (sw - w) / 2; + y[i] = sh - height + h*(i + 1); + min_x = std::min(min_x, x[i]); + max_x = std::max(max_x, x[i]+w); + min_y = std::min(min_y, y[i]-h); + max_y = std::max(max_y, y[i]); + } + + frameBuffer->paintBoxRel(min_x, min_y, max_x - min_x, max_y-min_y, COL_MENUCONTENT_PLUS_0); + + for (unsigned i = 0; i < subtext.size(); i++) + g_Font[SNeutrinoSettings::FONT_TYPE_MENU]->RenderString(x[i], y[i], sw, subtext[i].c_str(), COL_MENUCONTENT, 0, true); + + end_time = sub->end_display_time + time_monotonic_ms(); + } + avsubtitle_free(sub); + delete sub; +} diff --git a/src/gui/movieplayer.h b/src/gui/movieplayer.h index df8434f67..c3356e12e 100644 --- a/src/gui/movieplayer.h +++ b/src/gui/movieplayer.h @@ -61,7 +61,7 @@ class CMoviePlayerGui : public CMenuTarget PLAY = 3, PAUSE = 4, FF = 5, - REW = 6, + REW = 6 }; private: @@ -87,6 +87,15 @@ class CMoviePlayerGui : public CMenuTarget unsigned short ac3flags[REC_MAX_APIDS]; unsigned short currentapid, currentac3; + /* subtitles vars */ + unsigned short numsubs; + std::string slanguage[REC_MAX_APIDS]; + unsigned short spids[REC_MAX_APIDS]; + unsigned short sub_supported[REC_MAX_APIDS]; + int currentspid; + int min_x, min_y, max_x, max_y; + time_t end_time; + /* playback from MB */ bool isMovieBrowser; CMovieBrowser* moviebrowser; @@ -118,12 +127,17 @@ class CMoviePlayerGui : public CMenuTarget bool getAudioName(int pid, std::string &apidtitle); void selectAudioPid(bool file_player); void getCurrentAudioName( bool file_player, std::string &audioname); - void addAudioFormat(int count, std::string &apidtitle, bool file_player, bool& enabled ); + void addAudioFormat(int count, std::string &apidtitle, bool& enabled ); void handleMovieBrowser(neutrino_msg_t msg, int position = 0); bool SelectFile(); void updateLcd(); + void selectSubtitle(); + void showSubtitle(neutrino_msg_data_t data); + void clearSubtitle(); + void selectChapter(); + CMoviePlayerGui(const CMoviePlayerGui&) {}; CMoviePlayerGui(); diff --git a/src/gui/network_setup.cpp b/src/gui/network_setup.cpp index db7a36d48..13d81ea53 100644 --- a/src/gui/network_setup.cpp +++ b/src/gui/network_setup.cpp @@ -337,12 +337,14 @@ int CNetworkSetup::showNetworkSetup() showNetworkNTPSetup(&ntp); +#ifdef ENABLE_GUI_MOUNT //nfs mount submenu CMenuWidget networkmounts(LOCALE_MAINSETTINGS_NETWORK, NEUTRINO_ICON_SETTINGS, width, MN_WIDGET_ID_NETWORKSETUP_MOUNTS); mf = new CMenuForwarder(LOCALE_NETWORKMENU_MOUNT, true, NULL, &networkmounts, NULL, CRCInput::RC_blue, NEUTRINO_ICON_BUTTON_BLUE); mf->setHint("", LOCALE_MENU_HINT_NET_MOUNT); networkSettings->addItem(mf); showNetworkNFSMounts(&networkmounts); +#endif //proxyserver submenu CProxySetup proxy(LOCALE_MAINSETTINGS_NETWORK); @@ -393,6 +395,7 @@ void CNetworkSetup::showNetworkNTPSetup(CMenuWidget *menu_ntp) menu_ntp->addItem( ntp3); } +#ifdef ENABLE_GUI_MOUNT void CNetworkSetup::showNetworkNFSMounts(CMenuWidget *menu_nfs) { menu_nfs->addIntroItems(LOCALE_NETWORKMENU_MOUNT); @@ -403,6 +406,7 @@ void CNetworkSetup::showNetworkNFSMounts(CMenuWidget *menu_nfs) mf->setHint("", LOCALE_MENU_HINT_NET_NFS_UMOUNT); menu_nfs->addItem(mf); } +#endif typedef struct n_isettings_t { diff --git a/src/gui/network_setup.h b/src/gui/network_setup.h index bec83879b..2464f573c 100644 --- a/src/gui/network_setup.h +++ b/src/gui/network_setup.h @@ -100,19 +100,19 @@ class CNetworkSetup : public CMenuTarget, CChangeObserver enum NETWORK_DHCP_MODE { NETWORK_DHCP_OFF = 0, //static - NETWORK_DHCP_ON = 1, + NETWORK_DHCP_ON = 1 }; enum NETWORK_START_MODE { NETWORK_AUTOSTART_OFF = 0, - NETWORK_AUTOSTART_ON = 1, + NETWORK_AUTOSTART_ON = 1 }; enum NETWORK_NTP_MODE { NETWORK_NTP_OFF = 0, - NETWORK_NTP_ON = 1, + NETWORK_NTP_ON = 1 }; enum NETWORK_SETUP_MODE diff --git a/src/gui/osd_setup.cpp b/src/gui/osd_setup.cpp index cacbdaad8..e9f27f895 100644 --- a/src/gui/osd_setup.cpp +++ b/src/gui/osd_setup.cpp @@ -333,7 +333,7 @@ const CMenuOptionChooser::keyval INFOBAR_SUBCHAN_DISP_POS_OPTIONS[INFOBAR_SUBCH { 4 , LOCALE_INFOVIEWER_SUBCHAN_INFOBAR } }; -#define VOLUMEBAR_DISP_POS_OPTIONS_COUNT 6 +#define VOLUMEBAR_DISP_POS_OPTIONS_COUNT 7 const CMenuOptionChooser::keyval VOLUMEBAR_DISP_POS_OPTIONS[VOLUMEBAR_DISP_POS_OPTIONS_COUNT]= { { 0 , LOCALE_SETTINGS_POS_TOP_RIGHT }, @@ -341,7 +341,8 @@ const CMenuOptionChooser::keyval VOLUMEBAR_DISP_POS_OPTIONS[VOLUMEBAR_DISP_POS_ { 2 , LOCALE_SETTINGS_POS_BOTTOM_LEFT }, { 3 , LOCALE_SETTINGS_POS_BOTTOM_RIGHT }, { 4 , LOCALE_SETTINGS_POS_TOP_CENTER }, - { 5 , LOCALE_SETTINGS_POS_BOTTOM_CENTER } + { 5 , LOCALE_SETTINGS_POS_BOTTOM_CENTER }, + { 6 , LOCALE_SETTINGS_POS_HIGHER_CENTER } }; #define MENU_DISP_POS_OPTIONS_COUNT 5 diff --git a/src/gui/pictureviewer.cpp b/src/gui/pictureviewer.cpp index 055de3006..15f200dd7 100644 --- a/src/gui/pictureviewer.cpp +++ b/src/gui/pictureviewer.cpp @@ -45,8 +45,12 @@ #include #include -#include +#ifdef ENABLE_GUI_MOUNT +#include +#endif + +#include #include #include #include @@ -123,6 +127,26 @@ CPictureViewerGui::~CPictureViewerGui() } //------------------------------------------------------------------------ + +#define PictureViewerButtons1Count 4 +const struct button_label PictureViewerButtons1[PictureViewerButtons1Count] = +{ + { NEUTRINO_ICON_BUTTON_RED , LOCALE_AUDIOPLAYER_DELETE }, + { NEUTRINO_ICON_BUTTON_GREEN , LOCALE_AUDIOPLAYER_ADD }, + { NEUTRINO_ICON_BUTTON_YELLOW , LOCALE_AUDIOPLAYER_DELETEALL }, + { NEUTRINO_ICON_BUTTON_BLUE , LOCALE_PICTUREVIEWER_SLIDESHOW } +}; + +#define PictureViewerButtons2Count 3 +struct button_label PictureViewerButtons2[PictureViewerButtons2Count] = +{ + { NEUTRINO_ICON_BUTTON_5 , LOCALE_PICTUREVIEWER_SORTORDER_DATE }, + { NEUTRINO_ICON_BUTTON_OKAY , LOCALE_PICTUREVIEWER_SHOW }, + { NEUTRINO_ICON_BUTTON_MUTE_SMALL, LOCALE_FILEBROWSER_DELETE } +}; + +//------------------------------------------------------------------------ + int CPictureViewerGui::exec(CMenuTarget* parent, const std::string & actionKey) { audioplayer = false; @@ -134,27 +158,17 @@ int CPictureViewerGui::exec(CMenuTarget* parent, const std::string & actionKey) width = frameBuffer->getScreenWidthRel(); height = frameBuffer->getScreenHeightRel(); - sheight = g_Font[SNeutrinoSettings::FONT_TYPE_INFOBAR_SMALL]->getHeight(); + sheight = g_Font[SNeutrinoSettings::FONT_TYPE_INFOBAR_SMALL]->getHeight(); + theight = g_Font[SNeutrinoSettings::FONT_TYPE_MENU_TITLE]->getHeight(); + fheight = g_Font[SNeutrinoSettings::FONT_TYPE_MENU]->getHeight(); - int icol_w, icol_h; + //get footerHeight from paintButtons + buttons1Height = ::paintButtons(0, 0, 0, PictureViewerButtons1Count, PictureViewerButtons1, 0, 0, "", false, COL_INFOBAR_SHADOW, NULL, 0, false); + buttons2Height = ::paintButtons(0, 0, 0, PictureViewerButtons2Count, PictureViewerButtons2, 0, 0, "", false, COL_INFOBAR_SHADOW, NULL, 0, false); + footerHeight = buttons1Height + buttons2Height; - theight = g_Font[SNeutrinoSettings::FONT_TYPE_MENU_TITLE]->getHeight(); - - frameBuffer->getIconSize(NEUTRINO_ICON_MP3, &icol_w, &icol_h); - theight = std::max(theight, icol_h); - - frameBuffer->getIconSize(NEUTRINO_ICON_BUTTON_HELP, &icol_w, &icol_h); - theight = std::max(theight, icol_h); - - frameBuffer->getIconSize(NEUTRINO_ICON_BUTTON_MENU, &icol_w, &icol_h); - theight = std::max(theight, icol_h); - - frameBuffer->getIconSize(NEUTRINO_ICON_BUTTON_RED, &icol_w, &icol_h); - buttonHeight = 8 + std::max(icol_h+2, sheight); //TODO get value from buttonbar - - fheight = g_Font[SNeutrinoSettings::FONT_TYPE_MENU]->getHeight(); - listmaxshow = (height-theight-2*buttonHeight)/(fheight); - height = theight+2*buttonHeight+listmaxshow*fheight; // recalc height + listmaxshow = (height-theight-footerHeight)/(fheight); + height = theight+listmaxshow*fheight+footerHeight; // recalc height x=getScreenStartX( width ); y=getScreenStartY( height ); @@ -552,6 +566,7 @@ int CPictureViewerGui::show() if (!playlist.empty()) view(selected, true); } +#ifdef ENABLE_GUI_MOUNT else if (msg==CRCInput::RC_setup) { if (m_state==MENU) @@ -562,6 +577,7 @@ int CPictureViewerGui::show() CVFD::getInstance()->setMode(CVFD::MODE_MENU_UTF8, g_Locale->getText(LOCALE_PICTUREVIEWER_HEAD)); } } +#endif else if (((msg==CRCInput::RC_plus) || (msg==CRCInput::RC_minus)) && decodeTflag) { // FIXME: do not accept volume-keys while decoding @@ -689,63 +705,41 @@ void CPictureViewerGui::paintItem(int pos) void CPictureViewerGui::paintHead() { -// printf("paintHead{\n"); - std::string strCaption = g_Locale->getText(LOCALE_PICTUREVIEWER_HEAD); + CComponentsHeader header(x, y, width, theight, LOCALE_PICTUREVIEWER_HEAD, NEUTRINO_ICON_MP3, CComponentsHeader::CC_BTN_HELP); - int iw1, iw2, iw3, ih; - frameBuffer->getIconSize(NEUTRINO_ICON_MP3, &iw1, &ih); - frameBuffer->getIconSize(NEUTRINO_ICON_BUTTON_HELP, &iw2, &ih); - frameBuffer->getIconSize(NEUTRINO_ICON_BUTTON_MENU, &iw3, &ih); +#ifdef ENABLE_GUI_MOUNT + header.addButtonIcon(NEUTRINO_ICON_BUTTON_MENU); +#endif - frameBuffer->paintBoxRel(x, y, width, theight, COL_MENUHEAD_PLUS_0, RADIUS_LARGE, CORNER_TOP); - - frameBuffer->paintIcon(NEUTRINO_ICON_MP3, x+5, y, theight); - g_Font[SNeutrinoSettings::FONT_TYPE_MENU_TITLE]->RenderString(x+iw1+10, y+theight+0, width- iw1 - iw2 - iw3 - 5*5, strCaption, COL_MENUHEAD, 0, true); // UTF-8 - - frameBuffer->paintIcon(NEUTRINO_ICON_BUTTON_HELP, x+ width- iw2 - 5, y, theight); - frameBuffer->paintIcon(NEUTRINO_ICON_BUTTON_MENU, x+ width- iw2 - iw3 - 10, y, theight ); -// printf("paintHead}\n"); + header.paint(CC_SAVE_SCREEN_NO); } //------------------------------------------------------------------------ -const struct button_label PictureViewerButtons[5] = -{ - { NEUTRINO_ICON_BUTTON_RED , LOCALE_AUDIOPLAYER_DELETE }, - { NEUTRINO_ICON_BUTTON_GREEN , LOCALE_AUDIOPLAYER_ADD }, - { NEUTRINO_ICON_BUTTON_YELLOW, LOCALE_AUDIOPLAYER_DELETEALL }, - { NEUTRINO_ICON_BUTTON_BLUE , LOCALE_PICTUREVIEWER_SLIDESHOW }, - { NEUTRINO_ICON_BUTTON_MUTE_SMALL , LOCALE_FILEBROWSER_DELETE } -}; -const struct button_label PictureViewerButtons2[][2] = -{ - { - { NEUTRINO_ICON_BUTTON_5 , LOCALE_PICTUREVIEWER_SORTORDER_DATE }, - { NEUTRINO_ICON_BUTTON_OKAY , LOCALE_PICTUREVIEWER_SHOW } - }, - { - { NEUTRINO_ICON_BUTTON_5 , LOCALE_PICTUREVIEWER_SORTORDER_FILENAME }, - { NEUTRINO_ICON_BUTTON_OKAY , LOCALE_PICTUREVIEWER_SHOW } - } -}; + void CPictureViewerGui::paintFoot() { -// printf("paintFoot{\n"); + if (m_sort == FILENAME) + PictureViewerButtons2[0].locale = LOCALE_PICTUREVIEWER_SORTORDER_FILENAME; + else + PictureViewerButtons2[0].locale = LOCALE_PICTUREVIEWER_SORTORDER_DATE; - frameBuffer->paintBoxRel(x, y+(height-2*buttonHeight), width, 2*buttonHeight, COL_INFOBAR_SHADOW_PLUS_1, RADIUS_LARGE, CORNER_BOTTOM); + frameBuffer->paintBoxRel(x, y + (height - footerHeight), width, footerHeight, COL_INFOBAR_SHADOW_PLUS_1, RADIUS_LARGE, CORNER_BOTTOM); if (!playlist.empty()) { - ::paintButtons(x, y + (height - 2 * buttonHeight), 0, 5, PictureViewerButtons, width); - ::paintButtons(x, y + (height - buttonHeight), 0, 2, (m_sort==FILENAME)?PictureViewerButtons2[0]:PictureViewerButtons2[1], width); + ::paintButtons(x, y + (height - footerHeight), 0, PictureViewerButtons1Count, PictureViewerButtons1, width); + ::paintButtons(x, y + (height - buttons2Height), 0, PictureViewerButtons2Count, PictureViewerButtons2, width); } else - ::paintButtons(x , y + (height - 2 * buttonHeight), 0, 1, &(PictureViewerButtons[1]), width); -// printf("paintFoot}\n"); + ::paintButtons(x, y + (height - footerHeight), 0, 1, &(PictureViewerButtons1[1]), width); } + //------------------------------------------------------------------------ + void CPictureViewerGui::paintInfo() { } + //------------------------------------------------------------------------ void CPictureViewerGui::paint() diff --git a/src/gui/pictureviewer.h b/src/gui/pictureviewer.h index 4e98071ae..500635b0c 100644 --- a/src/gui/pictureviewer.h +++ b/src/gui/pictureviewer.h @@ -77,7 +77,9 @@ class CPictureViewerGui : public CMenuTarget int fheight; // Fonthoehe Playlist-Inhalt int theight; // Fonthoehe Playlist-Titel int sheight; // Fonthoehe MP Info - int buttonHeight; + int footerHeight; + int buttons1Height; + int buttons2Height; bool visible; State m_state; SortOrder m_sort; diff --git a/src/gui/scan.cpp b/src/gui/scan.cpp index 642cea1c4..1bab633bc 100644 --- a/src/gui/scan.cpp +++ b/src/gui/scan.cpp @@ -41,6 +41,7 @@ #include #include +#include #include #include @@ -370,10 +371,9 @@ int CScanTs::exec(CMenuTarget* /*parent*/, const std::string & actionKey) g_RCInput->open_click(); } if(!test) { - const char * text = g_Locale->getText(success ? LOCALE_SCANTS_FINISHED : LOCALE_SCANTS_FAILED); - frameBuffer->paintBoxRel(x, y, width, hheight, COL_MENUHEAD_PLUS_0, RADIUS_LARGE, CORNER_TOP); - g_Font[SNeutrinoSettings::FONT_TYPE_MENU_TITLE]->RenderString(xpos1, y + hheight, width, text, COL_MENUHEAD, 0, true); // UTF-8 - frameBuffer->blit(); + CComponentsHeader header(x, y, width, hheight, success ? LOCALE_SCANTS_FINISHED : LOCALE_SCANTS_FAILED, NULL /*no header icon*/); + header.paint(CC_SAVE_SCREEN_NO); + // frameBuffer->blit(); // ?? uint64_t timeoutEnd = CRCInput::calcTimeoutEnd(0xFFFF); do { g_RCInput->getMsgAbsoluteTimeout(&msg, &data, &timeoutEnd); @@ -487,7 +487,7 @@ neutrino_msg_t CScanTs::handleMsg(neutrino_msg_t msg, neutrino_msg_data_t data) case CRCInput::RC_minus: case CRCInput::RC_left: case CRCInput::RC_right: - CVolume::getInstance()->setVolume(msg, true /*nowait = true*/); + CVolume::getInstance()->setVolume(msg); break; default: break; @@ -539,19 +539,14 @@ void CScanTs::paintLine(int px, int py, int w, const char * const txt) void CScanTs::paint(bool fortest) { - int ypos; + CComponentsHeader header(x, y, width, hheight, fortest ? LOCALE_SCANTS_TEST : LOCALE_SCANTS_HEAD, NULL /*no header icon*/); + header.paint(CC_SAVE_SCREEN_NO); - ypos = y; - - //frameBuffer->paintBoxRel(x, ypos, width, hheight, COL_MENUHEAD_PLUS_0); - frameBuffer->paintBoxRel(x, ypos, width, hheight, COL_MENUHEAD_PLUS_0, RADIUS_LARGE, CORNER_TOP); - g_Font[SNeutrinoSettings::FONT_TYPE_MENU_TITLE]->RenderString(xpos1, ypos + hheight, width, fortest ? g_Locale->getText(LOCALE_SCANTS_TEST) : g_Locale->getText(LOCALE_SCANTS_HEAD), COL_MENUHEAD, 0, true); // UTF-8 - //frameBuffer->paintBoxRel(x, ypos + hheight, width, height - hheight, COL_MENUCONTENT_PLUS_0); - frameBuffer->paintBoxRel(x, ypos + hheight, width, height - hheight, COL_MENUCONTENT_PLUS_0, RADIUS_LARGE, CORNER_BOTTOM); + frameBuffer->paintBoxRel(x, y + hheight, width, height - hheight, COL_MENUCONTENT_PLUS_0, RADIUS_LARGE, CORNER_BOTTOM); frameBuffer->loadPal(tuned ? "radar.pal" : "radar_red.pal", 18, 38); - ypos = y + hheight + (mheight >> 1); + int ypos = y + hheight + (mheight >> 1); ypos_cur_satellite = ypos; diff --git a/src/gui/scan_setup.cpp b/src/gui/scan_setup.cpp index a3e687797..b2c2da607 100644 --- a/src/gui/scan_setup.cpp +++ b/src/gui/scan_setup.cpp @@ -232,6 +232,7 @@ CScanSetup::CScanSetup(bool wizard_mode) nid = NULL; lcnhd = NULL; linkfe = NULL; + in_menu = false; } CScanSetup* CScanSetup::getInstance() @@ -347,7 +348,9 @@ int CScanSetup::exec(CMenuTarget* parent, const std::string &actionKey) printf("[neutrino] CScanSetup %s: init scan setup (Mode: %d)...\n",__FUNCTION__ , is_wizard); CZapit::getInstance()->GetConfig(zapitCfg); + in_menu = true; res = showScanMenu(); + in_menu = false; return res; } @@ -503,20 +506,20 @@ printf("C: %d S: %d T: %d\n", CFEManager::getInstance()->haveCable(),CFEManager: /* FIXME leak, satSelect added to both auto and manual scan, so one of them cannot be deleted */ CMenuWidget * autoScan = new CMenuWidget(LOCALE_SERVICEMENU_SCANTS, NEUTRINO_ICON_SETTINGS, w/*width*/, MN_WIDGET_ID_SCAN_AUTO_SCAN); addScanMenuAutoScan(autoScan); - mf = new CMenuForwarderNonLocalized(autoscan, true, NULL, autoScan, "", have_sat ? CRCInput::RC_nokey : CRCInput::RC_green, have_sat ? NULL : NEUTRINO_ICON_BUTTON_GREEN); + mf = new CMenuForwarderNonLocalized(autoscan, true, NULL, autoScan, "", have_sat ? CRCInput::convertDigitToKey(shortcut++) : CRCInput::RC_green, have_sat ? NULL : NEUTRINO_ICON_BUTTON_GREEN); mf->setHint("", LOCALE_MENU_HINT_SCAN_AUTO); settings->addItem(mf); //manual scan CMenuWidget * manualScan = new CMenuWidget(LOCALE_SATSETUP_MANUAL_SCAN, NEUTRINO_ICON_SETTINGS, w/*width*/, MN_WIDGET_ID_SCAN_MANUAL_SCAN); addScanMenuManualScan(manualScan); - mf = new CMenuForwarder(LOCALE_SATSETUP_MANUAL_SCAN, true, NULL, manualScan, "", have_sat ? CRCInput::RC_nokey : CRCInput::RC_yellow, have_sat ? NULL : NEUTRINO_ICON_BUTTON_YELLOW); + mf = new CMenuForwarder(LOCALE_SATSETUP_MANUAL_SCAN, true, NULL, manualScan, "", have_sat ? CRCInput::convertDigitToKey(shortcut++) : CRCInput::RC_yellow, have_sat ? NULL : NEUTRINO_ICON_BUTTON_YELLOW); mf->setHint("", LOCALE_MENU_HINT_SCAN_MANUAL); settings->addItem(mf); //simple cable scan CMenuWidget * cableScan = new CMenuWidget(LOCALE_SATSETUP_CABLE, NEUTRINO_ICON_SETTINGS, w/*width*/, MN_WIDGET_ID_SCAN_CABLE_SCAN); addScanMenuCable(cableScan); - CMenuForwarder * fcableScan = new CMenuDForwarder(LOCALE_SATSETUP_CABLE, true, NULL, cableScan, "", have_sat ? CRCInput::RC_nokey : CRCInput::RC_blue, have_sat ? NULL : NEUTRINO_ICON_BUTTON_BLUE); + CMenuForwarder * fcableScan = new CMenuDForwarder(LOCALE_SATSETUP_CABLE, true, NULL, cableScan, "", have_sat ? CRCInput::convertDigitToKey(shortcut++) : CRCInput::RC_blue, have_sat ? NULL : NEUTRINO_ICON_BUTTON_BLUE); fcableScan->setHint("", LOCALE_MENU_HINT_SCAN_CABLE_SIMPLE); settings->addItem(fcableScan); } @@ -680,31 +683,33 @@ int CScanSetup::showScanMenuFrontendSetup() nc->setHint("", LOCALE_MENU_HINT_SCAN_FETIMEOUT); setupMenu->addItem(nc); - sprintf(zapit_lat, "%02.6f", zapitCfg.gotoXXLatitude); - sprintf(zapit_long, "%02.6f", zapitCfg.gotoXXLongitude); + if (CFEManager::getInstance()->haveSat()) { + sprintf(zapit_lat, "%02.6f", zapitCfg.gotoXXLatitude); + sprintf(zapit_long, "%02.6f", zapitCfg.gotoXXLongitude); - setupMenu->addItem(new CMenuSeparator(CMenuSeparator::LINE | CMenuSeparator::STRING, LOCALE_SATSETUP_EXTENDED_MOTOR)); - CMenuOptionChooser * mc = new CMenuOptionChooser(LOCALE_EXTRA_LADIRECTION, (int *)&zapitCfg.gotoXXLaDirection, OPTIONS_SOUTH0_NORTH1_OPTIONS, OPTIONS_SOUTH0_NORTH1_OPTION_COUNT, true, NULL, CRCInput::convertDigitToKey(shortcut++)); - mc->setHint("", LOCALE_MENU_HINT_SCAN_LADIRECTION); - setupMenu->addItem(mc); + setupMenu->addItem(new CMenuSeparator(CMenuSeparator::LINE | CMenuSeparator::STRING, LOCALE_SATSETUP_EXTENDED_MOTOR)); + CMenuOptionChooser * mc = new CMenuOptionChooser(LOCALE_EXTRA_LADIRECTION, (int *)&zapitCfg.gotoXXLaDirection, OPTIONS_SOUTH0_NORTH1_OPTIONS, OPTIONS_SOUTH0_NORTH1_OPTION_COUNT, true, NULL, CRCInput::convertDigitToKey(shortcut++)); + mc->setHint("", LOCALE_MENU_HINT_SCAN_LADIRECTION); + setupMenu->addItem(mc); - CStringInput * toff1 = new CStringInput(LOCALE_EXTRA_LATITUDE, (char *) zapit_lat, 10, NONEXISTANT_LOCALE, NONEXISTANT_LOCALE, "0123456789."); - mf = new CMenuDForwarder(LOCALE_EXTRA_LATITUDE, true, zapit_lat, toff1, "", CRCInput::convertDigitToKey(shortcut++)); - mf->setHint("", LOCALE_MENU_HINT_SCAN_LATITUDE); - setupMenu->addItem(mf); + CStringInput * toff1 = new CStringInput(LOCALE_EXTRA_LATITUDE, (char *) zapit_lat, 10, NONEXISTANT_LOCALE, NONEXISTANT_LOCALE, "0123456789."); + mf = new CMenuDForwarder(LOCALE_EXTRA_LATITUDE, true, zapit_lat, toff1, "", CRCInput::convertDigitToKey(shortcut++)); + mf->setHint("", LOCALE_MENU_HINT_SCAN_LATITUDE); + setupMenu->addItem(mf); - mc = new CMenuOptionChooser(LOCALE_EXTRA_LODIRECTION, (int *)&zapitCfg.gotoXXLoDirection, OPTIONS_EAST0_WEST1_OPTIONS, OPTIONS_EAST0_WEST1_OPTION_COUNT, true, NULL, CRCInput::convertDigitToKey(shortcut++)); - mc->setHint("", LOCALE_MENU_HINT_SCAN_LODIRECTION); - setupMenu->addItem(mc); + mc = new CMenuOptionChooser(LOCALE_EXTRA_LODIRECTION, (int *)&zapitCfg.gotoXXLoDirection, OPTIONS_EAST0_WEST1_OPTIONS, OPTIONS_EAST0_WEST1_OPTION_COUNT, true, NULL, CRCInput::convertDigitToKey(shortcut++)); + mc->setHint("", LOCALE_MENU_HINT_SCAN_LODIRECTION); + setupMenu->addItem(mc); - CStringInput * toff2 = new CStringInput(LOCALE_EXTRA_LONGITUDE, (char *) zapit_long, 10, NONEXISTANT_LOCALE, NONEXISTANT_LOCALE, "0123456789."); - mf = new CMenuDForwarder(LOCALE_EXTRA_LONGITUDE, true, zapit_long, toff2, "", CRCInput::convertDigitToKey(shortcut++)); - mf->setHint("", LOCALE_MENU_HINT_SCAN_LONGITUDE); - setupMenu->addItem(mf); + CStringInput * toff2 = new CStringInput(LOCALE_EXTRA_LONGITUDE, (char *) zapit_long, 10, NONEXISTANT_LOCALE, NONEXISTANT_LOCALE, "0123456789."); + mf = new CMenuDForwarder(LOCALE_EXTRA_LONGITUDE, true, zapit_long, toff2, "", CRCInput::convertDigitToKey(shortcut++)); + mf->setHint("", LOCALE_MENU_HINT_SCAN_LONGITUDE); + setupMenu->addItem(mf); - nc = new CMenuOptionNumberChooser(LOCALE_SATSETUP_USALS_REPEAT, (int *)&zapitCfg.repeatUsals, true, 0, 10, NULL, 0, 0, LOCALE_OPTIONS_OFF); - nc->setHint("", LOCALE_MENU_HINT_SCAN_USALS_REPEAT); - setupMenu->addItem(nc); + nc = new CMenuOptionNumberChooser(LOCALE_SATSETUP_USALS_REPEAT, (int *)&zapitCfg.repeatUsals, true, 0, 10, NULL, 0, 0, LOCALE_OPTIONS_OFF); + nc->setHint("", LOCALE_MENU_HINT_SCAN_USALS_REPEAT); + setupMenu->addItem(nc); + } int res = setupMenu->exec(NULL, ""); delete setupMenu; @@ -820,7 +825,7 @@ int CScanSetup::showFrontendSetup(int number) setupMenu->addItem(dorder); CMenuWidget * satToSelect = new CMenuWidget(LOCALE_SATSETUP_SELECT_SAT, NEUTRINO_ICON_SETTINGS, width); - satToSelect->addIntroItems(); + //satToSelect->addIntroItems(); satellite_map_t & satmap = fe->getSatellites(); for (sat_iterator_t sit = satmap.begin(); sit != satmap.end(); ++sit) @@ -1573,6 +1578,9 @@ printf("[neutrino] CScanSetup::%s: logical numbers %d\n", __FUNCTION__, scansett void CScanSetup::updateManualSettings() { + if (in_menu) + return; + CZapitChannel * channel = CZapit::getInstance()->GetCurrentChannel(); if(channel) { transponder_list_t::iterator tI; diff --git a/src/gui/scan_setup.h b/src/gui/scan_setup.h index 096756ae7..bfc6fc382 100644 --- a/src/gui/scan_setup.h +++ b/src/gui/scan_setup.h @@ -84,6 +84,8 @@ class CScanSetup : public CMenuTarget, public CChangeObserver bool allow_start; /* flag to re-init frontends */ bool fe_restart; + /* flag to skip manual params update while in menu */ + bool in_menu; bool is_wizard; diff --git a/src/gui/streaminfo2.h b/src/gui/streaminfo2.h index 9b3b187fc..d8fbef52a 100644 --- a/src/gui/streaminfo2.h +++ b/src/gui/streaminfo2.h @@ -28,6 +28,7 @@ #include #include #include +#include #include diff --git a/src/gui/test_menu.cpp b/src/gui/test_menu.cpp index cbfbda39e..cf7459aec 100644 --- a/src/gui/test_menu.cpp +++ b/src/gui/test_menu.cpp @@ -71,9 +71,11 @@ CTestMenu::CTestMenu() form = NULL; txt = NULL; header = NULL; + footer = NULL; iconform = NULL; window = NULL; button = NULL; + clock = clock_r = NULL; } CTestMenu::~CTestMenu() @@ -84,11 +86,16 @@ CTestMenu::~CTestMenu() delete form; delete txt; delete header; + delete footer; delete iconform; delete window; delete button; + delete clock; + delete clock_r; } +static int test_pos[4] = { 130, 192, 282, 360 }; + int CTestMenu::exec(CMenuTarget* parent, const std::string &actionKey) { dprintf(DEBUG_DEBUG, "init test menu\n"); @@ -223,12 +230,9 @@ int CTestMenu::exec(CMenuTarget* parent, const std::string &actionKey) char buffer[255]; FILE *f = fopen("/proc/mounts", "r"); bool mounted = false; - if (f != NULL) - { - while (fgets (buffer, 255, f) != NULL) - { - if (strstr(buffer, "/dev/sda1")) - { + if (f != NULL) { + while (fgets (buffer, 255, f) != NULL) { + if (strstr(buffer, "/dev/sda1")) { mounted = true; break; } @@ -242,6 +246,27 @@ int CTestMenu::exec(CMenuTarget* parent, const std::string &actionKey) return res; } + else if (actionKey == "mmc") + { + char buffer[255]; + FILE *f = fopen("/proc/mounts", "r"); + bool mounted = false; + if (f != NULL) { + while (fgets (buffer, 255, f) != NULL) { + if (strstr(buffer, "/dev/mmcblk0p1")) { + mounted = true; + break; + } + } + fclose(f); + } + sprintf(buffer, "MMC: /dev/mmcblk0p1 is %s", mounted ? "mounted" : "NOT mounted"); + printf("%s\n", buffer); + + ShowMsgUTF(LOCALE_MESSAGEBOX_INFO, buffer, CMessageBox::mbrBack, CMessageBox::mbBack, NEUTRINO_ICON_INFO); + + return res; + } else if (actionKey == "buttons") { neutrino_msg_t msg; @@ -275,64 +300,66 @@ int CTestMenu::exec(CMenuTarget* parent, const std::string &actionKey) return res; } - else if (actionKey == "22kon1" || actionKey == "22koff1") + else if (actionKey.find("22kon") != std::string::npos) { - CScanTs * scanTs = new CScanTs(); - int freq = (actionKey == "22kon1") ? 12000*1000: 11000*1000; - sprintf(scansettings.sat_TP_freq, "%d", freq); + int fnum = atoi(actionKey.substr(5, 1).c_str()); + printf("22kon: fe %d sat pos %d\n", fnum, test_pos[fnum]); + sprintf(scansettings.sat_TP_freq, "%d", 12000*1000); strncpy(scansettings.satName, - CServiceManager::getInstance()->GetSatelliteName(130).c_str(), 50); - - scanTs->exec(NULL, "test"); - delete scanTs; + CServiceManager::getInstance()->GetSatelliteName(test_pos[fnum]).c_str(), 50); + CScanTs scanTs(FE_QPSK); + scanTs.exec(NULL, "test"); return res; } - else if (actionKey == "22kon2" || actionKey == "22koff2") + else if (actionKey.find("22koff") != std::string::npos) { - int freq = (actionKey == "22kon2") ? 12000*1000: 11000*1000; - sprintf(scansettings.sat_TP_freq, "%d", freq); + int fnum = atoi(actionKey.substr(6, 1).c_str()); + printf("22koff: fe %d sat pos %d\n", fnum, test_pos[fnum]); + sprintf(scansettings.sat_TP_freq, "%d", 11000*1000); strncpy(scansettings.satName, - CServiceManager::getInstance()->GetSatelliteName(192).c_str(), 50); - - CScanTs * scanTs = new CScanTs(); - scanTs->exec(NULL, "test"); - delete scanTs; + CServiceManager::getInstance()->GetSatelliteName(test_pos[fnum]).c_str(), 50); + CScanTs scanTs(FE_QPSK); + scanTs.exec(NULL, "test"); return res; } - else if (actionKey == "scan1" || actionKey == "scan2") + else if (actionKey.find("scan") != std::string::npos) { - int fnum = actionKey == "scan1" ? 0 : 1; - strncpy(scansettings.satName, actionKey == "scan1" ? - CServiceManager::getInstance()->GetSatelliteName(130).c_str() : - CServiceManager::getInstance()->GetSatelliteName(192).c_str(), 50); + int fnum = atoi(actionKey.substr(4, 1).c_str()); + printf("scan: fe %d sat pos %d\n", fnum, test_pos[fnum]); CFrontend *frontend = CFEManager::getInstance()->getFE(fnum); - CServiceScan::getInstance()->SetFrontend(fnum); - - int freq = 12538000; - sprintf(scansettings.sat_TP_freq, "%d", freq); - //CFrontend * frontend = CFEManager::getInstance()->getFE(0); - switch (frontend->getInfo()->type) - { + switch (frontend->getInfo()->type) { case FE_QPSK: - sprintf(scansettings.sat_TP_rate, "%d", 41250*1000); - scansettings.sat_TP_fec = 1; - scansettings.sat_TP_pol = 1; + strncpy(scansettings.satName, + CServiceManager::getInstance()->GetSatelliteName(test_pos[fnum]).c_str(), 50); + sprintf(scansettings.sat_TP_freq, "%d", (fnum & 1) ? 12439000: 12538000); + sprintf(scansettings.sat_TP_rate, "%d", (fnum & 1) ? 2500*1000 : 41250*1000); + scansettings.sat_TP_fec = (fnum & 1) ? FEC_3_4 : FEC_1_2; + scansettings.sat_TP_pol = (fnum & 1) ? 0 : 1; break; case FE_QAM: -#if 0 - sprintf(scansettings.sat_TP_rate, "%d", tmpI->second.feparams.u.qam.symbol_rate); - scansettings.sat_TP_fec = tmpI->second.feparams.u.qam.fec_inner; - scansettings.TP_mod = tmpI->second.feparams.u.qam.modulation; -#endif + { + unsigned count = CFEManager::getInstance()->getFrontendCount(); + for (unsigned i = 0; i < count; i++) { + CFrontend * fe = CFEManager::getInstance()->getFE(i); + if (fe->isCable()) + fe->setMode(CFrontend::FE_MODE_UNUSED); + } + frontend->setMode(CFrontend::FE_MODE_INDEPENDENT); + strncpy(scansettings.cableName, "CST Berlin", 50); + sprintf(scansettings.cable_TP_freq, "%d", 474*1000); + sprintf(scansettings.cable_TP_rate, "%d", 6875*1000); + scansettings.cable_TP_fec = 1; + scansettings.cable_TP_mod = 5; + } break; case FE_OFDM: case FE_ATSC: - break; + return res; } - CScanTs * scanTs = new CScanTs(); - scanTs->exec(NULL, "manual"); - delete scanTs; + + CScanTs scanTs(frontend->getInfo()->type); + scanTs.exec(NULL, "manual"); return res; } else if (actionKey == "button"){ @@ -439,7 +466,7 @@ int CTestMenu::exec(CMenuTarget* parent, const std::string &actionKey) if (header == NULL){ header = new CComponentsHeader (100, 50, 500, hh, "Test-Header"/*, NEUTRINO_ICON_INFO, CComponentsHeader::CC_BTN_HELP | CComponentsHeader::CC_BTN_EXIT | CComponentsHeader::CC_BTN_MENU*/); // header->addHeaderButton(NEUTRINO_ICON_BUTTON_RED); - header->setHeaderDefaultButtons(CComponentsHeader::CC_BTN_HELP | CComponentsHeader::CC_BTN_EXIT | CComponentsHeader::CC_BTN_MENU); + header->setDefaultButtons(CComponentsHeader::CC_BTN_HELP | CComponentsHeader::CC_BTN_EXIT | CComponentsHeader::CC_BTN_MENU); } // else //For existing instances it's recommended // //to remove old button icons before add new buttons, otherwise icons will be appended. @@ -451,11 +478,11 @@ int CTestMenu::exec(CMenuTarget* parent, const std::string &actionKey) // header->setCornerType(CORNER_TOP); // change text of header - header->setHeaderText("Test"); + header->setCaption("Test"); // add any other button icon -// header->addHeaderButton(NEUTRINO_ICON_BUTTON_BLUE); -// header->addHeaderButton(NEUTRINO_ICON_BUTTON_GREEN); +// header->addButton(NEUTRINO_ICON_BUTTON_BLUE); +// header->addButton(NEUTRINO_ICON_BUTTON_GREEN); // example to replace the text item with an image item // get text x position @@ -476,6 +503,22 @@ int CTestMenu::exec(CMenuTarget* parent, const std::string &actionKey) header->hide(); return res; } + else if (actionKey == "footer"){ + int hh = g_Font[SNeutrinoSettings::FONT_TYPE_MENU_TITLE]->getHeight(); + if (footer == NULL){ + footer = new CComponentsFooter (100, 50, 500, hh, CComponentsHeader::CC_BTN_HELP | CComponentsHeader::CC_BTN_EXIT | CComponentsHeader::CC_BTN_MENU, true); + int start = 5, btnw =90, btnh = 37; + footer->addCCItem(new CComponentsButtonRed(start, 0, btnw, btnh, "Button1")); + footer->addCCItem(new CComponentsButtonGreen(start+=btnw, 0, btnw, btnh, "Button2")); + footer->addCCItem(new CComponentsButtonYellow(start+=btnw, 0, btnw, btnh, "Button3")); + footer->addCCItem(new CComponentsButtonBlue(start+=btnw, 0, btnw, btnh, "Button4")); + } + if (!footer->isPainted()) + footer->paint(); + else + footer->hide(); + return res; + } else if (actionKey == "iconform"){ if (iconform == NULL) iconform = new CComponentsIconForm(); @@ -516,14 +559,30 @@ int CTestMenu::exec(CMenuTarget* parent, const std::string &actionKey) if (window == NULL){ window = new CComponentsWindow(); window->setWindowCaption("|.....................|"); - window->setDimensionsAll(50, 50, 800, 480); + window->setDimensionsAll(50, 50, 1000, 500); window->setWindowIcon(NEUTRINO_ICON_INFO); + + CComponentsShapeCircle *c10 = new CComponentsShapeCircle(0, 0, 28); + CComponentsShapeCircle *c11 = new CComponentsShapeCircle(0, CC_APPEND, 28); + CComponentsShapeCircle *c12 = new CComponentsShapeCircle(50, 0, 28); + CComponentsShapeCircle *c13 = new CComponentsShapeCircle(50, CC_APPEND, 28); + c10->setColorBody(COL_RED); + c11->setColorBody(COL_GREEN); + c12->setColorBody(COL_YELLOW); + c13->setColorBody(COL_BLUE); + + window->getBodyObject()->setAppendOffset(0,50); + window->addWindowItem(c10); + window->addWindowItem(c11); + window->addWindowItem(c12); + window->addWindowItem(c13); } else{ -// window->setDimensionsAll(50, 50, 800, 480); window->setWindowIcon(NEUTRINO_ICON_LOCK); window->setWindowCaption("Test"); } + + if (!window->isPainted()) window->paint(); @@ -532,6 +591,42 @@ int CTestMenu::exec(CMenuTarget* parent, const std::string &actionKey) return res; } + else if (actionKey == "running_clock"){ + if (clock_r == NULL){ + clock_r = new CComponentsFrmClock(100, 50, 0, 50, "%H.%M:%S"); + clock_r->setClockFontType(SNeutrinoSettings::FONT_TYPE_INFOBAR_CHANNAME); + clock_r->setClockIntervall(1); +// clock_r->doPaintBg(false); + } + + if (!clock_r->isPainted()){ + if (clock_r->Start()) + return menu_return::RETURN_EXIT_ALL;; + } + else { + if (clock_r->Stop()){ + clock_r->hide(); + delete clock_r; + clock_r = NULL; + return menu_return::RETURN_EXIT_ALL; + } + } + } + else if (actionKey == "clock"){ + if (clock == NULL){ + clock = new CComponentsFrmClock(100, 50, 0, 50, "%H:%M", false); + clock->setClockFontType(SNeutrinoSettings::FONT_TYPE_INFOBAR_CHANNAME); + } + + if (!clock->isPainted()) + clock->paint(); + else { + clock->hide(); + delete clock; + clock = NULL; + } + return res; + } return showTestMenu(); @@ -568,6 +663,8 @@ int CTestMenu::showTestMenu() void CTestMenu::showCCTests(CMenuWidget *widget) { widget->addIntroItems(); + widget->addItem(new CMenuForwarderNonLocalized("Running Clock", true, NULL, this, "running_clock")); + widget->addItem(new CMenuForwarderNonLocalized("Clock", true, NULL, this, "clock")); widget->addItem(new CMenuForwarderNonLocalized("Button", true, NULL, this, "button")); widget->addItem(new CMenuForwarderNonLocalized("Circle", true, NULL, this, "circle")); widget->addItem(new CMenuForwarderNonLocalized("Square", true, NULL, this, "square")); @@ -575,6 +672,7 @@ void CTestMenu::showCCTests(CMenuWidget *widget) widget->addItem(new CMenuForwarderNonLocalized("Form", true, NULL, this, "form")); widget->addItem(new CMenuForwarderNonLocalized("Text", true, NULL, this, "text")); widget->addItem(new CMenuForwarderNonLocalized("Header", true, NULL, this, "header")); + widget->addItem(new CMenuForwarderNonLocalized("Footer", true, NULL, this, "footer")); widget->addItem(new CMenuForwarderNonLocalized("Icon-Form", true, NULL, this, "iconform")); widget->addItem(new CMenuForwarderNonLocalized("Window", true, NULL, this, "window")); } @@ -589,33 +687,51 @@ void CTestMenu::showHWTests(CMenuWidget *widget) widget->addItem(new CMenuForwarderNonLocalized("Smartcard 2", true, NULL, this, "card1")); #endif widget->addItem(new CMenuForwarderNonLocalized("HDD", true, NULL, this, "hdd")); - - //CFEManager::getInstance()->setMode(CFEManager::FE_MODE_ALONE); - - CServiceManager::getInstance()->InitSatPosition(130, NULL, true); - CServiceManager::getInstance()->InitSatPosition(192, NULL, true); - - satellite_map_t satmap = CServiceManager::getInstance()->SatelliteList(); - satmap[130].configured = 1; - - CFrontend * frontend = CFEManager::getInstance()->getFE(0); - frontend->setSatellites(satmap); - - int count = CFEManager::getInstance()->getFrontendCount(); - if (frontend->getInfo()->type == FE_QPSK) { - widget->addItem(new CMenuForwarderNonLocalized("Tuner 1: Scan 12538000", true, NULL, this, "scan1")); - widget->addItem(new CMenuForwarderNonLocalized("Tuner 1: 22 Khz ON", true, NULL, this, "22kon1")); - widget->addItem(new CMenuForwarderNonLocalized("Tuner 1: 22 Khz OFF", true, NULL, this, "22koff1")); - if(count > 1) { - satmap = CServiceManager::getInstance()->SatelliteList(); - satmap[192].configured = 1; - frontend = CFEManager::getInstance()->getFE(1); + widget->addItem(new CMenuForwarderNonLocalized("SD/MMC", true, NULL, this, "mmc")); + + for (unsigned i = 0; i < sizeof(test_pos)/sizeof(int); i++) { + CServiceManager::getInstance()->InitSatPosition(test_pos[i], NULL, true); + } + + unsigned count = CFEManager::getInstance()->getFrontendCount(); + for (unsigned i = 0; i < count; i++) { + widget->addItem(GenericMenuSeparatorLine); + CFrontend * frontend = CFEManager::getInstance()->getFE(i); + char title[100]; + char scan[100]; + sprintf(scan, "scan%d", i); + if (frontend->getInfo()->type == FE_QPSK) { + sprintf(title, "Satellite tuner %d: Scan %s", i+1, (i & 1) ? "12439-02500-H-5/6" : "12538-41250-V-1/2"); + } else if (frontend->getInfo()->type == FE_QAM) { + sprintf(title, "Cable tuner %d: Scan 474-6875-QAM-256", i+1); + } else + continue; + + widget->addItem(new CMenuForwarderNonLocalized(title, true, NULL, this, scan)); + if (frontend->getInfo()->type == FE_QPSK) { + frontend->setMode(CFrontend::FE_MODE_INDEPENDENT); + + satellite_map_t satmap = CServiceManager::getInstance()->SatelliteList(); + satmap[test_pos[i]].configured = 1; frontend->setSatellites(satmap); - - widget->addItem(new CMenuForwarderNonLocalized("Tuner 2: Scan 12538000", true, NULL, this, "scan2")); - widget->addItem(new CMenuForwarderNonLocalized("Tuner 2: 22 Khz ON", true, NULL, this, "22kon2")); - widget->addItem(new CMenuForwarderNonLocalized("Tuner 2: 22 Khz OFF", true, NULL, this, "22koff2")); + if (i == 0) { + widget->addItem(new CMenuForwarderNonLocalized("Tuner 1: 22 Khz ON", true, NULL, this, "22kon0")); + widget->addItem(new CMenuForwarderNonLocalized("Tuner 1: 22 Khz OFF", true, NULL, this, "22koff0")); + } + if (i == 1) { + widget->addItem(new CMenuForwarderNonLocalized("Tuner 2: 22 Khz ON", true, NULL, this, "22kon1")); + widget->addItem(new CMenuForwarderNonLocalized("Tuner 2: 22 Khz OFF", true, NULL, this, "22koff1")); + } + if (i == 2) { + widget->addItem(new CMenuForwarderNonLocalized("Tuner 3: 22 Khz ON", true, NULL, this, "22kon2")); + widget->addItem(new CMenuForwarderNonLocalized("Tuner 3: 22 Khz OFF", true, NULL, this, "22koff2")); + } + if (i == 3) { + widget->addItem(new CMenuForwarderNonLocalized("Tuner 4: 22 Khz ON", true, NULL, this, "22kon3")); + widget->addItem(new CMenuForwarderNonLocalized("Tuner 4: 22 Khz OFF", true, NULL, this, "22koff3")); + } } } + CFEManager::getInstance()->linkFrontends(true); } #endif diff --git a/src/gui/test_menu.h b/src/gui/test_menu.h index b84f75970..39fd3913d 100644 --- a/src/gui/test_menu.h +++ b/src/gui/test_menu.h @@ -34,6 +34,8 @@ #include #include #include +#include +#include // #define TEST_MENU #include @@ -47,9 +49,11 @@ class CTestMenu : public CMenuTarget CComponentsForm *form; CComponentsText *txt; CComponentsHeader *header; + CComponentsHeader *footer; CComponentsIconForm *iconform; CComponentsWindow *window; CComponentsButton *button; + CComponentsFrmClock *clock ,*clock_r; int width, selected; int showTestMenu(); diff --git a/src/gui/timerlist.cpp b/src/gui/timerlist.cpp index 4b9a09ecf..e8472ead4 100644 --- a/src/gui/timerlist.cpp +++ b/src/gui/timerlist.cpp @@ -53,6 +53,7 @@ #include #include +#include #include #include #include @@ -76,8 +77,6 @@ extern CBouquetManager *g_bouquetManager; #include -#define info_height 60 - class CTimerListNewNotifier : public CChangeObserver { private: @@ -247,19 +246,16 @@ CTimerList::CTimerList() { frameBuffer = CFrameBuffer::getInstance(); visible = false; + x = y = 0; + width = height = 0; + fheight = theight = 0; + footerHeight = 0; selected = 0; liststart = 0; + listmaxshow = 0; Timer = new CTimerdClient(); skipEventID=0; - /* assuming all color icons must have same size */ - int icol_w, icol_h, ih2; - frameBuffer->getIconSize(NEUTRINO_ICON_BUTTON_RED, &icol_w, &icol_h); - frameBuffer->getIconSize(NEUTRINO_ICON_BUTTON_OKAY, &icol_w, &ih2); - icol_h = std::max(icol_h, ih2); - - //buttonHeight = 7 + std::max(icol_h+2, g_Font[SNeutrinoSettings::FONT_TYPE_INFOBAR_SMALL]->getHeight()); - buttonHeight = std::max(icol_h+4, g_Font[SNeutrinoSettings::FONT_TYPE_INFOBAR_SMALL]->getHeight()); /* most probable default */ saved_dispmode = (int)CVFD::MODE_TVRADIO; } @@ -414,6 +410,16 @@ int CTimerList::exec(CMenuTarget* parent, const std::string & actionKey) }*/ } +#define TimerListButtonsCount 5 +struct button_label TimerListButtons[TimerListButtonsCount] = +{ + { NEUTRINO_ICON_BUTTON_RED , LOCALE_TIMERLIST_DELETE }, + { NEUTRINO_ICON_BUTTON_GREEN , LOCALE_TIMERLIST_NEW }, + { NEUTRINO_ICON_BUTTON_YELLOW , LOCALE_TIMERLIST_RELOAD }, + { NEUTRINO_ICON_BUTTON_BLUE , LOCALE_TIMERLIST_MODIFY }, + { NEUTRINO_ICON_BUTTON_INFO_SMALL, NONEXISTANT_LOCALE } +}; + void CTimerList::updateEvents(void) { timerlist.clear(); @@ -429,35 +435,32 @@ void CTimerList::updateEvents(void) } } sort(timerlist.begin(), timerlist.end()); - width = w_max(g_Font[SNeutrinoSettings::FONT_TYPE_MENU]->getWidth()*56, 20); + theight = g_Font[SNeutrinoSettings::FONT_TYPE_MENU_TITLE]->getHeight(); - - int icol_w, icol_h; - frameBuffer->getIconSize(NEUTRINO_ICON_TIMER, &icol_w, &icol_h); - if(theight < icol_h) - theight = icol_h; - frameBuffer->getIconSize(NEUTRINO_ICON_BUTTON_INFO, &icol_w, &icol_h); - if(theight < icol_h) - theight = icol_h; - fheight = g_Font[SNeutrinoSettings::FONT_TYPE_MENU]->getHeight(); + //get footerHeight from paintButtons + footerHeight = ::paintButtons(0, 0, 0, TimerListButtonsCount, TimerListButtons, 0, 0, "", false, COL_INFOBAR_SHADOW, NULL, 0, false); - height = frameBuffer->getScreenHeight() - (info_height+50); + width = w_max(g_Font[SNeutrinoSettings::FONT_TYPE_MENU]->getWidth()*56, 20); + height = frameBuffer->getScreenHeight() - (2*theight); // max height + + listmaxshow = (height-theight)/(fheight*2); + height = theight+listmaxshow*fheight*2+footerHeight; // recalc height - listmaxshow = (height-theight-0)/(fheight*2); - height = theight+0+listmaxshow*fheight*2; // recalc height if (timerlist.size() < listmaxshow) { listmaxshow=timerlist.size(); - height = theight+0+listmaxshow*fheight*2; // recalc height + height = theight+listmaxshow*fheight*2+footerHeight; // recalc height } + if (selected==timerlist.size() && !(timerlist.empty())) { selected=timerlist.size()-1; liststart = (selected/listmaxshow)*listmaxshow; } - x=getScreenStartX( width ); - y = frameBuffer->getScreenY() + (frameBuffer->getScreenHeight() - (height+ info_height)) / 2; + + x = getScreenStartX(width); + y = getScreenStartY(height); } @@ -533,6 +536,8 @@ int CTimerList::show() { paintItem(selected - liststart); } + + paintFoot(); } else if ((msg == CRCInput::RC_down || msg == (unsigned int)g_settings.key_channelList_pagedown) && !(timerlist.empty())) { @@ -561,8 +566,10 @@ int CTimerList::show() { paintItem(selected - liststart); } + + paintFoot(); } - else if ((msg == CRCInput::RC_right || msg == CRCInput::RC_ok) && !(timerlist.empty())) + else if ((msg == CRCInput::RC_right || msg == CRCInput::RC_ok || msg==CRCInput::RC_blue) && !(timerlist.empty())) { if (modifyTimer()==menu_return::RETURN_EXIT_ALL) { @@ -637,7 +644,10 @@ int CTimerList::show() if (timer->eventType == CTimerd::TIMER_RECORD || timer->eventType == CTimerd::TIMER_ZAPTO) { hide(); - res = g_EpgData->show(timer->channel_id, timer->epgID, &timer->epg_starttime); + if (timer->epgID != 0) + res = g_EpgData->show(timer->channel_id, timer->epgID, &timer->epg_starttime); + else + ShowLocalizedHint(LOCALE_MESSAGEBOX_INFO, LOCALE_EPGVIEWER_NOTFOUND); if (res==menu_return::RETURN_EXIT_ALL) loop=false; else @@ -671,7 +681,7 @@ void CTimerList::hide() { if (visible) { - frameBuffer->paintBackgroundBoxRel(x, y, width, height+ info_height+ 5); + frameBuffer->paintBackgroundBoxRel(x, y, width + SHADOW_OFFSET, height + SHADOW_OFFSET); frameBuffer->blit(); visible = false; } @@ -679,7 +689,7 @@ void CTimerList::hide() void CTimerList::paintItem(int pos) { - int ypos = y+ theight+0 + pos*fheight*2; + int ypos = y+ theight+ pos*fheight*2; uint8_t color; fb_pixel_t bgcolor; @@ -690,16 +700,14 @@ void CTimerList::paintItem(int pos) real_width-=15; //scrollbar } + color = COL_MENUCONTENT; if (pos & 1) - { - color = COL_MENUCONTENTDARK; - bgcolor = COL_MENUCONTENTDARK_PLUS_0; - } + bgcolor = COL_MENUCONTENT_PLUS_1; else - { - color = COL_MENUCONTENT; bgcolor = COL_MENUCONTENT_PLUS_0; - } + //shadow + frameBuffer->paintBoxRel(x + width, ypos, SHADOW_OFFSET, 2*fheight, COL_MENUCONTENTDARK_PLUS_0); + //item frameBuffer->paintBoxRel(x, ypos, real_width, 2*fheight, bgcolor); if (liststart + pos == selected) @@ -707,8 +715,9 @@ void CTimerList::paintItem(int pos) color = COL_MENUCONTENTSELECTED; bgcolor = COL_MENUCONTENTSELECTED_PLUS_0; } - + //selected item frameBuffer->paintBoxRel(x,ypos, real_width, 2*fheight, bgcolor, RADIUS_MID); + if (liststart+posgetIconSize(NEUTRINO_ICON_TIMER, &icol_w, &icol_h); - - frameBuffer->paintBoxRel(x, y, width, theight, COL_MENUHEAD_PLUS_0, RADIUS_LARGE, CORNER_TOP); - frameBuffer->paintIcon(NEUTRINO_ICON_TIMER, x+5, y, theight); - g_Font[SNeutrinoSettings::FONT_TYPE_MENU_TITLE]->RenderString(x+icol_w+15, y+theight+0, width - 45, - g_Locale->getText(LOCALE_TIMERLIST_NAME), COL_MENUHEAD, 0, true); // UTF-8 - - //don't show info button on empty timerlist - if (!timerlist.empty()) - { - frameBuffer->getIconSize(NEUTRINO_ICON_BUTTON_INFO, &icol_w, &icol_h); - frameBuffer->paintIcon(NEUTRINO_ICON_BUTTON_INFO, x + width - icol_w - 10, y, theight); - } + CComponentsHeader header(x, y, width, theight, LOCALE_TIMERLIST_NAME, NEUTRINO_ICON_TIMER); + header.setShadowOnOff(CC_SHADOW_ON); + header.paint(CC_SAVE_SCREEN_NO); } -const struct button_label TimerListButtons[4] = -{ - { NEUTRINO_ICON_BUTTON_RED , LOCALE_TIMERLIST_DELETE }, - { NEUTRINO_ICON_BUTTON_GREEN , LOCALE_TIMERLIST_NEW }, - { NEUTRINO_ICON_BUTTON_YELLOW , LOCALE_TIMERLIST_RELOAD }, - { NEUTRINO_ICON_BUTTON_OKAY , LOCALE_TIMERLIST_MODIFY } -}; - void CTimerList::paintFoot() { + CTimerd::responseGetTimer* timer=&timerlist[selected]; + if (timer != NULL) + { + //replace info button with dummy if timer is not type REC or ZAP + if (timer->eventType == CTimerd::TIMER_RECORD || timer->eventType == CTimerd::TIMER_ZAPTO) + TimerListButtons[4].button = NEUTRINO_ICON_BUTTON_INFO_SMALL; + else + TimerListButtons[4].button = NEUTRINO_ICON_BUTTON_DUMMY_SMALL; + } + + //shadow + frameBuffer->paintBoxRel(x + SHADOW_OFFSET, y + height - footerHeight, width, footerHeight + SHADOW_OFFSET, COL_MENUCONTENTDARK_PLUS_0, RADIUS_LARGE, CORNER_BOTTOM); if (timerlist.empty()) - ::paintButtons(x, y + height, width, 2, &(TimerListButtons[1]), width); + ::paintButtons(x, y + height - footerHeight, width, 2, &(TimerListButtons[1]), width); else - ::paintButtons(x, y + height, width, 4, TimerListButtons, width); - + ::paintButtons(x, y + height - footerHeight, width, TimerListButtonsCount, TimerListButtons, width); } void CTimerList::paint() diff --git a/src/gui/timerlist.h b/src/gui/timerlist.h index 3645a7483..8b74bc278 100644 --- a/src/gui/timerlist.h +++ b/src/gui/timerlist.h @@ -45,14 +45,18 @@ class CTimerList : public CMenuTarget { private: - CFrameBuffer *frameBuffer; - unsigned int selected; - unsigned int liststart; - unsigned int listmaxshow; - int fheight; // Fonthoehe Timerlist-Inhalt - int theight; // Fonthoehe Timerlist-Titel - int buttonHeight; - bool visible; + CFrameBuffer *frameBuffer; + int x; + int y; + int width; + int height; + int fheight; // fontheight content + int theight; // fontheight titel + int footerHeight; + unsigned int selected; + unsigned int liststart; + unsigned int listmaxshow; + bool visible; CTimerdClient *Timer; CTimerd::TimerList timerlist; // List of timers @@ -66,11 +70,6 @@ class CTimerList : public CMenuTarget int timer_apids_ac3; int timer_apids_alt; - int width; - int height; - int x; - int y; - int skipEventID; void paintItem(int pos); diff --git a/src/gui/update.cpp b/src/gui/update.cpp index 221edb2ad..900d1b4b7 100644 --- a/src/gui/update.cpp +++ b/src/gui/update.cpp @@ -47,7 +47,6 @@ #include #include -#include #include #include @@ -463,13 +462,13 @@ int CFlashUpdate::exec(CMenuTarget* parent, const std::string &actionKey) printf("[update] flash/install filename %s type %c\n", filename.c_str(), fileType); #endif if(fileType < '3') { - CNeutrinoApp::getInstance()->exec(NULL, "savesettings"); //flash it... - #if ENABLE_EXTUPDATE - if (ShowMsgUTF(LOCALE_MESSAGEBOX_INFO, g_Locale->getText(LOCALE_FLASHUPDATE_APPLY_SETTINGS), CMessageBox::mbrYes, CMessageBox::mbYes | CMessageBox::mbNo, NEUTRINO_ICON_UPDATE) == CMessageBox::mbrYes) - if (!CExtUpdate::getInstance()->applySettings(filename, CExtUpdate::MODE_SOFTUPDATE)) - return menu_return::RETURN_REPAINT; + if (g_settings.apply_settings) { + if (ShowMsgUTF(LOCALE_MESSAGEBOX_INFO, g_Locale->getText(LOCALE_FLASHUPDATE_APPLY_SETTINGS), CMessageBox::mbrYes, CMessageBox::mbYes | CMessageBox::mbNo, NEUTRINO_ICON_UPDATE) == CMessageBox::mbrYes) + if (!CExtUpdate::getInstance()->applySettings(filename, CExtUpdate::MODE_SOFTUPDATE)) + return menu_return::RETURN_REPAINT; + } #endif #ifdef DEBUG1 @@ -485,16 +484,9 @@ int CFlashUpdate::exec(CMenuTarget* parent, const std::string &actionKey) //status anzeigen showGlobalStatus(100); showStatusMessageUTF(g_Locale->getText(LOCALE_FLASHUPDATE_READY)); // UTF-8 - hide(); - - // Unmount all NFS & CIFS volumes - nfs_mounted_once = false; /* needed by update.cpp to prevent removal of modules after flashing a new cramfs, since rmmod (busybox) might no longer be available */ - CFSMounter::umount(); - ShowHintUTF(LOCALE_MESSAGEBOX_INFO, g_Locale->getText(LOCALE_FLASHUPDATE_FLASHREADYREBOOT)); // UTF-8 sleep(2); - //my_system("/etc/init.d/rcK"); ft.reboot(); } else if(fileType == 'T') // display file contents diff --git a/src/gui/update_ext.cpp b/src/gui/update_ext.cpp index cc5920007..320107e46 100644 --- a/src/gui/update_ext.cpp +++ b/src/gui/update_ext.cpp @@ -62,8 +62,6 @@ CExtUpdate::CExtUpdate() imgFilename = ""; mtdRamError = ""; mtdNumber = -1; - MTDBufSize = 0xFFFF; - MTDBuf = new char[MTDBufSize]; backupList = CONFIGDIR "/settingsupdate.conf"; defaultBackup = CONFIGDIR; @@ -84,8 +82,6 @@ CExtUpdate::CExtUpdate() CExtUpdate::~CExtUpdate() { - if (MTDBuf != NULL) - delete[] MTDBuf; if(FileHelpers) delete[] FileHelpers; copyList.clear(); @@ -107,7 +103,7 @@ bool CExtUpdate::ErrorReset(bool modus, const std::string & msg1, const std::str if (modus & RESET_UNLOAD) { umount(mountPkt.c_str()); - my_system(2,"rmmod", mtdramDriver.c_str()); +// my_system(2,"rmmod", mtdramDriver.c_str()); } if (modus & RESET_FD1) close(fd1); @@ -242,7 +238,7 @@ bool CExtUpdate::applySettings() // find mtdram device std::string mtdRamFilename = "", mtdBlockFileName = ""; - int mtdRamSize, mtdRamEraseSize, mtdRamNr = 0; + int mtdRamSize = 0, mtdRamEraseSize = 0, mtdRamNr = 0; f1 = fopen("/proc/mtd", "r"); if(!f1) return ErrorReset(RESET_UNLOAD, "cannot read /proc/mtd"); @@ -272,6 +268,8 @@ bool CExtUpdate::applySettings() } } + int MTDBufSize = 0xFFFF; + char *MTDBuf = new char[MTDBufSize]; // copy image to mtdblock if (MTDBuf == NULL) return ErrorReset(RESET_UNLOAD, "malloc error"); @@ -362,6 +360,8 @@ bool CExtUpdate::applySettings() if(hintBox) hintBox->hide(); + delete[] MTDBuf; + MTDBuf = NULL; sync(); return true; } diff --git a/src/gui/update_ext.h b/src/gui/update_ext.h index 9a81b3d8c..e6cc4642b 100644 --- a/src/gui/update_ext.h +++ b/src/gui/update_ext.h @@ -47,8 +47,6 @@ class CExtUpdate std::string imgFilename; std::string mtdRamError; int mtdNumber; - int MTDBufSize; - char *MTDBuf; int fd1, fd2; FILE *f1; std::string mtdramDriver; diff --git a/src/gui/update_settings.cpp b/src/gui/update_settings.cpp index 7c7742194..27e609283 100644 --- a/src/gui/update_settings.cpp +++ b/src/gui/update_settings.cpp @@ -35,6 +35,7 @@ #include #include +#include #include #include "update_settings.h" #include "filebrowser.h" @@ -103,56 +104,34 @@ int CUpdateSettings::exec(CMenuTarget* parent, const std::string &actionKey) /* init options for software update */ int CUpdateSettings::initMenu() { - CMenuWidget w_upsettings(LOCALE_SERVICEMENU_UPDATE, NEUTRINO_ICON_UPDATE, width, MN_WIDGET_ID_SOFTWAREUPDATE_SETTINGS); + COnOffNotifier* OnOffNotifier = new COnOffNotifier(0); + CMenuWidget w_upsettings(LOCALE_SERVICEMENU_UPDATE, NEUTRINO_ICON_UPDATE, width, MN_WIDGET_ID_SOFTWAREUPDATE_SETTINGS); w_upsettings.addIntroItems(LOCALE_FLASHUPDATE_SETTINGS); -#if 0 -#ifdef USE_SMS_INPUT - CMenuForwarder * fw_url = new CMenuForwarder(LOCALE_FLASHUPDATE_URL_FILE, g_settings.softupdate_mode, g_settings.softupdate_url_file, input_url_file, NULL, CRCInput::RC_green, NEUTRINO_ICON_BUTTON_GREEN); -#else - CMenuForwarder * fw_url = new CMenuForwarder(LOCALE_FLASHUPDATE_URL_FILE, g_settings.softupdate_mode, g_settings.softupdate_url_file, this, "select_url_config_file", CRCInput::RC_green, NEUTRINO_ICON_BUTTON_GREEN); -#endif - CMenuForwarder * fw_update_dir = new CMenuForwarder(LOCALE_EXTRA_UPDATE_DIR, !g_settings.softupdate_mode, g_settings.update_dir , this, "update_dir", CRCInput::RC_red, NEUTRINO_ICON_BUTTON_RED); - - CUrlConfigSetupNotifier url_setup_notifier(fw_url, fw_update_dir, updateItem); - - CMenuOptionChooser *oj_mode = new CMenuOptionChooser(LOCALE_FLASHUPDATE_UPDATEMODE, &g_settings.softupdate_mode, FLASHUPDATE_UPDATEMODE_OPTIONS, FLASHUPDATE_UPDATEMODE_OPTION_COUNT, true, &url_setup_notifier); -#endif - CMenuForwarder * fw_url = new CMenuForwarder(LOCALE_FLASHUPDATE_URL_FILE, true, g_settings.softupdate_url_file, this, "select_url_config_file", CRCInput::RC_green, NEUTRINO_ICON_BUTTON_GREEN); +// fw_url->setHint("", LOCALE_MENU_HINT_XXX); CMenuForwarder * fw_update_dir = new CMenuForwarder(LOCALE_EXTRA_UPDATE_DIR, true, g_settings.update_dir , this, "update_dir", CRCInput::RC_red, NEUTRINO_ICON_BUTTON_RED); +// fw_update_dir->setHint("", LOCALE_MENU_HINT_XXX); + + CMenuOptionChooser *apply_settings = new CMenuOptionChooser(LOCALE_FLASHUPDATE_MENU_APPLY_SETTINGS, &g_settings.apply_settings, OPTIONS_OFF0_ON1_OPTIONS, OPTIONS_OFF0_ON1_OPTION_COUNT, true, OnOffNotifier); +// apply_settings->setHint("", LOCALE_MENU_HINT_XXX); #if 0 - w_upsettings.addItem(oj_mode, true); - w_upsettings.addItem(GenericMenuSeparatorLine); + CMenuOptionChooser *apply_kernel = new CMenuOptionChooser(LOCALE_FLASHUPDATE_MENU_APPLY_KERNEL, &g_settings.apply_kernel, OPTIONS_OFF0_ON1_OPTIONS, OPTIONS_OFF0_ON1_OPTION_COUNT, g_settings.apply_settings); +// apply_kernel->setHint("", LOCALE_MENU_HINT_XXX); + OnOffNotifier->addItem(apply_kernel); #endif + w_upsettings.addItem(fw_update_dir); w_upsettings.addItem(fw_url); + w_upsettings.addItem(GenericMenuSeparatorLine); + w_upsettings.addItem(apply_settings); +#if 0 + w_upsettings.addItem(apply_kernel); +#endif int res = w_upsettings.exec (NULL, ""); + delete OnOffNotifier; return res; } - -#if 0 -CUrlConfigSetupNotifier::CUrlConfigSetupNotifier( CMenuItem* i1, CMenuItem* i2, CMenuForwarder * f1) -{ - toDisable[0] = i1; - toDisable[1] = i2; - updateItem = f1; -} - -bool CUrlConfigSetupNotifier::changeNotify(const neutrino_locale_t, void *) -{ - if (g_settings.softupdate_mode){ - toDisable[0]->setActive(true); - toDisable[1]->setActive(false); - updateItem->setTextLocale(LOCALE_FLASHUPDATE_CHECKUPDATE_INTERNET); - }else{ - toDisable[0]->setActive(false); - toDisable[1]->setActive(true); - updateItem->setTextLocale(LOCALE_FLASHUPDATE_CHECKUPDATE_LOCAL); - } - return false; -} -#endif diff --git a/src/gui/upnpbrowser.cpp b/src/gui/upnpbrowser.cpp index 709d85f64..f82b283ed 100644 --- a/src/gui/upnpbrowser.cpp +++ b/src/gui/upnpbrowser.cpp @@ -58,6 +58,7 @@ #include #include +#include #include #include #include @@ -1009,25 +1010,10 @@ void CUpnpBrowserGui::paintDevice() tmp, COL_MENUCONTENTSELECTED, 0, true); // UTF-8 // Head - tmp = g_Locale->getText(LOCALE_UPNPBROWSER_HEAD); - m_frameBuffer->paintBoxRel(m_x, m_y + m_title_height, m_width, m_theight, COL_MENUHEAD_PLUS_0, c_rad_mid, CORNER_TOP); - m_frameBuffer->paintIcon(NEUTRINO_ICON_UPNP, m_x + 7, m_y + m_title_height + 6); - g_Font[SNeutrinoSettings::FONT_TYPE_MENU_TITLE]->RenderString(m_x + 35, m_y + m_theight + m_title_height + 0, - m_width - 45, tmp, COL_MENUHEAD, 0, true); // UTF-8 - ypos = m_y + m_title_height; - if (m_theight > 26) - ypos = (m_theight - 26) / 2 + m_y + m_title_height; - m_frameBuffer->paintIcon(NEUTRINO_ICON_BUTTON_MENU, m_x + m_width - 30, ypos); -#if 0 - if ( CNeutrinoApp::getInstance()->isMuted() ) - { - xpos = m_x + m_width - 75; - ypos = m_y + m_title_height; - if (m_theight > 32) - ypos = (m_theight - 32) / 2 + m_y + m_title_height; - m_frameBuffer->paintIcon(NEUTRINO_ICON_BUTTON_MUTE, xpos, ypos); - } -#endif + CComponentsHeader header(m_x, m_y + m_title_height, m_width, m_theight, LOCALE_UPNPBROWSER_HEAD, NEUTRINO_ICON_UPNP, CComponentsHeader::CC_BTN_MENU); + if (CNeutrinoApp::getInstance()->isMuted()) + header.addButtonIcon(NEUTRINO_ICON_BUTTON_MUTE_SMALL); + header.paint(CC_SAVE_SCREEN_NO); // Items for (unsigned int count=0; count #include #include using namespace std; -//default vol_height -#define VOL_HEIGHT 36 CVolumeBar::CVolumeBar() { @@ -50,7 +47,8 @@ void CVolumeBar::initVarVolumeBar() initVarForm(); col_body = COL_MENUCONTENT_PLUS_0; - //init variables this + vb_item_offset = 4; + height = 4*vb_item_offset; //default height //assume volume value as pointer to global setting vb_vol = &g_settings.current_volume; @@ -65,12 +63,10 @@ void CVolumeBar::initVarVolumeBar() vb_pbw = 0; vb_pbh = 0; vb_pby = 0; - // progressbar whith - pb_w = 200; //digit vb_digit = NULL; - vb_digit_mode = CTextBox::CENTER; + vb_digit_mode = CTextBox::CENTER ; VolumeFont = SNeutrinoSettings::FONT_TYPE_INFOBAR_INFO; vb_font = g_Font[VolumeFont]; @@ -82,34 +78,29 @@ void CVolumeBar::initVarVolumeBar() //calculates size referred for possible activated clock or/and mute icon void CVolumeBar::initVolumeBarSize() { - // digit whith - if (g_settings.volume_digits) - digit_w = g_Font[VolumeFont]->getRenderWidth("100 "); - else - digit_w = 0; - int dummy = 0; - frameBuffer->getIconSize(NEUTRINO_ICON_VOLUME, &icon_w, &dummy); - icon_w += 12; - - //adapt x-pos - icon_x = corner_rad + 2; - pb_x = icon_x + icon_w + 4; - digit_x = pb_x + pb_w + 5; - - //width - if (g_settings.volume_digits) - width = digit_x + digit_w + corner_rad; - else - width = pb_x + pb_w + corner_rad + 12; - CVolumeHelper *cvh = CVolumeHelper::getInstance(); cvh->getSpacer(&h_spacer, &v_spacer); - cvh->getDimensions(&x, &y, &sw, &sh); + cvh->getDimensions(&x, &y, &sw, &sh, &vb_icon_w, &vb_digit_w); cvh->getVolBarDimensions(&y, &height); + vb_digit_w += cornerRad()/2; + + //scale + vb_pbw = 200; + vb_pbh = height-4*vb_item_offset; + + //adapt x-pos + vb_icon_x = vb_item_offset; + vb_pbx = vb_icon_x + vb_icon_w + vb_item_offset; + vb_digit_x = vb_pbx + vb_pbw + vb_item_offset; + + //result for width + width = (vb_icon_w + vb_pbw + vb_digit_w) + 4*vb_item_offset; + // mute icon cvh->getMuteIconDimensions(&mute_ax, &mute_ay, &mute_dx, &mute_dy); // info clock + int dummy; cvh->getInfoClockDimensions(&dummy, &clock_y, &clock_width, &clock_height, &dummy, &dummy); int mute_corrY = 0; if (mute_dy < height) @@ -136,7 +127,7 @@ void CVolumeBar::initVolumeBarPosition() if ((neutrino->isMuted()) && (!g_settings.mode_clock)) x_corr = mute_dx + h_spacer; if (g_settings.mode_clock) - y += max(clock_y + clock_height, mute_ay + mute_dy) /*+ v_spacer / 2*/; + y += max(clock_y + clock_height, mute_ay + mute_dy); } x = sw - width - x_corr; break; @@ -151,12 +142,16 @@ void CVolumeBar::initVolumeBarPosition() y = (sh + frameBuffer->getScreenY()) - height - v_spacer; break; case 4:// upper center - x = ((sw - width) / 2) + x; + x = ((sw - width) / 2) + x - h_spacer/2; break; case 5:// bottom center - x = ((sw - width) / 2) + x; + x = ((sw - width) / 2) + x - h_spacer/2; y = (sh + frameBuffer->getScreenY()) - height - v_spacer; break; + case 6:// higher center + x = ((sw - width) / 2) + x - h_spacer/2; + y = (sh + frameBuffer->getScreenY()) - sh/10; + break; } } @@ -176,11 +171,11 @@ void CVolumeBar::initVolumeBarItems() //init current icon object void CVolumeBar::initVolumeBarIcon() { - vb_icon = new CComponentsPicture(icon_x, 0, icon_w, height, NEUTRINO_ICON_VOLUME); + vb_icon = new CComponentsPicture(vb_icon_x, 0, vb_icon_w, height, NEUTRINO_ICON_VOLUME); vb_icon->setPictureAlign(CC_ALIGN_HOR_CENTER | CC_ALIGN_VER_CENTER); vb_icon->setColorBody(col_body); - vb_icon->setCornerRadius(corner_rad); + vb_icon->setCornerRadius(cornerRad()); vb_icon->setCornerType(CORNER_LEFT); //add icon to container @@ -192,9 +187,6 @@ void CVolumeBar::initVolumeBarScale() { vb_pb = new CProgressBar(); - vb_pbx = pb_x; - vb_pbw = pb_w; - vb_pb->setInvert(); vb_pb->setBlink(); vb_pb->setRgb(85, 75, 100); @@ -216,8 +208,10 @@ void CVolumeBar::initVolumeBarDigit() { vb_digit = new CComponentsLabel(); - vb_digit->setDimensionsAll(digit_x, 0, digit_w, height); + vb_digit->setDimensionsAll(vb_digit_x, 0, vb_digit_w, height); vb_digit->setTextColor(COL_MENUCONTENT); + vb_digit->setCornerRadius(cornerRad()); + vb_digit->setCornerType(CORNER_RIGHT); initVolumeBarDigitValue(); //add digit label to container @@ -231,9 +225,8 @@ void CVolumeBar::paintVolumeBarDigit() CTextBox* ctb = vb_digit->getCTextBoxObject(); if (ctb) ctb->setFontUseDigitHeight(); - int dx = vb_digit->getRealXPos(); - int dy = vb_digit->getRealYPos(); - vb_digit->setDimensionsAll(dx, dy, digit_w, height); + + // paint digit vb_digit->paint(CC_SAVE_SCREEN_NO); } @@ -285,7 +278,7 @@ void CVolumeHelper::Init() sw = g_settings.screen_EndX - h_spacer; sh = frameBuffer->getScreenHeight(); - initVolBarHeight(); + initVolBarSize(); initMuteIcon(); initInfoClock(); } @@ -324,17 +317,21 @@ void CVolumeHelper::initMuteIcon() mute_ay = y; } -void CVolumeHelper::initVolBarHeight() +void CVolumeHelper::initVolBarSize() { - vol_height = VOL_HEIGHT; + vol_height = 18; + icon_width = 0; + digit_width = 0; int tmp_h = 0; - int dummy = 0; - frameBuffer->getIconSize(NEUTRINO_ICON_VOLUME, &dummy, &tmp_h); - tmp_h += 4; + frameBuffer->getIconSize(NEUTRINO_ICON_VOLUME, &icon_width, &tmp_h); + tmp_h += 2; + icon_width += 8; vol_height = max(vol_height, tmp_h); + if (g_settings.volume_digits) { tmp_h = g_Font[SNeutrinoSettings::FONT_TYPE_INFOBAR_INFO]->getDigitHeight() + (g_Font[SNeutrinoSettings::FONT_TYPE_INFOBAR_INFO]->getDigitOffset() * 18) / 10; vol_height = max(vol_height, tmp_h); + digit_width = g_Font[SNeutrinoSettings::FONT_TYPE_INFOBAR_INFO]->getRenderWidth("100"); } } diff --git a/src/gui/volumebar.h b/src/gui/volumebar.h index e44b2d881..ce1903ae6 100644 --- a/src/gui/volumebar.h +++ b/src/gui/volumebar.h @@ -27,8 +27,11 @@ #ifndef __VOLUMEBAR_H__ #define __VOLUMEBAR_H__ +#include +#include #include //CComponentsForm #include //CProgressBar +#include //CComponentsLabel class CVolumeBar : public CComponentsForm { @@ -42,6 +45,7 @@ class CVolumeBar : public CComponentsForm int sy, sw, sh; int mute_ax, mute_ay, mute_dx, mute_dy, mute_ay_old; int h_spacer, v_spacer; + int vb_item_offset; //clock int clock_y, clock_width, clock_height; @@ -51,8 +55,12 @@ class CVolumeBar : public CComponentsForm //scale dimensions int vb_pbx, vb_pby, vb_pbw, vb_pbh; - int icon_x, pb_x, digit_x; - int icon_w, pb_w, digit_w; + + //icon dimensions + int vb_icon_x, vb_icon_w/*, vb_icon_h*/; + + //digit dimensions + int vb_digit_x, vb_digit_w/*, vb_digit_h*/; void initVarVolumeBar(); void initVolumeBarPosition(); @@ -67,6 +75,9 @@ class CVolumeBar : public CComponentsForm void paintVolScale(); void paintVolumeBarDigit(); +// inline int cornerRad() { return (g_settings.rounded_corners) ? height/2 : 0; } + inline int cornerRad() { return (g_settings.rounded_corners) ? CORNER_RADIUS_SMALL : 0; } + public: CVolumeBar(/*int current_volume*/); @@ -83,12 +94,13 @@ class CVolumeHelper int x, y, sw, sh; int mute_ax, mute_ay, mute_dx, mute_dy, mute_corrY; int clock_ax, clock_ay, clock_dx, clock_dy, digit_h, digit_offset; + int icon_width, digit_width; int h_spacer, v_spacer; int vol_ay, vol_height; CFrameBuffer *frameBuffer; void Init(); - void initVolBarHeight(); + void initVolBarSize(); void initMuteIcon(); void initInfoClock(); @@ -98,7 +110,7 @@ class CVolumeHelper static CVolumeHelper* getInstance(); void getSpacer(int *h, int *v) { *h = h_spacer; *v = v_spacer; } - void getDimensions(int *_x, int *_y, int *_sw, int *_sh) { *_x = x; *_y = y; *_sw = sw; *_sh = sh; } + void getDimensions(int *_x, int *_y, int *_sw, int *_sh, int *_iw, int *_dw) { *_x = x; *_y = y; *_sw = sw; *_sh = sh; *_iw = icon_width; *_dw = digit_width; } void getMuteIconDimensions(int *_x, int *_y, int *w, int *h) { *_x = mute_ax; *_y = mute_ay+mute_corrY; *w = mute_dx; *h = mute_dy; } void getInfoClockDimensions(int *_x, int *_y, int *w, int *h, int *d_h, int *d_o) { *_x = clock_ax; *_y = clock_ay; *w = clock_dx; *h = clock_dy, *d_h = digit_h, *d_o = digit_offset; } void getVolBarDimensions(int *_y, int *_dy) { *_y = vol_ay; *_dy = vol_height; } diff --git a/src/gui/widget/icons.h b/src/gui/widget/icons.h index dbeb07bf3..f6a40518c 100644 --- a/src/gui/widget/icons.h +++ b/src/gui/widget/icons.h @@ -24,6 +24,9 @@ /* icon files */ +#define NEUTRINO_ICON_BUTTON_DUMMY "dummy" +#define NEUTRINO_ICON_BUTTON_DUMMY_SMALL "dummy_small" + #define NEUTRINO_ICON_BUTTON_BLUE "blau" #define NEUTRINO_ICON_BUTTON_GREEN "gruen" #define NEUTRINO_ICON_BUTTON_RED "rot" @@ -241,6 +244,7 @@ #define NEUTRINO_ICON_HINT_FACTORY "hint_factory" /* misc */ +#define NEUTRINO_ICON_HINT_YTPLAY "hint_ytplay" #define NEUTRINO_ICON_VARPATH "/var/share/tuxbox/neutrino/icons/" //alternatively path for user-defined icons diff --git a/src/gui/widget/menue.cpp b/src/gui/widget/menue.cpp index c4c74452d..c196e94bc 100644 --- a/src/gui/widget/menue.cpp +++ b/src/gui/widget/menue.cpp @@ -33,6 +33,7 @@ #include #include +#include #include #include @@ -872,23 +873,16 @@ void CMenuWidget::paint() calcSize(); CVFD::getInstance()->setMode(CVFD::MODE_MENU_UTF8 /*, nameString.c_str()*/); - // paint shadow - frameBuffer->paintBoxRel(x+SHADOW_OFFSET ,y + SHADOW_OFFSET ,width + sb_width ,height + RADIUS_LARGE ,COL_MENUCONTENTDARK_PLUS_0 ,RADIUS_LARGE); // paint head - frameBuffer->paintBoxRel(x ,y ,width + sb_width ,hheight ,COL_MENUHEAD_PLUS_0 ,RADIUS_LARGE, CORNER_TOP); - // paint background - frameBuffer->paintBoxRel(x ,y+hheight, width + sb_width, height-hheight + RADIUS_LARGE ,COL_MENUCONTENT_PLUS_0 ,RADIUS_LARGE, CORNER_BOTTOM); + CComponentsHeader header(x, y, width + sb_width, hheight, nameString, iconfile.c_str()); + header.setShadowOnOff(CC_SHADOW_ON); + header.setOffset(10); + header.paint(CC_SAVE_SCREEN_NO); - //paint menu head - int HeadiconOffset = 0; - if(!(iconfile.empty())){ - int w, h; - frameBuffer->getIconSize(iconfile.c_str(), &w, &h); - HeadiconOffset = w+6; - } - int fw = g_Font[SNeutrinoSettings::FONT_TYPE_MENU_TITLE]->getWidth(); - g_Font[SNeutrinoSettings::FONT_TYPE_MENU_TITLE]->RenderString(x+(fw/3)+HeadiconOffset,y+hheight+1, width-((fw/3)+HeadiconOffset), nameString.c_str(), COL_MENUHEAD, 0, true); // UTF-8 - frameBuffer->paintIcon(iconfile, x + fw/4, y, hheight); + // paint body shadow + frameBuffer->paintBoxRel(x+SHADOW_OFFSET, y + hheight + SHADOW_OFFSET, width + sb_width, height - hheight + RADIUS_LARGE, COL_MENUCONTENTDARK_PLUS_0, RADIUS_LARGE, CORNER_BOTTOM); + // paint body background + frameBuffer->paintBoxRel(x ,y+hheight, width + sb_width, height-hheight + RADIUS_LARGE ,COL_MENUCONTENT_PLUS_0 ,RADIUS_LARGE, CORNER_BOTTOM); item_start_y = y+hheight; paintItems(); @@ -1145,6 +1139,7 @@ void CMenuWidget::paintHint(int pos) info_box->setText(str, CTextBox::AUTO_WIDTH, g_Font[SNeutrinoSettings::FONT_TYPE_MENU_HINT]); info_box->setCornerRadius(RADIUS_LARGE); info_box->syncSysColors(); + info_box->setColorBody(COL_MENUCONTENTDARK_PLUS_0); info_box->setShadowOnOff(CC_SHADOW_ON); info_box->setPicture(item->hintIcon); } @@ -1864,7 +1859,7 @@ int CMenuSeparator::paint(bool selected) /* if no alignment is specified, align centered */ if (type & ALIGN_LEFT) - name_start_x = x + (!SUB_HEAD ? name_start_x : 20 +18); + name_start_x = x + (!SUB_HEAD ? name_start_x : 20 + 24 /*std icon_width is 24px - this should be determinated from NEUTRINO_ICON_BUTTON_HOME or so*/); else if (type & ALIGN_RIGHT) name_start_x = x + dx - stringwidth - 20; else /* ALIGN_CENTER */ diff --git a/src/gui/widget/menue.h b/src/gui/widget/menue.h index 11f7b8f4e..9d9eb92a1 100644 --- a/src/gui/widget/menue.h +++ b/src/gui/widget/menue.h @@ -41,7 +41,8 @@ #include #include #include -#include +#include +#include #include #include diff --git a/src/gui/widget/progressstatus.h b/src/gui/widget/progressstatus.h index 1e2358ffb..6b37930f3 100644 --- a/src/gui/widget/progressstatus.h +++ b/src/gui/widget/progressstatus.h @@ -34,6 +34,7 @@ class CProgress_StatusViewer virtual unsigned int getGlobalStatus(void) = 0; virtual void showLocalStatus(const unsigned int prog) = 0; virtual void showStatusMessageUTF(const std::string & text) = 0; + virtual void paint() = 0; }; #endif diff --git a/src/gui/widget/progresswindow.cpp b/src/gui/widget/progresswindow.cpp index fe347a7a6..e3957c0f7 100644 --- a/src/gui/widget/progresswindow.cpp +++ b/src/gui/widget/progresswindow.cpp @@ -6,6 +6,8 @@ Copyright (C) 2001 Steffen Hehn 'McClean' Homepage: http://dbox.cyberphoria.org/ + Copyright (C) 2009-2013 Stefan Seyfried + License: GPL This program is free software; you can redistribute it and/or modify @@ -35,6 +37,7 @@ #include #include #include +#include #include @@ -120,6 +123,8 @@ void CProgressWindow::showLocalStatus(const unsigned int prog) #ifdef VFD_UPDATE CVFD::getInstance()->showProgressBar2(local_progress); +#else + CVFD::getInstance()->showPercentOver(local_progress); #endif // VFD_UPDATE } diff --git a/src/gui/widget/progresswindow.h b/src/gui/widget/progresswindow.h index 667920087..9b4282d4f 100644 --- a/src/gui/widget/progresswindow.h +++ b/src/gui/widget/progresswindow.h @@ -57,13 +57,12 @@ class CProgressWindow : public CMenuTarget, public CProgress_StatusViewer //---------------------------- - virtual void paint(); - public: CProgressWindow(); void setTitle(const neutrino_locale_t title); virtual void hide(); + virtual void paint(); virtual int exec( CMenuTarget* parent, const std::string & actionKey ); diff --git a/src/gui/widget/stringinput.cpp b/src/gui/widget/stringinput.cpp index feb9baefe..72ea25b4b 100644 --- a/src/gui/widget/stringinput.cpp +++ b/src/gui/widget/stringinput.cpp @@ -439,10 +439,10 @@ int CStringInput::exec( CMenuTarget* parent, const std::string & ) strcat(value, " "); strncpy(oldval, value, size); - fb_pixel_t * pixbuf = new fb_pixel_t[(width + SHADOW_OFFSET) * (hheight + bheight + SHADOW_OFFSET)]; + fb_pixel_t * pixbuf = new fb_pixel_t[(width + SHADOW_OFFSET) * (height + SHADOW_OFFSET)]; if (pixbuf != NULL) - frameBuffer->SaveScreen(x, y, width + SHADOW_OFFSET, hheight + bheight + SHADOW_OFFSET, pixbuf); + frameBuffer->SaveScreen(x, y, width + SHADOW_OFFSET, height + SHADOW_OFFSET, pixbuf); paint(); frameBuffer->blit(); @@ -559,7 +559,7 @@ int CStringInput::exec( CMenuTarget* parent, const std::string & ) if (pixbuf != NULL) { - frameBuffer->RestoreScreen(x, y, width + SHADOW_OFFSET, hheight + bheight + SHADOW_OFFSET, pixbuf); + frameBuffer->RestoreScreen(x, y, width + SHADOW_OFFSET, height + SHADOW_OFFSET, pixbuf); delete[] pixbuf;//Mismatching allocation and deallocation: pixbuf } @@ -574,7 +574,7 @@ int CStringInput::exec( CMenuTarget* parent, const std::string & ) } value[size]=0; - if (valueString != NULL) + if ( (valueString != NULL) && (msg == CRCInput::RC_ok) ) { *valueString = value; } @@ -601,7 +601,7 @@ void CStringInput::hide() void CStringInput::paint(bool sms) { - frameBuffer->paintBoxRel(x + SHADOW_OFFSET, y + SHADOW_OFFSET, width, hheight + bheight, COL_MENUCONTENTDARK_PLUS_0, RADIUS_LARGE, CORNER_ALL); //round + frameBuffer->paintBoxRel(x + SHADOW_OFFSET, y + SHADOW_OFFSET, width, height, COL_MENUCONTENTDARK_PLUS_0, RADIUS_LARGE, CORNER_ALL); //round frameBuffer->paintBoxRel(x, y, width, hheight, COL_MENUHEAD_PLUS_0, RADIUS_LARGE, CORNER_TOP); //round frameBuffer->paintBoxRel(x, y + hheight, width, bheight, COL_MENUCONTENT_PLUS_0, sms ? 0 : RADIUS_LARGE, CORNER_BOTTOM); diff --git a/src/gui/widget/stringinput.h b/src/gui/widget/stringinput.h index b0b64fe8e..47d5d692a 100644 --- a/src/gui/widget/stringinput.h +++ b/src/gui/widget/stringinput.h @@ -101,7 +101,7 @@ class CStringInputSMS : public CStringInput { bool capsMode; int arraySizes[10]; - char Chars[10][9]; // maximal 9 character in one CharList entry! + char Chars[10][10]; // maximal 10 character in one CharList entry! int keyCounter; int last_digit; diff --git a/src/gui/widget/stringinput_ext.cpp b/src/gui/widget/stringinput_ext.cpp index 0a3bd9602..e3a0438dd 100644 --- a/src/gui/widget/stringinput_ext.cpp +++ b/src/gui/widget/stringinput_ext.cpp @@ -270,7 +270,10 @@ int CExtendedInput::exec( CMenuTarget* parent, const std::string & ) } else if ( CNeutrinoApp::getInstance()->handleMsg( msg, data ) & messages_return::cancel_all ) { - loop = false; + strcpy(value, oldval); + loop=false; + if(cancel != NULL) + *cancel = true; res = menu_return::RETURN_EXIT_ALL; } frameBuffer->blit(); diff --git a/src/gui/widget/textbox.cpp b/src/gui/widget/textbox.cpp index 07a8c1a1a..20bd21643 100644 --- a/src/gui/widget/textbox.cpp +++ b/src/gui/widget/textbox.cpp @@ -220,10 +220,7 @@ void CTextBox::setTextFont(Font* font_text) void CTextBox::setTextBorderWidth(int border) { - /* we need a minimal borderwith of 1px because the edge-smoothing - (or fontrenderer?) otherwise will paint single pixels outside the - defined area. e.g. 'j' is leaving such residues */ - text_border_width = (border > 0) ? border : 1; + text_border_width = border; //Initialise the window frames first and than refresh text line array initFramesAndTextArray(); } @@ -353,8 +350,8 @@ void CTextBox::refreshTextLineArray(void) lineBreakWidth = std::max(m_nMaxWidth, m_cFrameTextRel.iWidth - 2*text_border_width); } - if(m_nMaxTextWidth) - lineBreakWidth = m_nMaxTextWidth; + if(m_nMaxTextWidth) + lineBreakWidth = m_nMaxTextWidth - 2*text_border_width; //TRACE("[CTextBox] line %d: lineBreakWidth %d\n", __LINE__, lineBreakWidth); diff --git a/src/neutrino.cpp b/src/neutrino.cpp index a3672f010..cac679fd0 100644 --- a/src/neutrino.cpp +++ b/src/neutrino.cpp @@ -60,6 +60,7 @@ #include #include #include +#include #include "gui/audiomute.h" #include "gui/audioplayer.h" @@ -151,7 +152,7 @@ extern cAudio * audioDecoder; cPowerManager *powerManager; cCpuFreqManager * cpuFreq; -void stop_daemons(bool stopall = true); +void stop_daemons(bool stopall = true, bool for_flash = false); void stop_video(void); // uncomment if you want to have a "test" menue entry (rasc) @@ -437,8 +438,8 @@ int CNeutrinoApp::loadSetup(const char * fname) } g_settings.infobar_show = configfile.getInt32("infobar_show", 1); g_settings.infobar_show_channellogo = configfile.getInt32("infobar_show_channellogo" , 3 ); - g_settings.infobar_progressbar = configfile.getInt32("infobar_progressbar" , 0 ); - g_settings.casystem_display = configfile.getInt32("casystem_display", 2 );//mini ca mode default + g_settings.infobar_progressbar = configfile.getInt32("infobar_progressbar" , 1 ); // below channel name + g_settings.casystem_display = configfile.getInt32("casystem_display", 1 );//discreet ca mode default g_settings.scrambled_message = configfile.getBool("scrambled_message", true ); g_settings.volume_pos = configfile.getInt32("volume_pos", 0 ); g_settings.volume_digits = configfile.getBool("volume_digits", true); @@ -487,6 +488,7 @@ int CNeutrinoApp::loadSetup(const char * fname) g_settings.epg_save = configfile.getBool("epg_save", false); g_settings.epg_save_standby = configfile.getBool("epg_save_standby", true); + g_settings.epg_scan = configfile.getBool("epg_scan", false); //widget settings g_settings.widget_fade = false; g_settings.widget_fade = configfile.getBool("widget_fade" , false ); @@ -547,7 +549,7 @@ int CNeutrinoApp::loadSetup(const char * fname) g_settings.personalize[i] = configfile.getInt32( personalize_settings[i].personalize_settings_name, personalize_settings[i].personalize_default_val ); g_settings.colored_events_channellist = configfile.getInt32( "colored_events_channellist" , 0 ); - g_settings.colored_events_infobar = configfile.getInt32( "colored_events_infobar" , 0 ); + g_settings.colored_events_infobar = configfile.getInt32( "colored_events_infobar" , 2 ); // next g_settings.colored_events_alpha = configfile.getInt32( "colored_events_alpha", 0x00 ); g_settings.colored_events_red = configfile.getInt32( "colored_events_red", 95 ); g_settings.colored_events_green = configfile.getInt32( "colored_events_green", 70 ); @@ -629,12 +631,12 @@ int CNeutrinoApp::loadSetup(const char * fname) g_settings.recording_zap_on_announce = configfile.getBool("recording_zap_on_announce" , false); g_settings.shutdown_timer_record_type = configfile.getBool("shutdown_timer_record_type" , false); - g_settings.recording_stream_vtxt_pid = configfile.getBool("recordingmenu.stream_vtxt_pid" , false); - g_settings.recording_stream_subtitle_pids = configfile.getBool("recordingmenu.stream_subtitle_pids", false); + g_settings.recording_stream_vtxt_pid = configfile.getBool("recordingmenu.stream_vtxt_pid" , true); + g_settings.recording_stream_subtitle_pids = configfile.getBool("recordingmenu.stream_subtitle_pids", true); g_settings.recording_stream_pmt_pid = configfile.getBool("recordingmenu.stream_pmt_pid" , false); g_settings.recording_choose_direct_rec_dir = configfile.getInt32( "recording_choose_direct_rec_dir", 0 ); g_settings.recording_epg_for_filename = configfile.getBool("recording_epg_for_filename" , true); - g_settings.recording_epg_for_end = configfile.getBool("recording_epg_for_end" , false); + g_settings.recording_epg_for_end = configfile.getBool("recording_epg_for_end" , true); g_settings.recording_save_in_channeldir = configfile.getBool("recording_save_in_channeldir" , false); g_settings.recording_slow_warning = configfile.getBool("recording_slow_warning" , true); @@ -705,6 +707,8 @@ int CNeutrinoApp::loadSetup(const char * fname) //Software-update g_settings.softupdate_mode = configfile.getInt32( "softupdate_mode", 1 ); + g_settings.apply_kernel = configfile.getBool("apply_kernel" , false); + g_settings.apply_settings = configfile.getBool("apply_settings" , true); strcpy(g_settings.softupdate_url_file, configfile.getString("softupdate_url_file", "/var/etc/update.urls").c_str()); strcpy(g_settings.softupdate_proxyserver, configfile.getString("softupdate_proxyserver", "" ).c_str()); @@ -953,6 +957,7 @@ void CNeutrinoApp::saveSetup(const char * fname) // epg configfile.setBool("epg_save", g_settings.epg_save); configfile.setBool("epg_save_standby", g_settings.epg_save_standby); + configfile.setBool("epg_scan", g_settings.epg_scan); configfile.setString("epg_cache_time" ,g_settings.epg_cache ); configfile.setString("epg_extendedcache_time" ,g_settings.epg_extendedcache); configfile.setString("epg_old_events" ,g_settings.epg_old_events ); @@ -1135,6 +1140,8 @@ void CNeutrinoApp::saveSetup(const char * fname) //Software-update configfile.setInt32 ("softupdate_mode" , g_settings.softupdate_mode ); + configfile.setBool("apply_kernel", g_settings.apply_kernel); + configfile.setBool("apply_settings", g_settings.apply_settings); configfile.setString("softupdate_url_file" , g_settings.softupdate_url_file ); configfile.setString("softupdate_proxyserver" , g_settings.softupdate_proxyserver ); @@ -1764,6 +1771,7 @@ void CNeutrinoApp::InitSectiondClient() g_Sectionsd = new CSectionsdClient; g_Sectionsd->registerEvent(CSectionsdClient::EVT_TIMESET, 222, NEUTRINO_UDS_NAME); g_Sectionsd->registerEvent(CSectionsdClient::EVT_GOT_CN_EPG, 222, NEUTRINO_UDS_NAME); + g_Sectionsd->registerEvent(CSectionsdClient::EVT_EIT_COMPLETE, 222, NEUTRINO_UDS_NAME); g_Sectionsd->registerEvent(CSectionsdClient::EVT_WRITE_SI_FINISHED, 222, NEUTRINO_UDS_NAME); } @@ -2059,16 +2067,23 @@ void CNeutrinoApp::quickZap(int msg) StopSubtitles(); printf("CNeutrinoApp::quickZap haveFreeFrontend %d\n", CFEManager::getInstance()->haveFreeFrontend()); +#if 0 if(!CFEManager::getInstance()->haveFreeFrontend()) { res = channelList->numericZap(g_settings.key_zaphistory); StartSubtitles(res < 0); return; } +#endif + bool ret; if(!bouquetList->Bouquets.empty()) - bouquetList->Bouquets[bouquetList->getActiveBouquetNumber()]->channelList->quickZap(msg, g_settings.zap_cycle); + ret = bouquetList->Bouquets[bouquetList->getActiveBouquetNumber()]->channelList->quickZap(msg, g_settings.zap_cycle); else - channelList->quickZap(msg); + ret = channelList->quickZap(msg); + if (!ret) { + res = channelList->numericZap(g_settings.key_zaphistory); + StartSubtitles(res < 0); + } } void CNeutrinoApp::numericZap(int msg) @@ -2164,6 +2179,8 @@ void CNeutrinoApp::RealRun(CMenuWidget &mainMenu) InfoClock->StartClock(); StartSubtitles(); saveSetup(NEUTRINO_SETTINGS_FILE); + if (!g_settings.epg_scan) + CEpgScan::getInstance()->Clear(); } } else if (((msg == CRCInput::RC_tv) || (msg == CRCInput::RC_radio)) && (g_settings.key_tvradio_mode == (int)CRCInput::RC_nokey)) { @@ -2190,7 +2207,7 @@ void CNeutrinoApp::RealRun(CMenuWidget &mainMenu) showInfo(); break; case SNeutrinoSettings::VOLUME: - g_volume->setVolume(msg, true); + g_volume->setVolume(msg); break; default: /* SNeutrinoSettings::ZAP */ quickZap(msg); @@ -2210,7 +2227,7 @@ void CNeutrinoApp::RealRun(CMenuWidget &mainMenu) showInfo(); break; case SNeutrinoSettings::VOLUME: - g_volume->setVolume(msg, true); + g_volume->setVolume(msg); break; default: /* SNeutrinoSettings::ZAP */ quickZap(msg); @@ -2425,6 +2442,7 @@ int CNeutrinoApp::handleMsg(const neutrino_msg_t _msg, neutrino_msg_data_t data) /* update scan settings for manual scan to current channel */ CScanSetup::getInstance()->updateManualSettings(); + CEpgScan::getInstance()->handleMsg(msg, data); } if ((msg == NeutrinoMessages::EVT_TIMER)) { if(data == scrambled_timer) { @@ -2436,6 +2454,10 @@ int CNeutrinoApp::handleMsg(const neutrino_msg_t _msg, neutrino_msg_data_t data) return messages_return::handled; } } + if ((msg == NeutrinoMessages::EVT_EIT_COMPLETE)) { + CEpgScan::getInstance()->handleMsg(msg, data); + return messages_return::handled; + } res = res | g_RemoteControl->handleMsg(msg, data); res = res | g_InfoViewer->handleMsg(msg, data); @@ -2637,7 +2659,7 @@ _repeat: } else if ((msg == CRCInput::RC_plus) || (msg == CRCInput::RC_minus)) { - g_volume->setVolume(msg, (mode != mode_scart)); + g_volume->setVolume(msg); return messages_return::handled; } else if( msg == CRCInput::RC_spkr ) { @@ -3703,11 +3725,24 @@ bool CNeutrinoApp::changeNotify(const neutrino_locale_t OptionName, void * /*dat return false; } +void CNeutrinoApp::stopDaemonsForFlash() +{ + stop_daemons(false, true); +} + /************************************************************************************** * Main programm - no function here * **************************************************************************************/ -void stop_daemons(bool stopall) +void stop_daemons(bool stopall, bool for_flash) { + if (for_flash) { + CVFD::getInstance()->Clear(); + CVFD::getInstance()->setMode(CVFD::MODE_TVRADIO); + CVFD::getInstance()->ShowText("Stop daemons..."); + g_settings.epg_scan = false; + my_system(NEUTRINO_ENTER_FLASH_SCRIPT); + } + dvbsub_close(); tuxtxt_stop(); tuxtxt_close(); @@ -3723,7 +3758,7 @@ void stop_daemons(bool stopall) } printf("httpd shutdown done\n"); CStreamManager::getInstance()->Stop(); - if(stopall) { + if(stopall || for_flash) { printf("timerd shutdown\n"); if (g_Timerd) g_Timerd->shutdown(); @@ -3738,15 +3773,16 @@ void stop_daemons(bool stopall) #endif tuxtx_stop_subtitle(); printf("zapit shutdown\n"); - if(!stopall && g_settings.hdmi_cec_mode && g_settings.hdmi_cec_standby){ + if(!for_flash && !stopall && g_settings.hdmi_cec_mode && g_settings.hdmi_cec_standby){ videoDecoder->SetCECMode((VIDEO_HDMI_CEC_MODE)0); } delete &CMoviePlayerGui::getInstance(); CZapit::getInstance()->Stop(); printf("zapit shutdown done\n"); - CVFD::getInstance()->Clear(); - if(stopall) { + if (!for_flash) + CVFD::getInstance()->Clear(); + if(stopall && !for_flash) { if (cpuFreq) { cpuFreq->SetCpuFreq(g_settings.cpufreq * 1000 * 1000); delete cpuFreq; @@ -3763,6 +3799,13 @@ void stop_daemons(bool stopall) } cs_deregister_messenger(); } + + if (for_flash) { + delete CRecordManager::getInstance(); + delete videoDemux; + int ret = my_system(4, "mount", "-no", "remount,ro", "/"); + printf("remount rootfs readonly %s.\n", (ret == 0)?"successful":"failed"); fflush(stdout); + } } void stop_video() @@ -3826,7 +3869,7 @@ void CNeutrinoApp::loadKeys(const char * fname) } //rc-key configuration - g_settings.key_tvradio_mode = tconfig.getInt32( "key_tvradio_mode", CRCInput::RC_nokey ); + g_settings.key_tvradio_mode = tconfig.getInt32( "key_tvradio_mode", (unsigned int)CRCInput::RC_nokey ); g_settings.key_power_off = tconfig.getInt32( "key_power_off", CRCInput::RC_standby ); g_settings.key_channelList_pageup = tconfig.getInt32( "key_channelList_pageup", CRCInput::RC_page_up ); @@ -3836,12 +3879,12 @@ void CNeutrinoApp::loadKeys(const char * fname) g_settings.key_channelList_addrecord = tconfig.getInt32( "key_channelList_addrecord", CRCInput::RC_red ); g_settings.key_channelList_addremind = tconfig.getInt32( "key_channelList_addremind", CRCInput::RC_yellow ); - g_settings.key_list_start = tconfig.getInt32( "key_list_start", CRCInput::RC_nokey ); - g_settings.key_list_end = tconfig.getInt32( "key_list_end", CRCInput::RC_nokey ); + g_settings.key_list_start = tconfig.getInt32( "key_list_start", (unsigned int)CRCInput::RC_nokey ); + g_settings.key_list_end = tconfig.getInt32( "key_list_end", (unsigned int)CRCInput::RC_nokey ); g_settings.key_timeshift = tconfig.getInt32( "key_timeshift", CRCInput::RC_pause ); - g_settings.key_plugin = tconfig.getInt32( "key_plugin", CRCInput::RC_nokey ); + g_settings.key_plugin = tconfig.getInt32( "key_plugin", (unsigned int)CRCInput::RC_nokey ); g_settings.key_unlock = tconfig.getInt32( "key_unlock", CRCInput::RC_setup ); - g_settings.key_screenshot = tconfig.getInt32( "key_screenshot", CRCInput::RC_nokey ); + g_settings.key_screenshot = tconfig.getInt32( "key_screenshot", (unsigned int)CRCInput::RC_nokey ); #ifdef ENABLE_PIP g_settings.key_pip_close = tconfig.getInt32( "key_pip_close", CRCInput::RC_help ); g_settings.key_pip_setup = tconfig.getInt32( "key_pip_setup", CRCInput::RC_pos ); @@ -3868,6 +3911,7 @@ void CNeutrinoApp::loadKeys(const char * fname) g_settings.mpkey_time = tconfig.getInt32( "mpkey.time", CRCInput::RC_setup ); g_settings.mpkey_bookmark = tconfig.getInt32( "mpkey.bookmark", CRCInput::RC_blue ); g_settings.mpkey_plugin = tconfig.getInt32( "mpkey.plugin", CRCInput::RC_red ); + g_settings.mpkey_subtitle = tconfig.getInt32( "mpkey.subtitle", CRCInput::RC_sub ); /* options */ g_settings.menu_left_exit = tconfig.getInt32( "menu_left_exit", 0 ); @@ -3931,6 +3975,7 @@ void CNeutrinoApp::saveKeys(const char * fname) tconfig.setInt32( "mpkey.time", g_settings.mpkey_time ); tconfig.setInt32( "mpkey.bookmark", g_settings.mpkey_bookmark ); tconfig.setInt32( "mpkey.plugin", g_settings.mpkey_plugin ); + tconfig.setInt32( "mpkey.subtitle", g_settings.mpkey_subtitle ); tconfig.setInt32( "menu_left_exit", g_settings.menu_left_exit ); tconfig.setInt32( "audio_run_player", g_settings.audio_run_player ); diff --git a/src/neutrino.h b/src/neutrino.h index bf470f6ad..b79678e08 100644 --- a/src/neutrino.h +++ b/src/neutrino.h @@ -138,7 +138,6 @@ private: void radioMode( bool rezap = true ); void scartMode( bool bOnOff ); void standbyMode( bool bOnOff, bool fromDeepStandby = false ); - void saveEpg(bool cvfd_mode); void getAnnounceEpgName(CTimerd::RecordingInfo * eventinfo, std::string &name); void ExitRun(const bool write_si = true, int retcode = 0); @@ -233,6 +232,9 @@ public: void showInfo(void); CConfigFile* getConfigFile() {return &configfile;}; bool SDTreloadChannels; + + void saveEpg(bool cvfd_mode); + void stopDaemonsForFlash(); }; #endif diff --git a/src/neutrinoMessages.h b/src/neutrinoMessages.h index 7eeaaae4a..50d703020 100644 --- a/src/neutrinoMessages.h +++ b/src/neutrinoMessages.h @@ -110,6 +110,7 @@ struct NeutrinoMessages { EVT_PMT_CHANGED = CRCInput::RC_Events + 40, /* NEVER CHANGE THIS */ EVT_CA_MESSAGE = CRCInput::RC_Events + 60, /* data = CA_MESSAGE pointer */ + EVT_SUBT_MESSAGE = CRCInput::RC_Events + 61, /* data = subtitles pointer */ /* END */ EVT_CURRENTEPG = CRCInput::RC_WithData + 1, @@ -146,7 +147,9 @@ struct NeutrinoMessages { EVT_TUNE_COMPLETE = CRCInput::RC_WithData + 22, /* data: (t_channel_id *) */ /* neutrino */ - EVT_RECORDING_ENDED = CRCInput::RC_WithData + 23 + EVT_RECORDING_ENDED = CRCInput::RC_WithData + 23, + /* sectionsd */ + EVT_EIT_COMPLETE = CRCInput::RC_WithData + 24, /* data: (t_channel_id *) */ }; enum { diff --git a/src/nhttpd/tuxboxapi/coolstream/controlapi.cpp b/src/nhttpd/tuxboxapi/coolstream/controlapi.cpp index fda35eb27..ff62a833d 100644 --- a/src/nhttpd/tuxboxapi/coolstream/controlapi.cpp +++ b/src/nhttpd/tuxboxapi/coolstream/controlapi.cpp @@ -627,6 +627,8 @@ void CControlAPI::HWInfoCGI(CyhookHandler *hh) case 8: case 9: boxname += "Neo"; + if (CFEManager::getInstance()->getFrontendCount() > 1) + boxname += " Twin"; break; case 10: boxname += "Zee"; diff --git a/src/nhttpd/tuxboxapi/coolstream/neutrinoyparser.cpp b/src/nhttpd/tuxboxapi/coolstream/neutrinoyparser.cpp index b099cebf4..9ea0ebaaf 100644 --- a/src/nhttpd/tuxboxapi/coolstream/neutrinoyparser.cpp +++ b/src/nhttpd/tuxboxapi/coolstream/neutrinoyparser.cpp @@ -694,6 +694,8 @@ std::string CNeutrinoYParser::func_get_boxtype(CyhookHandler *, std::string) case 8: case 9: boxname += "Neo"; + if (CFEManager::getInstance()->getFrontendCount() > 1) + boxname += " Twin"; break; case 10: boxname += "Zee"; diff --git a/src/nhttpd/web/Y_Blocks.txt b/src/nhttpd/web/Y_Blocks.txt index c887e2822..7894b0ca4 100644 --- a/src/nhttpd/web/Y_Blocks.txt +++ b/src/nhttpd/web/Y_Blocks.txt @@ -496,7 +496,13 @@ end-block~frame_live_epg # ------- Remote start-block~remote -{=if-equal:CST Neo SAT~{=if-equal:{=ini-get:/var/tuxbox/config/Y-Web.conf;fb;default=}~default~{=func:get_boxtype=}~{=ini-get:/var/tuxbox/config/Y-Web.conf;fb;default=}=}~{=include-block:Y_Blocks.txt;remote_neo=}~{=if-equal:{=func:get_boxtype=}~CST Neo CABLE~{=include-block:Y_Blocks.txt;remote_neo=}~{=if-equal:{=func:get_boxtype=}~CST Zee SAT~{=include-block:Y_Blocks.txt;remote_zee=}~{=if-equal:{=func:get_boxtype=}~CST Zee CABLE~{=include-block:Y_Blocks.txt;remote_zee=}~{=include-block:Y_Blocks.txt;remote_hd1=}=}=}=}=} +{=if-equal:CST Neo SAT~{=if-equal:{=ini-get:/var/tuxbox/config/Y-Web.conf;fb;default=}~default~{=func:get_boxtype=}~{=ini-get:/var/tuxbox/config/Y-Web.conf;fb;default=}=}~{=include-block:Y_Blocks.txt;remote_neo=}~ + {=if-equal:{=func:get_boxtype=}~CST Neo CABLE~{=include-block:Y_Blocks.txt;remote_neo=}~ + {=if-equal:{=func:get_boxtype=}~CST Zee SAT~{=include-block:Y_Blocks.txt;remote_zee=}~ + {=if-equal:{=func:get_boxtype=}~CST Zee CABLE~{=include-block:Y_Blocks.txt;remote_zee=}~ + {=if-equal:{=func:get_boxtype=}~CST Neo Twin SAT~{=include-block:Y_Blocks.txt;remote_zee=}~ + {=if-equal:{=func:get_boxtype=}~CST Neo Twin CABLE~{=include-block:Y_Blocks.txt;remote_zee=}~ +{=include-block:Y_Blocks.txt;remote_hd1=}=}=}=}=}=}=} end-block~remote # ------- Remote Coolstream Neo diff --git a/src/system/Makefile.am b/src/system/Makefile.am index 723e7e91e..fd370524c 100644 --- a/src/system/Makefile.am +++ b/src/system/Makefile.am @@ -38,5 +38,6 @@ libneutrino_system_a_SOURCES = \ helpers.cpp \ ping.c \ settings.cpp \ + ytparser.cpp \ setting_helpers.cpp # safe_system.c diff --git a/src/system/flashtool.cpp b/src/system/flashtool.cpp index 395b5a411..b6fb4bb40 100644 --- a/src/system/flashtool.cpp +++ b/src/system/flashtool.cpp @@ -25,10 +25,14 @@ #include #include +#include +#include +#include #include #include #include +#include #include #include #include @@ -37,6 +41,8 @@ #include #include +#include +#include #if HAVE_TRIPLEDRAGON /* TD kernel 2.6.12 is too old and does not have writesize yet, use oobsize instead */ @@ -104,13 +110,7 @@ bool CFlashTool::readFromMTD( const std::string & filename, int globalProgressEn filesize = CMTDInfo::getInstance()->getMTDSize(mtdDevice); - unsigned char * buf = new unsigned char[meminfo.writesize]; - if (buf == NULL) { - printf("CFlashTool::program: mem alloc failed\n"); - close(fd); - close(fd1); - return false; - } + unsigned char buf[meminfo.writesize]; unsigned mtdoffset = 0; long fsize = filesize; while(fsize > 0) { @@ -153,7 +153,6 @@ bool CFlashTool::readFromMTD( const std::string & filename, int globalProgressEn if(statusViewer) statusViewer->showLocalStatus(100); - delete[] buf; close(fd); close(fd1); return true; @@ -165,6 +164,8 @@ bool CFlashTool::program( const std::string & filename, int globalProgressEndEra ssize_t filesize; int globalProgressBegin = 0; + CNeutrinoApp::getInstance()->saveEpg(false); + if(statusViewer) statusViewer->showLocalStatus(0); @@ -173,7 +174,32 @@ bool CFlashTool::program( const std::string & filename, int globalProgressEndEra return false; } - if( (fd1 = open( filename.c_str(), O_RDONLY )) < 0 ) { + char buf1[1024]; + memset(buf1, 0, sizeof(buf1)); + strncpy(buf1, filename.c_str(), sizeof(buf1)-1); + char* dn = dirname(buf1); + std::string flashfile; + if (strcmp(dn, "/tmp") != 0) { + memset(buf1, 0, sizeof(buf1)); + strncpy(buf1, filename.c_str(), sizeof(buf1)-1); + flashfile = (std::string)"/tmp/" + basename(buf1); + CFileHelpers fh; + printf("##### [CFlashTool::program] copy flashfile to %s\n", flashfile.c_str()); + if(statusViewer) + statusViewer->showStatusMessageUTF("Copy Image"); + fh.copyFile(filename.c_str(), flashfile.c_str(), 0644); + sync(); + if(statusViewer) + statusViewer->showGlobalStatus(statusViewer->getGlobalStatus()+5); + } + else + flashfile = filename; + + // Unmount all NFS & CIFS volumes + nfs_mounted_once = false; + CFSMounter::umount(); + + if( (fd1 = open( flashfile.c_str(), O_RDONLY )) < 0 ) { ErrorMessage = g_Locale->getText(LOCALE_FLASHUPDATE_CANTOPENFILE); return false; } @@ -200,10 +226,12 @@ bool CFlashTool::program( const std::string & filename, int globalProgressEndEra if(statusViewer) { if(globalProgressEndErase!=-1) statusViewer->showGlobalStatus(globalProgressEndErase); - statusViewer->showLocalStatus(0); statusViewer->showStatusMessageUTF(g_Locale->getText(LOCALE_FLASHUPDATE_PROGRAMMINGFLASH)); // UTF-8 } +#ifndef VFD_UPDATE + CVFD::getInstance()->ShowText("Write Flash"); +#endif if( (fd = open( mtdDevice.c_str(), O_WRONLY )) < 0 ) { ErrorMessage = g_Locale->getText(LOCALE_FLASHUPDATE_CANTOPENMTD); @@ -214,16 +242,10 @@ bool CFlashTool::program( const std::string & filename, int globalProgressEndEra if(statusViewer) globalProgressBegin = statusViewer->getGlobalStatus(); - unsigned char * buf = new unsigned char[meminfo.writesize]; - if (buf == NULL) { - printf("CFlashTool::program: mem alloc failed\n"); - close(fd); - close(fd1); - return false; - } + unsigned char buf[meminfo.writesize]; unsigned mtdoffset = 0; unsigned fsize = filesize; - printf("CFlashTool::program: file %s write size %d, erase size %d\n", filename.c_str(), meminfo.writesize, meminfo.erasesize); + printf("CFlashTool::program: file %s write size %d, erase size %d\n", flashfile.c_str(), meminfo.writesize, meminfo.erasesize); while(fsize > 0) { unsigned block = meminfo.writesize; if (block > fsize) @@ -231,7 +253,7 @@ bool CFlashTool::program( const std::string & filename, int globalProgressEndEra unsigned res = read(fd1, buf, block); if (res != block) { - printf("CFlashTool::program: read from %s failed: %d from %d\n", filename.c_str(), res, block); + printf("CFlashTool::program: read from %s failed: %d from %d\n", flashfile.c_str(), res, block); } if (isnand) { if (block < (unsigned) meminfo.writesize) { @@ -273,12 +295,12 @@ bool CFlashTool::program( const std::string & filename, int globalProgressEndEra if(statusViewer) statusViewer->showLocalStatus(100); - delete[] buf; close(fd1); close(fd); // FIXME error message if (fsize) return false; + CVFD::getInstance()->ShowText("Flash OK."); return true; } @@ -293,7 +315,7 @@ bool CFlashTool::getInfo() meminfo.writesize = 1024; isnand = (meminfo.type == MTD_NANDFLASH); - printf("CFlashTool::getInfo: NAND: %s\n", isnand ? "yes" : "no"); + printf("CFlashTool::getInfo: NAND: %s writesize %d\n", isnand ? "yes" : "no", meminfo.writesize); return true; } @@ -314,8 +336,18 @@ bool CFlashTool::erase(int globalProgressEnd) return false; } - if(statusViewer) + CNeutrinoApp::getInstance()->stopDaemonsForFlash(); + +#ifndef VFD_UPDATE + CVFD::getInstance()->ShowText("Erase Flash"); +#endif + + if(statusViewer) { globalProgressBegin = statusViewer->getGlobalStatus(); + statusViewer->paint(); + statusViewer->showLocalStatus(0); + statusViewer->showGlobalStatus(globalProgressBegin); + } lerase.length = meminfo.erasesize; @@ -342,17 +374,15 @@ bool CFlashTool::erase(int globalProgressEnd) continue; } } - if(ioctl( fd, MEMERASE, &lerase) != 0) { ErrorMessage = g_Locale->getText(LOCALE_FLASHUPDATE_ERASEFAILED); close(fd); return false; } - printf( "Erasing %u Kbyte @ %x -- %2u %% complete.\n", - meminfo.erasesize/1024, lerase.start, - prog /* lerase.start*100/meminfo.size */); + printf( "Erasing %u Kbyte @ 0x%08X -- %2u %% complete.\n", meminfo.erasesize/1024, lerase.start, prog); } + printf("\n"); close(fd); return true; @@ -389,7 +419,6 @@ bool CFlashTool::check_md5( const std::string & filename, const std::string & sm void CFlashTool::reboot() { - ::sync(); ::reboot(RB_AUTOBOOT); ::exit(0); } diff --git a/src/system/fsmounter.cpp b/src/system/fsmounter.cpp index 28e35a523..a6bfb93b3 100644 --- a/src/system/fsmounter.cpp +++ b/src/system/fsmounter.cpp @@ -159,16 +159,12 @@ bool CFSMounter::isMounted(const char * const local_dir) std::ifstream in; if (local_dir == NULL) return false; - - // according to the man page realpath() sucks, but there's nothing better :( - int path_max = 0; #ifdef PATH_MAX - path_max = PATH_MAX; + char mount_point[PATH_MAX]; #else - path_max = 4096; + char mount_point[4096]; #endif - char mount_point[path_max]; if (realpath(local_dir, mount_point) == NULL) { printf("[CFSMounter] could not resolve dir: %s: %s\n",local_dir, strerror(errno)); return false; diff --git a/src/system/locals.h b/src/system/locals.h index 26153123e..e9aff93c9 100644 --- a/src/system/locals.h +++ b/src/system/locals.h @@ -125,6 +125,7 @@ typedef enum LOCALE_GENRE_UNKNOWN, LOCALE_APIDSELECTOR_HEAD, LOCALE_AUDIO_SRS_ALGO, + LOCALE_AUDIO_SRS_ALGO_HEAVY, LOCALE_AUDIO_SRS_ALGO_LIGHT, LOCALE_AUDIO_SRS_ALGO_NORMAL, LOCALE_AUDIO_SRS_IQ, @@ -506,6 +507,8 @@ typedef enum LOCALE_FLASHUPDATE_HEAD, LOCALE_FLASHUPDATE_MD5CHECK, LOCALE_FLASHUPDATE_MD5SUMERROR, + LOCALE_FLASHUPDATE_MENU_APPLY_KERNEL, + LOCALE_FLASHUPDATE_MENU_APPLY_SETTINGS, LOCALE_FLASHUPDATE_MSGBOX, LOCALE_FLASHUPDATE_MSGBOX_MANUAL, LOCALE_FLASHUPDATE_MTDSELECTOR, @@ -620,6 +623,7 @@ typedef enum LOCALE_IMAGEINFO_IMAGE, LOCALE_IMAGEINFO_KERNEL, LOCALE_IMAGEINFO_LICENSE, + LOCALE_IMAGEINFO_VCS, LOCALE_IMAGEINFO_VERSION, LOCALE_INETRADIO_NAME, LOCALE_INFOVIEWER_EPGNOTLOAD, @@ -805,6 +809,7 @@ typedef enum LOCALE_MENU_HINT_EPG_OLD_EVENTS, LOCALE_MENU_HINT_EPG_SAVE, LOCALE_MENU_HINT_EPG_SAVE_STANDBY, + LOCALE_MENU_HINT_EPG_SCAN, LOCALE_MENU_HINT_EVENT_TEXTCOLOR, LOCALE_MENU_HINT_EVENTLIST_ADDITIONAL, LOCALE_MENU_HINT_EVENTLIST_FONTS, @@ -883,6 +888,7 @@ typedef enum LOCALE_MENU_HINT_KEY_MPPLUGIN, LOCALE_MENU_HINT_KEY_MPREWIND, LOCALE_MENU_HINT_KEY_MPSTOP, + LOCALE_MENU_HINT_KEY_MPSUBTITLE, LOCALE_MENU_HINT_KEY_MPTIME, LOCALE_MENU_HINT_KEY_MPTIMESHIFT, LOCALE_MENU_HINT_KEY_PAGEDOWN, @@ -1143,6 +1149,7 @@ typedef enum LOCALE_MENU_HINT_VOLUME, LOCALE_MENU_HINT_VOLUME_DIGITS, LOCALE_MENU_HINT_VOLUME_POS, + LOCALE_MENU_HINT_YTPLAY, LOCALE_MENU_HINT_ZAP_CYCLE, LOCALE_MENU_NEXT, LOCALE_MESSAGEBOX_BACK, @@ -1176,6 +1183,7 @@ typedef enum LOCALE_MISCSETTINGS_EPG_OLD_EVENTS_HINT2, LOCALE_MISCSETTINGS_EPG_SAVE, LOCALE_MISCSETTINGS_EPG_SAVE_STANDBY, + LOCALE_MISCSETTINGS_EPG_SCAN, LOCALE_MISCSETTINGS_GENERAL, LOCALE_MISCSETTINGS_HEAD, LOCALE_MISCSETTINGS_INFOBAR, @@ -1378,6 +1386,22 @@ typedef enum LOCALE_MOVIEBROWSER_USE_DIR, LOCALE_MOVIEBROWSER_USE_MOVIE_DIR, LOCALE_MOVIEBROWSER_USE_REC_DIR, + LOCALE_MOVIEBROWSER_YT_ERROR, + LOCALE_MOVIEBROWSER_YT_MAX_RESULTS, + LOCALE_MOVIEBROWSER_YT_MOST_DISCUSSED, + LOCALE_MOVIEBROWSER_YT_MOST_POPULAR, + LOCALE_MOVIEBROWSER_YT_MOST_RESENT, + LOCALE_MOVIEBROWSER_YT_MOST_RESPONDED, + LOCALE_MOVIEBROWSER_YT_MOST_SHARED, + LOCALE_MOVIEBROWSER_YT_NEXT_RESULTS, + LOCALE_MOVIEBROWSER_YT_ON_THE_WEB, + LOCALE_MOVIEBROWSER_YT_PREV_RESULTS, + LOCALE_MOVIEBROWSER_YT_RECENTLY_FEATURED, + LOCALE_MOVIEBROWSER_YT_REGION, + LOCALE_MOVIEBROWSER_YT_RELATED, + LOCALE_MOVIEBROWSER_YT_SEARCH, + LOCALE_MOVIEBROWSER_YT_TOP_FAVORITES, + LOCALE_MOVIEBROWSER_YT_TOP_RATED, LOCALE_MOVIEPLAYER_BOOKMARK, LOCALE_MOVIEPLAYER_BOOKMARKNAME, LOCALE_MOVIEPLAYER_BOOKMARKNAME_HINT1, @@ -1399,6 +1423,7 @@ typedef enum LOCALE_MOVIEPLAYER_TSHELP8, LOCALE_MOVIEPLAYER_TSHELP9, LOCALE_MOVIEPLAYER_TSPLAYBACK, + LOCALE_MOVIEPLAYER_YTPLAYBACK, LOCALE_MPKEY_AUDIO, LOCALE_MPKEY_BOOKMARK, LOCALE_MPKEY_FORWARD, @@ -1407,6 +1432,7 @@ typedef enum LOCALE_MPKEY_PLUGIN, LOCALE_MPKEY_REWIND, LOCALE_MPKEY_STOP, + LOCALE_MPKEY_SUBTITLE, LOCALE_MPKEY_TIME, LOCALE_NETWORKMENU_APPLY_SETTINGS, LOCALE_NETWORKMENU_APPLY_SETTINGS_NOW, @@ -1742,6 +1768,7 @@ typedef enum LOCALE_SETTINGS_POS_BOTTOM_LEFT, LOCALE_SETTINGS_POS_BOTTOM_RIGHT, LOCALE_SETTINGS_POS_DEFAULT_CENTER, + LOCALE_SETTINGS_POS_HIGHER_CENTER, LOCALE_SETTINGS_POS_TOP_CENTER, LOCALE_SETTINGS_POS_TOP_LEFT, LOCALE_SETTINGS_POS_TOP_RIGHT, @@ -1859,6 +1886,7 @@ typedef enum LOCALE_TIMING_INFOBAR_RADIO, LOCALE_TIMING_MENU, LOCALE_TIMING_NUMERICZAP, + LOCALE_TIMING_VOLUMEBAR, LOCALE_UNICABLE_LNB, LOCALE_UNICABLE_QRG, LOCALE_UNICABLE_SCR, diff --git a/src/system/locals_intern.h b/src/system/locals_intern.h index dfae5e5f4..84e7587ee 100644 --- a/src/system/locals_intern.h +++ b/src/system/locals_intern.h @@ -125,6 +125,7 @@ const char * locale_real_names[] = "GENRE.UNKNOWN", "apidselector.head", "audio.srs_algo", + "audio.srs_algo_heavy", "audio.srs_algo_light", "audio.srs_algo_normal", "audio.srs_iq", @@ -506,6 +507,8 @@ const char * locale_real_names[] = "flashupdate.head", "flashupdate.md5check", "flashupdate.md5sumerror", + "flashupdate.menu_apply_kernel", + "flashupdate.menu_apply_settings", "flashupdate.msgbox", "flashupdate.msgbox_manual", "flashupdate.mtdselector", @@ -620,6 +623,7 @@ const char * locale_real_names[] = "imageinfo.image", "imageinfo.kernel", "imageinfo.license", + "imageinfo.vcs", "imageinfo.version", "inetradio.name", "infoviewer.epgnotload", @@ -805,6 +809,7 @@ const char * locale_real_names[] = "menu.hint_epg_old_events", "menu.hint_epg_save", "menu.hint_epg_save_standby", + "menu.hint_epg_scan", "menu.hint_event_textcolor", "menu.hint_eventlist_additional", "menu.hint_eventlist_fonts", @@ -883,6 +888,7 @@ const char * locale_real_names[] = "menu.hint_key_mpplugin", "menu.hint_key_mprewind", "menu.hint_key_mpstop", + "menu.hint_key_mpsubtitle", "menu.hint_key_mptime", "menu.hint_key_mptimeshift", "menu.hint_key_pagedown", @@ -1143,6 +1149,7 @@ const char * locale_real_names[] = "menu.hint_volume", "menu.hint_volume_digits", "menu.hint_volume_pos", + "menu.hint_ytplay", "menu.hint_zap_cycle", "menu.next", "messagebox.back", @@ -1176,6 +1183,7 @@ const char * locale_real_names[] = "miscsettings.epg_old_events_hint2", "miscsettings.epg_save", "miscsettings.epg_save_standby", + "miscsettings.epg_scan", "miscsettings.general", "miscsettings.head", "miscsettings.infobar", @@ -1378,6 +1386,22 @@ const char * locale_real_names[] = "moviebrowser.use_dir", "moviebrowser.use_movie_dir", "moviebrowser.use_rec_dir", + "moviebrowser.yt_error", + "moviebrowser.yt_max_results", + "moviebrowser.yt_most_discussed", + "moviebrowser.yt_most_popular", + "moviebrowser.yt_most_resent", + "moviebrowser.yt_most_responded", + "moviebrowser.yt_most_shared", + "moviebrowser.yt_next_results", + "moviebrowser.yt_on_the_web", + "moviebrowser.yt_prev_results", + "moviebrowser.yt_recently_featured", + "moviebrowser.yt_region", + "moviebrowser.yt_related", + "moviebrowser.yt_search", + "moviebrowser.yt_top_favorites", + "moviebrowser.yt_top_rated", "movieplayer.bookmark", "movieplayer.bookmarkname", "movieplayer.bookmarkname_hint1", @@ -1399,6 +1423,7 @@ const char * locale_real_names[] = "movieplayer.tshelp8", "movieplayer.tshelp9", "movieplayer.tsplayback", + "movieplayer.ytplayback", "mpkey.audio", "mpkey.bookmark", "mpkey.forward", @@ -1407,6 +1432,7 @@ const char * locale_real_names[] = "mpkey.plugin", "mpkey.rewind", "mpkey.stop", + "mpkey.subtitle", "mpkey.time", "networkmenu.apply_settings", "networkmenu.apply_settings_now", @@ -1742,6 +1768,7 @@ const char * locale_real_names[] = "settings.pos_bottom_left", "settings.pos_bottom_right", "settings.pos_default_center", + "settings.pos_higher_center", "settings.pos_top_center", "settings.pos_top_left", "settings.pos_top_right", @@ -1859,6 +1886,7 @@ const char * locale_real_names[] = "timing.infobar_radio", "timing.menu", "timing.numericzap", + "timing.volumebar", "unicable.lnb", "unicable.qrg", "unicable.scr", diff --git a/src/system/settings.cpp b/src/system/settings.cpp index 1f75181e6..d848aec29 100644 --- a/src/system/settings.cpp +++ b/src/system/settings.cpp @@ -92,6 +92,7 @@ const struct personalize_settings_t personalize_settings[SNeutrinoSettings::P_SE //media menu->movieplayer {"personalize_mplayer_mbrowswer" , CPersonalizeGui::PERSONALIZE_MODE_VISIBLE}, {"personalize_mplayer_fileplay" , CPersonalizeGui::PERSONALIZE_MODE_VISIBLE}, + {"personalize_mplayer_ytplay" , CPersonalizeGui::PERSONALIZE_MODE_VISIBLE}, //key {"personalize_feat_key_fav" , CPersonalizeGui::PERSONALIZE_FEAT_KEY_GREEN}, diff --git a/src/system/settings.h b/src/system/settings.h index 2aca3223a..706dbdf13 100644 --- a/src/system/settings.h +++ b/src/system/settings.h @@ -147,6 +147,7 @@ struct SNeutrinoSettings std::string epg_max_events; std::string epg_extendedcache; std::string epg_dir; + int epg_scan; //network std::string network_ntpserver; @@ -218,6 +219,7 @@ struct SNeutrinoSettings //movieplayer menu P_MPLAYER_MBROWSER, P_MPLAYER_FILEPLAY, + P_MPLAYER_YTPLAY, //feature keys P_FEAT_KEY_FAVORIT, @@ -237,15 +239,15 @@ struct SNeutrinoSettings //timing enum TIMING_SETTINGS { - TIMING_MENU = 0, - TIMING_CHANLIST = 1, - TIMING_EPG = 2, - TIMING_INFOBAR = 3, - TIMING_INFOBAR_RADIO = 4, - TIMING_INFOBAR_MOVIE = 5, -// TIMING_VOLUMEBAR, - TIMING_FILEBROWSER = 6, - TIMING_NUMERICZAP = 7, + TIMING_MENU = 0, + TIMING_CHANLIST = 1, + TIMING_EPG = 2, + TIMING_INFOBAR = 3, + TIMING_INFOBAR_RADIO = 4, + TIMING_INFOBAR_MOVIE = 5, + TIMING_VOLUMEBAR = 6, + TIMING_FILEBROWSER = 7, + TIMING_NUMERICZAP = 8, TIMING_SETTING_COUNT }; @@ -398,6 +400,7 @@ struct SNeutrinoSettings int mpkey_time; int mpkey_bookmark; int mpkey_plugin; + int mpkey_subtitle; int key_timeshift; int key_plugin; @@ -475,6 +478,8 @@ struct SNeutrinoSettings char softupdate_proxyserver[31]; char softupdate_proxyusername[31]; char softupdate_proxypassword[31]; + int apply_settings; + int apply_kernel; //BouquetHandling int bouquetlist_mode; @@ -652,7 +657,7 @@ const time_settings_struct_t timing_setting[SNeutrinoSettings::TIMING_SETTING_CO { 6, LOCALE_TIMING_INFOBAR }, { 0, LOCALE_TIMING_INFOBAR_RADIO }, { 6, LOCALE_TIMING_INFOBAR_MOVIEPLAYER}, -// { 3, LOCALE_TIMING_VOLUMEBAR }, + { 3, LOCALE_TIMING_VOLUMEBAR }, { 60, LOCALE_TIMING_FILEBROWSER }, { 3, LOCALE_TIMING_NUMERICZAP } }; diff --git a/src/system/ytparser.cpp b/src/system/ytparser.cpp new file mode 100644 index 000000000..012684e77 --- /dev/null +++ b/src/system/ytparser.cpp @@ -0,0 +1,608 @@ +/* + Copyright (C) 2013 CoolStream International Ltd + + License: GPLv2 + + 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; + + 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., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include "ytparser.h" + +#if LIBCURL_VERSION_NUM < 0x071507 +#include +#endif + +#define URL_TIMEOUT 60 + +std::string cYTVideoUrl::GetUrl() +{ + std::string fullurl = url; + fullurl += "&signature="; + fullurl += sig; + return fullurl; +} + +void cYTVideoInfo::Dump() +{ + printf("id: %s\n", id.c_str()); + printf("author: %s\n", author.c_str()); + printf("title: %s\n", title.c_str()); + printf("duration: %d\n", duration); + //printf("description: %s\n", description.c_str()); + printf("urls: %d\n", formats.size()); + for (yt_urlmap_iterator_t it = formats.begin(); it != formats.end(); ++it) { + printf("format %d type [%s] url %s\n", it->first, it->second.type.c_str(), it->second.GetUrl().c_str()); + } + printf("===================================================================\n"); +} + +std::string cYTVideoInfo::GetUrl(int fmt) +{ + yt_urlmap_iterator_t it; + if (fmt) { + if ((it = formats.find(fmt)) != formats.end()) + return it->second.GetUrl(); + return ""; + } + if ((it = formats.find(37)) != formats.end()) + return it->second.GetUrl(); + if ((it = formats.find(22)) != formats.end()) + return it->second.GetUrl(); + if ((it = formats.find(18)) != formats.end()) + return it->second.GetUrl(); + return ""; +} + +cYTFeedParser::cYTFeedParser() +{ + thumbnail_dir = "/tmp/ytparser"; + parsed = false; + feedmode = -1; + tquality = "mqdefault"; + max_results = 25; +} + +cYTFeedParser::~cYTFeedParser() +{ +} + +size_t cYTFeedParser::CurlWriteToString(void *ptr, size_t size, size_t nmemb, void *data) +{ + std::string* pStr = (std::string*) data; + pStr->append((char*) ptr, nmemb); + return size*nmemb; +} + +bool cYTFeedParser::getUrl(std::string &url, std::string &answer) +{ + CURL * curl_handle = curl_easy_init(); + curl_easy_setopt(curl_handle, CURLOPT_URL, url.c_str()); + curl_easy_setopt(curl_handle, CURLOPT_WRITEFUNCTION, &cYTFeedParser::CurlWriteToString); + curl_easy_setopt(curl_handle, CURLOPT_FILE, (void *)&answer); + curl_easy_setopt(curl_handle, CURLOPT_FAILONERROR, 1); + curl_easy_setopt(curl_handle, CURLOPT_TIMEOUT, URL_TIMEOUT); + curl_easy_setopt(curl_handle, CURLOPT_NOSIGNAL, (long)1); + + char cerror[CURL_ERROR_SIZE]; + curl_easy_setopt(curl_handle, CURLOPT_ERRORBUFFER, cerror); + + printf("try to get [%s] ...\n", url.c_str()); + CURLcode httpres = curl_easy_perform(curl_handle); + + curl_easy_cleanup(curl_handle); + + printf("http: res %d size %d\n", httpres, answer.size()); + + if (httpres != 0 || answer.empty()) { + printf("error: %s\n", cerror); + return false; + } + return true; +} + +bool cYTFeedParser::DownloadUrl(std::string &url, std::string &file) +{ + FILE * fp = fopen(file.c_str(), "wb"); + if (fp == NULL) { + perror(file.c_str()); + return false; + } + CURL * curl_handle = curl_easy_init(); + curl_easy_setopt(curl_handle, CURLOPT_URL, url.c_str()); + curl_easy_setopt(curl_handle, CURLOPT_FILE, fp); + curl_easy_setopt(curl_handle, CURLOPT_FAILONERROR, 1); + curl_easy_setopt(curl_handle, CURLOPT_TIMEOUT, URL_TIMEOUT); + curl_easy_setopt(curl_handle, CURLOPT_NOSIGNAL, (long)1); + + char cerror[CURL_ERROR_SIZE]; + curl_easy_setopt(curl_handle, CURLOPT_ERRORBUFFER, cerror); + + printf("try to get [%s] ...\n", url.c_str()); + CURLcode httpres = curl_easy_perform(curl_handle); + + double dsize; + curl_easy_getinfo(curl_handle, CURLINFO_SIZE_DOWNLOAD, &dsize); + curl_easy_cleanup(curl_handle); + fclose(fp); + + printf("http: res %d size %f.\n", httpres, dsize); + + if (httpres != 0) { + printf("curl error: %s\n", cerror); + unlink(file.c_str()); + return false; + } + return true; +} + +void cYTFeedParser::decodeUrl(std::string &url) +{ + CURL * curl_handle = curl_easy_init(); + char * str = curl_easy_unescape(curl_handle, url.c_str(), 0, NULL); + curl_easy_cleanup(curl_handle); + if(str) + url = str; + curl_free(str); +} + +void cYTFeedParser::encodeUrl(std::string &txt) +{ + CURL * curl_handle = curl_easy_init(); + char * str = curl_easy_escape(curl_handle, txt.c_str(), txt.length()); + curl_easy_cleanup(curl_handle); + if(str) + txt = str; + curl_free(str); +} + +void cYTFeedParser::splitString(std::string &str, std::string delim, std::vector &strlist, int start) +{ + strlist.clear(); + unsigned int end = 0; + while ((end = str.find(delim, start)) != std::string::npos) { + strlist.push_back(str.substr(start, end - start)); + start = end + delim.size(); + } + strlist.push_back(str.substr(start)); +} + +void cYTFeedParser::splitString(std::string &str, std::string delim, std::map &strmap, int start) +{ + unsigned int end = 0; + if ((end = str.find(delim, start)) != std::string::npos) { + strmap[str.substr(start, end - start)] = str.substr(end - start + delim.size()); + } +} + +bool cYTFeedParser::saveToFile(const char * name, std::string str) +{ + FILE * fp = fopen(name, "w+"); + if (fp) { + fprintf(fp, "%s", str.c_str()); + fclose(fp); + return false; + } + printf("cYTFeedParser::saveToFile: failed to open %s\n", name); + return false; +} + +std::string cYTFeedParser::getXmlName(xmlNodePtr node) +{ + std::string result; + char * name = xmlGetName(node); + if (name) + result = name; + return result; +} + +std::string cYTFeedParser::getXmlAttr(xmlNodePtr node, const char * attr) +{ + std::string result; + char * value = xmlGetAttribute(node, attr); + if (value) + result = value; + return result; +} + +std::string cYTFeedParser::getXmlData(xmlNodePtr node) +{ + std::string result; + char * value = xmlGetData(node); + if (value) + result = value; + return result; +} + +bool cYTFeedParser::parseFeedXml(std::string &answer) +{ + xmlDocPtr answer_parser = parseXmlFile(curfeedfile.c_str()); + if (answer_parser == NULL) + answer_parser = parseXml(answer.c_str()); + + if (answer_parser == NULL) { + printf("failed to parse xml\n"); + return false; + } + next.clear(); + prev.clear(); + total.clear(); + start.clear(); + xmlNodePtr entry = xmlDocGetRootElement(answer_parser)->xmlChildrenNode; + while (entry) { + std::string name = getXmlName(entry); +#ifdef DEBUG_PARSER + printf("entry: %s\n", name.c_str()); +#endif + if (name == "openSearch:startIndex") { + start = getXmlData(entry); + printf("start %s\n", start.c_str()); + } else if (name == "openSearch:totalResults") { + total = getXmlData(entry); + printf("total %s\n", total.c_str()); + } + else if (name == "link") { + std::string link = getXmlAttr(entry, "rel"); + if (link == "next") { + next = getXmlAttr(entry, "href"); + printf(" next [%s]\n", next.c_str()); + } else if (link == "previous") { + prev = getXmlAttr(entry, "href"); + printf(" prev [%s]\n", prev.c_str()); + } + } + else if (name != "entry") { + entry = entry->xmlNextNode; + continue; + } + xmlNodePtr node = entry->xmlChildrenNode; + cYTVideoInfo vinfo; + std::string thumbnail; + while (node) { + name = getXmlName(node); +#ifdef DEBUG_PARSER + printf(" node: %s\n", name.c_str()); +#endif + if (name == "title") { +#ifdef DEBUG_PARSER + printf(" title [%s]\n", getXmlData(node).c_str()); +#endif + vinfo.title = getXmlData(node); + } + else if (name == "published") { + vinfo.published = getXmlData(node).substr(0, 10); + } + else if (name == "author") { + xmlNodePtr author = node->xmlChildrenNode; + while(author) { + name = getXmlName(author); + if (name == "name") { +#ifdef DEBUG_PARSER + printf(" author [%s]\n", getXmlData(author).c_str()); +#endif + vinfo.author = getXmlData(author); + } + author = author->xmlNextNode; + } + } + else if (name == "media:group") { + xmlNodePtr media = node->xmlChildrenNode; + while (media) { + name = getXmlName(media); + if (name == "media:description") { + vinfo.description = getXmlData(media).c_str(); + } + else if (name == "media:category") { + if (vinfo.category.size() < 3) + vinfo.category = getXmlData(media).c_str(); + } + else if (name == "yt:videoid") { +#ifdef DEBUG_PARSER + printf(" id [%s]\n", getXmlData(media).c_str()); +#endif + vinfo.id = getXmlData(media).c_str(); + } + else if (name == "media:thumbnail") { + /* save first found */ + if (thumbnail.empty()) + thumbnail = getXmlAttr(media, "url"); + + /* check wanted quality */ + if (tquality == getXmlAttr(media, "yt:name")) { + vinfo.thumbnail = getXmlAttr(media, "url"); +#ifdef DEBUG_PARSER + printf("vinfo.thumbnail [%s]\n", vinfo.thumbnail.c_str()); +#endif + } + } + else if (name == "yt:duration") { + vinfo.duration = atoi(getXmlAttr(media, "seconds").c_str()); + } +#if 0 + else if (name == "media:player") { + std::string url = getXmlAttr(media, "url"); + printf(" media:player [%s]\n", url.c_str()); + } + else if (name == "media:title") { + } +#endif + media = media->xmlNextNode; + } + } + node = node->xmlNextNode; + } + if (!vinfo.id.empty()) { + /* save first one, if wanted not found */ + if (vinfo.thumbnail.empty()) + vinfo.thumbnail = thumbnail; + if (ParseVideoInfo(vinfo)) + videos.push_back(vinfo); + } + entry = entry->xmlNextNode; + } + xmlFreeDoc(answer_parser); + parsed = !videos.empty(); + return parsed; +} + +bool cYTFeedParser::supportedFormat(int fmt) +{ + if((fmt == 37) || (fmt == 22) || (fmt == 18)) + return true; + return false; +} + +bool cYTFeedParser::decodeVideoInfo(std::string &answer, cYTVideoInfo &vinfo) +{ + bool ret = false; + decodeUrl(answer); +#if 0 + std::string infofile = thumbnail_dir; + infofile += "/"; + infofile += vinfo.id; + infofile += ".txt" + saveToFile(infofile.c_str(), answer); +#endif + if(answer.find("token=") == std::string::npos) + return ret; + + //FIXME check expire + std::vector ulist; + unsigned fmt = answer.find("url_encoded_fmt_stream_map="); + if (fmt != std::string::npos) { + fmt = answer.find("=", fmt); + splitString(answer, ",", ulist, fmt+1); + for (unsigned i = 0; i < ulist.size(); i++) { +#if 0 // to decode all params + decodeUrl(ulist[i]); + printf("URL: %s\n", ulist[i].c_str()); +#endif + std::map smap; + std::vector uparams; + splitString(ulist[i], "&", uparams); + if (uparams.size() < 3) + continue; + for (unsigned j = 0; j < uparams.size(); j++) { + decodeUrl(uparams[j]); +#ifdef DEBUG_PARSER + printf(" param: %s\n", uparams[j].c_str()); +#endif + splitString(uparams[j], "=", smap); + } +#ifdef DEBUG_PARSER + printf("=========================================================\n"); +#endif + cYTVideoUrl yurl; + yurl.url = smap["url"]; + yurl.sig = smap["sig"]; + int id = atoi(smap["itag"].c_str()); + if (supportedFormat(id) && !yurl.url.empty() && !yurl.sig.empty()) { + yurl.quality = smap["quality"]; + yurl.type = smap["type"]; + vinfo.formats.insert(yt_urlmap_pair_t(id, yurl)); + ret = true; + } + } + } + return ret; +} + +bool cYTFeedParser::ParseFeed(std::string &url) +{ + videos.clear(); + + std::string answer; + curfeedfile = thumbnail_dir; + curfeedfile += "/"; + curfeedfile += curfeed; + curfeedfile += ".xml"; +#ifdef CACHE_FILES + if(!DownloadUrl(url, cfile)) + return false; +#else + if (!getUrl(url, answer)) + return false; +#endif + return parseFeedXml(answer); +} + +bool cYTFeedParser::ParseFeed(yt_feed_mode_t mode, std::string search, std::string vid) +{ + std::string url = "http://gdata.youtube.com/feeds/api/standardfeeds/"; + bool append_res = true; + if (mode < FEED_LAST) { + switch(mode) { + case TOP_RATED: + curfeed = "top_rated"; + break; + case TOP_FAVORITES: + curfeed = "top_favorites"; + break; + case MOST_SHARED: + curfeed = "most_shared"; + break; + case MOST_POPULAR: + default: + curfeed = "most_popular"; + break; + case MOST_RESENT: + curfeed = "most_recent"; + break; + case MOST_DISCUSSED: + curfeed = "most_discussed"; + break; + case MOST_RESPONDED: + curfeed = "most_responded"; + break; + case RECENTLY_FEATURED: + curfeed = "recently_featured"; + break; + case ON_THE_WEB: + curfeed = "on_the_web"; + break; + } + if (!region.empty()) { + url += region; + url += "/"; + } + url += curfeed; + url += "?"; + } + else if (mode == NEXT) { + if (next.empty()) + return false; + url = next; + append_res = false; + } + else if (mode == PREV) { + if (prev.empty()) + return false; + url = prev; + append_res = false; + } + else if (mode == RELATED) { + if (vid.empty()) + return false; + url = "http://gdata.youtube.com/feeds/api/videos/"; + url += vid; + url += "/related?"; + } + else if (mode == SEARCH) { + if (search.empty()) + return false; + encodeUrl(search); + url = "http://gdata.youtube.com/feeds/api/videos?q="; + url += search; + url += "&"; + } + + feedmode = mode; + if (append_res) { + url += "v=2&max-results="; + char res[10]; + sprintf(res, "%d", max_results); + url+= res; + } + + return ParseFeed(url); +} + +bool cYTFeedParser::ParseVideoInfo(cYTVideoInfo &vinfo) +{ + bool ret = false; + std::vector estr; + estr.push_back("&el=embedded"); + estr.push_back("&el=vevo"); + estr.push_back("&el=detailpage"); + + for (unsigned i = 0; i < estr.size(); i++) { + std::string vurl = "http://www.youtube.com/get_video_info?video_id="; + vurl += vinfo.id; + vurl += estr[i]; + vurl += "&ps=default&eurl=&gl=US&hl=en"; + printf("cYTFeedParser::ParseVideoInfo: get [%s]\n", vurl.c_str()); + std::string answer; + if (!getUrl(vurl, answer)) + continue; + ret = decodeVideoInfo(answer, vinfo); + if (ret) + break; + } + return ret; +} + +bool cYTFeedParser::DownloadThumbnails() +{ + bool ret = false; + if (mkdir(thumbnail_dir.c_str(), 0755)) { + perror(thumbnail_dir.c_str()); + //return ret; + } + for (unsigned i = 0; i < videos.size(); i++) { + if (!videos[i].thumbnail.empty()) { + std::string fname = thumbnail_dir; + fname += "/"; + fname += videos[i].id; + fname += ".jpg"; + bool found = !access(fname.c_str(), F_OK); + if (!found) + found = DownloadUrl(videos[i].thumbnail, fname); + if (found) + videos[i].tfile = fname; + ret |= found; + } + } + return ret; +} + +bool cYTFeedParser::GetVideoUrls() +{ + bool ret = false; + for (unsigned i = 0; i < videos.size(); i++) { + ret |= ParseVideoInfo(videos[i]); + } + return ret; +} + +void cYTFeedParser::Cleanup(bool delete_thumbnails) +{ + printf("cYTFeedParser::Cleanup: %d videos\n", videos.size()); + if (delete_thumbnails) { + for (unsigned i = 0; i < videos.size(); i++) { + unlink(videos[i].tfile.c_str()); + } + } + unlink(curfeedfile.c_str()); + videos.clear(); + parsed = false; + feedmode = -1; +} + +void cYTFeedParser::Dump() +{ + printf("feed: %d videos\n", videos.size()); + for (unsigned i = 0; i < videos.size(); i++) + videos[i].Dump(); +} diff --git a/src/system/ytparser.h b/src/system/ytparser.h new file mode 100644 index 000000000..8978f7ef0 --- /dev/null +++ b/src/system/ytparser.h @@ -0,0 +1,143 @@ +/* + Copyright (C) 2013 CoolStream International Ltd + + License: GPLv2 + + 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; + + 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., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#ifndef __YT_PARSER__ +#define __YT_PARSER__ + +#include +#include + +#include +#include +#include +#include + +class cYTVideoUrl +{ + public: + std::string quality; + std::string type; + std::string sig; + std::string url; + + std::string GetUrl(); +}; + +typedef std::map yt_urlmap_t; +typedef std::pair yt_urlmap_pair_t; +typedef yt_urlmap_t::iterator yt_urlmap_iterator_t; + +class cYTVideoInfo +{ + public: + std::string id; + std::string title; + std::string author; + std::string description; + std::string category; + std::string thumbnail; + std::string tfile; + std::string published; + int duration; + yt_urlmap_t formats; + + void Dump(); + std::string GetUrl(int fmt = 0); + +}; + +typedef std::vector yt_video_list_t; + +class cYTFeedParser +{ + private: + std::string error; + std::string thumbnail_dir; + std::string curfeed; + std::string curfeedfile; + std::string tquality; // thumbnail size + std::string region; // more results + std::string next; // next results + std::string prev; // prev results + std::string start; // start index + std::string total; // total results + + int feedmode; + int max_results; + bool parsed; + yt_video_list_t videos; + + std::string getXmlName(xmlNodePtr node); + std::string getXmlAttr(xmlNodePtr node, const char * attr); + std::string getXmlData(xmlNodePtr node); + + static size_t CurlWriteToString(void *ptr, size_t size, size_t nmemb, void *data); + static void encodeUrl(std::string &txt); + static void decodeUrl(std::string &url); + static void splitString(std::string &str, std::string delim, std::vector &strlist, int start = 0); + static void splitString(std::string &str, std::string delim, std::map &strmap, int start = 0); + static bool saveToFile(const char * name, std::string str); + bool getUrl(std::string &url, std::string &answer); + bool DownloadUrl(std::string &url, std::string &file); + bool parseFeedXml(std::string &answer); + bool decodeVideoInfo(std::string &answer, cYTVideoInfo &vinfo); + bool supportedFormat(int fmt); + bool ParseFeed(std::string &url); + public: + enum yt_feed_mode_t + { + TOP_RATED, + TOP_FAVORITES, + MOST_SHARED, + MOST_POPULAR, + MOST_RESENT, + MOST_DISCUSSED, + MOST_RESPONDED, + RECENTLY_FEATURED, + ON_THE_WEB, + FEED_LAST, + NEXT, + PREV, + RELATED, + SEARCH, + MODE_LAST + }; + cYTFeedParser(); + ~cYTFeedParser(); + + bool ParseFeed(yt_feed_mode_t mode = MOST_POPULAR, std::string search = "", std::string vid = ""); + bool ParseVideoInfo(cYTVideoInfo &vinfo); + bool GetVideoUrls(); + bool DownloadThumbnails(); + void Dump(); + void Cleanup(bool delete_thumbnails = true); + + yt_video_list_t &GetVideoList() { return videos; } + bool Parsed() { return parsed; } + int GetFeedMode() { return feedmode; } + bool HaveNext(void) { return !next.empty(); } + bool HavePrev(void) { return !prev.empty(); } + std::string GetTotal(void) { return total; } + std::string GetError(void) { return error; } + + void SetRegion(std::string reg) { region = reg; } + void SetMaxResults(int count) { max_results = count; } +}; + +#endif diff --git a/src/timerd/timermanager.cpp b/src/timerd/timermanager.cpp index 3b11dfdec..a9bfa47e2 100644 --- a/src/timerd/timermanager.cpp +++ b/src/timerd/timermanager.cpp @@ -625,8 +625,8 @@ void CTimerManager::loadRecordingSafety() { /* set defaults if no configuration file exists */ dprintf("%s not found\n", CONFIGFILE); - m_extraTimeStart = 0; - m_extraTimeEnd = 0; + m_extraTimeStart = 300; + m_extraTimeEnd = 300; config.saveConfig(CONFIGFILE); } else diff --git a/src/zapit/include/zapit/scan.h b/src/zapit/include/zapit/scan.h index d12b0ab3e..0040e0624 100644 --- a/src/zapit/include/zapit/scan.h +++ b/src/zapit/include/zapit/scan.h @@ -55,7 +55,7 @@ class CServiceScan : public OpenThreads::Thread SCAN_TVRADIO = 0x60, SCAN_DATA = 0x80, SCAN_ALL = 0xE0, - SCAN_LOGICAL_HD = 0x100, + SCAN_LOGICAL_HD = 0x100 } scan_flags_t; private: diff --git a/src/zapit/include/zapit/scansdt.h b/src/zapit/include/zapit/scansdt.h index ac725cd08..2103930d9 100644 --- a/src/zapit/include/zapit/scansdt.h +++ b/src/zapit/include/zapit/scansdt.h @@ -28,7 +28,7 @@ #include #include -#define SDT_SECTION_SIZE 1026 +#define SDT_SECTION_SIZE 4096 class CSdt { diff --git a/src/zapit/include/zapit/zapit.h b/src/zapit/include/zapit/zapit.h index 231c80e63..ab38f7ba3 100644 --- a/src/zapit/include/zapit/zapit.h +++ b/src/zapit/include/zapit/zapit.h @@ -245,6 +245,7 @@ class CZapit : public OpenThreads::Thread void SetCurrentChannelID(const t_channel_id channel_id) { live_channel_id = channel_id; }; void SetLiveFrontend(CFrontend * fe) { if(fe) live_fe = fe; } CFrontend * GetLiveFrontend() { return live_fe; }; + CFrontend * GetPipFrontend() { return pip_fe; }; int GetPidVolume(t_channel_id channel_id, int pid, bool ac3 = false); void SetPidVolume(t_channel_id channel_id, int pid, int percent); diff --git a/src/zapit/src/Makefile.am b/src/zapit/src/Makefile.am index d8048a98c..5ec76ed42 100644 --- a/src/zapit/src/Makefile.am +++ b/src/zapit/src/Makefile.am @@ -29,7 +29,6 @@ libzapit_a_SOURCES = \ bouquets.cpp \ capmt.cpp \ channel.cpp \ - dvbstring.cpp \ femanager.cpp \ frontend.cpp \ getservices.cpp \ diff --git a/src/zapit/src/femanager.cpp b/src/zapit/src/femanager.cpp index 1dc4fd0bb..0c6b36a67 100644 --- a/src/zapit/src/femanager.cpp +++ b/src/zapit/src/femanager.cpp @@ -42,6 +42,8 @@ #include static int fedebug = 0; +static int unused_demux; + #define FEDEBUG(fmt, args...) \ do { \ if (fedebug) \ @@ -214,6 +216,9 @@ bool CFEManager::loadSettings() int def_mode0 = CFrontend::FE_MODE_INDEPENDENT; int def_modeX = CFrontend::FE_MODE_UNUSED; + if (cableOnly()) + def_modeX = CFrontend::FE_MODE_INDEPENDENT; + int newmode = (fe_mode_t) configfile.getInt32("mode", -1); if (newmode >= 0) { INFO("old mode param: %d\n", newmode); @@ -389,6 +394,7 @@ void CFEManager::linkFrontends(bool init) OpenThreads::ScopedLock m_lock(mutex); enabled_count = 0; have_sat = have_cable = have_terr = false; + unused_demux = 0; for(fe_map_iterator_t it = femap.begin(); it != femap.end(); it++) { CFrontend * fe = it->second; #if 0 @@ -450,8 +456,12 @@ void CFEManager::linkFrontends(bool init) else if (fe->isTerr()) have_terr = true; } - else /* unused -> no need to keep open */ + else { /* unused -> no need to keep open */ fe->Close(); + if (!unused_demux) { + unused_demux = fe->fenumber + 1; + } + } } } @@ -693,7 +703,7 @@ CFrontend * CFEManager::allocateFE(CZapitChannel * channel, bool forrecord) #ifdef ENABLE_PIP /* FIXME until proper demux management */ if (enabled_count < 4) { - channel->setPipDemux(PIP_DEMUX); + channel->setPipDemux(unused_demux ? unused_demux : PIP_DEMUX); //cDemux::SetSource(PIP_DEMUX, frontend->fenumber); } INFO("pip demux: %d", channel->getPipDemux()); @@ -727,12 +737,12 @@ CFrontend * CFEManager::getScanFrontend(t_satellite_position satellitePosition) for(fe_map_iterator_t it = femap.begin(); it != femap.end(); it++) { CFrontend * mfe = it->second; if (mfe->isCable()) { - if ((satellitePosition & 0xF00) == 0xF00) { + if ((mfe->getMode() != CFrontend::FE_MODE_UNUSED) && ((satellitePosition & 0xF00) == 0xF00)) { frontend = mfe; break; } } else if (mfe->isTerr()) { - if ((satellitePosition & 0xF00) == 0xE00) { + if ((mfe->getMode() != CFrontend::FE_MODE_UNUSED) && (satellitePosition & 0xF00) == 0xE00) { frontend = mfe; break; } diff --git a/src/zapit/src/zapit.cpp b/src/zapit/src/zapit.cpp index 53938868a..48482a235 100644 --- a/src/zapit/src/zapit.cpp +++ b/src/zapit/src/zapit.cpp @@ -690,7 +690,7 @@ bool CZapit::ZapForRecord(const t_channel_id channel_id) printf("zapit_to_record: channel_id " PRINTF_CHANNEL_ID_TYPE " not found", channel_id); return false; } - printf("%s: %s (%" PRIx64 ")\n", __FUNCTION__, newchannel->getName().c_str(), channel_id); + INFO("%s: %s (%" PRIx64 ")", __FUNCTION__, newchannel->getName().c_str(), channel_id); CFrontend * frontend = CFEManager::getInstance()->allocateFE(newchannel); if(frontend == NULL) {