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() |
---|