MD5Final(dest, &ctx);
}
-void* init_md5()
+void* inititialize_md5()
{
MD5_CTX* ctx = malloc(sizeof(MD5_CTX));
memset(ctx, 0, sizeof(MD5_CTX));
char * crypt_md5(const char *pw, const char *salt);
void hash_md5(const unsigned char*buf, int len, unsigned char*dest); //dest needs to be 16 bytes wide
-void* init_md5();
+void* initialize_md5();
void update_md5(void*ctx, unsigned char*data, int len);
void finish_md5(void*ctx, unsigned char*dest);
#endif
int has_buttons = 0;
TAG*tag=swf->firstTag;
- void*md5 = init_md5();
+ void*md5 = initialize_md5();
while(tag) {
if(tag->id == ST_SHOWFRAME)
exit(1);
}
- void*md5 = init_md5();
+ void*md5 = initialize_md5();
int s,t;
gfxpolystroke_t*stroke = current_polygon->strokes;
--- /dev/null
+#!/usr/bin/env python
+# -*- coding: UTF-8 -*-
+#
+# gpdf2swf.py
+# graphical user interface for pdf2swf
+#
+# Part of the swftools package.
+#
+# Copyright (c) 2008,2009 Matthias Kramm <kramm@quiss.org>
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+
+from __future__ import division
+import os
+import wx
+import time
+import pickle
+
+from wx.lib.wordwrap import wordwrap
+from wx.lib.pubsub import Publisher
+
+from document import Document
+from gui import (PdfFrame, ProgressDialog, OptionsDialog, AboutDialog,
+ ID_INVERT_SELECTION, ID_SELECT_ODD, ID_SELECT_EVEN)
+
+
+def GetDataDir():
+ """
+ Return the standard location on this platform for application data
+ """
+ sp = wx.StandardPaths.Get()
+ return sp.GetUserDataDir()
+
+def GetConfig():
+ if not os.path.exists(GetDataDir()):
+ os.makedirs(GetDataDir())
+
+ config = wx.FileConfig(
+ localFilename=os.path.join(GetDataDir(), "options"))
+ return config
+
+
+class Pdf2Swf:
+ def __init__(self):
+ self.__doc = Document()
+
+ self.__threads = {}
+
+ self.__busy = None
+ self.__progress = None
+
+ self.__can_save = False
+
+ self.view = PdfFrame()
+ wx.GetApp().SetTopWindow(self.view)
+ # Call Show after the current and pending event
+ # handlers have been completed. Otherwise on MSW
+ # we see the frame been draw and after that we saw
+ # the menubar appear
+ wx.CallAfter(self.view.Show)
+
+ self.options = OptionsDialog(self.view)
+ self.__ReadConfigurationFile()
+
+ Publisher.subscribe(self.OnPageChanged, "PAGE_CHANGED")
+ Publisher.subscribe(self.OnFileLoaded, "FILE_LOADED")
+ Publisher.subscribe(self.OnDiffSizes, "DIFF_SIZES")
+ Publisher.subscribe(self.OnThumbnailAdded, "THUMBNAIL_ADDED")
+ Publisher.subscribe(self.OnThumbnailDone, "THUMBNAIL_DONE")
+ Publisher.subscribe(self.OnProgressBegin, "SWF_BEGIN_SAVE")
+ Publisher.subscribe(self.OnProgressUpdate, "SWF_PAGE_SAVED")
+ Publisher.subscribe(self.OnProgressDone, "SWF_FILE_SAVED")
+ Publisher.subscribe(self.OnCombineError, "SWF_COMBINE_ERROR")
+ Publisher.subscribe(self.OnFileDroped, "FILE_DROPED")
+ Publisher.subscribe(self.OnFilesDroped, "FILES_DROPED")
+
+ self.view.Bind(wx.EVT_MENU, self.OnMenuOpen, id=wx.ID_OPEN)
+ self.view.Bind(wx.EVT_MENU, self.OnMenuSave, id=wx.ID_SAVE)
+ self.view.Bind(wx.EVT_MENU, self.OnMenuSaveSelected, id=wx.ID_SAVEAS)
+ self.view.Bind(wx.EVT_MENU, self.OnMenuExit, id=wx.ID_EXIT)
+ self.view.Bind(wx.EVT_MENU_RANGE, self.OnFileHistory,
+ id=wx.ID_FILE1, id2=wx.ID_FILE9)
+
+ self.view.Bind(wx.EVT_UPDATE_UI, self.OnUpdateUI, id=wx.ID_SAVE)
+ self.view.Bind(wx.EVT_UPDATE_UI, self.OnUpdateUI, id=wx.ID_SAVEAS)
+
+ self.view.Bind(wx.EVT_MENU, self.OnMenuSelectAll, id=wx.ID_SELECTALL)
+ self.view.Bind(wx.EVT_MENU,
+ self.OnMenuInvertSelection, id=ID_INVERT_SELECTION)
+ self.view.Bind(wx.EVT_MENU, self.OnMenuSelectOdd, id=ID_SELECT_ODD)
+ self.view.Bind(wx.EVT_MENU, self.OnMenuSelectEven, id=ID_SELECT_EVEN)
+ self.view.Bind(wx.EVT_MENU, self.OnMenuOptions, id=wx.ID_PREFERENCES)
+
+ self.view.Bind(wx.EVT_UPDATE_UI, self.OnUpdateUI, id=wx.ID_SELECTALL)
+ self.view.Bind(wx.EVT_UPDATE_UI, self.OnUpdateUI, id=ID_INVERT_SELECTION)
+ self.view.Bind(wx.EVT_UPDATE_UI, self.OnUpdateUI, id=ID_SELECT_ODD)
+ self.view.Bind(wx.EVT_UPDATE_UI, self.OnUpdateUI, id=ID_SELECT_EVEN)
+
+ self.view.Bind(wx.EVT_MENU, self.OnAbout, id=wx.ID_ABOUT)
+
+ self.view.Bind(wx.EVT_MENU, self.OnZoom, id=wx.ID_ZOOM_IN)
+ self.view.Bind(wx.EVT_MENU, self.OnZoom, id=wx.ID_ZOOM_OUT)
+ self.view.Bind(wx.EVT_MENU, self.OnZoom, id=wx.ID_ZOOM_100)
+ self.view.Bind(wx.EVT_MENU, self.OnFit, id=wx.ID_ZOOM_FIT)
+
+ self.view.Bind(wx.EVT_UPDATE_UI, self.OnUpdateUI, id=wx.ID_ZOOM_IN)
+ self.view.Bind(wx.EVT_UPDATE_UI, self.OnUpdateUI, id=wx.ID_ZOOM_OUT)
+ self.view.Bind(wx.EVT_UPDATE_UI, self.OnUpdateUI, id=wx.ID_ZOOM_100)
+ self.view.Bind(wx.EVT_UPDATE_UI, self.OnUpdateUI, id=wx.ID_ZOOM_FIT)
+
+ self.view.page_list.Bind(wx.EVT_LIST_ITEM_SELECTED, self.OnSelectItem)
+ self.view.Bind(wx.EVT_CLOSE, self.OnMenuExit)
+
+ # statusbar cancel thumbanails generation button
+ self.view.statusbar.btn_cancel.Bind(wx.EVT_BUTTON,
+ self.OnThumbnailCancel)
+
+ def OnFilesDroped(self, evt):
+ dlg = wx.MessageDialog(self.view,
+ u"You must drop only one file.",
+ u"Notice",
+ style=wx.OK, pos=wx.DefaultPosition)
+ dlg.ShowModal()
+ dlg.Destroy()
+
+ def OnFileDroped(self, message):
+ self.__Load(message.data["filename"])
+
+ def OnFileHistory(self, evt):
+ # get the file based on the menu ID
+ fileNum = evt.GetId() - wx.ID_FILE1
+ filename = self.view.filehistory.GetHistoryFile(fileNum)
+
+ self.__Load(filename)
+
+ def OnProgressBegin(self, message):
+ if self.__progress:
+ self.__progress.Destroy()
+ pages = message.data["pages"]
+ style = (
+ wx.PD_APP_MODAL|wx.PD_ELAPSED_TIME|
+ wx.PD_REMAINING_TIME|wx.PD_CAN_ABORT|
+ wx.PD_AUTO_HIDE
+ )
+ self.__progress = ProgressDialog(u"Saving...",
+ u"Start saving SWF pages",
+ maximum=pages-1,
+ parent=self.view, style=style)
+ self.__progress.Show()
+ self.view.SetStatusText(u"Saving document...")
+
+ def OnProgressUpdate(self, message):
+ pagenr = message.data["pagenr"]
+ pagenr0 = pagenr - 1 # 0 based
+ pages = message.data["pages"]
+
+ keep_running, skip = self.__progress.Update(
+ pagenr0,
+ u"Saving SWF page %d of %d" % (pagenr, pages)
+ )
+ if not keep_running and self.__threads.has_key("progress"):
+ self.view.SetStatusText(u"Cancelling...")
+ self.__threads.pop("progress").Stop()
+
+ # Send size events to resize the progress dialog,
+ # this will allow the progress message label to resize accordingly.
+ # Here we minimize that events every 10 times.
+ if pagenr0 % 10 == 0:
+ self.__progress.SendSizeEvent()
+
+ def OnProgressDone(self, message):
+ self.__progress.Hide()
+ if self.__threads.has_key("progress"): # it goes all the way?
+ self.__threads.pop("progress")
+ self.view.SetStatusText(u"SWF document saved successfully.")
+ else:
+ self.view.SetStatusText(u"")
+
+ def OnCombineError(self, message):
+ from wx.lib.dialogs import ScrolledMessageDialog
+ ScrolledMessageDialog(self.view, message.data, u"Notice").ShowModal()
+
+
+ def OnThumbnailAdded(self, message):
+ self.view.statusbar.SetGaugeValue(message.data['pagenr'])
+ tot = self.view.page_list.GetItemCount()
+ self.view.SetStatusText(u"Generating thumbnails %s/%d" %
+ (message.data['pagenr'], tot), 0)
+
+ def OnThumbnailDone(self, message):
+ self.view.statusbar.SetGaugeValue(0)
+ self.view.SetStatusText(u"", 0)
+ if self.__threads.has_key("thumbnails"):
+ self.__threads.pop("thumbnails")
+
+ def OnThumbnailCancel(self, event):
+ if self.__threads.has_key("thumbnails"):
+ self.__threads["thumbnails"].Stop()
+
+ def OnSelectItem(self, event):
+ self.__doc.ChangePage(event.GetIndex() + 1)
+
+ def OnPageChanged(self, message):
+ # ignore if we have more than one item selected
+ if self.view.page_list.GetSelectedItemCount() > 1:
+ return
+
+ self.view.page_preview.DisplayPage(message.data)
+
+ def OnFileLoaded(self, message):
+ if self.__progress:
+ self.__progress.Destroy()
+ self.__progress = None
+
+ self.view.SetStatusText(u"Document loaded successfully.")
+ self.view.page_list.DisplayEmptyThumbnails(message.data["pages"])
+ thumbs = self.__doc.GetThumbnails()
+ t = self.view.page_list.DisplayThumbnails(thumbs)
+ self.__threads["thumbnails"] = t
+ self.view.statusbar.SetGaugeRange(message.data["pages"])
+ del self.__busy
+
+ def OnDiffSizes(self, message):
+ # just let the user know- for now, we can't handle this properly
+ self.Message(
+ u"In this PDF, width or height are not the same for "
+ u"each page. This might cause problems if you export "
+ u"pages of different dimensions into the same SWF file.",
+ u"Notice")
+
+ def OnMenuOpen(self, event):
+ dlg = wx.FileDialog(self.view, u"Choose PDF File:",
+ style = wx.FD_CHANGE_DIR|wx.FD_OPEN,
+ wildcard = u"PDF files (*.pdf)|*.pdf|all files (*.*)|*.*")
+
+ if dlg.ShowModal() == wx.ID_OK:
+ filename = dlg.GetPath()
+ self.__Load(filename)
+
+ def OnMenuSave(self, event, pages=None):
+ defaultFile = self.__doc.lastsavefile
+ allFiles = "*.*" if "wxMSW" in wx.PlatformInfo else "*"
+ self.view.SetStatusText(u"")
+ dlg = wx.FileDialog(self.view, u"Choose Save Filename:",
+ style = wx.SAVE | wx.OVERWRITE_PROMPT,
+ defaultFile=defaultFile,
+ wildcard=u"SWF files (*.swf)|*.swf"
+ "|all files (%s)|%s" % (allFiles, allFiles))
+
+ if dlg.ShowModal() == wx.ID_OK:
+ self.__threads["progress"] = self.__doc.SaveSWF(dlg.GetPath(),
+ pages, self.options)
+
+ def OnUpdateUI(self, event):
+ menubar = self.view.GetMenuBar()
+ menubar.Enable(event.GetId(), self.__can_save)
+
+ self.view.GetToolBar().EnableTool(event.GetId(), self.__can_save)
+
+ def OnMenuSaveSelected(self, event):
+ pages = []
+ page = self.view.page_list.GetFirstSelected()
+ pages.append(page+1)
+
+ while True:
+ page = self.view.page_list.GetNextSelected(page)
+ if page == -1:
+ break
+ pages.append(page+1)
+
+ self.OnMenuSave(event, pages)
+
+ def OnMenuExit(self, event):
+ self.view.SetStatusText(u"Cleaning up...")
+
+ # Stop any running thread
+ self.__StopThreads()
+
+ config = GetConfig()
+ self.view.filehistory.Save(config)
+ config.Flush()
+ # A little extra cleanup is required for the FileHistory control
+ del self.view.filehistory
+
+ # Save quality options
+ dirpath = GetDataDir()
+ data = self.options.quality_panel.pickle()
+ try:
+ f = file(os.path.join(dirpath, 'quality.pkl'), 'wb')
+ pickle.dump(data, f)
+ f.close()
+ except IOError:
+ pass
+
+ # Save viewer options
+ try:
+ f = file(os.path.join(dirpath, 'viewers.pkl'), 'wb')
+ data = self.options.viewers_panel.pickle()
+ pickle.dump(data, f)
+ f.close()
+ except Exception, e:
+ pass
+
+ self.view.Destroy()
+
+ def OnMenuSelectAll(self, event):
+ for i in range(0, self.view.page_list.GetItemCount()):
+ self.view.page_list.Select(i, True)
+
+ def OnMenuInvertSelection(self, event):
+ for i in range(0, self.view.page_list.GetItemCount()):
+ self.view.page_list.Select(i, not self.view.page_list.IsSelected(i))
+
+ def OnMenuSelectOdd(self, event):
+ for i in range(0, self.view.page_list.GetItemCount()):
+ self.view.page_list.Select(i, not bool(i%2))
+
+ def OnMenuSelectEven(self, event):
+ for i in range(0, self.view.page_list.GetItemCount()):
+ self.view.page_list.Select(i, bool(i%2))
+
+ def OnMenuOptions(self, event):
+ self.options.ShowModal()
+
+ def OnFit(self, event):
+ self.__doc.Fit(self.view.page_preview.GetClientSize())
+
+ def OnZoom(self, event):
+ zoom = {
+ wx.ID_ZOOM_IN: .1,
+ wx.ID_ZOOM_OUT: -.1,
+ wx.ID_ZOOM_100: 1,
+ }
+ self.__doc.Zoom(zoom[event.GetId()])
+
+ def OnAbout(self, evt):
+ AboutDialog(self.view)
+
+ def __Load(self, filename):
+ self.__can_save = True
+ self.__StopThreads()
+ self.view.SetStatusText(u"Loading document...")
+ self.__busy = wx.BusyInfo(u"One moment please, "
+ u"opening pdf document...")
+
+ self.view.filehistory.AddFileToHistory(filename)
+
+ # Need to delay the file load a little bit
+ # for the BusyInfo get a change to repaint itself
+ wx.FutureCall(150, self.__doc.Load, filename)
+
+ def __StopThreads(self):
+ for n, t in self.__threads.items():
+ t.Stop()
+
+ running = True
+ while running:
+ running = False
+ for n, t in self.__threads.items():
+ running = running + t.IsRunning()
+ time.sleep(0.1)
+
+ def __ReadConfigurationFile(self):
+ config = GetConfig()
+ self.view.filehistory.Load(config)
+
+ dirpath = GetDataDir()
+ try:
+ f = file(os.path.join(dirpath, 'quality.pkl'), 'rb')
+ try:
+ data = pickle.load(f)
+ self.options.quality_panel.unpickle(data)
+ except:
+ self.Message(
+ u"Error loading quality settings. "
+ u"They will be reset to defaults. ")
+ f.close()
+ except IOError:
+ pass
+
+ try:
+ f = file(os.path.join(dirpath, 'viewers.pkl'), 'rb')
+ try:
+ data = pickle.load(f)
+ self.options.viewers_panel.unpickle(data)
+ except:
+ self.Message(
+ u"Error loading viewers settings. "
+ u"They will be reset to defaults. ")
+ f.close()
+ except IOError:
+ pass
+ #d = pickle.load(f)
+
+ def Message(self, message):
+ dlg = wx.MessageDialog(self.view,
+ message,
+ style=wx.OK, pos=wx.DefaultPosition)
+ dlg.ShowModal()
+ dlg.Destroy()
+
--- /dev/null
+#!/usr/bin/env python
+# -*- coding: UTF-8 -*-
+#
+# gpdf2swf.py
+# graphical user interface for pdf2swf
+#
+# Part of the swftools package.
+#
+# Copyright (c) 2008,2009 Matthias Kramm <kramm@quiss.org>
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+
+from __future__ import division
+import os
+import time
+import thread
+import gfx
+import wx
+from wx.lib.pubsub import Publisher
+from subprocess import Popen, PIPE
+
+class _SaveSWFThread:
+ def __init__(self, filename, doc, pages, options):
+ self.__doc = doc
+ self.__filename = filename
+ self.__pages = pages or range(1, doc.pages+1)
+ self.__options = options
+
+ def Start(self):
+ self.__keep_running = self.__running = True
+ thread.start_new_thread(self.Run, ())
+ #self.Run()
+
+ def Stop(self):
+ self.__keep_running = False
+
+ def IsRunning(self):
+ return self.__running
+
+ def Run(self):
+ pages = len(self.__pages)
+ wx.CallAfter(Publisher.sendMessage, "SWF_BEGIN_SAVE",
+ {'pages': pages,})
+
+ time.sleep(0.05)
+
+ swf = gfx.SWF()
+ self.set_swf_parameters(swf)
+
+ plugin = self.__options.viewers.init(swf, self.__filename)
+
+ plugin.before_render()
+ for i, pagenr in enumerate(self.__pages):
+ page = self.__doc.getPage(pagenr)
+ swf.startpage(page.width, page.height)
+ page.render(swf)
+ swf.endpage()
+ wx.CallAfter(Publisher.sendMessage, "SWF_PAGE_SAVED",
+ {'pagenr': i+1,
+ 'pages': pages,})
+ time.sleep(0.05)
+ if not self.__keep_running:
+ break
+ else:
+ # This will not run if we break the for loop
+ plugin.before_save(page)
+ swf.save(self.__filename)
+ plugin.after_save(page)
+
+ # No need. But to be sure that it's clean up
+ # as soon as possible
+ del swf
+
+ wx.CallAfter(Publisher.sendMessage, "SWF_FILE_SAVED")
+ time.sleep(0.05)
+
+ self.__running = False
+
+ def set_swf_parameters(self, swf):
+ for opt in self.__options.quality:
+ if type(opt.name) in (tuple, list):
+ for name, value in (
+ # Example to better understand the list comprehension:
+ # opt.name = ['a', 'b', 'c']
+ # opt.value = [1, 2, 3]
+ # zip them = [('a',1), ('b', 2), ('c', 3)]
+ # pair will be in this example ('a', 1) due to
+ # the if pair[1] condition
+ pair for pair in zip(opt.name, opt.value) if pair[1] == 1
+ ):
+ #print "1.swf.setparameter(%s, %s)" % (name, value)
+ swf.setparameter(str(name), str(value))
+ else:
+ #print "2.swf.setparameter(%s, %s)" % (opt.name, str(opt.value))
+ swf.setparameter(opt.name, str(opt.value))
+
+
+class Document:
+ def __init__(self):
+ self.__page = None
+ self.__zoom = 1
+ self.__lastsavefile = "output.swf"
+
+ def __get_lastsavefile(self):
+ return self.__lastsavefile
+ def __set_lastsavefile(self, lastsavefile):
+ self.__lastsavefile = lastsavefile
+ lastsavefile = property(__get_lastsavefile, __set_lastsavefile)
+
+ def __SwapExtension(self, filename, newext):
+ basename, ext = os.path.splitext(filename)
+ return "%s.%s" % (basename, newext)
+
+ def __Reload(self):
+ Publisher.sendMessage("PAGE_CHANGED",
+ {'page': self.__page,
+ 'width': int(self.__page.width * self.__zoom),
+ 'height': int(self.__page.height * self.__zoom)})
+
+ def Load(self, filename):
+ self.__lastsavefile = self.__SwapExtension(filename, "swf")
+ #self.__htmlfilename = self.__SwapExtension(filename, "html")
+ self.__pdf = gfx.open("pdf", filename)
+ Publisher.sendMessage("FILE_LOADED", {'pages': self.__pdf.pages})
+
+ def ChangePage(self, pagenr=1, size=None):
+ self.__page = page = self.__pdf.getPage(pagenr)
+ self.__Reload()
+
+ def Fit(self, size):
+ w = size[0] / self.__page.width
+ h = size[1] / self.__page.height
+ self.__zoom = min(w, h)
+ self.__Reload()
+
+ def Zoom(self, zoom):
+ self.__zoom = 1 if zoom == 1 else self.__zoom + zoom
+ self.__Reload()
+
+ def GetThumbnails(self):
+ for pagenr in range(1, self.__pdf.pages + 1):
+ page = self.__pdf.getPage(pagenr)
+ yield page
+
+ def SaveSWF(self, filename, pages, options):
+ self.__lastsavefile = filename
+ t = _SaveSWFThread(filename, self.__pdf, pages, options)
+ t.Start()
+ return t
+
+
--- /dev/null
+#!/usr/bin/env python
+# -*- coding: UTF-8 -*-
+#
+# gpdf2swf.py
+# graphical user interface for pdf2swf
+#
+# Part of the swftools package.
+#
+# Copyright (c) 2008,2009 Matthias Kramm <kramm@quiss.org>
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+
+from __future__ import division
+import os
+import sys
+import imp
+
+def main_is_frozen():
+ return (hasattr(sys, "frozen") or # new py2exe
+ hasattr(sys, "importers") # old py2exe
+ or imp.is_frozen("__main__")) # tools/freeze
+
+if main_is_frozen():
+ sys.path.insert(0, os.path.join("..", "python25"))
+else:
+ sys.path.insert(0, os.path.join("..", "lib", "python"))
+
+import wx
+from app import Pdf2Swf
+
+if __name__ == "__main__":
+ app = wx.App(False)
+ app.SetAppName(u"gpdf2swf")
+ Pdf2Swf()
+ app.MainLoop()
+
--- /dev/null
+#!/usr/bin/env python
+# -*- coding: UTF-8 -*-
+#
+# gpdf2swf.py
+# graphical user interface for pdf2swf
+#
+# Part of the swftools package.
+#
+# Copyright (c) 2008,2009 Matthias Kramm <kramm@quiss.org>
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+
+from main import *
+from dialogs import *
--- /dev/null
+#!/usr/bin/env python
+# -*- coding: UTF-8 -*-
+#
+# gpdf2swf.py
+# graphical user interface for pdf2swf
+#
+# Part of the swftools package.
+#
+# Copyright (c) 2008,2009 Matthias Kramm <kramm@quiss.org>
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+
+import wx
+
+class BoldStaticText(wx.StaticText):
+ def __init__(self, *args, **kwargs):
+ wx.StaticText.__init__(self, *args, **kwargs)
+ font = self.GetFont()
+ font.SetWeight(wx.BOLD)
+ self.SetFont(font)
+
--- /dev/null
+#!/usr/bin/env python
+# -*- coding: UTF-8 -*-
+#
+# gpdf2swf.py
+# graphical user interface for pdf2swf
+#
+# Part of the swftools package.
+#
+# Copyright (c) 2008,2009 Matthias Kramm <kramm@quiss.org>
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+
+import wx
+import wx.lib.intctrl
+
+class ChoiceInt(wx.Panel):
+ def __init__(self, parent, choices=[], editselection=None):
+ wx.Panel.__init__(self, parent)
+ choices = choices
+ self.editselection = editselection
+
+ s = wx.BoxSizer(wx.HORIZONTAL)
+
+ self.choice = choice = wx.Choice(self, choices=choices)
+ self.text = text = wx.lib.intctrl.IntCtrl(self)
+ s.Add(choice, 1, wx.EXPAND)
+ s.Add(text, 1, wx.EXPAND)
+
+ self.SetSizer(s)
+
+ choice.Bind(wx.EVT_CHOICE, self.__OnChoice)
+
+ def IsEditableSelection(self, n):
+ return n == self.editselection
+
+ def GetValue(self):
+ return self.text.GetValue()
+
+ def SetValue(self, value):
+ self.text.SetValue(value)
+
+ def GetSelectionAndValue(self):
+ return self.choice.GetSelection(), self.text.GetValue()
+
+ def SetSelectionAndValue(self, n, value):
+ self.SetSelection(n)
+ self.text.SetValue(value)
+
+ def GetSelection(self):
+ return self.choice.GetSelection()
+
+ def SetSelection(self, n):
+ self.choice.SetSelection(n)
+ self.EnableText(self.IsEditableSelection(n))
+
+ def EnableText(self, enable):
+ self.text.Enable(enable)
+
+ def __OnChoice(self, event):
+ self.EnableText(self.IsEditableSelection(event.Selection))
+
--- /dev/null
+#!/usr/bin/env python
+# -*- coding: UTF-8 -*-
+#
+# gpdf2swf.py
+# graphical user interface for pdf2swf
+#
+# Part of the swftools package.
+#
+# Copyright (c) 2008,2009 Matthias Kramm <kramm@quiss.org>
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+
+from __future__ import division
+import os
+
+import wx
+from wx.lib.wordwrap import wordwrap
+
+from gui.options import Quality, ViewerBook
+
+
+class ProgressDialog(wx.ProgressDialog):
+ def __init__(self, title, message, maximum=100, parent=None,
+ style=wx.PD_AUTO_HIDE|wx.PD_APP_MODAL):
+ wx.ProgressDialog.__init__(self, title, message, maximum=maximum,
+ parent=parent, style=style)
+
+class OptionsDialog(wx.Dialog):
+ def __init__(self, parent):
+ wx.Dialog.__init__(self, parent)
+
+ app_name = wx.GetApp().GetAppName()
+ self.SetTitle(u"%s options" % app_name)
+
+ p = wx.Notebook(self)
+ self.__quality = Quality(p)
+ self.__viewers = ViewerBook(p)
+ p.AddPage(self.__quality, u"Quality")
+ p.AddPage(self.__viewers, u"Viewer")
+
+ sizer = wx.BoxSizer(wx.VERTICAL)
+ btnsizer = wx.BoxSizer(wx.HORIZONTAL)
+
+ btn = wx.Button(self, wx.ID_CLOSE)
+ self.SetAffirmativeId(wx.ID_CLOSE)
+ btnsizer.Add(btn)
+
+ sizer.Add(p, 0, wx.EXPAND|wx.ALIGN_CENTER_VERTICAL|wx.ALL, 5)
+ sizer.Add(btnsizer, 0, wx.ALIGN_RIGHT|wx.ALIGN_CENTER_VERTICAL|wx.ALL, 5)
+
+ self.SetSizer(sizer)
+ sizer.Fit(self)
+
+ def __get_quality(self):
+ return self.__quality
+ quality_panel = property(__get_quality)
+
+ def __get_viewers(self):
+ return self.__viewers
+ viewers_panel = property(__get_viewers)
+
+ def __get_quality_options(self):
+ return self.__quality.options
+ quality = property(__get_quality_options)
+
+ def __get_viewers_options(self):
+ return self.__viewers.options
+ viewers = property(__get_viewers_options)
+
+
+class AboutDialog:
+ def __init__(self, parent):
+ info = wx.AboutDialogInfo()
+ # no need to get app name
+ #info.Name = wx.GetApp().GetAppName()
+ info.Version = u"0.9.0"
+ info.Copyright = (u"Copyright (c) 2008,2009 "
+ u"Matthias Kramm <kramm@quiss.org>")
+ info.Description = u"graphical user interface for pdf2swf"
+ info.Developers = [
+ u"Matthias Kramm <kramm@quiss.org>",
+ u"Ricardo Pedroso <rmdpedroso@gmail.com>",
+ ]
+
+ if 'wxGTK' in wx.PlatformInfo:
+ info.WebSite = (u"http://www.swftools.org/", u"swftools home page")
+ licenseText = [
+ u"%(name)s is free software; you can redistribute "
+ u"it and/or modify it under the terms of the GNU General "
+ u"Public License as published by the Free Software "
+ u"Foundation; either version 2 of the License, or (at "
+ u"your option) any later version."
+ ]
+ licenseText.append(
+ u"%(name)s is distributed in the hope that it will "
+ u"be useful, but WITHOUT ANY WARRANTY; without even the "
+ u"implied warranty of MERCHANTABILITY or FITNESS FOR A "
+ u"PARTICULAR PURPOSE. See the GNU General Public License "
+ u"for more details."
+ )
+ licenseText.append(
+ u"You should have received a copy of the GNU General "
+ u"Public License along with %(name)s; if not, "
+ u"write to the Free Software Foundation, Inc., 51 "
+ u"Franklin St, Fifth Floor, Boston, MA 02110-1301 USA"
+ )
+ lic = (os.linesep*2).join(licenseText) % {'name': info.Name}
+ info.License = wordwrap(lic, 350, wx.ClientDC(parent))
+
+ wx.AboutBox(info)
+
--- /dev/null
+#!/usr/bin/env python
+# -*- coding: UTF-8 -*-
+#
+# gpdf2swf.py
+# graphical user interface for pdf2swf
+#
+# Part of the swftools package.
+#
+# Copyright (c) 2008,2009 Matthias Kramm <kramm@quiss.org>
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+
+import wx
+from choicetext import ChoiceInt
+
+class Option(object):
+ def __init__(self, name, label, data, selection):
+ self.name = name
+ self.label = label
+ self.data = data
+ self.selection = selection
+
+ def _Update(self):
+ self.value = self.ctrl.GetValue()
+
+ def _SetControlValue(self, value):
+ self.value = value
+ self.ctrl.SetValue(value)
+
+ def _OnUpdate(self, event):
+ self._Update()
+ event.Skip()
+
+ def SetValue(self, value):
+ self._SetControlValue(value)
+
+class Hidden:
+ def __init__(self, name, value):
+ self.name = name
+ self.value = value
+
+ def draw(self, parent):
+ return None, None
+
+ def SetValue(self, value):
+ self.value = value
+
+class Choose(Option):
+ klass = wx.Choice
+ def __init__(self, name, label, data, selection):
+ Option.__init__(self, name, label, data, selection)
+ self.choices = data[0::2]
+ self.data = data[1::2]
+
+ def draw(self, parent):
+ label = wx.StaticText(parent, label=self.label)
+ self.ctrl = ctrl = self.klass(parent, choices=self.choices)
+ ctrl.Bind(wx.EVT_CHOICE, self._OnUpdate)
+ self._SetControlValue(self.selection)
+ return label, ctrl
+
+ def _Update(self):
+ n = self.ctrl.GetSelection()
+ self.value = self.data[n]
+
+ def _SetControlValue(self, n):
+ self.ctrl.SetSelection(n)
+ self.value = self.data[n]
+
+ def SetValue(self, value):
+ # in python < 2.6 tuples doesnt have the index method
+ # be sure that we are using a list
+ tmp = list(self.data)
+ try:
+ n = tmp.index(value)
+ except ValueError:
+ n = self.selection
+ self._SetControlValue(n)
+
+class ChooseAndInt(Choose):
+ klass = ChoiceInt
+ def __init__(self, name, label, data, selection, editselection, editvalue):
+ Choose.__init__(self, name, label, data, selection)
+ self.editselection = editselection
+ self.editvalue = editvalue
+
+ def draw(self, parent):
+ label = wx.StaticText(parent, label=self.label)
+ self.ctrl = ctrl = self.klass(parent, choices=self.choices,
+ editselection=self.editselection)
+ ctrl.choice.Bind(wx.EVT_CHOICE, self._OnUpdate)
+ ctrl.text.Bind(wx.EVT_TEXT, self._OnUpdate)
+ self._SetControlValue(self.selection)
+ return label, ctrl
+
+ def _Update(self):
+ n = self.ctrl.GetSelection()
+ if self.ctrl.IsEditableSelection(n):
+ self.value = self.ctrl.GetValue()
+ else:
+ self.value = self.data[n]
+
+ def _SetControlValue(self, n):
+ self.ctrl.SetSelectionAndValue(n, self.editvalue)
+ self.value = self.data[n]
+
+ def SetValue(self, value):
+ # in python < 2.6 tuples doesnt have the index method
+ # be sure that we are using a list
+ tmp = list(self.data)
+ try:
+ n = tmp.index(value)
+ except ValueError:
+ n = self.editselection
+ self.editvalue = value
+ self._SetControlValue(n)
+
+class Radio(Option):
+ klass = wx.RadioBox
+ def __init__(self, name, label, data, selection):
+ Option.__init__(self, name, label, data, selection)
+ self.choices = data[0::2]
+ self.data = data[1::2]
+ self.selection = selection
+
+ def draw(self, parent):
+ self.ctrl = ctrl = self.klass(parent, label=self.label,
+ choices=self.choices,
+ majorDimension=1,
+ style=wx.RA_SPECIFY_COLS)
+ ctrl.Bind(wx.EVT_RADIOBOX, self._OnUpdate)
+ self._SetControlValue(self.selection)
+ return ctrl
+
+ def _Update(self):
+ n = self.ctrl.GetSelection()
+ self.value = self.data[n]
+
+ def _SetControlValue(self, n):
+ self.ctrl.SetSelection(n)
+ self.value = self.data[n]
+
+ def SetValue(self, value):
+ # in python < 2.6 tuples doesnt have the index method
+ # be sure that we are using a list
+ tmp = list(self.data)
+ try:
+ n = tmp.index(value)
+ except ValueError:
+ n = self.selection
+ self._SetControlValue(n)
+
+class Spinner(Option):
+ klass = wx.SpinCtrl
+ def __init__(self, name, label, data, selection):
+ Option.__init__(self, name, label, data, selection)
+ self.min = data[0]
+ self.max = data[1]
+
+ def draw(self, parent):
+ label = wx.StaticText(parent, label=self.label)
+ self.ctrl = ctrl = self.klass(parent, min=self.min, max=self.max,
+ initial=self.selection)
+ ctrl.Bind(wx.EVT_SPINCTRL, self._OnUpdate)
+ self._SetControlValue(self.selection)
+ return label, ctrl
+
+class Slider(Option):
+ klass = wx.Slider
+ def __init__(self, name, label, data, selection):
+ Option.__init__(self, name, label, data, selection)
+ self.min = data[0]
+ self.max = data[1]
+
+ def draw(self, parent):
+ label = wx.StaticText(parent, label=self.label)
+ self.ctrl = ctrl = self.klass(parent, minValue=self.min,
+ maxValue=self.max,
+ value=self.selection,
+ style=wx.SL_LABELS)
+ ctrl.Bind(wx.EVT_SCROLL, self._OnUpdate)
+ self._SetControlValue(self.selection)
+ return label, ctrl
--- /dev/null
+#!/usr/bin/env python
+# -*- coding: UTF-8 -*-
+#
+# gpdf2swf.py
+# graphical user interface for pdf2swf
+#
+# Part of the swftools package.
+#
+# Copyright (c) 2008,2009 Matthias Kramm <kramm@quiss.org>
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+
+from __future__ import division
+import os
+import wx
+from wx.lib.pubsub import Publisher
+from wx.lib.embeddedimage import PyEmbeddedImage
+import thread
+import time
+
+ICON_SIZE = 64
+
+ID_INVERT_SELECTION = wx.NewId()
+ID_SELECT_ODD = wx.NewId()
+ID_SELECT_EVEN = wx.NewId()
+
+# TODO: move into images.py
+blank = PyEmbeddedImage(
+ "iVBORw0KGgoAAAANSUhEUgAAAEAAAABACAYAAACqaXHeAAAAAXNSR0IArs4c6QAAAAZiS0dE"
+ "AP8A/wD/oL2nkwAAAAlwSFlzAAALEwAACxMBAJqcGAAAAAd0SU1FB9kHDAscKjCK/4UAAABo"
+ "SURBVHja7dABAcBAEAIgXf/Ofo8dRKDblqPa5stxAgQIECBAgAABAgQIECBAgAABAgQIECBA"
+ "gAABAgQIECBAgAABAgQIECBAgAABAgQIECBAgAABAgQIECBAgAABAgQIEPALTbLLAQ8OIAV9"
+ "8WNeKwAAAABJRU5ErkJggg==")
+getblankData = blank.GetData
+getblankImage = blank.GetImage
+getblankBitmap = blank.GetBitmap
+
+stop_width=8
+stop_height=8
+stop_data="""\xd5\x07\x07\xd5\x08\x08\xd5\x09\x09\xd4\x0a\x0a\xd4\x0a\x0a\xd5\x09\x09\xd5\x08\x08\xd5\x07\x07\xd5\x08\x08\xd4\x12\x12\xd4<<\xd1--\xd1,-\xd4;;\xd5\x12\x12\xd6\x08\x08\xd5\x0a\x0a\xd2@@\xd4\xc6\xc7\xd5kk\xd2gi\xd2\xc4\xc6\xd4<<\xd6\x0a\x0a\xd4\x0c\x0c\xcb66\xd6gi\xe3\xeb\xed\xe1\xeb\xed\xd4bc\xd3++\xd5\x0c\x0c\xd4\x0b\x0b\xd0--\xd3hi\xe2\xeb\xed\xe2\xed\xee\xd5cd\xd3++\xd5\x0c\x0c\xd5\x09\x09\xd4:;\xd3\xc5\xc7\xd3ij\xd3jj\xd3\xc5\xc7\xd4<<\xd6\x0a\x0a\xd5\x08\x08\xd4\x12\x12\xd5<=\xd2..\xd1,,\xd4;;\xd5\x12\x12\xd6\x08\x08\xd5\x07\x07\xd6\x08\x08\xd6\x0a\x0a\xd5\x0b\x0b\xd4\x0b\x0b\xd5\x09\x09\xd5\x08\x08\xd5\x07\x07"""
+
+
+class _AppendThumbnailThread:
+ def __init__(self, win, thumbs):
+ self.__win = win
+ self.__thumbs = thumbs
+
+ def Start(self):
+ self.__keep_running = self.running = True
+ thread.start_new_thread(self.Run, ())
+
+ def IsRunning(self):
+ return self.running
+
+ def Stop(self):
+ self.__keep_running = False
+
+ def Run(self):
+ thumbs = self.__thumbs
+ different_sizes = False
+ for pos, thumb in enumerate(thumbs):
+ if pos == 0:
+ width, height = thumb.width, thumb.height
+ else:
+ if abs(width - thumb.width) > 2 or \
+ abs(height - thumb.height) > 2:
+ different_sizes = True
+
+ wx.CallAfter(self.__win.AppendThumbnail, pos,
+ thumb.asImage(ICON_SIZE, ICON_SIZE))
+ wx.CallAfter(Publisher.sendMessage, "THUMBNAIL_ADDED",
+ {'pagenr':pos+1,})
+ time.sleep(.05)
+ if not self.__keep_running:
+ break
+
+ else:
+ if different_sizes:
+ wx.CallAfter(Publisher.sendMessage, "DIFF_SIZES")
+ time.sleep(.10)
+ wx.CallAfter(Publisher.sendMessage, "THUMBNAIL_DONE")
+ time.sleep(.10)
+
+ self.running = False
+
+class FileDropTarget(wx.FileDropTarget):
+ def __init__(self, window):
+ wx.FileDropTarget.__init__(self)
+ self.window = window
+
+ def OnDropFiles(self, x, y, filenames):
+ if len(filenames) == 1:
+ Publisher.sendMessage("FILE_DROPED",
+ {'filename': filenames[0]}
+ )
+ else:
+ Publisher.sendMessage("FILES_DROPED",
+ {'filenames': filenames}
+ )
+
+class PagePreviewWindow(wx.ScrolledWindow):
+ def __init__(self, parent):
+ wx.ScrolledWindow.__init__(self, parent)
+ self.SetBackgroundColour('grey')
+ self.SetScrollRate(20, 20)
+
+ self.__buffer = wx.EmptyBitmap(1, 1)
+
+ self.Bind(wx.EVT_PAINT, self.__OnPaint)
+
+ def DisplayPage(self, page):
+ thread.start_new_thread(self.__DisplayPageThread, (page,))
+
+ def __OnPaint(self, event):
+ dc = wx.BufferedPaintDC(self, self.__buffer, wx.BUFFER_VIRTUAL_AREA)
+
+ def __DisplayPage(self, w, h, page):
+ self.SetVirtualSize((w, h))
+ self.__buffer = wx.EmptyBitmap(w+2, h+2)
+ dc = wx.BufferedDC(None, self.__buffer)
+ dc.Clear()
+ dc.DrawRectangle(0, 0, w+2, h+2)
+ dc.DrawBitmap(wx.BitmapFromBuffer(w, h, page), 1, 1, True)
+ self.Refresh()
+
+ def __DisplayPageThread(self, page):
+ w = page['width']
+ h = page['height']
+ time.sleep(.02)
+ page = page["page"].asImage(w, h)
+ wx.CallAfter(self.__DisplayPage, w, h, page)
+
+
+class PageListCtrl(wx.ListView):
+ def __init__(self, parent):
+ wx.ListView.__init__(self, parent, style=wx.LC_ICON)
+ self.Bind(wx.EVT_CONTEXT_MENU, self.OnContextMenu)
+
+ def OnContextMenu(self, event):
+ menu = wx.Menu()
+ menu.Append(wx.ID_SELECTALL, u"Select All\tCTRL-A")
+ menu.AppendSeparator()
+ menu.Append(wx.ID_SAVE, u"Save SWF (all pages)\tCTRL-W")
+ menu.Append(wx.ID_SAVEAS, u"Save SWF (selected pages)\tCTRL-S")
+ self.PopupMenu(menu)
+ menu.Destroy()
+
+ def DisplayEmptyThumbnails(self, pages):
+ self.DeleteAllItems()
+ self.imglist = wx.ImageList(ICON_SIZE, ICON_SIZE, mask=True)
+ self.AssignImageList(self.imglist, wx.IMAGE_LIST_NORMAL)
+ bmp = getblankBitmap()
+ for pos in range(pages):
+ self.imglist.Add(bmp)
+ self.InsertImageStringItem(pos, u"Page %s" % (pos+1), pos)
+
+ def DisplayThumbnails(self, thumbs):
+ t = _AppendThumbnailThread(self, thumbs)
+ t.Start()
+ return t
+
+ def AppendThumbnail(self, pos, thumb):
+ bmp = wx.BitmapFromBuffer(ICON_SIZE, ICON_SIZE, thumb)
+ self.imglist.Replace(pos, bmp)
+ if pos == 0:
+ wx.CallAfter(self.Select, 0)
+ self.Refresh()
+
+
+class StatusBar(wx.StatusBar):
+ def __init__(self, parent):
+ wx.StatusBar.__init__(self, parent, -1)
+
+ self.sizeChanged = False
+ self.Bind(wx.EVT_SIZE, self.OnSize)
+ self.Bind(wx.EVT_IDLE, self.OnIdle)
+
+ self.gauge = wx.Gauge(self)
+
+ bmp = wx.BitmapFromImage(wx.ImageFromData(stop_width,stop_height,stop_data))
+ self.btn_cancel = wx.BitmapButton(self, bitmap=bmp,
+ style = wx.NO_BORDER)
+ self.gauge.Hide()
+ self.btn_cancel.Hide()
+
+ self.Reposition()
+
+ def SetGaugeValue(self, value):
+ if value == 0:
+ self.gauge.Hide()
+ self.btn_cancel.Hide()
+ self.gauge.SetValue(value)
+
+ def SetGaugeRange(self, pages):
+ self.gauge.Show()
+ self.btn_cancel.Show()
+ self.gauge.SetRange(pages)
+
+ def OnSize(self, evt):
+ self.Reposition()
+ self.sizeChanged = True
+
+ def OnIdle(self, evt):
+ if self.sizeChanged:
+ self.Reposition()
+
+ def Reposition(self):
+ rect = self.GetFieldRect(0)
+ of = rect.width // 1.5
+ self.gauge.SetPosition((rect.x+of , rect.y+2))
+ self.gauge.SetSize((rect.width-of-24, rect.height-4))
+ self.btn_cancel.SetPosition((rect.width-22, rect.y+1))
+ self.btn_cancel.SetSize((22, rect.height-2))
+ self.sizeChanged = False
+
+
+class PdfFrame(wx.Frame):
+ def __init__(self):
+ wx.Frame.__init__(self, None, size=(750,550), title=u"gpdf2swf")
+
+ icon = self.__MakeIcon(os.path.join("images", "pdf2swf_gui.ico"))
+ self.SetIcon(icon)
+ self.__CreateMenu()
+ self.__CreateToolbar()
+ self.statusbar = StatusBar(self)
+ self.SetStatusBar(self.statusbar)
+
+ dt = FileDropTarget(self)
+ self.SetDropTarget(dt)
+
+ hsplit = wx.SplitterWindow(self, style=wx.SP_3D|wx.SP_LIVE_UPDATE)
+ self.page_list = PageListCtrl(hsplit)
+ self.page_preview = PagePreviewWindow(hsplit)
+ hsplit.SplitVertically(self.page_list, self.page_preview,
+ sashPosition=ICON_SIZE*2)
+ hsplit.SetMinimumPaneSize(ICON_SIZE*2)
+
+ def __MakeIcon(self, filename):
+ # TODO: Probably include the icon on a .py file
+ img = wx.Bitmap(filename).ConvertToImage()
+ if "wxMSW" in wx.PlatformInfo:
+ img = img.Scale(16, 16)
+ #elif "wxGTK" in wx.PlatformInfo:
+ # img = img.Scale(22, 22)
+ # wxMac and wxGTK???? can be any size up to 128x128,
+ # so leave the source img alone....
+ icon = wx.IconFromBitmap(img.ConvertToBitmap())
+ return icon
+
+ def __CreateMenu(self):
+ menubar = wx.MenuBar()
+
+ menu = wx.Menu()
+ menu.Append(wx.ID_OPEN, u"Open PDF\tCTRL-O", u"Open a PDF document")
+ menu.AppendSeparator()
+ menu.Append(wx.ID_SAVE, u"Save SWF (all pages)\tCTRL-W",
+ u"Save all pages")
+ menu.Append(wx.ID_SAVEAS, u"Save SWF (selected pages)\tCTRL-S",
+ u"Save selected pages")
+ menu.AppendSeparator()
+ menu.Append(wx.ID_EXIT, u"Exit\tCTRL-Q")
+ menubar.Append(menu, u"&File")
+
+ self.filehistory = wx.FileHistory()
+ self.filehistory.UseMenu(menu)
+
+ menu = wx.Menu()
+ menu.Append(wx.ID_SELECTALL, u"Select All\tCTRL-A",
+ u"Select all pages")
+ menu.Append(ID_INVERT_SELECTION, u"Invert Selection",
+ u"Invert current selection")
+ menu.Append(ID_SELECT_ODD, u"Select Odd",
+ u"Select odd pages")
+ menu.Append(ID_SELECT_EVEN, u"Select Even",
+ u"Select even pages")
+ menu.AppendSeparator()
+ menu.Append(wx.ID_PREFERENCES, u"Options\tCTRL-R",
+ u"Show options dialog")
+ menubar.Append(menu, u"&Edit")
+
+ menu = wx.Menu()
+ menu.Append(wx.ID_ZOOM_IN, u"Zoom In\tCTRL-+")
+ menu.Append(wx.ID_ZOOM_OUT, u"Zoom Out\tCTRL--")
+ menu.Append(wx.ID_ZOOM_100, u"Normal Size\tCTRL-0")
+ menu.Append(wx.ID_ZOOM_FIT, u"Fit\tCTRL-1")
+ menubar.Append(menu, u"&View")
+
+ menu = wx.Menu()
+ menu.Append(wx.ID_ABOUT, u"About")
+ menubar.Append(menu, u"&Help")
+ self.SetMenuBar(menubar)
+
+ def __CreateToolbar(self):
+ tsize = (16,16)
+ wxart = wx.ArtProvider.GetBitmap
+ self.toolbar = self.CreateToolBar(wx.TB_HORIZONTAL |
+ wx.NO_BORDER | wx.TB_FLAT)
+ self.toolbar.AddSimpleTool(wx.ID_OPEN,
+ wxart(wx.ART_FILE_OPEN,
+ wx.ART_TOOLBAR, tsize),
+ u"Open")
+ self.toolbar.AddSimpleTool(wx.ID_SAVE,
+ wxart(wx.ART_FILE_SAVE,
+ wx.ART_TOOLBAR, tsize),
+ u"Save SWF (all pages)")
+ self.toolbar.AddSimpleTool(wx.ID_PREFERENCES,
+ wxart(wx.ART_LIST_VIEW,
+ wx.ART_TOOLBAR, tsize),
+ u"Options")
+ self.toolbar.Realize()
+
--- /dev/null
+#!/usr/bin/env python
+# -*- coding: UTF-8 -*-
+#
+# gpdf2swf.py
+# graphical user interface for pdf2swf
+#
+# Part of the swftools package.
+#
+# Copyright (c) 2008,2009 Matthias Kramm <kramm@quiss.org>
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+
+from quality import *
+from viewer import *
--- /dev/null
+#!/usr/bin/env python
+# -*- coding: UTF-8 -*-
+#
+# gpdf2swf.py
+# graphical user interface for pdf2swf
+#
+# Part of the swftools package.
+#
+# Copyright (c) 2008,2009 Matthias Kramm <kramm@quiss.org>
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+
+import wx
+from gui import fields
+
+class Quality(wx.Panel):
+ def __init__(self, parent):
+ wx.Panel.__init__(self, parent)
+ self.__options = []
+
+ sizer = wx.BoxSizer(wx.VERTICAL)
+ obj = fields.Radio(
+ ("bitmap", "poly2bitmap", "bitmapfonts"),
+ u"Rendering mode",
+ [u"Convert polygons to polygons and fonts to fonts", (0, 0, 0),
+ u"Convert fonts to fonts, everything else to bitmaps", (0, 1, 0),
+ u"Convert everthing to bitmaps", (1, 0, 1),
+ ], 0)
+
+ ra = obj.draw(self)
+ self.__options.append(obj)
+ sizer.Add(ra, 0, wx.EXPAND|wx.ALL, 5)
+
+ quality = [
+ ('Spinner', 'zoom', u'Resolution (in dpi):', (0, 100), 72),
+ ('Slider', 'fontquality', u'Font quality:', (0, 100), 20),
+ ('Choose', 'storeallcharacters', u'Insert full fonts in SWF file:',
+ (u'no', 0, u'yes', 1), 0),
+ ('Slider', 'splinequality', u'Polygon quality:', (0, 100), 100),
+ ('Slider', 'jpegquality', u'JPEG quality:', (0, 100), 75),
+ ('Choose', 'jpegsubpixels', u'JPEG image resolution:',
+ (u'same as in PDF', 0, u'1x', 1, u'2x', 2, u'4x', 4), 0),
+ ('Choose', 'ppmsubpixels', u'non-JPEG image resolution:',
+ (u'same as in PDF', 0, u'1x', 1, u'2x', 2, u'4x', 4), 0),
+ ]
+
+ box = wx.StaticBox(self, label=u"Quality")
+ bsizer = wx.StaticBoxSizer(box, wx.VERTICAL)
+
+ flex = wx.FlexGridSizer(rows=1, cols=2, hgap=0, vgap=0)
+ flex.AddGrowableCol(0)
+ flex.AddGrowableCol(1)
+ for ctrl, opt, label, range, value in quality:
+ wxobj = getattr(fields, ctrl)
+ optobj = wxobj(opt, label, range, value)
+ lb, sp = optobj.draw(self)
+ flex.Add(lb, 0, wx.TOP|wx.ALIGN_CENTER_VERTICAL, 5)
+ flex.Add(sp, 0, wx.TOP|wx.EXPAND, 5)
+ self.__options.append(optobj)
+
+ bsizer.Add(flex, 0, wx.EXPAND)
+ sizer.Add(bsizer, 0, wx.EXPAND|wx.ALL, 5)
+
+ self.SetSizer(sizer)
+
+ def __get_options(self):
+ return self.__options
+ options = property(__get_options)
+
+ def pickle(self):
+ data = {}
+ for opt in self.__options:
+ data[opt.name] = opt.value
+ return data
+
+ def unpickle(self, data):
+ fields = {}
+ for opt in self.__options:
+ fields[opt.name] = opt
+
+ for k, v in data.items():
+ fields[k].SetValue(v)
--- /dev/null
+#!/usr/bin/env python
+# -*- coding: UTF-8 -*-
+#
+# gpdf2swf.py
+# graphical user interface for pdf2swf
+#
+# Part of the swftools package.
+#
+# Copyright (c) 2008,2009 Matthias Kramm <kramm@quiss.org>
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+
+import os
+import wx
+import operator
+import imp
+from wx.lib.wordwrap import wordwrap
+from gui.boldstatictext import BoldStaticText
+import viewers
+import gui.fields
+
+class Viewers:
+ def __init__(self):
+ self.viewers = []
+ self.modules = []
+ self.list_viewers()
+ self.import_viewers()
+
+ def list_viewers(self):
+ for file in os.listdir('viewers'):
+ if (file.startswith('.') or file.startswith('_')
+ or file.endswith(".pyc") or not file.endswith('.py')):
+ continue
+ self.viewers.append(os.path.splitext(file)[0])
+
+ def import_viewers(self):
+ for file in self.viewers:
+ _temp = imp.load_source("viewers.%s" % file, os.path.join(os.getcwdu(), "viewers/%s.py" % file))
+ self.modules.append(_temp)
+
+
+
+class ViewerBook(wx.Listbook):
+ def __init__(self, parent):
+ wx.Listbook.__init__(self, parent, wx.ID_ANY, style=
+ wx.BK_DEFAULT
+ )
+
+ self.__mod = []
+ self.__viewers = viewers = Viewers()
+
+ # make an image list
+ il = wx.ImageList(102, 102)
+ self.AssignImageList(il)
+
+ # Sort viewers by attribute order.
+ # The attribute order must be an int from 0..n
+ viewers.modules.sort(key=operator.attrgetter('order'))
+
+ # Make a bunch of panels for the list book
+ for idx, mod in enumerate(viewers.modules):
+ bmp = mod.preview.GetBitmap()
+ il.Add(bmp)
+
+ win = self.makePanel(mod)
+ self.AddPage(win, mod, imageId=idx)
+
+ # A hack to avoid having the scrollbar be on bottom
+ # the first time the control is created
+ self.ListView.Select(self.ListView.GetItemCount()-1)
+ self.ListView.Select(0)
+
+ def makePanel(self, mod):
+ p = wx.Panel(self)
+ sizer = wx.BoxSizer(wx.VERTICAL)
+
+ nameCtrl = BoldStaticText(p, label=mod.name)
+ sizer.Add(nameCtrl, 0, wx.EXPAND|wx.TOP|wx.BOTTOM, 10)
+
+ t = wordwrap(mod.desc, 400, wx.ClientDC(p))
+ descCtrl = wx.StaticText(p, label=t)
+ sizer.Add(descCtrl, 0, wx.EXPAND|wx.TOP|wx.BOTTOM, 10)
+
+ #swf_options = []
+
+ # Avoid showing an empty StaticBox
+ if (len(mod.swf_options) == 1
+ and isinstance(mod.swf_options[0], gui.fields.Hidden)
+ ):
+ hidden = True
+ else:
+ hidden = False
+
+ if mod.swf_options and not hidden:
+ box = wx.StaticBox(p, label=u"SWF")
+ bsizer = wx.StaticBoxSizer(box, wx.VERTICAL)
+
+ flex = wx.FlexGridSizer(rows=len(mod.swf_options), cols=2, hgap=0, vgap=0)
+ flex.AddGrowableCol(1)
+
+ for option in mod.swf_options:
+ #swf_options.append(option)
+ label, ctrl = option.draw(p)
+ if label and ctrl:
+ flex.Add(label, 0, wx.ALIGN_CENTER_VERTICAL|wx.ALL, 4)
+ flex.Add(ctrl, 0, wx.EXPAND|wx.ALL, 4)
+
+ bsizer.Add(flex, 0, wx.EXPAND)
+ sizer.Add(bsizer, 0, wx.EXPAND)
+
+ #vie_options = []
+ if mod.viewer_options:
+ box = wx.StaticBox(p, label=u"Viewer")
+ bsizer = wx.StaticBoxSizer(box, wx.VERTICAL)
+
+ flex = wx.FlexGridSizer(rows=len(mod.viewer_options),
+ cols=2, hgap=0, vgap=0)
+ flex.AddGrowableCol(1)
+
+ for option in mod.viewer_options:
+ #vie_options.append(option)
+ label, ctrl = option.draw(p)
+ if label and ctrl:
+ flex.Add(label, 0, wx.ALIGN_CENTER_VERTICAL|wx.ALL, 4)
+ flex.Add(ctrl, 0, wx.EXPAND|wx.ALL, 4)
+
+ bsizer.Add(flex, 0, wx.EXPAND)
+ sizer.Add(bsizer, 0, wx.EXPAND)
+
+ p.SetSizer(sizer)
+ return p
+
+ def AddPage(self, win, mod, select=False, imageId=-1):
+ wx.Listbook.AddPage(self, win, mod.name, select, imageId)
+ self.__mod.append(mod)
+
+ def __get_options(self):
+ page = self.GetSelection()
+ return self.__mod[page]
+
+ options = property(__get_options)
+
+ def pickle(self):
+ data = {}
+ data['selected_viewer'] = self.GetSelection()
+
+ for viewer, module in zip(self.__viewers.viewers, self.__viewers.modules):
+ data[viewer] = {}
+ for opt in module.swf_options:
+ data[viewer][opt.name] = opt.value
+ for opt in module.viewer_options:
+ data[viewer][opt.name] = opt.value
+
+ return data
+
+ def unpickle(self, data):
+ if not data:
+ return
+
+ selected_viewer = data.pop('selected_viewer')
+ self.SetSelection(selected_viewer)
+
+ _fields = {}
+ for viewer, module in zip(self.__viewers.viewers, self.__viewers.modules):
+ _fields[viewer] = {}
+
+ all_opts = module.swf_options + module.viewer_options
+ for field in all_opts:
+ _fields[viewer][field.name] = field
+
+ for modname, opts in data.items():
+ for k, v in opts.items():
+ _fields[modname][k].SetValue(v)
+
--- /dev/null
+#!/usr/bin/env python
+# -*- coding: UTF-8 -*-
+#
+# gpdf2swf.py
+# graphical user interface for pdf2swf
+#
+# Part of the swftools package.
+#
+# Copyright (c) 2008,2009 Matthias Kramm <kramm@quiss.org>
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+
+import os
+import time
+import wx
+from wx.lib.pubsub import Publisher
+from subprocess import Popen, PIPE
+
+class Plugin:
+ def before_render(self):
+ pass
+
+ def before_save(self, page):
+ pass
+
+ def after_save(self, page):
+ pass
+
+ def _swap_extension(self, filename, newext, flashversion=""):
+ name, ext = os.path.splitext(filename)
+ return u"%s%s.%s" % (name, flashversion, newext)
+
+ def __find_swfcombine(self):
+ found = False
+ prog = "swfcombine.exe" if "wxMSW" in wx.PlatformInfo else "swfcombine"
+ basedir = os.path.dirname(__file__)
+
+ opj = os.path.join
+ locations = [opj(basedir, prog)]
+ if "wxMSW" in wx.PlatformInfo:
+ locations.extend([
+ opj("c:", "swftools", prog),
+ opj("c:", "Program Files", "SWFTools", prog)
+ ])
+ else:
+ locations.extend([
+ opj(os.sep, "usr", "local", "bin", prog),
+ opj(os.sep, "usr", "bin", prog),
+ ])
+
+ exe = prog
+ for e in locations:
+ if os.path.isfile(e):
+ exe = e
+ found = True
+ break
+ return exe, found
+
+ def swfcombine(self, *args):
+ try:
+ self.__swfcombine(*args)
+ except Exception, e:
+ wx.CallAfter(Publisher.sendMessage,
+ "SWF_COMBINE_ERROR", unicode(e))
+ time.sleep(0.05)
+
+ def __swfcombine(self, *args):
+ exe, found = self.__find_swfcombine()
+ # uncoment to test a failed swfcombine find
+ #found = False
+
+ if not found:
+ raise Exception(u"Could not execute %s: %s not found" % (exe, exe))
+
+ # Create a command line
+ cmd = [exe,]
+ cmd.extend(args)
+
+ output = Popen(cmd, stdout=PIPE).communicate()[0]
+
+ # Check the process output
+ if output:
+ raise Exception(u"Error executing %s:%s%s" %
+ (u" ".join(cmd), os.linesep, output))
+
#!/usr/bin/env python
+# -*- coding: ISO-8859-15 -*-
#
-# images.py
-#
-# graphical user interface for pdf2swf: image data
+# pdf2swf.py
+# graphical user interface for pdf2swf
#
# Part of the swftools package.
#
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+import sys
+import wx
+import os
+sys.path+=["../lib/python"]
+import gfx
+import images
+import stat
+
+basedir = os.getcwd()
+
+gfx.verbose(3)
+
+#try:
+# gfx.setparameter("wxwindowparams", "1")
+#except:
+# gfx.setoption("wxwindowparams", "1")
+
+class StaticData:
+ def __init__(self):
+ self.simpleviewer_bitmap = wx.BitmapFromImage(wx.ImageFromData(images.simpleviewer_width,images.simpleviewer_height,images.simpleviewer_data))
+ self.raw_bitmap = wx.BitmapFromImage(wx.ImageFromData(images.raw_width,images.raw_height,images.raw_data))
+ self.motionpaper_bitmap = wx.BitmapFromImage(wx.ImageFromData(images.motionpaper_width,images.motionpaper_height,images.motionpaper_data))
+ self.rfxview_bitmap = wx.BitmapFromImage(wx.ImageFromData(images.rfxview_width,images.rfxview_height,images.rfxview_data))
+staticdata = None
+
+HTMLTEMPLATE = """<html>
+<body style="padding: 0px; margin: 0px">
+<object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"
+ width="%(width)s"
+ height="%(height)s"
+ codebase="http://active.macromedia.com/flash5/cabs/swflash.cab#version=%(version)d,0,0,0">
+ <param name="MOVIE" value="%(swffilename)s">
+ <param name="PLAY" value="true">
+ <param name="LOOP" value="true">
+ <param name="QUALITY" value="high">
+ <param name="FLASHVARS" value="%(flashvars)s">
+ <embed src="%(swffilename)s" width="%(width)s" height="%(height)s"
+ play="true" ALIGN="" loop="true" quality="high"
+ type="application/x-shockwave-flash"
+ flashvars="%(flashvars)s"
+ pluginspage="http://www.macromedia.com/go/getflashplayer">
+ </embed>
+</object>
+</body>
+</html>
+"""
+
+def error(msg):
+ dlg = wx.MessageDialog(None, msg, "Error", style=wx.OK, pos=wx.DefaultPosition)
+ dlg.ShowModal()
+ dlg.Destroy()
+
+def savefilestatus(msg):
+ dlg = wx.MessageDialog(None, msg, "Save file status", style=wx.OK, pos=wx.DefaultPosition)
+ dlg.ShowModal()
+ dlg.Destroy()
+
+def swfcombine(params):
+ exe = "swfcombine"
+ if os.path.sep == '/':
+ locations = [os.path.join(basedir, "swfcombine"),
+ "/usr/local/bin/swfcombine",
+ "/usr/bin/swfcombine"
+ ]
+ else:
+ locations = [os.path.join(basedir, "swfcombine.exe"),
+ "c:\\swftools\\swfcombine.exe"]
+ params = ['"'+p+'"' for p in params]
+
+ for e in locations:
+ if os.path.isfile(e):
+ exe = e
+ break
+
+ if hasattr(os,"spawnv"):
+ print "spawnv",exe,params
+ ret = -1
+ try:
+ ret = os.spawnv(os.P_WAIT, exe, ["swfcombine"]+params)
+ except:
+ ret = -1
+ if not ret:
+ return
+
+ cmd = '"' + exe + '"' + " " + (" ".join(params))
+ print "system",cmd
+ ret = os.system(cmd)
+ if ret&0xff00:
+ error("Couldn't execute swfcombine.exe- error code "+str(ret))
+
+ICON_SIZE = 64
+
+EVENT_PAGE_CHANGE = 1
+EVENT_FILE_CHANGE = 2
+EVENT_STATUS_TEXT = 4
+
+class ProgressFrame(wx.Dialog):
+ def __init__(self, parent, message=""):
+ wx.Dialog.__init__(self, parent, -1, "Progress", size=(350, 150))
+ panel = wx.Panel(self, -1)
+ self.count = 0
+
+ self.msg = wx.StaticText(panel, -1, message, (20,25))
+ self.gauge = wx.Gauge(panel, -1, 100, (20, 50), (250, 25))
+
+ self.gauge.SetBezelFace(3)
+ self.gauge.SetShadowWidth(3)
+
+ self.Bind(wx.EVT_WINDOW_DESTROY, self.close, id=wx.ID_CLOSE)
+
+ def setProgress(self, num):
+ self.gauge.SetValue(int(num))
+
+ def close(self, event):
+ print "close"
+
+
+def swapextension(filename,newext):
+ basename,ext = os.path.splitext(filename)
+ return basename + "." + newext
+
+def has_different_size_pages(doc):
+ width,height = 0,0
+ for i in range(1,doc.pages+1):
+ page = doc.getPage(i)
+ if i==1:
+ width,height = page.width,page.height
+ else:
+ if abs(width-page.width)>2 or \
+ abs(height-page.height)>2:
+ return 1
+ return 0
+
+
+options = []
+gfx_options = {}
+
+class Option:
+ def __init__(self, parameter, text, options, default, mapping=None):
+ self.parameter = parameter
+ self.text = text
+ self.options = options
+ self.default = default
+ self.mapping = mapping
+ self.control = None
+ self.enabled = 1
+ self.register()
+
+ def generateControl(self, panel):
+ if type(self.options) == type((0,)):
+ control = wx.Choice(panel, -1, choices=self.options)
+ control.SetSelection(self.default)
+ elif self.options == "slider":
+ control = wx.Slider(panel, -1, self.default, 0, 100, size=(100, -1), style=wx.SL_HORIZONTAL|wx.SL_LABELS|wx.SL_TOP)
+ elif self.options == "spinner":
+ control = wx.SpinCtrl(panel, -1, str(self.default))
+ else:
+ control = wx.Choice(panel, -1, choices=["broken"])
+ control.SetSelection(0)
+
+ self.control = control
+ return self.control
+
+ def getSettings(self):
+ value = ""
+ if type(self.options) == type((0,)):
+ value = self.options[self.control.GetCurrentSelection()]
+ if self.mapping and value in self.mapping:
+ value = str(self.mapping[value])
+ if value == "yes":
+ value = "1"
+ elif value == "no":
+ value = "0"
+ return {self.parameter:value}
+ elif self.options == "slider" or self.options == "spinner":
+ value = str(self.control.GetValue())
+ return {self.parameter:value}
+
+ def register(self):
+ global options
+ options += [self]
+
+class Option2(Option):
+
+ def __init__(self, parameter, text, options, default, mapping=None):
+ Option.__init__(self, parameter, text, options, default, mapping)
+ self.enabled = 0
+
+ def generateControl(self, panel):
+ p = wx.Panel(panel, -1)
+ #p.SetOwnBackgroundColour('#ff0000')
+ h = wx.BoxSizer(wx.HORIZONTAL)
+ control = wx.Choice(p, -1, choices=self.options)
+ control.SetSelection(self.default)
+ text = wx.StaticText(p, -1, self.text)
+ h.Add(text,1,wx.EXPAND|wx.ALIGN_LEFT|wx.TOP, 5)
+ h.Add(control,1,wx.EXPAND|wx.ALIGN_RIGHT|wx.ALIGN_TOP)
+ self.control = control
+ if self.enabled:
+ control.Enable()
+ else:
+ control.Disable()
+ p.SetSizer(h)
+ p.Fit()
+ return p
+
+ def Disable(self):
+ self.enabled=0
+ if self.control:
+ self.control.Disable()
+
+ def Enable(self):
+ self.enabled=1
+ if self.control:
+ self.control.Enable()
+
+ def getSettings(self):
+ if not self.enabled:
+ return {}
+ return Option.getSettings(self)
+
+class ChooseAndText(Option):
+ def __init__(self, parameter, text, options, default, editselection, textvalue=""):
+ Option.__init__(self, parameter, text, options, default)
+ self.editselection = editselection
+ self.selection = default
+ self.textvalue = textvalue
+ self.enabled = 0
+ self.choice = None
+
+ def generateControl(self, panel):
+ p = wx.Panel(panel, -1)
+ h = wx.BoxSizer(wx.HORIZONTAL)
+ control = wx.Choice(p, -1, choices=self.options)
+ p.Bind(wx.EVT_CHOICE, self.OnChoice, control)
+ control.SetSelection(self.default)
+ text = wx.StaticText(p, -1, self.text)
+ if self.selection == self.editselection:
+ edittext = wx.TextCtrl(p, -1, self.textvalue)
+ self.textvalue = ""
+ else:
+ edittext = wx.TextCtrl(p, -1, "")
+ edittext.Disable()
+ p.Bind(wx.EVT_TEXT, self.OnText, edittext)
+ h.Add(text,1,wx.EXPAND|wx.ALIGN_LEFT|wx.TOP, 5)
+ h.Add(control,1,wx.EXPAND|wx.ALIGN_RIGHT)
+ h.Add(edittext,1,wx.EXPAND|wx.ALIGN_RIGHT)
+ self.choice = control
+ self.edittext = edittext
+ if self.enabled:
+ control.Enable()
+ else:
+ control.Disable()
+ p.SetSizer(h)
+ p.Fit()
+ return p
+
+ def OnText(self, event):
+ text = self.edittext.GetValue()
+ text2 = "".join(c for c in text if c.isdigit())
+ if text2!=text:
+ self.edittext.SetValue(text2)
+
+ def OnChoice(self, event):
+ self.selection = self.choice.GetCurrentSelection()
+ if self.selection != self.editselection:
+ if not self.textvalue and self.edittext.GetValue():
+ self.textvalue = self.edittext.GetValue()
+ self.edittext.SetValue("")
+ self.edittext.Disable()
+ else:
+ if self.textvalue and not self.edittext.GetValue():
+ self.edittext.SetValue(self.textvalue)
+ self.textvalue = ""
+ self.edittext.Enable()
+
+ def Disable(self):
+ self.enabled=0
+ if not self.choice:
+ return
+ self.choice.Disable()
+ self.edittext.Disable()
+
+ def Enable(self):
+ self.enabled=1
+ if not self.choice:
+ return
+ self.choice.Enable()
+ if self.choice.GetCurrentSelection() == self.editselection:
+ if self.textvalue and not self.edittext.GetValue():
+ self.edittext.SetValue(self.textvalue)
+ self.textvalue = ""
+ self.edittext.Enable()
+ else:
+ self.edittext.Disable()
+
+ def getSettings(self):
+ if not self.enabled:
+ return {}
+ if self.choice.GetCurrentSelection() != self.editselection:
+ value = self.options[self.choice.GetCurrentSelection()]
+ else:
+ value = self.edittext.GetValue().strip()
+ return {self.parameter:value}
+
+class TextOption:
+ def __init__(self, parameter, label, default=""):
+ self.parameter = parameter
+ self.label = label
+ self.default = default
+ self.register()
+
+ def generateControl(self, panel):
+ v = wx.BoxSizer(wx.VERTICAL)
+ self.control = wx.TextCtrl(panel, -1, self.default, size=(250, -1))
+ self.control.Fit()
+ return self.control
+
+ def getSettings(self):
+ settings = {}
+ for items in self.control.GetValue().split(" "):
+ if "=" in items:
+ l = items.split("=")
+ if len(l) == 2:
+ settings[l[0]] = l[1]
+ return settings
+
+ def register(self):
+ global options
+ options += [self]
+
+class RadioOption(Option):
+ def __init__(self, text, options):
+ self.text = text
+ self.options = options
+ self.selected = "==nothing=="
+ self.radios = []
+ self.register()
+
+ def generateControl(self, panel):
+ control = wx.Panel(panel, -1)
+ vsplit = wx.BoxSizer(wx.VERTICAL)
+ for i in range(len(self.options)/2):
+ text = self.options[i*2]
+ if i == 0:
+ c = wx.RadioButton(control, -1, text, style=wx.RB_GROUP)
+ else:
+ c = wx.RadioButton(control, -1, text)
+ control.Bind(wx.EVT_RADIOBUTTON, self.OnRadio, c)
+ self.radios += [c]
+ vsplit.Add(c)
+ control.SetSizer(vsplit)
+ control.Fit()
+ self.control = control
+ return control
+
+ def OnRadio(self, event):
+ self.selected = event.GetEventObject().GetLabel()
+
+ def getSettings(self):
+ for i in range(len(self.options)/2):
+ if self.options[i*2] == self.selected:
+ return self.options[i*2+1]
+ return self.options[1]
+
+class BitmapWindow(wx.Window):
+ def __init__(self, parent, image):
+ wx.Window.__init__(self, parent, -1)
+ self.image = image
+ self.SetMinSize((image.GetWidth()+2, image.GetHeight()+2))
+ self.SetMaxSize((image.GetWidth()+2, image.GetHeight()+2))
+ self.SetSize((image.GetWidth()+2, image.GetHeight()+2))
+ self.Bind(wx.EVT_PAINT, self.OnPaint)
+ self.Update()
+ def OnPaint(self, event):
+ dc = wx.PaintDC(self)
+ self.Draw(dc)
+ def Draw(self,dc=None):
+ if not dc:
+ dc = wx.ClientDC(self)
+ dc.DrawRectangleRect((0, 0, self.image.GetWidth()+2, self.image.GetHeight()+2))
+ dc.DrawBitmap(self.image, 1, 1, False)
+
+class ImageRadioOption(Option):
+ def __init__(self, text, options):
+ self.text = text
+ self.options = options
+ self.selected = "==nothing=="
+ self.radios = []
+ self.register()
+ self.ids = []
+
+ def generateControl(self, panel):
+ control = wx.Panel(panel, -1)
+ vsplit = wx.BoxSizer(wx.VERTICAL)
+ first = 1
+ for image,text,params,selected,extraoptions in self.options:
+ hsplit = wx.BoxSizer(wx.HORIZONTAL)
+
+ v = wx.BoxSizer(wx.VERTICAL)
+
+ name,text = text.split("- ")
+
+ c = wx.CheckBox(control, -1, name)
+ control.Bind(wx.EVT_CHECKBOX, self.OnRadio, c)
+
+ # radio buttons crash windows when clicked on- even without event bindings.
+ # This is caused by the subpanel which is created for extra options
+ # (I tried this with a empty Panel(), and even that crashed)
+ #if first:
+ # c = wx.RadioButton(control, -1, name, style=wx.RB_GROUP)
+ #else:
+ # c = wx.RadioButton(control, -1, name)
+ #control.Bind(wx.EVT_RADIOBUTTON, self.OnRadio, c)
+
+ self.ids += [c.GetId()]
+
+ first = 0
+
+ if "disable" in text:
+ c.Enable(False)
+ if selected:
+ self.selected = c.GetId()
+ c.SetValue(True)
+ else:
+ c.SetValue(False)
+ self.radios += [c]
+
+ bitmap = BitmapWindow(control, image)
+ t = wx.StaticText(control, -1, text, size=(400,50))
+
+ v.Add(c, 0, wx.EXPAND)
+ v.Add(t, 0, wx.EXPAND|wx.LEFT, 20)
+
+ for o in extraoptions:
+ cx = o.generateControl(control)
+ if selected:
+ o.Enable()
+ else:
+ o.Disable()
+ v.Add(cx, 0, wx.EXPAND|wx.LEFT, 20)
+
+ v.SetMinSize((330,170))
+
+ hsplit.Add(bitmap, 0, wx.LEFT|wx.RIGHT|wx.BOTTOM|wx.ALIGN_TOP, 5)
+ hsplit.Add(v, 0, wx.EXPAND)
+ vsplit.Add(hsplit, 0, wx.EXPAND)
+
+ control.SetSizer(vsplit)
+ control.Fit()
+ self.control = control
+ return vsplit
+
+ def OnRadio(self, event):
+ self.selected = event.GetEventObject().GetId()
+ for c in self.radios:
+ if c.GetId() == self.selected:
+ c.SetValue(1)
+ else:
+ c.SetValue(0)
+ i = 0
+ for image,text,params,selected,extraoptions in self.options:
+ if self.ids[i] == self.selected:
+ for xo in extraoptions:
+ xo.Enable()
+ pass
+ else:
+ for xo in extraoptions:
+ xo.Disable()
+ pass
+ i = i + 1
+ event.ResumePropagation(0)
+
+ def getSettings(self):
+ i = 0
+ for image,text,params,s,extraoptions in self.options:
+ id = self.ids[i]
+ i = i + 1
+ if id == self.selected:
+ return params
+ return {}
+
+
+class OptionFrame(wx.Dialog):
+
+ def __init__(self, parent):
+ wx.Dialog.__init__(self, parent, -1, "Options")
+
+ #self.nb = wx.Notebook(self, -1)#, wx.Point(0,0), wx.Size(0,0), wxNB_FIXEDWIDTH)
+ self.nb = wx.Notebook(self, -1)
+
+ self.needreload = 0
+
+ options0 = [RadioOption('Rendering mode',
+ ["Convert polygons to polygons and fonts to fonts", {},
+ "Convert fonts to fonts, everything else to bitmaps", {"poly2bitmap":"1"},
+ "Convert everthing to bitmaps", {"poly2bitmap":"1", "bitmapfonts":"1"}
+ ])]
+
+ mp_options = []
+ sv_options = [Option2('flashversion', 'Flash version:', ('4','5','6','7','8'), 2),
+ Option2('transparent', 'Make SWF file transparent:', ('no','yes'), 0),
+ ]
+
+ raw_options = [Option2('flashversion', 'Flash version:', ('4','5','6','7','8','9'), 2),
+ Option2('insertstop', 'Insert stop after each frame:', ('no','yes'), 0),
+ Option2('transparent', 'Make SWF file transparent:', ('no','yes'), 0),
+ ]
+ rfxview_options = [ChooseAndText('rfxwidth', 'Width:', ('same as PDF','fullscreen','custom'),1,2,"600"),
+ ChooseAndText('rfxheight', 'Height:', ('same as PDF','fullscreen','custom'),1,2,"800"),
+ Option2('rfxzoomtype', 'Initial zoom level:', ('Original resolution','Show all','Maximum width/height'),2),
+ ]
+
+ options4 = [ImageRadioOption('Select Paging GUI',
+ [(staticdata.raw_bitmap, "No Viewer- The SWF will be in \"raw\" format, with each page a seperate frame. Use this if you want to add a viewer yourself afterwards.", {}, 0, raw_options),
+ (staticdata.simpleviewer_bitmap, "SimpleViewer- A tiny viewer, which attaches directly to the SWF, and provides small previous/next buttons in the upper left corner", {"simpleviewer":"1", "insertstop":"1"}, 0, sv_options),
+ (staticdata.rfxview_bitmap, "rfxView- A more sophisticated viewer with zooming and scrolling.", {"rfxview":"1", "flashversion":"8"}, 1, rfxview_options),
+ #(staticdata.motionpaper_bitmap, "MotionPaper- A highly sophisticated viewer with page flipping. (disabled in this evaluation version)", {}, 0, mp_options),
+ #(staticdata.motionpaper_bitmap, "Your advertisement here- Are you are company who developed a viewer for pdf2swf, or who offers commercial PDF hosting service? Place your advertisement or demo viewer here, or allow pdf2swf to upload SWFs directly to your site! contact sales@swftools.org for details.", {}, 0, mp_options),
+ ])]
+
+ options1 = [Option('zoom', 'Resolution (in dpi):', "spinner", 72),
+ Option('fontquality', 'Font quality:', "slider", 20),
+ Option('storeallcharacters', 'Insert full fonts in SWF file:', ('no','yes'), 0),
+ Option('splinequality', 'Polygon quality:', "slider", 100),
+ Option('jpegquality', 'JPEG quality:', "slider", 75),
+ Option('jpegsubpixels', 'JPEG image resolution:', ('same as in PDF', '1x', '2x', '4x'), 0, {"same as in PDF": 0, "1x": 1, "2x": 2, "3x": 3}),
+ Option('ppmsubpixels', 'non-JPEG image resolution:', ('same as in PDF', '1x', '2x', '4x'), 0, {"same as in PDF": 0, "1x": 1, "2x": 2, "3x": 3}),
+ ]
+
+
+ options3 = [TextOption('_additional_', 'Additional options')]
+
+ panel1 = [('Rendering options', options0,''),
+ ('Quality',options1,'v')]
+ panel3 = [('Select paging GUI', options4,'')]
+ panel4 = [('Additional options', options3,'')]
+
+ panels = [('Quality', panel1),
+ ('Viewer', panel3),
+ ('Advanced', panel4)]
+
+ for name,poptions in panels:
+ panel = wx.Panel(self.nb, -1)
+ self.nb.AddPage(panel, name)
+
+ vsplit = wx.BoxSizer(wx.VERTICAL)
+
+ for name,options,align in poptions:
+ optiongroup = wx.StaticBox(panel, -1, name)
+ optiongroupsizer= wx.StaticBoxSizer(optiongroup, wx.VERTICAL)
+ optiongroup.SetSizer(optiongroupsizer)
+
+ if align == 'v':
+ grid = wx.GridSizer(rows=len(options), cols=2, hgap=3, vgap=3)
+ optiongroupsizer.Add(grid, 1, wx.EXPAND, 0)
+ else:
+ grid = wx.GridSizer(rows=len(options), cols=1, hgap=3, vgap=3)
+ optiongroupsizer.Add(grid, 1, wx.EXPAND, 0)
+
+ for option in options:
+ if align=='v':
+ t = wx.StaticText(panel, -1, option.text)
+ grid.Add(t, 0, wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_LEFT)
+ optionbox = option.generateControl(panel)
+ grid.Add(optionbox, 0, wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_LEFT)
+
+ vsplit.Add(optiongroupsizer, 0, wx.EXPAND, 0)
+
+ #hs = wx.BoxSizer(wx.HORIZONTAL)
+ #hs.Add(gobutton, 0, wx.ALIGN_CENTER, 0)
+ gobutton = wx.Button(panel, -1, "Apply")
+ self.Bind(wx.EVT_BUTTON, self.Apply, gobutton)
+
+ vsplit.Add(gobutton, 0, wx.ALIGN_CENTER|wx.ALL, 0)
+
+ panel.SetSizer(vsplit)
+ panel.Fit()
+
+ self.nb.Fit()
+
+ self.Fit()
+
+
+ def updateOptions(self):
+ global options,gfx_options
+ a = []
+
+ # FIXME: we clear *our* options- but gfx will still have
+ # stored the old ones. Critical for options in the "imageradio" section.
+ gfx_options.clear()
+ i = 0
+ print "----- options ------"
+ for option in options:
+ for k,v in option.getSettings().items():
+ gfx_options[k] = v
+ gfx.setparameter(k,v)
+ print k,v
+ i = i + 1
+
+ # TODO: filter out "global" options, and do this only if
+ # pdf layer is affected
+
+ def Apply(self, event):
+ self.updateOptions()
+ self.Hide()
+ self.needreload = 1
+
+
+class State:
+ def __init__(self):
+ self.pdf = None
+ self.page = None
+ self.pagenr = 1
+ self.pagebitmap = None
+ self.bitmap_width = 0
+ self.bitmap_height = 0
+ self.bitmap_page = 0
+ self.filename = None
+ self.status_text = None
+ self.lastsavefile = "output.swf"
+ self.lasthtmlfile = "index.html"
+
+ self.listeners = []
+
+ def onEvent(self,event_type, function):
+ self.listeners += [(event_type,function)]
+ def loadPDF(self,filename):
+ self.filename = filename
+ self.lastsavefile = swapextension(filename,"swf")
+ self.lasthtmlfile = swapextension(filename,"html")
+
+ self.pdf = gfx.open("pdf",filename)
+ if(has_different_size_pages(self.pdf)):
+ # just let the user know- for now, we can't handle this properly
+ dlg = wx.MessageDialog(app.frame, """In this PDF, width or height are not the same for each page. This might cause problems if you export pages of different dimensions into the same SWF file.""", "Notice", style=wx.OK, pos=wx.DefaultPosition)
+ dlg.ShowModal()
+ dlg.Destroy()
+
+ self.changePage(1)
+
+ for type,f in self.listeners:
+ if type&EVENT_PAGE_CHANGE or type&EVENT_FILE_CHANGE:
+ f()
+ self.setStatus("File loaded successfully.")
+
+ def saveSWF(self, filename, progress, pages=None, html=0):
+ if html:
+ basename,ext = os.path.splitext(filename)
+ if not ext:
+ html = basename + ".html"
+ filename = basename + ".swf"
+ elif ext.lower() != ".swf":
+ html = filename
+ filename = basename + ".swf"
+ else:
+ html = basename + ".html"
+ filename = filename
+
+ steps = 100.0 / (self.pdf.pages*2 + 3)
+ pos = [0]
+
+ self.lastsavefile = filename
+ if html:
+ self.lasthtmlfile = html
+
+ swf = gfx.SWF()
+ for k,v in gfx_options.items():
+ swf.setparameter(k,v)
+ if pages is None:
+ pages = range(1,self.pdf.pages+1)
+ pdfwidth,pdfheight=0,0
+ for pagenr in pages:
+ page = self.pdf.getPage(pagenr)
+ pdfwidth = page.width
+ pdfheight = page.height
+ swf.startpage(page.width, page.height)
+ page.render(swf)
+ swf.endpage()
+ swf.save(filename)
+ if not os.path.isfile(filename):
+ error("Couldn't create file "+filename)
+
+ if gfx_options.get("rfxview",None):
+ rfxview = os.path.join(basedir, "rfxview.swf")
+ if not os.path.isfile(rfxview):
+ error("File rfxview.swf not found in working directory")
+ else:
+ size1 = os.stat(filename)[stat.ST_SIZE]
+ swfcombine([rfxview,"viewport="+filename,"-o",filename])
+ size2 = os.stat(filename)[stat.ST_SIZE]
+ if size1 == size2:
+ error("Couldn't add viewer to file "+filename)
+
+ if html:
+ version = int(gfx_options.get("flashversion", "8"))
+ swf = gfx.open("swf", filename)
+ page1 = swf.getPage(1)
+
+ width,height = str(page1.width),str(page1.height)
+
+
+ w = gfx_options.get("rfxwidth","")
+ if w == "fullscreen": width = "100%"
+ elif w == "same as PDF": width = pdfwidth+40
+ elif w.isdigit(): width = w
+ else: width = pdfwidth
+
+ h = gfx_options.get("rfxheight","")
+ if h == "fullscreen": height = "100%"
+ elif h == "same as PDF": height = pdfheight+70
+ elif h.isdigit(): height = h
+ else: height = pdfwidth
+
+ flashvars = ""
+ zoomtype = gfx_options.get("rfxzoomtype","")
+ if zoomtype=="Original resolution":
+ flashvars = "zoomtype=1"
+ elif zoomtype=="Show all":
+ flashvars = "zoomtype=2"
+ elif zoomtype=="Maximum width/height":
+ flashvars = "zoomtype=3"
+
+ swffilename = os.path.basename(filename)
+ fi = open(html, "wb")
+ fi.write(HTMLTEMPLATE % locals())
+ fi.close()
+
+
+ def changePage(self,page):
+ self.pagenr = page
+ self.page = self.pdf.getPage(self.pagenr)
+ for type,f in self.listeners:
+ if type&EVENT_PAGE_CHANGE:
+ f()
+
+ def getPageIcon(self,pagenr):
+ page = self.pdf.getPage(pagenr)
+ return wx.BitmapFromImage(wx.ImageFromData(ICON_SIZE,ICON_SIZE,page.asImage(ICON_SIZE,ICON_SIZE)))
+ #return wx.BitmapFromImage(wx.ImageFromData(8,8,"0"*(64*3)))
+
+ def getPageImage(self, width, height):
+ if self.bitmap_width == width and self.bitmap_height == height and self.bitmap_page == self.pagenr:
+ return self.pagebitmap
+ else:
+ self.bitmap_width = width
+ self.bitmap_height = height
+ self.bitmap_page = self.pagenr
+ self.pagebitmap = wx.BitmapFromImage(wx.ImageFromData(width,height,self.page.asImage(width,height)))
+ #self.pagebitmap = wx.BitmapFromImage(wx.ImageFromData(8,8,"0"*(64*3)))
+ return self.pagebitmap
+
+ def setStatus(self,text):
+ self.status_text = text
+ for type,f in self.listeners:
+ if type&EVENT_STATUS_TEXT:
+ f()
+
+state = State()
+
+class PageListWidget(wx.ListCtrl):
+ def __init__(self,parent):
+ wx.ListCtrl.__init__(self,parent,style=wx.LC_ICON|wx.LC_AUTOARRANGE)
+ #self.SetMinSize((ICON_SIZE+8,-1))
+ #self.SetMaxSize((ICON_SIZE+8,-1))
+ #self.SetSize((ICON_SIZE+8,-1))
+ self.Bind(wx.EVT_LIST_ITEM_SELECTED, self.SelectItem)
+ state.onEvent(EVENT_FILE_CHANGE, self.reload)
+ state.onEvent(EVENT_PAGE_CHANGE, self.switchPage)
+ self.reload()
+ self.dontcare = 0
+ #self.Bind(wx.EVT_IDLE, self.OnIdle)
+ #print dir(self)
+
+ def processFiles(self):
+ if self.filepos >= 0 and self.filepos < state.pdf.pages:
+ icon = state.getPageIcon(self.filepos+1)
+ self.imglist.Add(icon)
+ self.InsertImageStringItem(self.filepos, str(self.filepos+1), self.filepos)
+ self.filepos = self.filepos + 1
+ self.Update()
+
+ def OnIdle(self,event):
+ self.processFiles()
+ event.ResumePropagation(0)
+
+ def reload(self):
+ self.filepos = -1
+ self.DeleteAllItems()
+ self.imglist = wx.ImageList(ICON_SIZE,ICON_SIZE,mask=False)
+ self.AssignImageList(self.imglist,wx.IMAGE_LIST_NORMAL)
+ self.filepos = 0
+ while state.pdf and self.filepos < state.pdf.pages:
+ self.processFiles()
+
+ def switchPage(self):
+ if self.dontcare:
+ self.dontcare = 0
+ return
+ for i in range(0,self.GetItemCount()):
+ self.Select(i, False)
+ self.Select(state.pagenr-1, True)
+ self.Focus(state.pagenr-1)
+ self.Update()
+
+ def SelectItem(self,event):
+ self.dontcare = 1 #ignore next change event
+ state.changePage(event.GetIndex()+1)
+
+
+helptxt = """
+This is the SWF preview window.
+Here, you will see how the SWF file generated from
+the PDF file will look like. Changing parameters in
+the configuration which affect the appeareance of
+the final SWF will affect this preview, too, so you
+can always evaluate the final output beforehand.
+"""
+
+
+class OnePageWidget(wx.Window):
+ def __init__(self,parent):
+ wx.Window.__init__(self, parent)
+ self.SetSize((160,100))
+ self.SetMinSize((160,100))
+ self.Fit()
+ self.Bind(wx.EVT_PAINT, self.OnPaint)
+ self.Bind(wx.EVT_SIZE, self.OnSize)
+ self.Bind(wx.EVT_KEY_DOWN, self.key_down)
+ state.onEvent(EVENT_PAGE_CHANGE, self.OnPageChange)
+
+ def key_down(self, event):
+ if state.pdf:
+ if event.GetKeyCode() == 312 and state.pagenr>1:
+ state.changePage(state.pagenr-1)
+ elif event.GetKeyCode() == 313 and state.pagenr<state.pdf.pages:
+ state.changePage(state.pagenr+1)
+
+ def OnPageChange(self):
+ self.Refresh()
+
+ def OnSize(self, event):
+ self.Refresh()
+
+ def Draw(self,dc=None):
+ global bitmap
+ if not dc:
+ dc = wx.ClientDC(self)
+ posx = 0
+ posy = 0
+ window_width,window_height = self.GetSize()
+ dc.Clear()
+
+ if not state.pdf or not state.page:
+ return
+
+ if state.page.width * window_height > state.page.height * window_width:
+ width = window_width
+ height = window_width * state.page.height / state.page.width
+ posy = (window_height - height) / 2
+ else:
+ width = window_height * state.page.width / state.page.height
+ height = window_height
+ posx = (window_width - width) / 2
+
+ dc.DrawBitmap(state.getPageImage(width,height), posx,posy, False)
+ #state.getPageImage(
+
+ def OnPaint(self, event):
+ dc = wx.PaintDC(self)
+ self.Draw(dc)
+
+class Pdf2swfFrame(wx.Frame):
+ #def __init__(self):
+ #wx.Window.__init__(self, None, id=-1, pos=wx.DefaultPosition, size=wx.DefaultSize)
+ def __init__(self,application):
+ wx.Frame.__init__(self, None, -1, style = wx.DEFAULT_FRAME_STYLE)
+ self.application = application
+
+ self.SetTitle("pdf2swf")
+ self.createMenu()
+ self.createToolbar()
+ self.createStatusBar()
+ self.createMainFrame()
+
+ self.SetSize((800,600))
+
+ self.options = OptionFrame(None)
+ self.options.Show(False)
+ self.options.updateOptions()
+
+ state.onEvent(EVENT_STATUS_TEXT, self.status_change)
+ self.html = 0
+
+ #self.table = wx.AcceleratorTable([(wx.ACCEL_ALT, ord('X'), 333),])
+ #self.SetAcceleratorTable(self.table)
+
+ self.Bind(wx.EVT_IDLE, self.OnIdle)
+ self.Bind(wx.EVT_CLOSE, self.menu_exit)
+ return
+
+ def menu_open(self,event):
+ global state
+ if state.filename:
+ dlg = wx.FileDialog(self, "Choose PDF File:", style = wx.DD_DEFAULT_STYLE, defaultFile = state.filename, wildcard = "PDF files (*.pdf)|*.pdf|all files (*.*)|*.*")
+ else:
+ dlg = wx.FileDialog(self, "Choose PDF File:", style = wx.DD_DEFAULT_STYLE, wildcard = "PDF files (*.pdf)|*.pdf|all files (*.*)|*.*")
+
+ if dlg.ShowModal() == wx.ID_OK:
+ self.filename = dlg.GetFilename()
+ state.loadPDF(self.filename)
+
+ def menu_save(self,event,pages=None):
+ html,self.html = self.html,0
+ global state
+ if not state.pdf:
+ return
+ print "html",html
+ if not html:
+ defaultFile = state.lastsavefile
+ else:
+ defaultFile = state.lasthtmlfile
+ dlg = wx.FileDialog(self, "Choose Save Filename:", style = wx.SAVE | wx.OVERWRITE_PROMPT, defaultFile = defaultFile, wildcard = "all files (*.*)|*.*|SWF files (*.swf)|*.swf|HTML template (*.html)|*.html")
+
+ if dlg.ShowModal() == wx.ID_OK:
+ filename = os.path.join(dlg.GetDirectory(),dlg.GetFilename())
+
+ #progress = ProgressFrame(self, "Saving %s File '%s'..." % (html and "HTML" or "SWF", filename))
+ #progress.Show(True)
+ progress = None
+ state.saveSWF(filename, progress, pages, html)
+ #progress.Destroy()
+
+ def menu_save_selected(self,event):
+ if not state.pdf:
+ return
+ p = []
+ for i in range(0,self.pagelist.GetItemCount()):
+ if self.pagelist.IsSelected(i):
+ p += [i+1]
+ self.menu_save(event, pages=p)
+
+ def menu_save_html(self,event):
+ self.html = 1
+ return self.menu_save(event)
+
+ def menu_save_selected_html(self,event):
+ self.html = 1
+ return self.menu_save_selected(event)
+
+ def menu_exit(self,event):
+ self.application.Exit()
+
+ def menu_selectall(self,event):
+ for i in range(0,self.pagelist.GetItemCount()):
+ self.pagelist.Select(i, True)
+ def menu_options(self,event):
+ self.options.Show(True)
+
+ def status_change(self):
+ self.statusbar.SetStatusText(state.status_text)
+
+ def OnIdle(self,event):
+ if self.options.needreload:
+ self.options.needreload = 0
+ if state.pdf:
+ # reload
+ state.loadPDF(state.filename)
+
+ def createMenu(self):
+ menubar = wx.MenuBar()
+
+ menu = wx.Menu();menubar.Append(menu, "&File")
+ menu.Append(wx.ID_OPEN, "Open PDF\tCTRL-O");self.Bind(wx.EVT_MENU, self.menu_open, id=wx.ID_OPEN)
+ menu.AppendSeparator()
+ menu.Append(wx.ID_SAVE, "Save SWF (all pages)\tCTRL-W");self.Bind(wx.EVT_MENU, self.menu_save, id=wx.ID_SAVE)
+ menu.Append(wx.ID_SAVEAS, "Save SWF (selected pages)\tCTRL-S");self.Bind(wx.EVT_MENU, self.menu_save_selected, id=wx.ID_SAVEAS)
+ menu.AppendSeparator()
+ menu.Append(2001, "Save HTML template (all pages)\tCTRL-H");self.Bind(wx.EVT_MENU, self.menu_save_html, id=2001)
+ menu.Append(2002, "Save HTML template (selected pages)");self.Bind(wx.EVT_MENU, self.menu_save_selected_html, id=2002)
+ menu.AppendSeparator()
+ menu.Append(wx.ID_EXIT, "Exit\tCTRL-Q");self.Bind(wx.EVT_MENU, self.menu_exit, id=wx.ID_EXIT)
+
+ menu = wx.Menu();menubar.Append(menu, "&Edit")
+ menu.Append(wx.ID_SELECTALL, "Select All\tCTRL-A");self.Bind(wx.EVT_MENU, self.menu_selectall, id=wx.ID_SELECTALL)
+ menu.AppendSeparator()
+ menu.Append(wx.ID_PREFERENCES, "Options\tCTRL-R");self.Bind(wx.EVT_MENU, self.menu_options, id=wx.ID_PREFERENCES)
+
+ menu = wx.Menu();menubar.Append(menu, "&Help")
+
+ self.SetMenuBar(menubar)
+
+
+ def createToolbar(self):
+
+ tsize = (16,16)
+ self.toolbar = self.CreateToolBar(wx.TB_HORIZONTAL | wx.NO_BORDER | wx.TB_FLAT)
+
+ self.toolbar.AddSimpleTool(wx.ID_OPEN,
+ wx.ArtProvider.GetBitmap(wx.ART_FILE_OPEN, wx.ART_TOOLBAR, tsize),
+ "Open")
+ self.toolbar.AddSimpleTool(wx.ID_SAVE,
+ wx.ArtProvider.GetBitmap(wx.ART_FILE_SAVE, wx.ART_TOOLBAR, tsize),
+ "Save selected pages")
+ self.toolbar.AddSimpleTool(wx.ID_PREFERENCES,
+ wx.ArtProvider.GetBitmap(wx.ART_LIST_VIEW, wx.ART_TOOLBAR, tsize),
+ "Options")
+ #self.toolbar.AddSeparator()
+ self.toolbar.Realize()
+
+ def createStatusBar(self):
+ self.statusbar = self.CreateStatusBar(1)
+
+ def createMainFrame(self):
+
+ if 0:
+ self.pagelist = PageListWidget(self)
+ self.onepage = OnePageWidget(self)
+ hsplit = wx.BoxSizer(wx.HORIZONTAL)
+ pagelistbox = wx.StaticBox(self, -1, "Pages")
+ pagelistboxsizer= wx.StaticBoxSizer(pagelistbox, wx.VERTICAL)
+ pagelistboxsizer.Add(self.pagelist, proportion=1, flag=wx.EXPAND)
+ onepagebox = wx.StaticBox(self, -1, "Page 1")
+ onepageboxsizer= wx.StaticBoxSizer(onepagebox, wx.VERTICAL)
+ onepageboxsizer.Add(self.onepage, proportion=1, flag=wx.EXPAND)
+ hsplit.Add(pagelistboxsizer, 0, wx.EXPAND, 0)
+ hsplit.Add(onepageboxsizer, 1, wx.EXPAND, 0)
+ self.SetAutoLayout(True)
+ self.SetSizer(hsplit)
+ hsplit.Fit(self)
+ hsplit.SetSizeHints(self)
+ else:
+ hsplit = wx.SplitterWindow(self, style=wx.SP_3D|wx.SP_LIVE_UPDATE)
+ #p1 = wx.Panel(hsplit,-1, style=wx.SUNKEN_BORDER)
+ #p2 = wx.Panel(hsplit,-1, style=wx.SUNKEN_BORDER)
+ self.pagelist = PageListWidget(hsplit)
+ self.onepage = OnePageWidget(hsplit)
+ #hsplit.SplitVertically(p1,p2, sashPosition=64)
+ hsplit.SplitVertically(self.pagelist, self.onepage, sashPosition=ICON_SIZE*3/2)
+ hsplit.SetMinimumPaneSize(10)
+
+class MyApp(wx.App):
+ def __init__(self):
+ wx.App.__init__(self, redirect=False, filename=None, useBestVisual=False)
+
+ #state.loadPDF("sitis2007.pdf")
+ #state.loadPDF("wxPython-Advanced-OSCON2004.pdf")
+ global staticdata
+ staticdata = StaticData()
+
+ self.frame = Pdf2swfFrame(self)
+ self.SetTopWindow(self.frame)
+ self.frame.Show(True)
+
+ #self.frame = TestFrame(self)
+ #self.frame.Show(True)
+
+ def OnInit(self):
+ return True
+
+
raw_width=100
raw_height=100
raw_data="""\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xfe\xfe\xfe\xfe\xfe\xff\xff\xff\xfe\xfe\xfe\xff\xff\xff\xfe\xfe\xfe\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xfe\xfe\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfa\xfa\xfa\xff\xff\xffQQQ\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"""+\
"""\xff\xff\xff\xfe\xfe\xfe\xfd\xfd\xfd\xff\xff\xff\xfe\xfe\xfe\xfd\xfd\xfd\xfe\xfe\xfe\xff\xff\xff\xfd\xfd\xfd\xff\xff\xff\xfd\xfd\xfd\xfd\xfd\xfd\xfe\xfe\xfe\xfe\xfe\xfe\xff\xff\xff\xfd\xfd\xfd\xfd\xfd\xfd\xff\xff\xff\xfe\xfe\xfe\xfd\xfd\xfd\xfc\xfc\xfc\xfe\xfe\xfe\xff\xff\xff\xfe\xfe\xfe\xfe\xfe\xfe\xff\xff\xff\xfe\xfe\xfe\xff\xff\xff\xfe\xfe\xfe\xff\xff\xff\xfe\xfe\xfe\xfd\xfd\xfd\xfd\xfd\xfd\xfd"""+\
"""\xfd\xfd\xfe\xfe\xfe\xfe\xfe\xfe\xfd\xfd\xfd\xfe\xfe\xfe\xff\xff\xff\xfe\xfe\xfe\xfd\xfd\xfd\xfd\xfd\xfd\xfe\xfe\xfe\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfe\xfe\xfe\xff\xff\xff\xfe\xfe\xfe\xff\xff\xff\xfe\xfe\xfe\xfb\xfb\xfb\xff\xff\xff\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xff\xff\xff\xf3\xf3\xf3\xa6\xa6\xa6\xf7\xf7\xf7\xff\xff\xff\xfe\xfe\xfe\xfd\xfd\xfd\xfc\xfc\xfc\xff\xff\xff\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfe\xfe\xfe\xfe\xfe\xfe\xfd\xfd\xfd\xff\xff\xff\xfe\xfe\xfe\xfe\xfe\xfe\xff\xff\xff\xfe\xfe\xfe\xfe\xfe\xfe\xff\xff\xff\xfe\xfe\xfe\xfd\xfd\xfd\xfe\xfe\xfe\xff\xff\xff\xfe\xfe\xfe\xfe\xfe\xfe\xfd\xfd\xfd\xff\xff\xff\xc3\xc3\xc3\xb2\xb2\xb2\xec\xec\xec\xff\xff\xff\xff\xff\xff\xd1\xd1\xd1\xcb\xcb\xcb\xb0\xb0\xb0bbbkkk\xb1\xb1\xb1\xfb\xfb\xfb\xfd\xfd\xfd\xfe\xfe\xfe\xfd\xfd\xfd\xfd\xfd\xfd\xfe\xfe\xfe\xfd\xfd\xfd\xfb\xfb\xfb\xfd\xfd\xfd\xfc\xfc\xfc\xfc\xfc\xfc\xfd\xfd\xfd\xfd\xfd\xfd\xfc\xfc\xfc\xfc\xfc\xfc\xfc\xfc\xfc\xfc\xfc\xfc\xfb\xfb\xfb\xfc\xfc\xfc\xfe\xfe\xfe\xff\xff\xff\xfc\xfc\xfc\xfb\xfb\xfb\xfc\xfc\xfc\xfd\xfd\xfd\xfb\xfb\xfb\xfd\xfd\xfd\xfa\xfa\xfa\xfd\xfd\xfd\xfe\xfe\xfe\xfe\xfe\xfe\xfd\xfd\xfd\xfc\xfc\xfc\xfd\xfd\xfd\xfb\xfb\xfb\xfb\xfb\xfb\xfd\xfd\xfd\xfc\xfc\xfc\xfc\xfc\xfc\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfe\xfe\xfe\xfb\xfb\xfb\xfc\xfc\xfc\xfc\xfc\xfc\xfb\xfb\xfb\xfc\xfc\xfc\xff\xff\xff\xfb\xfb\xfb\xfd\xfd\xfd\xfc\xfc\xfc\xfc\xfc\xfc\xfc\xfc\xfc\xfd\xfd\xfd\xfd\xfd\xfd\xfe\xfe\xfe\xfd\xfd\xfd\xfd\xfd\xfd\xfc\xfc\xfc\xfe\xfe\xfe\xfe\xfe\xfe\xfb\xfb\xfb\xfc\xfc\xfc\xfd\xfd\xfd\xfb\xfb\xfb\xfd\xfd\xfd\xfc\xfc\xfc\xfb\xfb\xfb\xfd\xfd\xfd\xfc\xfc\xfc\xfd\xfd\xfd\xfd\xfd\xfd\xfc\xfc\xfc\xfc\xfc\xfc\xfd\xfd\xfd\xfd\xfd\xfd\xfc\xfc\xfc\xfe\xfe\xfe\xfc\xfc\xfc\xfc\xfc\xfc\xfd\xfd\xfd\xfc\xfc\xfc\xfc\xfc\xfc\xfc\xfc\xfc\xfe\xfe\xfe\xff\xff\xff\xff\xff\xff\xfb\xfb\xfb\xff\xff\xff\xd0\xd0\xd0\xcb\xcb\xcb\xb0\xb0\xb0bbbkkk\xb1\xb1\xb1\xf5\xf5\xf5\xc0\xc0\xc0\xc4\xc4\xc4\xff\xff\xff\xfc\xfc\xfc\xfd\xfd\xfd\xfe\xfe\xfe\xff\xff\xff\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xff\xff\xff\xfe\xfe\xfe\xfd\xfd\xfd\xff\xff\xff\xf2\xf2\xf2\xc8\xc8\xc8\xff\xff\xff\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfd\xfd\xfd\xff\xff\xff\xfa\xfa\xfa\xc5\xc5\xc5\xfd\xfd\xfd\xfe\xfe\xfe\xfe\xfe\xfe\xfd\xfd\xfd\xff\xff\xff\xfe\xfe\xfe\xfd\xfd\xfd\xfe\xfe\xfe\xfc\xfc\xfc\xff\xff\xff\xc9\xc9\xc9\xef\xef\xef\xff\xff\xff\xfe\xfe\xfe\xfd\xfd\xfd\xfe\xfe\xfe\xfd\xfd\xfd\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xff\xff\xff\xf5\xf5\xf5\xb0\xb0\xb0\xfa\xfa\xfa\xff\xff\xff\xfd\xfd\xfd\xff\xff\xff\xfe\xfe\xfe\xff\xff\xff\xff\xff\xff\xfc\xfc\xfc\xfd\xfd\xfd\xfc\xfc\xfc\xff\xff\xff\xd3\xd3\xd3\xe2\xe2\xe2\xff\xff\xff\xfe\xfe\xfe\xfe\xfe\xfe\xff\xff\xff\xfe\xfe\xfe\xfd\xfd\xfd\xff\xff\xff\xfd\xfd\xfd\xfd\xfd\xfd\xfe\xfe\xfe\xfd\xfd\xfd\xfe\xfe\xfe\xff\xff\xff\xfd\xfd\xfd\xfd\xfd\xfd\xff\xff\xff\xfe\xfe\xfe\xfe\xfe\xfe\xff\xff\xff\xfd\xfd\xfd\xfe\xfe\xfe\xfe\xfe\xfe\xfd\xfd\xfd\xfd\xfd\xfd\xfe\xfe\xfe\xfe\xfe\xfe\xfd\xfd\xfd\xff\xff\xff\xd1\xd1\xd1\xcb\xcb\xcb\xb0\xb0\xb0bbbkkk\xb1\xb1\xb1\x80\x80\x80\x97\x97\x97\xf2\xf2\xf2\xfe\xfe\xfe\xfc\xfc\xfc\xff\xff\xff\xe8\xe8\xe8\xde\xde\xde\xed\xed\xed\xea\xea\xea\xe6\xe6\xe6\xf2\xf2\xf2\xec\xec\xec\xe9\xe9\xe9\xf9\xf9\xf9\xe2\xe2\xe2\xd6\xd6\xd6\xf1\xf1\xf1\xa4\xa4\xa4\xe9\xe9\xe9\xdd\xdd\xdd\xec\xec\xec\xe0\xe0\xe0\xe2\xe2\xe2\xf2\xf2\xf2\xe4\xe4\xe4\xfa\xfa\xfa\xa5\xa5\xa5\xe4\xe4\xe4\xda\xda\xda\xfc\xfc\xfc\xe3\xe3\xe3\xe5\xe5\xe5\xfa\xfa\xfa\xe0\xe0\xe0\xd5\xd5\xd5\xfb\xfb\xfb\xfe\xfe\xfe\xfd\xfd\xfd\xff\xff\xff\xd8\xd8\xd8\xf4\xf4\xf4\xf6\xf6\xf6\xe9\xe9\xe9\xff\xff\xff\xfc\xfc\xfc\xff\xff\xff\xc7\xc7\xc7\xbb\xbb\xbb\xf8\xf8\xf8\xe4\xe4\xe4\xf8\xf8\xf8\x7c\x7c\x7c\xe0\xe0\xe0\xe5\xe5\xe5\xf8\xf8\xf8\xe3\xe3\xe3\xf8\xf8\xf8\xe6\xe6\xe6\xd3\xd3\xd3\xf5\xf5\xf5\xff\xff\xff\xfc\xfc\xfc\xff\xff\xff\xdf\xdf\xdf\xe8\xe8\xe8\xec\xec\xec\xd1\xd1\xd1\xf8\xf8\xf8\xad\xad\xad\xdb\xdb\xdb\xf5\xf5\xf5\xda\xda\xda\xfa\xfa\xfa\xfe\xfe\xfe\xfd\xfd\xfd\xff\xff\xff\xf2\xf2\xf2\xe4\xe4\xe4\xfc\xfc\xfc\xf5\xf5\xf5\xd9\xd9\xd9\xf7\xf7\xf7\xef\xef\xef\xdb\xdb\xdb\xfc\xfc\xfc\xe6\xe6\xe6\xe3\xe3\xe3\xf4\xf4\xf4\xe8\xe8\xe8\xe7\xe7\xe7\xef\xef\xef\xe8\xe8\xe8\xd8\xd8\xd8\xc6\xc6\xc6\xcd\xcd\xcd\xaf\xaf\xafbbbkkk\xb1\xb1\xb1ddd\x9e\x9e\x9e\xff\xff\xff\xfb\xfb\xfb\xff\xff\xff\xcc\xcc\xcc\xbd\xbd\xbd\x98\x98\x98\xa4\xa4\xa4\xa3\xa3\xa3\xa4\xa4\xa4\xa8\xa8\xa8\xca\xca\xca\x8c\x8c\x8c\xc0\xc0\xc0\x82\x82\x82\x8e\x8e\x8e\xaa\xaa\xaa\x83\x83\x83\xd8\xd8\xd8\x7f\x7f\x7f\xf4\xf4\xf4\x91\x91\x91\x95\x95\x95\xd9\xd9\xd9\x93\x93\x93\xb1\xb1\xb1\x82\x82\x82\xd8\xd8\xd8\x86\x86\x86\xba\xba\xba\xbc\xbc\xbc\x9c\x9c\x9c\xa7\xa7\xa7\x87\x87\x87\x87\x87\x87\xc7\xc7\xc7\xff\xff\xff\xfa\xfa\xfa\xff\xff\xff\x87\x87\x87\xbe\xbe\xbe\x96\x96\x96\xdf\xdf\xdf\xff\xff\xff\xfb\xfb\xfb\xff\xff\xff\xa0\xa0\xa0\xa5\xa5\xa5\xd5\xd5\xd5\x8f\x8f\x8f\xbe\xbe\xbe\x87\x87\x87\xad\xad\xad\xe5\xe5\xe5\xaf\xaf\xaf\x7f\x7f\x7f\xad\xad\xad\x87\x87\x87\x8e\x8e\x8e\xa9\xa9\xa9\xff\xff\xff\xf8\xf8\xf8\xff\xff\xff\x99\x99\x99\xb7\xb7\xb7\x8b\x8b\x8b\x8e\x8e\x8e\xa6\xa6\xa6\x8c\x8c\x8c\xbc\xbc\xbc\xab\xab\xab\xb9\xb9\xb9\x98\x98\x98\xff\xff\xff\xfa\xfa\xfa\xff\xff\xff\xc9\xc9\xc9\x97\x97\x97\xa9\xa9\xa9\xbe\xbe\xbe\xc0\xc0\xc0\xaa\xaa\xaa\xbe\xbe\xbe\xbc\xbc\xbc\xa6\xa6\xa6\xbc\xbc\xbc\xa4\xa4\xa4\x9c\x9c\x9c\xa2\xa2\xa2\xa3\xa3\xa3\xa9\xa9\xa9\x8b\x8b\x8b\x94\x94\x94uuu\xdb\xdb\xdb\xae\xae\xaeccclll\xb2\xb2\xb2mmm\xab\xab\xab\xff\xff\xff\xf8\xf8\xf8\xff\xff\xff\x9b\x9b\x9b\xc0\xc0\xc0\xaf\xaf\xaf\xa5\xa5\xa5\xa3\xa3\xa3\xa9\xa9\xa9\x9c\x9c\x9c\xbd\xbd\xbd\x80\x80\x80\xb6\xb6\xb6\x9c\x9c\x9c\xb3\xb3\xb3\x9e\x9e\x9e\x95\x95\x95\xe6\xe6\xe6\x7c\x7c\x7c\xf2\xf2\xf2nnn\xf4\xf4\xf4\xb8\xb8\xb8\x90\x90\x90\xa6\xa6\xa6\x93\x93\x93\xe5\xe5\xe5\x83\x83\x83\x84\x84\x84\xc8\xc8\xc8\xbe\xbe\xbe\x87\x87\x87\xa7\xa7\xa7\xa9\xa9\xa9\xb6\xb6\xb6\xff\xff\xff\xf9\xf9\xf9\xff\xff\xff\x82\x82\x82\xcf\xcf\xcf\x95\x95\x95\x85\x85\x85\xff\xff\xff\xfa\xfa\xfa\xff\xff\xff\xaa\xaa\xaa\xb3\xb3\xb3\xc5\xc5\xc5\x89\x89\x89\xb3\xb3\xb3ssslll\xe9\xe9\xe9xxx\xeb\xeb\xeb\xdd\xdd\xdd\x90\x90\x90\xbe\xbe\xbe\x9c\x9c\x9c\xff\xff\xff\xf8\xf8\xf8\xff\xff\xff\x9b\x9b\x9b\xb6\xb6\xb6\x9b\x9b\x9b\xbe\xbe\xbe\x9d\x9d\x9d\xa0\xa0\xa0\xab\xab\xab\x89\x89\x89\xf4\xf4\xf4\x79\x79\x79\xff\xff\xff\xfb\xfb\xfb\xff\xff\xff\xb7\xb7\xb7\x97\x97\x97\x87\x87\x87\x8a\x8a\x8a\xff\xff\xff\xb6\xb6\xb6\x92\x92\x92\xff\xff\xff\x8c\x8c\x8c\xbb\xbb\xbb\xce\xce\xce\x7b\x7b\x7b\xa5\xa5\xa5\xa4\xa4\xa4\xa9\xa9\xa9\x99\x99\x99\xc3\xc3\xc3hhh\xdc\xdc\xdc\xae\xae\xaeccclll\xb2\xb2\xb2\x85\x85\x85\xab\xab\xab\xff\xff\xff\xfc\xfc\xfc\xff\xff\xff\xde\xde\xde\x88\x88\x88xxx\xc4\xc4\xc4\x98\x98\x98\x93\x93\x93\xb2\xb2\xb2\x90\x90\x90\x99\x99\x99\xa7\xa7\xa7\xa9\xa9\xa9\xb5\xb5\xb5\xb6\xb6\xb6\x9a\x9a\x9a\xc1\xc1\xc1\x9f\x9f\x9f\xa9\xa9\xa9\x9e\x9e\x9e\xd8\xd8\xd8\x8c\x8c\x8c\x97\x97\x97\xa7\xa7\xa7\x9c\x9c\x9c\xc0\xc0\xc0\x97\x97\x97\xd4\xd4\xd4\xa5\xa5\xa5\xc8\xc8\xc8\xce\xce\xce\xa5\xa5\xa5\xb1\xb1\xb1\xbf\xbf\xbf\xff\xff\xff\xfb\xfb\xfb\xff\xff\xff\x98\x98\x98\xc1\xc1\xc1\xd8\xd8\xd8\xad\xad\xad\xfd\xfd\xfd\xfd\xfd\xfd\xff\xff\xff\xc8\xc8\xc8\x9c\x9c\x9c\x94\x94\x94\x98\x98\x98\x9d\x9d\x9d\xaa\xaa\xaa\xa3\xa3\xa3\xad\xad\xad\x9e\x9e\x9e\x98\x98\x98\xde\xde\xde\x9d\x9d\x9d\xbe\xbe\xbe\xa8\xa8\xa8\xff\xff\xff\xfa\xfa\xfa\xff\xff\xff\xa9\xa9\xa9\xb6\xb6\xb6\xa4\xa4\xa4\xbd\xbd\xbd\xad\xad\xad\xaa\xaa\xaa\xb9\xb9\xb9\xaf\xaf\xaf\xb9\xb9\xb9\xd9\xd9\xd9\xff\xff\xff\xfb\xfb\xfb\xff\xff\xff\x93\x93\x93\x96\x96\x96\xa9\xa9\xa9\x9e\x9e\x9e\x87\x87\x87\xe7\xe7\xe7\x81\x81\x81\xa3\xa3\xa3\xe1\xe1\xe1\xa3\xa3\xa3\xc2\xc2\xc2\xe4\xe4\xe4\x92\x92\x92\x92\x92\x92\xb9\xb9\xb9\xa3\xa3\xa3\xc2\xc2\xc2\x82\x82\x82\xd8\xd8\xd8\xae\xae\xaeccclll\xb2\xb2\xb2\xfd\xfd\xfd\xfc\xfc\xfc\xfe\xfe\xfe\xff\xff\xff\xfe\xfe\xfe\xfb\xfb\xfb\xff\xff\xff\x8a\x8a\x8a\xbe\xbe\xbe\xff\xff\xff\xfa\xfa\xfa\xff\xff\xff\xfc\xfc\xfc\xfd\xfd\xfd\xfc\xfc\xfc\xfd\xfd\xfd\xfc\xfc\xfc\xfd\xfd\xfd\xfd\xfd\xfd\xfc\xfc\xfc\xfd\xfd\xfd\xfd\xfd\xfd\xf9\xf9\xf9\xfa\xfa\xfa\xfe\xfe\xfe\xfc\xfc\xfc\xfe\xfe\xfe\xfe\xfe\xfe\xfc\xfc\xfc\xfd\xfd\xfd\xfe\xfe\xfe\xfb\xfb\xfb\xfb\xfb\xfb\xfe\xfe\xfe\xfc\xfc\xfc\xfc\xfc\xfc\xfd\xfd\xfd\xfe\xfe\xfe\xff\xff\xff\xfe\xfe\xfe\xfc\xfc\xfc\xfd\xfd\xfd\xf8\xf8\xf8\xfd\xfd\xfd\xff\xff\xff\xfe\xfe\xfe\xff\xff\xff\xfe\xfe\xfe\xfc\xfc\xfc\xfd\xfd\xfd\xfc\xfc\xfc\xfd\xfd\xfd\xfc\xfc\xfc\xfd\xfd\xfd\xfc\xfc\xfc\xfd\xfd\xfd\xfa\xfa\xfa\xfd\xfd\xfd\xfc\xfc\xfc\xfc\xfc\xfc\xfd\xfd\xfd\xfe\xfe\xfe\xff\xff\xff\xfe\xfe\xfe\xfd\xfd\xfd\xfc\xfc\xfc\xfc\xfc\xfc\xfc\xfc\xfc\xfd\xfd\xfd\xfd\xfd\xfd\xfc\xfc\xfc\xfd\xfd\xfd\xf9\xf9\xf9\xff\xff\xff\xfe\xfe\xfe\xfe\xfe\xfe\xff\xff\xff\xfd\xfd\xfd\xfc\xfc\xfc\xfe\xfe\xfe\xfe\xfe\xfe\xfb\xfb\xfb\xff\xff\xff\xfd\xfd\xfd\xfc\xfc\xfc\xff\xff\xff\xfb\xfb\xfb\xfa\xfa\xfa\xff\xff\xff\xfc\xfc\xfc\xfc\xfc\xfc\xfe\xfe\xfe\xfb\xfb\xfb\xff\xff\xff\xd2\xd2\xd2\xcc\xcc\xcc\xb1\xb1\xb1ccclll\xb2\xb2\xb2\xfd\xfd\xfd\xfe\xfe\xfe\xff\xff\xff\xfe\xfe\xfe\xff\xff\xff\xfe\xfe\xfe\xff\xff\xff\xe2\xe2\xe2\xec\xec\xec\xff\xff\xff\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfe\xfe\xfe\xfd\xfd\xfd\xfd\xfd\xfd\xfe\xfe\xfe\xfd\xfd\xfd\xfe\xfe\xfe\xfd\xfd\xfd\xfe\xfe\xfe\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfe\xfe\xfe\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xff\xff\xff\xfd\xfd\xfd\xfe\xfe\xfe\xfe\xfe\xfe\xfd\xfd\xfd\xfe\xfe\xfe\xfd\xfd\xfd\xfe\xfe\xfe\xff\xff\xff\xfd\xfd\xfd\xfe\xfe\xfe\xfe\xfe\xfe\xff\xff\xff\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfe\xfe\xfe\xfd\xfd\xfd\xfe\xfe\xfe\xfc\xfc\xfc\xfe\xfe\xfe\xfd\xfd\xfd\xff\xff\xff\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfd\xfd\xfd\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfd\xfd\xfd\xfe\xfe\xfe\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfc\xfc\xfc\xfe\xfe\xfe\xfd\xfd\xfd\xfe\xfe\xfe\xfd\xfd\xfd\xfe\xfe\xfe\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfc\xfc\xfc\xfe\xfe\xfe\xfd\xfd\xfd\xfc\xfc\xfc\xfe\xfe\xfe\xfd\xfd\xfd\xfd\xfd\xfd\xfe\xfe\xfe\xfc\xfc\xfc\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfc\xfc\xfc\xff\xff\xff\xd0\xd0\xd0\xcc\xcc\xcc\xb1\xb1\xb1ccclll\xb2\xb2\xb2\xfd\xfd\xfd\xfe\xfe\xfe\xfe\xfe\xfe\xff\xff\xff\xfc\xfc\xfc\xf2\xf2\xf2\xf4\xf4\xf4\xff\xff\xff\xfe\xfe\xfe\xfc\xfc\xfc\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfc\xfc\xfc\xfd\xfd\xfd\xfc\xfc\xfc\xfc\xfc\xfc\xfd\xfd\xfd\xfc\xfc\xfc\xfc\xfc\xfc\xfc\xfc\xfc\xfd\xfd\xfd\xfd\xfd\xfd\xfe\xfe\xfe\xfc\xfc\xfc\xfc\xfc\xfc\xfc\xfc\xfc\xfc\xfc\xfc\xfc\xfc\xfc\xfd\xfd\xfd\xfd\xfd\xfd\xfc\xfc\xfc\xff\xff\xff\xfb\xfb\xfb\xf5\xf5\xf5\xfc\xfc\xfc\xfc\xfc\xfc\xfd\xfd\xfd\xfd\xfd\xfd\xfc\xfc\xfc\xfd\xfd\xfd\xfb\xfb\xfb\xf7\xf7\xf7\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xff\xff\xff\xfe\xfe\xfe\xfc\xfc\xfc\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfc\xfc\xfc\xfe\xfe\xfe\xfe\xfe\xfe\xfc\xfc\xfc\xf5\xf5\xf5\xfc\xfc\xfc\xfc\xfc\xfc\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfc\xfc\xfc\xfd\xfd\xfd\xfc\xfc\xfc\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfc\xfc\xfc\xfc\xfc\xfc\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfc\xfc\xfc\xfc\xfc\xfc\xfc\xfc\xfc\xfd\xfd\xfd\xfe\xfe\xfe\xfe\xfe\xfe\xfd\xfd\xfd\xfd\xfd\xfd\xfc\xfc\xfc\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfc\xfc\xfc\xfd\xfd\xfd\xfe\xfe\xfe\xfc\xfc\xfc\xff\xff\xff\xd2\xd2\xd2\xcc\xcc\xcc\xb1\xb1\xb1ccclll\xb2\xb2\xb2\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfc\xfc\xfc\xff\xff\xff\x82\x82\x82\xa8\xa8\xa8\xff\xff\xff\xfc\xfc\xfc\xfe\xfe\xfe\xfe\xfe\xfe\xff\xff\xff\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xff\xff\xff\xfe\xfe\xfe\xff\xff\xff\xfe\xfe\xfe\xfe\xfe\xfe\xff\xff\xff\xff\xff\xff\xfe\xfe\xfe\xff\xff\xff\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xff\xff\xff\xf3\xf3\xf3\xe2\xe2\xe2\x83\x83\x83\xff\xff\xff\xfd\xfd\xfd\xfe\xfe\xfe\xfe\xfe\xfe\xfd\xfd\xfd\xff\xff\xff\xe5\xe5\xe5\x88\x88\x88\xff\xff\xff\xfd\xfd\xfd\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfd\xfd\xfd\xfd\xfd\xfd\xfe\xfe\xfe\xff\xff\xff\xfe\xfe\xfe\xfe\xfe\xfe\xff\xff\xff\xf3\xf3\xf3\x81\x81\x81\xfd\xfd\xfd\xff\xff\xff\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfd\xfd\xfd\xfe\xfe\xfe\xfe\xfe\xfe\xff\xff\xff\xfe\xfe\xfe\xfe\xfe\xfe\xff\xff\xff\xfe\xfe\xfe\xff\xff\xff\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xff\xff\xff\xfe\xfe\xfe\xfc\xfc\xfc\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xff\xff\xff\xfa\xfa\xfa\xc4\xc4\xc4\xcf\xcf\xcf\xb0\xb0\xb0ccclll\xb2\xb2\xb2\xfd\xfd\xfd\xfd\xfd\xfd\xff\xff\xff\xfb\xfb\xfb\xff\xff\xff\x8b\x8b\x8b\xb5\xb5\xb5\xc5\xc5\xc5\x98\x98\x98\xb8\xb8\xb8\xff\xff\xff\xfb\xfb\xfb\xff\xff\xff\xd7\xd7\xd7\xb5\xb5\xb5\xcc\xcc\xcc\xbb\xbb\xbb\xcd\xcd\xcd\xb1\xb1\xb1\xcf\xcf\xcf\x93\x93\x93\xd6\xd6\xd6\xff\xff\xff\xff\xff\xff\xcb\xcb\xcb\xa8\xa8\xa8\xab\xab\xab\xb2\xb2\xb2\xba\xba\xba\xf2\xf2\xf2\xa8\xa8\xa8\xc1\xc1\xc1\x7f\x7f\x7f\xc6\xc6\xc6\x80\x80\x80\x9e\x9e\x9e\xd4\xd4\xd4\xdb\xdb\xdb\xb0\xb0\xb0\xd1\xd1\xd1\xe9\xe9\xe9\xb3\xb3\xb3xxx\xff\xff\xff\xfb\xfb\xfb\xfe\xfe\xfe\xff\xff\xff\xe2\xe2\xe2\xa9\xa9\xa9\xbd\xbd\xbd\xca\xca\xca\xd0\xd0\xd0\xdd\xdd\xdd\xac\xac\xac\xbf\xbf\xbf\xff\xff\xff\xfd\xfd\xfd\xfd\xfd\xfd\x7a\x7a\x7a\x9b\x9b\x9b\xce\xce\xce\xdc\xdc\xdc\xb1\xb1\xb1\xce\xce\xce\xab\xab\xab\xc6\xc6\xc6\xb3\xb3\xb3\xdc\xdc\xdc\xd4\xd4\xd4\xc9\xc9\xc9\xab\xab\xab\xa6\xa6\xa6\xd3\xd3\xd3\xce\xce\xce\xdc\xdc\xdc\xaf\xaf\xaf\xbe\xbe\xbe\xbd\xbd\xbd\x99\x99\x99\xec\xec\xec\xff\xff\xff\xfb\xfb\xfb\xb0\xb0\xb0\xcc\xcc\xcc\xb5\xb5\xb5\xe1\xe1\xe1\xd3\xd3\xd3\xee\xee\xee\xcb\xcb\xcb\x9f\x9f\x9f\xf5\xf5\xf5\xfe\xfe\xfe\xff\xff\xff\xa0\xa0\xa0\x80\x80\x80\xdc\xdc\xdc\xae\xae\xaeccclll\xb2\xb2\xb2\xfe\xfe\xfe\xfe\xfe\xfe\xff\xff\xff\xfb\xfb\xfb\xff\xff\xff\x8b\x8b\x8b\xbf\xbf\xbf\x9b\x9b\x9b\xb5\xb5\xb5\x8a\x8a\x8a\xff\xff\xff\xfe\xfe\xfe\xf9\xf9\xf9xxx\xf7\xf7\xf7\x7e\x7e\x7e\x82\x82\x82\xc2\xc2\xc2\x8d\x8d\x8d\xa7\xa7\xa7\x9e\x9e\x9e\xff\xff\xff\xfa\xfa\xfa\xff\xff\xff\xaa\xaa\xaa\xa3\xa3\xa3\x9a\x9a\x9a\xbd\xbd\xbd\x8d\x8d\x8d\x94\x94\x94\xaf\xaf\xaf\xb7\xb7\xb7\x8f\x8f\x8f\xdb\xdb\xdb\x8e\x8e\x8e\xc7\xc7\xc7\x83\x83\x83\x8a\x8a\x8a\xf7\xf7\xf7iii\x8c\x8c\x8c\xe9\xe9\xe9\x84\x84\x84\xff\xff\xff\xfd\xfd\xfd\xfe\xfe\xfe\xff\xff\xff\xfb\xfb\xfb\x84\x84\x84\x8e\x8e\x8e\x80\x80\x80\xda\xda\xda\x8f\x8f\x8f\xb1\xb1\xb1\xb0\xb0\xb0\xff\xff\xff\xfe\xfe\xfe\xfb\xfb\xfb\x86\x86\x86\xca\xca\xca\x7e\x7e\x7e\x88\x88\x88\xf4\xf4\xf4\x7d\x7d\x7d\x95\x95\x95\x96\x96\x96lll\xd0\xd0\xd0\xaa\xaa\xaa\x9f\x9f\x9f\xb5\xb5\xb5\xb0\xb0\xb0\x88\x88\x88\xd3\xd3\xd3\x90\x90\x90\xae\xae\xae\xba\xba\xba\x87\x87\x87\xc8\xc8\xc8\xff\xff\xff\xfd\xfd\xfd\xff\xff\xff\x88\x88\x88\xbf\xbf\xbf\x90\x90\x90\xab\xab\xab\x8e\x8e\x8e\xbb\xbb\xbb\x9c\x9c\x9c\xa9\xa9\xa9\xe6\xe6\xe6\xff\xff\xff\xff\xff\xff\xab\xab\xab\x8d\x8d\x8d\xdb\xdb\xdb\xae\xae\xaeccclll\xb2\xb2\xb2\xe0\xe0\xe0\xd4\xd4\xd4\xff\xff\xff\xfa\xfa\xfa\xff\xff\xff\x7d\x7d\x7d\xb4\xb4\xb4\x9b\x9b\x9b\xbd\xbd\xbd\x83\x83\x83\xff\xff\xff\xfd\xfd\xfd\xff\xff\xffvvv\xd5\xd5\xd5\xab\xab\xab\x8b\x8b\x8b\x9b\x9b\x9b\x82\x82\x82\xa3\xa3\xa3\xaa\xaa\xaa\xff\xff\xff\xf9\xf9\xf9\xff\xff\xff\xa9\xa9\xa9\xa6\xa6\xa6\x9a\x9a\x9a\xc1\xc1\xc1\x8f\x8f\x8f\x7e\x7e\x7e\xac\xac\xac\xf0\xf0\xf0\x7e\x7e\x7e\xc0\xc0\xc0\x8d\x8d\x8d\xc7\xc7\xc7\x87\x87\x87\x84\x84\x84\xdb\xdb\xdb\x9a\x9a\x9aooo\xb4\xb4\xb4\x7a\x7a\x7a\xd4\xd4\xd4\xdb\xdb\xdb\xff\xff\xff\xfa\xfa\xfa\xff\xff\xff\xa6\xa6\xa6\x8a\x8a\x8a\x7d\x7d\x7d\xe1\xe1\xe1\x83\x83\x83\xb1\xb1\xb1\xe6\xe6\xe6\xfe\xfe\xfe\xff\xff\xff\xf8\xf8\xf8\x82\x82\x82\xcb\xcb\xcb\x82\x82\x82\x82\x82\x82\xda\xda\xda\x9f\x9f\x9f\xde\xde\xdesss\x95\x95\x95\xad\xad\xad\xc8\xc8\xc8\x7b\x7b\x7b\xe2\xe2\xe2\xf8\xf8\xf8lll\xdf\xdf\xdf\x8a\x8a\x8a\xa6\xa6\xa6\xf3\xf3\xf3\x81\x81\x81\xd8\xd8\xd8\xff\xff\xff\xfb\xfb\xfb\xff\xff\xff\x83\x83\x83\x9c\x9c\x9c\x7c\x7c\x7c\xea\xea\xea\x85\x85\x85\x84\x84\x84\x84\x84\x84\xdf\xdf\xdf\xf1\xf1\xf1\xfe\xfe\xfe\xff\xff\xff\xaa\xaa\xaa\x7e\x7e\x7e\xdc\xdc\xdc\xae\xae\xaeccclll\xb2\xb2\xb2\xe1\xe1\xe1\xd6\xd6\xd6\xff\xff\xff\xfe\xfe\xfe\xff\xff\xff\xcc\xcc\xcc\xdb\xdb\xdb\xd6\xd6\xd6\xdf\xdf\xdf\xd1\xd1\xd1\xfd\xfd\xfd\xfe\xfe\xfe\xff\xff\xff\xeb\xeb\xeb\xca\xca\xca\xf2\xf2\xf2\xeb\xeb\xeb\xbc\xbc\xbc\xdb\xdb\xdb\xd8\xd8\xd8\xd8\xd8\xd8\xff\xff\xff\xfd\xfd\xfd\xff\xff\xff\xdf\xdf\xdf\xda\xda\xda\xd5\xd5\xd5\xe0\xe0\xe0\xd5\xd5\xd5\xe6\xe6\xe6\xae\xae\xae\xee\xee\xee\xd9\xd9\xd9\xd0\xd0\xd0\xd5\xd5\xd5\xdc\xdc\xdc\xda\xda\xda\xea\xea\xea\xca\xca\xca\xf7\xf7\xf7\xe3\xe3\xe3\xb6\xb6\xb6\xdc\xdc\xdc\xbd\xbd\xbd\xbe\xbe\xbe\xff\xff\xff\xfc\xfc\xfc\xff\xff\xff\xf1\xf1\xf1\xec\xec\xec\xeb\xeb\xeb\xfb\xfb\xfb\xea\xea\xea\xae\xae\xae\xeb\xeb\xeb\xff\xff\xff\xff\xff\xff\xf8\xf8\xf8\xcf\xcf\xcf\xde\xde\xde\xd8\xd8\xd8\xea\xea\xea\xcb\xcb\xcb\xf2\xf2\xf2\xfe\xfe\xfe\xe5\xe5\xe5\xf1\xf1\xf1\xed\xed\xed\xff\xff\xff\xb9\xb9\xb9\xcc\xcc\xcc\xff\xff\xff\xe4\xe4\xe4\xf9\xf9\xf9\xef\xef\xef\xae\xae\xae\xe8\xe8\xe8\xd2\xd2\xd2\xe6\xe6\xe6\xff\xff\xff\xfd\xfd\xfd\xff\xff\xff\xdb\xdb\xdb\xbf\xbf\xbf\xdf\xdf\xdf\xe3\xe3\xe3\xe1\xe1\xe1\xf8\xf8\xf8\xbf\xbf\xbf\xc8\xc8\xc8\xff\xff\xff\xfe\xfe\xfe\xff\xff\xff\xed\xed\xed\xac\xac\xac\xd2\xd2\xd2\xb0\xb0\xb0ccclll\xb2\xb2\xb2\xff\xff\xff\xfd\xfd\xfd\xfc\xfc\xfc\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xff\xff\xff\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfd\xfd\xfd\xfd\xfd\xfd\xff\xff\xff\xfd\xfd\xfd\xfe\xfe\xfe\xff\xff\xff\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfd\xfd\xfd\xfe\xfe\xfe\xfd\xfd\xfd\xfe\xfe\xfe\xff\xff\xff\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfc\xfc\xfc\xff\xff\xff\xfe\xfe\xfe\xfe\xfe\xfe\xff\xff\xff\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfd\xfd\xfd\xff\xff\xff\xfd\xfd\xfd\xfd\xfd\xfd\xff\xff\xff\xff\xff\xff\xfc\xfc\xfc\xfd\xfd\xfd\xfe\xfe\xfe\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfe\xfe\xfe\xff\xff\xff\xfe\xfe\xfe\xfd\xfd\xfd\xfd\xfd\xfd\xfe\xfe\xfe\xff\xff\xff\xff\xff\xff\xfe\xfe\xfe\xfd\xfd\xfd\xff\xff\xff\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfe\xfe\xfe\xfe\xfe\xfe\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfe\xfe\xfe\xff\xff\xff\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfd\xfd\xfd\xfe\xfe\xfe\xfd\xfd\xfd\xfe\xfe\xfe\xff\xff\xff\xfe\xfe\xfe\xfe\xfe\xfe\xff\xff\xff\xfe\xfe\xfe\xfe\xfe\xfe\xff\xff\xff\xfe\xfe\xfe\xfd\xfd\xfd\xfc\xfc\xfc\xff\xff\xff\xd2\xd2\xd2\xcb\xcb\xcb\xb0\xb0\xb0bbbkkk\xb1\xb1\xb1\xfd\xfd\xfd\xfe\xfe\xfe\xff\xff\xff\xfe\xfe\xfe\xfe\xfe\xfe\xfc\xfc\xfc\xfc\xfc\xfc\xfe\xfe\xfe\xff\xff\xff\xfc\xfc\xfc\xfd\xfd\xfd\xfe\xfe\xfe\xfd\xfd\xfd\xfc\xfc\xfc\xfc\xfc\xfc\xfd\xfd\xfd\xfd\xfd\xfd\xfa\xfa\xfa\xfc\xfc\xfc\xfe\xfe\xfe\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfc\xfc\xfc\xfc\xfc\xfc\xfb\xfb\xfb\xfc\xfc\xfc\xfd\xfd\xfd\xfe\xfe\xfe\xfc\xfc\xfc\xff\xff\xff\xfc\xfc\xfc\xfb\xfb\xfb\xfc\xfc\xfc\xfe\xfe\xfe\xfc\xfc\xfc\xfb\xfb\xfb\xfb\xfb\xfb\xfd\xfd\xfd\xfd\xfd\xfd\xfb\xfb\xfb\xfd\xfd\xfd\xfe\xfe\xfe\xfd\xfd\xfd\xff\xff\xff\xfe\xfe\xfe\xff\xff\xff\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfe\xfe\xfe\xfd\xfd\xfd\xfb\xfb\xfb\xfd\xfd\xfd\xff\xff\xff\xff\xff\xff\xfe\xfe\xfe\xfc\xfc\xfc\xfd\xfd\xfd\xfc\xfc\xfc\xfd\xfd\xfd\xfc\xfc\xfc\xfe\xfe\xfe\xfe\xfe\xfe\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfe\xfe\xfe\xfb\xfb\xfb\xfc\xfc\xfc\xff\xff\xff\xfd\xfd\xfd\xfe\xfe\xfe\xfd\xfd\xfd\xfb\xfb\xfb\xfd\xfd\xfd\xfc\xfc\xfc\xfe\xfe\xfe\xff\xff\xff\xfe\xfe\xfe\xff\xff\xff\xfd\xfd\xfd\xfb\xfb\xfb\xfc\xfc\xfc\xfd\xfd\xfd\xfc\xfc\xfc\xfe\xfe\xfe\xfc\xfc\xfc\xfc\xfc\xfc\xfe\xfe\xfe\xff\xff\xff\xfe\xfe\xfe\xff\xff\xff\xd0\xd0\xd0\xcc\xcc\xcc\xb1\xb1\xb1ccclll\xb2\xb2\xb2\xff\xff\xff\xd0\xd0\xd0\xd6\xd6\xd6\xff\xff\xff\xfc\xfc\xfc\xfc\xfc\xfc\xff\xff\xff\xe5\xe5\xe5\xb1\xb1\xb1\xee\xee\xee\xff\xff\xff\xfc\xfc\xfc\xff\xff\xff\xfe\xfe\xfe\xfe\xfe\xfe\xfd\xfd\xfd\xfd\xfd\xfd\xff\xff\xff\xfd\xfd\xfd\xc8\xc8\xc8\xfb\xfb\xfb\xff\xff\xff\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xff\xff\xff\xee\xee\xee\xc2\xc2\xc2\xe6\xe6\xe6\xd4\xd4\xd4\xff\xff\xff\xfc\xfc\xfc\xff\xff\xff\xcb\xcb\xcb\xf2\xf2\xf2\xff\xff\xff\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xff\xff\xff\xf6\xf6\xf6\xe8\xe8\xe8\xff\xff\xff\xfd\xfd\xfd\xfe\xfe\xfe\xfe\xfe\xfe\xfd\xfd\xfd\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfd\xfd\xfd\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfd\xfd\xfd\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfd\xfd\xfd\xfe\xfe\xfe\xfe\xfe\xfe\xfd\xfd\xfd\xfe\xfe\xfe\xfe\xfe\xfe\xfd\xfd\xfd\xfe\xfe\xfe\xfd\xfd\xfd\xfd\xfd\xfd\xfe\xfe\xfe\xfe\xfe\xfe\xfd\xfd\xfd\xfd\xfd\xfd\xfe\xfe\xfe\xfd\xfd\xfd\xfd\xfd\xfd\xfe\xfe\xfe\xfe\xfe\xfe\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfd\xfd\xfd\xfe\xfe\xfe\xfd\xfd\xfd\xfe\xfe\xfe\xfc\xfc\xfc\xff\xff\xff\xd1\xd1\xd1\xcb\xcb\xcb\xb0\xb0\xb0bbbkkk\xb1\xb1\xb1\xff\xff\xff\xaf\xaf\xaf\xa5\xa5\xa5\xff\xff\xff\xfa\xfa\xfa\xfd\xfd\xfd\xfe\xfe\xfe\x84\x84\x84\xc8\xc8\xc8\xef\xef\xef\xe4\xe4\xe4\xfa\xfa\xfa\xf5\xf5\xf5\xde\xde\xde\xf8\xf8\xf8\xff\xff\xff\xff\xff\xff\xf1\xf1\xf1\xf2\xf2\xf2\xda\xda\xda\xf6\xf6\xf6\xec\xec\xec\xe5\xe5\xe5\xed\xed\xed\xe9\xe9\xe9\xfb\xfb\xfb\xe8\xe8\xe8\xe6\xe6\xe6\xf0\xf0\xf0\x7a\x7a\x7a\xeb\xeb\xeb\xe0\xe0\xe0\xff\xff\xff\xe1\xe1\xe1\xf7\xf7\xf7\xde\xde\xde\xe3\xe3\xe3\xb2\xb2\xb2\xed\xed\xed\xf0\xf0\xf0\xf6\xf6\xf6\xf1\xf1\xf1\xff\xff\xff\xbe\xbe\xbe\xe1\xe1\xe1\xff\xff\xff\xfc\xfc\xfc\xfe\xfe\xfe\xfd\xfd\xfd\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfd\xfd\xfd\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfd\xfd\xfd\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfd\xfd\xfd\xfe\xfe\xfe\xfe\xfe\xfe\xfd\xfd\xfd\xfe\xfe\xfe\xfe\xfe\xfe\xfd\xfd\xfd\xfe\xfe\xfe\xfd\xfd\xfd\xfd\xfd\xfd\xfe\xfe\xfe\xfe\xfe\xfe\xfd\xfd\xfd\xfd\xfd\xfd\xfe\xfe\xfe\xfd\xfd\xfd\xfd\xfd\xfd\xfe\xfe\xfe\xfe\xfe\xfe\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfd\xfd\xfd\xfe\xfe\xfe\xfd\xfd\xfd\xfe\xfe\xfe\xfc\xfc\xfc\xff\xff\xff\xd1\xd1\xd1\xcb\xcb\xcb\xb0\xb0\xb0bbbkkk\xb1\xb1\xb1\xc6\xc6\xc6\xb4\xb4\xb4\xad\xad\xad\xff\xff\xff\xfa\xfa\xfa\xff\xff\xff\xf9\xf9\xf9qqq\xd8\xd8\xd8\xac\xac\xac\xb5\xb5\xb5\xa0\xa0\xa0\x87\x87\x87\x9a\x9a\x9a\xf2\xf2\xf2\xff\xff\xff\xba\xba\xba\xa7\xa7\xa7\xea\xea\xea\x87\x87\x87\xc8\xc8\xc8\x7f\x7f\x7f\x98\x98\x98\x9a\x9a\x9a\x92\x92\x92\xaa\xaa\xaa\x89\x89\x89\x85\x85\x85\xb8\xb8\xb8\x9c\x9c\x9c\xbb\xbb\xbb\x9a\x9a\x9a\xc8\xc8\xc8\xb4\xb4\xb4\xbf\xbf\xbf\x95\x95\x95\xb6\xb6\xb6\x85\x85\x85\xc5\xc5\xc5\x84\x84\x84\xca\xca\xca\xd3\xd3\xd3\xff\xff\xff\xca\xca\xca\x9f\x9f\x9f\xff\xff\xff\xfa\xfa\xfa\xfe\xfe\xfe\xfd\xfd\xfd\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfd\xfd\xfd\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfd\xfd\xfd\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfd\xfd\xfd\xfe\xfe\xfe\xfe\xfe\xfe\xfd\xfd\xfd\xfe\xfe\xfe\xfe\xfe\xfe\xfd\xfd\xfd\xfe\xfe\xfe\xfd\xfd\xfd\xfd\xfd\xfd\xfe\xfe\xfe\xfe\xfe\xfe\xfd\xfd\xfd\xfd\xfd\xfd\xfe\xfe\xfe\xfd\xfd\xfd\xfd\xfd\xfd\xfe\xfe\xfe\xfe\xfe\xfe\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfd\xfd\xfd\xfe\xfe\xfe\xfd\xfd\xfd\xfe\xfe\xfe\xfc\xfc\xfc\xff\xff\xff\xd1\xd1\xd1\xcb\xcb\xcb\xb0\xb0\xb0bbbkkk\xb1\xb1\xb1\xec\xec\xec\xb1\xb1\xb1\xa9\xa9\xa9\xff\xff\xff\xfa\xfa\xfa\xfd\xfd\xfd\xff\xff\xff\x89\x89\x89\xc8\xc8\xc8\x82\x82\x82\xf8\xf8\xf8\x7d\x7d\x7d\x86\x86\x86\xe5\xe5\xe5\xff\xff\xff\xff\xff\xff\xdc\xdc\xdcggg\xc2\xc2\xc2\x81\x81\x81\xc9\xc9\xc9\x92\x92\x92\xb6\xb6\xb6\xb3\xb3\xb3\xa0\xa0\xa0\xa0\xa0\xa0\xb6\xb6\xb6\xc4\xc4\xc4\x94\x94\x94\x9c\x9c\x9c\xbf\xbf\xbf\x87\x87\x87\x8d\x8d\x8d\xf2\xf2\xf2\xff\xff\xff\x80\x80\x80\xba\xba\xba\x8f\x8f\x8f\xff\xff\xff\x7b\x7b\x7b\x9c\x9c\x9c\xff\xff\xff\xff\xff\xff\xd4\xd4\xd4\x92\x92\x92\xff\xff\xff\xfb\xfb\xfb\xfe\xfe\xfe\xfd\xfd\xfd\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfd\xfd\xfd\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfd\xfd\xfd\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfd\xfd\xfd\xfe\xfe\xfe\xfe\xfe\xfe\xfd\xfd\xfd\xfe\xfe\xfe\xfe\xfe\xfe\xfd\xfd\xfd\xfe\xfe\xfe\xfd\xfd\xfd\xfd\xfd\xfd\xfe\xfe\xfe\xfe\xfe\xfe\xfd\xfd\xfd\xfd\xfd\xfd\xfe\xfe\xfe\xfd\xfd\xfd\xfd\xfd\xfd\xfe\xfe\xfe\xfe\xfe\xfe\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfd\xfd\xfd\xfe\xfe\xfe\xfd\xfd\xfd\xfe\xfe\xfe\xfc\xfc\xfc\xff\xff\xff\xd1\xd1\xd1\xcb\xcb\xcb\xb0\xb0\xb0bbbkkk\xb1\xb1\xb1\xf1\xf1\xf1\xb2\xb2\xb2\xb4\xb4\xb4\xa0\xa0\xa0\xdf\xdf\xdf\xff\xff\xff\xfa\xfa\xfa\x85\x85\x85\xe5\xe5\xe5\xa4\xa4\xa4\xba\xba\xba\xd3\xd3\xd3\x93\x93\x93\xdb\xdb\xdb\xff\xff\xff\xff\xff\xff\xdf\xdf\xdf\xbd\xbd\xbd\xb4\xb4\xb4\x95\x95\x95\xc5\xc5\xc5\x9d\x9d\x9d\xb4\xb4\xb4\xb4\xb4\xb4\xaa\xaa\xaa\xa4\xa4\xa4\x8d\x8d\x8d\xbf\xbf\xbf\xd3\xd3\xd3\x98\x98\x98\xbc\xbc\xbc\xa3\xa3\xa3\xac\xac\xac\x79\x79\x79\xe6\xe6\xe6\x93\x93\x93\xc8\xc8\xc8\x86\x86\x86\xfc\xfc\xfc\xb6\xb6\xb6\xb4\xb4\xb4\xd4\xd4\xd4\xdc\xdc\xdc\xc2\xc2\xc2\xb8\xb8\xb8\xff\xff\xff\xfc\xfc\xfc\xff\xff\xff\xfe\xfe\xfe\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xfe\xfe\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xfe\xfe\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xfe\xfe\xff\xff\xff\xff\xff\xff\xfe\xfe\xfe\xff\xff\xff\xff\xff\xff\xfe\xfe\xfe\xff\xff\xff\xfe\xfe\xfe\xfe\xfe\xfe\xff\xff\xff\xff\xff\xff\xfe\xfe\xfe\xfe\xfe\xfe\xff\xff\xff\xfe\xfe\xfe\xfe\xfe\xfe\xff\xff\xff\xff\xff\xff\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xfe\xfe\xff\xff\xff\xfe\xfe\xfe\xff\xff\xff\xfd\xfd\xfd\xff\xff\xff\xd2\xd2\xd2\xcc\xcc\xcc\xb1\xb1\xb1ccclll\xb2\xb2\xb2\xfe\xfe\xfe\xfb\xfb\xfb\xff\xff\xff\xd7\xd7\xd7\xf2\xf2\xf2\xff\xff\xff\xfc\xfc\xfc\xfb\xfb\xfb\xfc\xfc\xfc\xfc\xfc\xfc\xf4\xf4\xf4\xfe\xfe\xfe\xfb\xfb\xfb\xfb\xfb\xfb\xfe\xfe\xfe\xfe\xfe\xfe\xfb\xfb\xfb\xf5\xf5\xf5\xfd\xfd\xfd\xfb\xfb\xfb\xfb\xfb\xfb\xfb\xfb\xfb\xfb\xfb\xfb\xf9\xf9\xf9\xff\xff\xff\xb7\xb7\xb7\x89\x89\x89\xff\xff\xff\xfa\xfa\xfa\xfb\xfb\xfb\xfb\xfb\xfb\xfb\xfb\xfb\xfd\xfd\xfd\xf6\xf6\xf6\xfd\xfd\xfd\xfb\xfb\xfb\xfb\xfb\xfb\xff\xff\xff\xd3\xd3\xd3\x98\x98\x98\xf8\xf8\xf8\xfe\xfe\xfe\xf6\xf6\xf6\xc4\xc4\xc4\xf9\xf9\xf9\xff\xff\xff\xfd\xfd\xfd\xfe\xfe\xfe\xfd\xfd\xfd\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfd\xfd\xfd\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfd\xfd\xfd\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfd\xfd\xfd\xfe\xfe\xfe\xfe\xfe\xfe\xfd\xfd\xfd\xfe\xfe\xfe\xfe\xfe\xfe\xfd\xfd\xfd\xfe\xfe\xfe\xfd\xfd\xfd\xfd\xfd\xfd\xfe\xfe\xfe\xfe\xfe\xfe\xfd\xfd\xfd\xfd\xfd\xfd\xfe\xfe\xfe\xfd\xfd\xfd\xfd\xfd\xfd\xfe\xfe\xfe\xfe\xfe\xfe\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfd\xfd\xfd\xfe\xfe\xfe\xfd\xfd\xfd\xfe\xfe\xfe\xfc\xfc\xfc\xff\xff\xff\xd1\xd1\xd1\xcb\xcb\xcb\xb0\xb0\xb0bbbkkk\xb1\xb1\xb1\xfd\xfd\xfd\xfe\xfe\xfe\xfd\xfd\xfd\xfd\xfd\xfd\xff\xff\xff\xfe\xfe\xfe\xff\xff\xff\xfe\xfe\xfe\xfe\xfe\xfe\xfc\xfc\xfc\xfe\xfe\xfe\xfc\xfc\xfc\xfe\xfe\xfe\xfe\xfe\xfe\xff\xff\xff\xff\xff\xff\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfd\xfd\xfd\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xff\xff\xff\xe9\xe9\xe9\xdc\xdc\xdc\xff\xff\xff\xfd\xfd\xfd\xfe\xfe\xfe\xfe\xfe\xfe\xfd\xfd\xfd\xfc\xfc\xfc\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfd\xfd\xfd\xff\xff\xff\xe6\xe6\xe6\xda\xda\xda\xff\xff\xff\xfe\xfe\xfe\xfd\xfd\xfd\xfc\xfc\xfc\xfe\xfe\xfe\xff\xff\xff\xfe\xfe\xfe\xff\xff\xff\xfe\xfe\xfe\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xfe\xfe\xff\xff\xff\xff\xff\xff\xfe\xfe\xfe\xfe\xfe\xfe\xff\xff\xff\xfd\xfd\xfd\xfe\xfe\xfe\xff\xff\xff\xff\xff\xff\xfe\xfe\xfe\xfe\xfe\xfe\xff\xff\xff\xfe\xfe\xfe\xff\xff\xff\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfd\xfd\xfd\xff\xff\xff\xfe\xfe\xfe\xff\xff\xff\xfe\xfe\xfe\xfe\xfe\xfe\xff\xff\xff\xff\xff\xff\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xfe\xfe\xff\xff\xff\xfe\xfe\xfe\xff\xff\xff\xfd\xfd\xfd\xff\xff\xff\xd2\xd2\xd2\xcc\xcc\xcc\xb1\xb1\xb1ccclll\xb2\xb2\xb2\xfb\xfb\xfb\xfb\xfb\xfb\xfe\xfe\xfe\xfe\xfe\xfe\xfd\xfd\xfd\xfc\xfc\xfc\xfc\xfc\xfc\xfd\xfd\xfd\xfc\xfc\xfc\xfc\xfc\xfc\xfe\xfe\xfe\xfe\xfe\xfe\xfc\xfc\xfc\xfe\xfe\xfe\xff\xff\xff\xff\xff\xff\xfd\xfd\xfd\xf8\xf8\xf8\xf3\xf3\xf3\xf3\xf3\xf3\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfd\xfd\xfd\xfd\xfd\xfd\xfe\xfe\xfe\xff\xff\xff\xfc\xfc\xfc\xfd\xfd\xfd\xfe\xfe\xfe\xfd\xfd\xfd\xfe\xfe\xfe\xfd\xfd\xfd\xfb\xfb\xfb\xfe\xfe\xfe\xfc\xfc\xfc\xfc\xfc\xfc\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfc\xfc\xfc\xfc\xfc\xfc\xfd\xfd\xfd\xfb\xfb\xfb\xfd\xfd\xfd\xfd\xfd\xfd\xfc\xfc\xfc\xfd\xfd\xfd\xfc\xfc\xfc\xfb\xfb\xfb\xfd\xfd\xfd\xfc\xfc\xfc\xfb\xfb\xfb\xfd\xfd\xfd\xfd\xfd\xfd\xfc\xfc\xfc\xfe\xfe\xfe\xfd\xfd\xfd\xfd\xfd\xfd\xff\xff\xff\xfe\xfe\xfe\xff\xff\xff\xfd\xfd\xfd\xfd\xfd\xfd\xfe\xfe\xfe\xfc\xfc\xfc\xfc\xfc\xfc\xfe\xfe\xfe\xff\xff\xff\xfe\xfe\xfe\xfd\xfd\xfd\xfe\xfe\xfe\xfe\xfe\xfe\xfb\xfb\xfb\xfe\xfe\xfe\xfd\xfd\xfd\xfc\xfc\xfc\xfe\xfe\xfe\xff\xff\xff\xff\xff\xff\xfd\xfd\xfd\xfc\xfc\xfc\xfd\xfd\xfd\xfc\xfc\xfc\xfd\xfd\xfd\xfc\xfc\xfc\xfb\xfb\xfb\xfc\xfc\xfc\xfe\xfe\xfe\xfc\xfc\xfc\xfc\xfc\xfc\xfe\xfe\xfe\xfb\xfb\xfb\xff\xff\xff\xd2\xd2\xd2\xcc\xcc\xcc\xb1\xb1\xb1ccclll\xb2\xb2\xb2\xfc\xfc\xfc\xff\xff\xff\xd7\xd7\xd7\xa0\xa0\xa0\xff\xff\xff\xfd\xfd\xfd\xfe\xfe\xfe\xfd\xfd\xfd\xfd\xfd\xfd\xff\xff\xff\xa0\xa0\xa0\xd5\xd5\xd5\xff\xff\xff\xfd\xfd\xfd\xfe\xfe\xfe\xfc\xfc\xfc\xff\xff\xff\x9b\x9b\x9b\xa1\xa1\xa1\xb8\xb8\xb8\xbe\xbe\xbe\xff\xff\xff\xfd\xfd\xfd\xff\xff\xff\xfb\xfb\xfb\xfc\xfc\xfc\xfe\xfe\xfe\xff\xff\xff\xfe\xfe\xfe\xfc\xfc\xfc\xff\xff\xff\xb5\xb5\xb5\xbb\xbb\xbb\xff\xff\xff\xfb\xfb\xfb\xfe\xfe\xfe\xff\xff\xff\xff\xff\xff\xfd\xfd\xfd\xfd\xfd\xfd\xff\xff\xff\xfe\xfe\xfe\xfe\xfe\xfe\xff\xff\xff\xfe\xfe\xfe\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xfe\xfe\xff\xff\xff\xfe\xfe\xfe\xfe\xfe\xfe\xff\xff\xff\xfe\xfe\xfe\xfe\xfe\xfe\xff\xff\xff\xfc\xfc\xfc\xff\xff\xff\xbc\xbc\xbc\xc3\xc3\xc3\xff\xff\xff\xfd\xfd\xfd\xfd\xfd\xfd\xfa\xfa\xfa\xfe\xfe\xfe\xff\xff\xff\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xff\xff\xff\xd9\xd9\xd9\xa2\xa2\xa2\xff\xff\xff\xfc\xfc\xfc\xfe\xfe\xfe\xff\xff\xff\xfe\xfe\xfe\xff\xff\xff\xff\xff\xff\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xfe\xfe\xff\xff\xff\xfe\xfe\xfe\xfe\xfe\xfe\xff\xff\xff\xfe\xfe\xfe\xfd\xfd\xfd\xff\xff\xff\xd2\xd2\xd2\xcc\xcc\xcc\xb1\xb1\xb1ccclll\xb2\xb2\xb2\xa8\xa8\xa8\xc0\xc0\xc0\xe5\xe5\xe5\x88\x88\x88\xfc\xfc\xfc\xc6\xc6\xc6\xd9\xd9\xd9\xfe\xfe\xfe\xca\xca\xca\xdb\xdb\xdb\x9d\x9d\x9d\xb9\xb9\xb9\xd4\xd4\xd4\xfa\xfa\xfa\xff\xff\xff\xfc\xfc\xfc\xff\xff\xff\x8a\x8a\x8a\xdd\xdd\xdd\xff\xff\xffxxx\xf8\xf8\xf8\xff\xff\xff\xfd\xfd\xfd\x84\x84\x84\xe3\xe3\xe3\xdd\xdd\xdd\xc5\xc5\xc5\xf7\xf7\xf7\xfe\xfe\xfe\xff\xff\xff\xba\xba\xba\x7a\x7a\x7a\xc0\xc0\xc0\xfa\xfa\xfa\xd6\xd6\xd6\xcc\xcc\xcc\xff\xff\xff\xff\xff\xff\xfd\xfd\xfd\xce\xce\xce\xc1\xc1\xc1\xcf\xcf\xcf\xc1\xc1\xc1\xee\xee\xee\xd9\xd9\xd9\xd8\xd8\xd8\xeb\xeb\xeb\xc7\xc7\xc7\xb8\xb8\xb8\xe5\xe5\xe5\xcc\xcc\xcc\xb4\xb4\xb4\xe9\xe9\xe9\xef\xef\xef\xc2\xc2\xc2\xef\xef\xef\xf0\xf0\xf0\x8b\x8b\x8b\xab\xab\xab\xff\xff\xff\xff\xff\xff\xbc\xbc\xbc\x9f\x9f\x9f\xfb\xfb\xfb\xc7\xc7\xc7\xd7\xd7\xd7\xff\xff\xff\xfe\xfe\xfe\xfd\xfd\xfd\x8c\x8c\x8c\xc3\xc3\xc3\x7f\x7f\x7f\xbf\xbf\xbf\xf0\xf0\xf0\xe9\xe9\xe9\xc3\xc3\xc3\xf5\xf5\xf5\xff\xff\xff\xff\xff\xff\xda\xda\xda\xb9\xb9\xb9\xd1\xd1\xd1\xd3\xd3\xd3\xeb\xeb\xeb\xd9\xd9\xd9\xb6\xb6\xb6\xd1\xd1\xd1\xfd\xfd\xfd\xcb\xcb\xcb\xc4\xc4\xc4\xf5\xf5\xf5\xd1\xd1\xd1\xd7\xd7\xd7\xd6\xd6\xd6\xcb\xcb\xcb\xb1\xb1\xb1ccclll\xb2\xb2\xb2\xef\xef\xef\x7b\x7b\x7b\xae\xae\xae\xa0\xa0\xa0\x98\x98\x98\xd9\xd9\xd9\x8a\x8a\x8a\x8a\x8a\x8a\xd6\xd6\xd6\xd4\xd4\xd4\x9a\x9a\x9auuu\xf2\xf2\xf2\xff\xff\xff\xfd\xfd\xfd\xff\xff\xff\xf7\xf7\xf7\x80\x80\x80\xff\xff\xff\xec\xec\xecppp\xff\xff\xff\xfd\xfd\xfd\xfc\xfc\xfc\x86\x86\x86\xb7\xb7\xb7\xae\xae\xae\xbb\xbb\xbb\x94\x94\x94\xff\xff\xff\xff\xff\xff\xb8\xb8\xb8\x99\x99\x99\x91\x91\x91\x7a\x7a\x7a\xab\xab\xab\x84\x84\x84\xf2\xf2\xf2\xff\xff\xff\xff\xff\xffqqq\xb7\xb7\xb7\x8c\x8c\x8c\xa1\xa1\xa1\xa8\xa8\xa8\xcd\xcd\xcd\x84\x84\x84\xb0\xb0\xb0\x89\x89\x89\xb1\xb1\xb1vvv\x86\x86\x86\xb7\xb7\xb7nnn\xa7\xa7\xa7\x94\x94\x94\x94\x94\x94\xc7\xc7\xc7\xb0\xb0\xb0\xac\xac\xac\xff\xff\xff\xff\xff\xff\xb0\xb0\xb0\xab\xab\xab\x9e\x9e\x9e\xdb\xdb\xdb\x7c\x7c\x7c\xdf\xdf\xdf\xff\xff\xff\xfc\xfc\xfc\x80\x80\x80\xd1\xd1\xd1\x8f\x8f\x8f\xa8\xa8\xa8\x92\x92\x92\xaa\xaa\xaa\x88\x88\x88\xcb\xcb\xcb\xff\xff\xff\xff\xff\xff\x8c\x8c\x8c\xa7\xa7\xa7\xd2\xd2\xd2\x9c\x9c\x9c\xa2\xa2\xa2\x9a\x9a\x9a\x9c\x9c\x9c\x95\x95\x95\xb4\xb4\xb4\xa2\xa2\xa2\x8d\x8d\x8d\xab\xab\xab\x9d\x9d\x9d\x90\x90\x90\xd1\xd1\xd1\xcb\xcb\xcb\xb0\xb0\xb0bbbkkk\xb1\xb1\xb1\xff\xff\xff\xb3\xb3\xb3\xac\xac\xac\x99\x99\x99\x7b\x7b\x7b\xdd\xdd\xdd\xab\xab\xab```\xb6\xb6\xb6\xff\xff\xff\x9c\x9c\x9cQQQ\xbf\xbf\xbf\xff\xff\xff\xfb\xfb\xfb\xff\xff\xff\xcb\xcb\xcb\x86\x86\x86\xff\xff\xff\xa4\xa4\xa4\xbc\xbc\xbc\xff\xff\xff\xfc\xfc\xfc\xff\xff\xff\x8a\x8a\x8a\xa3\xa3\xa3\x95\x95\x95\xe0\xe0\xe0\x92\x92\x92\xff\xff\xff\xff\xff\xff\xb2\xb2\xb2\xae\xae\xae\xd6\xd6\xd6]]]\xa3\xa3\xa3\xed\xed\xed\xf2\xf2\xf2\xff\xff\xff\xff\xff\xff\x7a\x7a\x7a\xcf\xcf\xcf\x98\x98\x98\xbb\xbb\xbb\x90\x90\x90\xa4\xa4\xa4\x82\x82\x82\xa9\xa9\xa9\xa0\xa0\xa0\xde\xde\xde\x84\x84\x84\x97\x97\x97\xe7\xe7\xe7uuurrr\xf2\xf2\xf2\xa7\xa7\xa7\x95\x95\x95\xb4\xb4\xb4\x9f\x9f\x9f\xff\xff\xff\xff\xff\xff\xb6\xb6\xb6\xa9\xa9\xa9\x7c\x7c\x7c\xe1\xe1\xe1\x99\x99\x99\xd6\xd6\xd6\xff\xff\xff\xff\xff\xff\x82\x82\x82\xc6\xc6\xc6\x9a\x9a\x9a\xc6\xc6\xc6\x7c\x7c\x7c\x84\x84\x84\xe9\xe9\xe9\xe9\xe9\xe9\xfe\xfe\xfe\xff\xff\xff\x93\x93\x93\xd6\xd6\xd6\xb7\xb7\xb7\x8a\x8a\x8a\x97\x97\x97\x9e\x9e\x9e\xbc\xbc\xbc\x8f\x8f\x8f\xd4\xd4\xd4\x8b\x8b\x8b\xe6\xe6\xe6\x8e\x8e\x8e\xab\xab\xab\xf2\xf2\xf2\xca\xca\xca\xcd\xcd\xcd\xb1\xb1\xb1ccclll\xb2\xb2\xb2\xc9\xc9\xc9\xd6\xd6\xd6\xe1\xe1\xe1\xb6\xb6\xb6\xe4\xe4\xe4\xb4\xb4\xb4\xdc\xdc\xdc\xea\xea\xea\x86\x86\x86\xd2\xd2\xd2\xc4\xc4\xc4\xca\xca\xca\xa6\xa6\xa6\xf5\xf5\xf5\xff\xff\xff\xff\xff\xff\xc0\xc0\xc0\xb5\xb5\xb5\xd0\xd0\xd0\xd2\xd2\xd2\xff\xff\xff\xfe\xfe\xfe\xfd\xfd\xfd\xff\xff\xff\xaf\xaf\xaf\xd3\xd3\xd3\xc2\xc2\xc2\xc4\xc4\xc4\xf3\xf3\xf3\xff\xff\xff\xff\xff\xff\xe4\xe4\xe4\xb0\xb0\xb0\xd5\xd5\xd5\xef\xef\xef\x93\x93\x93\xc3\xc3\xc3\xff\xff\xff\xff\xff\xff\xfd\xfd\xfd\xb1\xb1\xb1\xd2\xd2\xd2\xba\xba\xba\xcd\xcd\xcd\xba\xba\xba\xa9\xa9\xa9\xb5\xb5\xb5\xb1\xb1\xb1\x7f\x7f\x7f\xcc\xcc\xcc\xde\xde\xdewww\xc0\xc0\xc0\xec\xec\xec\xb6\xb6\xb6\x9f\x9f\x9f\xf0\xf0\xf0\xaa\xaa\xaa\x9e\x9e\x9e\xca\xca\xca\xff\xff\xff\xff\xff\xff\xe1\xe1\xe1\xad\xad\xad\xe0\xe0\xe0\xb6\xb6\xb6\xd8\xd8\xd8\xff\xff\xff\xfd\xfd\xfd\xff\xff\xff\xb4\xb4\xb4\xbb\xbb\xbb\xbe\xbe\xbe\xc6\xc6\xc6\xca\xca\xca\xb0\xb0\xb0\xa6\xa6\xa6\xf7\xf7\xf7\xff\xff\xff\xff\xff\xff\xb7\xb7\xb7\xda\xda\xda\xc2\xc2\xc2\xa9\xa9\xa9\xb6\xb6\xb6\xb7\xb7\xb7\xcc\xcc\xcc\xbc\xbc\xbc\xba\xba\xba\x8c\x8c\x8c\x98\x98\x98\xd2\xd2\xd2\x92\x92\x92\xd3\xd3\xd3\xd5\xd5\xd5\xcb\xcb\xcb\xb1\xb1\xb1ccclll\xb2\xb2\xb2\xff\xff\xff\xfe\xfe\xfe\xfe\xfe\xfe\xff\xff\xff\xfe\xfe\xfe\xff\xff\xff\xfe\xfe\xfe\xfe\xfe\xfe\xff\xff\xff\xfe\xfe\xfe\xfe\xfe\xfe\xfd\xfd\xfd\xfe\xfe\xfe\xfe\xfe\xfe\xfd\xfd\xfd\xfe\xfe\xfe\xff\xff\xff\xfe\xfe\xfe\xff\xff\xff\xfe\xfe\xfe\xfd\xfd\xfd\xff\xff\xff\xff\xff\xff\xfd\xfd\xfd\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xff\xff\xff\xfe\xfe\xfe\xfe\xfe\xfe\xff\xff\xff\xfe\xfe\xfe\xff\xff\xff\xfe\xfe\xfe\xfe\xfe\xfe\xff\xff\xff\xff\xff\xff\xfd\xfd\xfd\xfe\xfe\xfe\xfd\xfd\xfd\xfe\xfe\xfe\xff\xff\xff\xfe\xfe\xfe\xff\xff\xff\xfe\xfe\xfe\xfd\xfd\xfd\xff\xff\xff\xd9\xd9\xd9\x86\x86\x86\xff\xff\xff\xe8\xe8\xe8\x7f\x7f\x7f\xfc\xfc\xfc\xfe\xfe\xfe\xfe\xfe\xfe\xff\xff\xff\xfe\xfe\xfe\xfe\xfe\xfe\xff\xff\xff\xfe\xfe\xfe\xff\xff\xff\xfe\xfe\xfe\xff\xff\xff\xfe\xfe\xfe\xfe\xfe\xfe\xff\xff\xff\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfd\xfd\xfd\xff\xff\xff\xfe\xfe\xfe\xfe\xfe\xfe\xff\xff\xff\xfe\xfe\xfe\xfe\xfe\xfe\xff\xff\xff\xfe\xfe\xfe\xff\xff\xff\xfd\xfd\xfd\xfe\xfe\xfe\xff\xff\xff\xfe\xfe\xfe\xff\xff\xff\xff\xff\xff\xfe\xfe\xfe\xfc\xfc\xfc\xff\xff\xff\xac\xac\xac\x9f\x9f\x9f\xcc\xcc\xcc\xf7\xf7\xf7\xff\xff\xff\xff\xff\xff\xd2\xd2\xd2\xcc\xcc\xcc\xb1\xb1\xb1ccclll\xb2\xb2\xb2\xfe\xfe\xfe\xfd\xfd\xfd\xfe\xfe\xfe\xff\xff\xff\xfc\xfc\xfc\xfc\xfc\xfc\xfd\xfd\xfd\xfd\xfd\xfd\xfb\xfb\xfb\xfc\xfc\xfc\xff\xff\xff\xfd\xfd\xfd\xfb\xfb\xfb\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfc\xfc\xfc\xfc\xfc\xfc\xfd\xfd\xfd\xfd\xfd\xfd\xfe\xfe\xfe\xfd\xfd\xfd\xfe\xfe\xfe\xff\xff\xff\xfc\xfc\xfc\xfe\xfe\xfe\xfc\xfc\xfc\xfd\xfd\xfd\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfd\xfd\xfd\xfc\xfc\xfc\xfd\xfd\xfd\xfd\xfd\xfd\xfb\xfb\xfb\xfc\xfc\xfc\xfe\xfe\xfe\xff\xff\xff\xff\xff\xff\xfc\xfc\xfc\xfd\xfd\xfd\xfb\xfb\xfb\xff\xff\xff\xfd\xfd\xfd\xfb\xfb\xfb\xfe\xfe\xfe\xfb\xfb\xfb\xf5\xf5\xf5\xfb\xfb\xfb\xfb\xfb\xfb\xf6\xf6\xf6\xfa\xfa\xfa\xfe\xfe\xfe\xfb\xfb\xfb\xfb\xfb\xfb\xfd\xfd\xfd\xfc\xfc\xfc\xfb\xfb\xfb\xfc\xfc\xfc\xfe\xfe\xfe\xfe\xfe\xfe\xfd\xfd\xfd\xfc\xfc\xfc\xfc\xfc\xfc\xfc\xfc\xfc\xfd\xfd\xfd\xfe\xfe\xfe\xff\xff\xff\xfe\xfe\xfe\xfb\xfb\xfb\xfd\xfd\xfd\xff\xff\xff\xfc\xfc\xfc\xfc\xfc\xfc\xfc\xfc\xfc\xfc\xfc\xfc\xfd\xfd\xfd\xfe\xfe\xfe\xff\xff\xff\xfc\xfc\xfc\xfd\xfd\xfd\xfc\xfc\xfc\xfb\xfb\xfb\xfc\xfc\xfc\xfc\xfc\xfc\xfc\xfc\xfc\xfd\xfd\xfd\xfe\xfe\xfe\xf9\xf9\xf9\xfe\xfe\xfe\xfc\xfc\xfc\xfa\xfa\xfa\xff\xff\xff\xd2\xd2\xd2\xcc\xcc\xcc\xb1\xb1\xb1ccclll\xb2\xb2\xb2\xfd\xfd\xfd\xff\xff\xff\xf4\xf4\xf4\xe5\xe5\xe5\xff\xff\xff\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfc\xfc\xfc\xff\xff\xff\xec\xec\xec\xf2\xf2\xf2\xff\xff\xff\xfb\xfb\xfb\xdc\xdc\xdc\xfe\xfe\xfe\xfd\xfd\xfd\xfd\xfd\xfd\xfe\xfe\xfe\xff\xff\xff\xfd\xfd\xfd\xfd\xfd\xfd\xff\xff\xff\xe7\xe7\xe7\xf1\xf1\xf1\xe5\xe5\xe5\xf7\xf7\xf7\xff\xff\xff\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfe\xfe\xfe\xfe\xfe\xfe\xff\xff\xff\xfd\xfd\xfd\xfd\xfd\xfd\xff\xff\xff\xe0\xe0\xe0\xf1\xf1\xf1\xe4\xe4\xe4\xfc\xfc\xfc\xfd\xfd\xfd\xff\xff\xff\xe4\xe4\xe4\xf0\xf0\xf0\xff\xff\xff\xee\xee\xee\xe8\xe8\xe8\xff\xff\xff\xfd\xfd\xfd\xfc\xfc\xfc\xff\xff\xff\xfe\xfe\xfe\xfc\xfc\xfc\xfe\xfe\xfe\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfe\xfe\xfe\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfc\xfc\xfc\xff\xff\xff\xee\xee\xee\xe5\xe5\xe5\xff\xff\xff\xf6\xf6\xf6\xe3\xe3\xe3\xfd\xfd\xfd\xfe\xfe\xfe\xfd\xfd\xfd\xfc\xfc\xfc\xfd\xfd\xfd\xff\xff\xff\xeb\xeb\xeb\xea\xea\xea\xff\xff\xff\xfd\xfd\xfd\xfd\xfd\xfd\xfe\xfe\xfe\xfe\xfe\xfe\xff\xff\xff\xf3\xf3\xf3\xcd\xcd\xcd\xbe\xbe\xbe\xda\xda\xda\xff\xff\xff\xfc\xfc\xfc\xff\xff\xff\xd2\xd2\xd2\xcc\xcc\xcc\xb1\xb1\xb1ccclll\xb2\xb2\xb2\xf8\xf8\xf8\xff\xff\xff\xe0\xe0\xe0\x7d\x7d\x7d\xff\xff\xff\xfd\xfd\xfd\xfd\xfd\xfd\xfc\xfc\xfc\xfc\xfc\xfc\xff\xff\xff\x9c\x9c\x9c\xb3\xb3\xb3\xff\xff\xff\xf8\xf8\xf8\xd1\xd1\xd1\xff\xff\xff\xfc\xfc\xfc\xfa\xfa\xfa\xff\xff\xff\xfe\xfe\xfe\xfe\xfe\xfe\xf6\xf6\xf6\xff\xff\xff\x98\x98\x98\xbe\xbe\xbe\x8f\x8f\x8f\xd5\xd5\xd5\xff\xff\xff\xfd\xfd\xfd\xf9\xf9\xf9\xfd\xfd\xfd\xfb\xfb\xfb\xfc\xfc\xfc\xfb\xfb\xfb\xfd\xfd\xfd\xf8\xf8\xf8\xff\xff\xff\xd5\xd5\xd5\xed\xed\xedxxx\xf5\xf5\xf5\xf8\xf8\xf8\xff\xff\xff\x98\x98\x98\xb2\xb2\xb2\xff\xff\xff\xc7\xc7\xc7\x88\x88\x88\xff\xff\xff\xf9\xf9\xf9\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfc\xfc\xfc\xfb\xfb\xfb\xfa\xfa\xfa\xff\xff\xff\xfd\xfd\xfd\xf9\xf9\xf9\xff\xff\xff\xfb\xfb\xfb\xf8\xf8\xf8\xff\xff\xff\xfd\xfd\xfd\xfc\xfc\xfc\xfd\xfd\xfd\xff\xff\xff\xc8\xc8\xc8\x86\x86\x86\xff\xff\xff\xf1\xf1\xf1uuu\xfb\xfb\xfb\xfb\xfb\xfb\xf9\xf9\xf9\xff\xff\xff\xf8\xf8\xf8\xff\xff\xff\xb8\xb8\xb8\x97\x97\x97\xff\xff\xff\xf8\xf8\xf8\xf9\xf9\xf9\xfa\xfa\xfa\xff\xff\xff\xf2\xf2\xf2\xc0\xc0\xc0vvv\xb4\xb4\xb4vvv\xb7\xb7\xb7\xff\xff\xff\xff\xff\xff\xd2\xd2\xd2\xcc\xcc\xcc\xb1\xb1\xb1ccclll\xb2\xb2\xb2\xc7\xc7\xc7\xac\xac\xac\xbf\xbf\xbf\x81\x81\x81\x92\x92\x92\xc8\xc8\xc8\xd3\xd3\xd3\x88\x88\x88\xca\xca\xca\xd7\xd7\xd7\x85\x85\x85\xb1\xb1\xb1\xff\xff\xff\xec\xec\xec\xa7\xa7\xa7\xc8\xc8\xc8\x90\x90\x90\x8f\x8f\x8f\xef\xef\xef\xff\xff\xff\xdb\xdb\xdb\xac\xac\xac\xc9\xc9\xc9\xae\xae\xae\xc1\xc1\xc1\x9e\x9e\x9e\xd2\xd2\xd2\xff\xff\xff\xe0\xe0\xe0\xaf\xaf\xaf\xbf\xbf\xbf\x9c\x9c\x9c\xca\xca\xca\xc9\xc9\xc9\xc3\xc3\xc3\xac\xac\xac\xce\xce\xce\xac\xac\xac\xe3\xe3\xe3\x8c\x8c\x8c\xd5\xd5\xd5\xb1\xb1\xb1\xc3\xc3\xc3\xb0\xb0\xb0qqq\x91\x91\x91\xc9\xc9\xc9\x96\x96\x96\xea\xea\xea\x96\x96\x96\xa9\xa9\xa9\xff\xff\xff\xed\xed\xed\x86\x86\x86\xa7\xa7\xa7\xbd\xbd\xbd\xad\xad\xad\xd2\xd2\xd2\x95\x95\x95\x8d\x8d\x8d\xd0\xd0\xd0\xc4\xc4\xc4\x93\x93\x93\xb5\xb5\xb5\xd8\xd8\xd8\x89\x89\x89\xc6\xc6\xc6\xff\xff\xff\xd9\xd9\xd9nnn\x81\x81\x81\xce\xce\xce\x8e\x8e\x8e\xdf\xdf\xdf\xba\xba\xba\xa7\xa7\xa7\xda\xda\xda\xc5\xc5\xc5\xac\xac\xac\xb3\xb3\xb3\x9a\x9a\x9a\xcf\xcf\xcf\xd4\xd4\xd4\xbe\xbe\xbe\xe1\xe1\xe1\xff\xff\xff\xf8\xf8\xf8\xf5\xf5\xf5\x86\x86\x86\xff\xff\xff\xcf\xcf\xcf\x90\x90\x90\xff\xff\xff\xec\xec\xec\xd0\xd0\xd0\xcb\xcb\xcb\xb0\xb0\xb0bbbkkk\xb1\xb1\xb1\xf9\xf9\xf9\xf8\xf8\xf8\xd5\xd5\xd5\x94\x94\x94\xcb\xcb\xcb\x81\x81\x81\x93\x93\x93\xd7\xd7\xd7\x8f\x8f\x8f\xbe\xbe\xbe\xba\xba\xba\xaf\xaf\xaf\xff\xff\xff\xf0\xf0\xf0\x7b\x7b\x7b\xbc\xbc\xbc\xa7\xa7\xa7\x99\x99\x99\xd5\xd5\xd5\xff\xff\xff\xdc\xdc\xdc\xa6\xa6\xa6\x93\x93\x93\xb1\xb1\xb1\xc1\xc1\xc1\x9e\x9e\x9e\xd3\xd3\xd3\xff\xff\xff\xe1\xe1\xe1\xad\xad\xad\x88\x88\x88\xcc\xcc\xcc\x7c\x7c\x7c\xda\xda\xda\xd6\xd6\xd6\x93\x93\x93\xa9\xa9\xa9\x90\x90\x90\xd2\xd2\xd2\x91\x91\x91\xd7\xd7\xd7\xaf\xaf\xaf\x8d\x8d\x8d\xa5\xa5\xa5\xc4\xc4\xc4\xa8\xa8\xa8\x96\x96\x96\xa2\xa2\xa2\x93\x93\x93\xc3\xc3\xc3\xc2\xc2\xc2\xff\xff\xff\xf2\xf2\xf2\x7e\x7e\x7e\xfa\xfa\xfa\xc4\xc4\xc4\x83\x83\x83\xbb\xbb\xbb\x99\x99\x99\xb2\xb2\xb2\xa7\xa7\xa7\x9f\x9f\x9f\xb7\xb7\xb7\xb3\xb3\xb3\x92\x92\x92\xca\xca\xca\xcc\xcc\xcc\xff\xff\xff\xd1\xd1\xd1\x99\x99\x99\xd2\xd2\xd2\x8a\x8a\x8a\xa3\xa3\xa3\x8f\x8f\x8f\xc4\xc4\xc4\xcb\xcb\xcbTTT\xbf\xbf\xbf\xff\xff\xff\xc8\xc8\xc8===\xd3\xd3\xd3\xf7\xf7\xf7hhh\xbc\xbc\xbc\xff\xff\xff\xff\xff\xff\xdd\xdd\xdd\x9a\x9a\x9a\xff\xff\xff\xb3\xb3\xb3\xdc\xdc\xdc\xdd\xdd\xdd\x9d\x9d\x9d\xdc\xdc\xdc\xca\xca\xca\xb1\xb1\xb1ccclll\xb2\xb2\xb2hhh\xad\xad\xad\xd3\xd3\xd3\x8b\x8b\x8b\xb9\xb9\xb9\x8f\x8f\x8f\x7d\x7d\x7d\xc2\xc2\xc2\xbc\xbc\xbc\x80\x80\x80\x8b\x8b\x8b\xa3\xa3\xa3\xff\xff\xff\xec\xec\xec\x7a\x7a\x7a\xb2\xb2\xb2\xa4\xa4\xa4\x92\x92\x92\xcf\xcf\xcf\xff\xff\xff\xa0\xa0\xa0\x7f\x7f\x7f\x8c\x8c\x8c\x99\x99\x99\xb8\xb8\xb8\x91\x91\x91\xcb\xcb\xcb\xff\xff\xff\xac\xac\xac\x80\x80\x80\x79\x79\x79\xf6\xf6\xf6vvv\xec\xec\xec\x8e\x8e\x8e\x83\x83\x83\x98\x98\x98\x86\x86\x86\xc7\xc7\xc7\x8e\x8e\x8e\x9e\x9e\x9e\x80\x80\x80\x89\x89\x89\xa0\xa0\xa0\xa6\xa6\xa6\xc6\xc6\xc6\xb4\xb4\xb4\x95\x95\x95\x96\x96\x96\x96\x96\x96\xdf\xdf\xdf\xff\xff\xff\xed\xed\xed\x7a\x7a\x7a\xe9\xe9\xe9www\x84\x84\x84\x9f\x9f\x9f\x98\x98\x98\xa8\xa8\xa8\xae\xae\xae\xaa\xaa\xaa\x90\x90\x90\xe1\xe1\xe1vvv\xb2\xb2\xb2\xe6\xe6\xe6\xff\xff\xff\xda\xda\xda\x8a\x8a\x8a\xcb\xcb\xcb\xc1\xc1\xc1\x88\x88\x88\xb6\xb6\xb6\x99\x99\x99\xc8\xc8\xc8\xa6\xa6\xa6ooo\xc8\xc8\xc8\xbd\xbd\xbdxxx\x82\x82\x82\xd8\xd8\xd8\xbf\xbf\xbf\x84\x84\x84\xff\xff\xff\xff\xff\xff\xa7\xa7\xa7\x92\x92\x92\xcc\xcc\xcc\xd2\xd2\xd2\xff\xff\xff\xb8\xb8\xb8\xc6\xc6\xc6\xdf\xdf\xdf\xca\xca\xca\xb1\xb1\xb1ccclll\xb2\xb2\xb2\xcf\xcf\xcf\xd5\xd5\xd5\xf7\xf7\xf7\xe5\xe5\xe5\xe8\xe8\xe8\xee\xee\xee\xe8\xe8\xe8\xcf\xcf\xcf\xff\xff\xff\xde\xde\xde\xd7\xd7\xd7\xf1\xf1\xf1\xff\xff\xff\xf7\xf7\xf7\xe4\xe4\xe4\xe9\xe9\xe9\xea\xea\xea\xe6\xe6\xe6\xf2\xf2\xf2\xff\xff\xff\xf1\xf1\xf1\xde\xde\xde\xe5\xe5\xe5\xe3\xe3\xe3\xec\xec\xec\xe5\xe5\xe5\xf1\xf1\xf1\xff\xff\xff\xf4\xf4\xf4\xde\xde\xde\xe2\xe2\xe2\xf7\xf7\xf7\xf5\xf5\xf5\xfe\xfe\xfe\xea\xea\xea\xdf\xdf\xdf\xe4\xe4\xe4\xe4\xe4\xe4\xed\xed\xed\xe5\xe5\xe5\xee\xee\xee\xde\xde\xde\xe4\xe4\xe4\xf0\xf0\xf0\xdd\xdd\xdd\xf1\xf1\xf1\xf2\xf2\xf2\xe6\xe6\xe6\xf7\xf7\xf7\xcb\xcb\xcb\xf2\xf2\xf2\xff\xff\xff\xf7\xf7\xf7\xe1\xe1\xe1\xfa\xfa\xfa\xe1\xe1\xe1\xe3\xe3\xe3\xe3\xe3\xe3\xe8\xe8\xe8\xee\xee\xee\xd7\xd7\xd7\x8a\x8a\x8a\xa7\xa7\xa7\xb3\xb3\xb3\xf2\xf2\xf2\xcc\xcc\xcc\xfb\xfb\xfb\xfe\xfe\xfe\xfe\xfe\xfe\xe2\xe2\xe2\xe6\xe6\xe6\xf9\xf9\xf9\xe1\xe1\xe1\xfa\xfa\xfa\xe4\xe4\xe4\xe5\xe5\xe5\xff\xff\xff\xda\xda\xda\xdd\xdd\xdd\xf1\xf1\xf1\xeb\xeb\xeb\xe6\xe6\xe6\xe3\xe3\xe3\xea\xea\xea\xf8\xf8\xf8\xfe\xfe\xfe\xff\xff\xff\xe5\xe5\xe5\xd9\xd9\xd9\xf3\xf3\xf3\xfe\xfe\xfe\xff\xff\xff\x94\x94\x94\xe4\xe4\xe4\xd8\xd8\xd8\xca\xca\xca\xb0\xb0\xb0bbbkkk\xb1\xb1\xb1\xff\xff\xff\xfe\xfe\xfe\xfe\xfe\xfe\xff\xff\xff\xff\xff\xff\xfe\xfe\xfe\xfe\xfe\xfe\xff\xff\xff\xfd\xfd\xfd\xfe\xfe\xfe\xff\xff\xff\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xff\xff\xff\xff\xff\xff\xfe\xfe\xfe\xff\xff\xff\xfe\xfe\xfe\xfe\xfe\xfe\xff\xff\xff\xfe\xfe\xfe\xfe\xfe\xfe\xff\xff\xff\xff\xff\xff\xfe\xfe\xfe\xff\xff\xff\xfe\xfe\xfe\xfe\xfe\xfe\xff\xff\xff\xfe\xfe\xfe\xfd\xfd\xfd\xfe\xfe\xfe\xff\xff\xff\xfe\xfe\xfe\xfe\xfe\xfe\xff\xff\xff\xfe\xfe\xfe\xff\xff\xff\xfe\xfe\xfe\xfe\xfe\xfe\xff\xff\xff\xfe\xfe\xfe\xff\xff\xff\xfe\xfe\xfe\xfe\xfe\xfe\xff\xff\xff\xfd\xfd\xfd\xff\xff\xff\xfe\xfe\xfe\xfe\xfe\xfe\xff\xff\xff\xfe\xfe\xfe\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xfe\xfe\xfe\xfe\xfe\xff\xff\xff\xf9\xf9\xf9\xb2\xb2\xb2\xc9\xc9\xc9\xfa\xfa\xfa\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xff\xff\xff\xfe\xfe\xfe\xff\xff\xff\xfe\xfe\xfe\xfd\xfd\xfd\xff\xff\xff\xfd\xfd\xfd\xfe\xfe\xfe\xfe\xfe\xfe\xfc\xfc\xfc\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xff\xff\xff\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xff\xff\xff\xfe\xfe\xfe\xff\xff\xff\xfe\xfe\xfe\xfd\xfd\xfd\xfc\xfc\xfc\xe8\xe8\xe8\xfe\xfe\xfe\xd3\xd3\xd3\xcc\xcc\xcc\xb1\xb1\xb1ccclll\xb2\xb2\xb2\xf9\xf9\xf9\xfb\xfb\xfb\xfe\xfe\xfe\xfd\xfd\xfd\xfb\xfb\xfb\xfb\xfb\xfb\xfc\xfc\xfc\xfb\xfb\xfb\xfd\xfd\xfd\xfe\xfe\xfe\xfc\xfc\xfc\xfc\xfc\xfc\xfc\xfc\xfc\xfd\xfd\xfd\xfe\xfe\xfe\xfc\xfc\xfc\xfb\xfb\xfb\xfb\xfb\xfb\xfd\xfd\xfd\xfc\xfc\xfc\xfb\xfb\xfb\xfc\xfc\xfc\xfb\xfb\xfb\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfe\xfe\xfe\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfe\xfe\xfe\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfc\xfc\xfc\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfc\xfc\xfc\xfd\xfd\xfd\xfe\xfe\xfe\xfd\xfd\xfd\xfd\xfd\xfd\xfe\xfe\xfe\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xff\xff\xff\xff\xff\xff\xfe\xfe\xfe\xfd\xfd\xfd\xfc\xfc\xfc\xfe\xfe\xfe\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfe\xfe\xfe\xfd\xfd\xfd\xfd\xfd\xfd\xfe\xfe\xfe\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfe\xfe\xfe\xfe\xfe\xfe\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfe\xfe\xfe\xfd\xfd\xfd\xff\xff\xff\xd1\xd1\xd1\xcb\xcb\xcb\xb0\xb0\xb0bbbkkk\xb1\xb1\xb1\xfc\xfc\xfc\xff\xff\xff\xd4\xd4\xd4\xdd\xdd\xdd\xff\xff\xff\xfd\xfd\xfd\xfe\xfe\xfe\xfe\xfe\xfe\xff\xff\xff\xc3\xc3\xc3\xf8\xf8\xf8\xff\xff\xff\xff\xff\xff\xe5\xe5\xe5\xce\xce\xce\xff\xff\xff\xfd\xfd\xfd\xff\xff\xff\xfe\xfe\xfe\xfe\xfe\xfe\xff\xff\xff\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xfe\xfe\xfe\xfe\xfe\xff\xff\xff\xff\xff\xff\xfe\xfe\xfe\xfe\xfe\xfe\xff\xff\xff\xff\xff\xff\xfe\xfe\xfe\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xfe\xfe\xff\xff\xff\xff\xff\xff\xfe\xfe\xfe\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xfe\xfe\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xfe\xfe\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xfe\xfe\xfe\xfe\xfe\xff\xff\xff\xfe\xfe\xfe\xfb\xfb\xfb\xfc\xfc\xfc\xfe\xfe\xfe\xff\xff\xff\xfe\xfe\xfe\xff\xff\xff\xfe\xfe\xfe\xff\xff\xff\xfe\xfe\xfe\xfe\xfe\xfe\xff\xff\xff\xff\xff\xff\xfe\xfe\xfe\xfe\xfe\xfe\xff\xff\xff\xfe\xfe\xfe\xfe\xfe\xfe\xff\xff\xff\xff\xff\xff\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xfe\xfe\xfe\xfe\xfe\xff\xff\xff\xfe\xfe\xfe\xfc\xfc\xfc\xff\xff\xff\xd2\xd2\xd2\xcc\xcc\xcc\xb1\xb1\xb1ccclll\xb2\xb2\xb2\xaf\xaf\xaf\xe1\xe1\xe1\xe1\xe1\xe1\xe2\xe2\xe2\xdc\xdc\xdc\xc9\xc9\xc9\xd7\xd7\xd7\xca\xca\xca\xf1\xf1\xf1\xd5\xd5\xd5\xe6\xe6\xe6\xd8\xd8\xd8\xcc\xcc\xcc\xe0\xe0\xe0\xdc\xdc\xdc\xe3\xe3\xe3\xc0\xc0\xc0\xd7\xd7\xd7\xff\xff\xff\xd3\xd3\xd3\xcf\xcf\xcf\xeb\xeb\xeb\xd5\xd5\xd5\xff\xff\xff\xfe\xfe\xfe\xfe\xfe\xfe\xff\xff\xff\xff\xff\xff\xfe\xfe\xfe\xfe\xfe\xfe\xff\xff\xff\xff\xff\xff\xfe\xfe\xfe\xfe\xfe\xfe\xff\xff\xff\xff\xff\xff\xfe\xfe\xfe\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xfe\xfe\xff\xff\xff\xff\xff\xff\xfe\xfe\xfe\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xfe\xfe\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xfe\xfe\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xfe\xfe\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xfe\xfe\xff\xff\xff\xff\xff\xff\xfe\xfe\xfe\xff\xff\xff\xff\xff\xff\xfe\xfe\xfe\xff\xff\xff\xfe\xfe\xfe\xfe\xfe\xfe\xff\xff\xff\xff\xff\xff\xfe\xfe\xfe\xfe\xfe\xfe\xff\xff\xff\xfe\xfe\xfe\xfe\xfe\xfe\xff\xff\xff\xff\xff\xff\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xfe\xfe\xff\xff\xff\xfe\xfe\xfe\xff\xff\xff\xfd\xfd\xfd\xff\xff\xff\xd2\xd2\xd2\xcc\xcc\xcc\xb1\xb1\xb1ccclll\xb2\xb2\xb2\x98\x98\x98\x9a\x9a\x9a\xa3\xa3\xa3\xaf\xaf\xaf\x86\x86\x86\xab\xab\xab\x88\x88\x88\x9d\x9d\x9d\xb1\xb1\xb1\x80\x80\x80\xe2\xe2\xe2\xb7\xb7\xb7\x7c\x7c\x7c\xc7\xc7\xc7\x93\x93\x93\x9f\x9f\x9f\x95\x95\x95\x92\x92\x92\xb8\xb8\xb8\xa0\xa0\xa0\x80\x80\x80\xe5\xe5\xe5\xd4\xd4\xd4\xff\xff\xff\xfe\xfe\xfe\xfe\xfe\xfe\xff\xff\xff\xff\xff\xff\xfe\xfe\xfe\xfe\xfe\xfe\xff\xff\xff\xff\xff\xff\xfe\xfe\xfe\xfe\xfe\xfe\xff\xff\xff\xff\xff\xff\xfe\xfe\xfe\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xfe\xfe\xff\xff\xff\xff\xff\xff\xfe\xfe\xfe\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xfe\xfe\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xfe\xfe\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xfe\xfe\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xfe\xfe\xff\xff\xff\xff\xff\xff\xfe\xfe\xfe\xff\xff\xff\xff\xff\xff\xfe\xfe\xfe\xff\xff\xff\xfe\xfe\xfe\xfe\xfe\xfe\xff\xff\xff\xff\xff\xff\xfe\xfe\xfe\xfe\xfe\xfe\xff\xff\xff\xfe\xfe\xfe\xfe\xfe\xfe\xff\xff\xff\xff\xff\xff\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xfe\xfe\xff\xff\xff\xfe\xfe\xfe\xff\xff\xff\xfd\xfd\xfd\xff\xff\xff\xd2\xd2\xd2\xcc\xcc\xcc\xb1\xb1\xb1ccclll\xb2\xb2\xb2\xc5\xc5\xc5\x99\x99\x99\xa6\xa6\xa6\xb1\xb1\xb1\x8f\x8f\x8f\xc7\xc7\xc7\x96\x96\x96\xb8\xb8\xb8\xaa\xaa\xaa\x82\x82\x82\xe1\xe1\xe1qqq\xe3\xe3\xe3\xc4\xc4\xc4\x96\x96\x96\xa5\xa5\xa5\xba\xba\xba\x90\x90\x90\xd2\xd2\xd2\x93\x93\x93\xd4\xd4\xd4\xfc\xfc\xfc\xf5\xf5\xf5\xff\xff\xff\xfe\xfe\xfe\xfe\xfe\xfe\xff\xff\xff\xff\xff\xff\xfe\xfe\xfe\xfe\xfe\xfe\xff\xff\xff\xff\xff\xff\xfe\xfe\xfe\xfe\xfe\xfe\xff\xff\xff\xff\xff\xff\xfe\xfe\xfe\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xfe\xfe\xff\xff\xff\xff\xff\xff\xfe\xfe\xfe\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xfe\xfe\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xfe\xfe\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xfe\xfe\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xfe\xfe\xff\xff\xff\xff\xff\xff\xfe\xfe\xfe\xff\xff\xff\xff\xff\xff\xfe\xfe\xfe\xff\xff\xff\xfe\xfe\xfe\xfe\xfe\xfe\xff\xff\xff\xff\xff\xff\xfe\xfe\xfe\xfe\xfe\xfe\xff\xff\xff\xfe\xfe\xfe\xfe\xfe\xfe\xff\xff\xff\xff\xff\xff\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xfe\xfe\xff\xff\xff\xfe\xfe\xfe\xff\xff\xff\xfd\xfd\xfd\xff\xff\xff\xd2\xd2\xd2\xcc\xcc\xcc\xb1\xb1\xb1ccclll\xb2\xb2\xb2\xcd\xcd\xcd\xb5\xb5\xb5\xbd\xbd\xbd\xc1\xc1\xc1\xb3\xb3\xb3\xcd\xcd\xcd\xb3\xb3\xb3\xc7\xc7\xc7\xbc\xbc\xbc\xb1\xb1\xb1\xbf\xbf\xbf\xa3\xa3\xa3\xd7\xd7\xd7\xbe\xbe\xbe\xb7\xb7\xb7\xba\xba\xba\xc6\xc6\xc6\xb5\xb5\xb5\xc0\xc0\xc0\x8a\x8a\x8a\x98\x98\x98\xd5\xd5\xd5\xbf\xbf\xbf\xff\xff\xff\xfd\xfd\xfd\xfe\xfe\xfe\xff\xff\xff\xff\xff\xff\xfe\xfe\xfe\xfe\xfe\xfe\xff\xff\xff\xff\xff\xff\xfe\xfe\xfe\xfe\xfe\xfe\xff\xff\xff\xff\xff\xff\xfe\xfe\xfe\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xfe\xfe\xff\xff\xff\xff\xff\xff\xfe\xfe\xfe\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xfe\xfe\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xfe\xfe\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xfe\xfe\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xfe\xfe\xff\xff\xff\xff\xff\xff\xfe\xfe\xfe\xff\xff\xff\xff\xff\xff\xfe\xfe\xfe\xff\xff\xff\xfe\xfe\xfe\xfe\xfe\xfe\xff\xff\xff\xff\xff\xff\xfe\xfe\xfe\xfe\xfe\xfe\xff\xff\xff\xfe\xfe\xfe\xfe\xfe\xfe\xff\xff\xff\xff\xff\xff\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xfe\xfe\xff\xff\xff\xfe\xfe\xfe\xff\xff\xff\xfd\xfd\xfd\xff\xff\xff\xd2\xd2\xd2\xcc\xcc\xcc\xb1\xb1\xb1ccclll\xb2\xb2\xb2\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfc\xfc\xfc\xff\xff\xff\xac\xac\xac\x9e\x9e\x9e\xc7\xc7\xc7\xf3\xf3\xf3\xff\xff\xff\xfd\xfd\xfd\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfd\xfd\xfd\xfd\xfd\xfd\xfe\xfe\xfe\xfe\xfe\xfe\xfd\xfd\xfd\xfd\xfd\xfd\xfe\xfe\xfe\xfe\xfe\xfe\xfd\xfd\xfd\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfd\xfd\xfd\xfe\xfe\xfe\xfe\xfe\xfe\xfd\xfd\xfd\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfd\xfd\xfd\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfd\xfd\xfd\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfd\xfd\xfd\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfd\xfd\xfd\xfe\xfe\xfe\xfe\xfe\xfe\xfd\xfd\xfd\xfe\xfe\xfe\xfe\xfe\xfe\xfd\xfd\xfd\xfe\xfe\xfe\xfd\xfd\xfd\xfd\xfd\xfd\xfe\xfe\xfe\xfe\xfe\xfe\xfd\xfd\xfd\xfd\xfd\xfd\xfe\xfe\xfe\xfd\xfd\xfd\xfd\xfd\xfd\xfe\xfe\xfe\xfe\xfe\xfe\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfd\xfd\xfd\xfe\xfe\xfe\xfd\xfd\xfd\xfe\xfe\xfe\xfc\xfc\xfc\xff\xff\xff\xd1\xd1\xd1\xcb\xcb\xcb\xb0\xb0\xb0bbbkkk\xb1\xb1\xb1\xfd\xfd\xfd\xfc\xfc\xfc\xfd\xfd\xfd\xfd\xfd\xfd\xfc\xfc\xfc\xfd\xfd\xfd\xfc\xfc\xfc\xfd\xfd\xfd\xfd\xfd\xfd\xfc\xfc\xfc\xfd\xfd\xfd\xfc\xfc\xfc\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfc\xfc\xfc\xe6\xe6\xe6\xf7\xf7\xf7\xff\xff\xff\xfc\xfc\xfc\xfe\xfe\xfe\xfd\xfd\xfd\xfd\xfd\xfd\xfe\xfe\xfe\xfe\xfe\xfe\xfd\xfd\xfd\xfd\xfd\xfd\xfe\xfe\xfe\xfe\xfe\xfe\xfd\xfd\xfd\xfd\xfd\xfd\xfe\xfe\xfe\xfe\xfe\xfe\xfd\xfd\xfd\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfd\xfd\xfd\xfe\xfe\xfe\xfe\xfe\xfe\xfd\xfd\xfd\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfd\xfd\xfd\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfd\xfd\xfd\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfd\xfd\xfd\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfd\xfd\xfd\xfe\xfe\xfe\xfe\xfe\xfe\xfd\xfd\xfd\xfe\xfe\xfe\xfe\xfe\xfe\xfd\xfd\xfd\xfe\xfe\xfe\xfd\xfd\xfd\xfd\xfd\xfd\xfe\xfe\xfe\xfe\xfe\xfe\xfd\xfd\xfd\xfd\xfd\xfd\xfe\xfe\xfe\xfd\xfd\xfd\xfd\xfd\xfd\xfe\xfe\xfe\xfe\xfe\xfe\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfd\xfd\xfd\xfe\xfe\xfe\xfd\xfd\xfd\xfe\xfe\xfe\xfc\xfc\xfc\xff\xff\xff\xd1\xd1\xd1\xcb\xcb\xcb\xb0\xb0\xb0bbbkkk\xb1\xb1\xb1\xfd\xfd\xfd\xfd\xfd\xfd\xfe\xfe\xfe\xfd\xfd\xfd\xfe\xfe\xfe\xfd\xfd\xfd\xfe\xfe\xfe\xfd\xfd\xfd\xfe\xfe\xfe\xfe\xfe\xfe\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfe\xfe\xfe\xfe\xfe\xfe\xfd\xfd\xfd\xfd\xfd\xfd\xff\xff\xff\xfe\xfe\xfe\xfd\xfd\xfd\xfe\xfe\xfe\xfd\xfd\xfd\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfd\xfd\xfd\xfd\xfd\xfd\xfe\xfe\xfe\xfe\xfe\xfe\xfd\xfd\xfd\xfd\xfd\xfd\xfe\xfe\xfe\xfe\xfe\xfe\xfd\xfd\xfd\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfd\xfd\xfd\xfe\xfe\xfe\xfe\xfe\xfe\xfd\xfd\xfd\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfd\xfd\xfd\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfd\xfd\xfd\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfd\xfd\xfd\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfd\xfd\xfd\xfe\xfe\xfe\xfe\xfe\xfe\xfd\xfd\xfd\xfe\xfe\xfe\xfe\xfe\xfe\xfd\xfd\xfd\xfe\xfe\xfe\xfd\xfd\xfd\xfd\xfd\xfd\xfe\xfe\xfe\xfe\xfe\xfe\xfd\xfd\xfd\xfd\xfd\xfd\xfe\xfe\xfe\xfd\xfd\xfd\xfd\xfd\xfd\xfe\xfe\xfe\xfe\xfe\xfe\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfd\xfd\xfd\xfe\xfe\xfe\xfd\xfd\xfd\xfe\xfe\xfe\xfc\xfc\xfc\xff\xff\xff\xd1\xd1\xd1\xcb\xcb\xcb\xb0\xb0\xb0bbbkkk\xb1\xb1\xb1\xfd\xfd\xfd\xfd\xfd\xfd\xfe\xfe\xfe\xfd\xfd\xfd\xfe\xfe\xfe\xfd\xfd\xfd\xfe\xfe\xfe\xfd\xfd\xfd\xfe\xfe\xfe\xfe\xfe\xfe\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfd\xfd\xfd\xfd\xfd\xfd\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfd\xfd\xfd\xfd\xfd\xfd\xfe\xfe\xfe\xfe\xfe\xfe\xfd\xfd\xfd\xfd\xfd\xfd\xfe\xfe\xfe\xfe\xfe\xfe\xfd\xfd\xfd\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfd\xfd\xfd\xfe\xfe\xfe\xfe\xfe\xfe\xfd\xfd\xfd\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfd\xfd\xfd\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfd\xfd\xfd\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfd\xfd\xfd\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfd\xfd\xfd\xfe\xfe\xfe\xfe\xfe\xfe\xfd\xfd\xfd\xfe\xfe\xfe\xfe\xfe\xfe\xfd\xfd\xfd\xfe\xfe\xfe\xfd\xfd\xfd\xfd\xfd\xfd\xfe\xfe\xfe\xfe\xfe\xfe\xfd\xfd\xfd\xfd\xfd\xfd\xfe\xfe\xfe\xfd\xfd\xfd\xfd\xfd\xfd\xfe\xfe\xfe\xfe\xfe\xfe\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfd\xfd\xfd\xfe\xfe\xfe\xfd\xfd\xfd\xfe\xfe\xfe\xfc\xfc\xfc\xff\xff\xff\xd1\xd1\xd1\xcb\xcb\xcb\xb0\xb0\xb0bbbkkk\xb1\xb1\xb1\xfe\xfe\xfe\xfe\xfe\xfe\xff\xff\xff\xfe\xfe\xfe\xff\xff\xff\xfe\xfe\xfe\xff\xff\xff\xfe\xfe\xfe\xff\xff\xff\xff\xff\xff\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xfe\xfe\xfe\xfe\xfe\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xfe\xfe\xfe\xfe\xfe\xff\xff\xff\xff\xff\xff\xfe\xfe\xfe\xfe\xfe\xfe\xff\xff\xff\xff\xff\xff\xfe\xfe\xfe\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xfe\xfe\xff\xff\xff\xff\xff\xff\xfe\xfe\xfe\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xfe\xfe\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xfe\xfe\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xfe\xfe\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xfe\xfe\xff\xff\xff\xff\xff\xff\xfe\xfe\xfe\xff\xff\xff\xff\xff\xff\xfe\xfe\xfe\xff\xff\xff\xfe\xfe\xfe\xfe\xfe\xfe\xff\xff\xff\xff\xff\xff\xfe\xfe\xfe\xfe\xfe\xfe\xff\xff\xff\xfe\xfe\xfe\xfe\xfe\xfe\xff\xff\xff\xff\xff\xff\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xfe\xfe\xff\xff\xff\xfe\xfe\xfe\xff\xff\xff\xfd\xfd\xfd\xff\xff\xff\xd2\xd2\xd2\xcc\xcc\xcc\xb1\xb1\xb1ccclll\xb2\xb2\xb2\xfe\xfe\xfe\xfe\xfe\xfe\xff\xff\xff\xfe\xfe\xfe\xff\xff\xff\xfe\xfe\xfe\xff\xff\xff\xfe\xfe\xfe\xff\xff\xff\xff\xff\xff\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xfe\xfe\xfe\xfe\xfe\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xfe\xfe\xfe\xfe\xfe\xff\xff\xff\xff\xff\xff\xfe\xfe\xfe\xfe\xfe\xfe\xff\xff\xff\xff\xff\xff\xfe\xfe\xfe\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xfe\xfe\xff\xff\xff\xff\xff\xff\xfe\xfe\xfe\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xfe\xfe\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xfe\xfe\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xfe\xfe\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xfe\xfe\xff\xff\xff\xff\xff\xff\xfe\xfe\xfe\xff\xff\xff\xff\xff\xff\xfe\xfe\xfe\xff\xff\xff\xfe\xfe\xfe\xfe\xfe\xfe\xff\xff\xff\xff\xff\xff\xfe\xfe\xfe\xfe\xfe\xfe\xff\xff\xff\xfe\xfe\xfe\xfe\xfe\xfe\xff\xff\xff\xff\xff\xff\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xfe\xfe\xff\xff\xff\xfe\xfe\xfe\xff\xff\xff\xfd\xfd\xfd\xff\xff\xff\xd2\xd2\xd2\xcc\xcc\xcc\xb1\xb1\xb1ccclll\xb2\xb2\xb2\xfe\xfe\xfe\xfe\xfe\xfe\xff\xff\xff\xfe\xfe\xfe\xff\xff\xff\xfe\xfe\xfe\xff\xff\xff\xfe\xfe\xfe\xff\xff\xff\xff\xff\xff\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xfe\xfe\xfe\xfe\xfe\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xfe\xfe\xfe\xfe\xfe\xff\xff\xff\xff\xff\xff\xfe\xfe\xfe\xfe\xfe\xfe\xff\xff\xff\xff\xff\xff\xfe\xfe\xfe\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xfe\xfe\xff\xff\xff\xff\xff\xff\xfe\xfe\xfe\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xfe\xfe\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xfe\xfe\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xfe\xfe\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xfe\xfe\xff\xff\xff\xff\xff\xff\xfe\xfe\xfe\xff\xff\xff\xff\xff\xff\xfe\xfe\xfe\xff\xff\xff\xfe\xfe\xfe\xfe\xfe\xfe\xff\xff\xff\xff\xff\xff\xfe\xfe\xfe\xfe\xfe\xfe\xff\xff\xff\xfe\xfe\xfe\xfe\xfe\xfe\xff\xff\xff\xff\xff\xff\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xfe\xfe\xff\xff\xff\xfe\xfe\xfe\xff\xff\xff\xfd\xfd\xfd\xff\xff\xff\xd2\xd2\xd2\xcc\xcc\xcc\xb1\xb1\xb1ccclll\xb2\xb2\xb2\xfe\xfe\xfe\xfe\xfe\xfe\xff\xff\xff\xfe\xfe\xfe\xff\xff\xff\xfe\xfe\xfe\xff\xff\xff\xfe\xfe\xfe\xff\xff\xff\xff\xff\xff\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xfe\xfe\xfe\xfe\xfe\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xfe\xfe\xfe\xfe\xfe\xff\xff\xff\xff\xff\xff\xfe\xfe\xfe\xfe\xfe\xfe\xff\xff\xff\xff\xff\xff\xfe\xfe\xfe\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xfe\xfe\xff\xff\xff\xff\xff\xff\xfe\xfe\xfe\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xfe\xfe\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xfe\xfe\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xfe\xfe\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xfe\xfe\xff\xff\xff\xff\xff\xff\xfe\xfe\xfe\xff\xff\xff\xff\xff\xff\xfe\xfe\xfe\xff\xff\xff\xfe\xfe\xfe\xfe\xfe\xfe\xff\xff\xff\xff\xff\xff\xfe\xfe\xfe\xfe\xfe\xfe\xff\xff\xff\xfe\xfe\xfe\xfe\xfe\xfe\xff\xff\xff\xff\xff\xff\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xfe\xfe\xff\xff\xff\xfe\xfe\xfe\xff\xff\xff\xfd\xfd\xfd\xff\xff\xff\xd2\xd2\xd2\xcc\xcc\xcc\xb1\xb1\xb1ccclll\xb2\xb2\xb2\xfe\xfe\xfe\xfe\xfe\xfe\xff\xff\xff\xfe\xfe\xfe\xff\xff\xff\xfe\xfe\xfe\xff\xff\xff\xfe\xfe\xfe\xff\xff\xff\xff\xff\xff\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xfe\xfe\xfe\xfe\xfe\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xfe\xfe\xfe\xfe\xfe\xff\xff\xff\xff\xff\xff\xfe\xfe\xfe\xfe\xfe\xfe\xff\xff\xff\xff\xff\xff\xfe\xfe\xfe\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xfe\xfe\xff\xff\xff\xff\xff\xff\xfe\xfe\xfe\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xfe\xfe\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xfe\xfe\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xfe\xfe\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xfe\xfe\xff\xff\xff\xff\xff\xff\xfe\xfe\xfe\xff\xff\xff\xff\xff\xff\xfe\xfe\xfe\xff\xff\xff\xfe\xfe\xfe\xfe\xfe\xfe\xff\xff\xff\xff\xff\xff\xfe\xfe\xfe\xfe\xfe\xfe\xff\xff\xff\xfe\xfe\xfe\xfe\xfe\xfe\xff\xff\xff\xff\xff\xff\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xfe\xfe\xff\xff\xff\xfe\xfe\xfe\xff\xff\xff\xfd\xfd\xfd\xff\xff\xff\xd2\xd2\xd2\xcc\xcc\xcc\xb1\xb1\xb1ccclll\xb2\xb2\xb2\xfe\xfe\xfe\xfe\xfe\xfe\xff\xff\xff\xfe\xfe\xfe\xff\xff\xff\xfe\xfe\xfe\xff\xff\xff\xfe\xfe\xfe\xff\xff\xff\xff\xff\xff\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xfe\xfe\xfe\xfe\xfe\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xfe\xfe\xfe\xfe\xfe\xff\xff\xff\xff\xff\xff\xfe\xfe\xfe\xfe\xfe\xfe\xff\xff\xff\xff\xff\xff\xfe\xfe\xfe\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xfe\xfe\xff\xff\xff\xff\xff\xff\xfe\xfe\xfe\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xfe\xfe\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xfe\xfe\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xfe\xfe\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xfe\xfe\xff\xff\xff\xff\xff\xff\xfe\xfe\xfe\xff\xff\xff\xff\xff\xff\xfe\xfe\xfe\xff\xff\xff\xfe\xfe\xfe\xfe\xfe\xfe\xff\xff\xff\xff\xff\xff\xfe\xfe\xfe\xfe\xfe\xfe\xff\xff\xff\xfe\xfe\xfe\xfe\xfe\xfe\xff\xff\xff\xff\xff\xff\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xfe\xfe\xff\xff\xff\xfe\xfe\xfe\xff\xff\xff\xfd\xfd\xfd\xff\xff\xff\xd2\xd2\xd2\xcc\xcc\xcc\xb1\xb1\xb1ccclll\xb2\xb2\xb2\xfd\xfd\xfd\xfd\xfd\xfd\xfe\xfe\xfe\xfd\xfd\xfd\xfe\xfe\xfe\xfd\xfd\xfd\xfe\xfe\xfe\xfd\xfd\xfd\xfe\xfe\xfe\xfe\xfe\xfe\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfd\xfd\xfd\xfd\xfd\xfd\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfd\xfd\xfd\xfd\xfd\xfd\xfe\xfe\xfe\xfe\xfe\xfe\xfd\xfd\xfd\xfd\xfd\xfd\xfe\xfe\xfe\xfe\xfe\xfe\xfd\xfd\xfd\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfd\xfd\xfd\xfe\xfe\xfe\xfe\xfe\xfe\xfd\xfd\xfd\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfd\xfd\xfd\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfd\xfd\xfd\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfd\xfd\xfd\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfd\xfd\xfd\xfe\xfe\xfe\xfe\xfe\xfe\xfd\xfd\xfd\xfe\xfe\xfe\xfe\xfe\xfe\xfd\xfd\xfd\xfe\xfe\xfe\xfd\xfd\xfd\xfd\xfd\xfd\xfe\xfe\xfe\xfe\xfe\xfe\xfd\xfd\xfd\xfd\xfd\xfd\xfe\xfe\xfe\xfd\xfd\xfd\xfd\xfd\xfd\xfe\xfe\xfe\xfe\xfe\xfe\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfd\xfd\xfd\xfe\xfe\xfe\xfd\xfd\xfd\xfe\xfe\xfe\xfc\xfc\xfc\xff\xff\xff\xd1\xd1\xd1\xcb\xcb\xcb\xb0\xb0\xb0bbbkkk\xb1\xb1\xb1\xfe\xfe\xfe\xfe\xfe\xfe\xff\xff\xff\xfe\xfe\xfe\xff\xff\xff\xfe\xfe\xfe\xff\xff\xff\xfe\xfe\xfe\xff\xff\xff\xff\xff\xff\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xfe\xfe\xfe\xfe\xfe\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xfe\xfe\xfe\xfe\xfe\xff\xff\xff\xff\xff\xff\xfe\xfe\xfe\xfe\xfe\xfe\xff\xff\xff\xff\xff\xff\xfe\xfe\xfe\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xfe\xfe\xff\xff\xff\xff\xff\xff\xfe\xfe\xfe\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xfe\xfe\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xfe\xfe\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xfe\xfe\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xfe\xfe\xff\xff\xff\xff\xff\xff\xfe\xfe\xfe\xff\xff\xff\xff\xff\xff\xfe\xfe\xfe\xff\xff\xff\xfe\xfe\xfe\xfe\xfe\xfe\xff\xff\xff\xff\xff\xff\xfe\xfe\xfe\xfe\xfe\xfe\xff\xff\xff\xfe\xfe\xfe\xfe\xfe\xfe\xff\xff\xff\xff\xff\xff\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xfe\xfe\xff\xff\xff\xfe\xfe\xfe\xff\xff\xff\xfd\xfd\xfd\xff\xff\xff\xd2\xd2\xd2\xcc\xcc\xcc\xb1\xb1\xb1ccclll\xb2\xb2\xb2\xfe\xfe\xfe\xfd\xfd\xfd\xfc\xfc\xfc\xfc\xfc\xfc\xfe\xfe\xfe\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfe\xfe\xfe\xfe\xfe\xfe\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfd\xfd\xfd\xfd\xfd\xfd\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfd\xfd\xfd\xfd\xfd\xfd\xfe\xfe\xfe\xfe\xfe\xfe\xfd\xfd\xfd\xfd\xfd\xfd\xfe\xfe\xfe\xfe\xfe\xfe\xfd\xfd\xfd\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfd\xfd\xfd\xfe\xfe\xfe\xfe\xfe\xfe\xfd\xfd\xfd\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfd\xfd\xfd\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfd\xfd\xfd\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfd\xfd\xfd\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfd\xfd\xfd\xfe\xfe\xfe\xfe\xfe\xfe\xfd\xfd\xfd\xfe\xfe\xfe\xfe\xfe\xfe\xfd\xfd\xfd\xfe\xfe\xfe\xfd\xfd\xfd\xfd\xfd\xfd\xfe\xfe\xfe\xfe\xfe\xfe\xfd\xfd\xfd\xfd\xfd\xfd\xfe\xfe\xfe\xfd\xfd\xfd\xfd\xfd\xfd\xfe\xfe\xfe\xfe\xfe\xfe\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfd\xfd\xfd\xfe\xfe\xfe\xfd\xfd\xfd\xfe\xfe\xfe\xfc\xfc\xfc\xff\xff\xff\xd1\xd1\xd1\xcb\xcb\xcb\xb0\xb0\xb0ccclll\xb1\xb1\xb1\xfa\xfa\xfa\xfe\xfe\xfe\xff\xff\xff\xfe\xfe\xfe\xfd\xfd\xfd\xfe\xfe\xfe\xfe\xfe\xfe\xfd\xfd\xfd\xfe\xfe\xfe\xfe\xfe\xfe\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfe\xfe\xfe\xfc\xfc\xfc\xfb\xfb\xfb\xfd\xfd\xfd\xfc\xfc\xfc\xfc\xfc\xfc\xfd\xfd\xfd\xfc\xfc\xfc\xfa\xfa\xfa\xfd\xfd\xfd\xfe\xfe\xfe\xfd\xfd\xfd\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfd\xfd\xfd\xfd\xfd\xfd\xfe\xfe\xfe\xfe\xfe\xfe\xfd\xfd\xfd\xfd\xfd\xfd\xfe\xfe\xfe\xfe\xfe\xfe\xfd\xfd\xfd\xfe\xfe\xfe\xfd\xfd\xfd\xfe\xfe\xfe\xfd\xfd\xfd\xfc\xfc\xfc\xfe\xfe\xfe\xfd\xfd\xfd\xfd\xfd\xfd\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfd\xfd\xfd\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfd\xfd\xfd\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfd\xfd\xfd\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfd\xfd\xfd\xfe\xfe\xfe\xfe\xfe\xfe\xfd\xfd\xfd\xfe\xfe\xfe\xfe\xfe\xfe\xfd\xfd\xfd\xfe\xfe\xfe\xfd\xfd\xfd\xfd\xfd\xfd\xfe\xfe\xfe\xfe\xfe\xfe\xfd\xfd\xfd\xfd\xfd\xfd\xfe\xfe\xfe\xfd\xfd\xfd\xfd\xfd\xfd\xfe\xfe\xfe\xfe\xfe\xfe\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfd\xfd\xfd\xfe\xfe\xfe\xfd\xfd\xfd\xfe\xfe\xfe\xfc\xfc\xfc\xff\xff\xff\xd1\xd1\xd1\xcb\xcb\xcb\xb2\xb2\xb2___hhh\xb2\xb2\xb2\xfb\xfb\xfb\xe8\xe8\xe8\xc9\xc9\xc9\xd7\xd7\xd7\xff\xff\xff\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xff\xff\xff\xff\xff\xff\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xfe\xfe\xff\xff\xff\xfe\xfe\xfe\xff\xff\xff\xfe\xfe\xfe\xfe\xfe\xfe\xff\xff\xff\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xff\xff\xff\xff\xff\xff\xfe\xfe\xfe\xfe\xfe\xfe\xff\xff\xff\xff\xff\xff\xfe\xfe\xfe\xfe\xfe\xfe\xff\xff\xff\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xff\xff\xff\xfe\xfe\xfe\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xfe\xfe\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xfe\xfe\xff\xff\xff\xff\xff\xff\xfe\xfe\xfe\xff\xff\xff\xfe\xfe\xfe\xfe\xfe\xfe\xff\xff\xff\xfe\xfe\xfe\xfe\xfe\xfe\xff\xff\xff\xff\xff\xff\xfe\xfe\xfe\xff\xff\xff\xff\xff\xff\xfe\xfe\xfe\xff\xff\xff\xfe\xfe\xfe\xfe\xfe\xfe\xff\xff\xff\xff\xff\xff\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xff\xff\xff\xfe\xfe\xfe\xfe\xfe\xfe\xfd\xfd\xfd\xfe\xfe\xfe\xff\xff\xff\xfe\xfe\xfe\xff\xff\xff\xff\xff\xff\xfe\xfe\xfe\xff\xff\xff\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfd\xfd\xfd\xff\xff\xff\xd2\xd2\xd2\xcb\xcb\xcb\xa1\xa1\xa1nnnwww\xa3\xa3\xa3\xff\xff\xff\x9f\x9f\x9f\x94\x94\x94\x82\x82\x82\xf9\xf9\xf9\xfe\xfe\xfe\xfd\xfd\xfd\xfd\xfd\xfd\xfe\xfe\xfe\xfe\xfe\xfe\xfd\xfd\xfd\xfd\xfd\xfd\xfb\xfb\xfb\xff\xff\xff\xb0\xb0\xb0\x89\x89\x89\xc3\xc3\xc3\xb4\xb4\xb4\xb9\xb9\xb9\xb2\xb2\xb2\x99\x99\x99ttt\xde\xde\xde\xff\xff\xff\xfc\xfc\xfc\xfe\xfe\xfe\xfd\xfd\xfd\xfe\xfe\xfe\xfd\xfd\xfd\xfd\xfd\xfd\xfe\xfe\xfe\xfe\xfe\xfe\xfd\xfd\xfd\xfd\xfd\xfd\xfe\xfe\xfe\xfe\xfe\xfe\xfd\xfd\xfd\xfe\xfe\xfe\xfd\xfd\xfd\xff\xff\xff\xec\xec\xec\xd1\xd1\xd1\xff\xff\xff\xfd\xfd\xfd\xfe\xfe\xfe\xfd\xfd\xfd\xfe\xfe\xfe\xfe\xfe\xfe\xfd\xfd\xfd\xfe\xfe\xfe\xfd\xfd\xfd\xfe\xfe\xfe\xfd\xfd\xfd\xfd\xfd\xfd\xfe\xfe\xfe\xfe\xfe\xfe\xfd\xfd\xfd\xfe\xfe\xfe\xfe\xfe\xfe\xfd\xfd\xfd\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfd\xfd\xfd\xfe\xfe\xfe\xfe\xfe\xfe\xfd\xfd\xfd\xfe\xfe\xfe\xfd\xfd\xfd\xfd\xfd\xfd\xfe\xfe\xfe\xfe\xfe\xfe\xfd\xfd\xfd\xfd\xfd\xfd\xfe\xfe\xfe\xfd\xfd\xfd\xfe\xfe\xfe\xfe\xfe\xfe\xff\xff\xff\xfd\xfd\xfd\xfd\xfd\xfd\xfe\xfe\xfe\xfd\xfd\xfd\xfe\xfe\xfe\xfe\xfe\xfe\xfd\xfd\xfd\xfe\xfe\xfe\xfd\xfd\xfd\xff\xff\xff\xf1\xf1\xf1\xf0\xf0\xf0\xff\xff\xff\xff\xff\xff\xd2\xd2\xd2\xc7\xc7\xc7\x9c\x9c\x9c\x9f\x9f\x9f\xae\xae\xae\x9c\x9c\x9c\xff\xff\xff\xa7\xa7\xa7\xbc\xbc\xbc\x8c\x8c\x8c\xf3\xf3\xf3\xff\xff\xff\xfe\xfe\xfe\xfe\xfe\xfe\xff\xff\xff\xff\xff\xff\xfe\xfe\xfe\xfe\xfe\xfe\xfd\xfd\xfd\xff\xff\xff\xd0\xd0\xd0\x1c\x1c\x1c\xd6\xd6\xd6\xfe\xfe\xfe\xf3\xf3\xf3\xf4\xf4\xf4\xec\xec\xec\xa8\xa8\xa8\xa9\xa9\xa9\xff\xff\xff\xf2\xf2\xf2\xf5\xf5\xf5\xff\xff\xff\xfc\xfc\xfc\xfe\xfe\xfe\xfe\xfe\xfe\xfd\xfd\xfd\xfe\xfe\xfe\xff\xff\xff\xff\xff\xff\xfe\xfe\xfe\xfd\xfd\xfd\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xda\xda\xda\xc4\xc4\xc4\xf6\xf6\xf6\xff\xff\xff\xfe\xfe\xfe\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xfe\xfe\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xfe\xfe\xff\xff\xff\xff\xff\xff\xfe\xfe\xfe\xff\xff\xff\xfb\xfb\xfb\xf8\xf8\xf8\xff\xff\xff\xfd\xfd\xfd\xfe\xfe\xfe\xfe\xfe\xfe\xff\xff\xff\xff\xff\xff\xfe\xfe\xfe\xfd\xfd\xfd\xfe\xfe\xfe\xff\xff\xff\xfe\xfe\xfe\xfe\xfe\xfe\xff\xff\xff\xff\xff\xff\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xff\xff\xff\xfd\xfd\xfd\xf6\xf6\xf6\xef\xef\xef\xfa\xfa\xfa\xff\xff\xff\xfe\xfe\xfe\xff\xff\xff\xff\xff\xff\xfe\xfe\xfe\xff\xff\xff\xf1\xf1\xf1\xf8\xf8\xf8\xf3\xf3\xf3\xc3\xc3\xc3\xa3\xa3\xa3\xef\xef\xef\xff\xff\xff\xd2\xd2\xd2\xc9\xc9\xc9\x9f\x9f\x9f\x9b\x9b\x9b\xaa\xaa\xaa\x9d\x9d\x9d\xe3\xe3\xe3\xb3\xb3\xb3\xc2\xc2\xc2\xa3\xa3\xa3\xf0\xf0\xf0\xff\xff\xff\xfd\xfd\xfd\xfd\xfd\xfd\xfe\xfe\xfe\xfe\xfe\xfe\xfd\xfd\xfd\xfe\xfe\xfe\xfe\xfe\xfe\xfa\xfa\xfa\xff\xff\xff\x9c\x9c\x9c777\xff\xff\xff\xff\xff\xff\xfe\xfe\xfe\xfe\xfe\xfe\xff\xff\xff\xf1\xf1\xf1\xfd\xfd\xfd\xbc\xbc\xbc\xf1\xf1\xf1\xff\xff\xff\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xff\xff\xff\xfe\xfe\xfe\xfd\xfd\xfd\xfd\xfd\xfd\xfe\xfe\xfe\xff\xff\xff\xfe\xfe\xfe\xfc\xfc\xfc\xff\xff\xff\xd8\xd8\xd8\x7f\x7f\x7f\xd3\xd3\xd3\xa1\xa1\xa1\xf6\xf6\xf6\xff\xff\xff\xfd\xfd\xfd\xfe\xfe\xfe\xfe\xfe\xfe\xfd\xfd\xfd\xfe\xfe\xfe\xfd\xfd\xfd\xfe\xfe\xfe\xfa\xfa\xfa\xf6\xf6\xf6\xff\xff\xff\xfc\xfc\xfc\xff\xff\xff\xe5\xe5\xe5\x95\x95\x95\xff\xff\xff\xfd\xfd\xfd\xfe\xfe\xfe\xfe\xfe\xfe\xfd\xfd\xfd\xfd\xfd\xfd\xfe\xfe\xfe\xff\xff\xff\xfe\xfe\xfe\xfd\xfd\xfd\xfe\xfe\xfe\xfd\xfd\xfd\xfe\xfe\xfe\xfe\xfe\xfe\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfe\xfe\xfe\x7e\x7e\x7e\xc0\xc0\xc0\xa6\xa6\xa6\xe8\xe8\xe8\xff\xff\xff\xfd\xfd\xfd\xfe\xfe\xfe\xfd\xfd\xfd\xff\xff\xff\xe8\xe8\xe8\xc2\xc2\xc2\xff\xff\xff\xf3\xf3\xf3\xb3\xb3\xb3\xf4\xf4\xf4\xff\xff\xff\xd1\xd1\xd1\xc7\xc7\xc7\x9e\x9e\x9e\x9b\x9b\x9b\xaa\xaa\xaa\x9d\x9d\x9d\xfd\xfd\xfd\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xff\xff\xff\xfe\xfe\xfe\xfe\xfe\xfe\xff\xff\xff\xff\xff\xff\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xff\xff\xff\xfb\xfb\xfb\xff\xff\xffeeejjj\xff\xff\xff\xfc\xfc\xfc\xfd\xfd\xfd\xfa\xfa\xfa\xff\xff\xff\xdd\xdd\xdd\xb0\xb0\xb0\xff\xff\xff\xe9\xe9\xe9\xd5\xd5\xd5\xef\xef\xef\xff\xff\xff\xfa\xfa\xfa\xfe\xfe\xfe\xff\xff\xff\xff\xff\xff\xfd\xfd\xfd\xfa\xfa\xfa\xfc\xfc\xfc\xfc\xfc\xfc\xff\xff\xff\xbe\xbe\xbe\x9b\x9b\x9b\xff\xff\xff\x96\x96\x96\xbb\xbb\xbb\xff\xff\xff\xfc\xfc\xfc\xff\xff\xff\xff\xff\xff\xfe\xfe\xfe\xff\xff\xff\xfe\xfe\xfe\xff\xff\xff\xeb\xeb\xeb\xcc\xcc\xcc\xff\xff\xff\xfb\xfb\xfb\xff\xff\xff\xd3\xd3\xd3\xab\xab\xab\xff\xff\xff\xf8\xf8\xf8\xfc\xfc\xfc\xff\xff\xff\xfe\xfe\xfe\xff\xff\xff\xfc\xfc\xfc\xfa\xfa\xfa\xfd\xfd\xfd\xff\xff\xff\xfe\xfe\xfe\xfe\xfe\xfe\xff\xff\xff\xff\xff\xff\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xff\xff\xff\xf2\xf2\xf2\x7d\x7d\x7d\xff\xff\xff\x89\x89\x89\xd9\xd9\xd9\xff\xff\xff\xfd\xfd\xfd\xff\xff\xff\xfe\xfe\xfe\xfd\xfd\xfd\xff\xff\xff\xb1\xb1\xb1\xef\xef\xef\xa3\xa3\xa3\xa1\xa1\xa1\xfc\xfc\xfc\xff\xff\xff\xd2\xd2\xd2\xc8\xc8\xc8\x9f\x9f\x9f\x9c\x9c\x9c\xab\xab\xab\x9d\x9d\x9d"""
+app = MyApp()
+app.MainLoop()
+
+++ /dev/null
-#!/usr/bin/env python
-# -*- coding: ISO-8859-15 -*-
-#
-# pdf2swf.py
-# graphical user interface for pdf2swf
-#
-# Part of the swftools package.
-#
-# Copyright (c) 2008,2009 Matthias Kramm <kramm@quiss.org>
-#
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
-
-
-import sys
-import wx
-import os
-sys.path+=["../lib/python"]
-import gfx
-import images
-import stat
-
-basedir = os.getcwd()
-
-gfx.verbose(3)
-
-#try:
-# gfx.setparameter("wxwindowparams", "1")
-#except:
-# gfx.setoption("wxwindowparams", "1")
-
-class StaticData:
- def __init__(self):
- self.simpleviewer_bitmap = wx.BitmapFromImage(wx.ImageFromData(images.simpleviewer_width,images.simpleviewer_height,images.simpleviewer_data))
- self.raw_bitmap = wx.BitmapFromImage(wx.ImageFromData(images.raw_width,images.raw_height,images.raw_data))
- self.motionpaper_bitmap = wx.BitmapFromImage(wx.ImageFromData(images.motionpaper_width,images.motionpaper_height,images.motionpaper_data))
- self.rfxview_bitmap = wx.BitmapFromImage(wx.ImageFromData(images.rfxview_width,images.rfxview_height,images.rfxview_data))
-staticdata = None
-
-HTMLTEMPLATE = """<html>
-<body style="padding: 0px; margin: 0px">
-<object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"
- width="%(width)s"
- height="%(height)s"
- codebase="http://active.macromedia.com/flash5/cabs/swflash.cab#version=%(version)d,0,0,0">
- <param name="MOVIE" value="%(swffilename)s">
- <param name="PLAY" value="true">
- <param name="LOOP" value="true">
- <param name="QUALITY" value="high">
- <param name="FLASHVARS" value="%(flashvars)s">
- <embed src="%(swffilename)s" width="%(width)s" height="%(height)s"
- play="true" ALIGN="" loop="true" quality="high"
- type="application/x-shockwave-flash"
- flashvars="%(flashvars)s"
- pluginspage="http://www.macromedia.com/go/getflashplayer">
- </embed>
-</object>
-</body>
-</html>
-"""
-
-def error(msg):
- dlg = wx.MessageDialog(None, msg, "Error", style=wx.OK, pos=wx.DefaultPosition)
- dlg.ShowModal()
- dlg.Destroy()
-
-def savefilestatus(msg):
- dlg = wx.MessageDialog(None, msg, "Save file status", style=wx.OK, pos=wx.DefaultPosition)
- dlg.ShowModal()
- dlg.Destroy()
-
-def swfcombine(params):
- exe = "swfcombine"
- if os.path.sep == '/':
- locations = [os.path.join(basedir, "swfcombine"),
- "/usr/local/bin/swfcombine",
- "/usr/bin/swfcombine"
- ]
- else:
- locations = [os.path.join(basedir, "swfcombine.exe"),
- "c:\\swftools\\swfcombine.exe"]
- params = ['"'+p+'"' for p in params]
-
- for e in locations:
- if os.path.isfile(e):
- exe = e
- break
-
- if hasattr(os,"spawnv"):
- print "spawnv",exe,params
- ret = -1
- try:
- ret = os.spawnv(os.P_WAIT, exe, ["swfcombine"]+params)
- except:
- ret = -1
- if not ret:
- return
-
- cmd = '"' + exe + '"' + " " + (" ".join(params))
- print "system",cmd
- ret = os.system(cmd)
- if ret&0xff00:
- error("Couldn't execute swfcombine.exe- error code "+str(ret))
-
-ICON_SIZE = 64
-
-EVENT_PAGE_CHANGE = 1
-EVENT_FILE_CHANGE = 2
-EVENT_STATUS_TEXT = 4
-
-class ProgressFrame(wx.Dialog):
- def __init__(self, parent, message=""):
- wx.Dialog.__init__(self, parent, -1, "Progress", size=(350, 150))
- panel = wx.Panel(self, -1)
- self.count = 0
-
- self.msg = wx.StaticText(panel, -1, message, (20,25))
- self.gauge = wx.Gauge(panel, -1, 100, (20, 50), (250, 25))
-
- self.gauge.SetBezelFace(3)
- self.gauge.SetShadowWidth(3)
-
- self.Bind(wx.EVT_WINDOW_DESTROY, self.close, id=wx.ID_CLOSE)
-
- def setProgress(self, num):
- self.gauge.SetValue(int(num))
-
- def close(self, event):
- print "close"
-
-
-def swapextension(filename,newext):
- basename,ext = os.path.splitext(filename)
- return basename + "." + newext
-
-def has_different_size_pages(doc):
- width,height = 0,0
- for i in range(1,doc.pages+1):
- page = doc.getPage(i)
- if i==1:
- width,height = page.width,page.height
- else:
- if abs(width-page.width)>2 or \
- abs(height-page.height)>2:
- return 1
- return 0
-
-
-options = []
-gfx_options = {}
-
-class Option:
- def __init__(self, parameter, text, options, default, mapping=None):
- self.parameter = parameter
- self.text = text
- self.options = options
- self.default = default
- self.mapping = mapping
- self.control = None
- self.enabled = 1
- self.register()
-
- def generateControl(self, panel):
- if type(self.options) == type((0,)):
- control = wx.Choice(panel, -1, choices=self.options)
- control.SetSelection(self.default)
- elif self.options == "slider":
- control = wx.Slider(panel, -1, self.default, 0, 100, size=(100, -1), style=wx.SL_HORIZONTAL|wx.SL_LABELS|wx.SL_TOP)
- elif self.options == "spinner":
- control = wx.SpinCtrl(panel, -1, str(self.default))
- else:
- control = wx.Choice(panel, -1, choices=["broken"])
- control.SetSelection(0)
-
- self.control = control
- return self.control
-
- def getSettings(self):
- value = ""
- if type(self.options) == type((0,)):
- value = self.options[self.control.GetCurrentSelection()]
- if self.mapping and value in self.mapping:
- value = str(self.mapping[value])
- if value == "yes":
- value = "1"
- elif value == "no":
- value = "0"
- return {self.parameter:value}
- elif self.options == "slider" or self.options == "spinner":
- value = str(self.control.GetValue())
- return {self.parameter:value}
-
- def register(self):
- global options
- options += [self]
-
-class Option2(Option):
-
- def __init__(self, parameter, text, options, default, mapping=None):
- Option.__init__(self, parameter, text, options, default, mapping)
- self.enabled = 0
-
- def generateControl(self, panel):
- p = wx.Panel(panel, -1)
- #p.SetOwnBackgroundColour('#ff0000')
- h = wx.BoxSizer(wx.HORIZONTAL)
- control = wx.Choice(p, -1, choices=self.options)
- control.SetSelection(self.default)
- text = wx.StaticText(p, -1, self.text)
- h.Add(text,1,wx.EXPAND|wx.ALIGN_LEFT|wx.TOP, 5)
- h.Add(control,1,wx.EXPAND|wx.ALIGN_RIGHT|wx.ALIGN_TOP)
- self.control = control
- if self.enabled:
- control.Enable()
- else:
- control.Disable()
- p.SetSizer(h)
- p.Fit()
- return p
-
- def Disable(self):
- self.enabled=0
- if self.control:
- self.control.Disable()
-
- def Enable(self):
- self.enabled=1
- if self.control:
- self.control.Enable()
-
- def getSettings(self):
- if not self.enabled:
- return {}
- return Option.getSettings(self)
-
-class ChooseAndText(Option):
- def __init__(self, parameter, text, options, default, editselection, textvalue=""):
- Option.__init__(self, parameter, text, options, default)
- self.editselection = editselection
- self.selection = default
- self.textvalue = textvalue
- self.enabled = 0
- self.choice = None
-
- def generateControl(self, panel):
- p = wx.Panel(panel, -1)
- h = wx.BoxSizer(wx.HORIZONTAL)
- control = wx.Choice(p, -1, choices=self.options)
- p.Bind(wx.EVT_CHOICE, self.OnChoice, control)
- control.SetSelection(self.default)
- text = wx.StaticText(p, -1, self.text)
- if self.selection == self.editselection:
- edittext = wx.TextCtrl(p, -1, self.textvalue)
- self.textvalue = ""
- else:
- edittext = wx.TextCtrl(p, -1, "")
- edittext.Disable()
- p.Bind(wx.EVT_TEXT, self.OnText, edittext)
- h.Add(text,1,wx.EXPAND|wx.ALIGN_LEFT|wx.TOP, 5)
- h.Add(control,1,wx.EXPAND|wx.ALIGN_RIGHT)
- h.Add(edittext,1,wx.EXPAND|wx.ALIGN_RIGHT)
- self.choice = control
- self.edittext = edittext
- if self.enabled:
- control.Enable()
- else:
- control.Disable()
- p.SetSizer(h)
- p.Fit()
- return p
-
- def OnText(self, event):
- text = self.edittext.GetValue()
- text2 = "".join(c for c in text if c.isdigit())
- if text2!=text:
- self.edittext.SetValue(text2)
-
- def OnChoice(self, event):
- self.selection = self.choice.GetCurrentSelection()
- if self.selection != self.editselection:
- if not self.textvalue and self.edittext.GetValue():
- self.textvalue = self.edittext.GetValue()
- self.edittext.SetValue("")
- self.edittext.Disable()
- else:
- if self.textvalue and not self.edittext.GetValue():
- self.edittext.SetValue(self.textvalue)
- self.textvalue = ""
- self.edittext.Enable()
-
- def Disable(self):
- self.enabled=0
- if not self.choice:
- return
- self.choice.Disable()
- self.edittext.Disable()
-
- def Enable(self):
- self.enabled=1
- if not self.choice:
- return
- self.choice.Enable()
- if self.choice.GetCurrentSelection() == self.editselection:
- if self.textvalue and not self.edittext.GetValue():
- self.edittext.SetValue(self.textvalue)
- self.textvalue = ""
- self.edittext.Enable()
- else:
- self.edittext.Disable()
-
- def getSettings(self):
- if not self.enabled:
- return {}
- if self.choice.GetCurrentSelection() != self.editselection:
- value = self.options[self.choice.GetCurrentSelection()]
- else:
- value = self.edittext.GetValue().strip()
- return {self.parameter:value}
-
-class TextOption:
- def __init__(self, parameter, label, default=""):
- self.parameter = parameter
- self.label = label
- self.default = default
- self.register()
-
- def generateControl(self, panel):
- v = wx.BoxSizer(wx.VERTICAL)
- self.control = wx.TextCtrl(panel, -1, self.default, size=(250, -1))
- self.control.Fit()
- return self.control
-
- def getSettings(self):
- settings = {}
- for items in self.control.GetValue().split(" "):
- if "=" in items:
- l = items.split("=")
- if len(l) == 2:
- settings[l[0]] = l[1]
- return settings
-
- def register(self):
- global options
- options += [self]
-
-class RadioOption(Option):
- def __init__(self, text, options):
- self.text = text
- self.options = options
- self.selected = "==nothing=="
- self.radios = []
- self.register()
-
- def generateControl(self, panel):
- control = wx.Panel(panel, -1)
- vsplit = wx.BoxSizer(wx.VERTICAL)
- for i in range(len(self.options)/2):
- text = self.options[i*2]
- if i == 0:
- c = wx.RadioButton(control, -1, text, style=wx.RB_GROUP)
- else:
- c = wx.RadioButton(control, -1, text)
- control.Bind(wx.EVT_RADIOBUTTON, self.OnRadio, c)
- self.radios += [c]
- vsplit.Add(c)
- control.SetSizer(vsplit)
- control.Fit()
- self.control = control
- return control
-
- def OnRadio(self, event):
- self.selected = event.GetEventObject().GetLabel()
-
- def getSettings(self):
- for i in range(len(self.options)/2):
- if self.options[i*2] == self.selected:
- return self.options[i*2+1]
- return self.options[1]
-
-class BitmapWindow(wx.Window):
- def __init__(self, parent, image):
- wx.Window.__init__(self, parent, -1)
- self.image = image
- self.SetMinSize((image.GetWidth()+2, image.GetHeight()+2))
- self.SetMaxSize((image.GetWidth()+2, image.GetHeight()+2))
- self.SetSize((image.GetWidth()+2, image.GetHeight()+2))
- self.Bind(wx.EVT_PAINT, self.OnPaint)
- self.Update()
- def OnPaint(self, event):
- dc = wx.PaintDC(self)
- self.Draw(dc)
- def Draw(self,dc=None):
- if not dc:
- dc = wx.ClientDC(self)
- dc.DrawRectangleRect((0, 0, self.image.GetWidth()+2, self.image.GetHeight()+2))
- dc.DrawBitmap(self.image, 1, 1, False)
-
-class ImageRadioOption(Option):
- def __init__(self, text, options):
- self.text = text
- self.options = options
- self.selected = "==nothing=="
- self.radios = []
- self.register()
- self.ids = []
-
- def generateControl(self, panel):
- control = wx.Panel(panel, -1)
- vsplit = wx.BoxSizer(wx.VERTICAL)
- first = 1
- for image,text,params,selected,extraoptions in self.options:
- hsplit = wx.BoxSizer(wx.HORIZONTAL)
-
- v = wx.BoxSizer(wx.VERTICAL)
-
- name,text = text.split("- ")
-
- c = wx.CheckBox(control, -1, name)
- control.Bind(wx.EVT_CHECKBOX, self.OnRadio, c)
-
- # radio buttons crash windows when clicked on- even without event bindings.
- # This is caused by the subpanel which is created for extra options
- # (I tried this with a empty Panel(), and even that crashed)
- #if first:
- # c = wx.RadioButton(control, -1, name, style=wx.RB_GROUP)
- #else:
- # c = wx.RadioButton(control, -1, name)
- #control.Bind(wx.EVT_RADIOBUTTON, self.OnRadio, c)
-
- self.ids += [c.GetId()]
-
- first = 0
-
- if "disable" in text:
- c.Enable(False)
- if selected:
- self.selected = c.GetId()
- c.SetValue(True)
- else:
- c.SetValue(False)
- self.radios += [c]
-
- bitmap = BitmapWindow(control, image)
- t = wx.StaticText(control, -1, text, size=(400,50))
-
- v.Add(c, 0, wx.EXPAND)
- v.Add(t, 0, wx.EXPAND|wx.LEFT, 20)
-
- for o in extraoptions:
- cx = o.generateControl(control)
- if selected:
- o.Enable()
- else:
- o.Disable()
- v.Add(cx, 0, wx.EXPAND|wx.LEFT, 20)
-
- v.SetMinSize((330,170))
-
- hsplit.Add(bitmap, 0, wx.LEFT|wx.RIGHT|wx.BOTTOM|wx.ALIGN_TOP, 5)
- hsplit.Add(v, 0, wx.EXPAND)
- vsplit.Add(hsplit, 0, wx.EXPAND)
-
- control.SetSizer(vsplit)
- control.Fit()
- self.control = control
- return vsplit
-
- def OnRadio(self, event):
- self.selected = event.GetEventObject().GetId()
- for c in self.radios:
- if c.GetId() == self.selected:
- c.SetValue(1)
- else:
- c.SetValue(0)
- i = 0
- for image,text,params,selected,extraoptions in self.options:
- if self.ids[i] == self.selected:
- for xo in extraoptions:
- xo.Enable()
- pass
- else:
- for xo in extraoptions:
- xo.Disable()
- pass
- i = i + 1
- event.ResumePropagation(0)
-
- def getSettings(self):
- i = 0
- for image,text,params,s,extraoptions in self.options:
- id = self.ids[i]
- i = i + 1
- if id == self.selected:
- return params
- return {}
-
-
-class OptionFrame(wx.Dialog):
-
- def __init__(self, parent):
- wx.Dialog.__init__(self, parent, -1, "Options")
-
- #self.nb = wx.Notebook(self, -1)#, wx.Point(0,0), wx.Size(0,0), wxNB_FIXEDWIDTH)
- self.nb = wx.Notebook(self, -1)
-
- self.needreload = 0
-
- options0 = [RadioOption('Rendering mode',
- ["Convert polygons to polygons and fonts to fonts", {},
- "Convert fonts to fonts, everything else to bitmaps", {"poly2bitmap":"1"},
- "Convert everthing to bitmaps", {"poly2bitmap":"1", "bitmapfonts":"1"}
- ])]
-
- mp_options = []
- sv_options = [Option2('flashversion', 'Flash version:', ('4','5','6','7','8'), 2),
- Option2('transparent', 'Make SWF file transparent:', ('no','yes'), 0),
- ]
-
- raw_options = [Option2('flashversion', 'Flash version:', ('4','5','6','7','8','9'), 2),
- Option2('insertstop', 'Insert stop after each frame:', ('no','yes'), 0),
- Option2('transparent', 'Make SWF file transparent:', ('no','yes'), 0),
- ]
- rfxview_options = [ChooseAndText('rfxwidth', 'Width:', ('same as PDF','fullscreen','custom'),1,2,"600"),
- ChooseAndText('rfxheight', 'Height:', ('same as PDF','fullscreen','custom'),1,2,"800"),
- Option2('rfxzoomtype', 'Initial zoom level:', ('Original resolution','Show all','Maximum width/height'),2),
- ]
-
- options4 = [ImageRadioOption('Select Paging GUI',
- [(staticdata.raw_bitmap, "No Viewer- The SWF will be in \"raw\" format, with each page a seperate frame. Use this if you want to add a viewer yourself afterwards.", {}, 0, raw_options),
- (staticdata.simpleviewer_bitmap, "SimpleViewer- A tiny viewer, which attaches directly to the SWF, and provides small previous/next buttons in the upper left corner", {"simpleviewer":"1", "insertstop":"1"}, 0, sv_options),
- (staticdata.rfxview_bitmap, "rfxView- A more sophisticated viewer with zooming and scrolling.", {"rfxview":"1", "flashversion":"8"}, 1, rfxview_options),
- #(staticdata.motionpaper_bitmap, "MotionPaper- A highly sophisticated viewer with page flipping. (disabled in this evaluation version)", {}, 0, mp_options),
- #(staticdata.motionpaper_bitmap, "Your advertisement here- Are you are company who developed a viewer for pdf2swf, or who offers commercial PDF hosting service? Place your advertisement or demo viewer here, or allow pdf2swf to upload SWFs directly to your site! contact sales@swftools.org for details.", {}, 0, mp_options),
- ])]
-
- options1 = [Option('zoom', 'Resolution (in dpi):', "spinner", 72),
- Option('fontquality', 'Font quality:', "slider", 20),
- Option('storeallcharacters', 'Insert full fonts in SWF file:', ('no','yes'), 0),
- Option('splinequality', 'Polygon quality:', "slider", 100),
- Option('jpegquality', 'JPEG quality:', "slider", 75),
- Option('jpegsubpixels', 'JPEG image resolution:', ('same as in PDF', '1x', '2x', '4x'), 0, {"same as in PDF": 0, "1x": 1, "2x": 2, "3x": 3}),
- Option('ppmsubpixels', 'non-JPEG image resolution:', ('same as in PDF', '1x', '2x', '4x'), 0, {"same as in PDF": 0, "1x": 1, "2x": 2, "3x": 3}),
- ]
-
-
- options3 = [TextOption('_additional_', 'Additional options')]
-
- panel1 = [('Rendering options', options0,''),
- ('Quality',options1,'v')]
- panel3 = [('Select paging GUI', options4,'')]
- panel4 = [('Additional options', options3,'')]
-
- panels = [('Quality', panel1),
- ('Viewer', panel3),
- ('Advanced', panel4)]
-
- for name,poptions in panels:
- panel = wx.Panel(self.nb, -1)
- self.nb.AddPage(panel, name)
-
- vsplit = wx.BoxSizer(wx.VERTICAL)
-
- for name,options,align in poptions:
- optiongroup = wx.StaticBox(panel, -1, name)
- optiongroupsizer= wx.StaticBoxSizer(optiongroup, wx.VERTICAL)
- optiongroup.SetSizer(optiongroupsizer)
-
- if align == 'v':
- grid = wx.GridSizer(rows=len(options), cols=2, hgap=3, vgap=3)
- optiongroupsizer.Add(grid, 1, wx.EXPAND, 0)
- else:
- grid = wx.GridSizer(rows=len(options), cols=1, hgap=3, vgap=3)
- optiongroupsizer.Add(grid, 1, wx.EXPAND, 0)
-
- for option in options:
- if align=='v':
- t = wx.StaticText(panel, -1, option.text)
- grid.Add(t, 0, wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_LEFT)
- optionbox = option.generateControl(panel)
- grid.Add(optionbox, 0, wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_LEFT)
-
- vsplit.Add(optiongroupsizer, 0, wx.EXPAND, 0)
-
- #hs = wx.BoxSizer(wx.HORIZONTAL)
- #hs.Add(gobutton, 0, wx.ALIGN_CENTER, 0)
- gobutton = wx.Button(panel, -1, "Apply")
- self.Bind(wx.EVT_BUTTON, self.Apply, gobutton)
-
- vsplit.Add(gobutton, 0, wx.ALIGN_CENTER|wx.ALL, 0)
-
- panel.SetSizer(vsplit)
- panel.Fit()
-
- self.nb.Fit()
-
- self.Fit()
-
-
- def updateOptions(self):
- global options,gfx_options
- a = []
-
- # FIXME: we clear *our* options- but gfx will still have
- # stored the old ones. Critical for options in the "imageradio" section.
- gfx_options.clear()
- i = 0
- print "----- options ------"
- for option in options:
- for k,v in option.getSettings().items():
- gfx_options[k] = v
- gfx.setparameter(k,v)
- print k,v
- i = i + 1
-
- # TODO: filter out "global" options, and do this only if
- # pdf layer is affected
-
- def Apply(self, event):
- self.updateOptions()
- self.Hide()
- self.needreload = 1
-
-
-class State:
- def __init__(self):
- self.pdf = None
- self.page = None
- self.pagenr = 1
- self.pagebitmap = None
- self.bitmap_width = 0
- self.bitmap_height = 0
- self.bitmap_page = 0
- self.filename = None
- self.status_text = None
- self.lastsavefile = "output.swf"
- self.lasthtmlfile = "index.html"
-
- self.listeners = []
-
- def onEvent(self,event_type, function):
- self.listeners += [(event_type,function)]
- def loadPDF(self,filename):
- self.filename = filename
- self.lastsavefile = swapextension(filename,"swf")
- self.lasthtmlfile = swapextension(filename,"html")
-
- self.pdf = gfx.open("pdf",filename)
- if(has_different_size_pages(self.pdf)):
- # just let the user know- for now, we can't handle this properly
- dlg = wx.MessageDialog(app.frame, """In this PDF, width or height are not the same for each page. This might cause problems if you export pages of different dimensions into the same SWF file.""", "Notice", style=wx.OK, pos=wx.DefaultPosition)
- dlg.ShowModal()
- dlg.Destroy()
-
- self.changePage(1)
-
- for type,f in self.listeners:
- if type&EVENT_PAGE_CHANGE or type&EVENT_FILE_CHANGE:
- f()
- self.setStatus("File loaded successfully.")
-
- def saveSWF(self, filename, progress, pages=None, html=0):
- if html:
- basename,ext = os.path.splitext(filename)
- if not ext:
- html = basename + ".html"
- filename = basename + ".swf"
- elif ext.lower() != ".swf":
- html = filename
- filename = basename + ".swf"
- else:
- html = basename + ".html"
- filename = filename
-
- steps = 100.0 / (self.pdf.pages*2 + 3)
- pos = [0]
-
- self.lastsavefile = filename
- if html:
- self.lasthtmlfile = html
-
- swf = gfx.SWF()
- for k,v in gfx_options.items():
- swf.setparameter(k,v)
- if pages is None:
- pages = range(1,self.pdf.pages+1)
- pdfwidth,pdfheight=0,0
- for pagenr in pages:
- page = self.pdf.getPage(pagenr)
- pdfwidth = page.width
- pdfheight = page.height
- swf.startpage(page.width, page.height)
- page.render(swf)
- swf.endpage()
- swf.save(filename)
- if not os.path.isfile(filename):
- error("Couldn't create file "+filename)
-
- if gfx_options.get("rfxview",None):
- rfxview = os.path.join(basedir, "rfxview.swf")
- if not os.path.isfile(rfxview):
- error("File rfxview.swf not found in working directory")
- else:
- size1 = os.stat(filename)[stat.ST_SIZE]
- swfcombine([rfxview,"viewport="+filename,"-o",filename])
- size2 = os.stat(filename)[stat.ST_SIZE]
- if size1 == size2:
- error("Couldn't add viewer to file "+filename)
-
- if html:
- version = int(gfx_options.get("flashversion", "8"))
- swf = gfx.open("swf", filename)
- page1 = swf.getPage(1)
-
- width,height = str(page1.width),str(page1.height)
-
-
- w = gfx_options.get("rfxwidth","")
- if w == "fullscreen": width = "100%"
- elif w == "same as PDF": width = pdfwidth+40
- elif w.isdigit(): width = w
- else: width = pdfwidth
-
- h = gfx_options.get("rfxheight","")
- if h == "fullscreen": height = "100%"
- elif h == "same as PDF": height = pdfheight+70
- elif h.isdigit(): height = h
- else: height = pdfwidth
-
- flashvars = ""
- zoomtype = gfx_options.get("rfxzoomtype","")
- if zoomtype=="Original resolution":
- flashvars = "zoomtype=1"
- elif zoomtype=="Show all":
- flashvars = "zoomtype=2"
- elif zoomtype=="Maximum width/height":
- flashvars = "zoomtype=3"
-
- swffilename = os.path.basename(filename)
- fi = open(html, "wb")
- fi.write(HTMLTEMPLATE % locals())
- fi.close()
-
-
- def changePage(self,page):
- self.pagenr = page
- self.page = self.pdf.getPage(self.pagenr)
- for type,f in self.listeners:
- if type&EVENT_PAGE_CHANGE:
- f()
-
- def getPageIcon(self,pagenr):
- page = self.pdf.getPage(pagenr)
- return wx.BitmapFromImage(wx.ImageFromData(ICON_SIZE,ICON_SIZE,page.asImage(ICON_SIZE,ICON_SIZE)))
- #return wx.BitmapFromImage(wx.ImageFromData(8,8,"0"*(64*3)))
-
- def getPageImage(self, width, height):
- if self.bitmap_width == width and self.bitmap_height == height and self.bitmap_page == self.pagenr:
- return self.pagebitmap
- else:
- self.bitmap_width = width
- self.bitmap_height = height
- self.bitmap_page = self.pagenr
- self.pagebitmap = wx.BitmapFromImage(wx.ImageFromData(width,height,self.page.asImage(width,height)))
- #self.pagebitmap = wx.BitmapFromImage(wx.ImageFromData(8,8,"0"*(64*3)))
- return self.pagebitmap
-
- def setStatus(self,text):
- self.status_text = text
- for type,f in self.listeners:
- if type&EVENT_STATUS_TEXT:
- f()
-
-state = State()
-
-class PageListWidget(wx.ListCtrl):
- def __init__(self,parent):
- wx.ListCtrl.__init__(self,parent,style=wx.LC_ICON|wx.LC_AUTOARRANGE)
- #self.SetMinSize((ICON_SIZE+8,-1))
- #self.SetMaxSize((ICON_SIZE+8,-1))
- #self.SetSize((ICON_SIZE+8,-1))
- self.Bind(wx.EVT_LIST_ITEM_SELECTED, self.SelectItem)
- state.onEvent(EVENT_FILE_CHANGE, self.reload)
- state.onEvent(EVENT_PAGE_CHANGE, self.switchPage)
- self.reload()
- self.dontcare = 0
- #self.Bind(wx.EVT_IDLE, self.OnIdle)
- #print dir(self)
-
- def processFiles(self):
- if self.filepos >= 0 and self.filepos < state.pdf.pages:
- icon = state.getPageIcon(self.filepos+1)
- self.imglist.Add(icon)
- self.InsertImageStringItem(self.filepos, str(self.filepos+1), self.filepos)
- self.filepos = self.filepos + 1
- self.Update()
-
- def OnIdle(self,event):
- self.processFiles()
- event.ResumePropagation(0)
-
- def reload(self):
- self.filepos = -1
- self.DeleteAllItems()
- self.imglist = wx.ImageList(ICON_SIZE,ICON_SIZE,mask=False)
- self.AssignImageList(self.imglist,wx.IMAGE_LIST_NORMAL)
- self.filepos = 0
- while state.pdf and self.filepos < state.pdf.pages:
- self.processFiles()
-
- def switchPage(self):
- if self.dontcare:
- self.dontcare = 0
- return
- for i in range(0,self.GetItemCount()):
- self.Select(i, False)
- self.Select(state.pagenr-1, True)
- self.Focus(state.pagenr-1)
- self.Update()
-
- def SelectItem(self,event):
- self.dontcare = 1 #ignore next change event
- state.changePage(event.GetIndex()+1)
-
-
-helptxt = """
-This is the SWF preview window.
-Here, you will see how the SWF file generated from
-the PDF file will look like. Changing parameters in
-the configuration which affect the appeareance of
-the final SWF will affect this preview, too, so you
-can always evaluate the final output beforehand.
-"""
-
-
-class OnePageWidget(wx.Window):
- def __init__(self,parent):
- wx.Window.__init__(self, parent)
- self.SetSize((160,100))
- self.SetMinSize((160,100))
- self.Fit()
- self.Bind(wx.EVT_PAINT, self.OnPaint)
- self.Bind(wx.EVT_SIZE, self.OnSize)
- self.Bind(wx.EVT_KEY_DOWN, self.key_down)
- state.onEvent(EVENT_PAGE_CHANGE, self.OnPageChange)
-
- def key_down(self, event):
- if state.pdf:
- if event.GetKeyCode() == 312 and state.pagenr>1:
- state.changePage(state.pagenr-1)
- elif event.GetKeyCode() == 313 and state.pagenr<state.pdf.pages:
- state.changePage(state.pagenr+1)
-
- def OnPageChange(self):
- self.Refresh()
-
- def OnSize(self, event):
- self.Refresh()
-
- def Draw(self,dc=None):
- global bitmap
- if not dc:
- dc = wx.ClientDC(self)
- posx = 0
- posy = 0
- window_width,window_height = self.GetSize()
- dc.Clear()
-
- if not state.pdf or not state.page:
- return
-
- if state.page.width * window_height > state.page.height * window_width:
- width = window_width
- height = window_width * state.page.height / state.page.width
- posy = (window_height - height) / 2
- else:
- width = window_height * state.page.width / state.page.height
- height = window_height
- posx = (window_width - width) / 2
-
- dc.DrawBitmap(state.getPageImage(width,height), posx,posy, False)
- #state.getPageImage(
-
- def OnPaint(self, event):
- dc = wx.PaintDC(self)
- self.Draw(dc)
-
-class Pdf2swfFrame(wx.Frame):
- #def __init__(self):
- #wx.Window.__init__(self, None, id=-1, pos=wx.DefaultPosition, size=wx.DefaultSize)
- def __init__(self,application):
- wx.Frame.__init__(self, None, -1, style = wx.DEFAULT_FRAME_STYLE)
- self.application = application
-
- self.SetTitle("pdf2swf")
- self.createMenu()
- self.createToolbar()
- self.createStatusBar()
- self.createMainFrame()
-
- self.SetSize((800,600))
-
- self.options = OptionFrame(None)
- self.options.Show(False)
- self.options.updateOptions()
-
- state.onEvent(EVENT_STATUS_TEXT, self.status_change)
- self.html = 0
-
- #self.table = wx.AcceleratorTable([(wx.ACCEL_ALT, ord('X'), 333),])
- #self.SetAcceleratorTable(self.table)
-
- self.Bind(wx.EVT_IDLE, self.OnIdle)
- self.Bind(wx.EVT_CLOSE, self.menu_exit)
- return
-
- def menu_open(self,event):
- global state
- if state.filename:
- dlg = wx.FileDialog(self, "Choose PDF File:", style = wx.DD_DEFAULT_STYLE, defaultFile = state.filename, wildcard = "PDF files (*.pdf)|*.pdf|all files (*.*)|*.*")
- else:
- dlg = wx.FileDialog(self, "Choose PDF File:", style = wx.DD_DEFAULT_STYLE, wildcard = "PDF files (*.pdf)|*.pdf|all files (*.*)|*.*")
-
- if dlg.ShowModal() == wx.ID_OK:
- self.filename = dlg.GetFilename()
- state.loadPDF(self.filename)
-
- def menu_save(self,event,pages=None):
- html,self.html = self.html,0
- global state
- if not state.pdf:
- return
- print "html",html
- if not html:
- defaultFile = state.lastsavefile
- else:
- defaultFile = state.lasthtmlfile
- dlg = wx.FileDialog(self, "Choose Save Filename:", style = wx.SAVE | wx.OVERWRITE_PROMPT, defaultFile = defaultFile, wildcard = "all files (*.*)|*.*|SWF files (*.swf)|*.swf|HTML template (*.html)|*.html")
-
- if dlg.ShowModal() == wx.ID_OK:
- filename = os.path.join(dlg.GetDirectory(),dlg.GetFilename())
-
- #progress = ProgressFrame(self, "Saving %s File '%s'..." % (html and "HTML" or "SWF", filename))
- #progress.Show(True)
- progress = None
- state.saveSWF(filename, progress, pages, html)
- #progress.Destroy()
-
- def menu_save_selected(self,event):
- if not state.pdf:
- return
- p = []
- for i in range(0,self.pagelist.GetItemCount()):
- if self.pagelist.IsSelected(i):
- p += [i+1]
- self.menu_save(event, pages=p)
-
- def menu_save_html(self,event):
- self.html = 1
- return self.menu_save(event)
-
- def menu_save_selected_html(self,event):
- self.html = 1
- return self.menu_save_selected(event)
-
- def menu_exit(self,event):
- self.application.Exit()
-
- def menu_selectall(self,event):
- for i in range(0,self.pagelist.GetItemCount()):
- self.pagelist.Select(i, True)
- def menu_options(self,event):
- self.options.Show(True)
-
- def status_change(self):
- self.statusbar.SetStatusText(state.status_text)
-
- def OnIdle(self,event):
- if self.options.needreload:
- self.options.needreload = 0
- if state.pdf:
- # reload
- state.loadPDF(state.filename)
-
- def createMenu(self):
- menubar = wx.MenuBar()
-
- menu = wx.Menu();menubar.Append(menu, "&File")
- menu.Append(wx.ID_OPEN, "Open PDF\tCTRL-O");self.Bind(wx.EVT_MENU, self.menu_open, id=wx.ID_OPEN)
- menu.AppendSeparator()
- menu.Append(wx.ID_SAVE, "Save SWF (all pages)\tCTRL-W");self.Bind(wx.EVT_MENU, self.menu_save, id=wx.ID_SAVE)
- menu.Append(wx.ID_SAVEAS, "Save SWF (selected pages)\tCTRL-S");self.Bind(wx.EVT_MENU, self.menu_save_selected, id=wx.ID_SAVEAS)
- menu.AppendSeparator()
- menu.Append(2001, "Save HTML template (all pages)\tCTRL-H");self.Bind(wx.EVT_MENU, self.menu_save_html, id=2001)
- menu.Append(2002, "Save HTML template (selected pages)");self.Bind(wx.EVT_MENU, self.menu_save_selected_html, id=2002)
- menu.AppendSeparator()
- menu.Append(wx.ID_EXIT, "Exit\tCTRL-Q");self.Bind(wx.EVT_MENU, self.menu_exit, id=wx.ID_EXIT)
-
- menu = wx.Menu();menubar.Append(menu, "&Edit")
- menu.Append(wx.ID_SELECTALL, "Select All\tCTRL-A");self.Bind(wx.EVT_MENU, self.menu_selectall, id=wx.ID_SELECTALL)
- menu.AppendSeparator()
- menu.Append(wx.ID_PREFERENCES, "Options\tCTRL-R");self.Bind(wx.EVT_MENU, self.menu_options, id=wx.ID_PREFERENCES)
-
- menu = wx.Menu();menubar.Append(menu, "&Help")
-
- self.SetMenuBar(menubar)
-
-
- def createToolbar(self):
-
- tsize = (16,16)
- self.toolbar = self.CreateToolBar(wx.TB_HORIZONTAL | wx.NO_BORDER | wx.TB_FLAT)
-
- self.toolbar.AddSimpleTool(wx.ID_OPEN,
- wx.ArtProvider.GetBitmap(wx.ART_FILE_OPEN, wx.ART_TOOLBAR, tsize),
- "Open")
- self.toolbar.AddSimpleTool(wx.ID_SAVE,
- wx.ArtProvider.GetBitmap(wx.ART_FILE_SAVE, wx.ART_TOOLBAR, tsize),
- "Save selected pages")
- self.toolbar.AddSimpleTool(wx.ID_PREFERENCES,
- wx.ArtProvider.GetBitmap(wx.ART_LIST_VIEW, wx.ART_TOOLBAR, tsize),
- "Options")
- #self.toolbar.AddSeparator()
- self.toolbar.Realize()
-
- def createStatusBar(self):
- self.statusbar = self.CreateStatusBar(1)
-
- def createMainFrame(self):
-
- if 0:
- self.pagelist = PageListWidget(self)
- self.onepage = OnePageWidget(self)
- hsplit = wx.BoxSizer(wx.HORIZONTAL)
- pagelistbox = wx.StaticBox(self, -1, "Pages")
- pagelistboxsizer= wx.StaticBoxSizer(pagelistbox, wx.VERTICAL)
- pagelistboxsizer.Add(self.pagelist, proportion=1, flag=wx.EXPAND)
- onepagebox = wx.StaticBox(self, -1, "Page 1")
- onepageboxsizer= wx.StaticBoxSizer(onepagebox, wx.VERTICAL)
- onepageboxsizer.Add(self.onepage, proportion=1, flag=wx.EXPAND)
- hsplit.Add(pagelistboxsizer, 0, wx.EXPAND, 0)
- hsplit.Add(onepageboxsizer, 1, wx.EXPAND, 0)
- self.SetAutoLayout(True)
- self.SetSizer(hsplit)
- hsplit.Fit(self)
- hsplit.SetSizeHints(self)
- else:
- hsplit = wx.SplitterWindow(self, style=wx.SP_3D|wx.SP_LIVE_UPDATE)
- #p1 = wx.Panel(hsplit,-1, style=wx.SUNKEN_BORDER)
- #p2 = wx.Panel(hsplit,-1, style=wx.SUNKEN_BORDER)
- self.pagelist = PageListWidget(hsplit)
- self.onepage = OnePageWidget(hsplit)
- #hsplit.SplitVertically(p1,p2, sashPosition=64)
- hsplit.SplitVertically(self.pagelist, self.onepage, sashPosition=ICON_SIZE*3/2)
- hsplit.SetMinimumPaneSize(10)
-
-class MyApp(wx.App):
- def __init__(self):
- wx.App.__init__(self, redirect=False, filename=None, useBestVisual=False)
-
- #state.loadPDF("sitis2007.pdf")
- #state.loadPDF("wxPython-Advanced-OSCON2004.pdf")
- global staticdata
- staticdata = StaticData()
-
- self.frame = Pdf2swfFrame(self)
- self.SetTopWindow(self.frame)
- self.frame.Show(True)
-
- #self.frame = TestFrame(self)
- #self.frame.Show(True)
-
- def OnInit(self):
- return True
-
-app = MyApp()
-app.MainLoop()
-
--- /dev/null
+#!/usr/bin/env python
+# -*- coding: UTF-8 -*-
+#
+# gpdf2swf.py
+# graphical user interface for pdf2swf
+#
+# Part of the swftools package.
+#
+# Copyright (c) 2008,2009 Matthias Kramm <kramm@quiss.org>
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+
--- /dev/null
+#!/usr/bin/env python
+# -*- coding: UTF-8 -*-
+#
+# gpdf2swf.py
+# graphical user interface for pdf2swf
+#
+# Part of the swftools package.
+#
+# Copyright (c) 2008,2009 Matthias Kramm <kramm@quiss.org>
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+
+from gui.fields import Choose
+
+order = 0
+type = "core"
+name = u"No Viewer"
+desc = (u'The SWF will be in "raw" format, with each page a seperate frame. '
+ u"Use this if you want to add a viewer yourself afterwards.")
+
+swf_options = [
+ Choose("flashversion", u"Flash version:",
+ (u"4", 4, u"5", 5, u"6", 6, u"7", 7, u"8", 8, u"9", 9), 2),
+ Choose("insertstop", u"Insert stop after each frame:",
+ (u"no", 0, u"yes", 1), 0),
+ Choose("transparent", u"Make SWF file transparent:",
+ (u"no", 0, u"yes", 1), 0),
+ ]
+
+viewer_options = []
+
+from gui.plugin import Plugin
+class Raw(Plugin):
+ def __init__(self, swf, filename):
+ for opt in swf_options:
+ swf.setparameter(opt.name, str(opt.value))
+
+def init(swf, filename):
+ return Raw(swf, filename)
+
+from wx.lib.embeddedimage import PyEmbeddedImage
+preview = PyEmbeddedImage(
+ "iVBORw0KGgoAAAANSUhEUgAAAGYAAABmCAIAAAC2vXM1AAAAAXNSR0IArs4c6QAADGNJREFU"
+ "eNrtXX1MFEcU36/74LwDvByNnIqaFL9ORU2MEUNtE6AVIxWjFuN30ESNTWtiIhpBTVDSNk2j"
+ "Jq3RfvxhNPEPg2kaVFo1ChgNKQo5vURRMIBIICdwX9zt7Gz/eHZc9/aWQ45DcN8fl7nZudmZ"
+ "t++9+b33ZucoSqN3IPFtwhhjjKFAPiOR9GooFBJFsaCgYGyzi4t5j8FgcNOmTTt37kQIMQxD"
+ "URRN0/BgaJom/KUoimEYuCR9eLIaqIQC/DxSA7hKWkZqI72LtDK8K+ntBEFgWbaxsXH37t2x"
+ "ZxnG+OOPP87MzBx78mU2m4dFymiaDgQCgiAghFiWlT1bQRDu3bvX09MjCEJmZqbVagVxE0WR"
+ "YRhBEMhDhkqMMRSgHmPMsizIKZGOuElZX1/fsLAMWAATk7IM7vr8+fOtW7du27YtFArNmzfv"
+ "o48+Ar6wLBsKhfR6vUw9WZaFq+QrQojjuDgrJtwa7AwnNRYy2wEF2dVIhoYsI7L1RCp9oijy"
+ "PL9w4cJDhw5RFNXW1rZz506DwZCbm9vX11dZWWmxWIqLi5OSkn744Qe/39/Z2bl+/fp//vmH"
+ "oqiSkpLk5OSff/65trZ2woQJpaWl48ePVxxwNOOM1D7S3KVzYeJsDoxGY0NDw9dff11eXt7S"
+ "0nLz5s29e/euWLEiJyenrKwsFAqdPn163Lhxf/75544dOwoKCg4cOFBaWmqz2a5evXrnzp0r"
+ "V678+uuvHMedOHEC7GacocVrKQsXY1Ip/VQxXqRA2hOSqUMwGJwxY0ZpaSnHcU+fPs3Kypo6"
+ "dWogEPjxxx9tNpvdbne73R6PZ8mSJbNmzfL5fNnZ2Varddq0aZ2dnRjjQCDwxx9/6PX6GTNm"
+ "yMYmHWSkAUfZOHzu0unEXjFlJLuKEMIYp6SkwDi8Xi/G2O1219fXnzt3rqyszOv1iqLo8/l4"
+ "ng8Gg4FAQBTFQCAQDAYXLlx4/vz5vLy8cePGQW+wMsRNMYdLymQke1BWq3X58uWgUDabLScn"
+ "h6Zpu92+bdu2Y8eOTZ06ddKkSXq9Pjs7m2XZ1NTUTz75hKIoh8PR2dnpcDi2bt1aXl5uNps3"
+ "b96cmpoK62mcpYwOtwgqq4bi0yNXeZ7X6XR5eXkLFiw4duyYIsiAMtwRZqvePzRWbCmTiDiA"
+ "jNra2qysrEFImeLcpDUcx9E0zXEcy7JQiPQwiWiEjzj8FopypCgyKqxXHEkk32NgWxY9RgUr"
+ "oy5lPT09vb29Xq9XUcrIZyRZGCmHyWQyMQyDMVYX+WhZBuixpqZmy5YtixcvJhhdNkkoG43G"
+ "Z8+e7dq1SzaB95llCCGfz1dRUSEV/yGxDLru6ekxGAwXLlyIFAuR4oxRR4WFhX6/32KxqCOE"
+ "aFkGXGBZ1mAwkLVCZtQJpxBCpBJCQ+BqCIIAPib4UhhjMHYkgiTV4nhKGZBOp5P2ELPgD/BL"
+ "2jU4gL/88svdu3cpilq0aNGePXtIe+IbiqIIjiGpkWoi8RnjjOZlZlo2tdiwLBxtgbBcvXq1"
+ "sLAwKyuLZdnm5ma/39/R0bFgwYJbt26JopiTk2OxWDo6OjweT2NjY25urtvtbmxszMnJMRqN"
+ "NE1XVVUFAoEvvvhCr9cDQFUR9gEx12Bx2WDtCTf050NRVFJSUnNzs9VqXbRo0TfffENR1Lp1"
+ "67q6utxu97Nnz65du3bmzJmTJ08+fvx4/vz5v//++7Jly168eOF0Og8ePPjdd995PB6apuvr"
+ "6w8fPhwNUhtZio1bLghCc3Ozy+Xq7u5mWbaoqGjNmjWpqakTJ06cM2dOXV2dz+djGCYvL6+k"
+ "pARj/Omnn544ceLBgwetra0VFRXz5s1zOBw1NTVtbW2w0r/vgewBfcxwtzE8KrJ9+/bFixdD"
+ "5bRp0xBCJ0+eRAh99dVXHMf5fD6TyWS32xFCM2fONJlMwBeSXrDb7cePH7fZbMRzVHcPVQb8"
+ "bj6m4gSH5GOqe44Mw/h8PkEQGIZhGAZwnNVqbW1tvXv3rtfr1el0oijCcsnzPKgeQigtLW31"
+ "6tX19fUGg4G4DZEUc7htWfjUFNF/VBkmmGRlZWVGRoYs7SQIgiiKLpfr1atXUPPo0SOIRiCE"
+ "Ll++fPv2bZfL1d/f39LS0t3djTF+8uSJx+PBGDudTujn2rVrZ8+eraurU8xp4f8pUrpLepWU"
+ "I7WRdiJtv3HjRo/HI8urkZaAnGpqamJm/mfOnElqZs2aRXzDL7/8ktRPmTKFJFOg4HA44IHl"
+ "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"
+ "gg==")
+getpreviewData = preview.GetData
+getpreviewImage = preview.GetImage
+getpreviewBitmap = preview.GetBitmap
+getpreviewIcon = preview.GetIcon
--- /dev/null
+#!/usr/bin/env python
+# -*- coding: UTF-8 -*-
+#
+# gpdf2swf.py
+# graphical user interface for pdf2swf
+#
+# Part of the swftools package.
+#
+# Copyright (c) 2008,2009 Matthias Kramm <kramm@quiss.org>
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+
+from gui.fields import Choose, ChooseAndInt
+
+order = 2
+type = "custom"
+name = u"rfx Viewer"
+desc = u"A more sophisticated viewer with zooming and scrolling."
+
+swf_options = [
+ Choose("flashversion", u"Flash version:",
+ (u"7", 7, u"8", 8), 1),
+]
+
+viewer_options = [
+ Choose("html", u"Save HTML:",
+ (u"no", False, u"yes", True, ), True),
+ ChooseAndInt('width', 'Width:',
+ ('same as PDF', -2, 'fullscreen', -1, 'custom', 0), 1, 2, 600),
+ ChooseAndInt('height', 'Height:',
+ ('same as PDF', -2, 'fullscreen', -1, 'custom', 0), 1, 2, 800),
+ Choose('zoomtype', 'Initial zoom level:',
+ ('Original resolution', 1,
+ 'Show all', 2,
+ 'Maximum width/height', 3), 2),
+]
+
+
+html_template = """<html>
+<body style="padding: 0px; margin: 0px">
+<object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"
+ width="%(width)s"
+ height="%(height)s"
+ codebase="http://active.macromedia.com/flash5/cabs/swflash.cab#version=%(version)d,0,0,0">
+ <param name="MOVIE" value="%(swffilename)s">
+ <param name="PLAY" value="true">
+ <param name="LOOP" value="true">
+ <param name="QUALITY" value="high">
+ <param name="FLASHVARS" value="%(flashvars)s">
+ <embed src="%(swffilename)s" width="%(width)s" height="%(height)s"
+ play="true" ALIGN="" loop="true" quality="high"
+ type="application/x-shockwave-flash"
+ flashvars="%(flashvars)s"
+ pluginspage="http://www.macromedia.com/go/getflashplayer">
+ </embed>
+</object>
+</body>
+</html>
+"""
+
+from gui.plugin import Plugin
+import os
+
+class Rfx(Plugin):
+ def __init__(self, swf, filename):
+ self.__swf = swf
+ self.__filename = filename
+
+ for opt in swf_options:
+ swf.setparameter(opt.name, str(opt.value))
+ setattr(self, "_%s" % opt.name, opt.value)
+
+ for opt in viewer_options:
+ setattr(self, "_%s" % opt.name, opt.value)
+
+ def after_save(self, page):
+ viewerfilename = self._swap_extension(__file__, "swf", self._flashversion)
+
+ self.swfcombine(
+ u"%s" % viewerfilename,
+ u"viewport=%s" % self.__filename,
+ u"-o", u"%s" % self.__filename,
+ )
+
+ if not self._html:
+ return
+
+ if self._width == -1:
+ width = "100%"
+ elif self._width == -2:
+ width = page.width+40
+ else:
+ width = self._width
+
+ if self._height == -1:
+ height = "100%"
+ elif self._height == -2:
+ height = page.height+70
+ else:
+ height = self._height
+
+ template_vars = {
+ 'width': width,
+ 'height': height,
+ 'version': self._flashversion,
+ 'flashvars': "zoomtype=%s" % self._zoomtype,
+ 'swffilename': os.path.basename(self.__filename),
+ }
+
+ htmlfilename = self._swap_extension(self.__filename, "html")
+ f = open(htmlfilename, "wb")
+ f.write(html_template % template_vars)
+ f.close()
+
+
+def init(swf, filename):
+ return Rfx(swf, filename)
+
+from wx.lib.embeddedimage import PyEmbeddedImage
+
+preview = PyEmbeddedImage(
+ "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")
+getpreviewData = preview.GetData
+getpreviewImage = preview.GetImage
+getpreviewBitmap = preview.GetBitmap
+getpreviewIcon = preview.GetIcon
+
--- /dev/null
+#!/usr/bin/env python
+# -*- coding: UTF-8 -*-
+#
+# gpdf2swf.py
+# graphical user interface for pdf2swf
+#
+# Part of the swftools package.
+#
+# Copyright (c) 2008,2009 Matthias Kramm <kramm@quiss.org>
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+
+from gui.fields import Hidden, Choose
+
+order = 1
+type = "core"
+name = u"Simple Viewer"
+desc = (u"A tiny viewer, which attaches directly to the SWF, "
+ u"and provides small previous/next buttons in the upper left corner")
+
+swf_options = [
+ Hidden('simpleviewer', u'1'),
+ Choose('flashversion', u'Flash version:',
+ (u'4', 4, u'5', 5, u'6', 6, u'7', 7, u'8', 8), 2
+ ),
+ Choose('transparent', u'Make SWF file transparent:', (u'no', 0, u'yes', 1), 0),
+ ]
+
+viewer_options = []
+
+from gui.plugin import Plugin
+class Simple(Plugin):
+ def __init__(self, swf, filename):
+
+ for opt in swf_options:
+ swf.setparameter(opt.name, str(opt.value))
+
+
+def init(swf, filename):
+ return Simple(swf, filename)
+
+
+from wx.lib.embeddedimage import PyEmbeddedImage
+preview = PyEmbeddedImage(
+ "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")
+getpreviewData = preview.GetData
+getpreviewImage = preview.GetImage
+getpreviewBitmap = preview.GetBitmap
+getpreviewIcon = preview.GetIcon