[4] | 1 | #!/usr/bin/env python |
---|
| 2 | |
---|
| 3 | ############################################################################ |
---|
| 4 | # |
---|
| 5 | # SAGE LAUNCHER - A GUI for launching SAGE and all related components |
---|
| 6 | # |
---|
| 7 | # Copyright (C) 2007 Electronic Visualization Laboratory, |
---|
| 8 | # University of Illinois at Chicago |
---|
| 9 | # |
---|
| 10 | # All rights reserved. |
---|
| 11 | # |
---|
| 12 | # Redistribution and use in source and binary forms, with or without |
---|
| 13 | # modification, are permitted provided that the following conditions are met: |
---|
| 14 | # |
---|
| 15 | # * Redistributions of source code must retain the above copyright |
---|
| 16 | # notice, this list of conditions and the following disclaimer. |
---|
| 17 | # * Redistributions in binary form must reproduce the above |
---|
| 18 | # copyright notice, this list of conditions and the following disclaimer |
---|
| 19 | # in the documentation and/or other materials provided with the distribution. |
---|
| 20 | # * Neither the name of the University of Illinois at Chicago nor |
---|
| 21 | # the names of its contributors may be used to endorse or promote |
---|
| 22 | # products derived from this software without specific prior written permission. |
---|
| 23 | # |
---|
| 24 | # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
---|
| 25 | # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
---|
| 26 | # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
---|
| 27 | # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR |
---|
| 28 | # CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, |
---|
| 29 | # EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, |
---|
| 30 | # PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR |
---|
| 31 | # PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF |
---|
| 32 | # LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING |
---|
| 33 | # NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS |
---|
| 34 | # SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
---|
| 35 | # |
---|
| 36 | # Direct questions, comments etc about SAGE UI to www.evl.uic.edu/cavern/forum |
---|
| 37 | # |
---|
| 38 | # Author: Ratko Jagodic |
---|
| 39 | # |
---|
| 40 | ############################################################################ |
---|
| 41 | |
---|
| 42 | |
---|
| 43 | import wx, cPickle, os, sys, os.path, stat, string, copy, time, cStringIO, zlib, pickle |
---|
| 44 | import wx.lib.filebrowsebutton as fb |
---|
| 45 | import wx.lib.buttons as buttons |
---|
| 46 | import wx.lib.hyperlink as hl |
---|
| 47 | import wx.lib.scrolledpanel as scrolled |
---|
| 48 | from wx import BitmapFromImage, ImageFromStream |
---|
| 49 | import traceback as tb |
---|
| 50 | import subprocess as sp |
---|
| 51 | from threading import Thread |
---|
| 52 | |
---|
| 53 | |
---|
| 54 | # shortcut |
---|
| 55 | opj = os.path.join |
---|
| 56 | from sagePath import getUserPath, SAGE_DIR, getPath, getDefaultPath |
---|
| 57 | |
---|
| 58 | |
---|
| 59 | # -------------------------------------------------------- |
---|
| 60 | # |
---|
| 61 | # GLOBALS |
---|
| 62 | # |
---|
| 63 | # -------------------------------------------------------- |
---|
| 64 | |
---|
| 65 | # component types and official names |
---|
| 66 | APP_LAUNCHER = "Application Launcher" |
---|
| 67 | FILE_SERVER = "File Server" |
---|
| 68 | SAGE_PROXY = "SAGE Proxy" |
---|
| 69 | SAGE_UI = "SAGE UI" |
---|
| 70 | SAGE = "SAGE" |
---|
| 71 | componentNames = [SAGE, APP_LAUNCHER, SAGE_UI, FILE_SERVER, SAGE_PROXY] |
---|
| 72 | |
---|
| 73 | # this is where all the information about the components is stored |
---|
| 74 | components = {} # key=componentType, value=Component() |
---|
| 75 | |
---|
| 76 | # tileConfig file (structure of the cluster driving the display) |
---|
| 77 | tileConfig = None |
---|
| 78 | |
---|
| 79 | MAX_TEXT_LEN = 64000 # max characters in the output text ctrl |
---|
| 80 | PREFS_FILE = getUserPath("sageLauncherSettings.pickle") # store the settings in a pickle file |
---|
| 81 | PY_EXEC = sys.executable # platform dependent python executable |
---|
| 82 | |
---|
| 83 | # quit if the SAGE_DIRECTORY env var is not set |
---|
| 84 | if not "SAGE_DIRECTORY" in os.environ: |
---|
| 85 | print "SAGE_DIRECTORY environment variable not set." |
---|
| 86 | print "Please first set the SAGE_DIRECTORY environment variable to your sage directory." |
---|
| 87 | sys.exit(0) |
---|
| 88 | |
---|
| 89 | # default frame background color on windows (screwed up otherwise) |
---|
| 90 | global colour |
---|
| 91 | |
---|
| 92 | |
---|
| 93 | |
---|
| 94 | |
---|
| 95 | |
---|
| 96 | # -------------------------------------------------------- |
---|
| 97 | # |
---|
| 98 | # CONVENIENCE FUNCTIONS |
---|
| 99 | # |
---|
| 100 | # -------------------------------------------------------- |
---|
| 101 | |
---|
| 102 | |
---|
| 103 | def makeBoldFont(widget): |
---|
| 104 | f = widget.GetFont() |
---|
| 105 | f.SetWeight(wx.BOLD) |
---|
| 106 | widget.SetFont(f) |
---|
| 107 | |
---|
| 108 | def makeBiggerFont(widget): |
---|
| 109 | f = widget.GetFont() |
---|
| 110 | ps = f.GetPointSize() |
---|
| 111 | f.SetPointSize(ps + ps*0.2) # make it 20% bigger |
---|
| 112 | widget.SetFont(f) |
---|
| 113 | |
---|
| 114 | def makeSmallerFont(widget): |
---|
| 115 | f = widget.GetFont() |
---|
| 116 | ps = f.GetPointSize() |
---|
| 117 | f.SetPointSize(ps - ps*0.2) # make it 20% smaller |
---|
| 118 | widget.SetFont(f) |
---|
| 119 | |
---|
| 120 | def makeBiggerBoldFont(widget): |
---|
| 121 | makeBoldFont(widget) |
---|
| 122 | makeBiggerFont(widget) |
---|
| 123 | |
---|
| 124 | def isWin(): |
---|
| 125 | return "__WXMSW__" in wx.PlatformInfo |
---|
| 126 | |
---|
| 127 | |
---|
| 128 | |
---|
| 129 | # if the loadSettings fails for some reason (other than first execution), |
---|
| 130 | # do not save (since you will overwrite the previous good settings) |
---|
| 131 | DO_SAVE = True |
---|
| 132 | def saveSettings(): |
---|
| 133 | if DO_SAVE: |
---|
| 134 | # first assemble a dictionary of all the settings and then store it |
---|
| 135 | settings = {} |
---|
| 136 | for componentType, comp in components.iteritems(): |
---|
| 137 | settings[componentType] = comp.settings |
---|
| 138 | |
---|
| 139 | # now try and save the dictionary |
---|
| 140 | try: |
---|
| 141 | f = open(PREFS_FILE, "wb") |
---|
| 142 | cPickle.Pickler(f, cPickle.HIGHEST_PROTOCOL).dump(settings) |
---|
| 143 | f.close() |
---|
| 144 | except: |
---|
| 145 | print " ***** Error occured while saving settings:" |
---|
| 146 | print "".join(tb.format_exception(sys.exc_info()[0], sys.exc_info()[1], sys.exc_info()[2])) |
---|
| 147 | |
---|
| 148 | |
---|
| 149 | |
---|
| 150 | def loadSettings(): |
---|
| 151 | """ try loading the settings and if it fails just return the default |
---|
| 152 | if it succeeds, update the default with the saved settings """ |
---|
| 153 | |
---|
| 154 | # default settings |
---|
| 155 | settings = {} |
---|
| 156 | settings[APP_LAUNCHER] = AppLauncherSettings(APP_LAUNCHER) |
---|
| 157 | settings[FILE_SERVER] = FileServerSettings(FILE_SERVER) |
---|
| 158 | settings[SAGE_PROXY] = SageProxySettings(SAGE_PROXY) |
---|
| 159 | settings[SAGE_UI] = SageUISettings(SAGE_UI) |
---|
| 160 | settings[SAGE] = SageSettings(SAGE) |
---|
| 161 | |
---|
| 162 | # try loading the saved ones |
---|
| 163 | try: |
---|
| 164 | if os.path.isfile(PREFS_FILE): |
---|
| 165 | f = open(PREFS_FILE, "rb") |
---|
| 166 | (d) = cPickle.Unpickler(f).load() |
---|
| 167 | f.close() |
---|
| 168 | settings.update(d) |
---|
| 169 | except: |
---|
| 170 | print " ***** Error occured while loading saved settings and the changes you make will not be saved after you quit sageLauncher:" |
---|
| 171 | print "".join(tb.format_exception(sys.exc_info()[0], sys.exc_info()[1], sys.exc_info()[2])) |
---|
| 172 | global DO_SAVE |
---|
| 173 | DO_SAVE = False |
---|
| 174 | |
---|
| 175 | return settings |
---|
| 176 | |
---|
| 177 | |
---|
| 178 | |
---|
| 179 | |
---|
| 180 | def getTileConfig(): |
---|
| 181 | """ returns the full path of the currently used tile |
---|
| 182 | config file as specifed in the fsManager.conf """ |
---|
| 183 | |
---|
| 184 | f = open( getPath("fsManager.conf"), "r") |
---|
| 185 | for line in f: |
---|
| 186 | line = line.strip() |
---|
| 187 | if line.startswith('tileConfiguration'): |
---|
| 188 | config = line.split()[1].strip() |
---|
| 189 | f.close() |
---|
| 190 | return getPath(config) |
---|
| 191 | |
---|
| 192 | |
---|
| 193 | |
---|
| 194 | |
---|
| 195 | # -------------------------------------------------------- |
---|
| 196 | # |
---|
| 197 | # COMPONENTS |
---|
| 198 | # |
---|
| 199 | # -------------------------------------------------------- |
---|
| 200 | |
---|
| 201 | |
---|
| 202 | class Component: |
---|
| 203 | """ this is the class that contains all the information |
---|
| 204 | about each of the components: |
---|
| 205 | - settings, output field, process object |
---|
| 206 | There is one of these for each component and they are |
---|
| 207 | all stored in a global dictionary |
---|
| 208 | """ |
---|
| 209 | def __init__(self, componentType): |
---|
| 210 | self.componentType = componentType |
---|
| 211 | self.settings = None |
---|
| 212 | self.output = None |
---|
| 213 | self.process = None |
---|
| 214 | |
---|
| 215 | |
---|
| 216 | |
---|
| 217 | |
---|
| 218 | |
---|
| 219 | # -------------------------------------------------------- |
---|
| 220 | # |
---|
| 221 | # COMPONENT SETTINGS |
---|
| 222 | # |
---|
| 223 | # -------------------------------------------------------- |
---|
| 224 | |
---|
| 225 | # these are the objects that store all the information about |
---|
| 226 | # a component and will be saved in a file |
---|
| 227 | # they define how things are run and other specific settings |
---|
| 228 | |
---|
| 229 | |
---|
| 230 | class ComponentSettings: |
---|
| 231 | """ this is the base class for all the settings """ |
---|
| 232 | def __init__(self, t): |
---|
| 233 | self.inBG = False |
---|
| 234 | self.doRun = True |
---|
| 235 | self.cmd = "" |
---|
| 236 | self.componentType = t |
---|
| 237 | self.pid = -1 # pid from the started process |
---|
| 238 | |
---|
| 239 | |
---|
| 240 | def getStartCommand(self): |
---|
| 241 | """ this must be implemented by the subclasses |
---|
| 242 | it should return the final command that is used to run the component |
---|
| 243 | """ |
---|
| 244 | raise NotImplemented |
---|
| 245 | |
---|
| 246 | |
---|
| 247 | def getCwd(self): |
---|
| 248 | """ this must be implemented by the subclasses |
---|
| 249 | returns the current working directory |
---|
| 250 | """ |
---|
| 251 | raise NotImplemented |
---|
| 252 | |
---|
| 253 | |
---|
| 254 | def __getinitargs__(self): |
---|
| 255 | """ for pickling to work properly if we add some |
---|
| 256 | more settings to this class at a later time """ |
---|
| 257 | return (self.componentType,) |
---|
| 258 | |
---|
| 259 | |
---|
| 260 | |
---|
| 261 | |
---|
| 262 | class SageSettings(ComponentSettings): |
---|
| 263 | def __init__(self, componentType): |
---|
| 264 | ComponentSettings.__init__(self, componentType) |
---|
| 265 | self.doRun = True |
---|
| 266 | self.onStart = "xhost +local:\npython ../dim/dim.py\npython ../dim/hwcapture/localPointer.py localhost" # a string of commands to be executed after shutdown (split by \n) |
---|
| 267 | self.onStop = "fuser -k 19010/tcp" |
---|
| 268 | |
---|
| 269 | # things to kill on each node |
---|
| 270 | self.toKill = "fsManager sageDisplayManager sageAudioManager svc imageviewer mplayer bplay bplay-noglut VNCViewer render atlantis atlantis-mpi checker pdfviewer sagepdf" |
---|
| 271 | |
---|
| 272 | |
---|
| 273 | def getStartCommand(self): |
---|
| 274 | """ commmand used to run this component """ |
---|
| 275 | return ["fsManager"] |
---|
| 276 | |
---|
| 277 | |
---|
| 278 | def getCwd(self): |
---|
| 279 | """ returns the current working directory """ |
---|
| 280 | return opj(SAGE_DIR, "bin") |
---|
| 281 | |
---|
| 282 | |
---|
| 283 | def getKillCmd(self): |
---|
| 284 | """ returns a list of kill commands to run for stopping sage |
---|
| 285 | On Windows just kill the stuff on the local machine for now |
---|
| 286 | """ |
---|
| 287 | cmds = [] # this will be returned as a list of lists |
---|
| 288 | killString = self.toKill # processes to be killed on each node |
---|
| 289 | |
---|
| 290 | # windows |
---|
| 291 | if isWin(): |
---|
| 292 | # first append .exe to the processes |
---|
| 293 | killList = [proc + ".exe" for proc in killString.split()] |
---|
| 294 | |
---|
| 295 | # generate the commands to kill each process |
---|
| 296 | c = ["taskkill", "/F"] |
---|
| 297 | for proc in killList: |
---|
| 298 | c.extend(["/IM", proc]) |
---|
| 299 | cmds.append(c) |
---|
| 300 | |
---|
| 301 | # Mac + Linux |
---|
| 302 | else: |
---|
| 303 | # get the ip addresses of the nodes of the cluster |
---|
| 304 | # + the master node |
---|
| 305 | tileConfig.readConfigFile(getTileConfig()) |
---|
| 306 | IPs = tileConfig.getAllIPs() |
---|
| 307 | IPs.append("127.0.0.1") |
---|
| 308 | |
---|
| 309 | for node in IPs: |
---|
| 310 | c = [] |
---|
| 311 | k = "/usr/bin/killall -9 %s" % killString |
---|
| 312 | c.extend( ["/usr/bin/ssh", "-fx", node, k] ) |
---|
| 313 | cmds.append(c) |
---|
| 314 | |
---|
| 315 | return cmds |
---|
| 316 | |
---|
| 317 | |
---|
| 318 | def __getinitargs__(self): |
---|
| 319 | """ for pickling to work properly if we add some |
---|
| 320 | more settings to this class at a later time """ |
---|
| 321 | return (self.componentType,) |
---|
| 322 | |
---|
| 323 | |
---|
| 324 | |
---|
| 325 | class AppLauncherSettings(ComponentSettings): |
---|
| 326 | def __init__(self, componentType): |
---|
| 327 | ComponentSettings.__init__(self, componentType) |
---|
| 328 | self.doReport = False |
---|
| 329 | self.doRun = True |
---|
| 330 | self.server = "sage.sl.startap.net" |
---|
| 331 | self.port = 19010 |
---|
| 332 | |
---|
| 333 | |
---|
| 334 | def getAppConfigFilename(self): |
---|
| 335 | return getPath("applications", "applications.conf") |
---|
| 336 | |
---|
| 337 | def getStartCommand(self): |
---|
| 338 | """ commmand used to run this component """ |
---|
| 339 | cmd = [PY_EXEC, "-u", opj(self.getCwd(), "appLauncher.py"), "-v", "-p", str(self.port)] |
---|
| 340 | |
---|
| 341 | # report to sage server? |
---|
| 342 | if self.doReport: cmd.extend( ["-s", self.server] ) |
---|
| 343 | else: rep = cmd.append("-n") |
---|
| 344 | |
---|
| 345 | # run in background? |
---|
| 346 | if self.inBG and not isWin(): cmd.append("&") |
---|
| 347 | |
---|
| 348 | return cmd |
---|
| 349 | |
---|
| 350 | |
---|
| 351 | def getKillCmd(self): |
---|
| 352 | """ returns the command to kill the appLauncher """ |
---|
| 353 | return [PY_EXEC, "KILL_LAUNCHER.py", str(self.port)] |
---|
| 354 | |
---|
| 355 | |
---|
| 356 | def getCwd(self): |
---|
| 357 | """ returns the current working directory """ |
---|
| 358 | return opj(SAGE_DIR, "bin", "appLauncher") |
---|
| 359 | |
---|
| 360 | |
---|
| 361 | def __getinitargs__(self): |
---|
| 362 | """ for pickling to work properly if we add some |
---|
| 363 | more settings to this class at a later time """ |
---|
| 364 | return (self.componentType,) |
---|
| 365 | |
---|
| 366 | |
---|
| 367 | |
---|
| 368 | class FileServerSettings(ComponentSettings): |
---|
| 369 | def __init__(self, componentType): |
---|
| 370 | ComponentSettings.__init__(self, componentType) |
---|
| 371 | |
---|
| 372 | |
---|
| 373 | def getConfigFilename(self): |
---|
| 374 | return getPath("fileServer", "fileServer.conf") |
---|
| 375 | |
---|
| 376 | |
---|
| 377 | def getStartCommand(self): |
---|
| 378 | """ commmand used to run this component """ |
---|
| 379 | if self.inBG and not isWin(): bg = "&" |
---|
| 380 | else: bg = "" |
---|
| 381 | return [PY_EXEC, "-u", opj(self.getCwd(), "fileServer.py"), "-v", bg] |
---|
| 382 | |
---|
| 383 | |
---|
| 384 | def getCwd(self): |
---|
| 385 | """ returns the current working directory """ |
---|
| 386 | return opj(SAGE_DIR, "bin", "fileServer") |
---|
| 387 | |
---|
| 388 | |
---|
| 389 | def __getinitargs__(self): |
---|
| 390 | """ for pickling to work properly if we add some |
---|
| 391 | more settings to this class at a later time """ |
---|
| 392 | return (self.componentType,) |
---|
| 393 | |
---|
| 394 | |
---|
| 395 | |
---|
| 396 | |
---|
| 397 | class SageProxySettings(ComponentSettings): |
---|
| 398 | def __init__(self, componentType): |
---|
| 399 | ComponentSettings.__init__(self, componentType) |
---|
| 400 | self.host = 'localhost' |
---|
| 401 | self.port = 20001 |
---|
| 402 | self.password = "pass" |
---|
| 403 | |
---|
| 404 | |
---|
| 405 | def getStartCommand(self): |
---|
| 406 | """ commmand used to run this component """ |
---|
| 407 | return [PY_EXEC, "-u", opj(self.getCwd(), "sageProxy.py"), |
---|
| 408 | "-s", self.host, "-p", str(self.port), "-x", self.password, "-v"] |
---|
| 409 | |
---|
| 410 | |
---|
| 411 | def getCwd(self): |
---|
| 412 | """ returns the current working directory """ |
---|
| 413 | return opj(SAGE_DIR, "bin", "sageProxy") |
---|
| 414 | |
---|
| 415 | |
---|
| 416 | def __getinitargs__(self): |
---|
| 417 | """ for pickling to work properly if we add some |
---|
| 418 | more settings to this class at a later time """ |
---|
| 419 | return (self.componentType,) |
---|
| 420 | |
---|
| 421 | |
---|
| 422 | |
---|
| 423 | class SageUISettings(ComponentSettings): |
---|
| 424 | def __init__(self, componentType): |
---|
| 425 | ComponentSettings.__init__(self, componentType) |
---|
| 426 | self.host = 'sage.sl.startap.net' |
---|
| 427 | self.port = 15558 |
---|
| 428 | self.doRun = True |
---|
| 429 | self.autologinMachine = "" |
---|
| 430 | self.loadState = "" |
---|
| 431 | |
---|
| 432 | |
---|
| 433 | def getStartCommand(self): |
---|
| 434 | """ commmand used to run this component """ |
---|
| 435 | cmd = [PY_EXEC, "-u", opj(self.getCwd(),"sageui.py"), "-v", "-s", self.host, "-p", str(self.port), "-t"] |
---|
| 436 | if self.autologinMachine != "": |
---|
| 437 | cmd.extend( ["-a", self.autologinMachine] ) |
---|
| 438 | if self.loadState != "": |
---|
| 439 | cmd.extend( ["-o", self.loadState] ) |
---|
| 440 | return cmd |
---|
| 441 | |
---|
| 442 | |
---|
| 443 | def getCwd(self): |
---|
| 444 | """ returns the current working directory """ |
---|
| 445 | return opj(SAGE_DIR, "ui") |
---|
| 446 | |
---|
| 447 | |
---|
| 448 | def __getinitargs__(self): |
---|
| 449 | """ for pickling to work properly if we add some |
---|
| 450 | more settings to this class at a later time """ |
---|
| 451 | return (self.componentType,) |
---|
| 452 | |
---|
| 453 | |
---|
| 454 | |
---|
| 455 | |
---|
| 456 | |
---|
| 457 | |
---|
| 458 | |
---|
| 459 | # -------------------------------------------------------- |
---|
| 460 | # |
---|
| 461 | # UI STUFF |
---|
| 462 | # |
---|
| 463 | # -------------------------------------------------------- |
---|
| 464 | |
---|
| 465 | |
---|
| 466 | ### |
---|
| 467 | ### these are the specific frames for each component that let's you configure the component |
---|
| 468 | ### |
---|
| 469 | |
---|
| 470 | |
---|
| 471 | class ComponentFrame(wx.Frame): |
---|
| 472 | def __init__(self, parent, componentType): |
---|
| 473 | s = wx.DEFAULT_FRAME_STYLE | wx.TAB_TRAVERSAL |
---|
| 474 | wx.Frame.__init__(self, parent, wx.ID_ANY, componentType+" Configuration", style=s) |
---|
| 475 | if isWin(): self.SetBackgroundColour(colour) |
---|
| 476 | self.settings = components[componentType].settings |
---|
| 477 | self.mainSizer = wx.BoxSizer(wx.VERTICAL) |
---|
| 478 | self.SetIcon(getSageIcon()) |
---|
| 479 | self.Bind(wx.EVT_CLOSE, self.OnClose) |
---|
| 480 | |
---|
| 481 | |
---|
| 482 | def MakeWidgets(self): |
---|
| 483 | okBtn = wx.Button(self, wx.ID_ANY, "OK") |
---|
| 484 | okBtn.Bind(wx.EVT_BUTTON, self.DoClose) |
---|
| 485 | self.mainSizer.Add(okBtn, 0, wx.ALIGN_CENTER_HORIZONTAL | wx.ALL, 15) |
---|
| 486 | self.SetSizerAndFit(self.mainSizer) |
---|
| 487 | |
---|
| 488 | |
---|
| 489 | def DoClose(self, evt=None): |
---|
| 490 | self.Close(True) |
---|
| 491 | |
---|
| 492 | |
---|
| 493 | def OnClose(self, evt): |
---|
| 494 | """ save everything here but let the subclasses do that |
---|
| 495 | since it's specific for each... therefore it must be implemented """ |
---|
| 496 | raise NotImplemented |
---|
| 497 | |
---|
| 498 | |
---|
| 499 | |
---|
| 500 | |
---|
| 501 | |
---|
| 502 | class AppLauncherFrame(ComponentFrame): |
---|
| 503 | def __init__(self, parent): |
---|
| 504 | ComponentFrame.__init__(self, parent, APP_LAUNCHER) |
---|
| 505 | self.configs = AppConfigurations(self.settings.getAppConfigFilename()) |
---|
| 506 | self.currentConfig = None #current config object being edited |
---|
| 507 | self.MakeWidgets() |
---|
| 508 | self.Show() |
---|
| 509 | |
---|
| 510 | |
---|
| 511 | def MakeWidgets(self): |
---|
| 512 | self.run = wx.CheckBox(self, wx.ID_ANY, "Run in background") |
---|
| 513 | self.run.SetToolTipString(HELP_INBG) |
---|
| 514 | self.run.SetValue(self.settings.inBG) |
---|
| 515 | |
---|
| 516 | self.mainSizer.Add(self.MakeConnectionBox(), 0, wx.EXPAND | wx.ALL, 10) |
---|
| 517 | self.mainSizer.Add(self.MakeAppConfigBox(), 0, wx.EXPAND | wx.ALL, 10) |
---|
| 518 | self.mainSizer.Add(self.run, 0, wx.ALIGN_CENTER_HORIZONTAL | wx.ALIGN_BOTTOM | wx.ALL, 5) |
---|
| 519 | ComponentFrame.MakeWidgets(self) |
---|
| 520 | |
---|
| 521 | |
---|
| 522 | def MakeConnectionBox(self): |
---|
| 523 | # the box |
---|
| 524 | box = wx.StaticBox(self, wx.ID_ANY, "Public access:") |
---|
| 525 | box.SetForegroundColour(wx.BLUE) |
---|
| 526 | makeBiggerBoldFont( box ) |
---|
| 527 | boxSizer = wx.StaticBoxSizer( box, wx.VERTICAL ) |
---|
| 528 | |
---|
| 529 | # widgets |
---|
| 530 | hostLabel = wx.StaticText(self, wx.ID_ANY, "Hostname / IP:") |
---|
| 531 | self.hostText = wx.TextCtrl(self, wx.ID_ANY, self.settings.server) |
---|
| 532 | self.hostText.SetMinSize((150, -1)) |
---|
| 533 | self.hostText.SetToolTipString(HELP_AL_PUBLIC_HOST) |
---|
| 534 | |
---|
| 535 | #portLabel = wx.StaticText(self, wx.ID_ANY, "Port:") |
---|
| 536 | #self.portText = wx.TextCtrl(self, wx.ID_ANY, str(self.settings.port)) |
---|
| 537 | |
---|
| 538 | self.reportCheck = wx.CheckBox(self, wx.ID_ANY, "Allow public access?") |
---|
| 539 | self.reportCheck.SetToolTipString(HELP_AL_PUBLIC) |
---|
| 540 | self.reportCheck.SetValue(self.settings.doReport) |
---|
| 541 | self.reportCheck.Bind(wx.EVT_CHECKBOX, self.OnPublicCheck) |
---|
| 542 | self.OnPublicCheck(None) |
---|
| 543 | |
---|
| 544 | # add widgets to the boxSizer |
---|
| 545 | hSizer = wx.BoxSizer(wx.HORIZONTAL) |
---|
| 546 | hSizer.Add(hostLabel, 0, wx.ALIGN_CENTER_VERTICAL | wx.ALIGN_LEFT | wx.ALL, 5) |
---|
| 547 | hSizer.Add(self.hostText, 0, wx.ALIGN_CENTER_VERTICAL | wx.ALIGN_LEFT | wx.RIGHT | wx.BOTTOM | wx.TOP, 5) |
---|
| 548 | hSizer.Add((10,10)) |
---|
| 549 | #hSizer.Add(portLabel, 0, wx.ALIGN_CENTER_VERTICAL | wx.ALIGN_LEFT | wx.ALL, 5) |
---|
| 550 | #hSizer.Add(self.portText, 0, wx.ALIGN_CENTER_VERTICAL | wx.ALIGN_LEFT | wx.RIGHT | wx.BOTTOM | wx.TOP, 5) |
---|
| 551 | |
---|
| 552 | boxSizer.Add(self.reportCheck, 0, wx.ALIGN_CENTER_VERTICAL | wx.ALIGN_LEFT | wx.ALL, 5) |
---|
| 553 | boxSizer.Add(hSizer, 0, wx.ALIGN_CENTER_VERTICAL | wx.ALIGN_LEFT | wx.ALL, 5) |
---|
| 554 | |
---|
| 555 | return boxSizer |
---|
| 556 | |
---|
| 557 | |
---|
| 558 | def MakeAppConfigBox(self): |
---|
| 559 | # the box |
---|
| 560 | box = wx.StaticBox(self, wx.ID_ANY, "SAGE Applications:") |
---|
| 561 | box.SetForegroundColour(wx.BLUE) |
---|
| 562 | makeBiggerBoldFont( box ) |
---|
| 563 | boxSizer = wx.StaticBoxSizer( box, wx.HORIZONTAL ) |
---|
| 564 | |
---|
| 565 | # apps label and list |
---|
| 566 | appsLabel = wx.StaticText(self, wx.ID_ANY, "Applications:") |
---|
| 567 | makeBoldFont(appsLabel) |
---|
| 568 | self.appsList = wx.ListBox(self, wx.ID_ANY, choices=self.configs.getAppList()) |
---|
| 569 | self.appsList.Bind(wx.EVT_LISTBOX, self.OnAppList) |
---|
| 570 | self.appsList.SetToolTipString(HELP_AL_APPS) |
---|
| 571 | addBtn = wx.Button(self, wx.ID_ANY, "Add", style=wx.BU_EXACTFIT) |
---|
| 572 | addBtn.Bind(wx.EVT_BUTTON, self.OnAppAdd) |
---|
| 573 | delBtn = wx.Button(self, wx.ID_ANY, "Delete", style=wx.BU_EXACTFIT) |
---|
| 574 | delBtn.Bind(wx.EVT_BUTTON, self.OnAppDel) |
---|
| 575 | |
---|
| 576 | btnSizer = wx.BoxSizer(wx.HORIZONTAL) |
---|
| 577 | btnSizer.Add(addBtn, 1, wx.ALIGN_CENTER | wx.ALL, 4) |
---|
| 578 | btnSizer.Add(delBtn, 1, wx.ALIGN_CENTER | wx.RIGHT | wx.TOP | wx.BOTTOM, 4) |
---|
| 579 | |
---|
| 580 | appsSizer = wx.BoxSizer(wx.VERTICAL) |
---|
| 581 | appsSizer.Add(appsLabel, 0, wx.EXPAND | wx.ALIGN_LEFT | wx.ALL, 5) |
---|
| 582 | appsSizer.Add(self.appsList, 1, wx.EXPAND | wx.ALIGN_LEFT | wx.ALL, 5) |
---|
| 583 | appsSizer.Add(btnSizer, 0, wx.EXPAND | wx.ALIGN_CENTER_HORIZONTAL | wx.ALL, 1) |
---|
| 584 | |
---|
| 585 | # add widgets to the boxSizer |
---|
| 586 | self.confSizer = self.MakeConfigBox() |
---|
| 587 | boxSizer.Add(appsSizer, 0, wx.EXPAND | wx.ALIGN_LEFT | wx.ALL, 5) |
---|
| 588 | boxSizer.Add(wx.StaticLine(self, wx.ID_ANY, style=wx.VERTICAL), 0, wx.EXPAND | wx.ALIGN_LEFT | wx.ALL, 5) |
---|
| 589 | boxSizer.Add(self.confSizer, 1, wx.EXPAND | wx.ALIGN_LEFT | wx.ALL, 5) |
---|
| 590 | |
---|
| 591 | return boxSizer |
---|
| 592 | |
---|
| 593 | |
---|
| 594 | def MakeConfigBox(self): |
---|
| 595 | self.configSizers = {} |
---|
| 596 | |
---|
| 597 | # configuration list |
---|
| 598 | configLabel = wx.StaticText(self, wx.ID_ANY, "Configurations:") |
---|
| 599 | makeBoldFont(configLabel) |
---|
| 600 | self.configCombo = wx.ComboBox(self, wx.ID_ANY, choices=[]) |
---|
| 601 | self.configCombo.SetMinSize((180, -1)) |
---|
| 602 | self.configCombo.Bind(wx.EVT_COMBOBOX, self.OnConfigCombo) |
---|
| 603 | self.configCombo.SetToolTipString(HELP_AL_CFG) |
---|
| 604 | newBtn = wx.Button(self, wx.ID_ANY, " Add ", style=wx.BU_EXACTFIT) |
---|
| 605 | newBtn.Bind(wx.EVT_BUTTON, self.OnAddConfig) |
---|
| 606 | delBtn = wx.Button(self, wx.ID_ANY, " Delete ", style=wx.BU_EXACTFIT) |
---|
| 607 | delBtn.Bind(wx.EVT_BUTTON, self.OnDelConfig) |
---|
| 608 | copyBtn = wx.Button(self, wx.ID_ANY, " Make Copy ", style=wx.BU_EXACTFIT) |
---|
| 609 | copyBtn.Bind(wx.EVT_BUTTON, self.OnCopyConfig) |
---|
| 610 | copyBtn.SetToolTipString(HELP_AL_CFG_COPY) |
---|
| 611 | |
---|
| 612 | self.comboSizer = wx.BoxSizer(wx.HORIZONTAL) |
---|
| 613 | self.comboSizer.Add(configLabel, 0, wx.ALIGN_CENTER | wx.ALL, 5) |
---|
| 614 | self.comboSizer.Add(self.configCombo, 0, wx.ALIGN_CENTER | wx.ALL, 5) |
---|
| 615 | self.comboSizer.Add(newBtn, 0, wx.ALIGN_CENTER | wx.ALL, 5) |
---|
| 616 | self.comboSizer.Add(delBtn, 0, wx.ALIGN_CENTER | wx.ALL, 5) |
---|
| 617 | self.comboSizer.Add(copyBtn, 0, wx.ALIGN_CENTER | wx.ALL, 5) |
---|
| 618 | |
---|
| 619 | # add all to the main config sizer |
---|
| 620 | vSizer = wx.BoxSizer(wx.VERTICAL) |
---|
| 621 | vSizer.Add(self.comboSizer, 1, wx.EXPAND | wx.ALIGN_CENTER_HORIZONTAL | wx.ALIGN_TOP | wx.ALL, 9) |
---|
| 622 | l = wx.StaticLine(self, wx.ID_ANY); l.Disable() |
---|
| 623 | vSizer.Add(l, 0, wx.EXPAND | wx.ALIGN_LEFT | wx.ALL, 5) |
---|
| 624 | |
---|
| 625 | # static app |
---|
| 626 | self.staticCheck = wx.CheckBox(self, wx.ID_ANY, "Static application")#, style=wx.ALIGN_RIGHT) |
---|
| 627 | self.staticCheck.SetValue(True) |
---|
| 628 | self.staticCheck.Bind(wx.EVT_KILL_FOCUS, self.OnStaticFocus) |
---|
| 629 | self.staticCheck.SetToolTipString(HELP_AL_CFG_STATIC) |
---|
| 630 | vSizer.Add(self.staticCheck, 0, wx.EXPAND | wx.ALIGN_TOP | wx.ALIGN_LEFT | wx.ALL, 10) |
---|
| 631 | |
---|
| 632 | # execution |
---|
| 633 | execFoldBar = FoldBar(self, 101, "Execution", self.OnFoldBtn) |
---|
| 634 | self.configSizers[101] = self.MakeExecutionSection() |
---|
| 635 | vSizer.Add(execFoldBar, 0, wx.EXPAND | wx.ALIGN_TOP | wx.ALIGN_LEFT | wx.ALL, 5) |
---|
| 636 | vSizer.Add(self.configSizers[101], 0, wx.EXPAND | wx.ALIGN_TOP | wx.ALIGN_LEFT | wx.LEFT | wx.BOTTOM | wx.RIGHT, 15) |
---|
| 637 | vSizer.Show(self.configSizers[101], False, True) |
---|
| 638 | |
---|
| 639 | # size and pos |
---|
| 640 | sizePosFoldBar = FoldBar(self, 100, "Size and position", self.OnFoldBtn) |
---|
| 641 | self.configSizers[100] = self.MakeSizePosSection() |
---|
| 642 | vSizer.Add(sizePosFoldBar, 0, wx.EXPAND | wx.ALIGN_TOP | wx.ALIGN_LEFT | wx.ALL, 5) |
---|
| 643 | vSizer.Add(self.configSizers[100], 0, wx.EXPAND | wx.ALIGN_TOP | wx.ALIGN_LEFT | wx.LEFT | wx.BOTTOM | wx.RIGHT, 15) |
---|
| 644 | vSizer.Show(self.configSizers[100], False, True) |
---|
| 645 | |
---|
| 646 | # parallel application stuff |
---|
| 647 | parallelFoldBar = FoldBar(self, 102, "Parallel Applications", self.OnFoldBtn) |
---|
| 648 | self.configSizers[102] = self.MakeParallelSection() |
---|
| 649 | vSizer.Add(parallelFoldBar, 0, wx.EXPAND | wx.ALIGN_TOP | wx.ALIGN_LEFT | wx.ALL, 5) |
---|
| 650 | vSizer.Add(self.configSizers[102], 0, wx.EXPAND | wx.ALIGN_TOP | wx.ALIGN_LEFT | wx.LEFT | wx.BOTTOM | wx.RIGHT, 15) |
---|
| 651 | vSizer.Show(self.configSizers[102], False, True) |
---|
| 652 | |
---|
| 653 | # advanced stuff... |
---|
| 654 | advFoldBar = FoldBar(self, 103, "Advanced", self.OnFoldBtn) |
---|
| 655 | self.configSizers[103] = self.MakeAdvancedSection() |
---|
| 656 | vSizer.Add(advFoldBar, 0, wx.EXPAND | wx.ALIGN_TOP | wx.ALIGN_LEFT | wx.ALL, 5) |
---|
| 657 | vSizer.Add(self.configSizers[103], 0, wx.EXPAND | wx.ALIGN_TOP | wx.ALIGN_LEFT | wx.LEFT | wx.BOTTOM | wx.RIGHT, 15) |
---|
| 658 | vSizer.Show(self.configSizers[103], False, True) |
---|
| 659 | |
---|
| 660 | return vSizer |
---|
| 661 | |
---|
| 662 | |
---|
| 663 | def MakeParallelSection(self): |
---|
| 664 | # parallel checkbox |
---|
| 665 | self.parallelCheck = wx.CheckBox(self, wx.ID_ANY, "This is a parallel application", style=wx.ALIGN_RIGHT) |
---|
| 666 | self.parallelCheck.Bind(wx.EVT_CHECKBOX, self.OnParallelCheck) |
---|
| 667 | |
---|
| 668 | # number of nodes |
---|
| 669 | nodeNumLabel = wx.StaticText(self, wx.ID_ANY, "Number of nodes:") |
---|
| 670 | self.nodeNumSpin = wx.SpinCtrl(self, wx.ID_ANY, min=1, initial=1) |
---|
| 671 | self.nodeNumSpin.SetToolTipString(HELP_AL_CFG_NUM_NODES) |
---|
| 672 | self.nodeNumSpin.Disable() |
---|
| 673 | self.nodeNumSpin.Bind(wx.EVT_KILL_FOCUS, self.OnNodeNumFocus) |
---|
| 674 | |
---|
| 675 | # master ip |
---|
| 676 | masterIPLabel = wx.StaticText(self, wx.ID_ANY, "Master node:") |
---|
| 677 | self.masterIPText = wx.TextCtrl(self, wx.ID_ANY) |
---|
| 678 | self.masterIPText.SetToolTipString(HELP_AL_CFG_MASTER) |
---|
| 679 | self.masterIPText.SetMinSize((120, -1)) |
---|
| 680 | self.masterIPText.Disable() |
---|
| 681 | self.masterIPText.Bind(wx.EVT_KILL_FOCUS, self.OnMasterIPFocus) |
---|
| 682 | |
---|
| 683 | # sizer stuff |
---|
| 684 | pSizer = wx.FlexGridSizer(2,2,5,5) |
---|
| 685 | pSizer.Add(nodeNumLabel, 0, wx.ALIGN_CENTER_VERTICAL | wx.ALIGN_LEFT | wx.LEFT | wx.RIGHT, 5) |
---|
| 686 | pSizer.Add(self.nodeNumSpin, 0, wx.ALIGN_CENTER_VERTICAL | wx.ALIGN_LEFT | wx.RIGHT, 5) |
---|
| 687 | pSizer.Add(masterIPLabel, 0, wx.ALIGN_CENTER_VERTICAL | wx.ALIGN_LEFT | wx.LEFT | wx.RIGHT, 5) |
---|
| 688 | pSizer.Add(self.masterIPText, 0, wx.ALIGN_CENTER_VERTICAL | wx.ALIGN_LEFT | wx.RIGHT, 5) |
---|
| 689 | |
---|
| 690 | sizer = wx.BoxSizer(wx.VERTICAL) |
---|
| 691 | sizer.Add(self.parallelCheck, 0, wx.ALIGN_CENTER_HORIZONTAL | wx.ALL, 5) |
---|
| 692 | sizer.Add(pSizer, 0, wx.ALIGN_LEFT | wx.ALL, 5) |
---|
| 693 | |
---|
| 694 | return sizer |
---|
| 695 | |
---|
| 696 | |
---|
| 697 | def MakeExecutionSection(self): |
---|
| 698 | appLabel = wx.StaticText(self, wx.ID_ANY, "Run application") |
---|
| 699 | appLabel.SetMinSize((100, -1)) |
---|
| 700 | self.appText = wx.TextCtrl(self, wx.ID_ANY) |
---|
| 701 | self.appText.SetToolTipString(HELP_AL_CFG_APP) |
---|
| 702 | self.appText.Bind(wx.EVT_KILL_FOCUS, self.OnAppTextFocus) |
---|
| 703 | |
---|
| 704 | dirLabel = wx.StaticText(self, wx.ID_ANY, "from directory") |
---|
| 705 | dirLabel.SetMinSize((100, -1)) |
---|
| 706 | self.dirText = wx.TextCtrl(self, wx.ID_ANY) |
---|
| 707 | self.dirText.SetToolTipString(HELP_AL_CFG_DIR) |
---|
| 708 | self.dirText.Bind(wx.EVT_KILL_FOCUS, self.OnDirTextFocus) |
---|
| 709 | |
---|
| 710 | machineLabel = wx.StaticText(self, wx.ID_ANY, "on host") |
---|
| 711 | self.machineText = wx.TextCtrl(self, wx.ID_ANY) |
---|
| 712 | self.machineText.SetToolTipString(HELP_AL_CFG_MACHINE) |
---|
| 713 | self.machineText.SetMinSize((140, -1)) |
---|
| 714 | self.machineText.Bind(wx.EVT_KILL_FOCUS, self.OnMachineTextFocus) |
---|
| 715 | |
---|
| 716 | sizer = wx.FlexGridSizer(3,2, 3,10) |
---|
| 717 | sizer.Add(appLabel, 0, wx.ALIGN_CENTER_VERTICAL | wx.ALIGN_LEFT | wx.ALL, 5) |
---|
| 718 | sizer.Add(self.appText, 0, wx.EXPAND | wx.ALIGN_CENTER_VERTICAL | wx.ALIGN_LEFT) |
---|
| 719 | sizer.Add(dirLabel, 0, wx.ALIGN_CENTER_VERTICAL | wx.ALIGN_LEFT | wx.ALL, 5) |
---|
| 720 | sizer.Add(self.dirText, 0, wx.EXPAND | wx.ALIGN_CENTER_VERTICAL | wx.ALIGN_LEFT) |
---|
| 721 | sizer.Add(machineLabel, 0, wx.ALIGN_CENTER_VERTICAL | wx.ALIGN_LEFT | wx.ALL, 5) |
---|
| 722 | sizer.Add(self.machineText, 0, wx.ALIGN_CENTER_VERTICAL | wx.ALIGN_LEFT) |
---|
| 723 | sizer.AddGrowableCol(1) |
---|
| 724 | |
---|
| 725 | return sizer |
---|
| 726 | |
---|
| 727 | |
---|
| 728 | def MakeSizePosSection(self): |
---|
| 729 | # sage window size |
---|
| 730 | szLabel = wx.StaticText(self, wx.ID_ANY, "Initial SAGE window size") |
---|
| 731 | szLabel.SetMinSize((180, -1)) |
---|
| 732 | wLabel = wx.StaticText(self, wx.ID_ANY, "W") |
---|
| 733 | self.wText = wx.TextCtrl(self, wx.ID_ANY, "1000") |
---|
| 734 | self.wText.Bind(wx.EVT_KILL_FOCUS, self.OnSizeTextFocus) |
---|
| 735 | self.wText.SetToolTipString(HELP_AL_CFG_SIZE) |
---|
| 736 | hLabel = wx.StaticText(self, wx.ID_ANY, "H") |
---|
| 737 | self.hText = wx.TextCtrl(self, wx.ID_ANY, "1000") |
---|
| 738 | self.hText.SetToolTipString(HELP_AL_CFG_SIZE) |
---|
| 739 | self.hText.Bind(wx.EVT_KILL_FOCUS, self.OnSizeTextFocus) |
---|
| 740 | |
---|
| 741 | # sage window position |
---|
| 742 | posLabel = wx.StaticText(self, wx.ID_ANY, "Initial SAGE window position") |
---|
| 743 | posLabel.SetMinSize((180, -1)) |
---|
| 744 | xLabel = wx.StaticText(self, wx.ID_ANY, "X") |
---|
| 745 | self.xText = wx.TextCtrl(self, wx.ID_ANY, "100") |
---|
| 746 | self.xText.Bind(wx.EVT_KILL_FOCUS, self.OnPosTextFocus) |
---|
| 747 | yLabel = wx.StaticText(self, wx.ID_ANY, "Y") |
---|
| 748 | self.yText = wx.TextCtrl(self, wx.ID_ANY, "100") |
---|
| 749 | self.yText.Bind(wx.EVT_KILL_FOCUS, self.OnPosTextFocus) |
---|
| 750 | |
---|
| 751 | # add to sizer |
---|
| 752 | sizer = wx.FlexGridSizer(2,5, 5,0) |
---|
| 753 | sizer.Add(szLabel, 0, wx.ALIGN_CENTER_VERTICAL | wx.ALIGN_LEFT | wx.ALL, border=5) |
---|
| 754 | sizer.Add(wLabel, 0, wx.ALIGN_CENTER_VERTICAL | wx.ALIGN_LEFT | wx.ALL, border=5) |
---|
| 755 | sizer.Add(self.wText, 0, wx.ALIGN_CENTER_VERTICAL | wx.ALIGN_LEFT | wx.ALL, border=5) |
---|
| 756 | sizer.Add(hLabel, 0, wx.ALIGN_CENTER_VERTICAL | wx.ALIGN_LEFT | wx.ALL, border=5) |
---|
| 757 | sizer.Add(self.hText, 0, wx.ALIGN_CENTER_VERTICAL | wx.ALIGN_LEFT | wx.ALL, border=5) |
---|
| 758 | |
---|
| 759 | sizer.Add(posLabel, 0, wx.ALIGN_CENTER_VERTICAL | wx.ALIGN_LEFT | wx.ALL, border=5) |
---|
| 760 | sizer.Add(xLabel, 0, wx.ALIGN_CENTER_VERTICAL | wx.ALIGN_LEFT | wx.ALL, border=5) |
---|
| 761 | sizer.Add(self.xText, 0, wx.ALIGN_CENTER_VERTICAL | wx.ALIGN_LEFT | wx.ALL, border=5) |
---|
| 762 | sizer.Add(yLabel, 0, wx.ALIGN_CENTER_VERTICAL | wx.ALIGN_LEFT | wx.ALL, border=5) |
---|
| 763 | sizer.Add(self.yText, 0, wx.ALIGN_CENTER_VERTICAL | wx.ALIGN_LEFT | wx.ALL, border=5) |
---|
| 764 | |
---|
| 765 | return sizer |
---|
| 766 | |
---|
| 767 | |
---|
| 768 | def MakeAdvancedSection(self): |
---|
| 769 | pbLabel = wx.StaticText(self, wx.ID_ANY, "Pixel block size") |
---|
| 770 | pbLabel.SetMinSize((130, -1)) |
---|
| 771 | self.pbSpin = wx.SpinCtrl(self, wx.ID_ANY, min=1, max=512, initial=64) |
---|
| 772 | self.pbSpin.Bind(wx.EVT_KILL_FOCUS, self.OnPBSpinFocus) |
---|
| 773 | self.pbSpin.SetToolTipString(HELP_AL_CFG_BP) |
---|
| 774 | |
---|
| 775 | #protoLabel = wx.StaticText(self, wx.ID_ANY, "Streaming protocol") |
---|
| 776 | #protoLabel.SetMinSize((130, -1)) |
---|
| 777 | #self.protoCombo = wx.ComboBox(self, wx.ID_ANY, choices=["TCP"]) |
---|
| 778 | |
---|
| 779 | bridgeIPLabel = wx.StaticText(self, wx.ID_ANY, "SAGE Bridge host") |
---|
| 780 | bridgeIPLabel.SetMinSize((130, -1)) |
---|
| 781 | self.bridgeIPText = wx.TextCtrl(self, wx.ID_ANY) |
---|
| 782 | self.bridgeIPText.SetMinSize((150, -1)) |
---|
| 783 | self.bridgeIPText.Bind(wx.EVT_KILL_FOCUS, self.OnBridgeIPTextFocus) |
---|
| 784 | self.bridgeIPText.SetToolTipString(HELP_AL_CFG_BHOST) |
---|
| 785 | |
---|
| 786 | bridgePortLabel = wx.StaticText(self, wx.ID_ANY, "SAGE Bridge port") |
---|
| 787 | bridgePortLabel.SetMinSize((130, -1)) |
---|
| 788 | self.bridgePortText = wx.TextCtrl(self, wx.ID_ANY) |
---|
| 789 | self.bridgePortText.SetMinSize((150, -1)) |
---|
| 790 | self.bridgePortText.Bind(wx.EVT_KILL_FOCUS, self.OnBridgePortTextFocus) |
---|
| 791 | self.bridgePortText.SetToolTipString(HELP_AL_CFG_BPORT) |
---|
| 792 | |
---|
| 793 | sizer = wx.FlexGridSizer(3,2, 3,10) |
---|
| 794 | #sizer.Add(protoLabel, 0, wx.ALIGN_CENTER_VERTICAL | wx.ALIGN_LEFT | wx.ALL, 5) |
---|
| 795 | #sizer.Add(self.protoCombo, 0, wx.ALIGN_CENTER_VERTICAL | wx.ALIGN_LEFT | wx.ALL, 5) |
---|
| 796 | sizer.Add(pbLabel, 0, wx.ALIGN_CENTER_VERTICAL | wx.ALIGN_LEFT | wx.ALL, 5) |
---|
| 797 | sizer.Add(self.pbSpin, 0, wx.ALIGN_CENTER_VERTICAL | wx.ALIGN_LEFT | wx.ALL, 5) |
---|
| 798 | sizer.Add(bridgeIPLabel, 0, wx.ALIGN_CENTER_VERTICAL | wx.ALIGN_LEFT | wx.ALL, 5) |
---|
| 799 | sizer.Add(self.bridgeIPText, 0, wx.ALIGN_CENTER_VERTICAL | wx.ALIGN_LEFT) |
---|
| 800 | sizer.Add(bridgePortLabel, 0, wx.ALIGN_CENTER_VERTICAL | wx.ALIGN_LEFT | wx.ALL, 5) |
---|
| 801 | sizer.Add(self.bridgePortText, 0, wx.ALIGN_CENTER_VERTICAL | wx.ALIGN_LEFT) |
---|
| 802 | sizer.AddGrowableCol(1) |
---|
| 803 | |
---|
| 804 | return sizer |
---|
| 805 | |
---|
| 806 | |
---|
| 807 | def OnFoldBtn(self, sectionId, collapse): |
---|
| 808 | self.confSizer.Show(self.configSizers[sectionId], not collapse, True) |
---|
| 809 | self.Fit() |
---|
| 810 | |
---|
| 811 | |
---|
| 812 | def OnParallelCheck(self, evt): |
---|
| 813 | self.nodeNumSpin.Enable( self.parallelCheck.IsChecked() ) |
---|
| 814 | self.masterIPText.Enable( self.parallelCheck.IsChecked() ) |
---|
| 815 | if not self.parallelCheck.IsChecked(): |
---|
| 816 | self.nodeNumSpin.SetValue(1) |
---|
| 817 | self.currentConfig.setNodeNum(1) |
---|
| 818 | |
---|
| 819 | |
---|
| 820 | def OnAddConfig(self, evt): |
---|
| 821 | """ add a new configuration for the currently selected app """ |
---|
| 822 | |
---|
| 823 | # an app must be selected first |
---|
| 824 | appName = self.appsList.GetStringSelection() |
---|
| 825 | if appName == "": |
---|
| 826 | wx.MessageBox("Please select an application first", "Error", parent=self) |
---|
| 827 | return |
---|
| 828 | app = self.configs.getApp(appName) |
---|
| 829 | |
---|
| 830 | # get the config name, do nothing if cancel pressed |
---|
| 831 | configName = wx.GetTextFromUser("Enter new configuration name", "Config Name", parent=self) |
---|
| 832 | if configName == "": return |
---|
| 833 | if configName in app.getAllConfigNames(): |
---|
| 834 | wx.MessageBox("Configuration with that name already exists", "Error", parent=self) |
---|
| 835 | return |
---|
| 836 | |
---|
| 837 | # add the new config and clear the config fields |
---|
| 838 | conf = OneConfig(configName, appName) |
---|
| 839 | app.addConfig(conf) |
---|
| 840 | self.ClearConfig() |
---|
| 841 | self.currentConfig = conf |
---|
| 842 | self.configCombo.Append(configName) |
---|
| 843 | self.configCombo.SetStringSelection(configName) |
---|
| 844 | |
---|
| 845 | |
---|
| 846 | def OnDelConfig(self, evt): |
---|
| 847 | # an app must be selected first |
---|
| 848 | appName = self.appsList.GetStringSelection() |
---|
| 849 | if appName == "": |
---|
| 850 | wx.MessageBox("Please select an application first", "Error", parent=self) |
---|
| 851 | return |
---|
| 852 | app = self.configs.getApp(appName) |
---|
| 853 | |
---|
| 854 | # get the config name, do nothing if cancel pressed |
---|
| 855 | configName = self.configCombo.GetValue() |
---|
| 856 | if configName == "": return |
---|
| 857 | |
---|
| 858 | # there must be at least one config per app |
---|
| 859 | if len(app.getAllConfigNames()) < 2: |
---|
| 860 | wx.MessageBox("Cannot delete the last configuration. There must be at least one configuration per application.", "Cannot Delete", parent=self) |
---|
| 861 | return |
---|
| 862 | |
---|
| 863 | # add the new config and clear the config fields |
---|
| 864 | app.delConfig(configName) |
---|
| 865 | self.configCombo.Delete(self.configCombo.FindString(configName)) |
---|
| 866 | self.configCombo.SetValue("") |
---|
| 867 | self.ClearConfig() |
---|
| 868 | self.currentConfig = None |
---|
| 869 | |
---|
| 870 | |
---|
| 871 | def OnCopyConfig(self, evt): |
---|
| 872 | # an app must be selected first |
---|
| 873 | appName = self.appsList.GetStringSelection() |
---|
| 874 | if appName == "": |
---|
| 875 | wx.MessageBox("Please select an application first", "Error", parent=self) |
---|
| 876 | return |
---|
| 877 | app = self.configs.getApp(appName) |
---|
| 878 | |
---|
| 879 | # get the config name, do nothing if cancel pressed |
---|
| 880 | configName = self.configCombo.GetValue() |
---|
| 881 | if configName == "": return |
---|
| 882 | |
---|
| 883 | # get the new config name, do nothing if cancel pressed |
---|
| 884 | newConfigName = wx.GetTextFromUser("Enter new configuration name", "Config Name", parent=self) |
---|
| 885 | if newConfigName == "": return |
---|
| 886 | if newConfigName in app.getAllConfigNames(): |
---|
| 887 | wx.MessageBox("Configuration with that name already exists", "Error", parent=self) |
---|
| 888 | return |
---|
| 889 | |
---|
| 890 | # copy the old config, change its name and add it to the app |
---|
| 891 | conf = copy.deepcopy( app.getConfig(configName) ) |
---|
| 892 | conf.setName(newConfigName) |
---|
| 893 | app.addConfig(conf) |
---|
| 894 | |
---|
| 895 | # select the new config |
---|
| 896 | self.configCombo.Append(newConfigName) |
---|
| 897 | self.configCombo.SetStringSelection(newConfigName) |
---|
| 898 | self.__SetConfig(conf) |
---|
| 899 | |
---|
| 900 | |
---|
| 901 | def OnAppList(self, evt): |
---|
| 902 | """ refill configCombo, select the first one and fill the fields for it""" |
---|
| 903 | a = evt.GetString() |
---|
| 904 | if not a: return |
---|
| 905 | self.configCombo.Clear() |
---|
| 906 | for c in self.configs.getApp(a).getAllConfigNames(): |
---|
| 907 | self.configCombo.Append(c) |
---|
| 908 | self.configCombo.SetSelection(0) |
---|
| 909 | conf = self.configs.getConfig(a, self.configCombo.GetString(0)) |
---|
| 910 | self.__SetConfig(conf) |
---|
| 911 | |
---|
| 912 | |
---|
| 913 | def OnConfigCombo(self, evt): |
---|
| 914 | configName = self.configCombo.GetValue() |
---|
| 915 | appName = self.appsList.GetStringSelection() |
---|
| 916 | c = self.configs.getConfig(appName, configName) |
---|
| 917 | self.__SetConfig(c) |
---|
| 918 | |
---|
| 919 | |
---|
| 920 | def __SetConfig(self, conf): |
---|
| 921 | """ fill all the widgets with correct values for this configuration """ |
---|
| 922 | self.currentConfig = conf |
---|
| 923 | |
---|
| 924 | self.staticCheck.SetValue( conf.getStaticApp() ) |
---|
| 925 | |
---|
| 926 | # execution |
---|
| 927 | self.dirText.SetValue( conf.getBinDir() ) |
---|
| 928 | self.machineText.SetValue( conf.getTargetMachine() ) |
---|
| 929 | self.appText.SetValue( conf.getCommand() ) |
---|
| 930 | |
---|
| 931 | # size and pos |
---|
| 932 | self.wText.SetValue( str(conf.getSize()[0]) ) |
---|
| 933 | self.hText.SetValue( str(conf.getSize()[1]) ) |
---|
| 934 | self.yText.SetValue( str(conf.getPosition()[1]) ) |
---|
| 935 | self.xText.SetValue( str(conf.getPosition()[0]) ) |
---|
| 936 | |
---|
| 937 | # parallel section |
---|
| 938 | if conf.getNodeNum() == 1: |
---|
| 939 | self.parallelCheck.SetValue(False) |
---|
| 940 | self.nodeNumSpin.SetValue(1) |
---|
| 941 | self.nodeNumSpin.Enable(False) |
---|
| 942 | self.masterIPText.Enable(False) |
---|
| 943 | else: |
---|
| 944 | self.parallelCheck.SetValue(True) |
---|
| 945 | self.nodeNumSpin.SetValue( conf.getNodeNum() ) |
---|
| 946 | if conf.getMasterIP(): # could be none |
---|
| 947 | self.masterIPText.SetValue( conf.getMasterIP() ) |
---|
| 948 | self.nodeNumSpin.Enable(True) |
---|
| 949 | self.masterIPText.Enable(True) |
---|
| 950 | |
---|
| 951 | |
---|
| 952 | # advanced |
---|
| 953 | self.pbSpin.SetValue( conf.getBlockSize()[0] ) |
---|
| 954 | self.bridgeIPText.SetValue( conf.getBridgeIP() ) |
---|
| 955 | self.bridgePortText.SetValue( conf.getBridgePort() ) |
---|
| 956 | |
---|
| 957 | |
---|
| 958 | def OnAppAdd(self, evt): |
---|
| 959 | appName = wx.GetTextFromUser("Enter new application name.\nHas to be the same as the sage app configuration file the application\nis trying to load (e.g. \"atlantis\" is trying to load \"atlantis.conf\")", "App Name", parent=self) |
---|
| 960 | if appName == "": return |
---|
| 961 | if appName in self.configs.getAppList(): |
---|
| 962 | wx.MessageBox("Application already exists", "Error", parent=self) |
---|
| 963 | return |
---|
| 964 | |
---|
| 965 | configName = wx.GetTextFromUser("Enter first configuration name", "Config Name", parent=self) |
---|
| 966 | if configName == "": return |
---|
| 967 | self.ClearConfig(clearConfigNames=True) |
---|
| 968 | |
---|
| 969 | # add to the list of apps |
---|
| 970 | self.appsList.Append(appName) |
---|
| 971 | self.appsList.SetStringSelection(appName) |
---|
| 972 | |
---|
| 973 | # add to the list of configs |
---|
| 974 | self.configCombo.Append(configName) |
---|
| 975 | self.configCombo.SetStringSelection(configName) |
---|
| 976 | |
---|
| 977 | # change the actual datastructure |
---|
| 978 | self.configs.addNewApp(appName) |
---|
| 979 | conf = OneConfig(configName, appName) |
---|
| 980 | self.currentConfig = conf |
---|
| 981 | self.configs.getApp(appName).addConfig(conf) |
---|
| 982 | |
---|
| 983 | |
---|
| 984 | def OnAppDel(self, evt): |
---|
| 985 | appName = self.appsList.GetStringSelection() |
---|
| 986 | if appName == "": return #nothing selected |
---|
| 987 | self.configs.delApp(appName) |
---|
| 988 | self.ClearConfig(clearConfigNames=True) |
---|
| 989 | self.currentConfig = None |
---|
| 990 | self.appsList.Delete( self.appsList.FindString(appName) ) |
---|
| 991 | |
---|
| 992 | |
---|
| 993 | def ClearConfig(self, clearConfigNames=False): |
---|
| 994 | """ clears all the config fields to their default values """ |
---|
| 995 | self.pbSpin.SetValue(64) |
---|
| 996 | self.bridgeIPText.SetValue("") |
---|
| 997 | self.bridgePortText.SetValue("") |
---|
| 998 | self.masterIPText.SetValue("") |
---|
| 999 | self.nodeNumSpin.SetValue(1) |
---|
| 1000 | self.parallelCheck.SetValue(False) |
---|
| 1001 | self.nodeNumSpin.Enable(False) |
---|
| 1002 | self.masterIPText.Enable(False) |
---|
| 1003 | self.xText.SetValue("100") |
---|
| 1004 | self.yText.SetValue("100") |
---|
| 1005 | self.hText.SetValue("1000") |
---|
| 1006 | self.wText.SetValue("1000") |
---|
| 1007 | self.staticCheck.SetValue(True) |
---|
| 1008 | self.dirText.SetValue("$SAGE_DIRECTORY/bin") |
---|
| 1009 | self.machineText.SetValue("127.0.0.1") |
---|
| 1010 | self.appText.SetValue("") |
---|
| 1011 | if clearConfigNames: |
---|
| 1012 | self.configCombo.Clear() |
---|
| 1013 | self.configCombo.SetValue("") |
---|
| 1014 | |
---|
| 1015 | |
---|
| 1016 | def OnPublicCheck(self, evt): |
---|
| 1017 | if self.reportCheck.IsChecked(): |
---|
| 1018 | self.hostText.Enable() |
---|
| 1019 | #self.portText.Enable() |
---|
| 1020 | else: |
---|
| 1021 | self.hostText.Disable() |
---|
| 1022 | #self.portText.Disable() |
---|
| 1023 | |
---|
| 1024 | |
---|
| 1025 | #### KILL FOCUS EVENT HANDLERS (for saving config data right away) |
---|
| 1026 | |
---|
| 1027 | def OnStaticFocus(self, evt): |
---|
| 1028 | if self.currentConfig: |
---|
| 1029 | self.currentConfig.setStaticApp(self.staticCheck.IsChecked()) |
---|
| 1030 | |
---|
| 1031 | def OnNodeNumFocus(self, evt): |
---|
| 1032 | if self.currentConfig: |
---|
| 1033 | self.currentConfig.setNodeNum(self.nodeNumSpin.GetValue()) |
---|
| 1034 | |
---|
| 1035 | def OnMasterIPFocus(self, evt): |
---|
| 1036 | if self.currentConfig: |
---|
| 1037 | self.currentConfig.setMasterIP(self.masterIPText.GetValue()) |
---|
| 1038 | |
---|
| 1039 | def OnAppTextFocus(self, evt): |
---|
| 1040 | if self.currentConfig: |
---|
| 1041 | self.currentConfig.setCommand(self.appText.GetValue()) |
---|
| 1042 | |
---|
| 1043 | def OnDirTextFocus(self, evt): |
---|
| 1044 | if self.currentConfig: |
---|
| 1045 | self.currentConfig.setBinDir(self.dirText.GetValue()) |
---|
| 1046 | |
---|
| 1047 | def OnMachineTextFocus(self, evt): |
---|
| 1048 | if self.currentConfig: |
---|
| 1049 | self.currentConfig.setTargetMachine(self.machineText.GetValue()) |
---|
| 1050 | |
---|
| 1051 | def OnSizeTextFocus(self, evt): |
---|
| 1052 | if self.currentConfig: |
---|
| 1053 | self.currentConfig.setSize((int(self.wText.GetValue()), |
---|
| 1054 | int(self.hText.GetValue()))) |
---|
| 1055 | |
---|
| 1056 | def OnPosTextFocus(self, evt): |
---|
| 1057 | if self.currentConfig: |
---|
| 1058 | self.currentConfig.setPosition((int(self.xText.GetValue()), |
---|
| 1059 | int(self.yText.GetValue()))) |
---|
| 1060 | |
---|
| 1061 | def OnPBSpinFocus(self, evt): |
---|
| 1062 | if self.currentConfig: |
---|
| 1063 | sz = self.pbSpin.GetValue() |
---|
| 1064 | self.currentConfig.setBlockSize((sz,sz)) |
---|
| 1065 | |
---|
| 1066 | def OnBridgePortTextFocus(self, evt): |
---|
| 1067 | if self.currentConfig: |
---|
| 1068 | self.currentConfig.setBridgePort(self.bridgePortText.GetValue()) |
---|
| 1069 | |
---|
| 1070 | def OnBridgeIPTextFocus(self, evt): |
---|
| 1071 | if self.currentConfig: |
---|
| 1072 | self.currentConfig.setBridgeIP(self.bridgeIPText.GetValue()) |
---|
| 1073 | |
---|
| 1074 | |
---|
| 1075 | def OnClose(self, evt): |
---|
| 1076 | """ save stuff here """ |
---|
| 1077 | self.settings.doReport = self.reportCheck.IsChecked() |
---|
| 1078 | self.settings.server = self.hostText.GetValue() |
---|
| 1079 | #self.settings.port = self.portText.GetValue() |
---|
| 1080 | self.settings.inBG = self.run.GetValue() |
---|
| 1081 | saveSettings() |
---|
| 1082 | self.configs.writeConfig() |
---|
| 1083 | evt.Skip() |
---|
| 1084 | |
---|
| 1085 | |
---|
| 1086 | |
---|
| 1087 | |
---|
| 1088 | |
---|
| 1089 | |
---|
| 1090 | class FileServerFrame(ComponentFrame): |
---|
| 1091 | def __init__(self, parent): |
---|
| 1092 | ComponentFrame.__init__(self, parent, FILE_SERVER) |
---|
| 1093 | |
---|
| 1094 | # for reading the config file |
---|
| 1095 | self.types ={} |
---|
| 1096 | self.viewers = {} |
---|
| 1097 | self.filesDir = "" |
---|
| 1098 | self.ReadConfigFile() |
---|
| 1099 | |
---|
| 1100 | self.MakeWidgets() |
---|
| 1101 | self.Show() |
---|
| 1102 | |
---|
| 1103 | |
---|
| 1104 | def MakeWidgets(self): |
---|
| 1105 | self.run = wx.CheckBox(self, wx.ID_ANY, "Run in background") |
---|
| 1106 | self.run.SetToolTipString(HELP_INBG) |
---|
| 1107 | self.run.SetValue(self.settings.inBG) |
---|
| 1108 | |
---|
| 1109 | self.mainSizer.Add(self.MakeConfigBox(), 1, wx.EXPAND | wx.ALL, 10) |
---|
| 1110 | self.mainSizer.Add(self.run, 0, wx.ALIGN_CENTER_HORIZONTAL | wx.ALIGN_BOTTOM | wx.ALL, 10) |
---|
| 1111 | ComponentFrame.MakeWidgets(self) |
---|
| 1112 | |
---|
| 1113 | |
---|
| 1114 | |
---|
| 1115 | def MakeConfigBox(self): |
---|
| 1116 | # the box |
---|
| 1117 | box = wx.StaticBox(self, wx.ID_ANY, "File Server Configuration:") |
---|
| 1118 | box.SetForegroundColour(wx.BLUE) |
---|
| 1119 | makeBiggerBoldFont( box ) |
---|
| 1120 | boxSizer = wx.StaticBoxSizer( box, wx.VERTICAL ) |
---|
| 1121 | |
---|
| 1122 | # widgets |
---|
| 1123 | self.fbb = fb.DirBrowseButton(self, wx.ID_ANY, labelText='Library Root:', |
---|
| 1124 | dialogTitle="Choose Library Root", |
---|
| 1125 | startDirectory=opj(SAGE_DIR,"bin"), |
---|
| 1126 | toolTip=HELP_FS_ROOT) |
---|
| 1127 | self.fbb.SetValue(self.filesDir) |
---|
| 1128 | self.fbb.label.SetMinSize((80, -1)) |
---|
| 1129 | self.fbb.SetMinSize((600,-1)) |
---|
| 1130 | |
---|
| 1131 | # types label and list |
---|
| 1132 | typesLabel = wx.StaticText(self, wx.ID_ANY, "File types:") |
---|
| 1133 | self.typesList = wx.ListBox(self, wx.ID_ANY, choices=self.types.keys()) |
---|
| 1134 | self.typesList.Bind(wx.EVT_LISTBOX, self.OnList) |
---|
| 1135 | self.typesList.SetToolTipString(HELP_FS_TYPES) |
---|
| 1136 | |
---|
| 1137 | addBtn = wx.Button(self, wx.ID_ANY, "Add", style=wx.BU_EXACTFIT) |
---|
| 1138 | addBtn.Bind(wx.EVT_BUTTON, self.OnAdd) |
---|
| 1139 | delBtn = wx.Button(self, wx.ID_ANY, "Delete", style=wx.BU_EXACTFIT) |
---|
| 1140 | delBtn.Bind(wx.EVT_BUTTON, self.OnDel) |
---|
| 1141 | |
---|
| 1142 | btnSizer = wx.BoxSizer(wx.HORIZONTAL) |
---|
| 1143 | btnSizer.Add(addBtn, 1, wx.ALIGN_CENTER | wx.ALL, 4) |
---|
| 1144 | btnSizer.Add(delBtn, 1, wx.ALIGN_CENTER | wx.RIGHT | wx.TOP | wx.BOTTOM, 4) |
---|
| 1145 | |
---|
| 1146 | typesSizer = wx.BoxSizer(wx.VERTICAL) |
---|
| 1147 | typesSizer.Add(typesLabel, 0, wx.EXPAND | wx.ALIGN_LEFT | wx.ALL, 5) |
---|
| 1148 | typesSizer.Add(self.typesList, 1, wx.EXPAND | wx.ALIGN_LEFT | wx.ALL, 5) |
---|
| 1149 | typesSizer.Add(btnSizer, 0, wx.EXPAND | wx.ALIGN_CENTER_HORIZONTAL | wx.ALL, 1) |
---|
| 1150 | |
---|
| 1151 | |
---|
| 1152 | # details (extensions and application) |
---|
| 1153 | extLabel = wx.StaticText(self, wx.ID_ANY, "File extensions:") |
---|
| 1154 | self.extText = wx.TextCtrl(self, wx.ID_ANY) |
---|
| 1155 | self.extText.Bind(wx.EVT_KILL_FOCUS, self.OnExtText) |
---|
| 1156 | self.extText.SetToolTipString(HELP_FS_EXT) |
---|
| 1157 | |
---|
| 1158 | appLabel = wx.StaticText(self, wx.ID_ANY, "Run with application (and any optional arguments):") |
---|
| 1159 | self.appText = wx.TextCtrl(self, wx.ID_ANY) |
---|
| 1160 | self.appText.Bind(wx.EVT_KILL_FOCUS, self.OnAppText) |
---|
| 1161 | self.appText.SetToolTipString(HELP_FS_APP) |
---|
| 1162 | |
---|
| 1163 | detailSizer = wx.BoxSizer(wx.VERTICAL) |
---|
| 1164 | detailSizer.Add(extLabel, 0, wx.EXPAND | wx.ALIGN_LEFT | wx.ALL, 5) |
---|
| 1165 | detailSizer.Add(self.extText, 0, wx.ALIGN_LEFT | wx.EXPAND | wx.LEFT | wx.RIGHT | wx.BOTTOM, 5) |
---|
| 1166 | detailSizer.Add(appLabel, 0, wx.EXPAND | wx.ALIGN_LEFT | wx.ALL, 5) |
---|
| 1167 | detailSizer.Add(self.appText, 0, wx.ALIGN_LEFT | wx.EXPAND | wx.LEFT | wx.RIGHT | wx.BOTTOM, 5) |
---|
| 1168 | |
---|
| 1169 | # add the above two to the horizontal sizer |
---|
| 1170 | horSizer = wx.BoxSizer(wx.HORIZONTAL) |
---|
| 1171 | horSizer.Add(typesSizer, 0, wx.EXPAND | wx.ALIGN_LEFT | wx.ALIGN_TOP | wx.ALL, 10) |
---|
| 1172 | horSizer.Add(detailSizer, 1, wx.EXPAND | wx.ALIGN_LEFT | wx.ALIGN_TOP | wx.ALL, 10) |
---|
| 1173 | |
---|
| 1174 | # add widgets to the boxSizer |
---|
| 1175 | boxSizer.Add(self.fbb, 0, wx.EXPAND | wx.ALIGN_CENTER_VERTICAL | wx.ALIGN_LEFT | wx.ALL, 10) |
---|
| 1176 | boxSizer.Add(horSizer, 1, wx.EXPAND | wx.ALIGN_LEFT | wx.ALL, 5) |
---|
| 1177 | |
---|
| 1178 | return boxSizer |
---|
| 1179 | |
---|
| 1180 | |
---|
| 1181 | |
---|
| 1182 | def ReadConfigFile(self): |
---|
| 1183 | # reinitialize everything |
---|
| 1184 | self.types = {} |
---|
| 1185 | self.viewers = {} |
---|
| 1186 | |
---|
| 1187 | # read the config file |
---|
| 1188 | try: |
---|
| 1189 | f = open(self.settings.getConfigFilename(), "r") |
---|
| 1190 | except: |
---|
| 1191 | m = """ |
---|
| 1192 | File Server configuration file doesn't exist yet which usually means |
---|
| 1193 | that it hasn't been compiled yet. Please compile it first by running "make install" from |
---|
| 1194 | %s.""" % opj(SAGE_DIR,"app","FileViewer") |
---|
| 1195 | wx.MessageBox(m, "No FileServer") |
---|
| 1196 | self.Destroy() |
---|
| 1197 | return |
---|
| 1198 | |
---|
| 1199 | for line in f: |
---|
| 1200 | line = line.strip() |
---|
| 1201 | |
---|
| 1202 | # read root library directory |
---|
| 1203 | if line.startswith("FILES_DIR"): |
---|
| 1204 | self.filesDir = line.split("=")[1].strip() |
---|
| 1205 | |
---|
| 1206 | # read types |
---|
| 1207 | elif line.startswith("type:"): |
---|
| 1208 | line = line.split(":",1)[1] |
---|
| 1209 | (type, extensions) = line.split("=") |
---|
| 1210 | self.types[type.strip()] = extensions.strip().split(" ") |
---|
| 1211 | |
---|
| 1212 | # read apps for types |
---|
| 1213 | elif line.startswith("app:"): |
---|
| 1214 | line = line.split(":", 1)[1].strip() |
---|
| 1215 | (type, app) = line.split("=") |
---|
| 1216 | tpl = app.strip().split(" ", 1) |
---|
| 1217 | if len(tpl) == 1: params = "" |
---|
| 1218 | else: params = tpl[1].strip() |
---|
| 1219 | app = tpl[0].strip() |
---|
| 1220 | self.viewers[type.strip()] = (app, params) |
---|
| 1221 | f.close() |
---|
| 1222 | |
---|
| 1223 | |
---|
| 1224 | def WriteConfigFile(self): |
---|
| 1225 | try: |
---|
| 1226 | self.filesDir = self.fbb.GetValue() |
---|
| 1227 | |
---|
| 1228 | f = open(getUserPath("fileServer", "fileServer.conf"), "w") |
---|
| 1229 | f.write("FILES_DIR = "+ self.filesDir+"\n") |
---|
| 1230 | |
---|
| 1231 | f.write("\n#"+"----"*12+"\n\n") # separator |
---|
| 1232 | |
---|
| 1233 | # write types out and their extensions |
---|
| 1234 | for t, ext in self.types.iteritems(): |
---|
| 1235 | f.write("type:" + t + " = " + " ".join(ext) + "\n") |
---|
| 1236 | |
---|
| 1237 | f.write("\n#"+"----"*12+"\n\n") # separator |
---|
| 1238 | |
---|
| 1239 | # write apps out and their parameters |
---|
| 1240 | for t, appTuple in self.viewers.iteritems(): |
---|
| 1241 | f.write("app:"+ t + " = " + " ".join(appTuple) + "\n") |
---|
| 1242 | |
---|
| 1243 | f.close() |
---|
| 1244 | except: |
---|
| 1245 | print " ***** Error while writing file server config file" |
---|
| 1246 | print "".join(tb.format_exception(sys.exc_info()[0], sys.exc_info()[1], sys.exc_info()[2])) |
---|
| 1247 | return False |
---|
| 1248 | |
---|
| 1249 | |
---|
| 1250 | def OnAdd(self, evt): |
---|
| 1251 | newType = wx.GetTextFromUser("Enter new file type to the file library:", "New Type", parent=self) |
---|
| 1252 | if newType != "": |
---|
| 1253 | if newType in self.types: |
---|
| 1254 | wx.MessageBox("File type already exists", "Error", parent=self) |
---|
| 1255 | return |
---|
| 1256 | self.extText.Clear() |
---|
| 1257 | self.appText.Clear() |
---|
| 1258 | self.types[newType] = [] |
---|
| 1259 | self.viewers[newType] = () |
---|
| 1260 | self.typesList.AppendAndEnsureVisible(newType) |
---|
| 1261 | self.typesList.SetStringSelection(newType) |
---|
| 1262 | |
---|
| 1263 | |
---|
| 1264 | def OnDel(self, evt): |
---|
| 1265 | t = self.typesList.GetStringSelection() |
---|
| 1266 | if t != "": |
---|
| 1267 | self.extText.Clear() |
---|
| 1268 | self.appText.Clear() |
---|
| 1269 | del self.types[t] |
---|
| 1270 | del self.viewers[t] |
---|
| 1271 | self.typesList.Delete( self.typesList.FindString(t) ) |
---|
| 1272 | |
---|
| 1273 | |
---|
| 1274 | def OnList(self, evt): |
---|
| 1275 | t = evt.GetString() |
---|
| 1276 | self.extText.SetValue(" ".join(self.types[t])) |
---|
| 1277 | self.appText.SetValue(" ".join(self.viewers[t])) |
---|
| 1278 | |
---|
| 1279 | |
---|
| 1280 | def OnAppText(self, evt): |
---|
| 1281 | """ gets called when the text ctrl loses focus so we save the data """ |
---|
| 1282 | t = self.typesList.GetStringSelection() |
---|
| 1283 | tpl = self.appText.GetValue().strip().split(" ", 1) |
---|
| 1284 | if len(tpl) == 1: params = "" |
---|
| 1285 | else: params = tpl[1].strip() |
---|
| 1286 | app = tpl[0].strip() |
---|
| 1287 | self.viewers[t] = (app, params) |
---|
| 1288 | |
---|
| 1289 | |
---|
| 1290 | def OnExtText(self, evt): |
---|
| 1291 | """ gets called when the text ctrl loses focus so we save the data """ |
---|
| 1292 | t = self.typesList.GetStringSelection() |
---|
| 1293 | self.types[t] = self.extText.GetValue().strip().split(' ') |
---|
| 1294 | |
---|
| 1295 | |
---|
| 1296 | def OnClose(self, evt): |
---|
| 1297 | """ save stuff here """ |
---|
| 1298 | self.settings.inBG = self.run.GetValue() |
---|
| 1299 | self.WriteConfigFile() |
---|
| 1300 | saveSettings() |
---|
| 1301 | evt.Skip() |
---|
| 1302 | |
---|
| 1303 | |
---|
| 1304 | |
---|
| 1305 | |
---|
| 1306 | |
---|
| 1307 | |
---|
| 1308 | class SageProxyFrame(ComponentFrame): |
---|
| 1309 | def __init__(self, parent): |
---|
| 1310 | ComponentFrame.__init__(self, parent, SAGE_PROXY) |
---|
| 1311 | self.MakeWidgets() |
---|
| 1312 | self.Show() |
---|
| 1313 | |
---|
| 1314 | |
---|
| 1315 | def MakeWidgets(self): |
---|
| 1316 | # add the boxes to the main sizer |
---|
| 1317 | self.mainSizer.Add(self.MakeConnectionBox(), 0, wx.EXPAND | wx.ALL, 10) |
---|
| 1318 | self.mainSizer.Add(self.MakePasswordBox(), 0, wx.EXPAND | wx.ALL, 10) |
---|
| 1319 | ComponentFrame.MakeWidgets(self) |
---|
| 1320 | |
---|
| 1321 | |
---|
| 1322 | def MakeConnectionBox(self): |
---|
| 1323 | # sage connection box |
---|
| 1324 | box = wx.StaticBox(self, wx.ID_ANY, "Run Proxy for SAGE on:") |
---|
| 1325 | box.SetForegroundColour(wx.BLUE) |
---|
| 1326 | makeBiggerBoldFont( box ) |
---|
| 1327 | boxSizer = wx.StaticBoxSizer( box, wx.HORIZONTAL ) |
---|
| 1328 | |
---|
| 1329 | # widgets |
---|
| 1330 | hostLabel = wx.StaticText(self, wx.ID_ANY, "Hostname / IP:") |
---|
| 1331 | self.hostText = wx.TextCtrl(self, wx.ID_ANY, self.settings.host) |
---|
| 1332 | self.hostText.SetToolTipString(HELP_SP_HOST) |
---|
| 1333 | self.hostText.SetMinSize((150, -1)) |
---|
| 1334 | |
---|
| 1335 | portLabel = wx.StaticText(self, wx.ID_ANY, "Port:") |
---|
| 1336 | self.portText = wx.TextCtrl(self, wx.ID_ANY, str(self.settings.port)) |
---|
| 1337 | self.portText.SetToolTipString(HELP_SP_PORT) |
---|
| 1338 | |
---|
| 1339 | # add widgets to the boxSizer |
---|
| 1340 | boxSizer.Add(hostLabel, 0, wx.ALIGN_CENTER_VERTICAL | wx.ALIGN_LEFT | wx.ALL, 5) |
---|
| 1341 | boxSizer.Add(self.hostText, 0, wx.ALIGN_CENTER_VERTICAL | wx.ALIGN_LEFT | wx.RIGHT | wx.BOTTOM | wx.TOP, 5) |
---|
| 1342 | boxSizer.Add((10,10)) |
---|
| 1343 | boxSizer.Add(portLabel, 0, wx.ALIGN_CENTER_VERTICAL | wx.ALIGN_LEFT | wx.ALL, 5) |
---|
| 1344 | boxSizer.Add(self.portText, 0, wx.ALIGN_CENTER_VERTICAL | wx.ALIGN_LEFT | wx.RIGHT | wx.BOTTOM | wx.TOP, 5) |
---|
| 1345 | |
---|
| 1346 | return boxSizer |
---|
| 1347 | |
---|
| 1348 | |
---|
| 1349 | def MakePasswordBox(self): |
---|
| 1350 | # password box |
---|
| 1351 | box = wx.StaticBox(self, wx.ID_ANY, "Password for SAGE Web UI access:") |
---|
| 1352 | box.SetForegroundColour(wx.BLUE) |
---|
| 1353 | makeBiggerBoldFont( box ) |
---|
| 1354 | boxSizer = wx.StaticBoxSizer( box, wx.HORIZONTAL ) |
---|
| 1355 | |
---|
| 1356 | # widgets |
---|
| 1357 | passLabel = wx.StaticText(self, wx.ID_ANY, "Password:") |
---|
| 1358 | self.passText = wx.TextCtrl(self, wx.ID_ANY, self.settings.password) |
---|
| 1359 | self.passText.SetToolTipString(HELP_SP_PASS) |
---|
| 1360 | self.passText.SetMinSize((150, -1)) |
---|
| 1361 | |
---|
| 1362 | # add widgets to the boxSizer |
---|
| 1363 | boxSizer.Add(passLabel, 0, wx.ALIGN_CENTER_VERTICAL | wx.ALIGN_LEFT | wx.ALL, 5) |
---|
| 1364 | boxSizer.Add(self.passText, 0, wx.ALIGN_CENTER_VERTICAL | wx.ALIGN_LEFT | wx.RIGHT | wx.BOTTOM | wx.TOP, 5) |
---|
| 1365 | |
---|
| 1366 | return boxSizer |
---|
| 1367 | |
---|
| 1368 | |
---|
| 1369 | def OnClose(self, evt): |
---|
| 1370 | """ save stuff here """ |
---|
| 1371 | self.settings.host = self.hostText.GetValue() |
---|
| 1372 | self.settings.port = int(self.portText.GetValue()) |
---|
| 1373 | self.settings.password = self.passText.GetValue() |
---|
| 1374 | saveSettings() |
---|
| 1375 | evt.Skip() |
---|
| 1376 | |
---|
| 1377 | |
---|
| 1378 | |
---|
| 1379 | |
---|
| 1380 | class SageUIFrame(ComponentFrame): |
---|
| 1381 | def __init__(self, parent): |
---|
| 1382 | ComponentFrame.__init__(self, parent, SAGE_UI) |
---|
| 1383 | self.MakeWidgets() |
---|
| 1384 | self.Show() |
---|
| 1385 | |
---|
| 1386 | |
---|
| 1387 | def MakeWidgets(self): |
---|
| 1388 | # make the box first (this is REQUIRED since the box is a |
---|
| 1389 | # sibling of the widgets inside it and not their parent) |
---|
| 1390 | |
---|
| 1391 | box = wx.StaticBox(self, wx.ID_ANY, "Connection Manager") |
---|
| 1392 | box.SetForegroundColour(wx.BLUE) |
---|
| 1393 | makeBiggerBoldFont( box ) |
---|
| 1394 | boxSizer = wx.StaticBoxSizer( box, wx.HORIZONTAL ) |
---|
| 1395 | |
---|
| 1396 | # widgets |
---|
| 1397 | hostLabel = wx.StaticText(self, wx.ID_ANY, "Hostname / IP:") |
---|
| 1398 | self.hostText = wx.TextCtrl(self, wx.ID_ANY, self.settings.host) |
---|
| 1399 | self.hostText.SetToolTipString(HELP_SU_HOST) |
---|
| 1400 | self.hostText.SetMinSize((150, -1)) |
---|
| 1401 | |
---|
| 1402 | portLabel = wx.StaticText(self, wx.ID_ANY, "Port:") |
---|
| 1403 | self.portText = wx.TextCtrl(self, wx.ID_ANY, str(self.settings.port)) |
---|
| 1404 | self.portText.SetToolTipString(HELP_SU_HOST) |
---|
| 1405 | |
---|
| 1406 | autologinLabel = wx.StaticText(self, wx.ID_ANY, "Autologin to (enter sage session name):") |
---|
| 1407 | self.autologinText = wx.TextCtrl(self, wx.ID_ANY, self.settings.autologinMachine) |
---|
| 1408 | self.autologinText.SetToolTipString(HELP_SU_AUTOLOGIN) |
---|
| 1409 | self.autologinText.SetMinSize((150, -1)) |
---|
| 1410 | |
---|
| 1411 | # add widgets to the boxSizer |
---|
| 1412 | boxSizer.Add(hostLabel, 0, wx.ALIGN_CENTER_VERTICAL | wx.ALIGN_LEFT | wx.ALL, 5) |
---|
| 1413 | boxSizer.Add(self.hostText, 0, wx.ALIGN_CENTER_VERTICAL | wx.ALIGN_LEFT | wx.RIGHT | wx.BOTTOM | wx.TOP, 5) |
---|
| 1414 | boxSizer.Add((10,10)) |
---|
| 1415 | boxSizer.Add(portLabel, 0, wx.ALIGN_CENTER_VERTICAL | wx.ALIGN_LEFT | wx.ALL, 5) |
---|
| 1416 | boxSizer.Add(self.portText, 0, wx.ALIGN_CENTER_VERTICAL | wx.ALIGN_LEFT | wx.RIGHT | wx.BOTTOM | wx.TOP, 5) |
---|
| 1417 | |
---|
| 1418 | # autologin sizer |
---|
| 1419 | loginSizer = wx.BoxSizer(wx.HORIZONTAL) |
---|
| 1420 | loginSizer.Add(autologinLabel, 0, wx.ALIGN_CENTER_VERTICAL | wx.ALIGN_LEFT | wx.ALL, 5) |
---|
| 1421 | loginSizer.Add(self.autologinText, 0, wx.ALIGN_CENTER_VERTICAL | wx.ALIGN_LEFT | wx.ALL, 5) |
---|
| 1422 | |
---|
| 1423 | # add the box to the main sizer |
---|
| 1424 | self.mainSizer.Add(boxSizer, 0, wx.EXPAND | wx.ALL, 10) |
---|
| 1425 | self.mainSizer.Add(loginSizer, 0, wx.EXPAND | wx.ALL, 10) |
---|
| 1426 | ComponentFrame.MakeWidgets(self) # call this last |
---|
| 1427 | |
---|
| 1428 | |
---|
| 1429 | def OnClose(self, evt): |
---|
| 1430 | """ save stuff here """ |
---|
| 1431 | self.settings.host = self.hostText.GetValue() |
---|
| 1432 | self.settings.port = int(self.portText.GetValue()) |
---|
| 1433 | self.settings.autologinMachine = self.autologinText.GetValue() |
---|
| 1434 | saveSettings() |
---|
| 1435 | evt.Skip() |
---|
| 1436 | |
---|
| 1437 | |
---|
| 1438 | |
---|
| 1439 | class SageFrame(ComponentFrame): |
---|
| 1440 | def __init__(self, parent): |
---|
| 1441 | ComponentFrame.__init__(self, parent, SAGE) |
---|
| 1442 | self.MakeWidgets() |
---|
| 1443 | self.Show() |
---|
| 1444 | |
---|
| 1445 | |
---|
| 1446 | def MakeWidgets(self): |
---|
| 1447 | box1 = wx.StaticBox(self, wx.ID_ANY, "ON SAGE STARTUP") |
---|
| 1448 | box1.SetForegroundColour(wx.BLUE) |
---|
| 1449 | makeBiggerBoldFont( box1 ) |
---|
| 1450 | box1Sizer = wx.StaticBoxSizer( box1, wx.VERTICAL ) |
---|
| 1451 | |
---|
| 1452 | box2 = wx.StaticBox(self, wx.ID_ANY, "ON SAGE SHUTDOWN") |
---|
| 1453 | box2.SetForegroundColour(wx.BLUE) |
---|
| 1454 | makeBiggerBoldFont( box2 ) |
---|
| 1455 | box2Sizer = wx.StaticBoxSizer( box2, wx.VERTICAL ) |
---|
| 1456 | |
---|
| 1457 | # start stuff |
---|
| 1458 | startLabel = wx.StaticText(self, wx.ID_ANY, "Specify any additional commands to be executed before SAGE starts") |
---|
| 1459 | self.start = wx.TextCtrl(self, wx.ID_ANY, self.settings.onStart, style=wx.TE_MULTILINE) |
---|
| 1460 | self.start.SetToolTipString(HELP_S_START) |
---|
| 1461 | box1Sizer.AddSpacer((10,10)) |
---|
| 1462 | box1Sizer.Add(startLabel, 0, wx.EXPAND | wx.ALIGN_LEFT | wx.ALL, 5) |
---|
| 1463 | box1Sizer.Add(self.start, 1, wx.EXPAND | wx.ALIGN_LEFT | wx.ALL, 5) |
---|
| 1464 | |
---|
| 1465 | # stop stuff |
---|
| 1466 | stopLabel = wx.StaticText(self, wx.ID_ANY, "Specify any additional commands to be executed after SAGE is stopped") |
---|
| 1467 | self.stop = wx.TextCtrl(self, wx.ID_ANY, self.settings.onStop, style=wx.TE_MULTILINE) |
---|
| 1468 | self.stop.SetToolTipString(HELP_S_STOP) |
---|
| 1469 | procLabel = wx.StaticText(self, wx.ID_ANY, "List all processes to be killed on the nodes and the master during SAGE shutdown") |
---|
| 1470 | self.proc = wx.TextCtrl(self, wx.ID_ANY, self.settings.toKill) |
---|
| 1471 | self.proc.SetToolTipString(HELP_S_PROC) |
---|
| 1472 | |
---|
| 1473 | box2Sizer.AddSpacer((10,10)) |
---|
| 1474 | box2Sizer.Add(stopLabel, 0, wx.EXPAND | wx.ALIGN_LEFT | wx.ALL, 5) |
---|
| 1475 | box2Sizer.Add(self.stop, 1, wx.EXPAND | wx.ALIGN_LEFT | wx.ALL, 5) |
---|
| 1476 | box2Sizer.AddSpacer((20,20)) |
---|
| 1477 | box2Sizer.Add(procLabel, 0, wx.EXPAND | wx.ALIGN_LEFT | wx.ALL, 5) |
---|
| 1478 | box2Sizer.Add(self.proc, 0, wx.EXPAND | wx.ALIGN_LEFT | wx.ALL, 5) |
---|
| 1479 | |
---|
| 1480 | self.mainSizer.Add(box1Sizer, 1, wx.EXPAND | wx.ALL, 15) |
---|
| 1481 | self.mainSizer.Add(box2Sizer, 1, wx.EXPAND | wx.ALL, 15) |
---|
| 1482 | ComponentFrame.MakeWidgets(self) # call this last |
---|
| 1483 | |
---|
| 1484 | |
---|
| 1485 | def OnClose(self, evt): |
---|
| 1486 | """ save stuff here """ |
---|
| 1487 | self.settings.onStop = self.stop.GetValue().strip() |
---|
| 1488 | self.settings.onStart = self.start.GetValue().strip() |
---|
| 1489 | self.settings.toKill = self.proc.GetValue().strip() |
---|
| 1490 | saveSettings() |
---|
| 1491 | evt.Skip() |
---|
| 1492 | |
---|
| 1493 | |
---|
| 1494 | |
---|
| 1495 | |
---|
| 1496 | |
---|
| 1497 | ### |
---|
| 1498 | ### the following are the main frame UI components |
---|
| 1499 | ### |
---|
| 1500 | |
---|
| 1501 | class ComponentSummary(wx.Panel): |
---|
| 1502 | """ this is the container for one SAGE component... |
---|
| 1503 | it has 3 widgets: name, run checkbox and edit button |
---|
| 1504 | """ |
---|
| 1505 | def __init__(self, parent, componentType): |
---|
| 1506 | wx.Panel.__init__(self, parent, wx.ID_ANY, style=wx.SIMPLE_BORDER) |
---|
| 1507 | self.color = wx.Colour(252,172,130) |
---|
| 1508 | self.componentType = componentType |
---|
| 1509 | self.SetMinSize((250,70)) |
---|
| 1510 | self.SetMaxSize((250,70)) |
---|
| 1511 | self.settings = components[componentType].settings |
---|
| 1512 | self.MakeWidgets() |
---|
| 1513 | |
---|
| 1514 | # for selecting the component on click |
---|
| 1515 | self.Bind(wx.EVT_LEFT_DOWN, self.OnRunCheck) |
---|
| 1516 | self.name.Bind(wx.EVT_LEFT_DOWN, self.OnRunCheck) |
---|
| 1517 | self.SetBackgroundColour(self.color) |
---|
| 1518 | |
---|
| 1519 | # where the console output will be printed |
---|
| 1520 | # it's a child of the whole ComponentsPanel |
---|
| 1521 | # since it's placed inside a sizer there |
---|
| 1522 | self.output = wx.TextCtrl(self.GetParent().outputNotebook, wx.ID_ANY, style=wx.TE_MULTILINE | wx.TE_READONLY) |
---|
| 1523 | self.output.SetMinSize((800, 300)) |
---|
| 1524 | self.output.SetMaxLength(MAX_TEXT_LEN) |
---|
| 1525 | components[componentType].output = self.output |
---|
| 1526 | |
---|
| 1527 | # the process tied with the component |
---|
| 1528 | components[componentType].process = Process(componentType) |
---|
| 1529 | |
---|
| 1530 | |
---|
| 1531 | def ChangeColor(self, newColor): |
---|
| 1532 | self.color = newColor |
---|
| 1533 | self.SetBackgroundColour(self.color) |
---|
| 1534 | self.run.faceDnClr = self.color |
---|
| 1535 | self.Refresh() |
---|
| 1536 | |
---|
| 1537 | |
---|
| 1538 | def MakeWidgets(self): |
---|
| 1539 | # make all the widgets |
---|
| 1540 | self.MakeName() |
---|
| 1541 | self.MakeRun() |
---|
| 1542 | self.MakeEdit() |
---|
| 1543 | self.MakeStopBtn() |
---|
| 1544 | |
---|
| 1545 | # add the widgets to the sizers |
---|
| 1546 | vSizer = wx.BoxSizer(wx.VERTICAL) |
---|
| 1547 | hSizer = wx.BoxSizer(wx.HORIZONTAL) |
---|
| 1548 | hSizer2 = wx.BoxSizer(wx.HORIZONTAL) |
---|
| 1549 | |
---|
| 1550 | hSizer.Add(self.run, 0, wx.ALIGN_LEFT | wx.ALL, 0) |
---|
| 1551 | hSizer.Add(self.name, 1, wx.ALIGN_LEFT | wx.ALL, 5) |
---|
| 1552 | |
---|
| 1553 | hSizer2.Add(self.stopBtn, 0, wx.ALIGN_RIGHT | wx.RIGHT, 20) |
---|
| 1554 | hSizer2.Add(self.editBtn, 0, wx.ALIGN_RIGHT | wx.RIGHT, 3) |
---|
| 1555 | |
---|
| 1556 | vSizer.Add(hSizer, 1, wx.ALIGN_TOP | wx.ALIGN_LEFT | wx.ALL, 3) |
---|
| 1557 | vSizer.Add(hSizer2, 0, wx.ALIGN_BOTTOM | wx.ALIGN_RIGHT | wx.BOTTOM, 1) |
---|
| 1558 | |
---|
| 1559 | self.SetSizer(vSizer) |
---|
| 1560 | |
---|
| 1561 | |
---|
| 1562 | def MakeStopBtn(self): |
---|
| 1563 | self.stopBtn = buttons.GenBitmapButton(self, wx.ID_ANY, getStopBitmap(), style=wx.BORDER_NONE) |
---|
| 1564 | self.stopBtn.faceDnClr = self.color |
---|
| 1565 | self.stopBtn.SetBestSize((24,24)) |
---|
| 1566 | self.stopBtn.Bind(wx.EVT_BUTTON, self.OnStopBtn) |
---|
| 1567 | self.stopBtn.SetToolTipString(HELP_COMP_STOP) |
---|
| 1568 | |
---|
| 1569 | def MakeName(self): |
---|
| 1570 | self.name = wx.StaticText(self, wx.ID_ANY, self.componentType) |
---|
| 1571 | makeBoldFont(self.name) |
---|
| 1572 | try: self.name.Wrap(150) # wrap the text if longer than 150 pixels |
---|
| 1573 | except: pass |
---|
| 1574 | help = "" |
---|
| 1575 | if self.componentType == APP_LAUNCHER: |
---|
| 1576 | help = HELP_AL |
---|
| 1577 | elif self.componentType == FILE_SERVER: |
---|
| 1578 | help = HELP_FS |
---|
| 1579 | elif self.componentType == SAGE_UI: |
---|
| 1580 | help = HELP_SU |
---|
| 1581 | elif self.componentType == SAGE_PROXY: |
---|
| 1582 | help = HELP_SP |
---|
| 1583 | elif self.componentType == SAGE: |
---|
| 1584 | help = HELP_S |
---|
| 1585 | self.name.SetToolTipString(help) |
---|
| 1586 | self.SetToolTipString(help) |
---|
| 1587 | |
---|
| 1588 | |
---|
| 1589 | def MakeRun(self): |
---|
| 1590 | bmp = getRunBitmap(self.settings.doRun) |
---|
| 1591 | self.run = buttons.GenBitmapButton(self, wx.ID_ANY, bmp, style=wx.BORDER_NONE) |
---|
| 1592 | self.run.SetBitmapSelected(bmp) |
---|
| 1593 | self.run.Bind(wx.EVT_BUTTON, self.OnRunCheck) |
---|
| 1594 | self.run.SetToolTipString(HELP_RUN) |
---|
| 1595 | self.run.faceDnClr = self.color |
---|
| 1596 | |
---|
| 1597 | |
---|
| 1598 | def MakeEdit(self): |
---|
| 1599 | self.editBtn = wx.Button(self, wx.ID_ANY, "Settings") |
---|
| 1600 | self.editBtn.Bind(wx.EVT_BUTTON, self.OnEdit) |
---|
| 1601 | self.editBtn.SetToolTipString(HELP_EDIT) |
---|
| 1602 | |
---|
| 1603 | |
---|
| 1604 | def OnEdit(self, evt): |
---|
| 1605 | if self.componentType == APP_LAUNCHER: |
---|
| 1606 | frame = AppLauncherFrame(self) |
---|
| 1607 | elif self.componentType == FILE_SERVER: |
---|
| 1608 | frame = FileServerFrame(self) |
---|
| 1609 | elif self.componentType == SAGE_PROXY: |
---|
| 1610 | frame = SageProxyFrame(self) |
---|
| 1611 | elif self.componentType == SAGE_UI: |
---|
| 1612 | frame = SageUIFrame(self) |
---|
| 1613 | elif self.componentType == SAGE: |
---|
| 1614 | frame = SageFrame(self) |
---|
| 1615 | |
---|
| 1616 | |
---|
| 1617 | def OnRunCheck(self, evt): |
---|
| 1618 | self.settings.doRun = not self.settings.doRun # reverse the value |
---|
| 1619 | bmp = getRunBitmap(self.settings.doRun) |
---|
| 1620 | self.run.SetBitmapLabel(bmp, False) |
---|
| 1621 | self.run.SetBitmapSelected(bmp) |
---|
| 1622 | self.run.Refresh() |
---|
| 1623 | |
---|
| 1624 | |
---|
| 1625 | def OnStopBtn(self, evt): |
---|
| 1626 | components[self.componentType].process.stop() |
---|
| 1627 | |
---|
| 1628 | |
---|
| 1629 | |
---|
| 1630 | |
---|
| 1631 | |
---|
| 1632 | |
---|
| 1633 | class ComponentsPanel(scrolled.ScrolledPanel): |
---|
| 1634 | """ this holds the summaries for each component on the main frame """ |
---|
| 1635 | |
---|
| 1636 | def __init__(self, parent): |
---|
| 1637 | scrolled.ScrolledPanel.__init__(self, parent, wx.ID_ANY) |
---|
| 1638 | self.MakeWidgets() |
---|
| 1639 | |
---|
| 1640 | |
---|
| 1641 | def ChangeAllColors(self, newColor): |
---|
| 1642 | for c in self.compSummary.itervalues(): |
---|
| 1643 | c.ChangeColor(newColor) |
---|
| 1644 | |
---|
| 1645 | |
---|
| 1646 | def MakeWidgets(self): |
---|
| 1647 | mainSizer = wx.BoxSizer( wx.HORIZONTAL ) |
---|
| 1648 | compSizer = wx.BoxSizer( wx.VERTICAL ) |
---|
| 1649 | |
---|
| 1650 | # notebook |
---|
| 1651 | self.outputNotebook = wx.Notebook(self, wx.ID_ANY, style=wx.NO_BORDER) |
---|
| 1652 | |
---|
| 1653 | # component objects |
---|
| 1654 | self.compSummary = {} |
---|
| 1655 | for componentType, c in components.iteritems(): |
---|
| 1656 | self.compSummary[componentType] = ComponentSummary(self, componentType) |
---|
| 1657 | |
---|
| 1658 | # add components to the compSizer |
---|
| 1659 | label = wx.StaticText(self, wx.ID_ANY, "Components to Start:") |
---|
| 1660 | makeBoldFont(label) |
---|
| 1661 | compSizer.Add(label, 0, wx.EXPAND | wx.TOP | wx.LEFT, 10) |
---|
| 1662 | for cName in componentNames: |
---|
| 1663 | c = self.compSummary[cName] |
---|
| 1664 | compSizer.Add(c, 0, wx.ALIGN_CENTER_HORIZONTAL | wx.ALIGN_TOP | wx.ALL, 10) |
---|
| 1665 | self.outputNotebook.AddPage(c.output, cName) # add the notebook pages |
---|
| 1666 | |
---|
| 1667 | # run controls |
---|
| 1668 | self.runPanel = RunPanel(self) |
---|
| 1669 | compSizer.Add(self.runPanel, 1, wx.EXPAND | wx.ALIGN_CENTER_HORIZONTAL | wx.ALIGN_TOP | wx.ALL, 5) |
---|
| 1670 | |
---|
| 1671 | # create the output label and sizer |
---|
| 1672 | self.outLabel = wx.StaticText(self, wx.ID_ANY, "Output from:") |
---|
| 1673 | makeBoldFont(self.outLabel) |
---|
| 1674 | self.outSizer = wx.BoxSizer(wx.VERTICAL) |
---|
| 1675 | self.outSizer.Add(self.outLabel, 0, wx.EXPAND | wx.TOP | wx.LEFT, 15) |
---|
| 1676 | self.outSizer.Add(self.outputNotebook, 1, wx.EXPAND | wx.TOP | wx.LEFT | wx.BOTTOM, 5) |
---|
| 1677 | |
---|
| 1678 | # add the stuff to the main sizer |
---|
| 1679 | mainSizer.Add(compSizer, 0, wx.EXPAND | wx.ALIGN_LEFT | wx.ALL, 5) |
---|
| 1680 | mainSizer.Add(self.outSizer, 1, wx.EXPAND | wx.LEFT | wx.BOTTOM, 15) |
---|
| 1681 | |
---|
| 1682 | # select the default component |
---|
| 1683 | self.SetSizerAndFit(mainSizer) |
---|
| 1684 | self.SetAutoLayout(1) |
---|
| 1685 | self.SetupScrolling() |
---|
| 1686 | |
---|
| 1687 | |
---|
| 1688 | |
---|
| 1689 | |
---|
| 1690 | class RunPanel(wx.Panel): |
---|
| 1691 | """ the run panel on the main frame for starting and stopping sage """ |
---|
| 1692 | |
---|
| 1693 | def __init__(self, parent): |
---|
| 1694 | wx.Panel.__init__(self, parent, wx.ID_ANY) |
---|
| 1695 | self.MakeWidgets() |
---|
| 1696 | |
---|
| 1697 | |
---|
| 1698 | def MakeWidgets(self): |
---|
| 1699 | mainSizer = wx.BoxSizer( wx.VERTICAL ) |
---|
| 1700 | boxSizer = wx.BoxSizer( wx.HORIZONTAL ) |
---|
| 1701 | |
---|
| 1702 | # add components to the boxSizer |
---|
| 1703 | self.runBtn = wx.Button(self, 1, "START") |
---|
| 1704 | self.runBtn.Bind(wx.EVT_BUTTON, self.OnRun) |
---|
| 1705 | self.runBtn.Bind(wx.EVT_ENTER_WINDOW, self.OnMouseEnterWindow) |
---|
| 1706 | self.runBtn.Bind(wx.EVT_LEAVE_WINDOW, self.OnMouseLeaveWindow) |
---|
| 1707 | makeBiggerBoldFont(self.runBtn) |
---|
| 1708 | makeBiggerFont(self.runBtn) |
---|
| 1709 | |
---|
| 1710 | self.stopBtn = wx.Button(self, 2, "STOP") |
---|
| 1711 | self.stopBtn.Bind(wx.EVT_BUTTON, self.OnStop) |
---|
| 1712 | self.stopBtn.Bind(wx.EVT_ENTER_WINDOW, self.OnMouseEnterWindow) |
---|
| 1713 | self.stopBtn.Bind(wx.EVT_LEAVE_WINDOW, self.OnMouseLeaveWindow) |
---|
| 1714 | makeBiggerBoldFont(self.stopBtn) |
---|
| 1715 | makeBiggerFont(self.stopBtn) |
---|
| 1716 | |
---|
| 1717 | self.helpNote = wx.StaticText(self, wx.ID_ANY, "\n", style=wx.ALIGN_CENTRE) |
---|
| 1718 | self.helpNote.SetMinSize((-1, 30)) |
---|
| 1719 | |
---|
| 1720 | self.simpleBtn = hl.HyperLinkCtrl(self, wx.ID_ANY, "<- Simple Mode") |
---|
| 1721 | self.simpleBtn.SetBackgroundColour(self.GetBackgroundColour()) |
---|
| 1722 | self.simpleBtn.AutoBrowse(False) |
---|
| 1723 | self.simpleBtn.Bind(hl.EVT_HYPERLINK_LEFT, self.OnSimple) |
---|
| 1724 | |
---|
| 1725 | boxSizer.Add(self.runBtn, 0, wx.ALIGN_CENTER | wx.TOP | wx.RIGHT, 15) |
---|
| 1726 | boxSizer.Add(self.stopBtn, 0, wx.ALIGN_CENTER | wx.TOP | wx.LEFT, 15) |
---|
| 1727 | |
---|
| 1728 | mainSizer.Add(boxSizer, 0, wx.ALIGN_CENTER) |
---|
| 1729 | mainSizer.Add(self.helpNote, 0, wx.EXPAND | wx.ALIGN_CENTER_HORIZONTAL | wx.ALIGN_TOP | wx.ALL, 5) |
---|
| 1730 | mainSizer.AddSpacer((10,10), 1) |
---|
| 1731 | mainSizer.Add(self.simpleBtn, 0, wx.ALIGN_BOTTOM | wx.ALIGN_LEFT | wx.ALL, 10) |
---|
| 1732 | |
---|
| 1733 | self.SetSizerAndFit(mainSizer) |
---|
| 1734 | |
---|
| 1735 | |
---|
| 1736 | def OnSimple(self, evt): |
---|
| 1737 | wx.GetApp().GetTopWindow().advancedFrame.Hide() |
---|
| 1738 | wx.GetApp().GetTopWindow().Show() |
---|
| 1739 | |
---|
| 1740 | |
---|
| 1741 | def OnMouseEnterWindow(self, evt): |
---|
| 1742 | if evt.GetId() == 1: |
---|
| 1743 | self.helpNote.SetLabel("Start all the checked components\nthat are not already running.") |
---|
| 1744 | else: |
---|
| 1745 | self.helpNote.SetLabel("Stop all the components that are\nnot running in the background.") |
---|
| 1746 | evt.Skip() |
---|
| 1747 | |
---|
| 1748 | |
---|
| 1749 | def OnMouseLeaveWindow(self, evt): |
---|
| 1750 | self.helpNote.SetLabel("") |
---|
| 1751 | self.GetSizer().Layout() |
---|
| 1752 | evt.Skip() |
---|
| 1753 | |
---|
| 1754 | |
---|
| 1755 | def OnRun(self, evt): |
---|
| 1756 | """ start all the checked processes... but start sage before everything else |
---|
| 1757 | because some components need sage running already |
---|
| 1758 | """ |
---|
| 1759 | |
---|
| 1760 | # first start sage and then sleep for a few seconds |
---|
| 1761 | sage = components[SAGE] |
---|
| 1762 | if sage.settings.doRun: |
---|
| 1763 | sage.process.start() |
---|
| 1764 | time.sleep(2) |
---|
| 1765 | |
---|
| 1766 | # now start the rest of the components |
---|
| 1767 | for c in components.itervalues(): |
---|
| 1768 | if c.componentType != SAGE and c.settings.doRun: |
---|
| 1769 | c.process.start() |
---|
| 1770 | saveSettings() # to save the changed PIDs |
---|
| 1771 | |
---|
| 1772 | |
---|
| 1773 | def OnStop(self, evt): |
---|
| 1774 | for c in components.itervalues(): |
---|
| 1775 | if not c.settings.inBG: |
---|
| 1776 | c.process.stop() |
---|
| 1777 | saveSettings() # to save the changed PIDs |
---|
| 1778 | |
---|
| 1779 | |
---|
| 1780 | |
---|
| 1781 | |
---|
| 1782 | |
---|
| 1783 | class QuickFrame(wx.Frame): |
---|
| 1784 | def __init__(self): |
---|
| 1785 | wx.Frame.__init__(self, None, wx.ID_ANY, "SAGE Launcher", |
---|
| 1786 | style=wx.SYSTEM_MENU | wx.CAPTION | wx.CLOSE_BOX | wx.CLIP_CHILDREN) |
---|
| 1787 | self.SetBackgroundColour(wx.Colour(14,51,51)) |
---|
| 1788 | #self.SetClientSize((373, 315)) |
---|
| 1789 | self.SetMinSize((377, 315)) |
---|
| 1790 | self.MakeWidgets() |
---|
| 1791 | self.SetThemeEnabled(False) |
---|
| 1792 | self.SetIcon(getSageIcon()) |
---|
| 1793 | self.Bind(wx.EVT_CLOSE, self.OnClose) |
---|
| 1794 | self.Centre() |
---|
| 1795 | self.Show() |
---|
| 1796 | |
---|
| 1797 | |
---|
| 1798 | def MakeWidgets(self): |
---|
| 1799 | ms = wx.BoxSizer(wx.VERTICAL) |
---|
| 1800 | self.panel = wx.Panel(self, wx.ID_ANY) |
---|
| 1801 | self.panel.SetBackgroundColour(self.GetBackgroundColour()) |
---|
| 1802 | self.panel.Bind(wx.EVT_PAINT, self.OnPaint) |
---|
| 1803 | ms.Add(self.panel, 1, wx.EXPAND) |
---|
| 1804 | |
---|
| 1805 | self.runBtn = buttons.GenBitmapButton(self.panel, 1, getSageStartUpBitmap(), style=wx.BORDER_NONE) |
---|
| 1806 | self.runBtn.SetBitmapSelected(getSageStartDownBitmap()) |
---|
| 1807 | self.runBtn.faceDnClr = self.GetBackgroundColour() |
---|
| 1808 | self.runBtn.Bind(wx.EVT_BUTTON, self.OnRun) |
---|
| 1809 | |
---|
| 1810 | self.stopBtn = buttons.GenBitmapButton(self.panel, 2, getSageStopUpBitmap(), style=wx.BORDER_NONE) |
---|
| 1811 | self.stopBtn.SetBitmapSelected(getSageStopDownBitmap()) |
---|
| 1812 | self.stopBtn.faceDnClr = self.GetBackgroundColour() |
---|
| 1813 | self.stopBtn.Bind(wx.EVT_BUTTON, self.OnStop) |
---|
| 1814 | |
---|
| 1815 | self.advancedBtn = hl.HyperLinkCtrl(self.panel, wx.ID_ANY, "Advanced Mode ->") |
---|
| 1816 | self.advancedBtn.SetBackgroundColour(self.GetBackgroundColour()) |
---|
| 1817 | self.advancedBtn.SetForegroundColour(wx.Colour(103,153,102)) |
---|
| 1818 | self.advancedBtn.AutoBrowse(False) |
---|
| 1819 | self.advancedBtn.Bind(hl.EVT_HYPERLINK_LEFT, self.OnAdvanced) |
---|
| 1820 | |
---|
| 1821 | btnSizer = wx.BoxSizer(wx.HORIZONTAL) |
---|
| 1822 | btnSizer.Add(self.runBtn, 0, wx.ALIGN_CENTER_HORIZONTAL | wx.ALIGN_BOTTOM | wx.TOP | wx.RIGHT, 15) |
---|
| 1823 | btnSizer.Add(self.stopBtn, 0, wx.ALIGN_CENTER_HORIZONTAL | wx.ALIGN_BOTTOM | wx.TOP | wx.LEFT, 15) |
---|
| 1824 | |
---|
| 1825 | sizer = wx.BoxSizer(wx.VERTICAL) |
---|
| 1826 | sizer.Add((150,150)) |
---|
| 1827 | sizer.Add(self.MakeStatesPanel(self.panel), 0, wx.ALIGN_CENTER_HORIZONTAL | wx.ALIGN_BOTTOM | wx.ALL, 10) |
---|
| 1828 | sizer.Add(btnSizer, 1, wx.ALIGN_CENTER_HORIZONTAL | wx.ALIGN_BOTTOM | wx.ALL, 10) |
---|
| 1829 | sizer.Add(self.advancedBtn, 0, wx.ALIGN_BOTTOM | wx.ALIGN_RIGHT | wx.ALL, 10) |
---|
| 1830 | |
---|
| 1831 | self.panel.SetSizer(sizer) |
---|
| 1832 | self.SetSizer(ms) |
---|
| 1833 | self.Fit() |
---|
| 1834 | |
---|
| 1835 | |
---|
| 1836 | def MakeStatesPanel(self, parent): |
---|
| 1837 | def OnSelectedRadioButton(evt): |
---|
| 1838 | session = evt.GetEventObject().GetLabel() |
---|
| 1839 | if session == "New session": |
---|
| 1840 | session = "" |
---|
| 1841 | components[SAGE_UI].settings.loadState = session |
---|
| 1842 | |
---|
| 1843 | stateHash = self.GetStateList() |
---|
| 1844 | |
---|
| 1845 | statesPanel = scrolled.ScrolledPanel(parent, wx.ID_ANY, size=(200,200)) |
---|
| 1846 | statesPanel.SetBackgroundColour(wx.Colour(14,51,51)) |
---|
| 1847 | statesPanel.SetForegroundColour(wx.Colour(200,200,200)) |
---|
| 1848 | sizer = wx.BoxSizer(wx.VERTICAL) |
---|
| 1849 | |
---|
| 1850 | # add the default radio button |
---|
| 1851 | choices = {} |
---|
| 1852 | states = stateHash.keys() |
---|
| 1853 | states.sort() |
---|
| 1854 | defaultBtn = wx.RadioButton(statesPanel, -1, "New session", style=wx.RB_GROUP) |
---|
| 1855 | defaultBtn.Bind(wx.EVT_RADIOBUTTON, OnSelectedRadioButton, defaultBtn) |
---|
| 1856 | #defaultBtn.SetBackgroundColour(wx.Colour(14,51,51)) |
---|
| 1857 | #defaultBtn.SetForegroundColour(wx.Colour(200,200,200)) |
---|
| 1858 | defaultBtn.SetToolTipString("Empty display wall with nothing running") |
---|
| 1859 | choices["new"] = defaultBtn |
---|
| 1860 | sizer.Add(defaultBtn, 0, wx.ALIGN_LEFT | wx.ALIGN_TOP | wx.TOP, border=5) |
---|
| 1861 | sizer.Add(wx.StaticLine(statesPanel, -1), 0, wx.EXPAND | wx.ALL, border=5) |
---|
| 1862 | |
---|
| 1863 | # add the rest of them |
---|
| 1864 | if len(stateHash) == 0: |
---|
| 1865 | t = wx.StaticText(statesPanel, wx.ID_ANY, "Any sessions you save through SAGE UI will show up here.") |
---|
| 1866 | try: t.Wrap(200) |
---|
| 1867 | except: pass |
---|
| 1868 | sizer.Add(t, 0, wx.ALIGN_LEFT | wx.ALIGN_TOP | wx.BOTTOM | wx.TOP, border=2) |
---|
| 1869 | |
---|
| 1870 | for stateName in states: |
---|
| 1871 | btn = wx.RadioButton(statesPanel, wx.ID_ANY, stateName) |
---|
| 1872 | btn.SetToolTipString(stateHash[stateName]) |
---|
| 1873 | #btn.SetBackgroundColour(wx.Colour(14,51,51)) |
---|
| 1874 | #btn.SetForegroundColour(wx.Colour(200,200,200)) |
---|
| 1875 | choices[stateName] = btn |
---|
| 1876 | btn.Bind(wx.EVT_RADIOBUTTON, OnSelectedRadioButton, btn) |
---|
| 1877 | sizer.Add(btn, 0, wx.ALIGN_LEFT | wx.ALIGN_TOP | wx.BOTTOM | wx.TOP, border=2) |
---|
| 1878 | |
---|
| 1879 | choices["new"].SetValue(True) |
---|
| 1880 | components[SAGE_UI].settings.loadState = "" |
---|
| 1881 | |
---|
| 1882 | statesPanel.SetSizer(sizer) |
---|
| 1883 | statesPanel.SetAutoLayout(1) |
---|
| 1884 | statesPanel.SetupScrolling(scroll_x = False) |
---|
| 1885 | |
---|
| 1886 | return statesPanel |
---|
| 1887 | |
---|
| 1888 | |
---|
| 1889 | def GetStateList(self): |
---|
| 1890 | """ returns a hash of key=stateName, value=description """ |
---|
| 1891 | savedStatesDir = getUserPath("saved-states") |
---|
| 1892 | stateHash = {} |
---|
| 1893 | appList = [] |
---|
| 1894 | description = "" |
---|
| 1895 | |
---|
| 1896 | if not os.path.isdir(savedStatesDir): |
---|
| 1897 | return {} |
---|
| 1898 | |
---|
| 1899 | # load all the states and read descriptions from them |
---|
| 1900 | for fileName in os.listdir(savedStatesDir): |
---|
| 1901 | filePath = opj(savedStatesDir, fileName) |
---|
| 1902 | if os.path.isfile(filePath) and os.path.splitext(filePath)[1] == ".state": |
---|
| 1903 | try: |
---|
| 1904 | stateName = os.path.splitext( os.path.split(filePath)[1] )[0] |
---|
| 1905 | f = open(filePath, "rb") |
---|
| 1906 | (description, appList) = pickle.Unpickler(f).load() |
---|
| 1907 | f.close() |
---|
| 1908 | stateHash[stateName] = description |
---|
| 1909 | except: |
---|
| 1910 | print "\nUnable to read saved state file: "+filePath |
---|
| 1911 | continue |
---|
| 1912 | |
---|
| 1913 | return stateHash |
---|
| 1914 | |
---|
| 1915 | |
---|
| 1916 | def OnPaint(self, evt): |
---|
| 1917 | dc = wx.PaintDC(self.panel) |
---|
| 1918 | self.Redraw(dc) |
---|
| 1919 | |
---|
| 1920 | |
---|
| 1921 | def Redraw(self, dc=None): |
---|
| 1922 | if not dc: |
---|
| 1923 | dc = wx.ClientDC(self.panel) |
---|
| 1924 | dc.DrawBitmap(getSageBitmap(), 0, 0, False) |
---|
| 1925 | |
---|
| 1926 | |
---|
| 1927 | def OnClose(self, evt): |
---|
| 1928 | saveSettings() |
---|
| 1929 | |
---|
| 1930 | # stop all the read threads from the executed processes |
---|
| 1931 | for c in components.itervalues(): |
---|
| 1932 | c.process.stopRead() |
---|
| 1933 | |
---|
| 1934 | evt.Skip() |
---|
| 1935 | |
---|
| 1936 | |
---|
| 1937 | def OnAdvanced(self, evt): |
---|
| 1938 | self.Hide() |
---|
| 1939 | self.advancedFrame.Show() |
---|
| 1940 | |
---|
| 1941 | |
---|
| 1942 | def OnRun(self, evt): |
---|
| 1943 | """ start all the checked processes... but start sage before everything else |
---|
| 1944 | because some components need sage running already |
---|
| 1945 | """ |
---|
| 1946 | |
---|
| 1947 | # first start sage and then sleep for a few seconds |
---|
| 1948 | sage = components[SAGE] |
---|
| 1949 | if sage.settings.doRun: |
---|
| 1950 | sage.process.start() |
---|
| 1951 | time.sleep(2) |
---|
| 1952 | |
---|
| 1953 | # now start the rest of the components |
---|
| 1954 | for c in components.itervalues(): |
---|
| 1955 | if c.componentType != SAGE and c.settings.doRun: |
---|
| 1956 | c.process.start() |
---|
| 1957 | saveSettings() # to save the changed PIDs |
---|
| 1958 | |
---|
| 1959 | |
---|
| 1960 | def OnStop(self, evt): |
---|
| 1961 | for c in components.itervalues(): |
---|
| 1962 | if not c.settings.inBG: |
---|
| 1963 | c.process.stop() |
---|
| 1964 | saveSettings() # to save the changed PIDs |
---|
| 1965 | |
---|
| 1966 | |
---|
| 1967 | |
---|
| 1968 | |
---|
| 1969 | |
---|
| 1970 | |
---|
| 1971 | class AdvancedFrame(wx.Frame): |
---|
| 1972 | def __init__(self, parent): |
---|
| 1973 | wx.Frame.__init__(self, parent, wx.ID_ANY, "SAGE Launcher - Advanced Settings") |
---|
| 1974 | self.MakeWidgets() |
---|
| 1975 | self.SetThemeEnabled(False) |
---|
| 1976 | self.SetIcon(getSageIcon()) |
---|
| 1977 | self.Bind(wx.EVT_CLOSE, self.OnClose) |
---|
| 1978 | |
---|
| 1979 | # a hack to get correct frame colour on Windows |
---|
| 1980 | if isWin(): |
---|
| 1981 | global colour |
---|
| 1982 | colour = self.componentsPanel.GetBackgroundColour() |
---|
| 1983 | self.SetBackgroundColour(colour) |
---|
| 1984 | |
---|
| 1985 | |
---|
| 1986 | def MakeWidgets(self): |
---|
| 1987 | sizer = wx.BoxSizer(wx.VERTICAL) |
---|
| 1988 | |
---|
| 1989 | # set up tooltips globally |
---|
| 1990 | tt = wx.ToolTip("") |
---|
| 1991 | tt.SetDelay(500) |
---|
| 1992 | tt.Enable(True) |
---|
| 1993 | |
---|
| 1994 | t = HELP_INTRO |
---|
| 1995 | introText = wx.StaticText(self, wx.ID_ANY, t) |
---|
| 1996 | |
---|
| 1997 | self.componentsPanel = ComponentsPanel(self) |
---|
| 1998 | sizer.Add(introText, 0, wx.EXPAND | wx.LEFT | wx.RIGHT | wx.BOTTOM, 20) |
---|
| 1999 | sizer.Add(self.componentsPanel, 1, wx.EXPAND | wx.ALL, 10) |
---|
| 2000 | self.SetSizerAndFit(sizer) |
---|
| 2001 | |
---|
| 2002 | |
---|
| 2003 | def OnClose(self, evt): |
---|
| 2004 | self.GetParent().Close() |
---|
| 2005 | |
---|
| 2006 | |
---|
| 2007 | |
---|
| 2008 | |
---|
| 2009 | # -------------------------------------------------------- |
---|
| 2010 | # |
---|
| 2011 | # MAIN ENTRY POINT |
---|
| 2012 | # |
---|
| 2013 | # -------------------------------------------------------- |
---|
| 2014 | |
---|
| 2015 | |
---|
| 2016 | def main(): |
---|
| 2017 | """ main called at the bottom of this file """ |
---|
| 2018 | |
---|
| 2019 | # load the settings before everything else |
---|
| 2020 | settings = loadSettings() # a hash comes back |
---|
| 2021 | |
---|
| 2022 | # read the tile config |
---|
| 2023 | global tileConfig |
---|
| 2024 | tileConfig = TileConfig(getTileConfig()) |
---|
| 2025 | |
---|
| 2026 | # create the Component objects and set their settings |
---|
| 2027 | global components |
---|
| 2028 | for componentType in componentNames: |
---|
| 2029 | c = Component(componentType) |
---|
| 2030 | c.settings = settings[componentType] |
---|
| 2031 | components[componentType] = c |
---|
| 2032 | |
---|
| 2033 | # create our GUI |
---|
| 2034 | app = wx.App(redirect = False) |
---|
| 2035 | quickFrame = QuickFrame() |
---|
| 2036 | advancedFrame = AdvancedFrame(quickFrame) |
---|
| 2037 | quickFrame.advancedFrame = advancedFrame |
---|
| 2038 | app.SetTopWindow( quickFrame ) |
---|
| 2039 | |
---|
| 2040 | # start the app |
---|
| 2041 | app.MainLoop() |
---|
| 2042 | |
---|
| 2043 | |
---|
| 2044 | |
---|
| 2045 | |
---|
| 2046 | |
---|
| 2047 | |
---|
| 2048 | |
---|
| 2049 | |
---|
| 2050 | |
---|
| 2051 | |
---|
| 2052 | |
---|
| 2053 | |
---|
| 2054 | # -------------------------------------------------------- |
---|
| 2055 | # |
---|
| 2056 | # MISCELLANEOUS HELPER CLASSES |
---|
| 2057 | # |
---|
| 2058 | # -------------------------------------------------------- |
---|
| 2059 | |
---|
| 2060 | |
---|
| 2061 | |
---|
| 2062 | |
---|
| 2063 | class Process: |
---|
| 2064 | """ there is one instance of this class for each component |
---|
| 2065 | that is running (or needs to run). It starts the process |
---|
| 2066 | itself and creates a thread to read data from that |
---|
| 2067 | process. |
---|
| 2068 | """ |
---|
| 2069 | def __init__(self, componentType): |
---|
| 2070 | self.componentType = componentType |
---|
| 2071 | self.settings = components[componentType].settings |
---|
| 2072 | self.output = components[componentType].output |
---|
| 2073 | self.running = False |
---|
| 2074 | self.p = None # Popen process object |
---|
| 2075 | self.t = None # thread reading the output from the process |
---|
| 2076 | self._extraProcesses = [] # pids of extra processes started before SAGE |
---|
| 2077 | |
---|
| 2078 | |
---|
| 2079 | def start(self): |
---|
| 2080 | """ if the process is already running do nothing... |
---|
| 2081 | otherwise launch the new process and |
---|
| 2082 | """ |
---|
| 2083 | if self.isAlive(): |
---|
| 2084 | self.output.SetInsertionPointEnd() |
---|
| 2085 | self.output.WriteText("\n\n**** Already running ****\n\n") |
---|
| 2086 | else: |
---|
| 2087 | cmd = self.settings.getStartCommand() |
---|
| 2088 | cwdir = self.settings.getCwd() |
---|
| 2089 | |
---|
| 2090 | try: |
---|
| 2091 | # execute any extra commands first |
---|
| 2092 | self.__startExtra() |
---|
| 2093 | |
---|
| 2094 | self.p = sp.Popen(cmd, stdout=sp.PIPE, stderr=sp.STDOUT, bufsize=1, cwd=cwdir) |
---|
| 2095 | self.t = Thread(target=self.__readOutput) |
---|
| 2096 | self.t.setDaemon(True) |
---|
| 2097 | self.doRead = True |
---|
| 2098 | self.t.start() |
---|
| 2099 | self.running = True |
---|
| 2100 | self.settings.pid = self.p.pid # save the pid for later |
---|
| 2101 | |
---|
| 2102 | except: |
---|
| 2103 | print " ***** Error while starting", self.componentType |
---|
| 2104 | print "".join(tb.format_exception(sys.exc_info()[0], sys.exc_info()[1], sys.exc_info()[2])) |
---|
| 2105 | self.running = False |
---|
| 2106 | self.doRead = False |
---|
| 2107 | self.t = None |
---|
| 2108 | self.p = None |
---|
| 2109 | |
---|
| 2110 | |
---|
| 2111 | def __startExtra(self): |
---|
| 2112 | """ if the component has any extra commands to execute |
---|
| 2113 | before startup, this will start them """ |
---|
| 2114 | if hasattr(self.settings, 'onStart'): |
---|
| 2115 | if self.settings.onStart != "": |
---|
| 2116 | for cmd in self.settings.onStart.splitlines(): |
---|
| 2117 | if not cmd.strip().startswith("#"): |
---|
| 2118 | proc = sp.Popen(cmd.split()) |
---|
| 2119 | self._extraProcesses.append(proc.pid) # save the pid for later killing |
---|
| 2120 | |
---|
| 2121 | |
---|
| 2122 | def stop(self): |
---|
| 2123 | """ stops the read thread and the process """ |
---|
| 2124 | try: |
---|
| 2125 | # kill SAGE unconditionally |
---|
| 2126 | if self.componentType == SAGE: |
---|
| 2127 | for c in self.settings.getKillCmd(): |
---|
| 2128 | sp.Popen(c) |
---|
| 2129 | |
---|
| 2130 | # kill extra stuff started before sage |
---|
| 2131 | for pid in self._extraProcesses: |
---|
| 2132 | self.__killProcess(pid) |
---|
| 2133 | self._extraProcesses = [] |
---|
| 2134 | |
---|
| 2135 | |
---|
| 2136 | # kill appLauncher unconditionally (because we can) |
---|
| 2137 | elif self.componentType == APP_LAUNCHER: |
---|
| 2138 | sp.Popen(self.settings.getKillCmd(), cwd=self.settings.getCwd()) |
---|
| 2139 | |
---|
| 2140 | # kill the other processes depending on whether they are running or not |
---|
| 2141 | elif self.isAlive(): |
---|
| 2142 | |
---|
| 2143 | # get the pid from the current object or from the saved settings |
---|
| 2144 | if self.p: pid = self.p.pid |
---|
| 2145 | else: pid = self.settings.pid |
---|
| 2146 | |
---|
| 2147 | # execute a kill command |
---|
| 2148 | self.__killProcess(pid) |
---|
| 2149 | |
---|
| 2150 | # execute any extra commands |
---|
| 2151 | self.__stopExtra() |
---|
| 2152 | |
---|
| 2153 | except: |
---|
| 2154 | print " ***** Error while stopping",self.componentType |
---|
| 2155 | print "".join(tb.format_exception(sys.exc_info()[0], sys.exc_info()[1], sys.exc_info()[2])) |
---|
| 2156 | |
---|
| 2157 | self.settings.pid = -1 |
---|
| 2158 | self.running = False |
---|
| 2159 | self.doRead = False |
---|
| 2160 | self.p = None |
---|
| 2161 | self.t = None |
---|
| 2162 | |
---|
| 2163 | |
---|
| 2164 | def __stopExtra(self): |
---|
| 2165 | """ if the component has any extra commands to execute |
---|
| 2166 | after stopping, this will execute them """ |
---|
| 2167 | if hasattr(self.settings, 'onStop'): |
---|
| 2168 | if self.settings.onStop != "": |
---|
| 2169 | for cmd in self.settings.onStop.splitlines(): |
---|
| 2170 | sp.Popen(cmd.split()) |
---|
| 2171 | |
---|
| 2172 | |
---|
| 2173 | def isAlive(self): |
---|
| 2174 | """ return true if the process is currently running, false otherwise """ |
---|
| 2175 | if self.running or \ |
---|
| 2176 | (self.p and (self.p.poll() is None)) or \ |
---|
| 2177 | self.settings.pid != -1: |
---|
| 2178 | |
---|
| 2179 | # if it's presumably running but its process object is dead, |
---|
| 2180 | # it's a zombie so report it as dead and close it's read thread |
---|
| 2181 | if self.p and not (self.p.poll() is None): |
---|
| 2182 | self.stopRead() |
---|
| 2183 | if self.t: self.t.join(1) # wait for the old read thread to die |
---|
| 2184 | return False |
---|
| 2185 | |
---|
| 2186 | return True |
---|
| 2187 | |
---|
| 2188 | else: |
---|
| 2189 | return False |
---|
| 2190 | |
---|
| 2191 | |
---|
| 2192 | def __killProcess(self, pid): |
---|
| 2193 | """ execute a kill command depending on the OS |
---|
| 2194 | the Windows version will only work on XP |
---|
| 2195 | """ |
---|
| 2196 | if isWin(): |
---|
| 2197 | sp.Popen(["taskkill", "/F", "/PID", str(pid)]) |
---|
| 2198 | else: |
---|
| 2199 | sp.Popen(["/bin/kill", "-9", str(pid)]) |
---|
| 2200 | |
---|
| 2201 | |
---|
| 2202 | def stopRead(self): |
---|
| 2203 | self.doRead = False |
---|
| 2204 | |
---|
| 2205 | |
---|
| 2206 | def __readOutput(self): |
---|
| 2207 | """ this runs in a thread and it checks for the output |
---|
| 2208 | from the executed process. Once the output comes in, |
---|
| 2209 | it tells the main wx thread to add the text that was |
---|
| 2210 | just read. |
---|
| 2211 | """ |
---|
| 2212 | while self.doRead: |
---|
| 2213 | txt = os.read(self.p.stdout.fileno(), 2048) |
---|
| 2214 | wx.CallAfter(self.fillText, txt) |
---|
| 2215 | time.sleep(0.3) # read at most twice / sec |
---|
| 2216 | |
---|
| 2217 | |
---|
| 2218 | def fillText(self, txt): |
---|
| 2219 | """ first check whether the text we are about to insert |
---|
| 2220 | will overflow the control or not. If it would, remove |
---|
| 2221 | some text from the beginning and then append the |
---|
| 2222 | new text. If not, just append the new text. |
---|
| 2223 | """ |
---|
| 2224 | if len(txt) + self.output.GetLastPosition() > MAX_TEXT_LEN: |
---|
| 2225 | self.output.Remove(0, 2048) |
---|
| 2226 | self.output.SetInsertionPointEnd() |
---|
| 2227 | self.output.WriteText(txt) |
---|
| 2228 | |
---|
| 2229 | |
---|
| 2230 | |
---|
| 2231 | |
---|
| 2232 | |
---|
| 2233 | |
---|
| 2234 | class FoldBar(wx.Panel): |
---|
| 2235 | """ This class represents the fold bar title for the individual |
---|
| 2236 | application configuration in the app launcher frame. |
---|
| 2237 | When clicked it expands/collapses the sizer that's holding the actual controls |
---|
| 2238 | for this section. It does that through the callback that's passed to this panel |
---|
| 2239 | """ |
---|
| 2240 | |
---|
| 2241 | def __init__(self, parent, btnId, title, callback): |
---|
| 2242 | wx.Panel.__init__(self, parent, wx.ID_ANY, style = wx.NO_BORDER) |
---|
| 2243 | label = wx.StaticText(self, wx.ID_ANY, title) |
---|
| 2244 | label.Bind(wx.EVT_LEFT_DOWN, self.OnBtn) |
---|
| 2245 | makeBoldFont(label) |
---|
| 2246 | self.btn = buttons.GenBitmapButton(self, btnId, GetCollapsedIconBitmap(), style=wx.BORDER_NONE) |
---|
| 2247 | self.btn.Bind(wx.EVT_BUTTON, self.OnBtn) |
---|
| 2248 | |
---|
| 2249 | sizer = wx.BoxSizer(wx.HORIZONTAL) |
---|
| 2250 | sizer.Add(label, 0, wx.ALIGN_LEFT | wx.ALIGN_CENTER_VERTICAL) |
---|
| 2251 | sizer.Add(self.btn, 0, wx.ALIGN_LEFT | wx.ALIGN_CENTER_VERTICAL) |
---|
| 2252 | self.SetSizer(sizer) |
---|
| 2253 | self.Fit() |
---|
| 2254 | |
---|
| 2255 | self.callback = callback |
---|
| 2256 | self.collapsed = True |
---|
| 2257 | |
---|
| 2258 | |
---|
| 2259 | def OnBtn(self, evt): |
---|
| 2260 | if self.collapsed: |
---|
| 2261 | self.collapsed = False |
---|
| 2262 | self.btn.SetBitmapLabel(GetExpandedIconBitmap()) |
---|
| 2263 | self.btn.Refresh() |
---|
| 2264 | self.callback(self.btn.GetId(), False) |
---|
| 2265 | else: |
---|
| 2266 | self.collapsed = True |
---|
| 2267 | self.btn.SetBitmapLabel(GetCollapsedIconBitmap()) |
---|
| 2268 | self.btn.Refresh() |
---|
| 2269 | self.callback(self.btn.GetId(), True) |
---|
| 2270 | |
---|
| 2271 | |
---|
| 2272 | |
---|
| 2273 | |
---|
| 2274 | |
---|
| 2275 | #### ##### |
---|
| 2276 | #### TILE CONFIGURATION CLASSES ##### |
---|
| 2277 | #### ##### |
---|
| 2278 | |
---|
| 2279 | class Tile: |
---|
| 2280 | """ describes one tile """ |
---|
| 2281 | |
---|
| 2282 | def __init__(self): |
---|
| 2283 | self.name = "node" |
---|
| 2284 | self.ip = "127.0.0.1" |
---|
| 2285 | self.numMonitors = 0 |
---|
| 2286 | self.monitors = [] # a list of positions for each monitor (tuples) |
---|
| 2287 | |
---|
| 2288 | |
---|
| 2289 | def addMonitor(self, pos): |
---|
| 2290 | if pos in self.monitors: |
---|
| 2291 | return |
---|
| 2292 | self.monitors.append(pos) |
---|
| 2293 | self.numMonitors += 1 |
---|
| 2294 | |
---|
| 2295 | |
---|
| 2296 | def delMonitor(self, pos): |
---|
| 2297 | if pos in self.monitors: |
---|
| 2298 | self.monitors.remove(pos) |
---|
| 2299 | self.numMonitors -= 1 |
---|
| 2300 | |
---|
| 2301 | |
---|
| 2302 | def toString(self): |
---|
| 2303 | s = "\n\nDisplayNode\n" |
---|
| 2304 | s += "\tName %s\n" % self.name |
---|
| 2305 | s += "\tIP %s\n" % self.ip |
---|
| 2306 | s += "\tMonitors %s " %self.numMonitors |
---|
| 2307 | for m in self.monitors: |
---|
| 2308 | s += str(m) + " " |
---|
| 2309 | |
---|
| 2310 | return s |
---|
| 2311 | |
---|
| 2312 | |
---|
| 2313 | |
---|
| 2314 | |
---|
| 2315 | |
---|
| 2316 | class TileConfig: |
---|
| 2317 | """ describes the whole tiled display configuration """ |
---|
| 2318 | |
---|
| 2319 | def __init__(self, configName): |
---|
| 2320 | self.dim = [1,1] # dimensions of the display (xTiles, yTiles) |
---|
| 2321 | self.mullions = ["0.75", "0.75", "0.75", "0.75"] # mullions on top, down, left, right |
---|
| 2322 | self.resolution = [800, 600] # of each tile in pixels |
---|
| 2323 | self.ppi = 72 # pixels-per-inch of each tile |
---|
| 2324 | self.numMachines = 1 # total number of machines in the display |
---|
| 2325 | self.tiles = {} # key=IP, value=Tile object |
---|
| 2326 | self.readConfigFile(configName) |
---|
| 2327 | |
---|
| 2328 | |
---|
| 2329 | def getAllIPs(self): |
---|
| 2330 | return self.tiles.keys() |
---|
| 2331 | |
---|
| 2332 | |
---|
| 2333 | def readConfigFile(self, filename): |
---|
| 2334 | f = open(filename, "r") |
---|
| 2335 | lines = f.readlines() |
---|
| 2336 | f.close() |
---|
| 2337 | |
---|
| 2338 | # reinitialize variables |
---|
| 2339 | self.tiles = {} |
---|
| 2340 | currentTile = None |
---|
| 2341 | |
---|
| 2342 | # read the file line by line |
---|
| 2343 | for line in lines: |
---|
| 2344 | |
---|
| 2345 | if '#' in line: # allow comments with # anywhere in the line |
---|
| 2346 | line = line.split('#')[0].strip() |
---|
| 2347 | line = line.strip() |
---|
| 2348 | |
---|
| 2349 | if 'Dimensions' in line: |
---|
| 2350 | d = line.lstrip('Dimensions').strip().split(' ',1) |
---|
| 2351 | self.dim = [int(d[0]), int(d[1])] |
---|
| 2352 | |
---|
| 2353 | elif 'Mullions' in line: |
---|
| 2354 | m = line.lstrip('Mullions').strip().split(' ',3) |
---|
| 2355 | self.mullions = [m[0], m[1], m[2], m[3]] |
---|
| 2356 | |
---|
| 2357 | elif 'Resolution' in line: |
---|
| 2358 | r = line.lstrip('Resolution').strip().split(' ',1) |
---|
| 2359 | self.resolution = [int(r[0]), int(r[1])] |
---|
| 2360 | |
---|
| 2361 | elif 'PPI' in line: |
---|
| 2362 | self.ppi = int( float ( line.lstrip('PPI').strip() ) ) |
---|
| 2363 | |
---|
| 2364 | elif 'Machines' in line: |
---|
| 2365 | self.numMachines = int( line.lstrip('Machines').strip() ) |
---|
| 2366 | |
---|
| 2367 | |
---|
| 2368 | # reading the tiles |
---|
| 2369 | elif 'DisplayNode' in line: |
---|
| 2370 | if currentTile: # store the previous Tile if exists |
---|
| 2371 | self.tiles[ currentTile.ip ] = currentTile |
---|
| 2372 | currentTile = Tile() |
---|
| 2373 | |
---|
| 2374 | elif 'Name' in line: |
---|
| 2375 | currentTile.name = line.lstrip('Name').strip() |
---|
| 2376 | |
---|
| 2377 | elif 'IP' in line: |
---|
| 2378 | currentTile.ip = line.lstrip('IP').split(":")[0].strip() |
---|
| 2379 | |
---|
| 2380 | elif 'Monitors' in line: |
---|
| 2381 | (num, positions) = line.lstrip('Monitors').strip().split(' ', 1) |
---|
| 2382 | nums = positions.replace('(', ' ').replace(')', ' ').replace(',', ' ').split() |
---|
| 2383 | for i in range(0, len(nums)-1, 2): |
---|
| 2384 | currentTile.addMonitor( (int(nums[i]),int(nums[i+1])) ) |
---|
| 2385 | |
---|
| 2386 | # add the last one |
---|
| 2387 | self.tiles[ currentTile.ip ] = currentTile |
---|
| 2388 | |
---|
| 2389 | |
---|
| 2390 | |
---|
| 2391 | def writeConfigFile(self): |
---|
| 2392 | # first the global stuff |
---|
| 2393 | s = "TileDisplay\n" |
---|
| 2394 | s += "\tDimensions %d %d\n" % (self.dim[0], self.dim[1]) |
---|
| 2395 | s += "\tMullions %s %s %s %s\n" % (self.mullions[0], self.mullions[1], |
---|
| 2396 | self.mullions[2], self.mullions[3]) |
---|
| 2397 | s += "\tResolution %d %d\n" % (self.resolution[0], self.resolution[1]) |
---|
| 2398 | s += "\tPPI %d\n" % self.ppi |
---|
| 2399 | s += "\tMachines %d\n" % self.numMachines |
---|
| 2400 | |
---|
| 2401 | # now each node |
---|
| 2402 | for t in self.tiles.itervalues(): |
---|
| 2403 | s += t.toString() |
---|
| 2404 | |
---|
| 2405 | return s |
---|
| 2406 | |
---|
| 2407 | |
---|
| 2408 | |
---|
| 2409 | |
---|
| 2410 | |
---|
| 2411 | #### ##### |
---|
| 2412 | #### APP LAUNCHER CONFIGURATION CLASSES ##### |
---|
| 2413 | #### ##### |
---|
| 2414 | class OneConfig: |
---|
| 2415 | ''' describes one configuration for an app ''' |
---|
| 2416 | |
---|
| 2417 | def __init__(self, name, appName, dynamic=False): |
---|
| 2418 | self._configName = name |
---|
| 2419 | self._dynamic = dynamic # dynamic config??? |
---|
| 2420 | self._appName = appName |
---|
| 2421 | self._configFilename = appName+".conf" |
---|
| 2422 | self._launcherId = "" |
---|
| 2423 | |
---|
| 2424 | self._binDir = "$SAGE_DIRECTORY/bin/" # where the binary resides - this is where the config is copied to |
---|
| 2425 | self._nodeNum = 1 |
---|
| 2426 | self._position = (100, 100) # initial position of the window on SAGE |
---|
| 2427 | self._size = (1000, 1000) # initial size of the window on SAGE |
---|
| 2428 | self._command = "" # the actual command used to start the application |
---|
| 2429 | self._targetMachine = "127.0.0.1" # the render machine where the app will be started |
---|
| 2430 | self._protocol = "TCP" |
---|
| 2431 | self._masterIP = None # the master machine of a parallel application |
---|
| 2432 | self._fsIP = None # which SAGE will the app connect to (if not using sageBridge) |
---|
| 2433 | self._fsPort = None # which SAGE will the app connect to (if not using sageBridge) |
---|
| 2434 | self._useBridge = False # if True the app will connect to sageBridge instead of fsManager |
---|
| 2435 | self._bridgeIP = "" # the machine for sage bridge |
---|
| 2436 | self._bridgePort = "" # the machine for sage bridge |
---|
| 2437 | |
---|
| 2438 | self._additionalParams = "" # any additional parameters you want to specify... used for testing |
---|
| 2439 | |
---|
| 2440 | # audio stuff |
---|
| 2441 | self._audioFile = "" |
---|
| 2442 | |
---|
| 2443 | self._nwID = 1 |
---|
| 2444 | self._msgPort = 23010 |
---|
| 2445 | self._syncPort = 13010 |
---|
| 2446 | self._nodeNum = 1 |
---|
| 2447 | self._appId = 0 # the port number for the app on the render machine |
---|
| 2448 | self._blockSize = (64,64) |
---|
| 2449 | self._blockThreshold = 0 |
---|
| 2450 | self._streamType = "SAGE_BLOCK_HARD_SYNC" # sync mode |
---|
| 2451 | self._staticApp = False # static applications dont refresh their windows so sage needs to keep the last frame |
---|
| 2452 | self._runOnNodes = False # if an app has to connect to the outside world or requires |
---|
| 2453 | #an SDL/GLUT window for rendering then it can't run on the nodes |
---|
| 2454 | |
---|
| 2455 | |
---|
| 2456 | def getName(self): return self._configName |
---|
| 2457 | def getAppName(self): return self._appName |
---|
| 2458 | def isDynamic(self): return self._dynamic |
---|
| 2459 | def getConfigFilename(self): return self._configFilename |
---|
| 2460 | |
---|
| 2461 | # audio stuff |
---|
| 2462 | def setAudioFile(self, f): |
---|
| 2463 | self._audioFile = f |
---|
| 2464 | def getAudioFile(self): |
---|
| 2465 | return self._audioFile |
---|
| 2466 | |
---|
| 2467 | |
---|
| 2468 | def getLauncherId(self): |
---|
| 2469 | return self._launcherId |
---|
| 2470 | def setLauncherId(self, launcherId): |
---|
| 2471 | self._launcherId = launcherId |
---|
| 2472 | |
---|
| 2473 | def setBinDir(self, d): |
---|
| 2474 | self._binDir = d |
---|
| 2475 | def getBinDir(self): |
---|
| 2476 | return self._binDir |
---|
| 2477 | |
---|
| 2478 | def setNodeNum(self, num): self._nodeNum = num |
---|
| 2479 | def getNodeNum(self): return self._nodeNum |
---|
| 2480 | |
---|
| 2481 | def setPosition(self, pos): self._position = pos |
---|
| 2482 | def getPosition(self): return self._position |
---|
| 2483 | |
---|
| 2484 | def setSize(self, size): self._size = size |
---|
| 2485 | def getSize(self): return self._size |
---|
| 2486 | |
---|
| 2487 | def setCommand(self, command): self._command = command |
---|
| 2488 | def getCommand(self): return self._command |
---|
| 2489 | |
---|
| 2490 | def setTargetMachine(self, target): self._targetMachine = target |
---|
| 2491 | def getTargetMachine(self): return self._targetMachine |
---|
| 2492 | |
---|
| 2493 | def setProtocol(self, protocol): |
---|
| 2494 | if protocol == "tvTcpModule.so" or protocol=="TCP": |
---|
| 2495 | self._protocol = "TCP" |
---|
| 2496 | else: |
---|
| 2497 | self._protocol = "UDP" |
---|
| 2498 | def getProtocol(self): return self._protocol |
---|
| 2499 | |
---|
| 2500 | def setMasterIP(self, ip): |
---|
| 2501 | self._masterIP = ip |
---|
| 2502 | def getMasterIP(self): |
---|
| 2503 | return self._masterIP |
---|
| 2504 | |
---|
| 2505 | def setFSIP(self, ip): |
---|
| 2506 | self._fsIP = ip |
---|
| 2507 | def getFSIP(self): |
---|
| 2508 | return self._fsIP |
---|
| 2509 | |
---|
| 2510 | def setFSPort(self, port): |
---|
| 2511 | self._fsPort = port |
---|
| 2512 | def getFSPort(self): |
---|
| 2513 | return self._fsPort |
---|
| 2514 | |
---|
| 2515 | def setBridgeIP(self, ip): |
---|
| 2516 | self._bridgeIP = ip |
---|
| 2517 | def getBridgeIP(self): |
---|
| 2518 | return self._bridgeIP |
---|
| 2519 | |
---|
| 2520 | def setBridgePort(self, port): |
---|
| 2521 | self._bridgePort = port |
---|
| 2522 | def getBridgePort(self): |
---|
| 2523 | return self._bridgePort |
---|
| 2524 | |
---|
| 2525 | def setUseBridge(self, doUse): |
---|
| 2526 | self._useBridge = doUse |
---|
| 2527 | def getUseBridge(self): |
---|
| 2528 | return self._useBridge |
---|
| 2529 | |
---|
| 2530 | def setNWId(self, id): |
---|
| 2531 | self._nwID = id |
---|
| 2532 | def getNWId(self): |
---|
| 2533 | return self._nwID |
---|
| 2534 | |
---|
| 2535 | def setMsgPort(self, port): |
---|
| 2536 | self._msgPort = port |
---|
| 2537 | def getMsgPort(self): |
---|
| 2538 | return self._msgPort |
---|
| 2539 | |
---|
| 2540 | def setSyncPort(self, port): |
---|
| 2541 | self._syncPort = port |
---|
| 2542 | def getSyncPort(self): |
---|
| 2543 | return self._syncPort |
---|
| 2544 | |
---|
| 2545 | def setAppId(self, id): |
---|
| 2546 | self._appId = id |
---|
| 2547 | def getAppId(self): |
---|
| 2548 | return self._appId |
---|
| 2549 | |
---|
| 2550 | def setBlockSize(self, size): |
---|
| 2551 | self._blockSize = size |
---|
| 2552 | def getBlockSize(self): |
---|
| 2553 | return self._blockSize |
---|
| 2554 | |
---|
| 2555 | def setBlockThreshold(self, threshold): |
---|
| 2556 | self._blockThreshold = threshold |
---|
| 2557 | def getBlockThreshold(self): |
---|
| 2558 | return self._blockThreshold |
---|
| 2559 | |
---|
| 2560 | def setStreamType(self, mode): |
---|
| 2561 | self._streamType = mode |
---|
| 2562 | def getStreamType(self): |
---|
| 2563 | return self._streamType |
---|
| 2564 | |
---|
| 2565 | def setStaticApp(self, do): |
---|
| 2566 | self._staticApp = do |
---|
| 2567 | def getStaticApp(self): |
---|
| 2568 | return self._staticApp |
---|
| 2569 | |
---|
| 2570 | def setRunOnNodes(self, run): |
---|
| 2571 | self._runOnNodes = run |
---|
| 2572 | def getRunOnNodes(self): |
---|
| 2573 | return self._runOnNodes |
---|
| 2574 | |
---|
| 2575 | def setAdditionalParams(self, param): |
---|
| 2576 | self._additionalParams += param + "\n" |
---|
| 2577 | def getAdditionalParams(self): |
---|
| 2578 | return self._additionalParams |
---|
| 2579 | |
---|
| 2580 | def writeToFile(self): |
---|
| 2581 | s = "" |
---|
| 2582 | |
---|
| 2583 | # sage bridge stuff |
---|
| 2584 | if self.getUseBridge(): # using sageBridge |
---|
| 2585 | s += 'bridgeOn true\n' |
---|
| 2586 | s += 'bridgeIP %s\n'% self.getBridgeIP() |
---|
| 2587 | s += 'bridgePort %s\n'% self.getBridgePort() |
---|
| 2588 | else: # not using sageBridge |
---|
| 2589 | s += 'bridgeOn false\n' |
---|
| 2590 | |
---|
| 2591 | s += 'fsIP %s\n'% self.getFSIP() |
---|
| 2592 | s += 'fsPort %s\n'% self.getFSPort() |
---|
| 2593 | s += 'masterIP %s\n'% self.getMasterIP() |
---|
| 2594 | s += 'nwID %d\n' % self.getNWId() |
---|
| 2595 | s += 'msgPort %d\n' % self.getMsgPort() |
---|
| 2596 | s += 'syncPort %d\n' % self.getSyncPort() |
---|
| 2597 | s += 'nodeNum %d\n' % self.getNodeNum() |
---|
| 2598 | s += 'appID %d\n' % self.getAppId() |
---|
| 2599 | s += 'launcherID %s\n' % self.getLauncherId() |
---|
| 2600 | s += 'pixelBlockSize %d %d\n' % (self.getBlockSize()[0], self.getBlockSize()[1]) |
---|
| 2601 | s += 'blockThreshold %d\n' % self.getBlockThreshold() |
---|
| 2602 | s += 'winX %d\n' % self.getPosition()[0] |
---|
| 2603 | s += 'winY %d\n' % self.getPosition()[1] |
---|
| 2604 | s += 'winWidth %d\n' % self.getSize()[0] |
---|
| 2605 | s += 'winHeight %d\n' % self.getSize()[1] |
---|
| 2606 | s += 'streamType %s\n' % self.getStreamType() |
---|
| 2607 | s += 'nwProtocol %s\n' % self.getProtocol() |
---|
| 2608 | |
---|
| 2609 | # audio |
---|
| 2610 | if self.getAudioFile(): |
---|
| 2611 | s += 'audioOn true\n' |
---|
| 2612 | s += 'audioFile %s\n' % self.getAudioFile() |
---|
| 2613 | s += 'audioType read\ndeviceNum -1\n' |
---|
| 2614 | s += 'framePerBuffer 512\n' |
---|
| 2615 | |
---|
| 2616 | # static app |
---|
| 2617 | if self.getStaticApp(): |
---|
| 2618 | s += 'asyncUpdate true\n' |
---|
| 2619 | else: |
---|
| 2620 | s += 'asyncUpdate false\n' |
---|
| 2621 | |
---|
| 2622 | # additional params |
---|
| 2623 | s += self.getAdditionalParams() |
---|
| 2624 | |
---|
| 2625 | f = open(self._configFilename, "w") |
---|
| 2626 | f.write(s) |
---|
| 2627 | f.close() |
---|
| 2628 | |
---|
| 2629 | |
---|
| 2630 | def getConfigString(self): |
---|
| 2631 | """ returns a tuple of strings: (configName, optionalArgs that the app was started with) """ |
---|
| 2632 | return (self.getName(), self.getCommand().split(" ", 1)[1].strip()) |
---|
| 2633 | |
---|
| 2634 | |
---|
| 2635 | def getAppLauncherConfig(self): |
---|
| 2636 | """ this returns the appLauncher config format (for applications.conf)""" |
---|
| 2637 | |
---|
| 2638 | s = "" |
---|
| 2639 | |
---|
| 2640 | # common parameters |
---|
| 2641 | s += 'configName %s\n' % self.getName() |
---|
| 2642 | s += 'Init %d %d %d %d\n' % (self.getPosition()[0], |
---|
| 2643 | self.getPosition()[1], |
---|
| 2644 | self.getSize()[0], |
---|
| 2645 | self.getSize()[1]) |
---|
| 2646 | s += 'exec %s %s\n' % (self.getTargetMachine(), self.getCommand()) |
---|
| 2647 | |
---|
| 2648 | # now the optional parameters |
---|
| 2649 | if self.getNodeNum() != 1: |
---|
| 2650 | s += 'nodeNum %d\n' % self.getNodeNum() |
---|
| 2651 | |
---|
| 2652 | if self.getStaticApp(): |
---|
| 2653 | s += 'staticApp\n' |
---|
| 2654 | |
---|
| 2655 | if self.getProtocol() != "TCP": |
---|
| 2656 | s += 'nwProtocol %s\n' % self.getProtocol() |
---|
| 2657 | |
---|
| 2658 | if self.getBinDir() != "$SAGE_DIRECTORY/bin/": |
---|
| 2659 | s += 'binDir %s\n' % self.getBinDir() |
---|
| 2660 | |
---|
| 2661 | if self.getBridgeIP() != "": |
---|
| 2662 | s += 'bridgeIP %s\n' % self.getBridgeIP() |
---|
| 2663 | s += 'bridgePort %s\n' % self.getBridgePort() |
---|
| 2664 | |
---|
| 2665 | if self.getBlockSize() != (64,64): |
---|
| 2666 | s += 'pixelBlockSize %s %s\n' % (self.getBlockSize()[0], |
---|
| 2667 | self.getBlockSize()[1]) |
---|
| 2668 | |
---|
| 2669 | if self.getMasterIP(): |
---|
| 2670 | s += 'masterIP %s\n' % self.getMasterIP() |
---|
| 2671 | |
---|
| 2672 | if self.getRunOnNodes(): |
---|
| 2673 | s += 'runOnNodes\n' |
---|
| 2674 | |
---|
| 2675 | if self.getStreamType() != "SAGE_BLOCK_HARD_SYNC": |
---|
| 2676 | s += 'sync %s\n' % self.getStreamType() |
---|
| 2677 | |
---|
| 2678 | if self.getAudioFile(): |
---|
| 2679 | s += 'audioFile %s\n' % self.getAudioFile() |
---|
| 2680 | |
---|
| 2681 | s += self.getAdditionalParams() |
---|
| 2682 | |
---|
| 2683 | return s |
---|
| 2684 | |
---|
| 2685 | |
---|
| 2686 | |
---|
| 2687 | |
---|
| 2688 | class AppConfig: |
---|
| 2689 | ''' a collection of all the configurations for an app ''' |
---|
| 2690 | |
---|
| 2691 | def __init__(self, appName): |
---|
| 2692 | self._configs = {} #key=configName, value=OneConfig object |
---|
| 2693 | self._appName = appName |
---|
| 2694 | |
---|
| 2695 | def getAppName(self): |
---|
| 2696 | return self._appName |
---|
| 2697 | |
---|
| 2698 | def addConfig(self, oneConfig): |
---|
| 2699 | self._configs[oneConfig.getName()] = oneConfig |
---|
| 2700 | |
---|
| 2701 | def addNewConfig(self, configName): |
---|
| 2702 | cfg = OneConfig(configName, self._appName) |
---|
| 2703 | self._configs[configName] = cfg |
---|
| 2704 | |
---|
| 2705 | def delConfig(self, configName): |
---|
| 2706 | if configName in self._configs: |
---|
| 2707 | del self._configs[configName] |
---|
| 2708 | |
---|
| 2709 | def getConfig(self, configName): |
---|
| 2710 | return self._configs[configName] |
---|
| 2711 | |
---|
| 2712 | def getDefaultConfig(self): |
---|
| 2713 | return self._configs.values()[0] #return an arbitrary config file |
---|
| 2714 | |
---|
| 2715 | def getAllConfigs(self): |
---|
| 2716 | return self._configs |
---|
| 2717 | |
---|
| 2718 | def getAllConfigNames(self): |
---|
| 2719 | return self._configs.keys() |
---|
| 2720 | |
---|
| 2721 | def makeConfigFile(self, configName): |
---|
| 2722 | config = self.getConfig(configName) |
---|
| 2723 | config.writeToFile() |
---|
| 2724 | |
---|
| 2725 | |
---|
| 2726 | |
---|
| 2727 | |
---|
| 2728 | |
---|
| 2729 | class AppConfigurations: |
---|
| 2730 | ''' a collection of all applications and their configurations ''' |
---|
| 2731 | |
---|
| 2732 | def __init__(self, configFile): |
---|
| 2733 | self._configFile = configFile |
---|
| 2734 | self._lastModTime = None #last modification time to the config file |
---|
| 2735 | # sageBridge stuff |
---|
| 2736 | self._bridgeIP = None |
---|
| 2737 | self._bridgePort = None |
---|
| 2738 | |
---|
| 2739 | self._appConfigs = {} #key=appName, value=AppConfig object |
---|
| 2740 | self._readConfig() |
---|
| 2741 | #self._printConfig() |
---|
| 2742 | |
---|
| 2743 | |
---|
| 2744 | # so that we can change the config file without restarting the appLauncher |
---|
| 2745 | # checks the last modification time so that we don't reload unnecessarily |
---|
| 2746 | def reloadConfigFile(self): |
---|
| 2747 | try: |
---|
| 2748 | lastModTime = os.path.getmtime(self._configFile) |
---|
| 2749 | if lastModTime != self._lastModTime: |
---|
| 2750 | self._appConfigs = {} #empty out the hash |
---|
| 2751 | self._readConfig() |
---|
| 2752 | self._lastModTime = lastModTime |
---|
| 2753 | except: |
---|
| 2754 | WriteLog( "".join(tb.format_exception(sys.exc_info()[0], sys.exc_info()[1], sys.exc_info()[2])) ) |
---|
| 2755 | |
---|
| 2756 | def addNewApp(self, appName): |
---|
| 2757 | self._appConfigs[appName] = AppConfig(appName) |
---|
| 2758 | |
---|
| 2759 | def delApp(self, appName): |
---|
| 2760 | if appName in self._appConfigs: |
---|
| 2761 | del self._appConfigs[appName] |
---|
| 2762 | |
---|
| 2763 | def getConfig(self, appName, configName): #returns a copy so that it can be safely modified without the destroying what's in the config file |
---|
| 2764 | return self._appConfigs[appName].getConfig(configName) |
---|
| 2765 | |
---|
| 2766 | def getDefaultConfig(self, appName): #returns a copy so that it can be safely modified without destroying what's in the config file |
---|
| 2767 | return self._appConfigs[appName].getDefaultConfig() |
---|
| 2768 | |
---|
| 2769 | def getApp(self, appName): |
---|
| 2770 | return self._appConfigs[appName] |
---|
| 2771 | |
---|
| 2772 | def getAppList(self): # returns just the names of the apps |
---|
| 2773 | return self._appConfigs.keys() |
---|
| 2774 | |
---|
| 2775 | def getBridgeIP(self): |
---|
| 2776 | return self._bridgeIP |
---|
| 2777 | |
---|
| 2778 | def getBridgePort(self): |
---|
| 2779 | return self._bridgePort |
---|
| 2780 | |
---|
| 2781 | def _printConfig(self): |
---|
| 2782 | for name, app in self._appConfigs.iteritems(): |
---|
| 2783 | print "\n----------------------------------------" |
---|
| 2784 | print "Config For: ", name |
---|
| 2785 | for name, config in app.getAllConfigs().iteritems(): |
---|
| 2786 | print "Config: ", name |
---|
| 2787 | print "nodeNum = ", config.getNodeNum() |
---|
| 2788 | print "pos = ", config.getPosition() |
---|
| 2789 | print "size = ", config.getSize() |
---|
| 2790 | print "command = ", config.getCommand() |
---|
| 2791 | print "target = ", config.getTargetMachine() |
---|
| 2792 | print "protocol = ", config.getProtocol() |
---|
| 2793 | print "runOnNodes = ", config.getRunOnNodes() |
---|
| 2794 | |
---|
| 2795 | print "\n----------------------------------------" |
---|
| 2796 | print "bridgePort = ", self._bridgePort |
---|
| 2797 | print "bridgeIP = ", self._bridgeIP |
---|
| 2798 | |
---|
| 2799 | |
---|
| 2800 | def getConfigHash(self): |
---|
| 2801 | """ returns a hash of all the configurations without the objects... just tuples of strings and ints """ |
---|
| 2802 | strHash = {} #keyed by appName, value = a list of configNames |
---|
| 2803 | for appName, app in self._appConfigs.iteritems(): |
---|
| 2804 | strHash[appName] = app.getAllConfigNames() |
---|
| 2805 | return strHash |
---|
| 2806 | |
---|
| 2807 | |
---|
| 2808 | def _readConfig(self): |
---|
| 2809 | f = open(self._configFile, "r") |
---|
| 2810 | lines = f.readlines() |
---|
| 2811 | f.close() |
---|
| 2812 | |
---|
| 2813 | self.appconfig = None |
---|
| 2814 | self.oneconfig = None |
---|
| 2815 | self.lineCounter = 0 |
---|
| 2816 | |
---|
| 2817 | for line in lines: |
---|
| 2818 | self.lineCounter += 1 |
---|
| 2819 | |
---|
| 2820 | # allow comments with # |
---|
| 2821 | if '#' in line: |
---|
| 2822 | line = line.split('#')[0].strip() |
---|
| 2823 | |
---|
| 2824 | |
---|
| 2825 | if '{' in line: |
---|
| 2826 | appName = line.replace('{', ' ').strip() |
---|
| 2827 | self.appconfig = AppConfig(appName) |
---|
| 2828 | |
---|
| 2829 | elif 'configName' in line: |
---|
| 2830 | if self.oneconfig: |
---|
| 2831 | self.appconfig.addConfig(self.oneconfig) |
---|
| 2832 | self.oneconfig = OneConfig(line.lstrip('configName').strip(), self.appconfig.getAppName()) |
---|
| 2833 | |
---|
| 2834 | elif 'nodeNum' in line: |
---|
| 2835 | self.oneconfig.setNodeNum(int(line.lstrip('nodeNum').strip())) |
---|
| 2836 | |
---|
| 2837 | elif 'Init' in line: |
---|
| 2838 | lineTokens = line.split() |
---|
| 2839 | pos = (int(lineTokens[1]), int(lineTokens[2])) |
---|
| 2840 | size = (int(lineTokens[3]), int(lineTokens[4])) |
---|
| 2841 | self.oneconfig.setPosition(pos) |
---|
| 2842 | self.oneconfig.setSize(size) |
---|
| 2843 | |
---|
| 2844 | elif 'exec' in line: |
---|
| 2845 | bla, target, command = line.split(' ', 2) |
---|
| 2846 | self.oneconfig.setTargetMachine(target.strip()) |
---|
| 2847 | if not self.oneconfig.getMasterIP(): #if it has been set, dont overwrite it |
---|
| 2848 | self.oneconfig.setMasterIP(target.strip()) |
---|
| 2849 | self.oneconfig.setCommand(command.strip()) |
---|
| 2850 | |
---|
| 2851 | elif 'nwProtocol' in line: |
---|
| 2852 | self.oneconfig.setProtocol(line.lstrip('nwProtocol').strip()) |
---|
| 2853 | |
---|
| 2854 | elif 'bridgeIP' in line: |
---|
| 2855 | self.oneconfig.setBridgeIP(line.split()[1].strip()) |
---|
| 2856 | |
---|
| 2857 | elif 'bridgePort' in line: |
---|
| 2858 | self.oneconfig.setBridgePort(line.split()[1].strip()) |
---|
| 2859 | |
---|
| 2860 | elif 'runOnNodes' in line: |
---|
| 2861 | self.oneconfig.setRunOnNodes(True) |
---|
| 2862 | |
---|
| 2863 | elif 'staticApp' in line: |
---|
| 2864 | self.oneconfig.setStaticApp(True) |
---|
| 2865 | |
---|
| 2866 | elif 'pixelBlockSize' in line: |
---|
| 2867 | s = line.split() |
---|
| 2868 | self.oneconfig.setBlockSize( (int(s[1].strip()), int(s[2].strip())) ) |
---|
| 2869 | |
---|
| 2870 | elif 'binDir' in line: |
---|
| 2871 | p = line.split()[1].strip() |
---|
| 2872 | if not p.endswith("/"): |
---|
| 2873 | p += "/" |
---|
| 2874 | self.oneconfig.setBinDir(p) |
---|
| 2875 | |
---|
| 2876 | elif 'masterIP' in line: |
---|
| 2877 | self.oneconfig.setMasterIP(line.split()[1].strip()) |
---|
| 2878 | |
---|
| 2879 | elif 'audioFile' in line: |
---|
| 2880 | self.oneconfig.setAudioFile(line.split()[1].strip()) |
---|
| 2881 | |
---|
| 2882 | elif 'sync' in line: |
---|
| 2883 | mode = line.split()[1].strip() |
---|
| 2884 | if not mode.startswith("SAGE_BLOCK_"): |
---|
| 2885 | mode = "SAGE_BLOCK_" + mode |
---|
| 2886 | |
---|
| 2887 | if mode == "SAGE_BLOCK_NO_SYNC" or \ |
---|
| 2888 | mode == "SAGE_BLOCK_SOFT_SYNC" or \ |
---|
| 2889 | mode == "SAGE_BLOCK_HARD_SYNC": |
---|
| 2890 | self.oneconfig.setStreamType(mode) |
---|
| 2891 | else: |
---|
| 2892 | WriteLog("\n*** Invalid streamType mode on line: "+str(self.lineCounter)+". Defaulting to NO_SYNC") |
---|
| 2893 | |
---|
| 2894 | elif '}' in line: |
---|
| 2895 | self.appconfig.addConfig(self.oneconfig) #save the last config |
---|
| 2896 | self._appConfigs[self.appconfig.getAppName()] = self.appconfig #save the appConfig |
---|
| 2897 | self.appconfig = None #reinitialize everything |
---|
| 2898 | self.oneconfig = None |
---|
| 2899 | |
---|
| 2900 | |
---|
| 2901 | elif 'defaultBridgeIP' in line: |
---|
| 2902 | self._bridgeIP = line.split()[1].strip() |
---|
| 2903 | |
---|
| 2904 | elif 'defaultBridgePort' in line: |
---|
| 2905 | self._bridgePort = line.split()[1].strip() |
---|
| 2906 | |
---|
| 2907 | |
---|
| 2908 | elif line in string.whitespace: |
---|
| 2909 | pass |
---|
| 2910 | |
---|
| 2911 | else: # if line is not recognized |
---|
| 2912 | self.oneconfig.setAdditionalParams(line.strip()) |
---|
| 2913 | |
---|
| 2914 | |
---|
| 2915 | def writeConfig(self): |
---|
| 2916 | """ write applications.conf based on the current configuration """ |
---|
| 2917 | self._configFile = getUserPath("applications", "applications.conf") |
---|
| 2918 | f = open(self._configFile, "w") |
---|
| 2919 | |
---|
| 2920 | # loop through all the apps and write their configs to a file |
---|
| 2921 | for appName, app in self._appConfigs.iteritems(): |
---|
| 2922 | f.write("\n"+appName+" {\n") |
---|
| 2923 | |
---|
| 2924 | # write all the configs |
---|
| 2925 | for configName, conf in app.getAllConfigs().iteritems(): |
---|
| 2926 | f.write("\n") |
---|
| 2927 | f.write(conf.getAppLauncherConfig()) |
---|
| 2928 | f.write("\n") |
---|
| 2929 | |
---|
| 2930 | f.write("}\n\n#"+"-"*30+"\n") # finish the app |
---|
| 2931 | |
---|
| 2932 | if self._bridgeIP: f.write("\ndefaultBridgeIP "+self._bridgeIP) |
---|
| 2933 | if self._bridgePort: f.write("\ndefaultBridgePort "+self._bridgePort+"\n") |
---|
| 2934 | |
---|
| 2935 | f.close() |
---|
| 2936 | |
---|
| 2937 | |
---|
| 2938 | |
---|
| 2939 | |
---|
| 2940 | |
---|
| 2941 | |
---|
| 2942 | |
---|
| 2943 | |
---|
| 2944 | |
---|
| 2945 | # -------------------------------------------------------- |
---|
| 2946 | # |
---|
| 2947 | # HELP STRINGS |
---|
| 2948 | # |
---|
| 2949 | # -------------------------------------------------------- |
---|
| 2950 | |
---|
| 2951 | HELP_INTRO = \ |
---|
| 2952 | """ |
---|
| 2953 | This SAGE Launcher helps you run SAGE and all the related components listed below. Check the components you wish to run with SAGE and click START. |
---|
| 2954 | For more information hover your mouse over any area. """ |
---|
| 2955 | |
---|
| 2956 | HELP_FS = "File Server allows you to easily show and organize\n"\ |
---|
| 2957 | "common multimedia files in a SAGE environment from\n"\ |
---|
| 2958 | "SAGE UI. Showing files is as easy as drag-and-drop\n"\ |
---|
| 2959 | "of files onto the UI." |
---|
| 2960 | |
---|
| 2961 | HELP_AL = "Application Launcher takes care of starting SAGE applications\n"\ |
---|
| 2962 | "either on a local machine or any node of a rendering cluster.\n"\ |
---|
| 2963 | "Applications are started through SAGE UI." |
---|
| 2964 | |
---|
| 2965 | HELP_SU = "SAGE UI is the main interface for controlling your SAGE display." |
---|
| 2966 | |
---|
| 2967 | HELP_SP = "SAGE Proxy allows interaction with SAGE through XML-RPC as opposed\n"\ |
---|
| 2968 | "to regular sockets. Primarily used by the SAGE Web UI." |
---|
| 2969 | |
---|
| 2970 | HELP_S = "SAGE itself (i.e. fsManager)" |
---|
| 2971 | |
---|
| 2972 | HELP_RUN = "If checked this component will run when START is pressed." |
---|
| 2973 | |
---|
| 2974 | HELP_EDIT = "Configure component specific settings." |
---|
| 2975 | |
---|
| 2976 | HELP_COMP_STOP = "Kills the component now.\n"\ |
---|
| 2977 | "To restart it, make sure that it's checked and then press START below." |
---|
| 2978 | |
---|
| 2979 | HELP_INBG = "If run in background, the component will keep running\n"\ |
---|
| 2980 | "even after STOP is pressed and they need not be restarted.\n"\ |
---|
| 2981 | "Usually you want to do this if the components are used\n"\ |
---|
| 2982 | "independently of your local SAGE session." |
---|
| 2983 | |
---|
| 2984 | |
---|
| 2985 | ### SAGE help stuff |
---|
| 2986 | |
---|
| 2987 | HELP_S_START = "These are just shell commands\n(each line is executed as a separate command)" |
---|
| 2988 | |
---|
| 2989 | HELP_S_STOP = "These are just shell commands\n(each line is executed as a separate command)" |
---|
| 2990 | |
---|
| 2991 | HELP_S_PROC = "Typically these are SAGE applications and SAGE itself.\n"\ |
---|
| 2992 | "This should not include components as they are killed separately." |
---|
| 2993 | |
---|
| 2994 | |
---|
| 2995 | ### AppLauncher help stuff |
---|
| 2996 | |
---|
| 2997 | HELP_AL_PUBLIC = "Makes the appLauncher visible to other SAGE UIs connected to\n"\ |
---|
| 2998 | "remote SAGE displays. This appLauncher can then be used by\n"\ |
---|
| 2999 | "remote SAGE UIs to start applications and stream to their SAGE display." |
---|
| 3000 | |
---|
| 3001 | HELP_AL_PUBLIC_HOST = "Which connection manager/SAGE server to report to?" |
---|
| 3002 | |
---|
| 3003 | HELP_AL_APPS = "List of applications currently configured with this appLauncher\n"\ |
---|
| 3004 | "and available for running from the SAGE UI." |
---|
| 3005 | |
---|
| 3006 | HELP_AL_CFG = "Different configurations for a particular application.\n"\ |
---|
| 3007 | "Configurations usually specify different running scenarios\n"\ |
---|
| 3008 | "of an application. All will show up in the SAGE UI." |
---|
| 3009 | |
---|
| 3010 | HELP_AL_CFG_COPY = "Makes a copy of the current configuration with\n"\ |
---|
| 3011 | "a different name but same parameters." |
---|
| 3012 | |
---|
| 3013 | HELP_AL_CFG_STATIC = "This should be checked for applications that are not animated\n"\ |
---|
| 3014 | "(i.e. do not refresh on a regular basis)" |
---|
| 3015 | |
---|
| 3016 | HELP_AL_CFG_APP = "This is the actual command executed (could also be a script)\n"\ |
---|
| 3017 | "Full paths and/or parameters can be specified as well." |
---|
| 3018 | |
---|
| 3019 | HELP_AL_CFG_DIR = "The directory where the app configuration file will be copied to.\n"\ |
---|
| 3020 | "This must be in the same directory as the executable that's\n"\ |
---|
| 3021 | "initializing SAIL and connecting to SAGE (basically your app).\n"\ |
---|
| 3022 | "If empty it defaults to $SAGE_DIRECTORY/bin." |
---|
| 3023 | |
---|
| 3024 | HELP_AL_CFG_MACHINE = "This is the remote machine that the application will be started\n"\ |
---|
| 3025 | "on. SSH and SCP need to be set up for this to work.\n"\ |
---|
| 3026 | "If left empty it defaults to the local machine." |
---|
| 3027 | |
---|
| 3028 | HELP_AL_CFG_SIZE = "This is just the initial SAGE window size. Sometimes it is\n"\ |
---|
| 3029 | "overwritten at startup by the application (such as imageviewer\n"\ |
---|
| 3030 | "or mplayer) to get the correct aspect ratio for the data being displayed." |
---|
| 3031 | |
---|
| 3032 | HELP_AL_CFG_NUM_NODES = "Specify the number of nodes of this application that are\n"\ |
---|
| 3033 | "streaming pixels to SAGE (this may or may not include the\n"\ |
---|
| 3034 | "master node depending on whether it's doing any rendering)" |
---|
| 3035 | |
---|
| 3036 | HELP_AL_CFG_MASTER = "This is the IP address of the master node for your parallel\n"\ |
---|
| 3037 | "application." |
---|
| 3038 | |
---|
| 3039 | HELP_AL_CFG_BP = "Block size that SAGE splits the image into and streams." |
---|
| 3040 | |
---|
| 3041 | HELP_AL_CFG_BHOST = "Used in visualcasting for sharing applications between displays.\n"\ |
---|
| 3042 | "Specify the address of the SAGE Bridge that's handling this." |
---|
| 3043 | |
---|
| 3044 | HELP_AL_CFG_BPORT = "Used in visualcasting for sharing applications between displays.\n"\ |
---|
| 3045 | "Specify the port of the SAGE Bridge that's handling this." |
---|
| 3046 | |
---|
| 3047 | |
---|
| 3048 | ### SAGE UI help stuff |
---|
| 3049 | |
---|
| 3050 | HELP_SU_HOST = "Specify the connection manager/SAGE server to connect to\n"\ |
---|
| 3051 | "in order to find the running SAGE sessions. This should be\n"\ |
---|
| 3052 | "the same as for SAGE and the appLauncher." |
---|
| 3053 | |
---|
| 3054 | HELP_SU_AUTOLOGIN = "To automatically log in to a sage session specify its name here\n"\ |
---|
| 3055 | "(the name should be exactly the same as the one that fsManager reports"\ |
---|
| 3056 | "to the connection manager... from the first line of fsManager.conf)" |
---|
| 3057 | |
---|
| 3058 | ### FileServer help |
---|
| 3059 | |
---|
| 3060 | HELP_FS_ROOT = "All the multimedia files will be organized under this directory.\n"\ |
---|
| 3061 | "Either specify a relative path to $SAGE_DIRECTORY/bin or a full path." |
---|
| 3062 | |
---|
| 3063 | HELP_FS_TYPES = "These are all the file types supported by the File Server.\n"\ |
---|
| 3064 | "All types have file extensions associated with them and all\n"\ |
---|
| 3065 | "the files are checked against that and matched to the correct\n"\ |
---|
| 3066 | "application for opening the files." |
---|
| 3067 | |
---|
| 3068 | HELP_FS_EXT = "List all the file extensions that match this file type\n"\ |
---|
| 3069 | "and can be opened by the specified application." |
---|
| 3070 | |
---|
| 3071 | HELP_FS_APP = "Specify the application for opening this file type.\n"\ |
---|
| 3072 | "When the application is started by the appLauncher,\n"\ |
---|
| 3073 | "the filename to open will always be the last argument." |
---|
| 3074 | |
---|
| 3075 | |
---|
| 3076 | ### SageProxy help |
---|
| 3077 | |
---|
| 3078 | HELP_SP_HOST = "Specify the SAGE machine to connect to" |
---|
| 3079 | |
---|
| 3080 | HELP_SP_PORT = "Specify port on which SAGE is accepting UI connections." |
---|
| 3081 | |
---|
| 3082 | HELP_SP_PASS = "This password is only used by the SAGE Web UI to restrict\n"\ |
---|
| 3083 | "access to this SAGE session. Since no encryption is used,\n"\ |
---|
| 3084 | "this is more of a determent." |
---|
| 3085 | |
---|
| 3086 | |
---|
| 3087 | |
---|
| 3088 | #---------------------------------------------------------------------- |
---|
| 3089 | # |
---|
| 3090 | # IMAGES |
---|
| 3091 | # |
---|
| 3092 | #---------------------------------------------------------------------- |
---|
| 3093 | |
---|
| 3094 | |
---|
| 3095 | def GetCollapsedIconData(): |
---|
| 3096 | return \ |
---|
| 3097 | '\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x00\x10\x00\x00\x00\x10\x08\x06\ |
---|
| 3098 | \x00\x00\x00\x1f\xf3\xffa\x00\x00\x00\x04sBIT\x08\x08\x08\x08|\x08d\x88\x00\ |
---|
| 3099 | \x00\x01\x8eIDAT8\x8d\xa5\x93-n\xe4@\x10\x85?g\x03\n6lh)\xc4\xd2\x12\xc3\x81\ |
---|
| 3100 | \xd6\xa2I\x90\x154\xb9\x81\x8f1G\xc8\x11\x16\x86\xcd\xa0\x99F\xb3A\x91\xa1\ |
---|
| 3101 | \xc9J&\x96L"5lX\xcc\x0bl\xf7v\xb2\x7fZ\xa5\x98\xebU\xbdz\xf5\\\x9deW\x9f\xf8\ |
---|
| 3102 | H\\\xbfO|{y\x9dT\x15P\x04\x01\x01UPUD\x84\xdb/7YZ\x9f\xa5\n\xce\x97aRU\x8a\ |
---|
| 3103 | \xdc`\xacA\x00\x04P\xf0!0\xf6\x81\xa0\xf0p\xff9\xfb\x85\xe0|\x19&T)K\x8b\x18\ |
---|
| 3104 | \xf9\xa3\xe4\xbe\xf3\x8c^#\xc9\xd5\n\xa8*\xc5?\x9a\x01\x8a\xd2b\r\x1cN\xc3\ |
---|
| 3105 | \x14\t\xce\x97a\xb2F0Ks\xd58\xaa\xc6\xc5\xa6\xf7\xdfya\xe7\xbdR\x13M2\xf9\ |
---|
| 3106 | \xf9qKQ\x1fi\xf6-\x00~T\xfac\x1dq#\x82,\xe5q\x05\x91D\xba@\xefj\xba1\xf0\xdc\ |
---|
| 3107 | zzW\xcff&\xb8,\x89\xa8@Q\xd6\xaaf\xdfRm,\xee\xb1BDxr#\xae\xf5|\xddo\xd6\xe2H\ |
---|
| 3108 | \x18\x15\x84\xa0q@]\xe54\x8d\xa3\xedf\x05M\xe3\xd8Uy\xc4\x15\x8d\xf5\xd7\x8b\ |
---|
| 3109 | ~\x82\x0fh\x0e"\xb0\xad,\xee\xb8c\xbb\x18\xe7\x8e;6\xa5\x89\x04\xde\xff\x1c\ |
---|
| 3110 | \x16\xef\xe0p\xfa>\x19\x11\xca\x8d\x8d\xe0\x93\x1b\x01\xd8m\xf3(;x\xa5\xef=\ |
---|
| 3111 | \xb7w\xf3\x1d$\x7f\xc1\xe0\xbd\xa7\xeb\xa0(,"Kc\x12\xc1+\xfd\xe8\tI\xee\xed)\ |
---|
| 3112 | \xbf\xbcN\xc1{D\x04k\x05#\x12\xfd\xf2a\xde[\x81\x87\xbb\xdf\x9cr\x1a\x87\xd3\ |
---|
| 3113 | 0)\xba>\x83\xd5\xb97o\xe0\xaf\x04\xff\x13?\x00\xd2\xfb\xa9`z\xac\x80w\x00\ |
---|
| 3114 | \x00\x00\x00IEND\xaeB`\x82' |
---|
| 3115 | |
---|
| 3116 | def GetCollapsedIconBitmap(): |
---|
| 3117 | return BitmapFromImage(GetCollapsedIconImage()) |
---|
| 3118 | |
---|
| 3119 | def GetCollapsedIconImage(): |
---|
| 3120 | stream = cStringIO.StringIO(GetCollapsedIconData()) |
---|
| 3121 | return ImageFromStream(stream) |
---|
| 3122 | |
---|
| 3123 | #---------------------------------------------------------------------- |
---|
| 3124 | def GetExpandedIconData(): |
---|
| 3125 | return \ |
---|
| 3126 | '\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x00\x10\x00\x00\x00\x10\x08\x06\ |
---|
| 3127 | \x00\x00\x00\x1f\xf3\xffa\x00\x00\x00\x04sBIT\x08\x08\x08\x08|\x08d\x88\x00\ |
---|
| 3128 | \x00\x01\x9fIDAT8\x8d\x95\x93\xa1\x8e\xdc0\x14EO\xb2\xc4\xd0\xd2\x12\xb7(mI\ |
---|
| 3129 | \xa4%V\xd1lQT4[4-\x9a\xfe\xc1\xc2|\xc6\xc2~BY\x83:A3E\xd3\xa0*\xa4\xd2\x90H!\ |
---|
| 3130 | \x95\x0c\r\r\x1fK\x81g\xb2\x99\x84\xb4\x0fY\xd6\xbb\xc7\xf7>=\'Iz\xc3\xbcv\ |
---|
| 3131 | \xfbn\xb8\x9c\x15 \xe7\xf3\xc7\x0fw\xc9\xbc7\x99\x03\x0e\xfbn0\x99F+\x85R\ |
---|
| 3132 | \x80RH\x10\x82\x08\xde\x05\x1ef\x90+\xc0\xe1\xd8\ryn\xd0Z-\\A\xb4\xd2\xf7\ |
---|
| 3133 | \x9e\xfbwoF\xc8\x088\x1c\xbbae\xb3\xe8y&\x9a\xdf\xf5\xbd\xe7\xfem\x84\xa4\ |
---|
| 3134 | \x97\xccYf\x16\x8d\xdb\xb2a]\xfeX\x18\xc9s\xc3\xe1\x18\xe7\x94\x12cb\xcc\xb5\ |
---|
| 3135 | \xfa\xb1l8\xf5\x01\xe7\x84\xc7\xb2Y@\xb2\xcc0\x02\xb4\x9a\x88%\xbe\xdc\xb4\ |
---|
| 3136 | \x9e\xb6Zs\xaa74\xadg[6\x88<\xb7]\xc6\x14\x1dL\x86\xe6\x83\xa0\x81\xba\xda\ |
---|
| 3137 | \x10\x02x/\xd4\xd5\x06\r\x840!\x9c\x1fM\x92\xf4\x86\x9f\xbf\xfe\x0c\xd6\x9ae\ |
---|
| 3138 | \xd6u\x8d \xf4\xf5\x165\x9b\x8f\x04\xe1\xc5\xcb\xdb$\x05\x90\xa97@\x04lQas\ |
---|
| 3139 | \xcd*7\x14\xdb\x9aY\xcb\xb8\\\xe9E\x10|\xbc\xf2^\xb0E\x85\xc95_\x9f\n\xaa/\ |
---|
| 3140 | \x05\x10\x81\xce\xc9\xa8\xf6><G\xd8\xed\xbbA)X\xd9\x0c\x01\x9a\xc6Q\x14\xd9h\ |
---|
| 3141 | [\x04\xda\xd6c\xadFkE\xf0\xc2\xab\xd7\xb7\xc9\x08\x00\xf8\xf6\xbd\x1b\x8cQ\ |
---|
| 3142 | \xd8|\xb9\x0f\xd3\x9a\x8a\xc7\x08\x00\x9f?\xdd%\xde\x07\xda\x93\xc3{\x19C\ |
---|
| 3143 | \x8a\x9c\x03\x0b8\x17\xe8\x9d\xbf\x02.>\x13\xc0n\xff{PJ\xc5\xfdP\x11""<\xbc\ |
---|
| 3144 | \xff\x87\xdf\xf8\xbf\xf5\x17FF\xaf\x8f\x8b\xd3\xe6K\x00\x00\x00\x00IEND\xaeB\ |
---|
| 3145 | `\x82' |
---|
| 3146 | |
---|
| 3147 | def GetExpandedIconBitmap(): |
---|
| 3148 | return BitmapFromImage(GetExpandedIconImage()) |
---|
| 3149 | |
---|
| 3150 | def GetExpandedIconImage(): |
---|
| 3151 | stream = cStringIO.StringIO(GetExpandedIconData()) |
---|
| 3152 | return ImageFromStream(stream) |
---|
| 3153 | |
---|
| 3154 | #---------------------------------------------------------------------- |
---|
| 3155 | def getCheckedData(): |
---|
| 3156 | return zlib.decompress( |
---|
| 3157 | 'x\xda\x01\xaf\x01P\xfe\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x00\x17\ |
---|
| 3158 | \x00\x00\x00\x16\x08\x06\x00\x00\x00+v\x07\x05\x00\x00\x00\x04sBIT\x08\x08\ |
---|
| 3159 | \x08\x08|\x08d\x88\x00\x00\x01fIDAT8\x8d\xc5\x95Mj\xc2P\x14\x85\xbf\x17\xad\ |
---|
| 3160 | \xd6\x1fp\t\x82#\xc76\x11\x91B\xad\xa3\x16\xa4\xa8\x9d\xb8\x10\xe9*\xa4\xd3"\ |
---|
| 3161 | \xddA\xd1\x06;\x97\x96\x8eK7\xe3@1!\xb7\x03m\x88&\x9a\xa8)\xbd!\x83\xf3\xee\ |
---|
| 3162 | \xe1{\x87\x97\xfb\x08JK\x10\xd7kL\x0c\xf1\xea$1T\xdd\xac\xc9\x92\xa5o]\x8b\ |
---|
| 3163 | \x03\x1e\x04\x06NK^5uqp\\]\xa4\xc8\x17\xdf\xae>)\xb9\x17\x8c\x03\xe3\x8e\xa9\ |
---|
| 3164 | \xbc\xfd\xa3\x92\xebfE\xbc\xba\xa0\nL\xef\xdf\xd5\xb6\xcfM~\xf9Z\x97\xbaY\ |
---|
| 3165 | \x93mCh\tL\xdb~\xb0\x0b\xd7\xcd\x8a,\xd4\x82%K\xc260\xcc\x8b\x8d\xbef\xef>\ |
---|
| 3166 | \xd9d\xcd\xac\x8a\x8d\xed.\xa4%\xbd\x13*\xac\x9e\xdf\xeaez\xf4;\x0f\x81\xa9W\ |
---|
| 3167 | \x1b{\xc0\x00\xb6\xd8\x81F/\x14\xc0\xb1\x1c\xfa7\xbb\xc1\x10\xf0A\xe7j\xbe\ |
---|
| 3168 | \xa1\xb7\xc7\r\xa0q\xde`\xd0y\xdc\x0b\x86\x1d\xa3\xd8}k\x0b@{t\xe7\x03;\x96\ |
---|
| 3169 | \xc3\xe06\x1c\x0c\xa0\x8c\x89\x11mB\x04J\x94x\xe9\x8e"\x81\x01\xb4\x9c\x95\ |
---|
| 3170 | \x8bd,\xaa\xe2A`\x00\xad\xac\x95\xf7\x1a\xc4\x12\x8c3\xc3w\xfb"\xc1\xc3\x0cz\ |
---|
| 3171 | V\xe7\xa95<\x18\x0c\xa0\x94\x96\xf0]gX%\xd6\xb3:\xc3\xd6\xf3Q`X\'O\x91\xf25\ |
---|
| 3172 | \x9a\x99\xe6I`X\'\x07\xb8\x1e_\xc9L\x9b\x01\x90\'\xcfG\xe7\xf3$\xf0\x06\xfc/\ |
---|
| 3173 | *\x96?\xd1\xbf\xc0\x7f\x00\x07#sW\xd1Zw\x10\x00\x00\x00\x00IEND\xaeB`\x82\ |
---|
| 3174 | \x03\t\xb8>' ) |
---|
| 3175 | |
---|
| 3176 | def getCheckedBitmap(): |
---|
| 3177 | return BitmapFromImage(getCheckedImage()) |
---|
| 3178 | |
---|
| 3179 | def getCheckedImage(): |
---|
| 3180 | stream = cStringIO.StringIO(getCheckedData()) |
---|
| 3181 | return ImageFromStream(stream) |
---|
| 3182 | |
---|
| 3183 | #---------------------------------------------------------------------- |
---|
| 3184 | def getUncheckedData(): |
---|
| 3185 | return zlib.decompress( |
---|
| 3186 | 'x\xda\x01\xe4\x01\x1b\xfe\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x00\ |
---|
| 3187 | \x13\x00\x00\x00\x16\x08\x06\x00\x00\x00"\x9d\xa7\x7f\x00\x00\x00\x04sBIT\ |
---|
| 3188 | \x08\x08\x08\x08|\x08d\x88\x00\x00\x01\x9bIDAT8\x8d\xb5U;O\xc30\x10\xbe\xb3\ |
---|
| 3189 | \xa9H\x93\x896\xc9\xd6f\xec\xd0\xb1]`\xe8\x06##\xfc\x84\xfe\x1d\xf8;\xb0C\'\ |
---|
| 3190 | \xd8*\xb1u)\x12Q\x1f\x03mB\x1f\xc91D6\x8e\xed\x14\x89\xc7\'EQ\xee\xce\x9f\ |
---|
| 3191 | \xbf{\xd8Ad\x1c\xfe\nL7\xe4\x94S\x1a\xb5\xe9\xd0\xa24jS\x1a\xb5i_w\xe8\xf5\ |
---|
| 3192 | \xfaJ\xc6\x96\xc8\x84c\xddl\x1eTP\x8bc`\xab\x15d\xae\x0b\xcer)\xed(\xd2\xdc4\ |
---|
| 3193 | \x1b\x04\x00\xc0\x93\x04X\x92\x14;!C\x95d_wH\xf8\x00\x00v\xbe\x0f<I\xe0(\xfd\ |
---|
| 3194 | \xc0\x92\xb2\xe3\xf9\x02\xb9\x12h\x03\xb3\xf8\xe3\xcb\xcb\xaf\x0fd\\>\x84H\ |
---|
| 3195 | \xfa\xb3\xeev)\xf3<\xc3\xbe\r\x02R\xd7"\xe3\xe5\x9a\xe5\xaek\xec\xec\x8e\xc7\ |
---|
| 3196 | \x86\xa2\x9d\xef\xc3\xba\xd73\x95\x97\x82\xc2\xd0J\xa8\xe3=\x8a\xa0qw\x8f\ |
---|
| 3197 | \x86C\x97\x8a\x8c\xc36\x08\x8c\xb4\x08\x912\xcf\xa3y\xbfo\xa4gMSUXe\xf7\x9f\ |
---|
| 3198 | \x9eME\xb64\x05jql\r\xce\xbe)\x81A\xb6i6\xa86\x9bY\x83\x9d\xc9\x04\xd4\x89\ |
---|
| 3199 | \xd7\x81\xea\xd9\xd4\x87\x12\xa0\xe8\xb0n\xd3\x87\xd9\xaa\xccF\xa4\xbe\x05\ |
---|
| 3200 | \xaa\xd41\x80"\xb5\x9cr#\xe0e8\x94\xcdP\tOF#X\\\x9c\x1b\xf1\x0c\xa08\x8f6ton\ |
---|
| 3201 | K\xe9\x08\xc2\xaaF 2\x0ei\xd4&\xb5\x83,IJuY\x9f\x9d\x12\x9bN%\xd1\xb6\xd5\ |
---|
| 3202 | \xb2\x0e-\x13\x01\x99\xeb\xc2.\x0c\xad\xbbz\x0f\x8f\x08P\\MUD\x92l\xdbj\xc9\ |
---|
| 3203 | \xdapM\x95@\xda\xe9\xc0\xdb`PI$\xd3\x14\xd8\xd7\x1d\x12w\xd3O\x80\xff\xfa\ |
---|
| 3204 | \x0f\xf8\r>\x01lo\xba\\\x08x\xd9{\x00\x00\x00\x00IEND\xaeB`\x82\xd6d\xd4\xb4\ |
---|
| 3205 | ' ) |
---|
| 3206 | |
---|
| 3207 | def getUncheckedBitmap(): |
---|
| 3208 | return BitmapFromImage(getUncheckedImage()) |
---|
| 3209 | |
---|
| 3210 | def getUncheckedImage(): |
---|
| 3211 | stream = cStringIO.StringIO(getUncheckedData()) |
---|
| 3212 | return ImageFromStream(stream) |
---|
| 3213 | |
---|
| 3214 | |
---|
| 3215 | def getRunBitmap(checked=False): |
---|
| 3216 | if checked: |
---|
| 3217 | bmp = getCheckedBitmap() |
---|
| 3218 | else: |
---|
| 3219 | bmp = getUncheckedBitmap() |
---|
| 3220 | return bmp |
---|
| 3221 | |
---|
| 3222 | |
---|
| 3223 | #---------------------------------------------------------------------- |
---|
| 3224 | def getStopData(): |
---|
| 3225 | return \ |
---|
| 3226 | '\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x00\x18\x00\x00\x00\x18\x08\x06\ |
---|
| 3227 | \x00\x00\x00\xe0w=\xf8\x00\x00\x00\x04sBIT\x08\x08\x08\x08|\x08d\x88\x00\x00\ |
---|
| 3228 | \x038IDATH\x89\xa5\x95]o\x1bE\x14\x86\x9f\xfd\xb0\xd7\x1fk\xc7\x9441m#\x12(T\ |
---|
| 3229 | \x14\x81PDS\xae\xe0"w\xdcrU\xa9\xff\xaf?\x01n\xb8\xa7v\x89T\x90\xa8\x84R@\ |
---|
| 3230 | \x04Gi\x9a\xb8q\xfc\x91\xf5\xec\xcc\x1c.v\xd7\xd9\x8d\x137\x88W\xb2\xb4\xda3\ |
---|
| 3231 | \xf3\xbcg\x8e\xcf\x9eq\x1c\xd7\xe3:\xeav\xb4\x008\x0e\x88\xc0\x83-\xdf\xb9\ |
---|
| 3232 | \xce>g\x91A\xb7\xa3\xe5/{\x82\t4\x81x\x94+\xe71\x15\x81V\x0e\xebnk\xa1\xd9\ |
---|
| 3233 | \x9c\xc1\xde\x9b\xb1\xbc\xda\r\xf8m\xda\xa7\\\xb7l\xdc\x08x\xbf\x15P/{TK\x1e\ |
---|
| 3234 | \x0e`E\x88\xb4\xe5$\xd2\xec\x9f*\xf6\x8f5k\xe6\x1d\xbe|0o4g\xd0\xedh\xf9\xc5\ |
---|
| 3235 | \x1e\xb2\xd5.\xb1\xbe\xda\xa4^^\\B+p\x1aiv\xf6\xc6\xb4FKs&\x05\x83g]-\xcf\ |
---|
| 3236 | \xcd!_\xaf\xd7\xf8`9L\x17,\xe4\xcf$\x02\xcfzC\xbc\xc3F\xc1df\x90\x87\x7fx3\ |
---|
| 3237 | \xbc\x1e\xf5\x12u\xff)\x9a\xb8Y\xe0\xb99\xe4\x8b\x15\xff\x7f\xc1\x016o\x85\ |
---|
| 3238 | \x9c\x84\x03:;S\x01\xf0!\xa9\xfb\xcb\xd2\x11\x1b+\xcd\xc2b}t\x8c\xff\xea`!P\ |
---|
| 3239 | \xaf\xb6\xf1\x97\xdf\x05\xc0X\xc1\x08\xdc\xbd\x19\xf0\xfa\x0f\x8f\xfe(\x12\ |
---|
| 3240 | \x1f\xe0\x85\xeaso5\xa0U\xf5\x0b\x9b\xbd\x1f\xbe\x87\'O\xe6\xa9\x9e\x07\xc6$\ |
---|
| 3241 | \x8f\x8f\x1e\xc1\xe3\xc7(#\x00\xc4\xc6\xd2\xac\xf8\xbc\xb4Sv\x7f\xf7\x93\x12\ |
---|
| 3242 | \xc5\xbe\xe6V\xb3|\xbd\x1a\xe4\xe0\x00N\x18"\x92\x80\x93_b$K\x11\x00n\xb7\ |
---|
| 3243 | \xa3\xa5\x1e\xb8\xb4*\xfe\xa5\xbc\x194S\x0e\x0e \xa3\x11\xc4\x8a\xd8\x08\xb1\ |
---|
| 3244 | \x11\x94\xb1(cy\xaf\xe12T\x1a7k\xc3\x8a\xefr\xa5.@/J\xa6S\x00\x94\xb1\xc4V\ |
---|
| 3245 | \x88\xadP\xf6\x1dFg\x86Y\xda\x9e{\xcd\x86\xcf+w\xb2\x0cn\xd2\x12\xa9dt\xe1\ |
---|
| 3246 | \x8a\xa4IZ\xf9\xef\x06\xe9\xc9\xecT\xcd\xe0\xb1\xd6\xc4Z32\x10V\xbd\xe4OVc\ |
---|
| 3247 | \x97H\xdb\xb7fyY\xcc\x99L\x00\x88\xa61\xb1\xd6\xb3\xec\x87\x13KX\xb7\xb8\xd9\ |
---|
| 3248 | $<\x1e\xc7I6\x92\x9cF\x94Zl\x92v\x93\xd4j\xa8\xd4$\x83[\xady3H*\xe2\x03\xdc\ |
---|
| 3249 | \x0fn\xb0\xfbz\xc0\xed\xa5\x00\x93\xb6\\\x8d\xa4\x05\xcd\'\xf7\x17V\xc9\x05\ |
---|
| 3250 | \x94["\x8a\xe2\xe2\xfb\xbe\xe6\xe1W\xcb\x8e\x0f\xc9\xa0\xda?6\x1c\xb4\x15\ |
---|
| 3251 | \xad\x8aOl\x84\x01.\xcd\xedm\x9c\xedm\xecT\x156\xab\xc9\x04\xe5\x96(\xdb\x04\ |
---|
| 3252 | \xda\x93\xe0<f\x85\xbfO\x1c\xee\xac\xd5\x81\xdc\xb0\xeb\xecL\xa5\xc7)\xdf|\ |
---|
| 3253 | \xdcH\x16\xa6]\x91)\xeb\x0e\xa0Pk\x9b=\xa7k\xe3\xa9\xa1\xf7\xa7\xc3w\xdf\xb6\ |
---|
| 3254 | \x8b\xc3nk3p\x9a\xaa\xc6\xce\xde\x18el\x01\x9c\xef\x8eXk\x94\x16\xa2(\xc6j\ |
---|
| 3255 | \x8d\xb22\x07\xff|\xf3\xfc\xea+|\xbe\x8d\xb2\xcfpP\xe1g\x19\xf3\xe9Ju.\xdbL\ |
---|
| 3256 | \x198\xaf\x0c~{C\xf8\xa8\xdd\x9a\xbf\x0f\xf2\xfa\xf1\xa7\xb1\xf4\xf4\x98{k%\ |
---|
| 3257 | \xc24<\xba\xf01\xfb&\x9e\x81\xf7\x06%\xdc\xbe\xe6\xceZ\x9d\x87\x9f5\xae\xbe\ |
---|
| 3258 | \xd1\xf2z\xfa\xebP\x0e\x8e\x84A)\xa2QshT]\x1a\xb5\xa4\xa2\xc3\x89exf\x19N\ |
---|
| 3259 | \x84\xfa\xa9\xbd\x14\xfcV\x83\xbc\xd1h\xec2:3\xe8\xb3\t\xe3\xa6\xcbR\\!\xacz\ |
---|
| 3260 | \x84u{%8\xd3\xbf\x07\xf8\xd8d\xb6\xf93\n\x00\x00\x00\x00IEND\xaeB`\x82' |
---|
| 3261 | |
---|
| 3262 | def getStopBitmap(): |
---|
| 3263 | return BitmapFromImage(getStopImage()) |
---|
| 3264 | |
---|
| 3265 | def getStopImage(): |
---|
| 3266 | stream = cStringIO.StringIO(getStopData()) |
---|
| 3267 | return ImageFromStream(stream) |
---|
| 3268 | |
---|
| 3269 | |
---|
| 3270 | #---------------------------------------------------------------------- |
---|
| 3271 | |
---|
| 3272 | def getSageIconData(): |
---|
| 3273 | return zlib.decompress( |
---|
| 3274 | 'x\xda\x01s\x06\x8c\xf9\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x00 \x00\ |
---|
| 3275 | \x00\x00 \x08\x02\x00\x00\x00\xfc\x18\xed\xa3\x00\x00\x00\x03sBIT\x08\x08\ |
---|
| 3276 | \x08\xdb\xe1O\xe0\x00\x00\x06+IDATH\x89\xb5V[oU\xc7\x15^k\xcd\xec\xbd\xcf\ |
---|
| 3277 | \xdd\xe7\xd8.6\x17\x03\xe6j\x0c\xae0\xd4Ih\xa0\t)A\xa8IT\xd4(/\x95\xfa\x90\ |
---|
| 3278 | \xa8?\xa8}\xe8[[\xa9J\x1b\xb5\xaa\xa0JS\xf5!j\xa9Dn$\x90\x00\xa1\\\xe2\x10HC\ |
---|
| 3279 | \x08\x81\xe3\xdb\xf1\xf1\xb9\xec=3\xeb\xeb\xc3\x01\x83\xaa \x15J\xd7\xd3\xd6\ |
---|
| 3280 | \xec\xf5}\xeb2#}\x1f\xef<\xfc\xc3\x85\xc5E\x80\x0103=\x8a\xe8Q1\xa3\xaf\\\ |
---|
| 3281 | \xb6\xf5\xd9\xd9f\xab\ra\xc1#!\xbf\x1d\xca\xc4\n\xe7\x9c5&"#L\xa4 \xe2GT\xa4\ |
---|
| 3282 | \xb7\x0b\xc3\xc6D\xc2\xcc\xacPU\x00\xcbC\x88>\xf0\xae\x96!\x02\x02\xa0\xaa\ |
---|
| 3283 | \xac`f\xdb;ef\xb9\xf3\x9b\x88\x88\xf1\xc0\x1b\xbb\x07b\x98\x94\x99@Dd\x97\ |
---|
| 3284 | \x13\x94I@\xbd>\x96?\x1e`\x82\xfb`\xe5\x1b\xb3\x1f|C\xf7\x85\xd8\xe5\xa7)\ |
---|
| 3285 | \xca\xbd1{\xa3<D,\x03EY\xefPXU\xcd\xb2,\x80X\x19\xc2\xacP\xa3y\x9bx\n>c1\nR(\ |
---|
| 3286 | \x91\xd1|R\x88HR\xcd\xd2,\x18\xcf\x1c\x8b@\x88T\x95l\x12G\x1c\x1a\x9d\xae\ |
---|
| 3287 | \x10\x1bc,1\x14\x1d\xc7\xc5\xa2\xb7\n\xfa\xf6\xb6M\xc3\xab\xfbE\x08\x81D\x08\ |
---|
| 3288 | dO\xbc\x7f\xbeT\x88\x1f{|w1F1.\xe5\xe2|\xa5R\xbat\xf9\xf3#o\x1e\x13\xe2\xa9\ |
---|
| 3289 | \x9d;\xd6\x8d\x0e\xda\xd8\xb3\x18\x0b\x13\xe7\xe3k\x9f\xd5?<s\xf5\xe5\x1f\ |
---|
| 3290 | \x1cZ\xbfj0sh\xb4\x17\x9a\xdaqi\xe7\xd2\xf9\xaf\xed\xf8\xd8\xc8\xd43#Jj\x94\ |
---|
| 3291 | \x85\xa2\x8c;L\xf6\xe2\xf9\xca\xe4\x13\xeb7\xee\xe8\x8b\x9a\xc5\x88L_\xb9rp\ |
---|
| 3292 | \xcf\xde\xf7\xce]|\xf5\xf57\x0e~o\xcf\xae\xef\xaf\x0c.\xa3n\xc1S\xd0\x94:iV\ |
---|
| 3293 | \xac\x16\x96\x16\x9b?:\xf4tl\xf5\xe4\xb9K\xca1[\xca\xd7dh\xc5\xb8]72\x08\xf8\ |
---|
| 3294 | so\xcd\x9d97mH\x9e}~\xe7\xc8\xe6\x1c3\x95+9M\xc3/~y\xa4\x99v\xb6\xac]\xfd\ |
---|
| 3295 | \xc5\x17\xf5\xa3\xc7\x8e\xe5l\x92\x14\xc0\xd0O?\x9a;~\xfc\x12\xc7v\xb86\xf0\ |
---|
| 3296 | \xe2\xe1}\x0b7\xafv\x83{\xef\xd4\xc7\xcdf\xf3g\xbf\xf9C)_0l\x7f\xf2\xd3\xef\ |
---|
| 3297 | \x96\x8ay\x0b1b\xf9\xe6\xd7\x0b7\xeau\x11\xb9\xf0\xd1\xf5\xfa\x8d\xf2B\xb3\ |
---|
| 3298 | \xf9\xee\xf1O\xca\x85|\xa3\xd5.\x98h\xdb\xe6\xedo\xbf\x7fz\xfa\xf2\xd5|\xb1\ |
---|
| 3299 | \xf4\xce\x07\xd3&\xe1\xe9K33\x8d\x19k\xa3\xe6\xfc\xdc\xc9S\xfd\x93c\xdb\x0b\ |
---|
| 3300 | \xb9w\xcf~2\xbdfx\xd8\x10\x03!(\x03\x89\x04\xb6\xce)\x14{\x0fn\x98zr\x84-\ |
---|
| 3301 | \xa7i\xb8rqv\xa1\xd1\x18\x1e\xac\x8e\x8d\r\x8fO\xad\xc9\x1b\xfa\xce\xd8\xc4\ |
---|
| 3302 | \xc7g\n\'.\x9c\xb5\xaa\xc5\\T\x1b\xccW\xfaK\xcf\x1d\xd8[\xae\x19\x0f\xef\x1d\ |
---|
| 3303 | \xb5}\x8b\xc4$69\xf0\xc4\xee\\\x91S\xb4<\xfb\\\x9f\x0f\x99\xb7gNMG\xf1\xa6\ |
---|
| 3304 | \xd2\x80$U\x03p\xae\xea\x9e\x1cY\xdbl\xa5\xbb\xf7\x8d\x14k\xc1\xb5\x12\x84\ |
---|
| 3305 | \xee\xec\xd2\xc2\xee\x89\x89\\\xf2z\xd6u\xb5\x95\xa55\xa3\xfd\x17N\xd6GG\x87\ |
---|
| 3306 | \xca\xab\xad\xcbP.\x13\xb9\xd8{mv\x97\n\xe5R\xb5Th8\x9f\x89v\x9b!\x0eb\x17\ |
---|
| 3307 | \x96\xdao\xfc\xe9\x84\xc9\x19\x86\xf1]=ph\xd7\xda\xed\xe9\xd0`\x1f\xb1K\xeb\ |
---|
| 3308 | \xf1\x1f_{;\r\xd9\x96u_\xbd\xf2\xd2K\xc5b\xf1V\xeb\x16\xbcs!\x03\xeb\xef~\ |
---|
| 3309 | \xff\xb7|>\'0/\xbf\xf2,\x8b\xf3\xdd\xf6\xd6\xb5\xeb\xff\xfa\xe6[\xbf:r4\xc9\ |
---|
| 3310 | \x17\x0c\xc8{_-W\xed\xfe\xa7v\x8el\xa8\xfc\xf6\xd7\xc7\xaf~u\x9d\x9c.-\xb6\ |
---|
| 3311 | \xd8TI\xc9\xb2\xb4:Y\xbd\xb1H\xc6\xa7\x99k,\xce\x97\xf3\xc9\xc0\xfa\x8d\x99k\ |
---|
| 3312 | \x82-\xac4\xe6\x1a\x8b\xb9\x0e{\xb26:}\xfab\x9ae\xe3\x9b\xd7\xbf\xf3\xe1\xd9\ |
---|
| 3313 | \xa5F\xb3\xeb2\xf5\xe6\xc7/\xee\xcf\x15c\x1bG\xe4\x93\xf6\x9e\xa7\xc6\xc7n\ |
---|
| 3314 | \x8e\x90\t\xabF\xfb\xbc\xf76\xc7.\xa0\\\x8b\xf7=\xbe]A\x93[v\xd4\xe7\xe7\xb6\ |
---|
| 3315 | n\xdc\xb4n\xc5\xd0\x07\x9f\x9d\xd5\xd0\x99\x9cZ\xb5\xa2V\xf4\xc4B\xbe\xd6_\ |
---|
| 3316 | \x99\x99\xef\xd4\xaa\xb54M\'\xb6n\xde\xb7w\x8a\x89l,\xab\xb6\x95b\x9fX\xcb\ |
---|
| 3317 | \x11A6\x8c\x95\xedx\xd5\x91\x0b\x81\x96f\xa2sg\xff900\xd1\xbf!y\xe6\x85\x89\ |
---|
| 3318 | \x1c\x15\x1f\xdb\xb4\xeb\xe8\x9f\xff^-\x15\'\xb6o\xf9\xcb\xb1\x7f\xb4g\xc7j\ |
---|
| 3319 | \x03\x18ZYVE\xce$\x85bd\xc0CC+>\xbdv\xfd\x85\xfd\xfb\x922\xcda\x0e\x94:\xe7\ |
---|
| 3320 | \xae\\\x9c\xe3\x89\xc3\xcfC\x19\xc1\x89X x\xefgg\x96Zi;_.\x0c\rT\xe0a\xa2d\ |
---|
| 3321 | \xcf\xe4\xe4\xf4\x95\xab\x95B~\xdb\xe8\xa6\x9f\xbf\xf6j\xb5\xd4W\xab\xf6\x19\ |
---|
| 3322 | \x06\x04\xd6\xc4I\x92\xa8\xd3\\\x12\xb9\xe0\xab\x95\xf2\x97\xd7o\x92U\xf8\ |
---|
| 3323 | \xe0\x95\xd2\xd4\xd9\xf9\x85\xa5\xb9\xd9\xf9 \xc4\x10""\x811b\x12\xe9v\xbb\ |
---|
| 3324 | \xff\xfa\xbc\x1d\x98XH\x9df!4\n\xc9|\xb3].\xe4;\xddv\xf3Z\x13\x86\x00\x108\ |
---|
| 3325 | \x12\xb3rE\xed\xd6\xac:\xd7\xbd\x8c\xd0Z\xea\x1a&\x02\x8b\xc8`\xb5j\r\x8b\ |
---|
| 3326 | \x8d\xd8\x08\x1b\x15\x00j\x84\xc0\x02\x80\x83\x89"\x16\xb1\x1an\xdc\xba\x01k\ |
---|
| 3327 | \xeb\rJ\xf8V\x08\x81\x19\x12Y\x16\xe2@\xccL\x1cn\xd4\xe7\x8cae\x81\x0f\xb9(\ |
---|
| 3328 | \x860\x00V\xa8\t\x16\xc4L\x96\x01\x05\x89\x11V\xcfdU\x94aY\xc8 \x80)0\xc4;O\ |
---|
| 3329 | \x1c\xc8\x0b\x1b%0\x1b(D<\xb3\x81\x1a\x12\n\x04\t\xc2\x02(X\t\xe2`,\x91\xb5D\ |
---|
| 3330 | D\x1c\x88D\r\x03$l\x94!j\x08\x80\x90\xb2\x12\x89h\xc4\xa4\xc2d@\x81\x95\x99\ |
---|
| 3331 | \x05\x8e\x85\x03\x0c\x81\x8c\xa8\x80\x03\x91\xb0:\x82\x11\x10\x0c!\x12\x90\ |
---|
| 3332 | \x04X\xe1\xdbbc\xf4\x1eW\xc1\xa0\xdb\xfa\'\xbd\x0e@$D\xb8\xabE\x02\x90\x10\ |
---|
| 3333 | \x88\x08`"2 \xcf0`\xea!{TF,p\x1b\xa1\x82e9}\x08\xc9\xbcW\xd4\x96\xe5\x0c\xc0\ |
---|
| 3334 | 7k\xf2CH\xe6\xfd \xf6?2\xeeZ\xa3\xff\xa1\xc6\xbd\xc6\xe2v\x01\x00\x01l\xf8\ |
---|
| 3335 | \x8e\xf5\xb8G\xb5\xff[\xf6;\x10\x01\x05\x10\x11z\x97a\x01@X\x88\xa1\xa4|\xf7\ |
---|
| 3336 | >\x1e\xb4\xfde\x88211\x0b\x83\x08\x80\r\xc1QP\x08K\xaf\xea\xa3\t(\x88\x15!8\ |
---|
| 3337 | \xfb\xad\x81\x81(\x8a\xfeO\xf6\xbdZ\xa9\xfc\x1b\'\x9f`y\x8c\\\xb8\xf0\x00\ |
---|
| 3338 | \x00\x00\x00IEND\xaeB`\x82e\xd2)\xef' ) |
---|
| 3339 | |
---|
| 3340 | def getSageIconBitmap(): |
---|
| 3341 | return BitmapFromImage(getSageIconImage()) |
---|
| 3342 | |
---|
| 3343 | def getSageIconImage(): |
---|
| 3344 | stream = cStringIO.StringIO(getSageIconData()) |
---|
| 3345 | return ImageFromStream(stream) |
---|
| 3346 | |
---|
| 3347 | def getSageIcon(): |
---|
| 3348 | icon = wx.EmptyIcon() |
---|
| 3349 | icon.CopyFromBitmap(getSageIconBitmap()) |
---|
| 3350 | return icon |
---|
| 3351 | |
---|
| 3352 | |
---|
| 3353 | #---------------------------------------------------------------------- |
---|
| 3354 | def getSageData(): |
---|
| 3355 | return \ |
---|
| 3356 | '\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x01u\x00\x00\x01;\x08\x06\x00\ |
---|
| 3357 | \x00\x00"\xaf\x11\xd4\x00\x00\x00\x04sBIT\x08\x08\x08\x08|\x08d\x88\x00\x00 \ |
---|
| 3358 | \x00IDATx\x9c\xec\xbd{x\x1c\xe5y6~\xcfaO\xda\x83v\xad\xf5J\xb2\x0e\x16\xb21\ |
---|
| 3359 | \x08[\x8aA\x96c\x08\xf6U\x88\x82\x81\x12N\r\x816!?\xd2\x03Iq\x93&_RZ\xda\x92\ |
---|
| 3360 | 4\x906m\x9a4|I\xe0KH\x9a\xf2\x85\xf0\x05Jj\x08%\t6\x0e\xa6\xb6\x03\xc4\xb6\ |
---|
| 3361 | \xc0\xf8$\x03\x96,\xeb`I\xeb\x95w\xb5\x07\xedi\x0e\xbf?F\xef\xec\xcc\xec\xec\ |
---|
| 3362 | jw\xb5+\xad\x94\xb9\xafK\xd7\xca\xab\xdd\xf5\xec\xcc;\xf7\xfb\xbc\xf7\xfb<\ |
---|
| 3363 | \xf7C\xb9\xba\xbbE\x180`\xc0\x80\x81e\x01z\xb1\x0f\xc0\x80\x01\x03\x06\x0c\ |
---|
| 3364 | \x94\x0f\x06\xa9\x1b0`\xc0\xc02\x82A\xea\x06\x0c\x180\xb0\x8c`\x90\xba\x01\ |
---|
| 3365 | \x03\x06\x0c,#\x18\xa4n\xc0\x80\x01\x03\xcb\x08\x06\xa9\x1b0`\xc0\xc02\x82A\ |
---|
| 3366 | \xea\x06\x0c\x180\xb0\x8c`\x90\xba\x01\x03\x06\x0c,#\x18\xa4n\xc0\x80\x01\ |
---|
| 3367 | \x03\xcb\x08\x06\xa9\x1b0`\xc0\xc02\x82A\xea\x06\x0c\x180\xb0\x8c`\x90\xba\ |
---|
| 3368 | \x01\x03\x06\x0c,#\x18\xa4n\xc0\x80\x01\x03\xcb\x08\x06\xa9\x1b0`\xc0\xc02\ |
---|
| 3369 | \x82A\xea\x06\x0c\x180\xb0\x8c`\x90\xba\x01\x03\x06\x0c,#\x18\xa4n\xc0\x80\ |
---|
| 3370 | \x01\x03\xcb\x08\x06\xa9\x1b0`\xc0\xc02\x82A\xea\x06\x0c\x180\xb0\x8c`\x90\ |
---|
| 3371 | \xba\x01\x03\x06\x0c,#\x18\xa4n\xc0\x80\x01\x03\xcb\x08\x06\xa9\x1b0`\xc0\ |
---|
| 3372 | \xc02\x82A\xea\x06\x0c\x180\xb0\x8c`\x90\xba\x01\x03\x06\x0c,#\x18\xa4n\xc0\ |
---|
| 3373 | \x80\x01\x03\xcb\x08\x06\xa9\x1b0`\xc0\xc02\x02\xbb\xd8\x07`\xc0\x00\x01MQe\ |
---|
| 3374 | \xf9\x1cA\x14\xcb\xf29\x06\x0c,E\x18\xa4n`Q\xa1%r\x96a\xe6\xf5y\x1c\xcf\xab>\ |
---|
| 3375 | \xd3 \xf8\xfc(t"5\xce\xe3\xd2\x81A\xea\x06\x16\rz\x84\xce\xf1\xbcL\xec\xac\ |
---|
| 3376 | \xc9\x94\xf3\xbd\\:\r\xd6d\x02\x97Ng\x9eS\xbc\x97\xe3y\xf9\xff0\x08)\x1b\xc5\ |
---|
| 3377 | \xae\x8a\xc8\xeb\x8dsY\xfd0H\xdd\xc0\xa2@I*\xca\xe8\x9ce\x98\xbcd.\xbfn\xf65\ |
---|
| 3378 | \x85\xbc\xd6 v\tzD^\xcc\xca\xc8X\x05-\r\x18\xa4n`\xc1A\x88AK(Z\x82\xb6\x9a\ |
---|
| 3379 | \xcds~V"\x95R\xbd\x9fD\xeeF\xc4\x9e\x81\xf2|+W3z \xd7@\xb9\x02\x92\xff\xa68\ |
---|
| 3380 | \xa7\xe4\xb3\x94\xf8]=\xbf\xd5\x06\x83\xd4\r,(r-\xfb\t\x99h\x89\xdcf\xb5\xe8\ |
---|
| 3381 | \xbe>\x9eHf\xbd>\x91J\xa9H)\x17\xf9\xfc. \xd7^E!\xd2V\xbe\xbfs\xe9\xb4\xea\ |
---|
| 3382 | \xb3\x94\xe7\xf6wy\xe2\xac&\x18\xa4n`Q\xa0G.J\x82\xd6\x92\xb9\xddfC,\x1e\x97\ |
---|
| 3383 | \x1f\xbd\x1e7b\xf1\xb8\xfc\xf7x")\xbf_I\xee\xe4\xff"\xd2\xc1r%\x9d\x9c\x93e\ |
---|
| 3384 | \x9e\xd5P!+!\x02\xb2"\xd2\xeec\x142i\x96+\xab\xa9\x14,\xd7\xeb\x9d\x0f\x94\ |
---|
| 3385 | \xab\xbb\xfbw\xef[\xff\x0e#\xdf\r\xa6\xbd\x01\xc42\xde\x10\x14E\xa9H\x95\xa6\ |
---|
| 3386 | (\x95~N\x08FI\xe6v\x9bm\xce\xcf\x8d\xc5\xe3r\xd4\xae\x94b\x08\x08\x01\x11\ |
---|
| 3387 | \xe2)\xf7M\xae\xfcN\xa2(B\x10\x04\x08\x82 \xff\x9d\x17*\x7f{14\x854\xc7I\xc7\ |
---|
| 3388 | C3\xaa\xe7\xa5\xe72\xe5(&\x96\xcd\xda\xb7\xb0\x9a\xcd9WD@fU\x04\xa8\xcf\xb1\ |
---|
| 3389 | \x9eD\x93\xe28\xd5y \xdf_\x10xp\xb3\xc7\xb8P`Y\x164\xcd\xa8\xce\x03M\xd3\xf2\ |
---|
| 3390 | X\x04\x96\'\xe9\x1b\x91\xfa\xef\x00\x04Q\x84(\x08Hs<\x04!\x13U\x91\x9b\x8ce\ |
---|
| 3391 | \xb3\x87\x81\xf2f\xa8\x148\x86\x01\x95N\x83\xa2(9\x9b\x05\x90\x88]I\xe8.\xa7\ |
---|
| 3392 | 3\xeb\xbd\xe1H\x04\xa3\x93~Yf\x11D\x11\xa2(\xca7lV\x84Z\x86h]\x10E@\x14\xc1\ |
---|
| 3393 | \xf3<xA\x94\x89\x8aeY\x98X\x16&\x9a\x81\xd3\xe1\x98\x93$\x17\n\xb9&E\xe5\xf9\ |
---|
| 3394 | t;\x9c\x08E#\x08G"\x00\xd4\x93$ ]\x0b\xbd\xef\xa2\x95\xba\xa4\xf7%\xc0\xb2,\ |
---|
| 3395 | \xac\x16\x0b\x9c\x0e\x07<.\xa7|\x1c\xe4\xfft;\xb2\xafe%\x10\x8aJ\xdf\'\x1c\ |
---|
| 3396 | \x89\xc8\xdf)\x91J!63\x83\x99x\\\xben4\xcd\xc0lbAQ\x14\xa8E\\Q\x94\x13\xcb\ |
---|
| 3397 | \x8e\xd4i\x8a\x02/\x08\xe08N\xbe\xf1\x96"L,\x0b\x8b\xd9\\2\x01\xd1\x14\x85d*\ |
---|
| 3398 | \x854\xc7\xc1\xc4\xb2\xa8u\xb9\xd0\\\xefCk\xe3*\xb4\xaej\xc4\nW-\x00\xa0\xde\ |
---|
| 3399 | d\x82\xbd\xc1\'\xbf\xcf\xdb\xe8@`<\no\xa3\xa3,\xdfC\x0b\xf2\xd9\x81\xf1\xa8\ |
---|
| 3400 | \xfc\\l\xc2\x8f\xc9\xd9\xa8opt\x14\xe1hT\xbe)\x95 \x84\xf0\xe6\xc9\x93\x08\ |
---|
| 3401 | \x04\x83\x00 \xdf\x88\xca\x9bR\x10E\xa48N\x97\xdc\x8bE:\x9d\x96\xa3`\x13\xcb\ |
---|
| 3402 | \xc2n\xb3ae\xdd\n4\xfa|\xe8Z\xb7\x0e+\\\xb5hoi\x82\xb7\xd1\x01/\xed\x81\xb5\ |
---|
| 3403 | \xae\x06\xde\xda:\xf9\xfd\xf5\x1e\x1f&\x83\xfeE{\x9c\xeb8\x00\xe0o\xbe\xfe-<\ |
---|
| 3404 | \x7f\xfc\x84\xfcZ\xe5\xca\xa3\xce\xed\x86\xd7\xe3\x96\xaeS<\x0e\x9b\xd5"K]\ |
---|
| 3405 | \x89T\n\x91h\x14&\x96\xc5\xfa\x8b\xd7\xe2\xea\xeenlZ\x7f\x19\xbc\x8d\x0e4\ |
---|
| 3406 | \xafl\x9a\xf3<T\x02\xda\xcfV\x9e\x03\x00\x18\x1d\x1cA@\x08\xe2\xec[\x83x\xfd\ |
---|
| 3407 | \xcc\x19\x1c\x7f\xef]\x9c>;\x8c\xe8\xcc\x0ch\x9a\x81\xc5lZ\xf2\xe4\xbel\xe4\ |
---|
| 3408 | \x17\x9a\xa2\xc0\xf1<\xa2\xb1\x18\x00\xc0\xe9p\xc8\x03\xd2\xe5t\xc2\xedp\xc2\ |
---|
| 3409 | \xe5\xa8\x0cQU\x02\xc7\xdf{\x17\xfd\x03\x83`J$\xa5\x99x\x1c&\x96\xc5\r\xdb\ |
---|
| 3410 | \xb6\xe1\xf6\x0f}\x10\x1b\xbb.\xc1\xfa\xb6\x8e\x9c\xaf\xd7#\x82B\xa0|O1\x843\ |
---|
| 3411 | \x17&\x83~\x8c\x0e\x8e\xe0\xd4\xd8\x08\x06G\xc6p\xe4\xd4)\x00\xc0\xf0\xf8\ |
---|
| 3412 | \xb9\xa2\xce\x8b\x92\xd8\x95\xdao\xbe\xc9\x92\xa6(\xcc$\x92H\xa5\x92\xb0\xd7\ |
---|
| 3413 | \xd4\xa0uU#\xde\xdf\xf5>\\y\xd1E\xf8\xc0u[u\xcf\xa3\xf2\xbc\x05\xa6\xa7\xe4\ |
---|
| 3414 | \xdf\x13S3\xb0\xd6\xd5`\xf4\xfc\x18\xbc\xb4\x07\x01!\xb8`\x8f\xcd+\x9b\x90\ |
---|
| 3415 | \x98\x9a\x91\x8f\xc5ZW#\x1f\x0f\x00\xfcf\xf7~<\xf2\xf3\xe71|n\x1c\x14M\x83\ |
---|
| 3416 | \x02\xb2\x08M\x10\x04\\\xda~\x11\\NgV4\x1f\x8d\xc5\xb0\xad\xa7\x07\xf7~\xe2\ |
---|
| 3417 | \x16l\xef\xe9\xcdy>\x94\xe7Dy<\xcac\xd5C0>\x05\x8f\xad\x0e\x81\xf1(\x18wR\ |
---|
| 3418 | \xf75Zxlu\xaa\x7f\x93\x89\x16@\xd6$C\xd0\xd7\xd7\x87\x9f\xec\xde\x85]\x07\ |
---|
| 3419 | \x0e\xa0\xff\xf4\x00lV\xeb\xbc\x02\xaa\xc5\xc6\xb2!\xf5\x99\xd9M\xb3m\x9b{\ |
---|
| 3420 | \xd0\xb5n\x1d\xae\xef\xdd,G\x0b\x95\x8a\n*\x89\x87\x1f}\x14_\xfa\xf6\xb7\xe1\ |
---|
| 3421 | v\xb9\x8a\x1a\\4E!:3\x83\xe6\x86\x06|\xf5/?\x83\x8f\xdd|+\x80\x0cI\xbe\x17;\ |
---|
| 3422 | \r\x00\x08\xc5B\x88Fc\xba\x9f\x11\r%\xe0p[u\xff\xe6\n: \xb4\x88\xa0G(\x84=Q\ |
---|
| 3423 | \xf9\xdf\x00@\x8fP\xf2\xef\x00\xe0L\xd7\xab\xde\xcb\xb8\x93\xe0C\x16\xf9\x06\ |
---|
| 3424 | %7\xa0\xf2\xc6\x0327\x9f\xf2\xba\x9d\x18\xea\xc7\x91\xa3\xef\xe0\x1f\xbf\xff\ |
---|
| 3425 | 8\x86F\xc7`* ?\x9d\xc0\xac\x90\x97\xe6\xd2\xd6\x05A@4\x16\x83\xd7\xe3\xc1M\ |
---|
| 3426 | \xd7\\\x83\xde+\xdf\x8f\xde\xadW\xc9\xc7B\xcec@\x08\xe2L`\x00\xd1h\x0c\x11q\ |
---|
| 3427 | \x1a\xb1d\x0c\xf1d\x12\x9c i\xceI.\x05\x8e\xd7K\x0b4\xa9\x9e/\xf4\xdf\xca\ |
---|
| 3428 | \xc7|`g5u\x86f\xc0\x0b<\x18\x9a\x01K+6\xa0-\x16\xd8-v\x1c\xf8\xd5Y\xbc\xf2\ |
---|
| 3429 | \xda\xeb0\x9b-\xb0Zro\x98\n\xa2\x08GM\r.[\xbb\x06@F\xce\x00\x80\xbf\xfb\xd4\ |
---|
| 3430 | \xbd\xaa\xf1\x15\x98\x9eBbjFE\xd2\xc1\xb8D\xe6\xe4\xba\x87b!\xd5\xe7k\xc7`4\ |
---|
| 3431 | \x94\xc8y,!!\n\xea\x82\x03\xe2\ni\x95\x17N\x85u_\x97BH>O\xe4\\\xb2\x8c\t,\ |
---|
| 3432 | \xcd\xc0\xc2\xda`\xb3X\xd0`]\x85\xe6\xfa&\\l_\x8b\xe6\xf6\x16\xd4{|81\xd4\ |
---|
| 3433 | \x8f\x1f\xfe\xf49\xfc\xf0\xd9\x9f!\x95\xe6Pc\xb5,Ib_\xf2\xa4\x9eN\xa7\x11O$p\ |
---|
| 3434 | \xedUW\xe2\x8fo\xbb5\xe7\rH\x06W5#\x14\x0b\xe1"\xef\x1al\xef\xe9-\x89\xd4\t\ |
---|
| 3435 | \xa1_\xdc\xb6\x1aO>\xf40\xba\xbb\xbbqb\xa8\x1f\xbf:\xf4+\x9c\x9c\x18\x84\xc0\ |
---|
| 3436 | \xc4@\xf3\xf6\xbc\x9f\xe12\xbb\xe4\xdf\xc9\rD]p\xa0\xd6\x9b\xfdZ&U\x0b\x9bO"\ |
---|
| 3437 | \xe8\xb8\xdf"\xff\xae$~%\xc9\x03\x12\xd1k\xa3.\xbd\xe8\n\x80*\xc2"\xd7\xb4\ |
---|
| 3438 | \xe7#\x7f\x80\x13\xef\x9d.;\xa9\x8b\xa2\x88x"\x81\x1a\xb3\x05\xb7_\xbf\x1d\ |
---|
| 3439 | \x7f\xf1\x91\x8f\xa0\xbb\xbb\x1b\x804\xa1\x1c\x1b>\x8a\xfe\x89\x93\x08\x84/ \ |
---|
| 3440 | \x96\x8af\x11\xb6\x92l\xf5\x88\xb5R`i38!\xa5"n@"o%\xec\x16\xe9\xba;\xa9Z\x8c\ |
---|
| 3441 | ^\x08\xe0\xa9\xffx\x05\x89t\x1a,M\xcf=\xbe\x04\n\xeb\xda[\xd1\xda\xb8\n\xc3\ |
---|
| 3442 | \xe3\xe7\xe0r:q\xff}\x1f\xc7\xf6\x9e^\x99\xccG\xcf\x8fe\xbd\x8dD\xda\xda{\ |
---|
| 3443 | \x8f\x0fY\x101M\xc2\x99\xaeG\xc44)\x8f\x13e\xa0\x10\xf6D\x11\xf7[\xc0\x9b\ |
---|
| 3444 | \xa7u\x0f)$Du\x9f\x0f\xa7\xc2\xb0\xd9(\xc4\xe3"L\x96\xcc5\xe2geXN\xe0\xb3&M\ |
---|
| 3445 | \xaf\xb3\x0e\x9bV\xf7\xe0\xaemw\x02\x00\x9ez\xe1y|\xf1_\xbf\x89\xc0\x85\x0b\ |
---|
| 3446 | \xa8)`\xb3\xbe\xda\xb0\xa45\xf5\x99x\x1c\xde\x15+\xf0\xc8\x8e\x1d\xb8\xf7\ |
---|
| 3447 | \xde{\x01H7\xe0\xdec{q\xf8\xec!\x04"S\xba\xd1R5\xe3t\xe0=\xd5R\xb6\x98H\x81D\ |
---|
| 3448 | \xe8\x84\xd0w\x1d\xda\x83\x9f\x1ez\n\x1c\x9f\x86\x19n\x15\xa1\xdbl\x14L\xbcz\ |
---|
| 3449 | \xd3\xcaM;\x10\x12\xa2p\xd3\xb32\x95\x17\x00\x1c\xb3\x8f\x12\x08\x91kI\x1c\ |
---|
| 3450 | \xbe(\x1c\x0e\xbb\x8a\xc8\xc9#!re\x94\x0e\xe4&s\x00\xaa\xc8\x9d,\xdd\x03\xd3\ |
---|
| 3451 | S\x08\x04\xd5\x91^\xa1 \xa9x\xda\rS\xb2\x07\x13\x89F\xb1\xa9s\x03\xbe\xfa\ |
---|
| 3452 | \xd7\x7f.\x9f\xff]\x87\xf6\xe0\xb53\xfb1\x11\x9a@,\x19\x93\x89\x9b\xa5\x19\ |
---|
| 3453 | \x15q\xe7C9\t]K\xdc\xb9\x9e\xcfG\xe8\x0e\x87\x1d\xbfy\xe67\x88\xc5\xe3`Y\xa6\ |
---|
| 3454 | \xa0\xf1\xc5\x8b\x9c\x1c\x9d\xbb\x9cN\xfc\xf1m\xb7\xaa\x08=15\xa3+\xa3h\t]{\ |
---|
| 3455 | \xfd#\xa6I\x00P\x11:\x00\x99\xd0m\xbe$\xa2:\x97;\x1f\xa1\xbb\xcc.\xa4\x11\ |
---|
| 3456 | \x81\xcdF\x01PNx\xd2\n\x8a\xa1\x19XX\xe9|\xf1\x02\x0fN\xe0\x11\x88L\xe1\xc5\ |
---|
| 3457 | \xb7\xff\x1b\x87\xcf\x1e\xc2\'\xb7\xfe\t>v\xf3\xad\xf06:\xf0\xf1\xcf\xfc=\ |
---|
| 3458 | \xc2\xb1\x99\xbc+\x99j\xc4\x92%\xf5p$\x82\x8e\xb5kT\x11\xe9\xfe\xfe}x\xe3\ |
---|
| 3459 | \xcc\x1b\xf22\x95U\\\xc0\xa5\x80X2&\xdf\x80\x04\x85fk\xa4\xd3i\x98X\x16_\xfd\ |
---|
| 3460 | \xcb\xcf\xc8\x84\xfe\xe4\x1bO\xc0\x0c7jm\x92N\xaa"q\x9d\xfd\xe3\\7\x8b\x12JB\ |
---|
| 3461 | \'\x11\x95,\xc38D\xe9\xf7\x11)R\'\x91\x18A\xc44\t7\xa4M7>d\x01t\x82 \xa2\xfb\ |
---|
| 3462 | \xe6\x832Eo.\x98Y6+\xb7Z\tN\x10\x10\x8dFq\xfbu\xd7\xe1\xb1\x87\x1eD\xbd\xc7\ |
---|
| 3463 | \x87\xbe\xbe>\xfc\xf4\xe4O1\x11\x9a\x90\xc7\x91\xf6\xba,$r\x919\x81\xcdbA<\ |
---|
| 3464 | \x99\xcc"s\x00\xaa\xe3v8\xec8\x1dx\x0f\xa3\x93\x92\xdeMQ\x85\x9dG\x8a\xa2\ |
---|
| 3465 | \x10\x0cKz\xfa\x9dW^%K.\x84\xd0\xb5{\x06\x04\xdaH\x9dL\xeczQ\xba\xd0"\xc25\ |
---|
| 3466 | \xe2\x90\x89\x9d\x8c3\x98\xb3\xe5\x18e\xf0\xa1\x1c\xb36\x1b\x854"\x88\xc7EE\ |
---|
| 3467 | \xb4\x0eY\x12\xd3\x82\xa1\x19y\xd2\xb5\xb0fL\x84&\xf0\xb5\xff\xfeG\xdc\xbd\ |
---|
| 3468 | \xe5\x1el\xef\xe9\xc5#\x7f\x1b\xc5\x9f=\xf8e\x08\x82P\xd4\x98[l,\x9d#U`&\x1e\ |
---|
| 3469 | \xc7\xa6\xce\rx\xf6\xd1o\xca\x04\xf6\xed\xdd\x8f\xe0\xc0\xe9\xfd\xf2\rha\xcd\ |
---|
| 3470 | \x15]\xf6V\x1b\xe2\x89\x04\xee\xbc\xf1F|\xec\xe6[qb\xa8\x1f?=\xf4\x14\xccpg\ |
---|
| 3471 | \x067\xefD\x9a\x89\xe4\xd4!It.G\xe9:p\xb8\xad\xaa\x08\x9d\x909\x90\x89\xb6\ |
---|
| 3472 | \x1c\x0e\xbb\x9cM\xa3\xbcy\x81\x8c\xc6\xee\xb1\xd5eI0\x84\x10\x94\x1by\x80zs\ |
---|
| 3473 | \xcb[[\x87\xf6\xd6\x16\xa4\xb9\xe22\x9a\xacf\xb3n\x85\xa4(\x8a\x88F\xa3\xb8\ |
---|
| 3474 | \xe7\xf6\xdb\xf1\xd8C\x0f\x02\x00\xbe\xf7\xab\xef\xe3;\xbf\xfd.\x02\x91\xa9\ |
---|
| 3475 | \xaa\x18G\xf9\x08\xddf\xb1\xc8D\xae\x17\x9d+\t\xddI\xd5\x82\xf6Q\xe0f\xcc\ |
---|
| 3476 | \xe0\xd2\xe9\xa2H\x8a\xa6i\x04.\\\x00\x00\xdcr\x87D\xe8\'\x86\xfa\x01($2\xc5\ |
---|
| 3477 | *\x8b@\xb9\x12\xe3C\xd2\xf11\xee\xa4<&\x9c\xe9z\xd5~\x0c!tW\xd0!\x8f3&U\x9b\ |
---|
| 3478 | \xf3\xb8\xb4A\x88\x89w\xc2\xc4;e\t\xd1f\xa3\xe6\x9c\x10\x95\xb0[\xec`\x19\ |
---|
| 3479 | \x13\x9e\xed{\x1a\'\x86\xfa\xf1\xb1\x9bo\xc5\r\xdb\xb6!\x91L.j\x01U\xb1Xr\ |
---|
| 3480 | \xa4\x1e\x8eD\xb0\xb1\xe3R<\xf1\x8d\xafb}[\x07\x9e\xde\xf7\x0c\x9e|\xe3\t9\ |
---|
| 3481 | \xca\xfd]"r\x82t:\r\x9b\xd5\x8a\xbbn\xff \x00\xe0?\x0f>\r\x00\xb3K\xd0\xcc#\ |
---|
| 3482 | \xa0\xd6\xcc\x95P\xc9.:\xd0\xbb\xb9H\xa4\xae\x95]\x94$\xce\xb8\x93p\xdb\xdd\ |
---|
| 3483 | \xaa\xa57\x89\xe0\xb4\xd0n\x98\x02R4\xa8$\xf6\xaeu\xeb\x8aNSM\xa4R\xba\x91z<\ |
---|
| 3484 | \x91\xc0\xa6\xce\r\xf8\xe7\xfb?\x8fz\x8f\x0fO\xee\xf9\x89\x1c\x18,\xe6\n\x8f\ |
---|
| 3485 | \x10\x91\x1e!\x11"\xcf\x17\x95kW\x15Dv\x11\xfc"\x9aWx\xe1\xb0\xdbU\x05R\x85\ |
---|
| 3486 | \x80\xd44h3\xa4\xc8\xaaJ/\x83E)\xbd\x90k\xaf\x8d\xd4\x81\x0c\xa1;\x1cvyLi%>-\ |
---|
| 3487 | r\x8d\xd5p*\x8c4#E\xeb\x00\xe4\xc7B\xc9\xdd\xc2\x9a\x91H\'\xf0\x1f\xfb\xff\ |
---|
| 3488 | \x1d\x00\xf0\xd0\x17\xee\x83\xa3\xa6fIYM,)RO$S\xf0z<\xf8\xea_\xff\xb9L\xe8/\ |
---|
| 3489 | \xbe\xfd\xdf\xb0\x9a\xac\x8b\xba<\xae$\n\xd2<\x05\x11m\xcdM\xd8\xb8\xb6\x0b\ |
---|
| 3490 | \'\x86\xfa129%\xeb\xe7$z!\xbfk\xe1\xa6\x1d\xf2\x8f\x1e\x98T-\x1cnk\x96\xec\ |
---|
| 3491 | \x02@\x97\xd0\x9d\xe9z\xd0#\x94|\xd3\xf2!K\xc1Z\xba\x9e\xf4B\x08\x9d\xe8\xea\ |
---|
| 3492 | \xd7\xf7n\x86\xcdj-\x88\x94h\x8a\x82\xc3.\x9d\x07m\xa4\xce\xf1<\x1c55\xf8\ |
---|
| 3493 | \xde\x03\x7f\x8bz\x8f\x0f\xdfx\xf6\xdfpd\xe2MXM\xd6\xaa\x08\x0c\xf4tr%\x91\ |
---|
| 3494 | \x93H\x9c\xfc\\\x08%\x10\x08_\xc8\x8a\xce\t\xa1G\xa31\xd0>\n\xcd\xf5M\xb8\ |
---|
| 3495 | \xe2\xb2\xcb\xe4\xdc\xfb\x82\x8f\x87e1<~.+%U\x19\xa9\xe7\xd2\xd4\x95\xd7[\ |
---|
| 3496 | \x19\xa9\x03\x90\xa3u2\x8e\x94\xd1\xba,\xc1\xe8\x80D\xe9\xdaq\xeb2\xbb\xe4h\ |
---|
| 3497 | \x9d\xc80d3\xb9P\xd8-vL\x84&\xd0\xd7\xd7\x87\xf5m\x1d\xb8b\xc3\xfa%\x15\xad/\ |
---|
| 3498 | )RO\xa5\x92\xf8\xec\xddwc{O/v\x1d\xda#\x13z5\xdc\x84\x95B!\x03I\x10xt\xb4\ |
---|
| 3499 | \xafA\xbd\xc7\x87c\xc3G!0R\x9a\x98\x89w\xca\x91K.\x90\x9b#\x97\x9e\xce\x9b\ |
---|
| 3500 | \xa7\x11\r%dB\x8f\xfb-\xaa\x1b/\x1a\x8d\xc9\xd2\x0b E\xe9B\x8b\xa8\x8a\xc6\ |
---|
| 3501 | \xb4R\x8b6\x1bBI\x06Z\xe9\x85\x909!\xf7\x8dk\xbb\xf0\xa1\xab\xaeB4\x16\x9b\ |
---|
| 3502 | \xf3\xdc\x90\xfct\xad\xc7\t\xcb0\x88\xc6b\xb8\xe7\xf6\xdbd\xf9\xaeZ\x08}.2\ |
---|
| 3503 | \x07$\xd2\x89%c\x18\x99\x9cB ,\xc9"g\xdf\x8cb\xefs\x03\x002d\xae\x84\xc3a\ |
---|
| 3504 | \x87+&=w\xc7\x1dW\xa3\xb9\xa1\x01|\x11\xd1\xa7\xc5lF\xff\xc0 \xfe\xf9{?\xc4\ |
---|
| 3505 | \x89\xa1~\xd5\xea\t\x90\xae[\xf3\xca\xa6\xac\xf7)5u"\xc1\x90\xb1\x01H\x85g\ |
---|
| 3506 | \xd1h\x0c\xd1hL\x1eWq\xbf\x05\xe7\xa8\x00\xa2\xa1\x84*\xfbe: \x8dS\xe5X\x1dN\ |
---|
| 3507 | \x9c\x03 E\xe8\xda\x1f@\x8a\xd4\xe3q\xb1(\x19\x86`\xef\xe0\xff\x00\x90\xf6\ |
---|
| 3508 | \x11\xa4b\xc6\xe2V7\x8b\x85%\xb1QJ\x8aA6un\xc0\xbd\x7ft\x07&\x83~\xbc\xf0\ |
---|
| 3509 | \xf6\xcf\xc12\xa6E\xbf\t\xab\x014\xcd\xa0uU#\x00)-\x92\xe3\xd3\xa8\xb5Q\x08\ |
---|
| 3510 | \xc73\xe9]\xb0IKR=\xf9e8q\x0e.\xb3+\x8b\xd8\x95Q\x90D\xee\x00\xcc\x89LF\x82\ |
---|
| 3511 | \x07\xb3\x91T\x0c\xf0@\xde\xe8")\x8d$\x1a\x0b\xc5BY\x190\xca\x08N.\x9a\x99\ |
---|
| 3512 | \xd2\xcfzQ\xa2\xde\xe3\x93\xbfk\xbeU\x8c(\x8a`M&\xd8\xac\x16y\x93\x8f@2\x04\ |
---|
| 3513 | \xf3\xe0O\xff\xf06\x00\xc0\xcb\xa7^\x02P\xdeL\x15 \x93]\x01 o\x16\x962\x1d2\ |
---|
| 3514 | \t\x85\x950\xcd\xc8\x11&!%\x9b\xc5\x82@\xf8\x02~\xf9\xd3\x93\x08\x85\xc3\xb0\ |
---|
| 3515 | Z\xad\xf0\xb8\x9c\x88\'\x92\x18\x1a\x1d\xc5\xf1\xfdk\xf0\xa1\x1bW\xc9\xf9\ |
---|
| 3516 | \xdf\x0e\x87\x14\xb9\xd3>\n\x98M\t\xf7\xd8\xeap\xcbG\xdf\x8f\xff\xf3\xdd\x17\ |
---|
| 3517 | ab\xd9\x82V\x83\x0c#e\xca|\xf7\'O\xe1@_\x1f\xbe\xf0\xd9\x8f\xe2\x9a\xcekT\ |
---|
| 3518 | \x9b\xa5\x85f\xc1\xb8\xedn\x00I\\d[#gV\x91J\xe3`|\n\xa8\x07\xc8\x1f\xc8x\xe1\ |
---|
| 3519 | C\x160\x97\xa87Z\x01\xa86\xe2\x01u\xde{D\x9c\xc6t0\x8dp*<+\xc3\x98d)r\xae\ |
---|
| 3520 | \xc8\x9deL\x98\x98\x9d0\xba\xbb\xbb\xe1v\xb9\x90L\xa5\x8aJ\xa5],,\tR\x17D\ |
---|
| 3521 | \xa9\xdc\xffs\x9f\xb8\x1b\xf5\x1e\x1f\xbe\xf7\xab\xefc:\x1e\\\xb6\x92K)\xe8\ |
---|
| 3522 | \xa8\x93n\x82\xf1\x884\x109!\x05\x93\x05\x00\xcc2\xb1\x93\xec\x00 \x13\xc5\ |
---|
| 3523 | \x03\xc0\xe6\xb5\x9dp\xdb\xdd\xb8\xd8\xbe6K\xd3\xce\x05\x12Ek\xa3i\xad\x06\ |
---|
| 3524 | \xae\x07eua@\x08\xca\x95\x85\xda\xff{\xae\xcf\xc9\x07\x11\x90\xbdGHI;\x01\ |
---|
| 3525 | \xd9T^\xdf\xd6\x81]\x87\xf6`"4Q\x96\xb1DH\x9cd_\xd9\xcd\x0e\xb8g\x8b}\x00dE\ |
---|
| 3526 | \xcfJD\xc4\xe9\xbc\x7fW\x92\xf3\xb97\x03\xb80\xfd\xbala0\x1d\x0e\x83\xa6i\ |
---|
| 3527 | \x98\xcd\x16\x0c\x8f\x9f\x03\xb0\x01\xaev\x07\x04\xbf(\xbf\x87D\xe9d"\xbd\ |
---|
| 3528 | \xe1\x8ak\xb1\xbb\xf5\x08\x06\x86G\x0bN\xd9\xa3)\nV\xab\x15\x87\x8f\x1d\xc77\ |
---|
| 3529 | \xbf\rt~\xa3\x0b@f"&\xd7Q\t2yw\xb6v\xc1\xdb\xb9\xb0\x85\x80D\xfb\x0fLO\xe1\ |
---|
| 3530 | \xd8\xf0Q\xec\x7f\xf7\x80\xac\xb1\xdbl\xd2w\xceE\xee\x16\xd6\x8c@d\n\x93A?\ |
---|
| 3531 | \xacu5p\xbb\\\x18\x9d\x980H\xbd\\\x98\x89\xc7qq\xdbj\xf4n\xbd\n\x93A?\x0e\ |
---|
| 3532 | \x9f=4ge\x9d\x1e\x947\xddBb>\x84QP\x14ES*\xff\x16\xe5\xb9!y\xbaJb\x8f\xc7E\ |
---|
| 3533 | \xc4\x11FK}\x1d>\xba\xf9.\xb9\xec\xbdX\x8b\x00B\xba\xda\x0c\x15\x82\\\x04/\ |
---|
| 3534 | \x97\xd9\xb7I\x0f\'\x86\xfau\xb5t\xbd\xf7O\x06\xfd\x18>7\x0e w\xba\xa7 \x08\ |
---|
| 3535 | \xf0z\xb2\xb31X\x93\t\x89D\x02f\xb3\x05\xbdW\xbe\x1f\x00\xf0\xda\x99\xfd%\ |
---|
| 3536 | \x8d%%H\xf5h\xad\xcd\x83Kk/Bg[WE\xab\x99\'\xdb\xfd\xf8\xc5\xae>\x1c}\xe7=0,\ |
---|
| 3537 | \r\x13\xc3@\x14\x05X\xcc,\x86F\xc7p\xf0\xf41lFg\x86\xccu\n\x87\x9bW6\xe1\xa3\ |
---|
| 3538 | \xb7^\x8d\x7f|\xe4)9_\xbf\x10\xd0\x14\x05\xb3\xd9\x82\xd1I?\x12S3hno\x91\'ib\ |
---|
| 3539 | K\xa0\x8c\xd6/\xb6\xaf\x95\x8b\xb8&\x83~\xf4\xf5\xf5\xe1\xd4\xd8\x88\xec\xf7\ |
---|
| 3540 | s!,\xc9++\\\xb5\xb8\x10\x9e\xce\xf9\xa8\xf7\x9a\\\xef\x03 \xfb\xf1\x90\xebp\ |
---|
| 3541 | \xd7\xb6;\xd1\xd9\xda\x85\xff<\xf84F&\xa5\xe3%)\x8f\xf9@\xc6\xa0\xd7\xe3\xc6\ |
---|
| 3542 | \xd0\xe8hA\xe7h\xb1\xb1$H\x9d\xe38l\xbf\xfaj\xd4{|xz\xdf3H\xa4\x13E\x13%\xb9\ |
---|
| 3543 | \xf1\x1a\xdc\rh\xb0\xae\x92#\x1fi)X9\x84b!\x1c\x1b;\x8e$\x17/iy_H\x9e:\xb17%\ |
---|
| 3544 | \xa4\xcc\xf1iU\xf6\x06\x89F\xa4\x9c]\x80,C\t\xa1?\xf5\xc2\xf3\xd8\xf3\xfao1<\ |
---|
| 3545 | 1\x8eq\xbf_eeK\xa2\\\xed\xa3\x16\xca\xbf\xeb\x818/\xba\x9cN\xb464\xa2\xbd\ |
---|
| 3546 | \xb9\x19\xed-M\xe8\xddz\x15\xd6\xb7u\xe0\x04\xfaU\xe9\x8cz\x84^\xef\xf1I\x05\ |
---|
| 3547 | AG\x8e\xc0^S\xa3{^x\x9e\x87\x89eU&T\xca\xe3Ks\x1cV\xf9Vbc\xd7%\x98\x0c\xfa1\ |
---|
| 3548 | \x11\x9a(9\xd3\x85\x17x$\xd2\t\xd4\xda<\xd8\xba\xeej\\\xd3yMV5\xf3\x11\xe1(\ |
---|
| 3549 | \xce\xbe58\xe7g\xd9\x1b|\x88M\xf8U\xbf+\'j-\xae\xee\xeeF \x18B(\x1cF\x9a\xe3\ |
---|
| 3550 | T\x0e\x9cO\xffp?\x8e]<\x8e\xdf\xdf\xde\r\xd7%\xb5\xba\x99F\x00p\xc7\x87n\xc3\ |
---|
| 3551 | /v\xf5\xe1\xf0\xb1\xe3EU.34\x85D"!\xf9\xcb\xa0E\xf57\xe5f\xb7\x97\xf6\xa0\ |
---|
| 3552 | \xbb\xbb\x1b\x93A?\xfe\xf9{?\xc4\xae\x03\x0700,\x11\xe3BX\xf1\x9a\xcd\x16\ |
---|
| 3553 | \xb8\xec5hkn\xc2\x9f]\xb7\x1d\xf7\xde{/\xee\xab\xdd\x81\x87\xfe\xeba\xb9\xe2\ |
---|
| 3554 | 4\xdf&*\xc7\xa7\xa5\xfc\xfb\xda:\xd9er)x\xf2W=\xa9\xa7\xd3i\x98\xcd\x16\\\ |
---|
| 3555 | \xdf\xbb\x19\x00\xd0?q\xb2\xe8\xc8*\x96\x8caM\xfd\x1a\\u\xd1Vl\\\xdb\xb5\xe0\ |
---|
| 3556 | K\xc0\xf1\x97\xcf\xe1l`\xb8b\xfa?CS\xb2\xab\xa2\xb2\xf21\x17\x04&\x86\xce\ |
---|
| 3557 | \xa6-X\xdf\xd6\x81\xc7\x1f\x7f\x1c\x9f\xf9\xcew\x91J%u-x\xf5@\xcfYEI\xc1D3\ |
---|
| 3558 | \x00\xc5\x80f\xa4\x8d\xc9D*\x85`8\x02k0\x84\xc1\xe1\x11\xfc\xf6\xe8\xdb\xb0\ |
---|
| 3559 | \xdbl\x18\x1c\x19\xc3\x83;vH\x91\xb9\xe23\xf4"\xf5\xa7^x\x1e\x7f\xff\xbf\xbf\ |
---|
| 3560 | \x83\x0b\xa1\xe9\x9c\x92\x01\xb1|U\x1aP\xa9\xbe\xbb \xa0\xbd\xb5E\x96^\x92\\\ |
---|
| 3561 | \xaa$R\'\x84~\xf5\xda\xad\xb8m\xcbm\xb2w\xc8\xcf\x9f}\x1e\xbb\x8e\x1dC\xff\ |
---|
| 3562 | \xe0\x00\xceO]@8\x96]H%\x08<h\x9a\x91\x1fS)i\x12U\x9e\x7f\x9af`b\x19\x95\xff\ |
---|
| 3563 | 9\xb1\xf4%\x93c{\xabD\xa8\xe3~\xbf\xdc<\xe4\xbd\xa1\xb3\xb0Z\xad8\xd2\x7f\n\ |
---|
| 3564 | \xa7\xcf\x0e\xe3\xda-[\xd0\xb2A"\xa4\xe6\x15^t\xb6u\xc1\xdb\xe3\x01\x86\xa4\ |
---|
| 3565 | \x15\xd3\xe7>q7\xfe\xe2\xe1\x7fD\x9a\xe3\x8a2\x8f\x13xIZ\xa9\xf7\xf8\xb2\xf6\ |
---|
| 3566 | >\xacu5\xc0\xf9 \x9a\xdb\xa5\xe3\xfb\x9b\xaf\x7f\x0bO\xec\xdc\xa9\xf2\x99QV\ |
---|
| 3567 | \xf4\x02s\x1b\xaci_\x93\xf5\x9c@\x01t\xc6\xab_\x10E@\xa0\x10O&q\xf8\xd8q\x1c\ |
---|
| 3568 | >v\x1c\x00p\xef\xbd\xf7\xa2\xb3i\x03\xde8\xf3\x06H\xc5\xe9\\P\xf2E\xb5\x13:\ |
---|
| 3569 | \xb0\x14H\x9d\xe3\xd0\xdc\xd0\x80\xe6\x95M\x98\x0c\xfa1vaL.\xd1.\x04\xb1d\ |
---|
| 3570 | \x0c\x1b\x1b\xae\xc0\xdd\xbd\x1fW\xddx\xfdS\x01\x84\xc2\x11\x84\xa3sWQ\x96\n\ |
---|
| 3571 | =\xf7\xbaJ\xa0\x98F\x0c\xc4\x03ck\xc76L\x06\xfd\xf8\xc1\xee]H\xa5\x92p\xd9]\ |
---|
| 3572 | \xaa\x9b"\x17\xb4\x83:g\x03\xe9\x1cM\x18\x88\xc77\x89|^=|\x08\x9b\x0f\xed\ |
---|
| 3573 | \xc1\xf6\x9e\xde,r \xf2\xc5\x89\xa1~|\xe3\xfb?\xc6\xb3/\xbd\x84d*\x95\xd7\ |
---|
| 3574 | \x8f\xc3\xe3r\xa2\xd1\xa7\x9e\xb4\x95v\xb1\x11\x9aF\xd7\xbau\x002Y8\xc5\xa6\ |
---|
| 3575 | \xbc\x11\x19\xef\xa6\xf7}\x18wm\xbb\x13\x93A?>\xff\xb5\x7f\xc2\xf3{~\x8d\xd1\ |
---|
| 3576 | \x89\t\x95W\xb7\x89e@e\x15\xfa\x98T\x8ff\xb3IER4E\xc9\xdfQ\xd9<D\xeb\x8fN\ |
---|
| 3577 | \xac\x88\xdd\x0e\'6^z)\xee\xfd\xa3;p\xdf\x97\x1e\xc6\xce\xdd\xbba6[\x90L\xa5\ |
---|
| 3578 | \xf0\xab}\xfb`z\xdd\x84D2\x85\x1a\xab\x05n\xd7/p\xc5e\x97\xa1\xb3\xab\x11G\ |
---|
| 3579 | \xea\xdf\x81\xb7\xd1\x81\xb5\xab[q\xe2\xbd\xd3\x05\x93\xba\x94B\xbb\x12\x9d\ |
---|
| 3580 | \xad]\x98\x0c\xfaU\xfb*\x80\xb4W\xd2\xbc\xb2I\xae\xce}q\xef^\xb8].U\x97$2\ |
---|
| 3581 | \x8e\n!I]\x89M\xfb\x1c-f\xff\x8d\x16\xc1\x08,\xdc.\x17B\xe10~\xb0{\x17n\xb9\ |
---|
| 3582 | \xe3Vl\xed\xd86K\xeasc)xFiQ\xf5\xa4\xceq\x1c\xda[[\xe0\xad\xad\xc3\xe8\xe0HQ\ |
---|
| 3583 | \xd2K\x92K\xa1\xd6\xe6\x91\t\xfd\xf3_\xfb\'\xfc\xf0g\xff\x85T*\xa3\xa9W\xc2o\ |
---|
| 3584 | \x9d,+\xb7wv\x02=\xd2\xc4R*\x8a\x8d\x0c\xe2\xc9\xb9-J-\xacY>\x9f\xa3\x93~\ |
---|
| 3585 | \x98\xcd\x16\xfd\x9b\xa2\xc0\xe3\xcb7\t(\xe5\x18-\xa1\x13R"\xde\xeaz\xd1\xf9\ |
---|
| 3586 | ?\xfc\xe0\x9f\xf0\xfd\x1f\xff\n\x81\x0b\x17`b\xd99\r\x96F&&\x11\x0cG\xd0\\\ |
---|
| 3587 | \xefS\xfd\x9f\x80\xd4\xc1\x87\xa2iySytR2\xa1Rf\x98\x14B\xee\x89tB&\xf4\x13C\ |
---|
| 3588 | \xfd\xf8\xecW\xfeEv<\xb4\x98\xcdE\x9b@\xe5j\xc4M\xa0mRA\xce_(\x1a\x91\x9b\\\ |
---|
| 3589 | \x00RD\xf9\xd0\x17\xee\x83\xcb\xe1\xc0\x8b{\xf7"\x14\x89H\x16\xb2\x82\x00\ |
---|
| 3590 | \xb3\x89E\x9a\xe30\x19\x08\xe0\x85W^\xc1\x8b\xaff\xfe/\x97\xbd\xa6\xe0\r@Q\ |
---|
| 3591 | \x14\xc1\xd0\x14>w\xcb\xadX\xdf\xd6!\xfb\xbfh\x89\x9d\xa0\xaf\xaf\x0f\x89tZ*\ |
---|
| 3592 | \xe0\xc9a\xd5PQ\xd0"\x04\x11p\xd8\xed\x18\x1a\x95\xae\xb7\xb7\xb6\x0e\x16\ |
---|
| 3593 | \xd6\\\xd4*m\xa1\x9a{\x94\x03UO\xea\x80tB\xeb=>\xec\x8d\xed-\xea}\x1c\x9f\ |
---|
| 3594 | \xc6\xd6u\x92\x16\xff\xf0\xa3\x8f\xe2\x91\'\xfe/lVk\xc5\rz\x04A\x00\xcf\xf3\ |
---|
| 3595 | \xb07H\xd5w\xa4\x98\xa1\x94e~%4<\xa7M:\x9fG\x84\xa3\xf3\xbe\xd1\x94\x84N\x1a\ |
---|
| 3596 | =\xe7kQ\xa7$t\xe2oO\xb4d \xb3\xd1\xbag\xffkx\xe4\xc7O\xe2\xf0\xb1\xe3\xb0Y\ |
---|
| 3597 | \xad\x05\x13%q\xaa\xec\x1f\x18\x84\xcdb\x91\x8b\x8fH\x07\x1fGMM\xc6\xc6@\x9c\ |
---|
| 3598 | \x86\x855\xcb\xe9\x82dS9\x1f\xb1\x93\x95\x1f\x89\xd0\xef\xd8\xf1\x05\xf4\x9f\ |
---|
| 3599 | \x1eP\xadtJ\x85\xf6\xfc\x11\xc4\x13I\xd8\xac\x16\xb9Gk8\x12\xd1\xed\x06Ep\ |
---|
| 3600 | \xe5G.\xc2\xfa+V\xe2\x99g~#m\xa6\xd2\x94L\xda\x0c\xc3\xc0d2A\x14E\x88\x00(H-\ |
---|
| 3601 | \xe8\x8a\x01/\x88\xe8\x9f\xca\x88eZB\x97\xb4vio\xa4\x7f*\x00V\xb1RY\xacF\xe0\ |
---|
| 3602 | \x14E!\x95Latp\x04\xcd\xed-`i\xb3*}t9aI\x90\xba2\x07\xbb\x18\xb0\x8cI^"\xfe\ |
---|
| 3603 | \xf4\x97\xbf\x90\xda\x8e-@J\x12EQ\xb2$B\xf4\xb8\xf9fX\xe4\x84P\\\x95\x1b\xa7\ |
---|
| 3604 | Y\x99$R\xa9\xb2\xb4\xad\xcb\xd5\xa5^)\xbb\xe8\x11\xba\xdb\xe5\x94\xbb\x1e\ |
---|
| 3605 | \x91\x8d\xd0\xc7\x7f\xfcs\xec:p\x00\xb1\x99\x99\xbc\xe4\x95\x0b4E\x01\x0c\ |
---|
| 3606 | \x83d:\x8d\xc4l\x87$2\xc1\xb0&\x13.mj\xd1\xcd\xf4\xd1+\xcfW\x12</\xf0\xb0\ |
---|
| 3607 | \x9a\xac\xb8\xa1\xe7\x06\x00\xc0\x1f\xfd\xaf\xfb\xd1\x7fz\xa0h\xcf\xfb\xb9\ |
---|
| 3608 | \xa0l\xed\x97\x0b\x84\xd8\xf5:D\t~\x11\xcd\xf5M\xf8\xc2g?\x8a]\xbf:\x82\x17\ |
---|
| 3609 | \xf7\xeeE<\x99T\xc9+\x14E\xa1\x94\xabNQ\x14\x18\x9a\xc2\xf7\x9f~\x06\x9b\xd6\ |
---|
| 3610 | _&{\riA&\xe7P8\xa2\x1a\x1b$\x88X\xe8\rG\x8a\xa2\x10\x9e\x89\xca\x9b\xbb6\x8b\ |
---|
| 3611 | \x05\xb1T\xe5\xa4\xd7\xc5\xc4\x92\xa8(%iJ@\xe1\xe4\xc8\x0b<\xecf\x07\xd6\xb7\ |
---|
| 3612 | u\xe0\xc8\xe9\xa3\x18;7\x01S\x81\x1b\x81\xe5\x00!\xca\xc9\xa0\x1f\xb1d\xac*-\ |
---|
| 3613 | \x80\x03\xe3Q\xa9\xfc\xb9D\x07\xba\xb9d\x17\xad\x8e\x0e\xa8\x97\xb1\xee\xd9<\ |
---|
| 3614 | \xf2\xfaY\x02{\xfc\xf1\xc7q\xd7}\x0f`\xe7\xee\xdd\x10\x04\x01n\x97\xbeOM\xa1\ |
---|
| 3615 | \xa0(Jn6\x9cL\xa7\x11O&1\x1d\x0e\xe3\x97od\xf4T\x966\xeb\xfa\xa8(AH>\x91N`\ |
---|
| 3616 | \xd3\xea\x1e9c\xe8\x95\xd7^\x87\xab\xc6>or\xd2{?!?\x92iD2\x92H6O.\x90\xcc\ |
---|
| 3617 | \x93\xb0]J\xf9\xbb\xeb\xf6\x0fb\xc7\x9f\xdc\x0c\x8a\xa2\x90H\xa6\xc0\xf3\xfc\ |
---|
| 3618 | \xbc\x1b\x8a\x9bL&\xa49\x0e\x7f\xff\xbf\xbf\x93U]*\xa74\xceF\xee\x95\xdc\xb3\ |
---|
| 3619 | *\x064E\x81eYU\x1b\xc5\xe5\x8a\xaa\'ueF\x00)\xac)\x04\x9c\xc0\xc3\xebZ\x01\ |
---|
| 3620 | \x008\xfb\xd6 \x12\x1c\xb7(\xf6\x99\xf5\x1e\x9f\xec\xfeV\n\xe6$\x8cy.\xf9\ |
---|
| 3621 | \x01\x14m\xee\xa4\x85V\x0b\xce\xa5\xa3\x13Bw9\x1c2\xa1\xafp\xd5\xc2\xde m\ |
---|
| 3622 | \x86~\xf9\xc9\'\x11\n\x87\xe1r:a2\x99\xca\x1a\xc9Q\x14\x05\x86a\xc0\x0b"\xbe\ |
---|
| 3623 | \xf1\xefO\xe0\xf1\xff\xf7\xac\xaa\xd8G\x8f\xd8\xb5r\x8c\xd5dE\x8fo\x13\x00\ |
---|
| 3624 | \xe0\x91\x1f?)\xbd\x88)\xcf\x98"\xdfUO\x9a\xd0\xa6\x90\x12b\'\xd9=\xe1HD\xce\ |
---|
| 3625 | \xdb\x06\xa4\xaaJRx\x14\x8cO\xe1\xd2K\xd6\xe0\xba\x0f|\x00kZ\x9ba\xb3X\x90L\ |
---|
| 3626 | \xa51\x13\x8fc&\x1eG8\x12\xc1L<^\xf4\x18p\xd4\xd4`ht\x14\x9f\xfd\xca\xbfd\ |
---|
| 3627 | \xed\x83\x04\x84 \xbc\xb5u\xf2jH\xbb\xea\x98o\xdf\xd8\xc5\x80\xde\x8a\xa8Z\ |
---|
| 3628 | \xb1$\xe4\x17\x82|\x15w\xf9^?\x99N#\x95J\xc2lZ\xf8\n\xd4\\\xb9\xe3\x85b!\x96\ |
---|
| 3629 | \xa9\xe5\x9a\xec\x947\xaf\x9e\x8e\x0ed\x13: 5\xbb\xfe\xe1O\x9f\xc3\x84\xdf\ |
---|
| 3630 | \x0fg\x85\xfb\xc8Z-f\xa4\xd3)\xfch\xe7N\xfc\xc1=\x97\xc3\xebZ!od\x13b\'\x9b\ |
---|
| 3631 | \xcdJ9&\xc9\xc5\xe1\xb6\xbb\xd1\xdc\xde\x82\xbe\xbe>\x0c\x8d\x8e\xc1f\xd5o\ |
---|
| 3632 | \xf9W.he\x18\x12\xadk\xf5u\xd5\xf7\xab\xab\x01f\xd3\xe2\xc3\xf6i\xb9\x92\xf4\ |
---|
| 3633 | \xdeO\xdc\x82`|\n\xa3\x93c\x18;\x9d\xc0\xd1w\xdfU\xbdopx\x04S\xa1P\xc1M\x97\ |
---|
| 3634 | \x05Q\x84\xcb\xe9\xc4\xbe\x83\x87p\xe4\xe8;\xe8\xddzU\xa6\xce\xe0|\xc6&\x80\ |
---|
| 3635 | \x90\xa1^}\xc3b\xe5|\x97\x92\xd2ll\x94V\x08\x11Q\xbf\xb5\x95\x1e8>-\x17\x18\ |
---|
| 3636 | \x91(f!#\xf5j\xd5\xd4\xcb\x85\\\x19\x1bzQ:\x80\xac\xc6\xdf\xca\xca\xbf\xb3o\ |
---|
| 3637 | \r\xe2\xf9=\xbf\x86\xd9l\x01SH{\xb5y\xc2d2atb\x02g\x0e&\xb1ak\xf6D\xaf%w\x82\ |
---|
| 3638 | \x06\xeb*\xd4{|x\xfc\x8dg\x11\x08\x06\xe5M\xd8r\x83l\x98\x02\x19b\'\x84h5\ |
---|
| 3639 | \x9b\xb36N\x95\x92\xcc\xe8\xf91\xe9>\x89\x02\x0e\xd8\x11BH\xf6}\xf1\xd8\xea\ |
---|
| 3640 | \xe0i\xab\xc3\r=M2\x01\xafo\xeb\x903x&\x03\x81\xa2\xf6\x9ch\x8a\x02\xc7q\xd8\ |
---|
| 3641 | \xf3\xfao\xb1\xb1\xeb\x12]\x97M-\x19j;P-$H}\xc5|\x93\x17\xaa\x1dU/\xbf(Ql\ |
---|
| 3642 | \xa4\xbe\x98X0M]G~\xe1\xf84x\x81\xd7\xfdY\x08h\xa3t\xad\x8eN\x08\x9dh\xe9\ |
---|
| 3643 | \xfdS\x01\x9c\xf3\x9f\x87\xd5\xb2p\x1d\xdcmV\x0b^;r\x04@vC\t\xd5\xebf7\xd4\ |
---|
| 3644 | \x12\xe9\x04\x9a\xeb%\x17\xc2\xc1\xd9r\xf1r\xcb\x08\xca\xef\xce\xf1\xbcLz\ |
---|
| 3645 | \xca\x0c%=\x8d=\x9eH"4kZ\xa6\xd7\xacB\xf0\x8b\x08\xdb\xa7\x11\x8cOI\xd1\xfa\ |
---|
| 3646 | \xf91\x95\xe9\x96\xb7\xb6\x0e\xe3\xfe\xe2,"\xc8\xf1\xda\xacV\xfc\xf6\xe8\xdb\ |
---|
| 3647 | \xf2sz\xbe\xea\xb9\xaa\x8c\x17\x1a$}y)6\xa2/\x06K\x8a\xd4\x8b\x89\xd4u\xc1/\ |
---|
| 3648 | \xbcu\xa62R\xcfE\xb4\xf9\xc8\xb6X\x92#\xfa/G|n\xb4?|\xba\xa0\\\xf6B\xa0\x8c\ |
---|
| 3649 | \xb6\xb4\xba\xa9\xb6P\xc6\xa5\x91U\xeaM&9\xb5\xf0@__Y\x8e\xa7\x18P\x14\x8dH4\ |
---|
| 3650 | \x8a\x81\xc9\x019X\xd0\x12\xbb\xd7\xb5\x02\x13\xa1\t\xfc\xe2\xc7\xfd\x18\x7f\ |
---|
| 3651 | \x93\x95\xcb\xed\x87\'\xc6+v\\\xda\xeb\x9d\x8b\xd8\x13\xa9\x14\xe2\x89$\xe2\ |
---|
| 3652 | \x89\xa4J\xd6\x08\x08A\xc4\x921D\xc4i\x8cG\xce\xc9\xae\x85\x82_\x94\xb3\xc7\ |
---|
| 3653 | \x08\xb9\x13\x8c\x0e\x8e \x18\x8e\x80)!\x91\x80a\x18\x04\xc3\x11\xb9\xf1\xb4\ |
---|
| 3654 | \xde\xa4BP-\xe4\x0e\xcc\xafv\xa4\xda\xb1\xa4\xe4\x97yG\xeae\xda\xd4*\x06JM\ |
---|
| 3655 | \xbd\x90h];\xd8\x8a\xd1\x1d\xeb=>|\xf6\xba\xcf\x15\x7f\x90%B)\x13\x00\xd97\ |
---|
| 3656 | \xad6\x1dQ\x19\xa5+14:\x06\x13\xbb\xf0\x9bg\x82 \xe0\xcd\x97.`\xe3=\x99\xe7\ |
---|
| 3657 | \x88W9\x00\x04\xc2\x17\xf0\x9b\xe7\xc7\xd1\xd6\xdc\x84\xcb\xaf\xf5\xe2\xc97\ |
---|
| 3658 | \x9e\xc0\xc1\x83\xef \x1c\x89\x14l\xa9PN\x10b\'\x13(\xf1\xda\xd1\xd6\x1a\xd8\ |
---|
| 3659 | -v\xb99\x86\x12\xc4\xe7H\xeb\x05\x13\x10\x82\x98\x89%PJ\x0f\x08\x8a\xa20\x1d\ |
---|
| 3660 | \x0e\xe3L`\x00\x1b\xd7vat\x8e\xfe\xb2\xd5\x00"\xbf,W,)R\x9fw\xa4\xbe\x08\xa8\ |
---|
| 3661 | \xf7\xf8\xf0\xc9\xad\x7f"G2\x80\xbaK\x8c\xd6\x7fZ\xaf\xd1@>\x08\xa2\x08\xab\ |
---|
| 3662 | \xc9\x82\xb3o\r\xe2\xc4\xca\xec|\xe1\\81\xd4\x8f\xc1\x911\xd04S\xf0\xe6\x98\ |
---|
| 3663 | \x16z\xb9\xe9\xdarv\xad\x96\x0ed\xa2to\xa3\x03/\xed9\x88X<\xbe(\x96\xa64M#\ |
---|
| 3664 | \x18\x8e\xc8\xb6\xb7d|\x11b\xdf\xfb\xdc\x00F\'&P\xb7v\x1a\xbf|:\x8e\xfe\xd3\ |
---|
| 3665 | \x03\xb8\xe7\xf6\x16\xd5dU\x89\xcd>\xad\xc7\x89\xbc\x1aR\xe8\xec\x00d\xad=\ |
---|
| 3666 | \x91J\xc9\xa9\x83\xdb{z\xb1qmW\xce\xcfV\xb6\xa3#\xab\xc8\xb3o\r"\x91N\x96T\ |
---|
| 3667 | \x94GQ\x14\xe2\x89\x04\xce\x0fr\x08t\xe4.\xa9\'V\r\xe4\xb8\x17\xa5\xbat\x16\ |
---|
| 3668 | \xcb]~YR\xa4\xbe\x944u\x9a\xa6\xe5JIom]\xc6n\xb6\x00\x14c\x81KS\x14@\x89\xf8\ |
---|
| 3669 | \xf2\x93O\xc2\xfa\xcc3E\x1dc"\x95\x82\xc5l*\x99\xd4\xf5\x10O$\xb3\xa4\x17 w\ |
---|
| 3670 | \x94>|n\x1c\xbc b\xe1)=\x83X2\x86F\xef*D"\x99\xa0\xe1\xcc\xc1\xa4\x9c\xe1\ |
---|
| 3671 | \xf2\xde!\n\x89\xf4(\\v\x17\xee\xba\xfd\x83\xf8\xfac?\xa9\xb8\xc3 \x81Vg\x07\ |
---|
| 3672 | \xb2\xc9\x1d\x90\xb2L\xfatd,\xbd\x9e\xaf\x804&I\x8ey\xffT`\xdev\x19q\xc1\x83\ |
---|
| 3673 | \xb5\x00\x00 \x00IDAT\x83\xa3\xa3\x19S\xb6\xf3\xd9\xbaz.\x14b\xe8Un\x14k1\ |
---|
| 3674 | \xbd\xd4\xb0\xa4H\xbd,\x9a\xfa\x02H0$\'\xfa\x91\x9f?\x8f\x1f\xec\xde\x05 \ |
---|
| 3675 | \x93[\xac\xcdV P>o\xb7\xd9\x10\x08\x86\xa4\x06\xc1\x05\x0e\xf6H4\x8a\x0b\x9c\ |
---|
| 3676 | tc2\xb4T\xd1\xaa\xf7\xa8\x04M\xd3E9\xf3\x15\x02\xb2I\x9a\xaf\x12\x94h\xe9\ |
---|
| 3677 | \x81\xf1(\xfa\x07\x07\xcaR\xd1Z\nh\x9a\xc6t8\x8c\xb7^\t`\xedG/VE\xebR\xb3\t\ |
---|
| 3678 | \xe9Z\x82\x92\xaeA\xef\x07\xb6\xa0ye\xd3\xa2\xc9/\xc4gGK\xee,\xc3\xe0\xcd\ |
---|
| 3679 | \xe3\'\xd0\xfb\xe9Og9:\x12\x90\x8a^\xb2r"i\xa5\x1du^\x1c}\xf7]X\xe6\xa1w\x9b\ |
---|
| 3680 | \xcd\x16\xb8]N]\xef\x17 \xdb\xbbf\xb1QJ\xa4n\xe4\xa9W\x08\xf3\x8d\xd4E\xba\ |
---|
| 3681 | \xb4\xd2\xe8R14:\x864\xc7\xc9\xae}\x00T\xbf+\xa1}\xdeb6\x17E\xb8\x0c\xc3\xa8\ |
---|
| 3682 | ^o\xca\xf18_h\xabH\xb5>/s\xa1^#\xb3\x9c\x9f\xba\xb0(Ea@f\xf2=\xda\x7f\n\x9d\ |
---|
| 3683 | \xc3\xabpi\xebj \x9a\x1d<\x90^\x9e\xf7~\xe2\x96yuc*\x07\xc8$\xafG\xee\x80Zo\ |
---|
| 3684 | \x07\xf4\xdd\x1d\x89T\xd3\xde\xdc\x0c@\x92\xc8\x04A(i\x82\'\xd5\xa9+\\\xb5\ |
---|
| 3685 | \xb2I\\\xb5\xa3\x94H\xdd\xc8S\xaf\x10\xe6\x1b\xa9\x97Sf(\x04&\x93I7\x02R\xde\ |
---|
| 3686 | \x98\xb9\xb0\x14|\x9b\x01u\x81\x8c6"\xd3\xd3\xd3\'\xd3i\xb4\x03\xb2\x9e\x9eH\ |
---|
| 3687 | \xa7u\xaci\x17\x0e4M#\x14\x89\xe07/\xbf\x83\xe6;\xbdp8\xec\xf8\xd5\x7f\x1eE\ |
---|
| 3688 | \xff\xc0 X\x96A:\x9dF\xad\xcb\x85\xcb\xd6\xae)z\xbf\xa3\x92P\xbac\xea\xe5\ |
---|
| 3689 | \xb5\x13\x10\x1d\x9b\x10;qv\x04f\xeb7f%\xb1R2_\x00\xa9m`\x8d\xd5\x82\xf6\x96\ |
---|
| 3690 | &\x04\xa6\xa7\xb2\x8a\x8f\xaa\x11\x86\xa6^E(5R\x0f\x85\x17o\xe9\x94\x8f\x9c\ |
---|
| 3691 | \x97\nq\xe7\x83\x96@\xb4\xc4\x1e\x8eFeC6@\x1d\xa9\x87\xc2\x11\xf09V.\x0b\x89\ |
---|
| 3692 | \x1a\x9b\r\'\xde;\x8d#\x136\x8c\xbf\xc9\xe2\xf57\xdf\x02\xcb2H\xa68\xacim\ |
---|
| 3693 | \xc6U\x1f^U\xf1\x0eY\xa5 W\xd4\xae,X"+("\xed\xe9\xc9b\xca\xebS,x\x8eCKs\x13.\ |
---|
| 3694 | mjY\xd6\x91\xfaR\xc2\x92"\xf5b"u\x961\xc99\xbaD?\x14Eq\xc1\xa3\xf5\xdf%h\t=\ |
---|
| 3695 | \x14\x8d\xa0\xb5\xa1\x11\xa1pD^\xea\x13\x04\xc6\xa3\x18\x9e\x18G\x9a\xe3\xaa\ |
---|
| 3696 | \xa2\x99/\xcb\xb2x\xe1\x89~\x00"\xd8\xd9\xf4J\xb3\xd9\x84+\xae_\x01\xb7\xdd\ |
---|
| 3697 | \x8dH|\xe9h\xaaZ\xe4\x9al\x81Le/MQ%\xdd\x1f\xbc \xa2\xd1\xe7\x83\xb5\xaeFWS\ |
---|
| 3698 | \xd7\xae\xd4\xaa\x01\xcb=R_R\xc5G\xa5F\xea\x1du^\xb0,\x0b\xbd\xb8\x98\xa6\ |
---|
| 3699 | \xa8\x8a\xfe,W\x90\xc2\xa3|\xa9iJ\x1d\x92X5\x08-\x99\xabp\xf2\xf4\xc0\x9c\ |
---|
| 3700 | \xad\xf1\x16\n\x14E\xcd\xfeH\xb7\x84 \x88\xf0\xba\xddhp7\x00\x90\x1a\xae\xe8\ |
---|
| 3701 | \xa1\x1aV[z\x192\x04\x89TJw\xb2\xd5Z64\xd5\xfb\x8a\xce\xe8\xa1)\n\x82\xc0\ |
---|
| 3702 | \xa3\xb5\xa11\xe7^C\xb5\xb84*aD\xeaU\x84b5\xf5\x89\x84\x94\xc1\xb0\xfa\xf2v\ |
---|
| 3703 | \x98X\x16\xd1h\x146\xab\x15\xbc V\xa4\xe3Q.\xc8m\xcdd\xe2X<\xb2\'\xcd\x110K\ |
---|
| 3704 | \x04\xa2(\x16\xe5\xd0G<mH\xc6J\x9a\xa6\xc1$S\x80C"\x10\x8f\xcb\x99\x95\xdd\ |
---|
| 3705 | \xa3$\x90\xf3\x83\x1c\x9c\xb3\xbd\x8a\x9b\xeb}\x98\xf0\xfbUM\x1c\xaa\x03\x12\ |
---|
| 3706 | Y}\xe0VI\x96\x88\'\x93Y-\x14\x17*\xa5\xb1P\xe8J1\xb3\xe7T\x19\xa9\x87#\x11\ |
---|
| 3707 | \xb46\xaeB8\x1a\x85\xcb\xe1\xc0\x85\xf04:\xea\xbc\xf8\xc3\x1b\x7f\x1f?\xda\ |
---|
| 3708 | \xb9\xb3(\xff\x17\xf2\x7f\xaen\xcf\xbf\x89\xa8ld\xce\xa5\xd3\xe0x\x1e\x82("\ |
---|
| 3709 | \xad\x08\x08*\xbdY\xce#s\xcd\x96{\xa4\xbe\xa4H\xbd\x98H\xdd\xc2\x9a\x11\x88L\ |
---|
| 3710 | \xa1\xaf\xaf\x0f\xdb{z\xf1\xc0\xbd\xf7\xe2\xa7\xbf\xfc\x85\xbca\xd4\xda\xb8J\ |
---|
| 3711 | \x95\xdaU\t\x90\x1e\xa8\xc3\xe3\xe7\x10\x08\x860\x19\x08 =;\xb0L\x0b\xd4\xb0\ |
---|
| 3712 | C\x10\x04\xa4\xd2\x9cj\x12#\xff\xb7(\x8ap\xd8\xedY\xe9o\xc5B\x99]\x91\xcfb\ |
---|
| 3713 | \x17\x90\x0c\xbc\x00i\xa3\xf4\xab\x7f\xfd\xe78x\xf0\x1d\xfch\xe7N\x04\x82\ |
---|
| 3714 | \xc1\x05\xcd\x82\x11\x04Aw\x82\x15D\x11<\xc7\xe1\xca+.G\x83\xdb;\xaf\xffc\ |
---|
| 3715 | \xbe\xbe\xe5\xa5@@\x86\xd89\x9e\x87U\xe1$\x19\x8b\xc7\xd1\xe8\xf3\xa96K\x01\ |
---|
| 3716 | \xc8MJ\x80\xd2\xc8u:\x90\xfbo.\x87\x03^Of?\x82L\xf8\x84\xe8\x17\x126\x8b\x05\ |
---|
| 3717 | \xdeF\x87\x11\xa9W\x03\xc8\xd2\xdd\xe1\xb0\x83\x9b(\xce\xc2\xf6\x85\x81\x17\ |
---|
| 3718 | \xd0\xdc\xde\x82\x07w\xec\xc0\x83;vT\xea\x10\xe7\xc4d\xd0\x8f#\xa7\x8f\xe2\ |
---|
| 3719 | \xe0\xc1w\xf0\xea\xe1Cx\xf3\xf8\t\x84\xc2a\xd8\xacV\xa9\x8fd\x19\t\x80\xdc\ |
---|
| 3720 | \xd4\xd1X\x0c,\xcb\xc2\xbbb\x05\x9a\xeb}\xd8p\xf1:\xb477\xa3\xbdE\xda\xd8\ |
---|
| 3721 | \x02 w|\x072\xd5\x86\xf3}\xd4~V>l\xef\xe9\xc5\x8d[\xb6\xe0#\xf7\xdf/\x9bzU\ |
---|
| 3722 | \x1a\xa2(\xe2\xd2\xf6\x8b04:\x86D:-\xcbd\xa2("\x95J\xe3\xeaMW\xe0\xf2k%B/\ |
---|
| 3723 | \xc5\'\x87\xa6(\xa49\x0e\xb1\x99\xc5/\x997\'\x92\xa8\xb1Z\x10\x8d1p\xd8\xed\ |
---|
| 3724 | \x18\xf7\xfb3\x1e\xf7\x8a\x15\xd4\xe0\xe8(\xce_\xb8PRZ#IDP:4\x06\xa6\xa7\xb0\ |
---|
| 3725 | \xbe\xad\x03\xff|\xff\xe7\xe7\xf9\r\xca\x8bR\xa3t#O\xbd\x8c\xe08N\x1e4\xc5f \ |
---|
| 3726 | XX3\x06&\x07\xf0\xaf/~\x1d\x9bV\xf7\xc0c\xabS\x95\xe5\x07\xe3SE\xb7\xc8+\x06\ |
---|
| 3727 | \xe4x/\xb6\xaf\x85\xb5\xae\x06\x1b\xd7va{O/\x1e\x04\xb0\xeb\xd0\x1e<\xbd\xf3\ |
---|
| 3728 | \xd7x\xf6\xa5\x97\xe4\xc6\x10\xe5\x00\xe9\xd1\t\x00\xd7^u%~oS\x0fn\xdc\xb2\ |
---|
| 3729 | \x05\xcd\xed-\xaa\x01M\xc8W\xb9\xb95:8\x02k]M\xc9\x8f\xaa>\x95\xb3\xbf+\x9f\ |
---|
| 3730 | \xd3\xd3]\xeb=>4\xb7\xb7\xc0\xebqcht\x145VKEujQ\x14\x91L\xa5\xb1\xe1\xe2uhm\ |
---|
| 3731 | \\\x85\x17_\xfd\x1f\xd4X-Hs\x1c\xd2\x1c\x8f\xaeK.\x96\t]\tm\x1b\xc0|Hs\x1cZW\ |
---|
| 3732 | 5b\xfb\xd5W\x97\xf3\xd0K\x86\xb6\x92Wi\xa6\x06\x00\x976\xb5\xe0\xbb?\xfb\x19\ |
---|
| 3733 | \xd2\x1c_\x14\xa9\xd3\x14\x05\x9afd\xdd\\k\xbd\x9b+"\xce\xd7\xa8\xba\xd2\x08\ |
---|
| 3734 | LO!15\x83X2V\x94\x1d\xb6\x91\xa7^f\x0cO\x8cc2\xe8\xcf2"*\x04v\x8b\x1d\x81\ |
---|
| 3735 | \xc8\x14^|\xfb\xbf\xc12\xa6Ek+g\xb7\xd8\xe1\xb49\xb1\xd6{1z|\x9b\xb0\xbd\xa7\ |
---|
| 3736 | \x17\xdb{zq\xd7\xed\x1f\xc4\xdf\xff\xcb\xff\xc1\xe1c\xc7\xe1p8\xe6\xbd\xb9\ |
---|
| 3737 | \x1a\x9d\x99\xc1\xc5m\xab\xf1w\x9f\xba\x17\xbd[\xaf\x92\x89\xbc\xaf\xaf\x0f{\ |
---|
| 3738 | c{1:9&\xef5\x90\x8c\x0e\xe2\x12I\\\x1c\xf3A\xefFP\xae\x9c\x9c6\xa7\xfc}\x01\ |
---|
| 3739 | \xc8\xc6RZ3)/\xedQM\x04\xe5\x9a\xd4\xe6\x025\xbb\xb9\x17\x8eF\xf1\xa1\x1b7\ |
---|
| 3740 | \xe0\xcd\x93\'1:1\x01\xb7\xd3\x89\xf7o\xbc\x14W\xdf\xb0\x1a\x80d\x1d@\xa2\ |
---|
| 3741 | \xf4|\x8d\xa8\xb5\xa0)\n\xe1\x99\x19t\xb4\xaf\xc1\xb7\x1e\xf8\xdb\x8a|\x87\ |
---|
| 3742 | \x8a\xe0g?C*\x95,jR%\xaf\x0bE#Y\x04=z~\x0c\xc7\x86\x8f\x82\x0fI\xb2^\xc44\tz\ |
---|
| 3743 | \x84B\xd8\x13E\xdco\x01o\xce\xde\x1f\x0b\t\x99M\xd54\x13\x81\x89w"\xcdd"\xe4\ |
---|
| 3744 | b\xaeC!X\x8e^\xea\xc0\x12 u\xb3\xd9\x82\x93\xa7\x07\x10\x98\x9e\xc2\xf6\x9e^\ |
---|
| 3745 | \xbc\xf0\xf6\xcf\x91\xe4\xe2`\x8a\xc8\x9a\x90:\xc6\xcf\x96T\xeb\xbc\xaf\x98\ |
---|
| 3746 | \xcf*\x05\xc4^7\x10\x99\xc2Dh\x02\x07N\xef\xc7\x9a\x815\xb8y\xcd\xcd\x92\x01\ |
---|
| 3747 | \xd3\x0f\xba\xf07_\xff\x16\x9e\xd8\xb9\x13\xf6\x9a\x1a\x98X\xb6\xe8hU\x10ED\ |
---|
| 3748 | \xa3Q\xdc~\xddux\xec\xa1\x07Q\xef\x91Z\xc4=\xf7\xc6s86v\x1c\xd3\xf1LA\x88\ |
---|
| 3749 | \x96\x98Y\x9a\x01\'\xf0`iF\xf7\xfc\xe4\x82\xf2\xbc)\x9b5\x13(\xf7@B\xb1P\xd6\ |
---|
| 3750 | J\x8b4j\xf0\xd6\xd6\xa1k\xdd:\xbc\xf2\xda\xeb\xe0g\xb5\xeeJ#\x14\x8d\x80\xf6\ |
---|
| 3751 | Q\xf8\x83{.\xc7\x85P\x026\x1b\xa5\xea\x82\xa4\x94]\xe6\xd3y\xfe\xc4P?\xf6\ |
---|
| 3752 | \xf7\xef+\xcb1\x17\x03\xb7\xdd\xad{\xce\x01\xb5Kc\xf3\xca&\xaco\xeb\xc0\xf0\ |
---|
| 3753 | \xc48\xcc\xe6\xe2WI\x0cMey\xb1kM\xea\x94\x84\x0e \x8b\xd0\x95dN\x10\x8f\x8b\ |
---|
| 3754 | \x88#,\xff[`b\xf28\x9d/X\x9a\xa9\xf8=\xbf\x98\xa8zR\xb7\x98M\x98\xf0\xfb\xf1\ |
---|
| 3755 | \x9b\xdd\xfb\xb1\xfe\xde\x0et6m\xc0\x81\xd3\xfb\x8b\xb6\xce\\\xcc\x8bH\xfeo\ |
---|
| 3756 | \x86f\xe4\xe8``r\x00\xdf\x9a\xfc\x16\xae\xf6o\xc5m[n\xc3\x7f|\xedkhon\xc6\ |
---|
| 3757 | \x97\xbe\xfdm\xd8\xac\xd6\xa26QE\x1dB\xff\xde\xaf\xbe\x8f\xc3g\x0f!\x91N\xc0\ |
---|
| 3758 | j\xb2\xc2j\xb2\xe6=\x07\xa5\x9e\x1f%\x99k\xfb|\x12\xf7C@_:S\x9aM]\xdf\xbb\ |
---|
| 3759 | \x19?\xf9\xf9\x0b\x08\xc7f\x16DW\x07$\x8f\xf1\x06\xeb*\xd8\xeb%\x92\xd1#\xf4\ |
---|
| 3760 | \xf9F\x87\xc7\x86\x8f\xe2\xc0\xe9\xfd\x00*\xd8\xfd*\x0f\xc8x#\r\xb6\xb5+\xa8\ |
---|
| 3761 | \xe6\x95M\x98\x0c\xfa18<R\xb2\xfd1\xd9\xf4$\x86^\xa4\xf94l\x00l\x00\x13O\x82\ |
---|
| 3762 | o\xb0@0\x89\xa0G(`\xd6r=\x1aJ\x00\x00\xdc\xb4#\x8b\xd8m6J\x15\xa9s\x82\xf4=\ |
---|
| 3763 | \x963\x19\x97\x0bU\x9f\xa7\xce\xd04X\x96\xc5\x0fv\xef\xc2d\xd0\x8f\xdb\xb6\ |
---|
| 3764 | \xdc\x06\xbb\xc5\x9e3ox\xa9\xc0n\xb1\xc3j\xb2\xe2\xc0\xe9\xfdx\xec\xe5G1\x19\ |
---|
| 3765 | \xf4\xe3\xc1\x1d;\xf0\xb9{\xfe?\xc4\x13\x89\xa2\xd2\x0c\xe3\x89\x046un\xc0c\ |
---|
| 3766 | \x0f=\x08\x00\xf8\xc6\xb3\xff&\x13\x89\xddb\x07S\xc1\xc8\xa4P\xd2S6h\x00\xd4\ |
---|
| 3767 | \x1dr\x02\xd3S\xd8\xb8\xb6\x0b7]s\r\x04a\xfe\xdd\xee\x0b\xc5x\xe4\x9c\x9c&[L\ |
---|
| 3768 | \xd3\x04=C\xb6\\ Q\xb1\xd5d\x85\x855/\xc8\x8f\xdd\xec\x90\x7f\x9c6\'\x9c6\ |
---|
| 3769 | \xa7L\xe8N\xaa6\xcbk\xfd\xc8\xe9\xa3\xb8p\xa1\xb4\xec#\x86a\x90H\xa5T\xd6\ |
---|
| 3770 | \xd2\xd6\xba\x1a\xd5\xf5\xf5\xd8\xea\xc0\xb8\x93p\xa6\xebao\xf0\xc1\xe1\xb0\ |
---|
| 3771 | \xc3\x15t\xc0\xe1\xb6\xc2\xe1\xb6\x82I\xd5\xc2M;\xe4\x1f\x000\xf1\x199.\x1e\ |
---|
| 3772 | \x17uW\x82\x06\xf4Q\xf5\xa4.\x88"jl6\x1c\xe9?\x85\xc7\xff\xdf\xb3\xa8\xf7\ |
---|
| 3773 | \xf8p\xfb\xe5w\x80\xe3\xd3K\x9e\xd8\x19\x9a\x81\xddb\x977s\'\x83~|\xeb\x81\ |
---|
| 3774 | \xbf\xc5\xb5W]\x89h\xac0\x92\x11E\x11&\x96\xc5W\xff\xfa\xcfQ\xef\xf1\xe1\xb9\ |
---|
| 3775 | 7\x9e\xc3\x91\x897e2\xaf$\xc8\x8dF\x88\xbd\xd8L\x11m?\xcb\xbbn\xff \xdcNg\ |
---|
| 3776 | \xd1\x9d\xedKA8\x12\x91W\x11\xb9\x08\x9d\x13R\x99\xef\xa8\xd8k\xd0\xb3\x16\ |
---|
| 3777 | \x9e\x0b\x0b\x19a\xeaM\xb4$B\xd7\xab\xf58\xfb\xd6 \x12\x1cW\x9a\xecEQ\x98\ |
---|
| 3778 | \x89f\x9f?e\x07$2\x913\xee\xcc\xf8\x10ZD\x99\xdcm\xbe\xa4L\xf0\x00T\x04\xbfR\ |
---|
| 3779 | l\x84\xcb\xec\x82\x89w\xc2&\xd6\x81\xa5\xcd\x06\xc1\xcf\x81\xaa\'u\x02\x13\ |
---|
| 3780 | \xcb\xe2\xdbO>)\xe7\x9d\xdf\xf4\xbe\x0f/\x0bb\x07\xa4(n"4\x81\'\xf7\xfc\x04\ |
---|
| 3781 | \x00\xf0\xf5\xbf\xf8\x0c\xbc\x1e\x8f\xec\x0e\x98\x0f\xf1D\x02W^q9\xb6\xf7\ |
---|
| 3782 | \xf4\xa2\xaf\xaf\x0fo\x9cyc\xc1\x96\xf9\xf9\xa2t%QFunz\x02%\xb17\xafl\xaaX3g\ |
---|
| 3783 | %H\x15\xab\x96\xe0\xe2\xc9d\xd6\xe6(y\\\x0c\xe9\xa4\x9cP^\x0f\x12\xa5\xd3\ |
---|
| 3784 | \xbe\xd9>\xba\xf3hXA\x01Hp\x1c\x02\xe3\x19\xf9D;Y\x93\xd5\n\xd94%P\xea\xec\ |
---|
| 3785 | \x00\x10\xf7[\xc0\xa4\xb2kQH\xf4\x0eH\x11\xbc\x89wJr\x92A\xf2\xbaX:\xa4n2!\ |
---|
| 3786 | \x14\x89\xe0\xee/=\x88\x13C\xfd\xb8k\xdb\x9d\xb8{\xcb=\x00\x96~\xbfA\x86f`5Y\ |
---|
| 3787 | qd\xe2M\xec:\xb4\x07\xdd\xdd\xdd\xf8\xf8-7#63\x937\x1b\x86ts\xff\xe3\xdbn\ |
---|
| 3788 | \x05\x00\xec\x1d\xfc\x1fp|qy\xfc\xe5\x80\xdeMU\xe8\x9e\x07\xd1\xd5I\x9a\x9b\ |
---|
| 3789 | \xd7\xe3\xaex\xa4\xae\xf4o\xd7\x1b;\xca\x08]\x0f\xc5\xc8/\x04\x0b\xd5\xf4;\ |
---|
| 3790 | \x17\x94Z:\x99d]1\x89@_=|h^\x15\xd6\x82\xc0cpdL\xf5\x9cR~Q\xf6C\x8d\x98&\x01\ |
---|
| 3791 | H\x84N,#\\A\x07\xe2~\x0bl\xbe\xe4\x9cY1\x04Do\x8f\xc7\xa5\xcfH\'M\x15%\xf7\ |
---|
| 3792 | \xa5\x94\xa7\xbedH\x1d\x90\xdc\xf4\xfaO\x0f\xe0\x8e\x1d_\x90#\xf6\xbf\xba\ |
---|
| 3793 | \xf1~4\xb8\x1b\x10K\xc6\x16\xfd\xc6\x99\x0f\xc8\xf2\xfc\xe5S/a2\xe8\xc7\x9f\ |
---|
| 3794 | \xfe\xe1mh\xf0\xf9\xe4\nT=$S)4\xf8|\xd8\xd8u\t&\x83~\x9c\x99>\xb3(\x11%\'\ |
---|
| 3795 | \xa4\xb2$\x18B\x96\xcahX[\x13\xa0\xd7y\xbe\xb5q\x95lEPI\xc4\xe2q\x15\xa1k\ |
---|
| 3796 | \xa5\xa3|\xab\x90R\xe4\x97\x85\x84\x1e\xb9\xe9E\xea\x80\xb4\x91;\xee\xf7\x97\ |
---|
| 3797 | \xec\xc1C\xcd\x06\x16J2\xb6\xd6\xd5\xa8\xe4\x17\x8f\xad\x0e|\xc8"\xeb\xea\ |
---|
| 3798 | \x80$\xbf\xd0#\xd2\xe4\x1a\xf6Da\xf3%\x11\xf7gW5\x87\x84\xa8*R\' )\x8f\x046\ |
---|
| 3799 | \x1bU\xf6\x94G%\x96R\x9e\xfa\x92"u@\xcag\xee?=\x80\x8f\xdc\x7f?\x9ez\xe1y\ |
---|
| 3800 | \xaco\xeb\xc0_\xddt?nz\xdf\x87\x01`I\x93\xbb\xddb\xc7Dh\x02GN\x1f\xc5\xfa\ |
---|
| 3801 | \xb6\x0e\\\xb5qc\xceh\x9d\x9e\xed\ry\xd9\xda5X\xdf\xd6\x81\xd1\xc1\x11L\xc7\ |
---|
| 3802 | \x83\x0b\x16\xa5\xe7;\xc7\xf1d\x12\xdcL\xee\xe3 \x91\x9b\x97\xf6d-\xd5[W5.\ |
---|
| 3803 | \xa8/\x0fP\xd8^\x00\xc7\xa7\xb3\x8e\xb5\x18T\x93\xa6N"u\x8f\xad\x0eo\xf4\xbf\ |
---|
| 3804 | \x8d\xd1\x89I\x98M%\xfa\xa9\x8b"X\x96UY\x05h\xcfS0>\x05\xc6\x9d\x94\xe5\x17%\ |
---|
| 3805 | \x99\xbb\x82\x12a\x93H]\x0b\xbd\xcc\x18@\x8a\xd4\xc3\xa90l\xb6YO\xf99VW\xbfK\ |
---|
| 3806 | \xa8\xfa\x94F=\xb8\x9cN\x8cNL\xe0\xcf\x1e\xfc2\x0e\x9f8\x89\xbf\xf9\xf4\x9f\ |
---|
| 3807 | \xe2\xaemw\xa2\xb3\xb5\x0b\xfb\xfb\xf7\xcd\x99\x97]n(s\xbb\xcbq\xf3\x1e\x1b:\ |
---|
| 3808 | *\x15\'uvb\xe7\xee\xddys\xb7[\x1b$\xd3\xa9>d\xf7\xa7,\x04\xbc\xc0#\x91N\xe4\ |
---|
| 3809 | \xfc{\xbe\x82-\xe5yei\x06\xbc \xd5\x0f\xb0\xb4\x19lM\n\xd3A\xe9\xa6\x8c\xd4N\ |
---|
| 3810 | \x03Q)B$\x11\x1b E\xea\x84\xd8\x89\x0c\xa3\xd7\xc7\xb4\xdc\xa0iZ\xd7{$_\xa4\ |
---|
| 3811 | \xc72\xa6\xac~\x9f\x85\x80L`\x0b\xb5\xf7#\xd5d\xe4&7\x92\xf9B\xfb(\x04cS\x18\ |
---|
| 3812 | 9\x1eA$\x1a\x85s\x1e\x16\xb9V\x8bEu\xdd\xacu5r6\x0c\xf9\xfe|\xc8"K/QO\x0c\ |
---|
| 3813 | \x88JD\x0e_TJm4\'\x10\rI>2\xb5^\xb5\xe4\x12N\x85\xe12\xbb\x10N\x85\xa1\x05\ |
---|
| 3814 | \x91_R\x88\x01X\xda2l\xb9\xb0$I\x1d\x90\xa4\x18\x9e\xe7\xf1\xc8\x13\xff\x17\ |
---|
| 3815 | \xbb\x0e\x1c\x90+(?}\xc3\xa7d\x9f\x953\x81\x01D\xa31L$\xce\x95\xe4\xe1Q\x088\ |
---|
| 3816 | !\x05^\xe0\xe5\xa2\x08B\x90,c*)j\xb6\x9a\xac83}\x06\x00\xd0\xdd\xdd\r\xaf\ |
---|
| 3817 | \xc7\xa3\x9b\xbb\xcd\xcf\xea\xce\xc4\xa7<<X\x9c\xc5)!s\xab\xc9\x8a5\xf5k\xe0\ |
---|
| 3818 | \xa4j\xd1\\/\x99m\x95R\xb9K@\nOH\xc5h\xce\xd7\xe5\xb0\x0choi\xaa\xb8\x1d/\ |
---|
| 3819 | \xd1\xec\xe3\xc9\xa4*\xb7\x9e\xa5\xcdr\xc4\x97w\x13\xb8\x84\x94\xc6\xb9\xc8\ |
---|
| 3820 | \xb6\x9c($j\x15\xfc"`\x07\xee\xb8\xe3j\x0c\x8f\x9f\xc3\x89\xf7N\x97l0\'\x8a\ |
---|
| 3821 | \xa2l\xd4\x06d\xf2\xd4\xadu5hF\x93\x14\xb9\xdb\x01\xa0E\x92\xdc\x88\x0bC[\ |
---|
| 3822 | \xe63\x02\xe3Qx\x1b\x1d\x08\xc6\xa7\xe4\x89_\xfb\x08dKx\x95D4\x1a\xc3\xc5\ |
---|
| 3823 | \xf6\xb5\xaa\xe7\x96BO\x86%K\xea\x80\x94#\xebv\xb9\xf0\xde\xd0Y\xdc\xf3\xc0\ |
---|
| 3824 | \xdfac\xc7\xa5\xb8\xf9\x9akq\xfb\xef_\x8b\xed=\xbd\x00z\x01\xa8}N\x88\xe7D\ |
---|
| 3825 | \xb9\x1e\x95HL\xcd \x04ql\xe8(\xceL\x9f\xc1t<XR\x91T,\x15\xc5\x89\xa1~4\xb7\ |
---|
| 3826 | \xb7`e\xdd\n\x84"\xd9\x9b4\x82 \xc0f\xb5\xca7SD\x9c.xEB&\xa1\xab\xd7n\xc5\ |
---|
| 3827 | \xd6\x8em\xf0\xd6\xd6U\xc4\x8eTk\xf6U\x08\xbc\x8d\x0e\xd4X-\xe0x\xbeb\xae\ |
---|
| 3828 | \x8dz\x9f\xab$\xf1\xb9\xb4\xd9b4\xf5\x8dk\xbb\xd0\xbc\xf2\xef\xca>\xeer=\x1e\ |
---|
| 3829 | \x1b>\x8a\x97\x8e\xbf\x04\xd6l\xce*\x06S\x9d\x03\x1f\x05\xc4\x80\xce\xd6.|\ |
---|
| 3830 | \xef\x81\xb5\xb8~\xc7\x0e$R\xa9\xa2\xcf\xb9\x08\x80\xa2iU\xba"\x00\xb5\xd7P[\ |
---|
| 3831 | Q\x1fY\xd5\xa8vB\x07\x968\xa9\x03\x99<vA\x10p\xa4\xff\x14\x8e\xf4\x9f\xc2cO?\ |
---|
| 3832 | \x8d\xcb\xd6\xaeA\xd7\xbau\xe8\xa8\xf3b\xf5\xe5\xedY^#\xe5z$\xf0\xd6\xd6\xa1\ |
---|
| 3833 | \xbe\xad\x03\x80\xe4<8\x19\xf4\xe3\xb97\x9e\x93R\x0c\x8b,\xfe\xe1\xf84F\xcf\ |
---|
| 3834 | \x8f\xc1[[\x87F\x9f\x0f\xfd\xa7\x07r\xbe\xd6\xdb(-\x9b\x03\xe1\x0b\x05\x97\ |
---|
| 3835 | \xf8s\x02\x8f\xeb7\\\x8f\xbb\xb6\xdd\t@2\x17;x\xf0\x1d\x0c\x8e\x8e"\x1c\x8d"\ |
---|
| 3836 | \x14\x8d \x1c\x89\xa8"R\xbb\xcd\x86X<\xae\xfb\xa8\x07\xe2\xe5\xa2\xb4\xe1\ |
---|
| 3837 | \x05\xa4.Td\xa9N\x8c\xa5\xbc\x8d\x8e\xd9IX\x8a\xf4\xdd.\x17&\x03\x81\x8a\x91\ |
---|
| 3838 | \xba^vM\xbe\xe8\x9c/\xc0\x13G\xfe\xecY\x8d\x19\x90\xfcv\x94\xd9=\x95|\x04 \ |
---|
| 3839 | \xed\xad(\x8a\x80\xb4+\x11\xd5q\xceF\xea\x80D\xc0\x0e\xbb\xbd\xa4\xd5\xac(\ |
---|
| 3840 | \x08p:\x1c\xb8\xd8\xbe6sLB\x10\xcd\x90\xdc?\x1f~\xf4Q\xd9e\x15X\xdc\xd6\x92\ |
---|
| 3841 | \xa5"\x1c\x8d\xe2\xcd\x93\'aS\xd8\x18W3\x96<\xa9\x13\xd04-\x93\xfb\x85\xd04^\ |
---|
| 3842 | y\xedu\xec;x\x084\xcd\x80\xa1)X\xccf\xb99/k2\xc9}\x1c\xe7\xfbH`5\x9b\xe1\xf5\ |
---|
| 3843 | \xb8\xd1\xda\xb8\n\xdb;;q\xcb\x1d\xb7\xe2\xd37|\n\xee}n\xbc\xf8\xf6\x7f\xcfY\ |
---|
| 3844 | \xa6\xafE0>\x85z\x8fO\xd6\xcc\xb5\x10\x04\x01&\xc6\xac\xca2(\x04I.\x85\r+;q\ |
---|
| 3845 | \xd7\xb6;qb\xa8\x1f\xf7|\xf1\xefq\xf4\x9d\xf7 \x08<8\x9d~\xa1D\n)d\xf3Rn\x06\ |
---|
| 3846 | B\xd3\xb0\x9aL`M&\xd9\xab\xddn\xb3\xc1\xe5tJ\x93F8"\xf9\xac\xbbj\x81\x911\ |
---|
| 3847 | \x00Mr4o\xad\xab\x81\xd7\xe3\xc69\xffyTj\'\x84aY\xa9a\x83\x90\x02`\x99S\xae(\ |
---|
| 3848 | v\x9f\xa4\xc6f\xc3+o\xbc\x81}\x87\x0e\xc9c\xa4\\\xe3M\xef1\x95L\xa1\xf7\xea\ |
---|
| 3849 | \x0f\xe0\xbf\xbe\xf3\x1d\xd5q\x10B\xd7Z\x03\x00\xc5;\x9e\xe6\x82 \x08\xf0\ |
---|
| 3850 | \xb8\x9c*\xa9\x8d\x8c\xc9\xc9\xa0\x1f\xaf\x1e>\x84\xa3\xfd\xa7\x00HM2DQD\x9a\ |
---|
| 3851 | \xe3\xe5\xf1\xb6\x14\xc0\xb2,\xac\x16K\x955r\xc9\x8deC\xea\x044M\xc3j1\xcb\ |
---|
| 3852 | \x1a\xb4 \x8a\xa0\x00p\x82\x00n6B\x13\x93IP\x14U\x96G\x82iA\xc0d \x80#\xfd\ |
---|
| 3853 | \xa7\xb0s\xf7n<\xf2\xf3\xe7\xf1\xec\xa3\xdf\xc4]\xdb\xeeD\xff\xc4I\x9c\r\x0c\ |
---|
| 3854 | \x17E\x0eD;\xcc\xd5\xc4\x83\x17D\xd4\xba\xa4\xc8a2\xe8/*\x9d\xeb\x86\x9e\x1b\ |
---|
| 3855 | \x00\x00\x9f\xfd\xca\xbf\xe0\xf0\xb1\xe3\xb0\xd7\xd4\x80\xa1,\x80\xad\xb4TB\ |
---|
| 3856 | \x92\x9d\xa3\x9c4I\xc3c%\xa1\xeb\xa5\x85\xd5\x9bL\xf06:d\x99\xc6[[\x87\xd6\ |
---|
| 3857 | \xc6U8\xd2\x7fJj\x97V\t\xcb\x001\x93\xdb\x8c\x02\x95\x14\xa5\xb4U\x88\xa6.\ |
---|
| 3858 | \x88"\x12\xa9\x140Kd\xe5\x1aoY\x8f4\x8d\xe8L\xac\xe0<\xeah4\x06W\xbbC\xdeS\ |
---|
| 3859 | \xf4\xd6\xd6a\xcf\xfe\xd7JnRBz\x94*\xe5He\xa4\xeev8\xe5\x822\x87\xdd.\x9d\ |
---|
| 3860 | \x13 \xd3\x01\x89\x07 \x16\x90\xedD\xcd\xde;\xf4\xe2\xb7\x0f\xacv,\xb9\x94\ |
---|
| 3861 | \xc6bA\xcfv\xb7Q\xf6\re\x18\x064M\x97\xe5\x91\xfc\x98L&\x98L&\xd4\xcc\x12X\ |
---|
| 3862 | \xff\xe9\x01|\xe3\xfb?\x06\x00t4\\V\xd41g\xb9(\xb2lN?\x94b22\x92\\\n^g\x1d\ |
---|
| 3863 | \xbc\xb5u\xe8\xeb\xeb\xc3\xe1#Ga6[$\x0f\xed\x05\xb8Y\xb4\xbd1\tH5"\xd1`[W5\ |
---|
| 3864 | \x82\xe3\xb8\xca\xf9\xaaS\x94\xaa\xb7\xea\\\x1b\xa3Z\x14\xaa\xa9\xd34]\xb6q\ |
---|
| 3865 | \x96\xeb\x91\x9d%\xe2B\xf3\xa8\x1d\x0e\xbb$\xbd\xcc"0=\x85=\xaf\xff\x16\x89\ |
---|
| 3866 | \xd9\x89\xa2\x18\x90\x1e\xa5]\xeb\xd6\xc9\xcf\xc9f^:\xd0\x12\xba\xf4!"\xc0\ |
---|
| 3867 | \xd0s\xff\xd0\xa2A\xe8\x05b\xd9\x93\xfa\xa2@\xa0\xc0\xb2,^=x\x10\x93A?:[\xbb\ |
---|
| 3868 | fS\xfe\n\xcf\xbf\x1e\x8fH\x9e\xe7+\\\xb5\xba\xcb\xd4Rr\xb99>\r\xbb\xc5\x8ez\ |
---|
| 3869 | \x8f\x0f\xa7\xc6F\x10\x9e\x89U\xcc\x11\x91\xdc\xc0Zh\x1b\x11+K\xd4\xc9\x86\ |
---|
| 3870 | \xf6B\xa45\x02\x92\x9dk\xa1\x98o\x9ez\xa5\xa1\x8c\xd4\xe7\xda[!\xf6\x00\x1e[\ |
---|
| 3871 | \x1dF\xcf\x8f\xe1\xd5\x83\x07ab\x8b_\xb4\x0b\xa2\x08\x9af\xb2\xd2\x19\x95EeK\ |
---|
| 3872 | \xa9\x12s\xb9\xc0 \xf5J\x80\x96L\xb6\xa2\xb1\x18F\x07G\xe0\xad\xad\x83\x85-\ |
---|
| 3873 | \xae\n\xb1\x98~\xac\xa5|\xae\xb6\xac{\xa1\xa0\x8d\xd4\xeb\x15:%\x89\xd4\xdb[\ |
---|
| 3874 | \x9a`\xb3Z+g\x17 \x8aH%\x0b\x8f\xccy\x81/9O}\xa1\xa0\x8c\xd49\x81\xcf\xab\ |
---|
| 3875 | \xa7\x13{\x00\x00xi\xcfA\x8cNL\x94\xd4\xc6N\x10\x04X-fl\xde|\x89,\xbdh\'>\ |
---|
| 3876 | \xb7\xc3\xa9\x9a\xe0\xb9y\xf8\xcc\x18(\x0c\x06\xa9W\x10\xb1x\x1c\xa7\xc6FP\ |
---|
| 3877 | \xef\xf1\xc1f\xb1\x14e\xf0\xaf5\x9b*\x97\x1d-\xb9\xb1IF\xc2|;-)\xc1\xe51 \ |
---|
| 3878 | \x0b\xcf\xa6e\x16\x12\xa9\xc7&\xfc\x92=B\x05\xd2\xc7DQ\x84(\x8a\xd8\xb4\xb1\ |
---|
| 3879 | \x0b^g]A\x19\x1f\xda\xbd\x90R\xbc_\x16\x12\x85dA\x91\xfc\xf9\xa3\xef\xbe\x0b\ |
---|
| 3880 | \xa0\xb4\x86\xd3\x89d\x12\xeb\xdaV\xa3yeS\xce\xd7\x18\x91\xfa\xc2\xc3 \xf5\n\ |
---|
| 3881 | \x81\xa6i\x95\x87I\xb1\xf9\xea\xcb\x016k&\x9d.W\xbb:\xbdH\xfd\xf53R\xf1\x15[\ |
---|
| 3882 | \x81\x94FQ\x14\xc1P,:\xb7\xac\xca\xba&\x85\x16\x07U\x9b\xf7\x8b6cI\x0b\xe5\ |
---|
| 3883 | \xaa\x8fH/\x00p&0\x80\xa3\xfd\xa7`1\x97&\xc1q\x1c\x87\xab\xbb\xbbu\x0b\xc9\ |
---|
| 3884 | \xb4PE\xeb\xb3\x93\x7f%{\xd1\xfe.\xc3 \xf5\nB\x10x\xc4&\xa4\xe8\xb3RrJ\xa9X\ |
---|
| 3885 | \x88|ae)~8\x12\xd1\xdd\xcc#\x91\xba\xb6Iq\xa5\xd2\xddh\x9aF\x9aOa\xe4\xb8\ |
---|
| 3886 | \xfa\xfb\x97+O}1\xa0=Wde\xa1\xe7\xa1\xee\x8a\xd5\xcaQ\xfa;G\xa6\x10\x8aDJ\ |
---|
| 3887 | \x92^x\x9e\x87\xd9l\xc1\xa6\xf5\xea$\x00=\x93\xb6\\(\xe7*\xd1@\x06K\x86\xd4i\ |
---|
| 3888 | M\x06K\xa1?\x8b\x05\x92I\xa0\x94\x17\xaa\x99\x18\xca\r\xab&\xfas9\x9d\xbaKq\ |
---|
| 3889 | \x12\xa9++N{\xaf|?\x1cv{^9g>Hs\x1cB\xd1H\xc1\x96\xcd\xd5\xdcB\x8d-\x80\x90\ |
---|
| 3890 | \x95~/@\xc6\x8f\xe5@_i~A\x80\xe4\x10\xba\xca\xb7\x12\x976\xb5\xc8\xcf\xe5\ |
---|
| 3891 | \xca|\xc9\xa5\xa3\x1b\x91ze\xb0$\xf2\xd4y\x9eGb\xb6`\xa1\x18\x90b\x98R"\x91r\ |
---|
| 3892 | \xa3\x982\xfeJBYt2\xd7\xb2\xbdX(\t&\x91Je\x11\xbb\x1e&\xd3i\xb4\x93\xdf\x15\ |
---|
| 3893 | \xd1z%=6L,;\xab\xf1{a\xb3X$W\xc99R\x1a\x8b\xcdS_H\x14z\x1dI\x15\xa9\xc7V\x87\ |
---|
| 3894 | 3\x81\x01\xbcs\xe6\x8cJ"+\x06\x1c\xc7\xe1\xf76oFs{\x8b\xaa\xaa\x95D\xea\xc4\ |
---|
| 3895 | \xba\xc0\xc0\xc2cI\x90\xba\xcdb\x81\xd3Q\x1a!r\xe94R\x8bX\xb9F"\xd1j\x91_\ |
---|
| 3896 | \x94\x86H\x95\xac\xe8\xcbE\xe8se\xbfL\x06\xfd\xd8\xf3\xfao\x11\x9b\x99\x81\ |
---|
| 3897 | \xdb\xe5\xaaX4\x17\x08*\xceC\x01&^JT\x8b\xa6\x9ek%\xaa\xdc\x1b\xc8UE\xfa\xdb\ |
---|
| 3898 | }C\x88\'\x92\xa8)\xe1\xbb\xa4\xd3ix=\x1e\xdcu\xfb\x07\xe5\xe7d\xa7\xcd\xf3\ |
---|
| 3899 | \x12\xa9+\t\x9d\xe3y\xb9\xfa\x95\xc0\x88\xd2+\x87\xaa\'\xf5t:\x8d/~\xf2\x93\ |
---|
| 3900 | \xb8\xf7\x8f\xee\xc8\xf2[)\x04\xbf\xd9\xbd\x1f\x9f{\xf4Q\xb9`c\xa11\x9fVa\ |
---|
| 3901 | \xcb\rn\x87d\x13\xa0W\x80\xa44\xfd\x1a\x9e\x18/j\x15!\xccZ\x13\x17\x1a\xd9\ |
---|
| 3902 | \x93q\x10\x89G\xe0\xb49\x0b\xda \x95\xf3\xd4\x97H\xf4\xa9\xd4\xd3\x1d\xc8l\ |
---|
| 3903 | \x08\x13=\xfd\xb7G\xdf.y\x834\xcdq\xd8\xd6\xd3\x83\x8dk\xbb\xe4{\xd2ZW\xa3Jg\ |
---|
| 3904 | \xcc\x15\xa9WJR+\x14\xe9t\xba\xe8&,\x0cM-\x19\x8b\x00`)\x90:\xc7\xa1\xbd\xa5\ |
---|
| 3905 | \xa9$\x17\xc1z\x8f\x0f\xa3\x97\x8f\x81\x17DT\x81\x02\xb3(\xad\xe6\xf2\xa1\ |
---|
| 3906 | \xdc\xf2\x8b\x12\x89T\n\x9e\x1c\x16\x07J\xeb\x03"\xbf\x90\xeb\x1b\x98\x9e\ |
---|
| 3907 | \xc2\xb8\xdf\x0f\x13\xcb\x16\x1c\xcd\xd14-\xa7*\x16B\xec4M!\x1a\x8b\xc96\x01\ |
---|
| 3908 | sy\xbfT{\x9ez>\xabb\xb2B$\xae\x8c\x80\xe4\xd7?21\t\x9a.M\xde2\xb1,\xde<y\x12\ |
---|
| 3909 | GN\x1f\x95\x89]\x9b\x9f\x9eKza\x19fQ\x89\xbd\xd6\xe5*\xe9}\x89D"o_\x83jB\xd5\ |
---|
| 3910 | \x93\xba\x12\x8f\xbd\xfc(\xce\x06\x86\xe7$F^\xe0\xe1\xb6\xbb\xf1\x8d\xbb\xbf\ |
---|
| 3911 | \xa1j\x88\xbb\x18 \xf2B5j\xea@\xe5\x96\xc1V\xb3\x19\xf1DR\xa5\xd9\x86\xa2\ |
---|
| 3912 | \x11\xb464f\x0c\xbd\xa0\x96_\x00`\xf4\xfc\x18\xceO](h\x1fD\x10\x04X\xcdf|\ |
---|
| 3913 | \xfc\x96\x9bq\xa0\xaf\x0fG\xfaO\x15$\'Hn@\xa4\xa2\xd4:\xa7\xf4\xc2\xd0\x0c\ |
---|
| 3914 | \x12\xe9\x84\x1c\xa9W\x83\xa6\x9e/\t\x80\x14\x1e)%?e\xc1\xd1\xeb\xfb\xce \ |
---|
| 3915 | \x95J\xc3l6\xa1\x14\x8a\xa2i\x1a\x81`P\xba\xb7f\xed\xc6\x95\x8d1\x00u\xa4\ |
---|
| 3916 | \xae\xdc\n#\x84^1_\x9f<H$S\xf8\xe2\'?\x89\xdb\x7f\xff\xda\xa2\xdew\xe4\xe8;\ |
---|
| 3917 | \xf8\xe2\xbf~\x13\xd3\xe1\xf0\x92\x88\xd8\x97\x14\xa9\xc7\x92\xb193H\xd8\xd9\ |
---|
| 3918 | \x1b\x90\x80X\xd3.\x16\x88\xfcR\xad\x9a\xfa|o.-\xb9(\x9d+\xb5\x9bpD~i]\xa5\ |
---|
| 3919 | \xef<\tH>0zMA\xf4\x90Js\xd8\xfc\xbe.|\xeb\x81\xbf\xc5\xc3\x8f>\x8aw\x87\xce\ |
---|
| 3920 | \x82\xe7\xf99\'\x04\n\x12\xb9\xd0\xbc$K\x14\xaa\xa9\x13\xa3\xaaj\xd1\xd4\t\ |
---|
| 3921 | \x18M\xc4\x1dO&e\xf9\x85\xe8\xe9a\xfb4V\x0b\xed\x08\xc6\xa7\xd0?(Y9\x97\x9a\ |
---|
| 3922 | \x1d\x96\xe6x\xacim\xc6\xc6\xaeK\xe4\xe7H\xe6\x8bnJc!\x86]\x15\x06\xf1\xa9io\ |
---|
| 3923 | i\xc2\xfa\xb6\x8e\xac\x14\xda\\P*\x04\xbc V\xcc9\xb4\x9c\xa8zRWn\xe6\xd9-\ |
---|
| 3924 | \xf6\x82,l\x95\x11\xf1bF\xea\xcae\xb1\xb6Bt\xb9BkI\xac%@\xad\x9eN\xe4\x17\ |
---|
| 3925 | \xa2\xa9\xc7&\xfc\x10\x04~\xce\xc9\x86\xa6(\xa4RI\xfc\xf1m\xb7\x02\x00n\xdc\ |
---|
| 3926 | \xb2\x05\xaf\x1e>\x84\xd7\xdf|kNR\'\x9f\xaa\x8c\xd4\x0bE\xbd\xc7\x87\xd6\xc6\ |
---|
| 3927 | U8|\xecx\xd5n\xf6\x91H]\xa9\xa7\xbbb\xb5\x80\r\x18\x9d\x1c\xc3\xd8\xa4\x1f&v\ |
---|
| 3928 | ~z\xa4\xd6\x99Q\xa9\xa9\x07\xe3S\xd8X\xdb%\xbfV,Q\xe6\xa9$\xe6Z\xf5\xf3\x02\ |
---|
| 3929 | \x0f\x86f\xf0\xd0\x1d\x0f/\xf0\x91\xcd\x1fK&O\x1d\x98\x8d\xd4\x8bLk\\\xecH\ |
---|
| 3930 | \x9d`\xbe\x91z%\xb4\xbcrj\xeaJ\xdb\xdd\xb9\x10\nGT\x8d2\x80LD4\x99N\x83\xa6\ |
---|
| 3931 | \x999\t}&\x91\xc4\xa6\xce\r\xe8\xddz\x15&\x83\xfe\xa2\x8a^\xc8\xf1\x92H\xbdP\ |
---|
| 3932 | \x9c\tH\x11n\xbe\x95F5A\xa5\xa7\xcf\xe2\xf5}g0\x13\x8f\xcf+i@\x10\xf8\xacB2\ |
---|
| 3933 | \xd2\xf5\x0b\x906c\x95I\r\xe5\xb2\xb8(\x17&\x83~y\xd5\xcf\x0b\xbc\xee\x0f\'\ |
---|
| 3934 | \xf0\x0b\xd6W\xb6\xdc\xa8zRW\x12O)\xa5\xf6\x81\xf1h\xd6\xf2t\xa1 \x08\xbcJ3.\ |
---|
| 3935 | \xb5\xf8\xa8\x92\x1b\x9a\xe5\x8a6sm~\xe9\xe9\xcfn\x97S\xf6\x9e\xd1f\x07]\x08\ |
---|
| 3936 | O\xcfY\x8f \x88"\x04\x81\xc7\x9f]\xb7\x1d\xf5\x1e\x1f\xea=>\x04\xc6\xa3\x18\ |
---|
| 3937 | \xf7\x17\xb6\xa4\x86(\xaa&\x1fNH\x15\x94\xa7N\x9c37\xad\xbf\x0c,\xcb\x82_\ |
---|
| 3938 | \xa4\r\xbfbe\x13b\xb5\x1b\x8cOax\\\xfa\x0e\xf3\r\x12\xf42\x98\x8am\xd8\xb2X\ |
---|
| 3939 | \xa8\xf7\xf8d.af\xbb\x92i\x7fX\x9a\x91\xa3\xf8jv\xe7\xd4C\xd5\x93\xba\x12\ |
---|
| 3940 | \xb1d\xac\xe0\x96m\x04\xdeF\x87d\x0e\xb5\xc0\xd0F\'\xa5n\x94\xb6\xb74I\xde\ |
---|
| 3941 | \xe2er,Tn\x94\x12M\xbd\x1c\xc8U\xd9H\x1adh\xa1\x8d\xd4\t\x86\xcf\x8d\x03\xc8\ |
---|
| 3942 | O\\3\xf18.n[\x8d\x0f\\\xb7U\xf5\xbc\xd2\x96 \x1f\xc8\xb51Y\xa4\t\x85\xc8/\ |
---|
| 3943 | \xf9d\x18\x96f0\x11\x9a\xc0d\xd0\x8f\x8d]\x97\xa0\xb9\xa1\x01in\xf1\xb5b`n3.\ |
---|
| 3944 | \xb7\xdd\r\x8f\xad\x0e\xa1X\x08C\xa3c%\xd9\xecf}\xa6&\xb3Ik\xb9\xab:>TA\xea\ |
---|
| 3945 | \x99\x02\x85\xea\xe9\x04\xd5\x9a\xf5\x94\x0bUO\xeaZM\xbdX\xf9%0\x1e\xadxwz=\ |
---|
| 3946 | \x08\x82\x00\xab\xd5\n{\x83$+\x14Z\x92\xae\x07\x96e+gC[\x01\x14RI\xaa\x85\ |
---|
| 3947 | \xf6F\xcb\xb5\x82\x10E\x11\x1c\xc7\xe1\x0fo\xfc}\xac\x9f\xed\t\x0bH\xce\x8e\ |
---|
| 3948 | \xd1X\xe1\xe7\xd8j6\xc3is\xaa\\\x1a\xe7\xca\x80\x89%c8r\xfa(\xd6\xb7u\xe0\ |
---|
| 3949 | \xf76oF*U|O\xcf\x85\x82R\xee\x0b\xdb\xa5UQ4\x1a\x9bwCoQ\xc7C\x1d\xd0\xb7\x08\ |
---|
| 3950 | \xa8\xf7\xf8$\x99\xa6J\x9a[p\x1c\'\xcb\xb1\xb1d\xac*\xb2\xd1*\x81\xaa\'\xf5\ |
---|
| 3951 | \xf9\xc2\xdb\xe8X4\xf9\xc5QS\x83K\x9bZ0\x19\xf4#\x9eL\x16\xb5\xca\x88%cR{\ |
---|
| 3952 | \xb7FGY"+\x02e\xf6\xcb|e\x9db\xa2|\xb7\xc3\xa9_t4+\xbf\x90j\xd2\xe1\xf1sy\'\ |
---|
| 3953 | \xe1d*\x8d\xb6\xe6f\xdc\xb8eK\xd6\xdf\n\xcd\x7fNs<\xbc\x1ew\xd1r\x1e\xcb\x98\ |
---|
| 3954 | \xf0\xf2\xa9\x97\x00\x00_\xfc\xd4\'\xd0\xe0\xf3I\xfa\xf4"\xe5.\xb3\x0c\x03\ |
---|
| 3955 | \xd6d\xd2\x95R"\xe2\xb4\xae\x7fz\xa5\xa0\x8cf\x89\xb7L\xb5\x81e\xd9EOq^\x08T\ |
---|
| 3956 | =\xa9+\x89\xa7\x94h70\x1e-\xba\x82\xac\x1cHs\x1c\x9a\xeb}\xe8\xee\xee\xc6\ |
---|
| 3957 | \xe8\xe0\x08b\xa9h\xc1\xc6P,\xcd\xc8\x11\xa4\x97\xf6\x94\\\xf9\x97\x0fn\x97\ |
---|
| 3958 | \xb3\xa26\x01\xdat\xc6P4\x92\xe5\xa5\x0ed\xcb/\x81`(\xef$,\x08<\xae\xb8\xec2\ |
---|
| 3959 | 4\xb7\xb7\xc8\xd1=y\xb4\x16\xd8\xed=\x95J\xa2\xb5qU\xd6\xe6\xf5\\Y0D\x82yz\ |
---|
| 3960 | \xdf3X\xdf\xd6\x81\'\xfe\xed\xcb\xa8\xb1\xd4 \x14\x0e/\x9a\x81\x9c\x9eYV\xae\ |
---|
| 3961 | \xc9*\x1aJ\xc8}z\xf5 \x8a\xe2\x9c\xfb\x04\xd4lj\xe0\xe0\xe8\xa8\xeay\xedF)\ |
---|
| 3962 | \x81\xdeD\xbe\x18 ]\x9aJM\x9c\xb0\x9a\xcd%u\x1b[\x0cT=\xa9+Q\xcaF\xa9\xb7\ |
---|
| 3963 | \xd1\xb1`\x17\x83T5&f\xbb\xea|\xee\x13w\x03\x00\x0e\xf9\x0f\x17\xbdI\x9a\xe4\ |
---|
| 3964 | \xe2\x08LO\xa1\xb9\xbd\x05n\x97\xabl\x13S4*M\x8c\xe5l\x19\x97+\xf3E\x99\xceH\ |
---|
| 3965 | "\xf5\\\x8d\xb4\x01\xe0\xe7\xcf>\x8f\xf3\x17.\x80\xc9\xb1\x82\x10\x04\x01&\ |
---|
| 3966 | \x96\xc5\xf6\xceNU\xfep\xbd\xc7\'\xcb\\sI\x0b\x84x]\x0e\x07\x9a\xeb\x9bT\x92\ |
---|
| 3967 | \xcb\\\x9b\xa5\x0c\xcd\xc0j\xb2b\xcf\xc9\x97\xd1\xd7\xd7\x87\xed=\xbd\xf8\ |
---|
| 3968 | \xcf\xef\x7f\r\x9b:7 \x14\x0e#:3\x03\x9e\xe7!\x08\x82<\x16\xca\re\xaa\'\xf1T\ |
---|
| 3969 | \xa1(*\x8b<\x9dT-\xa2\xd1\x98*\xf3\x85@/\xb2\xe7y\x1e\xf6\x9a\x1at\xaci\x87y\ |
---|
| 3970 | \x8ej^\x9af0<!\xed}\x90\x02#k]\x8d,\xbf\x04\xe3\x99\n\xd3\xf6\xe6f\xd5{\xc9X\ |
---|
| 3971 | Y\xe8tPA\x14Qc\xb5\xc8\r=\ni\x8e\xb2T\xb1\xa4\xf2\xd4KA`<\n\x8e\xe3\x10\xe5\ |
---|
| 3972 | \xb8\x8af\x91(\xd1\xdc\xd0\x80\x07\xee\xbc\x13\x1f\xbb\xf9V\x9c\x18\xea\xc7\ |
---|
| 3973 | \xe1\xb3\x87`5\x15\x16E\x12p\x02/W0\xea9\xe9\x11\x89\xa2\x18?\x12\x961a"!e?\ |
---|
| 3974 | \xdc\xb8e\x0b\x1ez\xec1Dgf`\xb3ZU7\xfa\\\x11\'\xb9!\x05Q\x9c\xf3\xb5\xb9\x9a\ |
---|
| 3975 | c\x00\xd9Q\xfa\xaec\xc7\x10\x9b\x99\xc9\xf9\x1eQ\x14Q\xebr\xa1\xbb\xbb[\xa5\ |
---|
| 3976 | \xc1\x93\xdf=.\'\xa6\xc3\xe1\xbcy\xea\x1c\xcf\x83eY\xf4^\xf9~xl\x19",\xd4\ |
---|
| 3977 | \xd0\x8b\xa1\x19$\xb9\x14\x1e\xef{\x1c\xb7\x0bw`{O/6\xfe\xa0\x0b{\xf6\xbf\ |
---|
| 3978 | \x86\x1f=\xf7<N\x9e\x1e@$\x1aEb\x81H\x83\x13\x04D\xa3\xd1\xacUPD\x9cF\xa3s\ |
---|
| 3979 | \x95\xec\xccH@*I\xb5Hs<\xacf3n\xbe\xe6Z\xfch\xe7N\xc4\x02\x01\xd09\xd2S\x19\ |
---|
| 3980 | \x9a\xc2\xb8\xdf\xafJ[Tf\x88xlur\xd4~\xe3\x96-\xf8\xf6\x93O":3\x03\xab\xc9\ |
---|
| 3981 | \xb4\xa0\x16\x01dR\x15\x04\x01\xb1\x99\x19l\xea\xdc\x80\xf5m\x1d81\xd4\x8fX*\ |
---|
| 3982 | Zt\xd2\xc5RA\xd5\x93\xba\x12\xa5\xc8/\x976\xb5`S\xe7\x86\xbc\xe42\x1f\x90|]\ |
---|
| 3983 | \x97\xc3\x81\xf6\xe6f\xb4\xb74\xa1w\xebU\xa8\xf7\xf8pb\xa8\x1f\xff\xb1\xff\ |
---|
| 3984 | \xdf\x91H\'\xaa\xa2\xf3\x91\x855#\x10\x99\xc2\x89\xa1~tww\xe3\xe37\xdf\x8c\ |
---|
| 3985 | \x9f\xbc\xf0\x02":\xb2H\xb1\xe9\x9d<w\x00\x00\x1a1IDAT`YV\xb6:\xe6,\x16$R)\ |
---|
| 3986 | \xc4\x13I\xc4\xe2\xf1\xac\x02$\x12\xad\x13=}s\xa3\x03\'\x86\xfa\xd1?8\x90w\ |
---|
| 3987 | \xe2\x15\x04\x01\xcd\xf5>4\xb7\xb7\xe8\xfe\xbd\xd1\xe7\xc3\xd0h\xfe\xde\xab\ |
---|
| 3988 | \xa94\x07\xef\x8a\x15\xd8\xd8u\t\xbc\xb5u\xd8\xf9\xd6\xb3\x00\xe6\x8e\xd2\ |
---|
| 3989 | \x95\xb0\xb0f$\xb9\x14~z\xe8)\x9c\t\x0c\xe0\xb6-\xb7\xe1c7\xdf*O\xe2\xa3\xe7\ |
---|
| 3990 | \xc7p\xf0\xe0;\xb8\x10\x9e\x96\xb3y*\xd5\xd6\xcd\xed\x90|\xea7^z\xa9\xeay=\ |
---|
| 3991 | \xcf\x17\x19\xa2\xa8\xdb*0\x1a\x8ba\xf3\xe6Kp\xe4\xd4ex\xf1\xd5\xff\xc9Y=\ |
---|
| 3992 | \xa9\\5\x92\x02$\xad\xa1W0\x9e\x19g\x9f\xbd\xfbn<\xf6\xf4\xd3\xb8\x10\x9a^\ |
---|
| 3993 | \x94\xcde\x96e\xd1\xe0\xf3\xc9+\xe7\xfd\xfd\xfb\x8a\xf6aJ\xa4R\x8b\x92pQ\n\ |
---|
| 3994 | \xaa\x9e\xd4\xb5y\xea\x81Hq\x9b0\xdd\xdd\xdd8\xf4\xb3\xff*\xf7a\xe5\xc5\x89\ |
---|
| 3995 | \xa1~\xec=\xb6\x17\xfb\xdf=\x80X*Z2\xa1\x17\x93J\xc5\xd2f\xf0Ba\x9e$\xffy\ |
---|
| 3996 | \xf0i\xdcW\xbb\x03\xff\xf1\xb5\xaf\xe1\xae\xdb?\x88\x83\x07\xdf\x915\xd2p4Z\ |
---|
| 3997 | \x10\x01\x91\xc9\x8c\xbcV[\x8cB\xe4\x00B\xe0\xca\x14F"\x95\x104\xaflBbj\x06\ |
---|
| 3998 | \xc1p$\xef\x8d\x93\xe6\xb8\x9c\x93\xf3\xa5M-\xe8Z\xb7\x0e\xbf=\xf2v\xde\xe3f\ |
---|
| 3999 | h\n\\Zr\\\xaco\xeb\x80\xd3\xe6D$\x1e)\xcaz\x17\x90\x88\x9d\x17x\x1c8\xbd\x1f\ |
---|
| 4000 | \x87\xcf\x1e\xc2\xa6\xd5=\xb8\xc8\xbb\x06\x1b\xd7v\xc1[[\x87\xed=\xbd\x05\ |
---|
| 4001 | \x7fV%\xa1\x8c\xd4C\x824y\xe7\xcbQ\xf7\xd2\x1e\xb4\xaej,Z\xb2$\x9a\xba\xd2*`\ |
---|
| 4002 | \xf4\xfc\x18\xbc\xb5uxp\xc7\x0e\xdc\xb8e\x0bN\x8d\x8d\xe0\xf0\x89\x93\xd2\ |
---|
| 4003 | \xb1,@\xe7-2\xf6:\xea\xbc\xf8\xc0u[\xe5(\xbd\xd0\x953\xd9cIL\xcd\x80K\xa7\ |
---|
| 4004 | \x17-\xe1\xa2XT=\xa9+Qh\x9e:\xd9h|z\xdf3\x002\x1b7\xc1\xf8TE~\x072Y%\xe3\x91\ |
---|
| 4005 | s\x98\x08M\xc8)S\xa5\xba2\x92\xef\x19\x98\x9eBP\xe7\x06`h\n\x89\x84\xe4qS\ |
---|
| 4006 | \xef\xf1\x15LH\x16\xd6\x8c\x81\xc9\x01<\xf6\xf2\xa3\xf8\xe8\xe6\xbb\xb0\xbd\ |
---|
| 4007 | \xa77\x8b\x80H\xc9~\xbeG\xf2\xff\x92\xd7\x93\x7fk_\xabE\xae\xe7\x9f:\xfa\xbc\ |
---|
| 4008 | $\x9d\xe4\xb8q\xf4d\x9e\xc0\xf4\x94\\|T\xdf-}\xe6\x13;\x9f\xcb\x9b\xb6\xc7\ |
---|
| 4009 | \xb2,B\x91\x08~\xf9\xc6\x1b\xe8\xee\xee\xc6\xa6\xd5=x\xe9\xf8K\x00[\xb8\x04C\ |
---|
| 4010 | \xc0\xd0\x0c\xec\x16;\x92\\\n\x07N\xef\xc7\x81\xd3\xfb\xb1\xf3-;\x1a\xdc\r\ |
---|
| 4011 | \xb2\x8f9\xa9\x0b\xf0\xd8\xea\xca6\xe6\xf2\x81\x8cG=\x0fu7M\xf6\x97\xb2cp-\ |
---|
| 4012 | \x89\xe7\x9b\\\x19\x9a\xc2\xf9\xa9\x0b8r\xf4\x1d\xf4n\xbd\n\xc0\xac\xa6>\x05\ |
---|
| 4013 | uU\xe9x\x14{\xe3{\xd1\xd9\xda\x85\xee\xeentww\xe3c7\xdf:\xe7w\xa8\x04&\x83~\ |
---|
| 4014 | \xec:\xb4\x07\xcf\xf6=\rN\xe0\xe7\xbc/9\x81\x87\xdbbA\xbd\xc7\x87#\xc2Q\x84c\ |
---|
| 4015 | 3\x06\xa9\x97\x0b\xda<\xf5@dj\xce,\x12I\xf7\x8cK7+2\x95\x9c,c*\xfb\xefZ\x90\ |
---|
| 4016 | \xdc\xd7\xf9\xc8-\x9c\xc0c\xb5\xb7\x15\xeb\xdb:\xf0\xd4\x0b\xcf#\x12\xcd\xae\ |
---|
| 4017 | \x8a\xa5i\x1a3\x89\xa4|\x13\x15\x13\xa9\xdb-v\x9c\r\x0c\xe3[/}\x13n\xbb\x1b\ |
---|
| 4018 | \r\xd6Uh\xae\xcft\x84W\x12P\xa1d\xa2\x04\xd90\x1b\xc5\x88\xfc\x1cYuxk\xebpb\ |
---|
| 4019 | \xa8_\xfe\x9d`pd\x0c\xf1D\x02\xce<\xd9\x12\xda\xfd\x15om\x9dJ[onoA\xa3o\xa5,\ |
---|
| 4020 | y\xe8\x81\xa2(\xd04\x83W\x0f\x1f\xc2\x83\x00:[\xbb\xb0\xf7\xd4+\xe0\x05\x1e@\ |
---|
| 4021 | ie\xe1\x16\xd6,G\xeeI.\x85\x81\xc9\x01\xdd\xd7\x95:\xb6\xc8\x98R\xbe\x06\x90\ |
---|
| 4022 | &~\xa9\xfa\xd1,\xfb\xbd\xd8-\xf6\xac\x1c\xf5\xd5\x82\xd4[j:\x909\x07\xba\xc7\ |
---|
| 4023 | 7\xab\xa1_\xdf\xbb\x19?\xf9\xf9\x0bH\xa6\xd3\xba\xaf5\x99L\x08\x04\x83\xd8\ |
---|
| 4024 | \xf9\xf2\xafeR\xd7"\x18\x9f\x02\xe3\x06\xf8\x90\x05\xfbc\xfb\xb0\xbf\x7f\x1f\ |
---|
| 4025 | \x9c\xe9z0\xee\xa4j<i\xc7Y9\xd3!\x95\x81V |\x01\xd3\xf1 \xac&kA\x81\x16\xc7\ |
---|
| 4026 | \xa7\xd1`]\x05\x008\xfb\xd6 R\xa9$\x1cU\x92\xc93\x17\xaa\x9e\xd4K\x05)\xf7\ |
---|
| 4027 | \x05\xa0\xba\x88\x95\xf8\xbd\xdc\xe0\xf84\xae\xbaH\xaa\x96$]\x80r\x91\x1d\ |
---|
| 4028 | \xc9\xbb\xf5\xbaV\xe0l`\xb8\xe0\xb4Ir\xfc\x81\xc8\x14&B\x1382\xf1&\x80\x0c\ |
---|
| 4029 | \xa9\x10\xe2\xa0y;\x04&\x96\xd3\'\xc5e\x96\xfc\xa9\xdd\xb4\xfa\xf8\x1cniyK\ |
---|
| 4030 | \xa2U~\xcc\x02o\xa3CZ\x92\x13\xd2\'\xddr\x00Y\xfe)\xa6|]\xaf\x11C\xa3\xcf\ |
---|
| 4031 | \x87\x81\xe1\xd1\xbc\x9b\xa55V\x0b\x8e\xf6\x9f\xc2S/<\x8f\x8f\xdd|+.o\xb9\ |
---|
| 4032 | \x02\x07N\xefG\xad\xcdST\xa4\xae\x05\x19s\xf9\xc6\xc6|\xc6\x16y^\x99z\xa9$s=\ |
---|
| 4033 | \xb8b\xb5\x08b\n\x17\xdb\xd7b\xdaq\xae\x80o\x01l\\\xdb\x85\xb6\xe6&\x1c}\xe7\ |
---|
| 4034 | \xbd\xbcn\x99\xc3\xe3\xe7r6\xae\xd1\x124=Ba\xdc3\x08L\x02\xa7B\xdaIo\x00\xd3\ |
---|
| 4035 | \x01@\\\xa1\x96\xce\xc2\xa9p\xd6\xe7J&l\xc5Yn\xb0\x8c\t\xec\xec\xaa\xaa\x18\ |
---|
| 4036 | \x90@\xa7\x7fJ\x9a\rY\x9a\xaeZ\x137%\xaa>\xa5q\xbey\xeaK\r\xb1d\x0ck\xea\xd7\ |
---|
| 4037 | `{O/\xfa\xfa\xfa\xf0\xea\xc1\x830\x9b-YdG\xd34R\xa9$\x06G\xa4\x8dA\'U[\x92\ |
---|
| 4038 | \xb7\x8c\x855\xc3n\xb1\xcb?\x16\xd6\x8cZ\x9bGz\xde,\x11\xb5\xdd\xec\x80\xcdF\ |
---|
| 4039 | \xc1f\xa3\xe02\xbbT?zd\xeep[\xe1\n:\xe0p\xd8\xe1L\xd7\x83\x0fY\xc0\xb8\xb37\ |
---|
| 4040 | \xc8\x94{\x06$E._6\r\x19\x0b\x84H\xf4\x1a1t\xad[\x87T*\x99\xf3sDQ\x94\xd3\ |
---|
| 4041 | \xea~\xf4\xdc\xf3\x00\x80\xad\x1d\xdbPk\xf3 \x96\xaa\xee\xc2\x14\x966\xeb\ |
---|
| 4042 | \x12\xba\x12\xca\xf6u$\x9dQ\x99\x8d\x02\x00\x10\xf4\xcf\x8d\xb2\x12\xd8\xe5t\ |
---|
| 4043 | \xcan\x99s\xc1[[\x97\xd7\x1f\xc5\x99\xae\x87\xd0"\xc2\xe1\xb0K\xe3\xc2m\xc5*\ |
---|
| 4044 | \xd1\xabzM\xadW\n\x0c\x94\xe3I9\xce\xc8\xf8\xa3y;\xecf\x87j\xcc\xce\xf5ca\ |
---|
| 4045 | \xcdE5\x0f\xe7g\xa5\xa8\xce\xd6.L\x06\xfd8\xd0\xd7\'Uu/\x01B\x07\x96\x00\xa9\ |
---|
| 4046 | +Q\r\x19$\x95D,\x19C\xad\xcd\x83\xfb>\xb4\x03\x00\xf0OO<\x81\xa1\xd1Q\xddh\ |
---|
| 4047 | \x89\x90<1\xc6R\xca\'\xf3\x852Z\xb5\xd9(\xc4\xe3"L\xbc\x13\xf1\xb8\x884\xa3\ |
---|
| 4048 | \xd6\xf7CB4\x8b\xd8\xb5\xd0.\xb9\xb5HL\xcd\x14n\xc6\x05\xa8,_\xb5\x91\xe2\ |
---|
| 4049 | \xc7\xaf\xdb\x8e\xb6\xe6f$S\xf9#n\x87\xdd\x8e\xd7\xdf|\x0b\x8f?\xfe8\xd6\xb7\ |
---|
| 4050 | u\xe0\xe6\xf7\xdd\x02 sCW\x1b\xb4\x85QJB\'\xf7\x85\xb6\x98JYI\xda\xbc\xb2\t\ |
---|
| 4051 | \xe2\xb9\xd9\x82\xb3\x1ce\xfb\xc54\xa1V\x06[$\xfbE\x0f\x8c;\x89\x88i\x12\xce\ |
---|
| 4052 | t\xbd\\#\x01\x00aO\x14L*\xbbVBo<\xa5\x99\x88<\xfel\xb6\xca\xeb\xda\x89t\x02\ |
---|
| 4053 | \r\xee\x06\xaco\xeb\xc0\xe8\xe0\x08N\x9d\x19\x82\xad\xc0\xc2\xb6j@\xd5\x93z%\ |
---|
| 4054 | \xab\x1e\xab\t2\xa1\xf7\xde\x87z\x8f\x0f\x0f?\xfa(^x\xe5\x95\x9c\xb2\x0b\x89\ |
---|
| 4055 | \xa0\x8e\xbe\xfb.&\x83~t\xb6J\xfe\xd5\xe5 %B \x9c\x90\x92o\xa44\x13\x81\xcb\ |
---|
| 4056 | \xec\x82\x89Wg\x9f\xb8i\x87\x9cU\xe1p[\x11\xf7g\x13\x03\x1f\xcaO\x16\x01!\ |
---|
| 4057 | \x88`8\x02\x9b\xd5\x9a7\x1a"c\x81\xc8.\xcaG\x82\xee\xeen\xdc\xda\xfbA\xc4\ |
---|
| 4058 | \x13\t\xdd\xcf\xa0(\n\x1c\xcf#\x91J\xc1n\xb3\xe1\xcbO>\x89]\x87\xf6`{O/\xae\ |
---|
| 4059 | \xdfp=\x12\xe9D\xd5Z\xae\xce%\r\xe5\xf3\xec\']\x89\n\xad\xd5p;\n\xaf8V\xae\ |
---|
| 4060 | \x98\xb4\xfe/|\xc8\x02g\xba\x1e\x11\xd3$\x1c\x0e;\xc2\x1ei\xac\xc4\xfd\x16\ |
---|
| 4061 | \xd8|\xfa\xe9\x8dd<\x11\xc4\xe3\xd2\x98 \x84\x1e\x8f\x8bEy\xe0\x17\x03r\xff|\ |
---|
| 4062 | \xe8\xd2\xeb\x01\x00\xdf\xfd\xd9\xcf\x10\x8dF\xc1,B\x7f\xe3R\xb1t\x8e\x14\ |
---|
| 4063 | \xcbS~Ir)Yr\xb9\xaf\xf7>ys\xf4_~\xf8CX\xcc\xe6\x9c\x1a\xb3 \x8ap\xd8\xed8t\ |
---|
| 4064 | \xf4\x18F\x07G\xb0\xbe\xad\x03\r\xee\x06U\xd7\xa7RA\xc8\x83\xa5\xcd\xaa\x1b)\ |
---|
| 4065 | \xcdD\xb2tNed\x15\r%`\xf3%\xe1\n: \xb4d\xc8\x99q\'e}\x95\xa4\xbc)\xf3\x9a\ |
---|
| 4066 | \x03\xe3Q\xcc\xc4\xe3yupA\x14\xc1\xb2,Z\x1b\x1a\xb3d\x17\xe5\xbf\'\x83~t\xd4\ |
---|
| 4067 | y\xf3\x9a\xa0\xf1\xb3\xcf;\xecvDgf\xf0\xf9\x7f\xf87\xf4\xf5\xf5\xe1\xaemw\ |
---|
| 4068 | \xe2\xee-\xf7\x80\x9d5\xef\xaa\x16h]$\xf5\xa2t@_zQB\xcf\xa6\x81@\x99\xedB&\ |
---|
| 4069 | \xc9\xb9&\x80X<._\xc3\xc4\xec\xfe\x88\x9eSc\xc44)\xfd\x1f#\xb3\xd5\xbcA\x07l\ |
---|
| 4070 | \xbe\xa4n\x00\xa0\xb7\xeaSF\xe7$\xc8\x98\xcf\xdeG>$\xd2\tll\xb8B\x96?_\xdc\ |
---|
| 4071 | \xbb\x17\x0e\xbb}\xc9H/\xc0\x12 \xf5\xf9\xfa\xa9W+\x08\x99[X3nz\xdf\x87q\xdf\ |
---|
| 4072 | \x87v`}[\x07\x1e~\xf4Q\xfc\xd9\x83_F\x9a\x9b\xbb-\x1b\xcb0\x88D\xa3\xf8\xc9\ |
---|
| 4073 | \xee]\x002\xd1E\xb9"Mr\xe3\xc4\xe3\xa2\x1c\xa5\x93\x8d\xd1|\x08{\xa2\xa0G(8\ |
---|
| 4074 | \xd3\xf5\xf2sD~!\xb9\xcc\t\xc5&il\xc2_P\xe3\x06\x9afp\xe5E\x17I\x9f\xa3\x88\ |
---|
| 4075 | \xce\xb5\x12\x8c\xec\xd1\x9eG\x0f&\x9e)\x8e\x9a\x1a\x0c\x0c\x8f\xe2\xee/=(\ |
---|
| 4076 | \x97\xfe\x7f\xfe\xfa/`M\xfd\x1a\xc4\x92\xb1\xaa\x8d\xdas\x81H\x1c\xc4C]\t\ |
---|
| 4077 | \x97\xc3\x913\xfa\x16\x04^U$F\xea\x0c\xf8\x1c\x13#M3\x88+\xb2\xaf\xb4\xc5G\ |
---|
| 4078 | \x00\xe4\xbd\x14\xe58 \xd1z\xdco\x01o\xce^Yh\xa3t\x000\xf1N9\x98\xa8\x94\xfc\ |
---|
| 4079 | \xc2\x0b<b\xc9\x1866\\\x81\xbb{?\x8e\xc9\xa0\x1f\xf7\x7f\xf7;\x08E"\xf3r\xb5\ |
---|
| 4080 | \\\x0c,\xa9\xa3-\xc5O}1\xa1\xed\xa6B\x88<\xc9\xa5\xe0u\xd6\xe1\xa6\xf7}\x18\ |
---|
| 4081 | \x0f\xdd\xf10\xee\xdav\'\x00\xe0\x93\x0f<\x80\x87\x1e{\x0c\xbc \xf9T\xcc\x05\ |
---|
| 4082 | A\x14a\xaf\xa9\xc1\x8f\xfek\xa7,!\xdc\xbd\xe5\x1ep|\x1a\xb1dL\xfe\x7fK\x85\ |
---|
| 4083 | \x1c\x19\xda(\x84Sa\xddH]\t\xa5\xfc"\xb4\x88r\x84\xa6\x84^#\x05m\xa3\x0c=\ |
---|
| 4084 | \xf0<\x8fU\xbe\x95X}y{\xe6\xb3\x14\x12\x0cA\xbd\xc7\x87\x0b\xe1\xe9\xa2\xbc\ |
---|
| 4085 | \xe2]\xf6\x1a\xbc7t\x167}\xeesx\xea\x85\xe7\xb1\xbe\xad\x03_\xf9\xe8Wp\xf7\ |
---|
| 4086 | \x96{\xe0u\xd6!\x96\x8c\xc9\xd7m\xbe\xe7\xb4T\xcc\x15\x99\x12=}\xaeH}\xae\ |
---|
| 4087 | \xe8\x9b\x90t8*YV\xe7\xcbFJ\xe8\xec[(\xaf/\xe3N\x82\x0fYdM\x9dL\xf6\x00`\xf3\ |
---|
| 4088 | %u5u ;Z\x0f\xa7\xc2p\x99]\xb2\x0cC\x1e\xe7\x03\xed=\xc9\xd0\x0cnz\xdf\x87\ |
---|
| 4089 | \xf1\xc5;\xfe\x17\xea=>\xfc\xcd\xd7\xbf\x85W^{}Ii\xe9\x04U\x9f\xd2\xa8\x8d,\ |
---|
| 4090 | \xca!/,\x14H*\x15C3p\xda\x9cr>xgk\x97\xec\x05>\x19\xf4\xe3\xf1\xc7\x1f\xc7\ |
---|
| 4091 | \xd7\x9ey\x06C\xa3\xa3\xb0\xd7\xd4\xc0T\xc4N;\xc30H$S\xf8\xfc?\xfc\x1b\x9e|\ |
---|
| 4092 | \xc8\x83\xed=\xbdh^\xd9\x84\xfd\xfd\xfbpl\xec8b\xa9\xe8<\xceY\xc6s\x9a\x86]\ |
---|
| 4093 | \xbe\x99\x94\xc4\xee2\xbb2\xd1U\x08\x809\x01\xc0\nz\x84B\xd8\x13\x85\xd3"El\ |
---|
| 4094 | \x81P\x14\xdeF\x87L\x1a\xcah\x9d\x90p.\xd0\x14\x85\xf0\xcc\x0c\xb6_}5\x9aW6\ |
---|
| 4095 | \xe9n\x92\x12r\x9f\x0c\xfa\x8b\xaaV\xb4\x9a\xcdH\x00p;%\xdf\x98\x8f\xff\xd5_\ |
---|
| 4096 | c\xe7\xcb\xbf\xc6C_\xb8O.\xcc:1\xd4\x8f\xfd\xfd\xfbp:\xf0\x1e"\xf1\x08\x92\\\ |
---|
| 4097 | jA\xc7!\xcbH\xe4\x99D\n,\xcd\xc8\x8d\xb2U\x98\x8d\x01"\x91iI\x86\x81\x1d!\ |
---|
| 4098 | \x84\xe0\xb6\xbbq\x96\x1e\xc4j\xa1\xbd\xacV\x05\x0cMa&\x96)~#\x9b\xa5D\xbb\ |
---|
| 4099 | \xd7\xe6\x9b\xc7&\xfc\x80GZ\xc5EC\xb3\xe7\xce,=J\xe9\x8c\x99\x08=$D\xb3\x82\ |
---|
| 4100 | \x07\xf2\xefx\\\x84\xc0\xc4\x10K\x96\xd6E\x8c\x80\x14\x06\xba\xednlZ\xdd\x83\ |
---|
| 4101 | k:\xaf\x91\x8b\xe6\xee\xfb\xd2\xc3\xd8\xb9{7\x1cv{E\xdaHV\x1aUO\xeaJlZ\xdd\ |
---|
| 4102 | \x83Q\xeb\x98\x1c\x8dT+H\xa7\x19@\xca:\xf0\xd6\xd6\xa9\xaa(\'\x83~\xf4\xf5\ |
---|
| 4103 | \xf5\xe1\'\xbbwa\xd7\x81\x03\xe8?=\x00\xb3\xd9"\x97\xc0\x17\xab\xdfY-f\xf4\ |
---|
| 4104 | \x9f\x1e\xc0G\xee\xbf\x1f_\xfd\xcb\xcf\xa0w\xebU\xf8\xf4\r\x9f\xc2d\xd0\x8f\ |
---|
| 4105 | \xd1\xc1\x11i#2>\xa5\xf2R/7Ha\t \x91\xb8\xf7\xf2L\xb4E\xa27\xbd\x0c\te\x94\ |
---|
| 4106 | \x9d\xab\xd94/\x080\x9b-\xd8\xde\xd9\xa9\x9b\xc6\xa8\xfc\x9cz\x8f/\xaf\x13$\ |
---|
| 4107 | \x81\x9e\xb1\x94\xddf\x83\xc9d\xc2\xce\xdd\xbb\xb1\xef\xd0!\xdct\xcd5\xf8\ |
---|
| 4108 | \x8b\x8f|\x04\xcd\xed-\xf8\xf4\r\x9f\x02 ]\xbb\xc0\xf4\x14F\xcf\x8feU\x13/\ |
---|
| 4109 | \x06\x94\x15\xa3\x04\xdaL\xa3\xce\xba.\x8c\x9e\x1f\xc3\xb8\xdf\x9f\xd7\xc6\ |
---|
| 4110 | \x99\x8c\xbf\xc4\xd4\x0c\\\x8e\xfc\xee\xa6\x0c\xc3`&9#\xd7I\x90 \x85\\\x87\ |
---|
| 4111 | \xc0\xf4\xacS\xa3\x1d\x08\x08\x0e@\x91\xc1\x18\x18\x8f\xcaQ<\x000\x97d~\xd7[\ |
---|
| 4112 | \xdd\xcd\x07\xda\xf3C\xce\x8d\x97\xf6\xc0ZW\x933\xb8\xaa\x94W\xd4B\xa0\xeaI]\ |
---|
| 4113 | \xb9\\$2\xc5R\x02!\xd6=c\xaf!6\xe1\xc7\xebg\xce\xe0\xf8{\xef\xa2\x7f`\x10\ |
---|
| 4114 | \xb1\x99\x19\x98\xcd\x16\xb8]\xaeyo\xc4\xb8].\x8cNL\xe0\x8f\xff\xeeK\xb8z\ |
---|
| 4115 | \xd3\x15\xb8\xf3\xca\xab\xd0\xdd\xdd\x8d\xe6\xf6\x16t{\xba\xcb\xf4m*\x03\xe2\ |
---|
| 4116 | \x0b\xa3w\x0eh\x8aBt\xb6}\xdd-w\xdc\xaak1\xa0EG\x9d\xc4 \xa2(\xeaFZT\x8e\xc9\ |
---|
| 4117 | \x03\x00\xcc,\x0b\xaf\xc7\x83X<\x8e\'v\xee\xc4\xf3{\xf6\xe0\x8a\r\xeb\xf1{\ |
---|
| 4118 | \x9bz\xd0\xde\xd2\x84K\x9bZ\xd0\xdc\xde\xa2\xea\xba\xb4\x14\xf0\x8d\xef\xff\ |
---|
| 4119 | \x18\xfd\xa7\x07\xf2\x92U8\x92\x89\xe4\xdd.g\xde\xe6,4M\xc3\xc4\xb2\xd8\xf9\ |
---|
| 4120 | \xf2\xaf\x01H\xde;\xd6\xba\x1a9\x80\xa9\xf7\xf8\x80\xb6\xb2\x1d~\xd9A&\xe7\ |
---|
| 4121 | \xa7^x\x1e\x87O\x9c\xc4\x81\xbe>\x1c>v\xbcl\xf7\xe3b\xa2\xeaI\xddb6c\xe7\xcb\ |
---|
| 4122 | \xbf\x96\x8bl\xaa\x19\x17\xc2\xd3\x08\x85#\xb2)V8\x12A \x18B"\x95Btf\x06\x89\ |
---|
| 4123 | DB\x96\x19lVk\xc9\x91\xb9\x1e\x04Q\x84\xa3\xa6\x06i\x8e\xc3+\xaf\xbd\x8e\x03\ |
---|
| 4124 | \x87\xdf\xc4\nw-\x9a\xeb}p9\x9dhmh\x04 \xdd\xac\xe5\xf4R\xd7Bi\xa7\xab5\xeeR\ |
---|
| 4125 | 6( Y0^\xda\x83#\xa7N\xc1l\xd6\xdfC \xe7\xc6n\xb3a\xcf\xfe\xd7\xb2\x9a\x1c\ |
---|
| 4126 | \xe4jv\xecp8 \x08B\xce\xcdfQ\x14\x91H\xa5\xb2Z\xef\x91\x08\xde\xf2\xff\xb7ww\ |
---|
| 4127 | \xbfm[w\x1c\xc6\xbf\x14E\xd9\x8ad\xcf\xdd\xda4\xe9\x1b\x06\xf7\xaa\xd7\xf9\ |
---|
| 4128 | \x97w\xbb\x9b\xdd\xec\x05E.z\xd1`\xc3\x80\r\x05\xd6\x15\xd9\x16\xb4i\x1b\'\ |
---|
| 4129 | \xee\xe6\xda\x92\x15\xd9\xa6D\xeeB:\xf4\xe11)Q\xb6\x93H\xbf<\x1f h\x91\xc4\ |
---|
| 4130 | \x8aM&\x8f\x8e\x0f\x0f\x0f;\x1dmu::\xbf\xb8\xd0\xc3/\x1f\xe9\xe1\x97\x8f\xd4\ |
---|
| 4131 | \xef\xf7\xf5\xee\xde\x9e\xba\xdb[\xba\x7f\xf7\xee\x95\xa79\xbd\xeac\xeb{?I\ |
---|
| 4132 | \xf4"M\x17\x1eoiv\xcc\xff\xf0\xf9_\xf4\xdb?\xfdQ\xfd^\xfdw\xb8\xadV\xac\x1f^\ |
---|
| 4133 | \x1c\xea\xbb\xbf=\xd1\xbb\x0f\x1e\x14_G\xdd\x1b\xa3t\xb9[\xe3\xe8\xf9\xa1~3\ |
---|
| 4134 | \xdf\xa8\xab\x89Wu\x8c\xc2\x07w\xf8\xfc\x95?\xfe\xbf\xcd\xe3\xc1@\xc7\x83\ |
---|
| 4135 | \xd9\xd4N\xbf\xdf\xaf\xfdnq\x93\xac}\xd4\xe38\xd6\xef\xbf\xf8B\xbf{\xf8\xf0M\ |
---|
| 4136 | \x7f*\x0b\xb5Z\xb1\xe2V\xa4\xf1\xd9Y\xb1\rm\x96M\x8b\xa5bq+\xd2\xf6\xd6\x96Z\ |
---|
| 4137 | \xc16\xb4\xb7)\xcbs\xc5q\xac\xdd\x9d\x1dM\xa7S\x1d\x1d\x9f\xe8\xe8\xf8DY6-\ |
---|
| 4138 | \xcdY\xdft_y\xf7Z\xee\xeb\x8c[\x91\x92$Q\xa7\xddV;I\xb4\xdd\xe9\xa8\xbb\xbdU\ |
---|
| 4139 | <t\xda\x8f_\xb8k\xa34\xbb\xdd\xbcn\xb3\xa4,\xcfu\xa7\xdb\xd5\'\xf7?\xd0\xe7\ |
---|
| 4140 | \x8f\xfe\\\xfc|\xd5\xeb\xf8>\xbe\xf7\xfe\xc2\xed\x02\xc2P\xb5\x93D\x934U;\ |
---|
| 4141 | \x8e\x8b\xb0gy\xae$I\x94$I\xf1l\xd4g\x87?I\x92\xfe\xf5\xedwW\xae\x03\xdc\xe6\ |
---|
| 4142 | ~\xfd\xe1\xf9r\xc79\x8e\xe3bUO\xff\xcel:\xcb\x1d\xef\xf1\xd9\xb9NG\xa3\xd29\ |
---|
| 4143 | \x90\xa4\x83\xc3\x9f\x94e\xf9\xc2\xd5T\x9d\xa4\xad\x97\xa3\xb3\xcb\xc7\x0b&\ |
---|
| 4144 | \x89z\xdd\xae\xc6\xe7\xe7\xb5\x1f\x97e\xd3b\x9e\xfe\x97\xbb\xbf(\x065O\x9f\ |
---|
| 4145 | \x1f\x14\xa3~7\xa8y9\x1e+MSM\xb3\xbc\x98\xd6\x99\xdc\xf23\x0eZ\xadx\xe1\xd6\ |
---|
| 4146 | \xbe\xedv\xbb\xf83\xdd\xf1\x94\xa4\x9d~\x7f#\xe7\xce\xeb\xac}\xd4\xa5\xd9\ |
---|
| 4147 | \x06B\xaf\xeb\x01\x177\x11E\xb3\xb8\xad\x838\x8e\x97\xae\xfb\xbe\x8e\xf0\xb1\ |
---|
| 4148 | m\xee9\x99\x92J1\x97T\x04\xdd\xa9\x0b\xf1h\xbc`#\xb2<W\xc7;\xa6u\xaf\xe1\xb6\ |
---|
| 4149 | \xf4\x1d=?T\xef\xde]}\xb6\xff\xa9\x9e>;X8\xd2\x9c\xa4\xa9\xd4\xf0Q\x81\xee\ |
---|
| 4150 | \xdc.;\xbb\xb7\xf5\xb4#\xf79\x87\xc7\xba\xf8\xffy\xb8%\x15A?:9\x99\xad\xcdO\ |
---|
| 4151 | \xd3b\x8f\xfc\xa8\xd5R+\x8a\x96.\x8f\xcd\xf3\\\xad\xf9?\xb1\xfff?\xabw\xef\ |
---|
| 4152 | \xae\xfa\xbd\x9eF\x0b\xee\x1fp\x03\x16\xf7F\xe0.P\xbbs>\x18\x0e\xd5\xdd\xdeR\ |
---|
| 4153 | w{kvAz\xbeZf\x92\xa6\xa57\xce\xf0\x98U\x9d\xaf\xf0\xefk\xf8;\xdc\xc7\xf8w_\ |
---|
| 4154 | \xe7y6\xff\xb5\x8dZ\xe4wc\x1b\xf3\xd5FQ\xb4\xf6?6\x89\x8b\xf3\xaa?\x9aX\x18\ |
---|
| 4155 | \xe9\n\xe3\xb3\xfa\xd1`\xc8\x85\xc3m\x8f ]N\xf9\xb8)\xbaa\xf2B\x9f|p_I\xbb\ |
---|
| 4156 | \xbd0\xb2.,\xe1\x14\xccM\xbc\xaa\xbfKa\xd0\xa5\xf2\x92\xc2\xb3\x8b\x8b\xd9\ |
---|
| 4157 | \xd7\x1aE\x8at\xf9\xa6\xde\xf4\x9c\xa5\x93\xa9\xee\xdf}O\xef\'\xc9\xe5&q\xef\ |
---|
| 4158 | \xec)]\xb0*)nEW\xe6\xe1C\xbdnW\xe3\xb3\xcb\xd1s\xd53U\x9b\xfc;\n\xff\x1e6\ |
---|
| 4159 | \xf9\x98(j\xbduA\x976(\xea\xd8\x1c\xfeM,U\xcb\xe8\xfc \x1f\rN*\xd7;\xfb\xc2g\ |
---|
| 4160 | \x9f\x86\xdcH\xf1\xbd\xfd\xb6^\xa4\xa9Z\xdfG\xfa\xea\xf1c\xa5\x93I\xa3\x1bG\ |
---|
| 4161 | \xc2?\xbf\xdd\xf0\r\xe6u\xf2W\xeb\xf8atO\x98\xda\xeet\xf4\xab\xbd=\xbd\xbb\ |
---|
| 4162 | \xb7\xa7\xde\x9d;\x951wA\xcc\xb2\xac\xf81\x9dN5\x9dN\x95\xb4c}\xb6\xffii^\ |
---|
| 4163 | \xbe\xc9\n\x10\xf7\x06\x1e^O\n\x7f\x1d\xaf\xcf\xfa\xcfi`\xa3\xb8Q\x99\x0b\ |
---|
| 4164 | \xbb?\xfdr<\x18\x16\xa39?\xec\xdb\x9d\x8eNG\xd5\xb7\xe5\xe7y\xaew\xe6\x1f38=\ |
---|
| 4165 | \xd5n\xbf_\xbc\xce\xd1\xe0\xa4\x98\x86y\x91\xa6\xd2\x13i\xff\xe3\x0f\xf5\xd7\ |
---|
| 4166 | \x7f|\xad\xaf\xfe\xf9\xcd\xd2\xcf\xd5\xc5\xdb\x9f\x1a\x90.\x03\xba\x0e\x17\ |
---|
| 4167 | \xcd\xfc\xe7\xc0N\xa6\xd3\xe2s\x9e\xa4ii\xc4\xeeO\xc5t\xb7\xb7\xa4`\xd4\xec\ |
---|
| 4168 | \xaeoH\xd2\xc1\xe1aq\x9e\xdcE\xdfO\xee\xdd\xd7\xfeG\x1f\xe9\xc9\xf7?V>\x9d\ |
---|
| 4169 | \xaaJ\xab\xd5\xd2\xcf\x83a\xe9\\\xe2\xcd#\xea\xb8U\xe1N\x7f\xc7\xa7C\xed\xf5\ |
---|
| 4170 | w\x8a \xd7}L\xd54I\x9e\xe7J\xdam\xdd\xbf\xbb<0\xd2l\x1a\xe6\xc9\xf7?\xea\xe9\ |
---|
| 4171 | \xb3\x03\rF/\x17\xee\x05\xbe\xa9\x16\x85\xdd\xe7\xceC\xf8|XI\xfal\xffSI\xe5G\ |
---|
| 4172 | \x0e\xfa\xd7(^\xa4\xa9\xf6U^\xe2X%\x9a\x7f\x17Tu\xb3\xd7`8,\x8d\xd2\x97}7\ |
---|
| 4173 | \x86\xdb\xc3\xf4\x0bn\x95?\x7fZ\xe5x0,E\xe0x0\x9c?\x9b\xf4\xea_E7W\xea\xc7\ |
---|
| 4174 | \xc5-M\xab\x9a[wK\xfcv\xfb}u:\x89\xa6K\x9e\\\xefvk\x0c\xbfKX\xb7\xe9\x97,\ |
---|
| 4175 | \xcfK\xdf1\x84S1\xe1t\x8c\x9b\x92q\x0f\xfevqu\xc7\xd1M\x8f\xf8\xc7\xf2hpR:\ |
---|
| 4176 | \x96\xee\xfa\xc4\xa2\xc7\xda\xb5\xa2\xd9#\x15\xdd\xeb4}\xbe\xad\x7f\x91\x14\ |
---|
| 4177 | \xb7\x8f\xa8\xe3\xc6\xaa.~I\xf5\x11\x91.\xe3\xfe\xf4\xf9\x81^\x8e\xc7\xf5+T\ |
---|
| 4178 | \xe6\x01X\x14\x8b0\xec{\xbb;\xdan\xb0\n)\xcbs\x9d\xbe|\xa9\xf34-\x9e\xf7\xba\ |
---|
| 4179 | \xce\xfc\xb8O\xa6\xd3\xa5q\x97.\xdfd\x9b\x84]\xd2\xcaS)n\xc3/\xff\xdc\xfao\ |
---|
| 4180 | \xc2\x8b\xde\xe4\x9b^\xc4\xc5j\x88:\xae\xed:#\xdap\xfb\xd7\xc1pX\xbbEn\x96e\ |
---|
| 4181 | \xa5\x95)u!\x92te\xa4\xd9\xef\xf5j_\xd7\xe7VR\xd4\x8d\x84\xd7\xd1\xb2\xb8;~\ |
---|
| 4182 | \xd8\xdd\xa8]*\x87\xfd\xf8tX\x19\xf6\xbf\x7f\xf3\x8d\xbe\xfd\xe1Gu:\x8b\xdf\ |
---|
| 4183 | \x1c\xf3<\xd7\xd3\x83g\xc5\xeb\xb9\xd7\xae\x9az\t\xdf\xfc\x19\xa9\xbf\x1aD\ |
---|
| 4184 | \x1d\xb7\xc6\x9f7\xad\x1b\x19J\xb3(\xbb\x1fu\xab#\\\xd0\x7f\xfd\xd1\x87\xa5U\ |
---|
| 4185 | \x18Ua\x0f\xe3.\xad\xf6\x14\x9f\xdc\xbb\x18Y\xfa\x1c\xd6<:\xe1\x1b\x91\x8b{U\ |
---|
| 4186 | \xd8\x9d\xf0\xbc8\xee|<}v\xa0\xaf\x1e?\xd6\xe7\x8f\x1e\xe9,M\x1b\x8f\xa6\xab\ |
---|
| 4187 | V\xbc,\x1a\xa5\xaf\xfb\xb1\xddd\\(\xc5\xca\xdc\x8a\x0c\xff\xa2\x9do|v^\x19U\ |
---|
| 4188 | \xf7\x0f\xdf_\x11\xd3\xebv\xafL\xbd\xe4y^\x04]*\x07hwg\xa7\xf2\xe2kx\xb1n\ |
---|
| 4189 | \xd9\xdc\xbe/\x8a\xa2\xcb\x8b\x8fk>J\x0f\xb98\x86+d\\\xd8\xdbIR\xac\x8eq\xe7\ |
---|
| 4190 | e4\x1e\xab\xd7\xed\x16\xc7\xd5\xad\x869\xbb\xb8\xd0$M5\x9a\xefm\xdf\xe4\xde\ |
---|
| 4191 | \x81(\x8a4\x1a\x8f\xb5\xbb\xb3S\xba8\xea\x8e\x7f8J\xdf\xb4\xe3\xbb\x89\x88:n\ |
---|
| 4192 | $\x0c\xbb\x1f\x10I\xa5x\xb8\x11w8?\x9e\xab|\x87`\x96e\xc5\xaa\x0e\x17\xa0\ |
---|
| 4193 | \x90\x1fvI\xa5\x955\xee\xe7\xaa.\xbeV\xdda\xda\xf1\xeeV\xf6\xb7\t\xd8$\xcb\ |
---|
| 4194 | \x96>V\x85\xfd\xa7\xff\x1d\xe9l\x1e\xdb<sw_\xae~W\xf4\xcf\x83\xa1z\xdd\xee\ |
---|
| 4195 | \xd2\xa0\xe3\xf5 \xea\xb8\x91\xaa\xe5u>?\xca~\xdc\x07\xc3\xa1vwv4\x1a\x8f\ |
---|
| 4196 | \xb5\x9d$\xba\xf0\xee\\\xecn\xcdn+w\x91p\xff\r\xdf \xfc\x91\x7f\xb8a\xd3\xd9\ |
---|
| 4197 | \xc5\xc5\x95x\xbb)\x9db\x9f\x17\xef\xf3\rG\x92\x9b8=P\x17v\'|\xc3\xbd\x98L\ |
---|
| 4198 | \x14i\xbe\xca\xe8\x9a+~\xdcQj\x12\xf4\xc9t\xba\x91\xc7u\xd3D\xbb\x0f\x1ep\ |
---|
| 4199 | \x94\xb1\xb2\xaa=I\xfcH\xfa7\xc38U#ni\x16\x84p\xba\xc4}\\8\x95\x13\xbeF\xdd]\ |
---|
| 4200 | \x8f_\xff\xfb?\xb3\xa5\x8a\xde\x1e*w\xba\xdd\xe2F&7\xdd ]\r\x8f\xb4\x99Qw\ |
---|
| 4201 | \x9a\x9e\x9b\xd3\xd1H\xe7i\xdax\x8b\x8b\xf0^\x82\xb8\xd5R;\x8eK\xbb?\x96n\ |
---|
| 4202 | \xe2\xaa8\xae\xd2f\x1f\xdbM@\xd4qmM\xe3!\xadv\xe1\xb2n>\xbci\xdc\xfd\x15\x18\ |
---|
| 4203 | \xfek\xb9\x8d\xaf\xa4\xea\xf8X\x08\xba\xb3h#0\xc7\xddI\xdbt9gx\x8e\xfd\xf3\ |
---|
| 4204 | \x1b^\x90\xad\x9bC\xb7pl\xd7\x1dQ\xc7\xb55\r\x87\xaf*\xeeU\x11w\x91X\xf6\xf1\ |
---|
| 4205 | u\xa3\x7f_\xdd\xd4\x80T\x1d\x1f+\xe1\xa9;?R\xfd~:\xabnnV\x17s\x89\xa0\xbf)D\ |
---|
| 4206 | \x1d7\xd2$\xecR\xb3X4\xb9\x95|\x95\xd1\xbf\x9b\xba\xf1\xdf4\x96M\x0fX\nO\xd5\ |
---|
| 4207 | r\xc4\xa6q_E\xd5\x85P\x82\xfe\xe6\x10u\xdc\xd8uF\x84\x8b\xf8\x171\xab.\xc0V\ |
---|
| 4208 | \xbdA\xb8x\x87\x11w\x9a\x8c(\xad\x86\'<?uKQW9Wu+Z\x88\xf9\x9bG\xd4qc\xe1\x88\ |
---|
| 4209 | \xf0:a_\xb6\xec\xed:\xd3\x05U#\xffE\xeb\xa5\xad\x07\xa8\xeeF\xa2U\xee\x0c\ |
---|
| 4210 | \x0e\xdf\x10,N[m:\x964\xe2\xc6\xaan\x80\x91\xca\xcb\x1dWUZk]\x11\xe0\xba\xdd\ |
---|
| 4211 | \t+_+\xf8\xf3\x8b\x1bt\xde\xb2 \x85_cx\xbe\x9ab4\xbe\xde\x88:nM\x16\xdcn\xef\ |
---|
| 4212 | \xc7\xb3\xc9h0\x8cm\xf8\xe6P\xfa\xbdA\xa8\xc3\xe9\x9a\xbay\xde\xf0\x8d\xe2m\ |
---|
| 4213 | \x0e\x92\xff\xb5\xaf\xba\xb9\xd6\xdb|\xdc\xd6\x1dQ\xc7\xad\xaa\x1b\xb57\x1d\ |
---|
| 4214 | \rV\xfd\xbeE\x1f\x1b\xbe\t\xb8[\xe4\xeb>\x86\x98W\xe3x\xd8A\xd4\xf1J\xbc\xae\ |
---|
| 4215 | H\xb8;Q\xcf\xe7#s\xb7\x83!\xdb\xba\xe2mE\xd4a\x82\x7fW$A\xc7\xdb\x8c\xadw\ |
---|
| 4216 | \x01\xc0\x10\xa2\x0e\x00\x86\x10u\x000\x84\xa8\x03\x80!D\x1d\x00\x0c!\xea\ |
---|
| 4217 | \x00`\x08Q\x07\x00C\x88:\x00\x18B\xd4\x01\xc0\x10\xa2\x0e\x00\x86\x10u\x000\ |
---|
| 4218 | \x84\xa8\x03\x80!D\x1d\x00\x0c!\xea\x00`\x08Q\x07\x00C\x88:\x00\x18B\xd4\x01\ |
---|
| 4219 | \xc0\x10\xa2\x0e\x00\x86\x10u\x000\x84\xa8\x03\x80!D\x1d\x00\x0c!\xea\x00`\ |
---|
| 4220 | \x08Q\x07\x00C\x88:\x00\x18B\xd4\x01\xc0\x10\xa2\x0e\x00\x86\x10u\x000\x84\ |
---|
| 4221 | \xa8\x03\x80!D\x1d\x00\x0c!\xea\x00`\x08Q\x07\x00C\x88:\x00\x18B\xd4\x01\xc0\ |
---|
| 4222 | \x10\xa2\x0e\x00\x86\x10u\x000\x84\xa8\x03\x80!D\x1d\x00\x0c!\xea\x00`\x08Q\ |
---|
| 4223 | \x07\x00C\x88:\x00\x18B\xd4\x01\xc0\x10\xa2\x0e\x00\x86\x10u\x000\x84\xa8\ |
---|
| 4224 | \x03\x80!D\x1d\x00\x0c!\xea\x00`\x08Q\x07\x00C\x88:\x00\x18B\xd4\x01\xc0\x10\ |
---|
| 4225 | \xa2\x0e\x00\x86\x10u\x000\x84\xa8\x03\x80!D\x1d\x00\x0c!\xea\x00`\x08Q\x07\ |
---|
| 4226 | \x00C\x88:\x00\x18B\xd4\x01\xc0\x10\xa2\x0e\x00\x86\x10u\x000\x84\xa8\x03\ |
---|
| 4227 | \x80!D\x1d\x00\x0c!\xea\x00`\x08Q\x07\x00C\x88:\x00\x18B\xd4\x01\xc0\x10\xa2\ |
---|
| 4228 | \x0e\x00\x86\x10u\x000\x84\xa8\x03\x80!D\x1d\x00\x0c!\xea\x00`\x08Q\x07\x00C\ |
---|
| 4229 | \x88:\x00\x18B\xd4\x01\xc0\x10\xa2\x0e\x00\x86\x10u\x000\x84\xa8\x03\x80!D\ |
---|
| 4230 | \x1d\x00\x0c!\xea\x00`\x08Q\x07\x00C\x88:\x00\x18B\xd4\x01\xc0\x10\xa2\x0e\ |
---|
| 4231 | \x00\x86\x10u\x000\x84\xa8\x03\x80!D\x1d\x00\x0c!\xea\x00`\x08Q\x07\x00C\x88\ |
---|
| 4232 | :\x00\x18B\xd4\x01\xc0\x10\xa2\x0e\x00\x86\x10u\x000\x84\xa8\x03\x80!D\x1d\ |
---|
| 4233 | \x00\x0c!\xea\x00`\x08Q\x07\x00C\x88:\x00\x18B\xd4\x01\xc0\x10\xa2\x0e\x00\ |
---|
| 4234 | \x86\x10u\x000\x84\xa8\x03\x80!D\x1d\x00\x0c!\xea\x00`\x08Q\x07\x00C\x88:\ |
---|
| 4235 | \x00\x18B\xd4\x01\xc0\x10\xa2\x0e\x00\x86\x10u\x000\x84\xa8\x03\x80!D\x1d\ |
---|
| 4236 | \x00\x0c!\xea\x00`\x08Q\x07\x00C\x88:\x00\x18B\xd4\x01\xc0\x10\xa2\x0e\x00\ |
---|
| 4237 | \x86\x10u\x000\x84\xa8\x03\x80!D\x1d\x00\x0c!\xea\x00`\x08Q\x07\x00C\x88:\ |
---|
| 4238 | \x00\x18B\xd4\x01\xc0\x10\xa2\x0e\x00\x86\x10u\x000\x84\xa8\x03\x80!D\x1d\ |
---|
| 4239 | \x00\x0c!\xea\x00`\x08Q\x07\x00C\x88:\x00\x18B\xd4\x01\xc0\x10\xa2\x0e\x00\ |
---|
| 4240 | \x86\x10u\x000\x84\xa8\x03\x80!D\x1d\x00\x0c!\xea\x00`\x08Q\x07\x00C\x88:\ |
---|
| 4241 | \x00\x18B\xd4\x01\xc0\x10\xa2\x0e\x00\x86\x10u\x000\x84\xa8\x03\x80!D\x1d\ |
---|
| 4242 | \x00\x0c!\xea\x00`\x08Q\x07\x00C\x88:\x00\x18B\xd4\x01\xc0\x10\xa2\x0e\x00\ |
---|
| 4243 | \x86\x10u\x000\x84\xa8\x03\x80!D\x1d\x00\x0c!\xea\x00`\x08Q\x07\x00C\x88:\ |
---|
| 4244 | \x00\x18B\xd4\x01\xc0\x10\xa2\x0e\x00\x86\x10u\x000\x84\xa8\x03\x80!D\x1d\ |
---|
| 4245 | \x00\x0c!\xea\x00`\x08Q\x07\x00C\x88:\x00\x18B\xd4\x01\xc0\x10\xa2\x0e\x00\ |
---|
| 4246 | \x86\x10u\x000\x84\xa8\x03\x80!D\x1d\x00\x0c\xf9?\xd2xo\xfe\xadF\xd4\xef\x00\ |
---|
| 4247 | \x00\x00\x00IEND\xaeB`\x82' |
---|
| 4248 | |
---|
| 4249 | |
---|
| 4250 | |
---|
| 4251 | def getSageImage(): |
---|
| 4252 | stream = cStringIO.StringIO(getSageData()) |
---|
| 4253 | return ImageFromStream(stream) |
---|
| 4254 | |
---|
| 4255 | sageImg = getSageImage()#.Rescale(300,254) |
---|
| 4256 | def getSageBitmap(): |
---|
| 4257 | return BitmapFromImage(sageImg)#getSageImage()) |
---|
| 4258 | |
---|
| 4259 | |
---|
| 4260 | |
---|
| 4261 | #---------------------------------------------------------------------- |
---|
| 4262 | def getSageStartUpData(): |
---|
| 4263 | return \ |
---|
| 4264 | '\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x00\x82\x00\x00\x002\x08\x06\ |
---|
| 4265 | \x00\x00\x00\x90\xc9\x03\x88\x00\x00\x00\x04sBIT\x08\x08\x08\x08|\x08d\x88\ |
---|
| 4266 | \x00\x00\t&IDATx\x9c\xed\x9c_l\xdb\xc6\x1d\xc7\xbf\x92%eV\x9c\x00.\xed\rv\ |
---|
| 4267 | \xe4\xd8\xc8*\xd9\xe8\x1cL\x9b\x03t\xb2\x83!\x813\xa4\xe8\xacb\x0fE\xeb\x05\ |
---|
| 4268 | \xc5\xe0\xbe\xac\xe8\xd6>9\x18\x86"o\xc1\x02\x0c\x8d\x9f\x83\x0e\xc1\xea\xbe\ |
---|
| 4269 | \xac\x80\xd1=d\xf20\x14M\x16\x03K\xa6\x16\xb5\r\xadq1[n\x13\xff\x91ld"\xedX\ |
---|
| 4270 | \x94\xf8_\xe2\x1e\x18\xd2\xa4I\xd92-\xff\x91\xc3\xcf\x8bt\xd4\xf1\xeeD~y\xf7\ |
---|
| 4271 | \xfb\xfd\xeex.\x97\xbb\x06\xa5\xb8\xff\xdf\x7f\xc9\xeaw\x86gJ\xe6s8xHE\t\x00\ |
---|
| 4272 | J"x\x89\x87(\x89\xb8\xf4\xd37\\\xa5\xf2\xbb\xac\x840\xf9\xed\xb8\x0c\x00\ |
---|
| 4273 | \xac\xc0\x02PD\xa0\x16,\x15\xa4\xca\xb7\xda\xa1\xa2\xc8\xb2\xf6\xfcj"\xe0D\ |
---|
| 4274 | \x0e4G\x83\x17y\xfc\xee\x17\xbf7\t\xc2$\x84\xc9o\xc7\xe5\x8d\x02\xd0\xab\xca\ |
---|
| 4275 | \xa1\xba\xe0DN\xfb\xae\n\x81fi\\\xfd\xe5\x1f\x0cb\xd0\x84\xa0\x1f\x06\x00 \ |
---|
| 4276 | \xcbf\x91\xe3r\x0659T/\xbc\xc8\x03\x00\x04I@\x96\xc9\x82\x17y\xe4\xf9<n\xfe\ |
---|
| 4277 | \xe6\xcf.\x00\xf0l<\x81\xe1\x19<a\x9e\x80fi\xd0\x1c\r\x9a\xa5\xb5B\xd4O\x87\ |
---|
| 4278 | \xea\xe2\x88\xf7\x88!\xcd\x8b<\x18\x9e\x81\xc0\n\xda1\x97\xcb]\x83\x7fL\xfe]\ |
---|
| 4279 | \x06\x94\xf1\x9f\x139\xd0,\x8d\xa5\xd5%M9bA\xd4l\x04\xc08\x069\x1cL\\\xae\ |
---|
| 4280 | \xf5\x9e\xdf\xe3\xf6\xc0[\xe3\xd5\xd2\xac\xc8\x82\xcbs\xe0\xf3<\xb8<\x87[\ |
---|
| 4281 | \x7f\x8c\xb9<\x00\xb4\xb1\x9f\x97x,\xad.\x81fid\x19ehP\x05\xe0\xdc\xfc\xeaB\ |
---|
| 4282 | \x7f\xbf\xa4\xa2\x04\xa9(\xc1\xe3V\x06\x00I\x90 \xf2"\xb8<\x07.\xa7\xd8\x10\ |
---|
| 4283 | \xae\x8f\xef},\x03\xebF\x05I\x93 \xb3\xa4#\x82C\x86\xbe\x87P{\x83\xfcj\x1e\ |
---|
| 4284 | \xb9\xd5\x1c\x00\xc0\xa3\xb7*I\x9a\xd4l\x02\xb1\xe0x\x08\x87\tY\x96\xe1r\xb9\ |
---|
| 4285 | \xb4\x87\xba \x16 \n\xca=\xcef\xb2\xf0\xe8\xbd\x01A\x124\x11\xe8Or8\x1c\xe8\ |
---|
| 4286 | \xef\xa7(\x88(\x88\x05d3Y\x00\x80[\xfdA\xef\x19HE\xc9\x11\xc13\x04Gs\x8a\xfb\ |
---|
| 4287 | X\t\xf7\xd0\xef\xf3\xe3\x04q\xc2t<M\xa5\xc1\x08Nx\xfa "\t\xeb\x9e\xa0G\x1fh\ |
---|
| 4288 | \xb0C$\x14\xc1\x85\xd3\x17\x10 \x02%\xf3\xb0\x02\x8b\x99\xa5\x19L\xa7\xa7\ |
---|
| 4289 | \xf1\xc5\xec\x17e\x0b\xe3\x83_\x7f\xa0}O.\'1\x14\x1b\xb2\xd5\xc6jf/\xae\x81(\ |
---|
| 4290 | \x88\xe6\x80\x12P\x9e\x97\xe0\xf7\xf91\x18\x1d\xdcT\x00*\xb5\xbeZ\x84\xdb\ |
---|
| 4291 | \xc2\x08\xb7\x85\x91ZIavyv\xfb\xadu\xd8U,\x85P\x0eo_|\xdb \x02\xf5\xa9OQ)\ |
---|
| 4292 | \xedX\xa89\x84\x16\xa2\x05\xb5\xbe\xda\x9d\xb5\xd2a\xd7\xb1%\x84\xce\x93\x9d\ |
---|
| 4293 | \x085\x85\xb4t<\x19\xc7\xc8\xbfG\xcc]\xfe\x84\xf2\xd1\xda\xd8\x8aS\xdf=\x85\ |
---|
| 4294 | \xb3\x1dgm7\xb4R\x04\x9b\x82\xe8h\xee\x00q\x8c\x00q\x8c\xd0\x8e3<\x83\x14\ |
---|
| 4295 | \x95\xc2W\x0b_a>3_vy\x1bm#2Kb5\xbf\xaa\xa5;Ov\xe2\x85\x13/\xa0\xa5\xa1E;\xb6\ |
---|
| 4296 | H."\x93\xcd\xe0\xee\xd7ww\xf8o*\x87\xeb\xfd\xbf\xbd/\x03\xeb\xaec\x96\xc9n9\ |
---|
| 4297 | \x86\x0f\x9c\x1b@$\x14\x01\xa0\xf4\x04\xef\xfd\xe5\xbd\x1d\x1b\x84\x83\xd1A\ |
---|
| 4298 | \x83\xb8\xecp=v\xddr\xd8\xa9?Z\x8f\xfe\x9e~\x84\xdb\xc2e\x95\x13O\xc61<6\\V\ |
---|
| 4299 | \xde`S\x10\x97\xa3\x97\xb5\xf4\xe8\xc4(b\x131\x04\x9b\x82x\xf3\xfc\x9b \xea\ |
---|
| 4300 | \x88\x92\xe7\xbe\xf5\xa7\xb7\x0c\xe9\xdd\xbc\x06zx\x86\xc7\xda\xff\xd6\xb0\ |
---|
| 4301 | \xf6x\r\xd9L\x164E\xdb\xeb\x11\xf4O\x12ES\x07\xde+h8\xdeP\xb6\x08\x00\xc5\ |
---|
| 4302 | \x00fx\x06#\xf1\x11[\xf5EB\x11\x0c\x9c\x1b\xb0u\xee~a\xdbFP\t\x10\x01\xb46\ |
---|
| 4303 | \xb6n\xab;\xddO\x12s\tL\xa7\xa7\x91ZI\x81\xcc\x92\x00\x80\x13\xc4\t\\\xfc\ |
---|
| 4304 | \xe1E\xc3\xd3\xd8\xdd\xdemK\x08\xe1\xb6\xb0\xc9vZ\xa4\x16\x91\\J\x828F \xdc\ |
---|
| 4305 | \x16>\x906\x93-!P4\x054\xad\xa7_\xfe\xd1\xcb\xf8h\xec\xa3\x1d\xf5\x0cVnQ\xa5\ |
---|
| 4306 | \\\'A\x120:1\x8a;\x0f\xeeX\xb6q5\xbf\x8a\xa9\x85)C\xd7\\\xeb\xabE\xb0)\xb8m\ |
---|
| 4307 | \x0fG/\x02\xab:7\xeb\xfew\xf3\x1al\x85{\xeb,ff\x96f\x0c\xe9p[\x18W^\xbd\x82\ |
---|
| 4308 | \xf3?8\x0f\xbf\xcf_\x91\x86U\x92\xf9\xcc<b\x13\xb1-\x85:\xf9p\xd2\x90\x0e<\ |
---|
| 4309 | \xb7\xb5kl\x05+\xb0\xb8\x1e\xbb^V\x9d\x07\x05[=B<\x19Gw{\xb7A\xd9D\x1d\x81\ |
---|
| 4310 | \xfe\x9e~\xf4\xf7\xf4#1\x97@b.\x81x2^\xb1\x86\xee\x05\xa9\x95\x94!]\xf7\x9d:\ |
---|
| 4311 | [\xe5\xdc\xfc\xe7\xcd\x92=\xc9\'\x9f\x7f\x02\x9f\xc7g\xab\xdc\xdd\xc4\xb6\ |
---|
| 4312 | \x8dp\xe3\xd3\x1bx\xad\xfb5\xcd{\xd0\xa3\x06\x8f^\xef~\x1d\x89\xb9\x04\xc6\ |
---|
| 4313 | \x1f\x8ecjajG\r\xad\x16\xee<\xb8\xb3\xe9\x7f=\xa8\xb6\x94m!0\x02\x83\xe1\xb1\ |
---|
| 4314 | a\xdc\x9f\xb9\x8fW\xce\xbcb9\xee\xd5\xfaj\x11\tE\x10\tE@\xe5(|x\xf7\xc3\x03\ |
---|
| 4315 | \x11U,\x15K\xa8\xc4\xb0\xa6.\xfc\xad6v\xec5\xcc.\xcfb(6\x84\xd6\xc6V\xbc\xf8\ |
---|
| 4316 | \xfc\x8b\xe8n\xef\xb6\xb4\x8a\x89:\x02\x97\xa3\x971<6\xbcoCF\xb4+\x8aH{dS\ |
---|
| 4317 | \xdf\xfeYe\xc7BP\x99\xcf\xccc>3\x8f\x91\xf8\x08:Ov\xe2\xcc\xa93\x96\xc3\xc6\ |
---|
| 4318 | \xc0\xb9\x01\x904\xb9\xa7=C\xfd\xd1z\xbc\xf3\xd2;\x96\xf3"\xc9\xe5\xa4\xf6\ |
---|
| 4319 | \xdd\xef\xf3\x975wr\x18\xa9\x98\x10\xf4L-Laja\n\xb7\xbe\xbc\x85\xb3\x1dg\xd1\ |
---|
| 4320 | \xd7\xd5g\xf8\xbd\xbf\xbb\x1fW\xffzu7\xaa6\xe1\xf7\xf9M"H\xcc%p\xfb\xc1m\x93\ |
---|
| 4321 | \x187F\t\x9f%vE\x08*\xab\xf9U\xc4&b i\xd2\x10i\xdb\xcb\xa7\xae\xf7t\xaf\xc9\ |
---|
| 4322 | \xb7\x8fM\xc4\xf6\xac\xfej\xc1V\x1ca\xbb\xc4\x93\xf1}3\xa2"\xed\xeb\xc3\x13+\ |
---|
| 4323 | \xb0\x8e\x08J\xb0\'B\x00\x80Ejq\xaf\xaa2\xa07\x0c\xab%\xb8\xb3\x1f\xd8\x12B\ |
---|
| 4324 | \xe7\xc9\xcem\xe5\xf7\xfb\xfch!\xd6\xa7a\xa9\x1cU\xd6y\xfa|\x95p\xed\x88:\ |
---|
| 4325 | \xc2\xd2\x80U\xcb\xefi\xef\xd9q\x1d\x95Fo\xcc\xea]\xddJcK\x08\xef\xbe\xf4.\ |
---|
| 4326 | \xae]\xba\x86hW\x14\xf5G\xeb7\xcd[\x7f\xb4\x1e\x83\xd1A\x83K\x19\x9f)\xcf}\\\ |
---|
| 4327 | $\xd7{\x91\x00\x11@\xb4+\xba\xed\xb6n\x14\xdd\x85\xd3\x17L\xa2\x8a\x84"\xb8\ |
---|
| 4328 | \xf2\xea\x15\x93Hv\xf3\xc2\x97\x0bE\xaf\xb7\x9f\xa8#vmV\xd3\xb6\xb1H\xd4\x11\ |
---|
| 4329 | \xe8\xeb\xeaC_W\x1fRT\n3K3\xc8d3Z\x98\xb6\xa3\xb9\x03\x01"`\x9a\xfeMQ\xa9\ |
---|
| 4330 | \xb2\xc7\xe9\xc4\\\xc2p~_W\x1f\xc2ma$\xe6\x12\xa6\xbc\xa1\xe6\x10&\x1fN\x9a\ |
---|
| 4331 | \x16{|\xf6\x9f\xcf\xd0\xdf\xd3\xaf\xa5\x03D\x00\xd7.]\xd3\x86\xaa\xcdVP\xa9\ |
---|
| 4332 | \xc2\xa0h\n\xf7\xa6\xef\x19\x16\x9c\xec\x15\xe3\x0f\xc7\r\x02\x8d\x84"\x085\ |
---|
| 4333 | \x87\x90x\x940\xd9]\xa5\xaeA9T\xc4k\x08\x10\x81\xb2<\x81\xe4r\x127>\xbdQv\ |
---|
| 4334 | \xb9\xf1d\xdc\xb40v\xb3\xba\x92KI\xd3\xb1\xbb_\xdfEkc\xab\xe1b\xd6\xfaj-#\ |
---|
| 4335 | \xa1\xa3\x13\xa3&\x0fG\x7f\xde~\x18\x9aS\x0bSHQ)\xc3\x7f&\xea\x08\xf4\x9e\ |
---|
| 4336 | \xee\xb5\xccou\r\xca\xc1\x96\x10\x86\xc7\x86\x11n\x0b\xa3\xa5\xa1\xa5\xac(]\ |
---|
| 4337 | \x8aJ\xe1\xf6\x83\xdb\xb6"\x8aC\xb1\xa1\x92s\x1a\xe52<6\x0c\x8a\xa6\xd0{\xba\ |
---|
| 4338 | \xd7\xf2\xe9\x8f\'\xe3\xb8\xf5\xe5-\xed\x89oon7\xd5\x97\xe3r\xb6\xeb\xdf)C\ |
---|
| 4339 | \xb1!\xf4u\xf5\x95\x8c\xdaV\x02[K\xd5\xf4\xa8k\xf6\x02\xcf\x05L\xb3u\x8f2\ |
---|
| 4340 | \x8f\x90\xa6\xd2\x15\xebR\x83MA4\x1ck@\xc3\xb1\x06\xed\x18I\x93 i\x12\x82$\ |
---|
| 4341 | \x945\xa1\x13l\n\x1a\xd2\xa5"\x9c\xad\x8d\xad\xda,\xe1\xc6u\x88\xfbI%\xae\ |
---|
| 4342 | \x81\xd5R\xb5\x1d\x0ba+\x9cW\xe7\x0e\x1eVBp\x03\xf6_n)\x07G\x04\x07\x8c\xa7\ |
---|
| 4343 | \xb7\xa3 \x14\x0c\x87\xdd\xbb)\x02\x87\xea@dE\xe3K\xb0\xce\xd68\x87\x1f\x192\ |
---|
| 4344 | D~\xfdux\x8eV\xb6E\xf0X\xdd|\xf5]z\x87C\x86\x0c\x14\xa5"\x00h{#\x88\x82\xa8\ |
---|
| 4345 | \xbc\xfb\xb8\xb1\'P\xf7F\x80\x0c\xc0\xd1\xc2\xa1B\x86\x0cI\x94 \xb2\xa2\xb2\ |
---|
| 4346 | \x7f\x12\xcdAdE\x14\xc5"<\xfa-r\xb4\x13\x9e\x1ax.\xd9\xe5\x88\xe1\x90 \xcb2\ |
---|
| 4347 | \x8aRQ\xd9;)\xc7!\x9b\xc9B\x14\x14A\x00OwU\xfb\xd5\xd0\x1b\x06\xd3\xde\xe3U\ |
---|
| 4348 | \xe2Ln\x8f\x1b.8b\xa8jd\xa5\'(JE\xb09\x16\xcc\x1a\x83\xb5\xc7kHO\xa7\x91#\ |
---|
| 4349 | \x95 \xd9\xf27\x8f\x95]\xd5\x98\'\x8c6fx}^\xd4xk\xe0\xf6\xb8\xe1=\xe2\x85\ |
---|
| 4350 | \xc7\xeb\x81\xdb\xa3\xd8\x94\x8e(\xaa\x04Y\xfdP\x04 \x89\x92a\xf3,\xbd\x08T\ |
---|
| 4351 | \xb4\x9dW/\xfe\xf6grAT|\xcb\x1ao\x8d"\x08_\x8dA\x18\x0e\xd5\x83j\x14\x16\xc4\ |
---|
| 4352 | \x02\xb8\x1c\x07.\xcfa%\xbd\x02\x9a\xa2\r"X\xfe\xe6\xb1q\xe7\xd5\x82X\xc0Jz\ |
---|
| 4353 | \x05\xc7\x1b\x8fc%\xbd\x02\x008\xdex|O\x1b\xefPy\xd4\xcd\xb28\x9a\xc3Zf\rE\ |
---|
| 4354 | \xb1h\x99\xcf\xb4)\xf7\x8f\x7f\x1e\x96U\xdf\xd2\xa1z\xd1\xdcCVq\x0f7\n@\xed\ |
---|
| 4355 | \tT,\xb7\xe9\x0f\xfe\xe4\xfbr\xa9\x02\x1c\xaa\x9f\x8d"\x00J\x08A\xa5\xe9\xf9\ |
---|
| 4356 | \xef9\x13\x05\x87\x08+\x01\xa8\xfc\x1f\x05\x81\x11\xc3\xb6\xc2\xdf\x94\x00\ |
---|
| 4357 | \x00\x00\x00IEND\xaeB`\x82' |
---|
| 4358 | |
---|
| 4359 | def getSageStartUpBitmap(): |
---|
| 4360 | return BitmapFromImage(getSageStartUpImage()) |
---|
| 4361 | |
---|
| 4362 | def getSageStartUpImage(): |
---|
| 4363 | stream = cStringIO.StringIO(getSageStartUpData()) |
---|
| 4364 | return ImageFromStream(stream) |
---|
| 4365 | |
---|
| 4366 | #---------------------------------------------------------------------- |
---|
| 4367 | def getSageStartDownData(): |
---|
| 4368 | return \ |
---|
| 4369 | '\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x00\x82\x00\x00\x002\x08\x06\ |
---|
| 4370 | \x00\x00\x00\x90\xc9\x03\x88\x00\x00\x00\x04sBIT\x08\x08\x08\x08|\x08d\x88\ |
---|
| 4371 | \x00\x00\x06\nIDATx\x9c\xed\x9d1h\xdbX\x18\xc7\xffN\x1b\x1f\x166=xYb,\xf0\ |
---|
| 4372 | \xf4\xbc\\\xb1\xc0\x934\x05\x0c\xbd\xc5\xde\x8a\x03]\x128\xae%]\xbd\x95\x0c\ |
---|
| 4373 | \x07\x85l\x9eC\xaf\x14|\xcb\r\x86\xa3\x83\xbd\xf4\xa8!\x93\x0cG\x0c\n\xe9bA\ |
---|
| 4374 | \xa9\x0f\x99\x18\x8e\xbc.\x0e1u9\xee\x86D\x8ae\xc9\x8e"\xcbv\x1a\xbf\x1f\x84\ |
---|
| 4375 | D\xb2\xa4\xf7\xf4\xf4\x7f\xdf\xf7\xbd\xef=+\xa1\xd0\xca=\x8c\xe3\xe7\xfd\x9f\ |
---|
| 4376 | \xfe\x1b\xfb!\xe7\x9b\xe3\xf5\xce\x9b\xd0\xb8\xcfBnB\xe0\x02\xb8\xdb\xb8\tbe\ |
---|
| 4377 | t\x07\x17\xc1\xdd\xc7\xed\x19[\x16\x81\x0b`91\xad\x83\xc3"p\x96\x93\x15\x80[\ |
---|
| 4378 | \x83e\xc6|\xf6\xdc"p\x00\x00\xa1\xa7\xaf\x9erk\xc0\xe1\x16\x81s\x01\x17\x02\ |
---|
| 4379 | \x07\x00\x17\x02\xe7\x92\xfbA]H\x08\x0bH\xac%\x1c\xfb;\xa7\x1d\x9c\x0f\xce\ |
---|
| 4380 | \x83*\x863#\xa6\x16\x82B\x15d\x1ff\x91 N\x11\x98\xf4\x07}\xe8\':Z\xdd\x16\ |
---|
| 4381 | \x1a\xad\x86ga\xbcz\xfa\xca\xfa[\xef\xea(UK\xd3V\xf7\x9bc^m\xe0[\x08BX@1_\ |
---|
| 4382 | \x9c(\x00\x93H8\x82t2\x8dt2\r\x83\x19\xd0Ot\xbf\xc5rf\x84o!\xec\xfc\xb8c\x13\ |
---|
| 4383 | \x81\xd9\xeb\rfX\xfbh\x9cB$""\xe1\xc8t\xb5\xe4\xcc\x1c_B\x90\x92\x12\xe8:\ |
---|
| 4384 | \xb5\xb6\x1bz\x03\x15\xb5\xe24\xf9\xcd\x8b_"\x11A\xe3\x14\nU|W4(h\x9c"\xb5\ |
---|
| 4385 | \x9e\x02\x89\x11\x90\x18\xb1\xf6\xf7\xbf\xf4a0\x03Z[\xb3\x89\xf9:Fc#\xd6c`=f\ |
---|
| 4386 | mKI\xc9\xea\x10&\x063\xc0z\x0c\xf5\xe3\xfa\x94w\x13\x1c\xbe\x12J\xdb\x1b\xdb\ |
---|
| 4387 | \x90\xa9\x0c\xe0\xc2\x12\xbc\xf8\xfd\xc5\xd4\x01a1_\xb4\x89\xcb\x0f\xa5Z\xc9\ |
---|
| 4388 | \xd5\xed\x90\x18\xc1\xa6\xbc\x89t2\xed\xe9:\r\xbd\x81\xf2A\xd9\xd3\xb14NQ\ |
---|
| 4389 | \xcc\x15\xad\xedZ\xb3\x86j\xb3\n\x1a\xa7\xd8\xde\xd8\x06\x89\x92\xb1\xe7>\ |
---|
| 4390 | \xfb\xf5\x99m{\x96mp\x1d\xbe,\xc2pOb=v\xebG\x05$F<\x8b\x00\x00d*\xe3|p\x8e\ |
---|
| 4391 | \x8aZ\xf1U\x9eB\x15lml\xf9:wQL=jH\x90\x04D"\xde\xc8\x9c.\x92\xa3\xf6\x11Z\ |
---|
| 4392 | \xdd\x96e\x9e\x81\x0b\xd7\x95}\x98\xb5\xf5F\x85*\xbe\x84 %%G\xecd\x06\xc8$F \ |
---|
| 4393 | %\xa5[\x193\xf9\x12\x02\xeb1`\xfdj;\x9f\xc9\xa3|P\x9e\xca2\xb8\r\x8b\x82\x1a\ |
---|
| 4394 | :\xf5\xbf\xf4Qk\xd6P?\xae\xbb\xd6\x91\xf5\x18\xb4\xb6f3\xcd\x91p\x044Nolf\ |
---|
| 4395 | \x87E\xe0V\xe6$\xf3?\xcb6\xb8\x0e_\x99\xc5\xd1\xc6I\'\xd3\xd8}\xbc\x8b\xec\ |
---|
| 4396 | \xc3,\x84\xb0\x10H\xc5\x82\xc4`\x06\xaa\xcd\xea\xb5B\xd5\xda\x9am{8\xc0\xbb\ |
---|
| 4397 | \t\xfdA\x1f\xa5Z\xc9S\x99\xb7\x05_\x16A\xd5U\xc8)\xd9\xa6l\x12%(\xc8\x05\x14\ |
---|
| 4398 | \xe4\x02\x8e\xdaG\xd0\xda\x1aT]\r\xac\xa2\xf3`\xd4\xbd\xf9\x15u\xf9\xa0<\xd6\ |
---|
| 4399 | \x92T\xd4\n"\xdf\xdd\x11\xd7\x00\x00\xfb\xef\xf6QP\n\xd6\xe8a\x183yTP\n\xd0\ |
---|
| 4400 | \xda\x9a\xf5\xb3\x0c\xd4?\xd4\'\xde\xebm\x8d\xa5|\x0b\xe1|p\x8e\xf2A\x19\xaa\ |
---|
| 4401 | \xae"\x9f\xc9\xbb\xfa\xbdH8\x02\x99\xca\x90\xa9\x0cv\xc6&\xf6\x94y2.\x97\x10\ |
---|
| 4402 | \x84[\xeb\x7f\xe9O}\x8dE0\xf5\xa8A?\xd1Q:)A$"\xe4\x94\x0c\x85*\xaeQ1\x89\x12\ |
---|
| 4403 | \x14sE\xfcv\xf0\xdb\xc2\\F>\x93\x87\x9c\x92\'\x8e\xed\x97\x95\xc0f\x1f\rf\ |
---|
| 4404 | \xc0P\rT\xd4\n\xa4\xa4\x04))\xb9\xba\x8d\xad\x8d-\x9c\x9e\x9d\xce\xd52\x90\ |
---|
| 4405 | \x18\xc1\xf3G\xcf]\xe7E\xf4\xeeU=\x84\xb0\xe0i\xee\xe4.\x12\x98\x10\x861c\ |
---|
| 4406 | \x82j\xb3\n\x85*\xc8er\xb6\xcf7\xe5M\xbc\xfc\xe3\xe5,\x8av \x84\x05\x87\x08\ |
---|
| 4407 | \x8e\xdaGx\xff\xe1\xbdC\x8c\xa3Y\xc2eb&B0a=\x86j\xb3\n\xd6c\xb6L\xdb<{\xdd\ |
---|
| 4408 | \xe8\x14\xb9\x99\x02\xe6\xd8\x99\xcb\n%UW\xd1\x1f,&\x88\x92SW\xee\xa9?\xe8s\ |
---|
| 4409 | \x11\x8canK\xd5\x165l\x1a\x0e\x0c\xbf\x95\xe4\xce"\xf0%\x04))\xdd\xe8x!,\xd8\ |
---|
| 4410 | \xb2t\xec\x8cM8\xfa\x8a\xe1\xe3\x82\x18\xda\x91(\x19;\x15.\x84\x85[1M>\xcap0\ |
---|
| 4411 | ;<\xd4\r\x1a_B\xd8y\xb4\x83\xbd\'{\xc8g\xf2\xd7V\x8e\xc4\x08\x8a\xf9\xa2mH\ |
---|
| 4412 | \xd9h5<\x95\xd39\xedX\x7f\'H\x02\xf9L\xfe\xc6u\x1d\x15\x9d[\x1a\\\xa1\nv\x1f\ |
---|
| 4413 | \xef:F9\xb3lx\xaf\x0c\xafm Q\x82\xed\x8d\xed\x99\x94\xe3;X$Q\x82\\&\x87\\&\ |
---|
| 4414 | \x87\x0e\xeb\xa0\xd5m\x81\xf5\x98\xe5\x02R\xeb)\x88DtL\xffvX\xc7\xb3\x9f\xd6\ |
---|
| 4415 | \xda\x9a\xed\xfc\\&\x07))\xb9f\xeeh\x9cBkk\x8e\xc5\x1e\xf5\xe3:\nr\xc1\xdaN\ |
---|
| 4416 | \x90\x04\xf6\x9e\xecY\xf5\x9c\xb4\x82\xca\x14\x06\xeb1\xa8\xbaj{(\xf3Bkk6\ |
---|
| 4417 | \x81\xcaT\xb6\xeeu4y5\xae\r\xbc\x10\xc8\xa8!A\x12\x9eF\x02zW\xc7\xfe\xbb}\ |
---|
| 4418 | \xcf\xd7Uu\xd5\x11\xf5O*\xcb-7Q?\xae_$\xbb\x86\x1a3\x12\x8e\xb8fBk\xcd\x9ac\ |
---|
| 4419 | \x843|\xde"\x02M\xad\xad\xa1\xc3:\xb6{&Q\x82\xec\x0fY\xd7\xe3\xfd\xe6g\xeee\ |
---|
| 4420 | \xf2\x99_nz\xd2\xe7\xdeg\x84\x10\xc2\xea\xfdUO\xbe\xbb\xc3:x\xfb\xd7[T\x1a\ |
---|
| 4421 | \x15|\xfd\xf7\xeb\x8d\xca:\xfcx\x88\x07\xc2\x03O3\x81zW\xb7\xf9T\x13\xad\xad\ |
---|
| 4422 | !\x84\x10\xc45\x11\xab\xf7V\x1d\x9f7\xf4\x06\xf6\xff\xdc\xb7\x96\xa9\xad\xc5\ |
---|
| 4423 | \xd6\x1c\xe5i\x7fk\xf8\xf4\xcf\'\xc7\xb9$f\x8f;\xc6\xd5a\x1a\x0e?\x1eb\xf5\ |
---|
| 4424 | \xfe*\xd6\xbf_w\xad\xff0~\xcb\x9f\xfa\xbb\x8f\xe6\x9a=\x91\x88\x0eQ\x18\xcc\ |
---|
| 4425 | \xb0-\x00\x99\x16\x1a\xa7X\x8b\xae9VH\x9d\x9e\x9dZk\x0e\xbd\\c\x98q=H$\xa25K\ |
---|
| 4426 | 8\xba\x0eq\x91\x04\xd1\x06n\xf0/\xc1r\x00\xf0\xaf\xbcq.\xe1B\xe0\x00\xe0B\ |
---|
| 4427 | \xe0\\\xc2\x85\xc0\x01\xc0\x85\xc0\xb9\x84\x0b\x81\x03\x00X\x99\xf4ZV\xcer\ |
---|
| 4428 | \xf0z\xe7M\x88[\x04\x0e\x80K\xd7\xc0\xad\xc2\xf2\xc2\xdf\xbc\xca\xb1\xe1x;;\ |
---|
| 4429 | \x7f\x0b\xebr0\xea\x05\x1c\x16\x81\xbb\x89\xbb\x8f\xdb3v\xfd\x7f\r&\xdc:\xdc\ |
---|
| 4430 | -&u\xf2\xff\x01\x07\x85\x9d\x95\xbbRg\x1a\x00\x00\x00\x00IEND\xaeB`\x82' |
---|
| 4431 | |
---|
| 4432 | def getSageStartDownBitmap(): |
---|
| 4433 | return BitmapFromImage(getSageStartDownImage()) |
---|
| 4434 | |
---|
| 4435 | def getSageStartDownImage(): |
---|
| 4436 | stream = cStringIO.StringIO(getSageStartDownData()) |
---|
| 4437 | return ImageFromStream(stream) |
---|
| 4438 | |
---|
| 4439 | #---------------------------------------------------------------------- |
---|
| 4440 | def getSageStopDownData(): |
---|
| 4441 | return \ |
---|
| 4442 | '\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x00\x82\x00\x00\x002\x08\x06\ |
---|
| 4443 | \x00\x00\x00\x90\xc9\x03\x88\x00\x00\x00\x04sBIT\x08\x08\x08\x08|\x08d\x88\ |
---|
| 4444 | \x00\x00\x06}IDATx\x9c\xed\x9dOh\xdbV\x1c\xc7\xbfN[\x0f\x9b\x84\x0c^`\x8d\ |
---|
| 4445 | \x91\xc1\xf4 _\x16,p/\xce\xc9`h/\xd2m$l\x97\x18\xc6\n\xee\xd5\xb7\xd0\xc3\ |
---|
| 4446 | \x0e%\xb7\xd2\xddL)\x05\xe7\xb2\x81a\xf4\x90\\Z0d=H0\x1a\xb0i;\xf0\x83\x81A"\ |
---|
| 4447 | \xbe\xf8\xf5\xe2\x10\xd3\x94\xb1\x1d\x1ci\xd6\x1f\xdbrb\xc9i\xf2>\x97\xe4\ |
---|
| 4448 | \xe9\xcf{O\xd2\xf7\xfd~\xbf\xf7{\x8a\x12\x89,\xdc\xc0(~\xaa\xfc\xf8\xef\xc8\ |
---|
| 4449 | \x9d\x9c/\x8e\xe7\xa5\x17\x91Q\xfb"^B\xe0\x02\xb8\xdax\tb\xc1\xb9\x81\x8b\ |
---|
| 4450 | \xe0\xea\xe3\xf5\x8c-\x8b\xc0\x05p=1\xad\x83\xcb"p\xae\'\x0b\x00\xb7\x06\xd7\ |
---|
| 4451 | \x19\xf3\xd9s\x8b\xc0\x01\x00D\x1e<{\xc0\xad\x01\x87[\x04\xce\x00.\x04\x0e\ |
---|
| 4452 | \x00.\x04\xce\x197\xe7\xd1h<\x1a\x87\xb0"\xb8\xb6\x1b]\x03\'\xa7\'s\xe8\x11\ |
---|
| 4453 | \'T!\xac\x8b\xeb(\xac\x15 \x10\xb7\x08L\xfa\xa7}\xd0#\x8aV\xa7\x05\xad\xa5\ |
---|
| 4454 | \xf9\x16\xc6\xb3\x07\xcf\xac\xdfi\x87\xe2\xc9\xde\x93\x0b\xf7\xf7:\x11\x8a\ |
---|
| 4455 | \x10\xe2\xd18\xcaJy\xac\x00Lb\xd1\x182\xa9\x0c2\xa9\x0ct\xa6\x83\x1e\xd1\x10\ |
---|
| 4456 | z\xc8\tE\x08\xa5\xfb%\x9b\x08\xccQ\xaf3\xdd\xda&&D$I\x12\xb1h,\x8c.q\x1c\x04\ |
---|
| 4457 | .\x04)%A\\\x15\xad\xb2F5\xd4\xd4\x9a\xdb\xe4\x1f\x0e~$I\x12bB\xc4\xba\xb8\ |
---|
| 4458 | \x1et\xd7&\x12\x8f\xc6!\xa5$\x08+\x02\x92$im\xd7\x99\x0e\xa3k\xa0\xd1n\xf8r]\ |
---|
| 4459 | d\x89\x80,\x11\xab<\x1c\x0b\x91%\x82uq\x1dbbp\x8f\xfa\x9f\xfaS\xbb\xc5Y\x10x\ |
---|
| 4460 | B\xa9\x98/"\'\xe6\x00\x0c,\xc1\xf6\xaf\xdb\x17\xbe\xc0\xb2R\xb6\x89\xeb<<\ |
---|
| 4461 | \xd9\x7f2\xd6\xed(Y\x05\x85\xb5\xc2D\x0b\xb5\x7f\xb8\x8f\xfa\xbb\xfa\xd8kR\ |
---|
| 4462 | \xb2\n\xe4\xac\xecj{c}\x03\x85o\x0b\x9e\xe7\xf4O\xfb\xa8\x1eT\xd1h7&\\\xc9l\ |
---|
| 4463 | \x08|\xfa8<\x12X\x8f}\x11\xb3\x82b\xbe\x089+\xfbrSrVFY)#\x1e\x8dO\xd5FY)\x8f\ |
---|
| 4464 | \x14\x010\x88\x95J\xf7J\x90R\xd2T\xf5\x9e\x97Pg\r\x02\x19\x98\xd8\xe1\xd8\ |
---|
| 4465 | \xe0\xb21l\xc1L4\xaaA\xa5*\x8c\xae\x01aE@z5m\xb3\x16\x02\x11P\xba_\xf2=S\xd9\ |
---|
| 4466 | \xccmZ1S\xff\xb4\x8fF\xbb\x01\xd6c K\x04RJ\xb2\t\xb0\x98/\xce\xc4\x8aN"p!\ |
---|
| 4467 | \xb0\x1e\x03V\xff/+Y\x05\xd5\x83\xea\x85.\xcc\xeb\x86\xcfb\xfa(&D\x97\x08*\ |
---|
| 4468 | \xaf+6\xf3L\x8f(\xe8\x11E\xa3\xdd@Y)[\x0fM\\\x1d\xc45*U\'\xb6c\x8a\xc0+^J\ |
---|
| 4469 | \x92\xa4\xad\xdeX4\x86\xc2Z\x01{\x87{S_\xcf4\x04\xee\x1a\x9c~8\x93\xca\xe0\ |
---|
| 4470 | \xd1w\x8fPX+LmN\x83F\xc9*\xb6\xf2\xfe\xe1\xfeH\x1f\xad3\x1d5\xb5f\xdb&\xdf\ |
---|
| 4471 | \x95=\x8f\xf5B\xa3\x9a\xe7\x80\xf0\xaa7\x97\xb6\x8b3\x08\x02\x17\x82JU\xd0\ |
---|
| 4472 | \x8e]\x0cd\x91`#\xb7\x81\xa7\xc5\xa7xx\xef\xe1\xa5\x99!8\x03\xd0\xfa\xbb\xfa\ |
---|
| 4473 | \xd8sT\xaa\x82\x1d3\xabL\x16\x89mv1\nS\x04\xe3\xea\x1d\x86,\x92\xc0\x07M(k\r\ |
---|
| 4474 | \x95W\x15hT\xf3\xdc\x97Ie\xb0\x95\xdf\xc2/\xc5_P\xcc\x17C\x0b\x8e\x9c\x98\ |
---|
| 4475 | \xd37\x93f\xbb\xe9\xcb}9-\x86\x9f\xfe\xfbq\x1f\xce\xc1\xe3\x95\x92\x9f%\xa1\ |
---|
| 4476 | \x04\x8b\'\xa7\'\xa8\x1eT\xa1R\x15JV\xf1\x9c\xfa\xc5\xa21\xe4\xc4\x1crb\x0e\ |
---|
| 4477 | \xec\x98\xa1zP\r5\xab\xe8\x1c\xc9~\x03Z\xa3k\xd8\xca\xb1\xaff\x93\x10s\xc6VA\ |
---|
| 4478 | \x13\xea\xea#=\x1a\x04q\x8f\x7f\x7f\x8c\xfa\xfb:\xfa\xa7}\xcf\xe3\xc8"AY._\n\ |
---|
| 4479 | \x971\x89\xeeq\xd7V\xf6\xe3\x1a\xfc\xc0z\xccV\x9eU\xbd\xa3\x98\xcb\xea\xa3\ |
---|
| 4480 | \xcet\xe8\xea (\x92R\x12\xa4\x94\xe4\x8a\xd6\x01`+\xbf\x85\xeeq\x97\xaf7\xc0\ |
---|
| 4481 | -\x8cY3\xf7\xf7\x11\x1a\xed\x06\xaa\x07Ul\xff\xb6\x8d\xfd\xc3}\xd7\xfe\xcd\ |
---|
| 4482 | \xdc\xe6\x1cz5\x7f\x86\x13q\x00\x02\xcf#\xcc]\x08&\xac\xc7\xb0w\xb8\x87\xdd\ |
---|
| 4483 | \x83]\xdbv?+\x96\xf3\xc4i\xb2ge\xbd\x9cB\xe8\x7f\xf2v\xa3\xb3\xe2\xd2\x08\ |
---|
| 4484 | \xc1D\xa5\xea\xc8\xd8!HZ\x9d\x96\xad\xecw\xf6\xe2\x14\xc2\xacL\xf8y\x83\xd7\ |
---|
| 4485 | \xf3r\xe9\x84\x00\x04\x7f\xd1^8G\xb2@\x04\xd7\xa8tb\xaeN\x0e\xe3\x14\xd4yp\ |
---|
| 4486 | \xa6\x99\x9b\xed\xe6\x85\xeb\x9cD\xe0B\x986/\x10\x8f\xc6m\xa3a8a3\x8e\xe1\ |
---|
| 4487 | \xe3\xce\x9b|q\xe6:&\xc5\'\xf2]\xfb\xc2\x14\xedP_\x16a\xd2l\xa8\xb0f_\x8c\nc\ |
---|
| 4488 | \x052p!\x94\xee\x95\xb0\xf3\xc3\x0e\x94\xac2q\x84\x91%b\xcb\xb3\x03\x80\xd6\ |
---|
| 4489 | \xf2ND9\x19\x9e\xcf\x0bDp\xa5\x8b\xfd\xb0w\xb8gsK\x99T\x06\xc5|\xd1\xf3\xd8\ |
---|
| 4490 | \xc2Z\xc1\xb5z\xe8w= \'\xe6PV\xca\x9e\xf7\xa3\x98/\xda\xf2,\x063|%\xa0.J(\ |
---|
| 4491 | \xd3G\xb2H ge\xc8Y\x19\x063\xd0\xea\xb4\xc0z\xccr\x01\xe9\xd54\x92$\x89L*c;\ |
---|
| 4492 | \xcf`\x86\xef\x9b\xdbh7l\xe7\xcbY\x19RJ\xf2\x1cMbBD\xa3\xddp\xa5\x90Y\x8f\ |
---|
| 4493 | \xa1\xa6\xd6\xb0\x95\xdf\xb2\xb6\xe5\xc4\x1c\xc4\x84h\x13\xa4\x94\x92\\Al\ |
---|
| 4494 | \xfd}}\xaa@Q\\\x15\xb1\xf3\xfd\x0e4\xaaYV\xc4\xab\xdeq\xa9\xe8Y\x12z\x1eA \ |
---|
| 4495 | \x82\xaf\x99\x00\xedPT^U|\xd7\xabR\xd5\xf5b\xec\xb8\xb6F=4s\xf4\r\x8b\xc1\ |
---|
| 4496 | \x14\xf2(\xea\xef\xeb\xae\x85\xa2qhT\xb3\xf2&^\xf9\x13\x93\xdd\x83\xdd\xd0\ |
---|
| 4497 | \xe2\xa5\x1bY%\xfbs\x90\r|\xec}D\x04\x11\xdc\xbay\xcb\x97\xef6\x98\x81\x97\ |
---|
| 4498 | \x7f\xbeDM\xab\xe1\xf3?\x9f\xa7j\xeb\xed\xdfo\xb1\x1c_\xf6\x95\x85\xa3\x1d\ |
---|
| 4499 | \xea\xca\xe7\x9b\xe8LG\xb3\xdd\xc4r|\x19\xb7\xbf\xbe=\xb6\x8e\xea\x1fU\xbc\ |
---|
| 4500 | \xf9\xeb\xcd\xd8\xb6\xd2\x89\xb4m-\xa3\xa6\xd5\xd0l7q\xe7\x9b;\x9e\xf7\x84v(\ |
---|
| 4501 | *\xaf+\xf8`|\x98x\x1d\xb3"\xd4\xbf}4\xff\x9e!I\x92\xae\x1b\xa03\x1d:\xd3g6\ |
---|
| 4502 | \xfd\x12\x13"V\x16W\\oHu\x8f\xbb\xe8\x7f\xea\xfb\x1eif\x9f\xd3\xabik\x9b\xe9\ |
---|
| 4503 | \xda\xfc\xf6u\xd4\xabjf?\xcd\xfb\xc1z\xcc\xaa;lBu\r\'\xa7\'\xd6\x8b\x1dAC\ |
---|
| 4504 | \x8f((.\xdeN\xd0}\x0e\xeb~L\xe2R\xe6\x118\xe1\xc3\x85\xc0\x01\xc0\x85\xc09\ |
---|
| 4505 | \x83\x0b\x81\x03\x80\x0b\x81s\x06\xfft\x0e\x07\x00\xb00\xee\xb3\xac\x9c\xeb\ |
---|
| 4506 | \xc1\xf3\xd2\x8b\x08w\r\x1c\x00g1\x02\xb7\n\xd7\x17\xfe\xe5U\x8e\r\xd7\xd7\ |
---|
| 4507 | \xd9\xf9WX\xaf\x07N/\xe0\xb2\x08\xdcM\\}\xbc\x9e\xb1\xe7\xffk0\xe1\xd6\xe1j1\ |
---|
| 4508 | n\x90\xff\x07\x00?\xc8\r\xeep)4\x00\x00\x00\x00IEND\xaeB`\x82' |
---|
| 4509 | |
---|
| 4510 | def getSageStopDownBitmap(): |
---|
| 4511 | return BitmapFromImage(getSageStopDownImage()) |
---|
| 4512 | |
---|
| 4513 | def getSageStopDownImage(): |
---|
| 4514 | stream = cStringIO.StringIO(getSageStopDownData()) |
---|
| 4515 | return ImageFromStream(stream) |
---|
| 4516 | |
---|
| 4517 | #---------------------------------------------------------------------- |
---|
| 4518 | def getSageStopUpData(): |
---|
| 4519 | return \ |
---|
| 4520 | '\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x00\x82\x00\x00\x002\x08\x06\ |
---|
| 4521 | \x00\x00\x00\x90\xc9\x03\x88\x00\x00\x00\x04sBIT\x08\x08\x08\x08|\x08d\x88\ |
---|
| 4522 | \x00\x00\t\x91IDATx\x9c\xed\x9coh\x1b\xe7\x1d\xc7\xbf\x92%eV\x9c\x80{\xf66;r\ |
---|
| 4523 | ,\x92E5\x145\xea\x94\x17S\x12\x863wII\xa5\xd0\x17#8]\x19\x82\xc2\xc0K\xde\ |
---|
| 4524 | \x14\x95\x11J\xdf\x8d\x85\x8e\xd6\xb4/\n\xa1\xd0\xaena+1\x85\x91\xd8c+\xd4\ |
---|
| 4525 | \x8d\xd9\xe6h\xa5qpk\xc6\xa4\xf3\xda\xd9\xb1\xfe\x90Ig\xc7:Iw\xba;\xe9\xf6\ |
---|
| 4526 | \xe2zg\x9dt\xfa\x17K\x8a\xed\xdc\xe7\x8d\xf4\x9c\xee\xcf\xa3\xbb\xef\xf3\xfb\ |
---|
| 4527 | ww\x8f\xc1`\xec@%\xe6\xfe\xfdwQ\xfe\x9e\xcde+\xae\xa7\xb3\xfd\x10\n\x02\x00\ |
---|
| 4528 | \x80\x17x\xe4\x84\x1cx\x81\xc7\xf3?~\xc1Pi}\x83\x96\x10\xee|}[\x04\x00\x86c\ |
---|
| 4529 | \x00H"\x90w,\xe4\x85\xe6\xf7Z\xa7\xa9\x88\xa22~\x15\x11\xb0<\x8b4\x9b\x06\ |
---|
| 4530 | \xcb\xb3\xf8\xf5s\x97\xcb\x04Q&\x84;_\xdf\x16K\x05P\xac*\x9d\x9d\x05\xcb\xb3\ |
---|
| 4531 | \xcawY\x084C\xe37\x17~\xab\x12\x83"\x84b7\x00\x00)&\x854\x9bV\xa9Ig\xe7"\x0b\ |
---|
| 4532 | \x82\x138\xa4\xb2)\xe4\xf8\x1c2\xb9\x0c\xde\xfd\xd5\xef\r\x00`*\xdd \x9b\xcb\ |
---|
| 4533 | \xe2~\xf6>h\x86F\x9aM#\xc5H\x1b\x01P>uv\x16{\xcc{T\xed\x1c\x9fC6\x97\x05\xc7\ |
---|
| 4534 | p\xca2\x83\xc1\xd8\x81\xbf\xdc\xf9\xb3\x08H\xfe_6\x1d\xb1\xf5\x98\xa2\x1c>\ |
---|
| 4535 | \xcf+1\x02\xa0\xf6A:\xdb\x13\x83a\xd3\xf2\x9b\x8c&\x98;\xccJ\x9b\xe1\x19\xb0\ |
---|
| 4536 | \x19\x16\xb9L\x0el\x86\xc5\xf5\xdfM\x19L\x00\x14\xdf\x9ff\xd3H\xd2I\xa4\x98\ |
---|
| 4537 | \x14RY\xc95\xc8\x02\xd0/\xfe\xce\xa2\xf8z\t\x05\x01BA\x80\xc9(9\x00\x81\x13\ |
---|
| 4538 | \xc0\xe7x\xb0\x19\x16lZr\x19\x86\x8f\xfe\xf1\x91\x08l\xfa\x90$\x9dD2\x95\xd4\ |
---|
| 4539 | E\xb0\xcb(\xb6\x10\xb25\xc8\xacg\x90^\x97b?SqT\x99\xa4\x93\xa0\x19Zq\x07:\ |
---|
| 4540 | \xbb\x07Q\x14a0\x18\x94A\x9d\xe7\xf3\xe09\xe9\x1a\xa7\x12)\x98\x8a\xb3\x01N\ |
---|
| 4541 | \xe0\x14\x11\x14o\xa4\xb3;(\xbe\x9e<\xc7#\xcf\xe7\x91J\xa4\x00\x00F\xf9\x07\ |
---|
| 4542 | \xd92\xe4\xf8\x1c\x84\x82\xa0\x8b\xe0\x11\x82\xa5Y\xb5khWzh\xb5Xq\x808P\xb6<\ |
---|
| 4543 | JE\x91\xe5\xf4Rv\xbb\x10\xb8\xcdLP\xa9#p\x02\xa7\xb9r3\xf18<x\xda\xf94l\x84\ |
---|
| 4544 | \xad\xe2:\x0c\xc7 \x1c\x0b#\x14\r\xe1\xf3\xa5\xcf\xeb\x16\xc6;\xbf|G\xf9N\ |
---|
| 4545 | \xc6I\x8cO\x8do\xb9\xbf\x8f\n<\xc7\x97\x17\x94\x80\xe6g\tV\x8b\x15\x01_\xa0\ |
---|
| 4546 | \xaa\x00d:-\x9dp\xd9]p\xd9]\x88\xacE\xb0\x14_jj_t\xb4\xd1\x14B\xb3\x19;3\xa6\ |
---|
| 4547 | \x12\x81<\xea#TDY\xe6\xe8w`\x80\x18@\xa7\xa5\xb3\x1d]\xd2)\xa1\xe5Bp\x1et\ |
---|
| 4548 | \xc2\xd1\xe7P\xdaA2\x88\xc9[\x93\xe5&\x7f^\xfa\x18\xec\x1d\xc4\xa1\xef\x1e\ |
---|
| 4549 | \xc2\xc9\xa1\x93\xad\xeeZM\xac\x16+\x8e\xda\x8fb\x80\x18\xc0@\xcf\x80\xb2|5\ |
---|
| 4550 | \xb9\x8aUj\x15_.\x7fY\x97\xeb\xea\xde\xdb\x8d\x9e\xfd=J\xbb8\x16\xea\xde\xdb\ |
---|
| 4551 | \x8d\x93C\'\xe1\xe8\x97\xceQ6\x97m\xd8-6\x03\xc3\xeb7^\x17\x81\xcd\xd41\x95M\ |
---|
| 4552 | 5\xb5\x03\xfea?<\x0e\x0f\x00\xc9\x12\xbc\xf2\xc7W\xb6\xbc\xff\x80/\xa0\x12\ |
---|
| 4553 | \xd7\x83\xf0\xc6\xd4\x1bU\xdd\x8e\xcf\xed\xc3\x88s\xa4\xa6\x85\x9a\x9e\x9f\ |
---|
| 4554 | \xc6\xcc\xe2L\xd5\xff\xe4s\xfb\xe0u{\xcb\x8e}\xdes\x1e#\xce\x11\xcdm\x18\x8e\ |
---|
| 4555 | \xc1{\x9f\xbd\x87\xc5\xbb\x8b5\xfeI\xe3\xe4\xb29l\xfco\x03\x1b\xf76\x90J\xa4\ |
---|
| 4556 | @S\xf4f\xfa\xd8*\x88}\x84\xf2\x9d\xa2\xa9\x1d\x91\x15\xf8\x87\xfd\xf0\xba\ |
---|
| 4557 | \xbdu\xb9)\xaf\xdb\x8b\x80/\x00\xab\xc5\xda\xd01\x02\xbe@E\x11\x00R\xact\xe9\ |
---|
| 4558 | \x99Kp\x1et6\xb4\xdf\x07\xa5-1\x82\x8c\x8d\xb0a\xb0w\x10+\x89\x95v\x1e\xb6!\ |
---|
| 4559 | \x8a-\x98L\x90\x0cb.<\x87(\x15\xc5\x01\xe2\x00\x86\xfa\x87T\xd6\xc2F\xd80vf\ |
---|
| 4560 | \xac\xeeLe\xf4\xf8\xa8\x1231\x1c\x83\x85\xe5\x05P4\x05b\x1f\x01\x97\xdd\xa5\ |
---|
| 4561 | \x12\xe0\x8b?y\xb1)V\xb4\x16-\x17\x02ES@\xdff\xfb\xecSg\xf1\xc1\xec\x07[\xfa\ |
---|
| 4562 | cZ\'\xbc\x19\xe9\xe3\x91\xbe#e"x\xfb\xafo\xab\xcc\xf3R|\tK\xf1%|u\xf7+\xbc\ |
---|
| 4563 | \xf4\xecK\xcaEs\xf49\xe0qx\x10$\x835\x8f#\x8b@+^\x1a\xec\x1dT\xed\xb7\xd3\ |
---|
| 4564 | \xd2\x89\x11\xe7\x08\xa6\xe6\xa7\x1a\xfe?\x8d\xd0r\xd7\x10\x8e\x85Um\x97\xdd\ |
---|
| 4565 | \x85W\x7f\xf6*N=q\xaaas\xdaj\xce\x1d;\xa7jO\xcfOW\xf4\xd1+\x89\x15\\\xbbuM\ |
---|
| 4566 | \xb5\xccw\xccW\xf7\xb1\x82d\x10\x13\xb3\x13e\x03Bk\xbf\x9e\xc7\xd5\xe2l\x05-\ |
---|
| 4567 | \x17B\x90\x0c\x82\x8c\x93\xaaeD\x17\x81\xd1\x13\xa3x\xd3\xff&\xc6N\x8f\x95\ |
---|
| 4568 | \x8d\xc2\x87\x81\xd5b-\x0b@g\x16g\xaan\x13$\x83\xa0\xd2\x94\xd2&\xba\x08\x0c\ |
---|
| 4569 | \xf6\x0e\xd6<\x96,\x82j\xbf\x17Ct\x11-\x1f4-\x17\x02\x00\\\xfd\xe4jE\x93\xe9\ |
---|
| 4570 | \xb2\xbb\xe0\x1f\xf6\xe3-\xff[\xf0\x0f\xfb\xdb\x16\x1c\x95r\xf8\xfb\x87U\xed\ |
---|
| 4571 | \x85\xe5\x85\xba\xdc\xd7\xc2\x7f\x17T\xed\'\x0f>Ys\x9b\xb9\xf0\\\xcduJ\x07\ |
---|
| 4572 | \x8fVI\xbe\x99\xb4%X\xccrYL\xccN`.<\x87s\xc7\xcei\xa6~\x9d\x96Nx\x1c\x1ex\ |
---|
| 4573 | \x1c\x1ePi\n\xef\xdf|\xbf\xadUE{\xaf]\xd5..vUc\x95ZU\xb5\x9bU\x10+\x8d\xadZM\ |
---|
| 4574 | [,\x82\xccR|\t\xe3S\xe3\xb8\xf2\xa7+\x98Y\x9cQ\x1e\x97/\x85\xe8"\xf0\xb2\xef\ |
---|
| 4575 | \xe5m\xe12j\x91\xa4\x93\xaavq\xe1i+P4\xa5j\xdb\x1e\xab]\x9e\xdf\nmM\x1feV\ |
---|
| 4576 | \x12+XI\xac`28\t\xe7A\'\xdc\x87\xdc\x9a\x17\xdd?\xecG\x92N\xea\xf7\x1bP.\xb8\ |
---|
| 4577 | f\xd3V\x8b\xa0\xc5\xe2\xddEL\xccN\xe0\xf2\x1f.cz~\xba\xec\xf7\xd1\xe3\xa3\ |
---|
| 4578 | \x0f\xa1W\x0f\x9f\xe2B\x1c\xa0~?\xa1\x15<t!\xc8\xacg\xd615?U\x16M\xd7s\xc7\ |
---|
| 4579 | \xf2aRj\xb2\xc9\x18Ya\xcd\xc6(\x15B\xab\x1f\x13\xd86B\x90\t\x92\xc1\x8a\xb1C\ |
---|
| 4580 | +\t\xc5B\xaa\xb6\xcb\xee\xaak\xbb\xd2t\xb1Y&|\x80P\xc7\x1a\xad\xae\xc6n;!\ |
---|
| 4581 | \x00\xe5\x91x;(\x8dCl\x84\r\xdd{\xbb\xabnc\xb5X\xcb\x04\x13\x8a\x86*\xac]?\ |
---|
| 4582 | \xce\x83NU\xf6\xb1\xb0\xbcPe\xed\xe6\xd0r!4Z\x17\xb0Z\xac\xaa\xd1P\\\xb0\xa9\ |
---|
| 4583 | F\xf1z\x0fZ|)\xadu\x8c\x9e\xa8\x1e\x9f\x94\xde\x98"\xe3$\xd63\xeb5\x8fs\xe2\ |
---|
| 4584 | \xf1\x13U\x7f?}\xf4\xb4\xaa\xbd+\x84p\xe9\x99K\xb8\xf2\xfc\x15\xf8\xdc\xbe\ |
---|
| 4585 | \x9a#\xac{o7\x02\xbe\x80\xea\xe4\x06\xc3\xb5k\xf7\x80\xf4\x8c\x80\x8c\x8d\ |
---|
| 4586 | \xb0\xc1\xe7\xae\xbf\xdc+s\xfd\x8b\xeb*\xb7$\x17\xbb\xb48\xf5\xc4\xa9\xb2\ |
---|
| 4587 | \xbb\x877n\xdf\xa8\xeb8\x1e\x87\x07\x01_@\xf3|\xf8\x87\xfd\xaa:K\x84\x8a\xd4\ |
---|
| 4588 | u\xffb\xab\xb4%}$\xba\x08x\xdd^x\xdd^D\xa8\x08\xc2\xb10\x12\xa9\x04"kR\xd1f\ |
---|
| 4589 | \xa8\x7f\x086\xc2Vff#T\xa4\xee\x9b-\x0b\xcb\x0b\xaa\xed\xbdn/\\v\x97\xe6hr\ |
---|
| 4590 | \xf4;p\xe7\x9b;\xb8\xf9\xaf\x9b\xaa\xe5\xeb\x99u\\\xbbuMu\xf1=\x0e\x0f\x1c\ |
---|
| 4591 | \xfd\x0e\x95 ]vWY\x10;\xb38\xd3P\x9a\xeb\xe8s\xe0\xb5\x9f\xbf&\x95\xa9\xbf\ |
---|
| 4592 | \xad\x19h\xed\xf7\xc3\xbf}X\xf7>\xb7B\xdb\xeb\x086\xc2VW&@\xc6I\\\xfd\xe4j\ |
---|
| 4593 | \xdd\xfb\r\x92\xc1\xb2\x07c\xab\x1d\xabRt/\x8f\xbeb1\xc8B\xae\xc4\xcc\xe2\ |
---|
| 4594 | \x0c&\x83\x93\r\xf5U\xae\x9bT+\x9aM\xccN\xb4\xed\x96}\xcb\x8501;\x01\x97\xdd\ |
---|
| 4595 | \x85\x81\x9e\x01\x10]D\xcd\xf5#T\x04\x9f.~\xfa@\xe6p|j\x1c\xe7\x8f\x9f\xdfrE\ |
---|
| 4596 | 2H\x06\x11[\x8f\xe1\xecSg\xabf\x0fd\x9c\xc4\x8d\xdb7\x1a.x\xcd\x85\xe70\xff\ |
---|
| 4597 | \xcd<.\x9c\xbc\xa0yN\xc88\x89\x8f\xff\xf9q[\x9f\xdbh\xf9\xa3j\xc5\xc8\xef3\ |
---|
| 4598 | \xd8\x1e\xb3\xa1\xeb;]\xaa\xdf\x96\x13\xcb\x88P\x91\xba\x82\xadz8\xd2w\x04=\ |
---|
| 4599 | \xfbz\xd0\xb3o\xf3Y\xc1$\x9dD\x92N\x82\x13\xb8\xbaO\xb2\xdc\xe7\xa1\xfe!eY(\ |
---|
| 4600 | \x16B2\x95\xac\xbb\xaf\x95\x1eU\x93\xfb)\x9f\x8f$\x9dD(\x1aj\xda9\xa8\x84\ |
---|
| 4601 | \xd6\xa3jmu\rY.\xab<\xd8\xd1j\x9au\x9cV\xf7\xb9]\xe7\xa3\x16F\xa0=/\xb7\xe8l\ |
---|
| 4602 | \x13\xbe}e%\xcf\xe5U\x8b\x8d\xba\x08tx\x86\xdf\xac#\xe4\xf8\x9c>5\xce#\x80\ |
---|
| 4603 | \x08\x11|n\xf3ux\x96\x96nf\x99\xb4.\xbe\xfc.\xbd\xce.C\x04\nB\x01\x00\x94\ |
---|
| 4604 | \xb9\x11x\x8e\x97\xde},\xb5\x04\xf2\xdc\x08\x10\x01\xe8Z\xd8U\x88\x10!\xf0\ |
---|
| 4605 | \x02x\x86\x97\xe6O\xa2Y\xf0\x0c\x8f\x02_\x80\xe1\xe2\xbb\x17\xc5\xe2\x89\xb2\ |
---|
| 4606 | \x00\xa0P\x90Tc\x80A\x17\xc3.A\x14E\x14\x84\x02\x984\x03:A#F\xc6@S4\xd2Ii\ |
---|
| 4607 | \xa2\x14\x83\xc1\xd8\x81_\x8c\xbf\xa0z\xfd\xd9d\x96\xb2J\xa3\xc9\xa8\x8ba\ |
---|
| 4608 | \xa7#J\x96@\x16Av#\x8b\x8d{\x1b\x88\x86\xa2\x8a\x08\xe2\xff\xb9\'\xcd\xaa\ |
---|
| 4609 | \x96\xbd\x9fU|\x86\xd9bF\x87\xb9\x03F\x93\x11\xe6=f\x98\xcc&\x18MRL\xa9\x8bb\ |
---|
| 4610 | \x87 \xca\x1f\x92\x00\x04^PM\x9eU,\x02\x19e\xe6\xd53\x17\x7f*\xe6y)\xb7\xec0\ |
---|
| 4611 | wH\x82\xb0t\xa8\x84\xa1\xb3s\x90\x83\xc2<\x9f\x07\x9bf\xc1fX\xacE\xd7T\xee\ |
---|
| 4612 | \x00\x90\xac\x01Pt\xaf!\xcf\xe7\xb1\x16]\xc3\xfe\xde\xfdX\x8b\xae\x01\x00\ |
---|
| 4613 | \xf6\xf7\xeeok\xe7u\x9a\x8f<Y\x16K\xb3\xd8Hl\xa0\xc0\x174\xd7+\x9b\x94\xfb\ |
---|
| 4614 | \x87\xcf\xbaD9\xb7\xd4\xd9\xb9(\xe9!#\xa5\x87\xa5\x02\x90-\x81\x8c\xe64\xfdG\ |
---|
| 4615 | ~tX\xac\xb4\x03\x9d\x9dO\xa9\x08\x80\nB\x90\xe9\xfb\xc1\xf7\xf49\xf6v\x11Z\ |
---|
| 4616 | \x02\x90\xf9?\xec\x08#j\x16n\xfd\xae\x00\x00\x00\x00IEND\xaeB`\x82' |
---|
| 4617 | |
---|
| 4618 | def getSageStopUpBitmap(): |
---|
| 4619 | return BitmapFromImage(getSageStopUpImage()) |
---|
| 4620 | |
---|
| 4621 | def getSageStopUpImage(): |
---|
| 4622 | stream = cStringIO.StringIO(getSageStopUpData()) |
---|
| 4623 | return ImageFromStream(stream) |
---|
| 4624 | |
---|
| 4625 | |
---|
| 4626 | |
---|
| 4627 | |
---|
| 4628 | |
---|
| 4629 | ########################################################## |
---|
| 4630 | ########################################################## |
---|
| 4631 | ########################################################## |
---|
| 4632 | # |
---|
| 4633 | # start everything |
---|
| 4634 | # |
---|
| 4635 | ########################################################## |
---|
| 4636 | |
---|
| 4637 | if __name__ == '__main__': |
---|
| 4638 | # change to the folder where the script is running |
---|
| 4639 | # so that the relative paths work out correctly |
---|
| 4640 | os.chdir(sys.path[0]) |
---|
| 4641 | main() |
---|