"""Graphical user interface system.
Widgets properties are classified as mutable or static.
Mutable properties have a clear separation between model and view.
@author Michael Reimpell
"""
# Copyright (C) 2005 Michael Reimpell
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
# License as published by the Free Software Foundation; either
# version 2.1 of the License, or (at your option) any later version.
#
# This library is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
# epydoc doc format
__docformat__ = "javadoc en"
import os
import Blender
from Blender import Draw
from Blender.BGL import *
import base
from base import *
class Action:
"""Action interface.
Actions encapsulate user requests.
"""
def __init__(self):
"""Constructor.
"""
return
def execute(self):
"""Executes the action.
"""
return
class QuitAction(Action):
"""Quits the windowing system.
"""
def execute(self):
Blender.Draw.Exit()
return
class Size:
"""Size hints.
@cvar INFINITY Infinity value for size hints.
"""
INFINITY = 2147483647
def __init__(self, preferredSize=None, minimumSize=None, maximumSize=None):
"""Constructor.
A size hint is a list of integers [width, height]
.
@param preferredSize Default [0,0]
.
@param minimumSize Default [0,0]
.
@param maximumSize Default [Size.INFINITY, Size.INFINITY]
.
"""
self.preferredSize = preferredSize or [0, 0]
if minimumSize:
self.minimumSize = minimumSize
elif ((self.preferredSize[0] < Size.INFINITY) and (self.preferredSize[1] < Size.INFINITY)):
self.minimumSize = self.preferredSize[:]
else:
self.minimumSize = [0, 0]
if preferredSize:
self.maximumSize = maximumSize or self.preferredSize[:]
else:
self.maximumSize = maximumSize or [Size.INFINITY, Size.INFINITY]
return
def getPreferredSize(self):
return self.preferredSize
def getMinimumSize(self):
return self.minimumSize
def getMaximumSize(self):
return self.maximumSize
class Widget:
"""Widget interface.
"""
def __init__(self, parent, size = Size()):
"""Constructor.
Overwrite the constructor to get event numbers for all used
actions via a call to parent._addButtonAction()
.
@param name The widget name must be unique.
@param size Size hints.
"""
self.parent = parent
self.size = size
self.parent._addWidget(self)
return
def draw(self, screenRectangle):
"""Draws the widget into an area of the screen.
@param screenRectangle Area of the screen to draw into.
The screenRectangle is a list of the integers
[xl, yl, xu, yu]
, where (xl,yl) is
the lower left corner of the area and (xu, yu) is
the upper right corner of the area.
"""
return
def eventFilter(self, event, value):
"""Called from event callback function.
@see Blender.Draw.Register
"""
return
def getSize(self):
"""Size hints of the widget.
@return Size object.
"""
return self.size
def resize(self, size=None):
"""Resizes the widget.
@param size New widget size or None
to
inform about resize of child widgets.
"""
if size:
self.size = size
self.parent.resize()
return
def removeFromParent(self):
"""Remove this widget from parent widget.
Remove a widget from its parent before deleting it. Overwrite
this to also remove all button actions separately with a call
to self.parent._removeButtonAction()
. This is not
done in the destructor as Python's garbage collector does not
guarantee to delete objects.
"""
self.parent._removeWidget(self)
return
def _addWidget(self, widget):
"""Adds a child widget.
@param widget Child widget to add.
"""
raise NotImplementedError
return
def _removeWidget(self, widget):
"""Removes a child widget.
@param widget Child widget to remove.
"""
raise NotImplementedError
return
def _addButtonAction(self, action):
"""Registers an action for a button event.
@param action Action to execute on receive of the returned button event number.
@return eventNumber Event number to use for the button that corresponds to that action.
"""
return self.parent._addButtonAction(action)
def _removeButtonAction(self, eventNumber):
"""Action for the given event number will no longer be called.
@param eventNumber Event number for the action.
"""
self.parent._removeButtonAction(eventNumber)
return
class Spacer(Widget):
"""Occupies blank space on the screen.
"""
def __init__(self, parent, size):
Widget.__init__(self, parent, size)
return
class Decorator(Widget):
"""Decorates a child widget.
A decorator does not have a name on its own. It adopts the name
of its child widget.
"""
def __init__(self, parent):
self.childWidget = None
Widget.__init__(self, parent)
return
def draw(self, screenRectangle):
self.childWidget.draw(screenRectangle)
return
def eventFilter(self, event, value):
self.childWidget.eventFilter(event, value)
return
def getSize(self):
if self.childWidget:
size = self.childWidget.getSize()
else:
# no child widget yet
size = Size()
return size
def resize(self, size=None):
if size:
# pass resize request to the child
self.childWidget.resize(size)
else:
# pass child resize notification to the parent
self.parent.resize()
return
def _addWidget(self, widget):
self.childWidget = widget
self.parent.resize()
return
class Activator(Decorator):
"""Enables and disables child widget.
"""
def __init__(self, parent, enabled=1):
Decorator.__init__(self, parent)
self.enabled = enabled
def eventFilter(self, event, value):
if self.enabled:
self.childWidget.eventFilter(event, value)
return
def draw(self, screenRectangle):
if self.enabled:
self.childWidget.draw(screenRectangle)
return
def setEnabled(self, enabled):
self.enabled = enabled
return
def isEnabled(self):
return self.enabled
class ValueModel(Model):
"""Model with a value of arbitrary type.
"""
def __init__(self, value):
Model.__init__(self)
self.value = None
self.setValue(value)
return
def setValue(self, value):
self.value = value
self._notify()
return
def getValue(self):
return self.value
class T(ValueModel):
"""Short name for ValueModel.
@see ValueModel
"""
class BoundedValueModel(ValueModel):
def __init__(self, minimum=0, maximum=0, initial=0):
self.minimum = minimum
self.maximum = maximum
ValueModel.__init__(self, initial)
return
def getMinimum(self):
return self.minimum
def getMaximum(self):
return self.maximum
def setValue(self, value):
if (value != self.value):
if value < self.minimum:
self.value = self.minimum
elif value > self.maximum:
self.value = self.maximum
else:
self.value = value
self._notify()
return
class BoundedRangeModel(BoundedValueModel):
"""Model for a bounded range.
minimum <= value <= value + extend <= maximum
"""
def __init__(self, minimum=0, initial=0, extend=0, maximum=0):
self.extend = 0
BoundedValueModel.__init__(self, minimum, maximum, initial)
self.setExtend(extend)
return
def setMaximum(self, maximum, silent=0):
if (maximum != self.maximum):
self.maximum = maximum
if self.value > self.maximum:
self.value = self.maximum
if ((self.value + self.extend) > self.maximum):
self.extend = self.maximum - self.value
if not silent:
self._notify()
return
def setValue(self, value, silent=0):
if (value != self.value):
if value < self.minimum:
self.value = self.minimum
elif value > self.maximum:
self.value = self.maximum
else:
self.value = value
if ((self.value + self.extend) > self.maximum):
# minimum <= value <= maximum
# ==> maximum - value >= 0
self.extend = self.maximum - self.value
if not silent:
self._notify()
return
def getExtend(self):
return self.extend
def setExtend(self, extend, silent=0):
"""
@param extend positive integer.
"""
if (extend != self.extend):
if ((self.value + extend) > self.maximum):
self.extend = self.maximum - self.value
else:
self.extend = extend
if not silent:
self._notify()
return
class BasenameModel(ValueModel):
"""Ensure string is a valid file name.
"""
def __init__(self, basename):
ValueModel.__init__(self, self._ensureIsBasename(basename))
return
def setValue(self, basename):
ValueModel.setValue(self, self._ensureIsBasename(basename))
return
def _ensureIsBasename(self, basename):
return os.path.basename(basename)
class DirnameModel(ValueModel):
"""Ensure string is a valid directory name.
"""
def __init__(self, dirname):
ValueModel.__init__(self, self._ensureIsDirname(dirname))
return
def setValue(self, dirname):
ValueModel.setValue(self, self._ensureIsDirname(dirname))
return
def _ensureIsDirname(self, dirname):
if os.path.isdir(dirname) and os.path.exists(dirname):
# remove possible trailing seperators
name = os.path.dirname(dirname + os.sep)
else:
name = os.path.dirname(dirname)
return name
class RedrawView(View):
def __init__(self, model):
View.__init__(self, model)
return
def update(self):
Blender.Draw.Redraw(1)
return
class ActionWidget(Widget):
"""Widget with single action and tooltip.
"""
def __init__(self, parent, size=Size(), action=Action(), tooltip=None):
"""Constructor.
@param tooltip Optional widget tooltip string ValueModel.
"""
Widget.__init__(self, parent, size)
self.event = self.parent._addButtonAction(action)
self.tooltip = tooltip
if tooltip:
RedrawView(self.tooltip)
return
def removeFromParent(self):
self.parent._removeButtonAction(self.event)
Widget.removeFromParent(self)
return
class ActionTitleWidget(ActionWidget):
"""Widget with single action, title and tooltip.
"""
def __init__(self, parent, size=Size(), action=Action(), title=ValueModel(''), tooltip=None):
"""Constructor.
@param title Widget title string ValueModel.
@param tooltip Optional widget tooltip string ValueModel.
"""
ActionWidget.__init__(self, parent, size, action, tooltip)
self.title = title
RedrawView(self.title)
return
class Button(ActionTitleWidget):
"""Push button.
"""
def __init__(self, parent, size, action, title, tooltip=None):
"""Constructor.
@param action Action to execute when the button is pushed.
"""
ActionTitleWidget.__init__(self, parent, size, action, title, tooltip)
return
def draw(self, rect):
if self.tooltip:
Blender.Draw.PushButton(self.title.getValue(), self.event, rect[0], rect[1], rect[2]-rect[0]-1, rect[3]-rect[1]-1, self.tooltip.getValue())
else:
Blender.Draw.PushButton(self.title.getValue(), self.event, rect[0], rect[1], rect[2]-rect[0]-1, rect[3]-rect[1]-1)
return
class ActionView(View):
"""View with single model and action.
"""
def __init__(self, model):
View.__init__(self, model)
self.valueButton = Blender.Draw.Create(self.model.getValue())
return
def update(self):
Blender.Draw.Redraw(1)
return
class ViewAction(Action):
def __init__(self, view):
self.view = view
return
def execute(self):
self.view.model.setValue(self.view.valueButton.val)
return
class StringView(ActionTitleWidget, ActionView):
def __init__(self, parent, size, model, title=ValueModel(''), tooltip=None):
"""Constructor.
@param model String ValueModel.
"""
ActionView.__init__(self, model)
ActionTitleWidget.__init__(self, parent, size, StringView.ViewAction(self), title, tooltip)
return
def draw(self, rect):
if self.tooltip:
self.valueButton = Blender.Draw.String(self.title.getValue(), self.event, rect[0], rect[1], rect[2]-rect[0]-1, rect[3]-rect[1]-1, self.model.getValue(), 255, self.tooltip.getValue())
else:
self.valueButton = Blender.Draw.String(self.title.getValue(), self.event, rect[0], rect[1], rect[2]-rect[0]-1, rect[3]-rect[1]-1, self.model.getValue(), 255)
return
class ToggleModel(ValueModel):
"""Interface and default implementation for a toggle model.
The toggle value can be True
or False
.
"""
def toggle(self):
if self.getValue():
self.setValue(False)
else:
self.setValue(True)
return
class ToggleGroup(ValueModel):
"""An exclusive toggle group.
Only one toggle is selected at a time. Returns current active
ToggleModel as value.
"""
def __init__(self):
# key: ToggleModel, value: ToggleGroup.Toggle
self.toggleDict = {}
ValueModel.__init__(self, None)
return
def addToggle(self, model):
"""Adds a toggle to the toggle group.
@param model ToggleModel.
"""
self.toggleDict[model] = ToggleGroup.Toggle(self, model)
if (len(self.toggleDict) == 1):
# always one toggle selected
self.value = model
model.setValue(True)
self._notify()
elif model.getValue():
# enable toggle
self._toggle(model)
return
def removeToggle(self, model):
"""Removes a toggle from the toggle group.
If the removed toggle was the current active,
select the first toggle instead.
@param model ToggleModel.
"""
if model in self.toggleDict.keys():
# remove toggle from group
self.toggleDict[model].detachModel()
del self.toggleDict[model]
# update current selected
if (model == self.getValue()):
if (len(self.toggleDict) > 0):
self.toggleDict.keys()[0].toggle()
else:
self.value = None
self._notify()
else:
raise KeyError
return
def setValue(self, value):
"""Sets a toggle to True
.
@param value Key of ToggleModel.
"""
# set value as current active
if (value in self.toggleDict.keys()):
self.value = value
self._notify()
elif value is None:
pass
else:
raise KeyError
return
def _toggle(self, model):
# if self.toggleDict.has_key(model):
if model.getValue():
## selected
if (self.value != model):
# deselect old
oldKey = self.value
self.setValue(model)
if self.toggleDict.has_key(oldKey):
oldKey.setValue(False)
elif (model == self.value):
## current selected deselected
# select again, as always one toggle is selected
model.setValue(True)
return
class Toggle(View):
def __init__(self, group, model):
View.__init__(self, model)
self.group = group
return
def update(self):
self.group._toggle(self.model)
return
class ToggleView(ActionTitleWidget, ActionView):
def __init__(self, parent, size, model, title=ValueModel(''), tooltip=None):
"""Constructor.
@param model ToggleModel.
"""
View.__init__(self, model)
ActionTitleWidget.__init__(self, parent, size, ToggleView.ViewAction(self), title, tooltip)
def draw(self, rect):
if self.tooltip:
Blender.Draw.Toggle(self.title.getValue(), self.event, rect[0], rect[1], rect[2]-rect[0]-1, rect[3]-rect[1]-1, self.model.getValue(), self.tooltip.getValue())
else:
Blender.Draw.Toggle(self.title.getValue(), self.event, rect[0], rect[1], rect[2]-rect[0]-1, rect[3]-rect[1]-1, self.model.getValue())
return
class ViewAction(Action):
def __init__(self, view):
self.view = view
return
def execute(self):
self.view.model.toggle()
return
class ScrollbarBase(Widget, RedrawView):
"""Scrollbar base class.
This class contains code common to VerticalScrollbar and HorizontalScrollbar.
Don't use this class directly, use VerticalScrollbar or HorizontalScrollbar instead.
"""
def __init__(self, parent, size, model):
"""Constructor.
@param size If l is the desired length of the smaller side, set the larger side to at least 2*l+5.
@param model BoundedRangeModel
"""
Widget.__init__(self, parent, size)
RedrawView.__init__(self, model)
# translate MOUSEX and MOUSEY coordinates into local ones
self.barRect = [0,0,0,0]
self.markerRect = [0,0,0,0]
self.mousePressed = 0
self.mouseFocusX = 0
self.mouseFocusY = 0
self.markerFocus = 0
self.mousePosition = 0
return
def _inc(self, amount=1):
"""limit maximum value to value + extend <= maximum
"""
value = self.model.getValue()
value += amount
if ((value + self.model.getExtend()) <= self.model.getMaximum()):
self.model.setValue(value)
else:
# set to maximum value
self.model.setValue(self.model.getMaximum() - self.model.getExtend())
return
def _dec(self, amount=1):
value = self.model.getValue()
value -= amount
if (self.model.getMinimum() <= value):
self.model.setValue(value)
else:
# set to minimum value
self.model.setValue(self.model.getMinimum())
return
def _addWidget(self, widget):
return
class IncAction(Action):
def __init__(self, scrollbar):
self.scrollbar = scrollbar
return
def execute(self):
self.scrollbar._inc()
return
class DecAction(Action):
def __init__(self, scrollbar):
self.scrollbar = scrollbar
return
def execute(self):
self.scrollbar._dec()
return
class VerticalScrollbar(ScrollbarBase):
"""Vertical scrollbar.
"""
def __init__(self, parent, size, model):
ScrollbarBase.__init__(self, parent, size, model)
self.incButton = Button(self, Size(), ScrollbarBase.IncAction(self), ValueModel("\\/"), ValueModel("Scroll down"))
self.decButton = Button(self, Size(), ScrollbarBase.DecAction(self), ValueModel("/\\"), ValueModel("Scroll up"))
return
def draw(self, rect):
# buttons
buttonSize = rect[2] - rect[0]
# \/
self.incButton.draw([rect[0], rect[1], rect[2], rect[1] + buttonSize])
# /\
self.decButton.draw([rect[0], rect[3]-buttonSize, rect[2], rect[3]])
# bar
# marker and bar are > 3x3 pix each as they have 1 pix border
self.barRect = [rect[0], rect[1] + buttonSize, rect[2], rect[3] - buttonSize]
Blender.BGL.glColor3f(0.13,0.13,0.13) # dark grey
Blender.BGL.glRectf(self.barRect[0], self.barRect[1], self.barRect[2], self.barRect[3])
Blender.BGL.glColor3f(0.78,0.78,0.78) # light grey
Blender.BGL.glRectf(self.barRect[0] + 1, self.barRect[1], self.barRect[2], self.barRect[3] - 1)
Blender.BGL.glColor3f(0.48,0.48,0.48) # grey
Blender.BGL.glRectf(self.barRect[0] + 1, self.barRect[1] + 1, self.barRect[2] - 1, self.barRect[3] - 1)
# marker
# calculate marker size
range = self.model.getMaximum() - self.model.getMinimum()
if range:
step = float(self.barRect[3] - self.barRect[1] - 2)/range
# relative positions
markerStart = step*(self.model.getValue() - self.model.getMinimum())
markerEnd = markerStart + step*self.model.getExtend()
else:
# relative positions
markerStart = 0.0
markerEnd = self.barRect[3] - self.barRect[1] - 2
if ((markerEnd - markerStart) < 3):
# minimal marker size
markerEnd = markerStart + 3
self.markerRect = [self.barRect[0] + 1, \
self.barRect[3] - 1 - markerEnd, \
self.barRect[2] - 1, \
self.barRect[3] - 1 - markerStart]
# draw maker
Blender.BGL.glColor3f(0.78,0.78,0.78) # light grey
Blender.BGL.glRectf(self.markerRect[0], self.markerRect[1], self.markerRect[2], self.markerRect[3])
Blender.BGL.glColor3f(0.13,0.13,0.13) # dark grey
Blender.BGL.glRectf(self.markerRect[0] + 1, self.markerRect[1], self.markerRect[2], self.markerRect[3] - 1)
# check if marker has foucs
if (self.mouseFocusX and self.mouseFocusY and (self.mousePosition > self.markerRect[1]) and (self.mousePosition < self.markerRect[3])):
Blender.BGL.glColor3f(0.64,0.64,0.64) # marker focus grey
else:
Blender.BGL.glColor3f(0.60,0.60,0.60) # marker grey
Blender.BGL.glRectf(self.markerRect[0] + 1, self.markerRect[1] + 1, self.markerRect[2] - 1, self.markerRect[3] - 1)
return
def eventFilter(self, event, value):
if (value != 0):
# Mouse
if (event == Blender.Draw.MOUSEX):
mousePositionX = value - ScreenManager.getSingleton().getScissorRectangle()[0]
# check if mouse is inside bar
if ((mousePositionX >= self.barRect[0]) and (mousePositionX <= self.barRect[2])):
# redraw if marker got focus
if (not self.mouseFocusX) and self.mouseFocusY:
Blender.Draw.Redraw(1)
self.mouseFocusX = 1
else:
# redraw if marker lost focus
if self.mouseFocusX and self.mouseFocusY:
Blender.Draw.Redraw(1)
self.mouseFocusX = 0
elif (event == Blender.Draw.MOUSEY):
# relative mouse position
self.mousePosition = value - ScreenManager.getSingleton().getScissorRectangle()[1]
# check if mouse is inside bar
if ((self.mousePosition >= self.barRect[1]) and (self.mousePosition <= self.barRect[3])):
self.mouseFocusY = 1
if ((self.mousePosition > self.markerRect[1]) and (self.mousePosition < self.markerRect[3])):
# redraw if marker got focus
if self.mouseFocusX and (not self.markerFocus):
Blender.Draw.Redraw(1)
self.markerFocus = 1
else:
# redraw if marker lost focus
if self.mouseFocusX and self.markerFocus:
Blender.Draw.Redraw(1)
self.markerFocus = 0
# move marker
if (self.mousePressed == 1):
# calculate step from distance to marker
if (self.mousePosition > self.markerRect[3]):
self._dec(1)
Blender.Draw.Draw()
elif (self.mousePosition < self.markerRect[1]):
self._inc(1)
Blender.Draw.Draw()
else:
# redraw if marker lost focus
if self.mouseFocusX and self.markerFocus:
Blender.Draw.Redraw(1)
self.markerFocus = 0
self.mouseFocusY = 0
self.mousePressed = 0
elif ((event == Blender.Draw.LEFTMOUSE) and (self.mouseFocusX == 1) and (self.mouseFocusY == 1)):
self.mousePressed = 1
# move marker
if (self.mousePosition > self.markerRect[3]):
self._dec(1)
elif (self.mousePosition < self.markerRect[1]):
self._inc(1)
elif (event == Blender.Draw.WHEELUPMOUSE):
if self.mouseFocusX and self.mouseFocusY:
self._dec(1)
elif (event == Blender.Draw.WHEELDOWNMOUSE):
if self.mouseFocusX and self.mouseFocusY:
self._inc(1)
else: # released keys and buttons
if (event == Blender.Draw.LEFTMOUSE):
self.mousePressed = 0
return
class HorizontalScrollbar(ScrollbarBase):
"""Horizontal scrollbar.
"""
def __init__(self, parent, size, model):
ScrollbarBase.__init__(self, parent, size, model)
self.incButton = Button(self, Size(), ScrollbarBase.IncAction(self), ValueModel(">"), ValueModel("Scroll right"))
self.decButton = Button(self, Size(), ScrollbarBase.DecAction(self), ValueModel("<"), ValueModel("Scroll left"))
return
def draw(self, rect):
# buttons
buttonSize = rect[3] - rect[1]
# <
self.decButton.draw([rect[0], rect[1], rect[0] + buttonSize, rect[3]])
# >
self.incButton.draw([rect[2] - buttonSize, rect[1], rect[2], rect[3]])
# bar
# marker and bar are > 3x3 pix each as they have 1 pix border
#TODO: Missed by one
self.barRect = [rect[0] + buttonSize, rect[1] - 1, rect[2] - buttonSize, rect[3] - 1]
Blender.BGL.glColor3f(0.13,0.13,0.13) # dark grey
Blender.BGL.glRectf(self.barRect[0], self.barRect[1], self.barRect[2], self.barRect[3])
Blender.BGL.glColor3f(0.78,0.78,0.78) # light grey
Blender.BGL.glRectf(self.barRect[0] + 1, self.barRect[1], self.barRect[2], self.barRect[3] - 1)
Blender.BGL.glColor3f(0.48,0.48,0.48) # grey
Blender.BGL.glRectf(self.barRect[0] + 1, self.barRect[1] + 1, self.barRect[2] - 1, self.barRect[3] - 1)
# marker
# calculate marker size
range = self.model.getMaximum() - self.model.getMinimum()
if range:
step = float(self.barRect[2] - self.barRect[0] - 2)/range
# relative positions
markerStart = step*(self.model.getValue() - self.model.getMinimum())
markerEnd = markerStart + step*self.model.getExtend()
else:
# relative positions
markerStart = 0.0
markerEnd = self.barRect[2] - self.barRect[0] - 2
if ((markerEnd - markerStart) < 3):
# minimal marker size
markerEnd = markerStart + 3
self.markerRect = [self.barRect[0] + 1 + markerStart, \
self.barRect[1] + 1, \
self.barRect[0] + markerEnd, \
self.barRect[3] - 1]
# draw maker
Blender.BGL.glColor3f(0.78,0.78,0.78) # light grey
Blender.BGL.glRectf(self.markerRect[0], self.markerRect[1], self.markerRect[2], self.markerRect[3])
Blender.BGL.glColor3f(0.13,0.13,0.13) # dark grey
Blender.BGL.glRectf(self.markerRect[0] + 1, self.markerRect[1], self.markerRect[2], self.markerRect[3] - 1)
# check if marker has foucs
if (self.mouseFocusX and self.mouseFocusY and (self.mousePosition > self.markerRect[0]) and (self.mousePosition < self.markerRect[2])):
Blender.BGL.glColor3f(0.64,0.64,0.64) # marker focus grey
else:
Blender.BGL.glColor3f(0.60,0.60,0.60) # marker grey
Blender.BGL.glRectf(self.markerRect[0] + 1, self.markerRect[1] + 1, self.markerRect[2] - 1, self.markerRect[3] - 1)
return
def eventFilter(self, event, value):
if (value != 0):
# Mouse
if (event == Blender.Draw.MOUSEY):
mousePositionY = value - ScreenManager.getSingleton().getScissorRectangle()[1]
# check if mouse is inside bar
if ((mousePositionY >= self.barRect[1]) and (mousePositionY <= self.barRect[3])):
# redraw if marker got focus
if (not self.mouseFocusY) and self.mouseFocusX:
Blender.Draw.Redraw(1)
self.mouseFocusY = 1
else:
# redraw if marker lost focus
if self.mouseFocusX and self.mouseFocusY:
Blender.Draw.Redraw(1)
self.mouseFocusY = 0
elif (event == Blender.Draw.MOUSEX):
# relative mouse position
self.mousePosition = value - ScreenManager.getSingleton().getScissorRectangle()[0]
# check if mouse is inside bar
if ((self.mousePosition >= self.barRect[0]) and (self.mousePosition <= self.barRect[2])):
self.mouseFocusX = 1
if ((self.mousePosition > self.markerRect[0]) and (self.mousePosition < self.markerRect[2])):
# redraw if marker got focus
if (not self.markerFocus) and self.mouseFocusY:
Blender.Draw.Redraw(1)
self.markerFocus = 1
else:
# redraw if marker lost focus
if self.mouseFocusX and self.markerFocus:
Blender.Draw.Redraw(1)
self.markerFocus = 0
# move marker
if (self.mousePressed == 1):
# calculate step from distance to marker
if (self.mousePosition > self.markerRect[2]):
self._inc(1)
Blender.Draw.Draw()
elif (self.mousePosition < self.markerRect[0]):
self._dec(1)
Blender.Draw.Draw()
else:
# redraw if marker lost focus
if self.mouseFocusX and self.markerFocus:
Blender.Draw.Redraw(1)
self.markerFocus = 0
self.mouseFocusX = 0
self.mousePressed = 0
elif ((event == Blender.Draw.LEFTMOUSE) and (self.mouseFocusX == 1) and (self.mouseFocusY == 1)):
self.mousePressed = 1
# move marker
if (self.mousePosition > self.markerRect[2]):
self._inc(1)
elif (self.mousePosition < self.markerRect[0]):
self._dec(1)
elif (event == Blender.Draw.WHEELUPMOUSE):
if self.mouseFocusX and self.mouseFocusY:
self._dec(1)
elif (event == Blender.Draw.WHEELDOWNMOUSE):
if self.mouseFocusX and self.mouseFocusY:
self._inc(1)
else: # released keys and buttons
if (event == Blender.Draw.LEFTMOUSE):
self.mousePressed = 0
return
class NumberView(ActionTitleWidget, ActionView):
def __init__(self, parent, size, model, title=ValueModel(''), tooltip=None):
"""Constructor.
@param model BoundedValueModel.
"""
ActionView.__init__(self, model)
ActionTitleWidget.__init__(self, parent, size, StringView.ViewAction(self), title, tooltip)
return
def draw(self, rect):
if self.tooltip:
self.valueButton = Blender.Draw.Number(self.title.getValue(), self.event, \
rect[0], rect[1], rect[2]-rect[0]-1, rect[3]-rect[1]-1, \
self.model.getValue(), self.model.getMinimum(), self.model.getMaximum(), self.tooltip.getValue())
else:
self.valueButton = Blender.Draw.Number(self.title.getValue(), self.event, \
rect[0], rect[1], rect[2]-rect[0]-1, rect[3]-rect[1]-1, \
self.model.getValue(), self.model.getMinimum(), self.model.getMaximum())
return
class SliderView(ActionTitleWidget, ActionView):
def __init__(self, parent, size, model, title=ValueModel(''), tooltip=None):
"""Constructor.
@param model BoundedValueModel.
"""
ActionView.__init__(self, model)
ActionTitleWidget.__init__(self, parent, size, StringView.ViewAction(self), title, tooltip)
return
def draw(self, rect):
if self.tooltip:
self.valueButton = Blender.Draw.Slider(self.title.getValue(), self.event, \
rect[0], rect[1], rect[2]-rect[0]-1, rect[3]-rect[1]-1, \
self.model.getValue(), self.model.getMinimum(), self.model.getMaximum(), 1, self.tooltip.getValue())
else:
self.valueButton = Blender.Draw.Slider(self.title.getValue(), self.event, \
rect[0], rect[1], rect[2]-rect[0]-1, rect[3]-rect[1]-1, \
self.model.getValue(), self.model.getMinimum(), self.model.getMaximum(), 1)
return
class MenuItem(ValueModel):
def __init__(self, text, action=Action()):
"""Constructor.
@param text Item string.
@param action Action to execute on selection.
"""
ValueModel.__init__(self, text)
self.action = action
return
def select(self):
self.action.execute()
return
class MenuTitle(MenuItem):
def __init__(self, text):
MenuItem.__init__(self, text + " %t")
return
def setValue(self, value):
MenuItem.setValue(self, value + " %t")
return
class MenuSeparator(MenuItem):
def __init__(self):
MenuItem.__init__(self, " %l")
return
def setValue(self, value):
raise NotImplementedError
return
class Menu(ActionWidget):
"""Blender menu button.
"""
def __init__(self, parent, size, tooltip=None):
"""Constructor.
@param title Optional title ValueModel.
"""
ActionWidget.__init__(self, parent, size, Menu.SelectAction(self), tooltip)
# cached menu string
self.menuString = ''
# current selected item id
self.current = 0
# id management
# display order of ids in menu
# value: id
self.displayList = []
# key: id, value: MenuItem
self.itemDict = {}
self.valueButton = Blender.Draw.Create(0)
return
def update(self):
"""Update cached menu string.
"""
self.menuString = ''
for itemId in self.displayList:
self.menuString = self.menuString + self.itemDict[itemId].getValue() + " %x" + str(itemId) + "|"
return
def insertItem(self, menuItem, position, setCurrent=False):
"""Inserts a menu item into a specific position of the display list.
"""
id = self._getId(menuItem, setCurrent)
self.displayList.insert(position, id)
# recreate menu string
self.update()
return id
def appendItem(self, menuItem, setCurrent=False):
"""Appends an item to the menu.
@param menuItem The MenuItem to add.
@param setCurrent Sets the item to be the current selected.
@return Item identifier.
"""
# get free id
id = self._getId(menuItem, setCurrent)
# append id
self.displayList.append(id)
# create menu string
self.menuString = self.menuString + menuItem.getValue() + " %x" + str(id) + "|"
return id
def removeItem(self, id):
if id in self.displayList:
# remove id
if self.current == id:
self.current = 0
del self.itemDict[id]
self.displayList.remove(id)
# recreate menu string
self.update()
return
def removeAll(self):
"""Removes all menu items.
"""
self.itemDict = {}
self.displayList = []
self.current = 0
self.menuString = ''
return
def draw(self, rect):
if self.tooltip:
self.valueButton = Blender.Draw.Menu(self.menuString, self.event, \
rect[0], rect[1], rect[2]-rect[0]-1, rect[3]-rect[1]-1, self.current, self.tooltip.getValue())
else:
self.valueButton = Blender.Draw.Menu(self.menuString, self.event, \
rect[0], rect[1], rect[2]-rect[0]-1, rect[3]-rect[1]-1, self.current.getValue())
return
def _getId(self, menuItem, setCurrent):
"""Creates an id for the menuItem and optinally set it to current menu string.
"""
# get a free id (button value)
if (len(self.itemDict) == len(self.displayList)):
# Blender's button values start with 1
id = len(self.displayList) + 1
else:
# first unused
id = [(x+1) for x in range(len(self.displayList)) if (x+1) not in self.itemDict.keys()][0]
# assign menu item to that id
self.itemDict[id] = menuItem
# manage current state
if setCurrent:
self.current = id
return id
class SelectAction(Action):
def __init__(self, menu):
self.menu = menu
return
def execute(self):
if self.menu.valueButton.val in self.menu.displayList:
self.menu.itemDict[self.menu.valueButton.val].select()
self.menu.current = self.menu.valueButton.val
return
class Border(Decorator):
"""Fixed border around widgets.
"""
def __init__(self, parent, borderSize=10):
"""Constructor.
@param borderSize Size of the border.
"""
Decorator.__init__(self, parent)
self.borderSize = borderSize
return
def draw(self, screenRectangle):
rect = screenRectangle[:]
rect[0] += self.borderSize
rect[1] += self.borderSize
rect[2] -= self.borderSize
rect[3] -= self.borderSize
self.childWidget.draw(rect)
return
def getSize(self):
prefSize = self.childWidget.getSize().getPreferredSize()[:]
prefSize[0] += 2*self.borderSize
prefSize[1] += 2*self.borderSize
minSize = self.childWidget.getSize().getMinimumSize()[:]
minSize[0] += 2*self.borderSize
minSize[1] += 2*self.borderSize
maxSize = self.childWidget.getSize().getMaximumSize()[:]
maxSize[0] += 2*self.borderSize
maxSize[1] += 2*self.borderSize
return Size(prefSize, minSize, maxSize)
class LabelModel(Model):
def __init__(self, text, fontsize='normal', color=None):
"""Constructor.
@param text Text to display.
@param fontsize 'large', 'normal', 'small' or 'tiny'
@param color List of font color values.
"""
Model.__init__(self)
self.text = text
if fontsize in ['large', 'normal', 'small', 'tiny']:
self.fontsize = fontsize
else:
raise ValueError
self.color = color
return
def setText(self, text):
self.text = text
self._notify()
return
def getText(self):
return self.text
def setFontsize(self, fontsize):
if fontsize in ['large', 'normal', 'small', 'tiny']:
self.fontsize = fontsize
self._notify()
else:
raise ValueError
return
def getFontsize(self):
return self.fontsize
def setColor(self, color):
self.color = color
self._notify()
def getColor(self):
return self.color
class L(LabelModel):
"""Short name for LabelModel.
@see LabelModel
"""
class LabelView(Widget, View):
"""Displays a text string.
"""
_HEIGHTDICT = {'large':14, 'normal':12, 'small':10, 'tiny':8}
_YSHIFT = {'large':5, 'normal':4, 'small':3, 'tiny':2}
def __init__(self, parent, model, size=None):
View.__init__(self, model)
if not size:
self.calculateSize = True
size = self._calculateSize()
else:
self.calculateSize = False
Widget.__init__(self, parent, size)
return
def draw(self, screenRectangle):
range = len(self.model.getText())
while ((range > 0) and (Blender.Draw.GetStringWidth(self.model.getText()[:range], self.model.getFontsize()) > (screenRectangle[2] - screenRectangle[0]))):
range -= 1
if self.model.getColor():
if (len(self.model.getColor()) == 3):
glColor3f(*self.model.getColor())
else:
glColor4f(*self.model.getColor())
else:
# theme font color
theme = Blender.Window.Theme.Get()[0]
glColor4ub(*theme.get('text').text)
glRasterPos2i(screenRectangle[0], screenRectangle[1] + LabelView._YSHIFT[self.model.getFontsize()])
Blender.Draw.Text(self.model.getText()[:range], self.model.getFontsize())
return
def update(self):
if self.calculateSize:
self.size = self._calculateSize()
Blender.Draw.Redraw(1)
return
def _calculateSize(self):
size = [0, 0]
size[0] = Blender.Draw.GetStringWidth(self.model.getText(), self.model.getFontsize())
size[1] = LabelView._HEIGHTDICT[self.model.getFontsize()]
return Size(size, size, size)
class Box(Decorator):
"""Provides a border with an optional title for a child widget.
"""
def __init__(self, parent, label=None, outerBorder=0, innerBorder=0):
"""Constructor.
@param childWidget Widget to decorate.
@param label Optional LabelModel as title.
"""
# borders
self.outerBorder = outerBorder
self.innerBorder = innerBorder
self.model = label
self.view = None
if self.model:
self.model.addView(self)
# use view to caculate size only
self.view = LabelView(Box.NoParent(), self.model)
Decorator.__init__(self, parent)
return
def draw(self, screenRectangle):
rect = screenRectangle[:]
rect[0] += self.outerBorder
rect[1] += self.outerBorder
rect[2] -= self.outerBorder
rect[3] -= self.outerBorder
if self.model:
# title
[labelWidth, labelHeight] = self.view.getSize().getMinimumSize()
self.view.draw([rect[0] + 7, rect[3] - labelHeight, rect[0] + 7 + labelWidth, rect[3]])
# border
glColor3f(0.0, 0.0, 0.0)
glBegin(GL_LINE_STRIP)
# 5--6 TITLE 1--2
# | |
# 4----------------3
glVertex2i(rect[0] + 9 + labelWidth, rect[3] - int(labelHeight/2.0))
glVertex2i(rect[2], rect[3] - int(labelHeight/2.0))
glVertex2i(rect[2], rect[1])
glVertex2i(rect[0], rect[1])
glVertex2i(rect[0], rect[3] - int(labelHeight/2.0))
glVertex2i(rect[0] + 3, rect[3] - int(labelHeight/2.0))
glEnd()
rect[0] += 1
rect[1] += 1
rect[2] -= 1
rect[3] -= labelHeight
else:
# border only
glColor3f(0.0, 0.0, 0.0)
glBegin(GL_LINE_STRIP)
glVertex2i(rect[0], rect[1])
glVertex2i(rect[0], rect[3])
glVertex2i(rect[2], rect[3])
glVertex2i(rect[2], rect[1])
glVertex2i(rect[0], rect[1])
glEnd()
rect[0] += 1
rect[1] += 1
rect[2] -= 1
rect[3] -= 1
rect[0] += self.innerBorder
rect[1] += self.innerBorder
rect[2] -= self.innerBorder
rect[3] -= self.innerBorder
self.childWidget.draw(rect)
return
def getSize(self):
if self.childWidget:
minSize = self.childWidget.getSize().getMinimumSize()[:]
prefSize = self.childWidget.getSize().getPreferredSize()[:]
maxSize = self.childWidget.getSize().getMaximumSize()[:]
else:
minSize = [0, 0]
prefSize = [0, 0]
maxSize = [0, 0]
# border
minSize[0] += 2 + 2*self.outerBorder + 2*self.innerBorder
minSize[1] += 2 + 2*self.outerBorder + 2*self.innerBorder
prefSize[0] += 2 + 2*self.outerBorder + 2*self.innerBorder
prefSize[1] += 2 + 2*self.outerBorder + 2*self.innerBorder
maxSize[0] += 2 + 2*self.outerBorder + 2*self.innerBorder
maxSize[1] += 2 + 2*self.outerBorder + 2*self.innerBorder
if self.model:
titleSize = self.view.getSize()
# 1+3 +3 +x +3+1 = 11+x
# +---___TITLE___+ y
# | | +
# +--------------+ 1
if (minSize[0] < (titleSize.getMinimumSize()[0] + 9)):
minSize[0] += 9 + titleSize.getMinimumSize()[0]
prefSize[0] += 9 + titleSize.getPreferredSize()[0]
maxSize[0] += 9 + titleSize.getMaximumSize()[0]
minSize[1] += titleSize.getMinimumSize()[1] - 1
prefSize[1] += titleSize.getPreferredSize()[1] - 1
maxSize[1] += titleSize.getMaximumSize()[1] - 1
return Size(prefSize, minSize, maxSize)
class NoParent(Widget):
"""Widget acts as dummy parent.
"""
def __init__(self):
return
def resize(self, size=None):
return
def _addWidget(self, widget):
return
def _removeWidget(self, widget):
return
class OgreFrame(Decorator):
"""Ogre Logo, Title and border.
"""
OGRE_LOGO = Buffer(GL_BYTE, [48,122*4],[[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,32,0,0,0,64,0,0,0,95,0,0,0,127,0,0,0,127,0,0,0,127,0,0,0,127,0,0,0,127,0,0,0,127,0,0,0,127,0,0,0,127,0,0,0,127,0,0,0,127,0,0,0,127,0,0,0,64,0,0,0,64,0,0,0,64,0,0,0,64,0,0,0,64,0,0,0,32,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,32,0,0,0,95,0,0,0,127,0,0,0,127,0,1,0,127,0,2,0,127,2,5,2,127,2,5,2,127,4,6,4,127,5,8,5,127,8,11,8,127,8,11,8,127,3,5,3,127,2,3,2,127,0,1,0,127,0,1,0,127,0,1,0,127,0,1,0,127,0,0,0,127,0,0,0,127,0,0,0,127,0,0,0,127,0,0,0,127,0,0,0,64,0,0,0,32,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,32,0,0,0,95,0,0,0,127,1,2,1,127,4,6,4,127,10,13,10,127,18,22,18,127,23,28,23,127,24,30,24,127,25,31,25,127,25,31,25,127,26,32,26,127,26,32,26,127,26,32,26,127,25,31,25,127,24,30,24,127,18,23,18,127,3,5,3,127,4,6,4,127,8,11,8,127,9,12,9,127,13,17,13,127,17,22,17,127,15,19,15,127,7,9,7,127,1,2,1,127,0,0,0,127,0,0,0,95,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,64,0,0,0,127,2,4,2,127,4,6,4,127,18,22,18,127,25,31,25,127,25,31,25,127,25,31,25,127,25,31,25,127,25,31,25,127,25,31,25,127,25,31,25,127,25,31,25,127,25,31,25,127,25,31,25,127,25,31,25,127,18,22,18,127,15,19,15,127,20,26,20,127,25,31,25,127,26,32,26,127,26,32,26,127,25,31,25,127,25,31,25,127,25,31,25,127,26,32,26,127,24,30,24,127,16,20,16,127,4,5,4,127,0,0,0,95,0,0,0,32,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,95,1,1,1,127,13,15,13,127,12,15,12,127,24,29,24,127,25,31,25,127,25,31,25,127,25,31,25,127,25,31,25,127,25,31,25,127,25,31,25,127,25,31,25,127,25,31,25,127,25,31,25,127,23,29,23,127,24,30,24,127,25,31,25,127,25,31,25,127,25,31,25,127,25,31,25,127,25,31,25,127,25,31,25,127,25,31,25,127,25,31,25,127,25,31,25,127,25,31,25,127,25,31,25,127,25,31,25,127,25,31,25,127,23,28,23,127,3,5,3,127,0,0,0,127,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,95,1,1,1,127,19,24,19,127,11,15,11,127,25,31,25,127,25,31,25,127,25,31,25,127,25,31,25,127,25,31,25,127,25,31,25,127,25,31,25,127,25,31,25,127,25,31,25,127,23,28,23,127,17,21,17,127,22,28,22,127,25,31,25,127,25,31,25,127,25,31,25,127,25,31,25,127,25,31,25,127,25,31,25,127,25,31,25,127,25,31,25,127,25,31,25,127,25,31,25,127,25,31,25,127,25,31,25,127,25,31,25,127,25,31,25,127,25,31,25,127,23,28,23,127,3,5,3,127,0,0,0,127,0,0,0,32,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
[0,0,0,0,0,0,0,0,0,0,0,32,0,0,0,127,20,24,20,127,16,20,16,127,20,25,20,127,24,30,24,127,25,31,25,127,25,31,25,127,25,31,25,127,25,31,25,127,25,31,25,127,25,31,25,127,25,31,25,127,25,31,25,127,22,28,22,127,25,31,25,127,25,31,25,127,25,31,25,127,25,31,25,127,25,31,25,127,25,31,25,127,25,31,25,127,25,31,25,127,25,31,25,127,25,31,25,127,25,31,25,127,25,31,25,127,25,31,25,127,25,31,25,127,25,31,25,127,25,31,25,127,25,31,25,127,25,31,25,127,23,28,23,127,3,5,3,127,0,0,0,127,0,0,0,32,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
[0,0,0,0,0,0,0,0,0,0,0,64,5,7,5,127,26,32,26,127,15,19,15,127,41,48,41,127,38,45,38,127,24,30,24,127,25,31,25,127,25,31,25,127,25,31,25,127,25,31,25,127,25,31,25,127,25,31,25,127,25,31,25,127,25,31,25,127,25,31,25,127,25,31,25,127,25,31,25,127,25,31,25,127,25,31,25,127,25,31,25,127,25,31,25,127,25,31,25,127,25,31,25,127,25,31,25,127,25,31,25,127,25,31,25,127,25,31,25,127,25,31,25,127,25,31,25,127,25,31,25,127,25,31,25,127,25,31,25,127,25,31,25,127,23,28,23,127,3,4,3,127,0,0,0,127,58,66,58,127,105,118,105,127,105,118,105,127,105,118,105,127,105,118,105,127,105,118,105,127,105,118,105,127,105,118,105,127,105,118,105,127,105,118,105,127,105,118,105,127,105,118,105,127,105,118,105,127,105,118,105,127,105,118,105,127,105,118,105,127,105,118,105,127,105,118,105,127,105,118,105,127,105,118,105,127,105,118,105,127,105,118,105,127,105,118,105,127,105,118,105,127,105,118,105,127,105,118,105,127,105,118,105,127,105,118,105,127,105,118,105,127,105,118,105,127,105,118,105,127,105,118,105,127,105,118,105,127,105,118,105,127,105,118,105,127,105,118,105,127,105,118,105,127,105,118,105,127,105,118,105,127,105,118,105,127,105,118,105,127,105,118,105,127,105,118,105,127,105,118,105,127,105,118,105,127,105,118,105,127,105,118,105,127,105,118,105,127,105,118,105,127,105,118,105,127,105,118,105,127,105,118,105,127,105,118,105,127,105,118,105,127,105,118,105,127,105,118,105,127,105,118,105,127,105,118,105,127,105,118,105,127,105,118,105,127,105,118,105,127,105,118,105,127,105,118,105,127,105,118,105,127,105,118,105,127,105,118,105,127,105,118,105,127,105,118,105,127,105,118,105,127,105,118,105,127,105,118,105,127,105,118,105,127,105,118,105,127,105,118,105,127,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
[0,0,0,0,0,0,0,0,0,0,0,127,20,24,20,127,27,34,27,127,26,32,26,127,47,55,47,127,47,55,47,127,39,46,39,127,25,31,25,127,25,31,25,127,25,31,25,127,25,31,25,127,25,31,25,127,25,31,25,127,25,31,25,127,25,31,25,127,25,31,25,127,25,31,25,127,25,31,25,127,25,31,25,127,25,31,25,127,25,31,25,127,25,31,25,127,25,31,25,127,25,31,25,127,25,31,25,127,25,31,25,127,25,31,25,127,25,31,25,127,25,31,25,127,25,31,25,127,25,31,25,127,25,31,25,127,25,31,25,127,25,31,25,127,25,31,25,127,11,16,11,127,0,1,0,127,3,3,3,127,94,106,94,127,105,118,105,127,105,118,105,127,105,118,105,127,105,118,105,127,105,118,105,127,105,118,105,127,105,118,105,127,105,118,105,127,105,118,105,127,105,118,105,127,105,118,105,127,105,118,105,127,105,118,105,127,105,118,105,127,105,118,105,127,105,118,105,127,105,118,105,127,105,118,105,127,105,118,105,127,105,118,105,127,105,118,105,127,105,118,105,127,105,118,105,127,105,118,105,127,105,118,105,127,105,118,105,127,105,118,105,127,105,118,105,127,105,118,105,127,105,118,105,127,105,118,105,127,105,118,105,127,105,118,105,127,105,118,105,127,105,118,105,127,105,118,105,127,105,118,105,127,105,118,105,127,105,118,105,127,105,118,105,127,105,118,105,127,105,118,105,127,105,118,105,127,105,118,105,127,105,118,105,127,105,118,105,127,105,118,105,127,105,118,105,127,105,118,105,127,105,118,105,127,105,118,105,127,105,118,105,127,105,118,105,127,105,118,105,127,105,118,105,127,105,118,105,127,105,118,105,127,105,118,105,127,105,118,105,127,105,118,105,127,105,118,105,127,105,118,105,127,105,118,105,127,105,118,105,127,105,118,105,127,105,118,105,127,105,118,105,127,105,118,105,127,105,118,105,127,105,118,105,127,105,118,105,127,105,118,105,127,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
[0,0,0,0,0,0,0,0,0,0,0,127,33,39,33,127,45,52,45,127,28,32,28,127,47,55,47,127,44,51,44,127,39,46,39,127,27,33,27,127,25,31,25,127,25,31,25,127,25,31,25,127,25,31,25,127,25,31,25,127,25,31,25,127,25,31,25,127,25,31,25,127,25,31,25,127,25,31,25,127,25,31,25,127,25,31,25,127,25,31,25,127,25,31,25,127,25,31,25,127,25,31,25,127,25,31,25,127,25,31,25,127,25,31,25,127,25,31,25,127,25,31,25,127,25,31,25,127,25,31,25,127,25,31,25,127,25,31,25,127,25,31,25,127,25,31,25,127,21,26,21,127,0,2,0,127,0,0,0,127,23,26,23,127,105,118,105,127,105,118,105,127,105,118,105,127,105,118,105,127,105,118,105,127,105,118,105,127,105,118,105,127,105,118,105,127,105,118,105,127,105,118,105,127,105,118,105,127,105,118,105,127,105,118,105,127,105,118,105,127,105,118,105,127,105,118,105,127,105,118,105,127,105,118,105,127,105,118,105,127,105,118,105,127,105,118,105,127,105,118,105,127,105,118,105,127,105,118,105,127,105,118,105,127,105,118,105,127,105,118,105,127,105,118,105,127,105,118,105,127,105,118,105,127,105,118,105,127,105,118,105,127,105,118,105,127,105,118,105,127,105,118,105,127,105,118,105,127,105,118,105,127,105,118,105,127,105,118,105,127,105,118,105,127,105,118,105,127,105,118,105,127,105,118,105,127,105,118,105,127,105,118,105,127,105,118,105,127,105,118,105,127,105,118,105,127,105,118,105,127,105,118,105,127,105,118,105,127,105,118,105,127,105,118,105,127,105,118,105,127,105,118,105,127,105,118,105,127,105,118,105,127,105,118,105,127,105,118,105,127,105,118,105,127,105,118,105,127,105,118,105,127,105,118,105,127,105,118,105,127,105,118,105,127,105,118,105,127,105,118,105,127,105,118,105,127,105,118,105,127,105,118,105,127,105,118,105,127,105,118,105,127,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
[0,0,0,0,0,0,0,0,0,0,0,127,24,28,24,127,33,40,33,127,18,22,18,127,29,35,29,127,25,31,25,127,24,30,24,127,25,31,25,127,25,31,25,127,25,31,25,127,25,31,25,127,25,31,25,127,25,31,25,127,25,31,25,127,25,31,25,127,25,31,25,127,25,31,25,127,25,31,25,127,25,31,25,127,25,31,25,127,25,31,25,127,25,31,25,127,25,31,25,127,25,31,25,127,25,31,25,127,25,31,25,127,25,31,25,127,25,31,25,127,25,31,25,127,25,31,25,127,25,31,25,127,25,31,25,127,25,31,25,127,25,31,25,127,25,31,25,127,25,31,25,127,5,8,5,127,1,2,1,127,0,0,0,127,70,79,70,127,105,118,105,127,105,118,105,127,105,118,105,127,105,118,105,127,105,118,105,127,105,118,105,127,105,118,105,127,105,118,105,127,105,118,105,127,105,118,105,127,105,118,105,127,105,118,105,127,105,118,105,127,105,118,105,127,105,118,105,127,105,118,105,127,105,118,105,127,105,118,105,127,105,118,105,127,105,118,105,127,105,118,105,127,105,118,105,127,105,118,105,127,105,118,105,127,105,118,105,127,105,118,105,127,105,118,105,127,105,118,105,127,105,118,105,127,105,118,105,127,105,118,105,127,105,118,105,127,105,118,105,127,105,118,105,127,105,118,105,127,105,118,105,127,105,118,105,127,105,118,105,127,105,118,105,127,105,118,105,127,105,118,105,127,105,118,105,127,105,118,105,127,105,118,105,127,105,118,105,127,105,118,105,127,105,118,105,127,105,118,105,127,105,118,105,127,105,118,105,127,105,118,105,127,105,118,105,127,105,118,105,127,105,118,105,127,105,118,105,127,105,118,105,127,105,118,105,127,105,118,105,127,105,118,105,127,105,118,105,127,105,118,105,127,105,118,105,127,94,105,94,127,70,79,70,127,76,86,76,127,90,101,90,127,103,116,103,127,105,118,105,127,105,118,105,127,105,118,105,127,105,118,105,127,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
[0,0,0,0,0,0,0,64,0,0,0,127,4,6,4,127,12,16,12,127,22,27,22,127,25,31,25,127,25,31,25,127,25,31,25,127,25,31,25,127,25,31,25,127,25,31,25,127,23,29,23,127,28,34,28,127,35,42,35,127,28,35,28,127,25,31,25,127,23,29,23,127,23,29,23,127,25,31,25,127,25,31,25,127,25,31,25,127,25,31,25,127,25,31,25,127,25,31,25,127,25,31,25,127,25,31,25,127,25,31,25,127,25,31,25,127,25,31,25,127,25,31,25,127,25,31,25,127,25,31,25,127,25,31,25,127,25,31,25,127,25,31,25,127,25,31,25,127,25,31,25,127,17,21,17,127,0,2,0,127,0,0,0,127,31,36,31,127,105,118,105,127,105,118,105,127,105,118,105,127,105,118,105,127,105,118,105,127,105,118,105,127,105,118,105,127,105,118,105,127,105,118,105,127,105,118,105,127,105,118,105,127,105,118,105,127,105,118,105,127,105,118,105,127,100,112,100,127,92,103,92,127,103,116,103,127,105,118,105,127,105,118,105,127,105,118,105,127,105,118,105,127,105,118,105,127,105,118,105,127,105,118,105,127,105,118,105,127,105,118,105,127,105,118,105,127,105,118,105,127,105,118,105,127,105,118,105,127,105,118,105,127,105,118,105,127,100,112,100,127,81,92,81,127,68,77,68,127,65,73,65,127,65,73,65,127,76,86,76,127,78,88,78,127,83,94,83,127,92,103,92,127,85,95,85,127,31,35,31,127,6,7,6,127,6,7,6,127,13,14,13,127,13,14,13,127,19,21,19,127,26,29,26,127,26,29,26,127,48,54,48,127,96,108,96,127,105,118,105,127,105,118,105,127,105,118,105,127,105,118,105,127,105,118,105,127,105,118,105,127,105,118,105,127,105,118,105,127,105,118,105,127,70,78,70,127,3,3,3,127,0,0,0,127,0,0,0,127,0,0,0,127,0,0,0,127,12,13,11,127,23,26,23,127,36,40,36,127,49,55,49,127,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
[0,0,0,64,0,0,0,127,2,4,2,127,16,20,16,127,25,31,25,127,25,31,25,127,25,31,25,127,25,31,25,127,25,31,25,127,25,31,25,127,24,30,24,127,26,33,26,127,59,68,59,127,81,91,81,127,87,98,87,127,86,96,86,127,80,90,80,127,71,79,71,127,59,66,59,127,36,41,35,127,23,29,23,127,25,31,25,127,25,31,25,127,25,31,25,127,25,31,25,127,25,31,25,127,25,31,25,127,25,31,25,127,25,31,25,127,25,31,25,127,24,31,24,127,26,32,26,127,25,31,25,127,25,31,25,127,25,31,25,127,25,31,25,127,25,31,25,127,25,31,25,127,25,31,25,127,5,8,5,127,0,1,0,127,18,20,18,127,105,118,105,127,105,118,105,127,105,118,105,127,105,118,105,127,105,118,105,127,105,118,105,127,105,118,105,127,105,118,105,127,105,118,105,127,105,118,105,127,91,103,91,127,58,65,58,127,29,33,29,127,6,7,6,127,0,0,0,127,0,0,0,127,1,2,1,127,22,24,22,127,54,61,54,127,94,106,94,127,105,118,105,127,105,118,105,127,105,118,105,127,105,118,105,127,105,118,105,127,105,118,105,127,105,118,105,127,105,118,105,127,105,118,105,127,88,99,88,127,51,58,51,127,18,21,18,127,0,0,0,127,0,0,0,127,0,0,0,127,0,0,0,127,0,0,0,127,0,0,0,127,0,0,0,127,0,0,0,127,0,0,0,127,0,0,0,127,0,0,0,127,0,0,0,127,0,0,0,127,0,0,0,127,0,0,0,127,0,0,0,127,0,0,0,127,0,0,0,127,0,0,0,127,0,0,0,127,17,19,17,127,48,54,48,127,80,91,80,127,102,115,102,127,105,118,105,127,105,118,105,127,105,118,105,127,105,118,105,127,105,118,105,127,29,33,29,127,0,0,0,127,41,31,14,127,33,25,11,127,18,14,6,127,2,2,1,127,0,0,0,127,0,0,0,127,0,0,0,127,0,0,0,127,0,0,0,127,0,0,0,127,0,0,0,127,0,0,0,64,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
[0,0,0,127,2,3,2,127,24,29,24,127,26,32,26,127,24,30,24,127,25,31,25,127,24,30,24,127,24,30,24,127,24,30,24,127,23,29,23,127,34,41,34,127,78,88,78,127,87,98,87,127,86,97,86,127,86,97,86,127,86,97,86,127,86,97,86,127,87,97,87,127,87,97,87,127,84,93,84,127,62,69,62,127,34,40,34,127,24,30,24,127,25,31,25,127,25,31,25,127,25,31,25,127,25,31,25,127,23,28,23,127,26,30,26,127,36,38,36,127,47,50,46,127,39,42,37,127,34,40,34,127,30,37,30,127,24,30,24,127,25,31,25,127,25,31,25,127,25,31,25,127,25,31,25,127,15,19,15,127,0,1,0,127,0,0,0,127,102,115,102,127,105,118,105,127,105,118,105,127,105,118,105,127,105,118,105,127,105,118,105,127,105,118,105,127,105,118,105,127,94,106,94,127,43,48,43,127,4,5,4,127,0,0,0,127,0,0,0,127,0,0,0,127,6,5,2,127,16,12,5,127,2,2,1,127,0,0,0,127,0,0,0,127,7,8,7,127,58,65,58,127,105,118,105,127,105,118,105,127,105,118,105,127,105,118,105,127,105,118,105,127,105,118,105,127,96,108,96,127,41,47,41,127,1,1,1,127,0,0,0,127,0,0,0,127,6,5,2,127,27,21,9,127,42,33,14,127,46,36,16,127,46,36,16,127,33,25,11,127,31,24,11,127,25,19,9,127,16,12,5,127,12,9,4,127,0,0,0,127,107,82,36,127,115,88,38,127,107,82,36,127,107,82,36,127,100,76,33,127,92,71,31,127,88,68,30,127,0,0,0,127,4,3,2,127,0,0,0,127,0,0,0,127,0,0,0,127,13,15,13,127,65,73,65,127,105,118,105,127,105,118,105,127,105,118,105,127,105,118,105,127,13,14,13,127,0,0,0,127,107,82,36,127,122,94,41,127,122,94,41,127,122,94,41,127,109,84,36,127,96,73,32,127,80,62,27,127,65,50,22,127,52,40,17,127,37,28,12,127,21,16,7,127,2,2,1,127,0,0,0,64,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
[0,0,0,127,9,11,9,127,48,56,48,127,45,53,45,127,41,48,41,127,33,40,33,127,34,41,34,127,37,44,37,127,54,62,54,127,77,87,77,127,87,97,87,127,87,97,87,127,86,97,86,127,86,97,86,127,86,97,86,127,86,97,86,127,86,97,86,127,86,97,86,127,86,97,86,127,86,97,86,127,86,97,86,127,79,88,79,127,61,69,61,127,25,31,25,127,25,31,25,127,23,28,23,127,19,23,19,127,42,43,41,127,60,60,59,127,61,61,59,127,61,61,59,127,63,63,61,127,35,37,34,127,38,45,38,127,33,39,33,127,25,31,25,127,25,31,25,127,25,31,25,127,25,31,25,127,15,19,15,127,0,1,0,127,0,0,0,127,102,115,102,127,105,118,105,127,105,118,105,127,105,118,105,127,105,118,105,127,105,118,105,127,105,118,105,127,81,91,81,127,9,11,9,127,0,0,0,127,2,2,1,127,44,34,15,127,86,66,29,127,115,88,38,127,122,94,41,127,122,94,41,127,121,92,40,127,94,72,31,127,39,30,13,127,0,0,0,127,0,0,0,127,40,45,40,127,101,114,101,127,105,118,105,127,105,118,105,127,105,118,105,127,85,95,85,127,11,13,11,127,0,0,0,127,4,3,2,127,50,38,17,127,94,72,31,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,92,71,31,127,0,0,0,127,107,82,36,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,100,76,33,127,2,2,1,127,105,81,35,127,98,75,33,127,60,46,20,127,23,18,8,127,0,0,0,127,1,1,1,127,90,102,90,127,105,118,105,127,105,118,105,127,105,118,105,127,6,7,6,127,0,0,0,127,115,88,38,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,8,6,3,127,0,0,0,95,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
[0,0,0,127,3,5,3,127,45,53,45,127,46,54,46,127,46,54,46,127,47,55,47,127,46,54,46,127,68,78,68,127,87,98,87,127,86,97,86,127,86,97,86,127,86,97,86,127,86,97,86,127,86,97,86,127,86,97,86,127,86,97,86,127,86,97,86,127,86,97,86,127,86,97,86,127,86,97,86,127,86,97,86,127,87,98,87,127,67,76,67,127,38,46,38,127,21,26,21,127,50,52,50,127,60,60,59,127,61,61,59,127,60,60,58,127,60,60,58,127,60,60,58,127,61,61,59,127,39,41,38,127,52,59,52,127,67,76,67,127,23,29,23,127,25,31,25,127,25,31,25,127,25,31,25,127,15,19,15,127,0,1,0,127,0,0,0,127,102,115,102,127,105,118,105,127,105,118,105,127,105,118,105,127,105,118,105,127,105,118,105,127,59,67,59,127,1,1,1,127,0,0,0,127,35,27,12,127,105,81,35,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,86,66,29,127,8,6,3,127,0,0,0,127,36,40,36,127,105,118,105,127,105,118,105,127,82,92,82,127,7,7,7,127,0,0,0,127,31,24,10,127,107,82,36,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,80,62,27,127,0,0,0,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,82,63,28,127,46,36,16,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,27,21,9,127,0,0,0,127,78,88,78,127,105,118,105,127,105,118,105,127,105,118,105,127,0,0,0,127,0,0,0,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,100,76,33,127,0,0,0,127,0,0,0,64,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
[0,0,0,127,0,2,0,127,41,49,41,127,46,54,46,127,46,54,46,127,49,56,49,127,77,87,77,127,87,98,87,127,86,97,86,127,86,97,86,127,86,97,86,127,86,97,86,127,86,97,86,127,86,97,86,127,86,97,86,127,86,97,86,127,86,97,86,127,86,97,86,127,86,97,86,127,86,97,86,127,85,96,85,127,55,64,55,127,44,52,44,127,23,28,23,127,17,22,17,127,90,92,90,127,84,84,82,127,60,60,58,127,60,60,58,127,60,60,58,127,60,60,58,127,61,61,59,127,39,41,38,127,54,62,54,127,62,71,62,127,23,29,23,127,25,31,25,127,25,31,25,127,25,31,25,127,15,20,15,127,0,1,0,127,0,0,0,127,102,115,102,127,105,118,105,127,105,118,105,127,105,118,105,127,105,118,105,127,81,90,81,127,1,1,1,127,0,0,0,127,61,47,21,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,103,79,34,127,12,9,4,127,0,0,0,127,47,52,47,127,93,104,93,127,8,9,8,127,0,0,0,127,52,40,17,127,121,92,40,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,77,59,26,127,0,0,0,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,63,49,21,127,105,81,35,127,122,94,41,127,122,94,41,127,122,94,41,127,100,76,33,127,0,0,0,127,9,11,9,127,101,113,101,127,105,118,105,127,105,118,105,127,105,118,105,127,0,0,0,127,0,0,0,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,69,53,23,127,0,0,0,127,0,0,0,32,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
[0,0,0,127,0,1,0,127,37,44,37,127,46,54,46,127,49,57,49,127,79,89,79,127,87,97,87,127,86,97,86,127,86,97,86,127,86,97,86,127,86,97,86,127,86,97,86,127,86,97,86,127,86,97,86,127,86,97,86,127,86,97,86,127,86,97,86,127,86,97,86,127,86,97,86,127,86,97,86,127,56,64,56,127,46,53,46,127,25,31,25,127,22,27,22,127,25,31,25,127,44,47,44,127,116,116,115,127,59,59,57,127,60,60,58,127,60,60,58,127,60,60,58,127,61,61,59,127,38,41,37,127,69,78,69,127,45,53,45,127,24,30,24,127,25,31,25,127,25,31,25,127,25,31,25,127,15,20,15,127,0,0,0,127,5,6,5,127,104,117,104,127,105,118,105,127,105,118,105,127,105,118,105,127,93,104,93,127,8,9,8,127,0,0,0,127,61,47,21,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,96,73,32,127,2,2,1,127,0,0,0,127,24,28,24,127,0,0,0,127,37,28,12,127,121,92,40,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,77,59,26,127,10,8,3,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,88,68,30,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,39,30,13,127,0,0,0,127,43,49,43,127,105,118,105,127,105,118,105,127,105,118,105,127,93,105,93,127,0,0,0,127,14,11,5,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,39,30,13,127,0,0,0,127,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
[0,0,0,64,0,1,0,127,21,25,21,127,48,57,49,127,82,92,82,127,87,97,87,127,86,97,86,127,86,97,86,127,86,97,86,127,86,97,86,127,86,97,86,127,86,97,86,127,86,97,86,127,86,97,86,127,86,97,86,127,86,97,86,127,86,97,86,127,87,97,87,127,87,98,87,127,60,69,60,127,43,50,43,127,29,36,29,127,25,31,25,127,25,31,25,127,25,31,25,127,25,31,25,127,116,116,116,127,71,71,70,127,60,60,58,127,60,60,58,127,60,60,58,127,62,62,60,127,30,32,29,127,75,85,75,127,29,36,29,127,25,31,25,127,24,30,24,127,24,30,24,127,23,28,23,127,10,14,10,127,0,0,0,127,40,45,40,127,105,118,105,127,105,118,105,127,105,118,105,127,105,118,105,127,33,38,33,127,0,0,0,127,39,30,13,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,67,52,23,127,0,0,0,127,0,0,0,127,10,8,3,127,113,87,38,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,107,82,36,127,84,65,28,127,71,54,24,127,115,88,38,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,67,51,22,127,16,12,5,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,121,92,40,127,122,94,41,127,122,94,41,127,122,94,41,127,105,81,35,127,2,2,1,127,0,0,0,127,0,0,0,127,18,21,18,127,61,69,61,127,102,115,102,127,92,103,92,127,0,0,0,127,16,12,5,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,60,46,20,127,52,40,17,127,69,53,23,127,86,66,29,127,10,8,3,127,0,0,0,127,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
[0,0,0,0,0,0,0,127,2,5,2,127,49,57,49,127,87,98,87,127,86,97,86,127,86,97,86,127,86,97,86,127,86,97,86,127,86,97,86,127,86,97,86,127,86,97,86,127,86,97,86,127,86,97,86,127,86,97,86,127,87,98,87,127,86,97,86,127,75,84,75,127,53,61,53,127,34,41,34,127,25,31,25,127,25,31,25,127,25,31,25,127,25,31,25,127,25,31,25,127,22,28,22,127,96,97,96,127,93,93,92,127,59,59,58,127,60,60,58,127,60,60,58,127,61,61,59,127,34,39,34,127,74,84,74,127,23,29,23,127,25,31,25,127,37,39,34,127,47,47,41,127,44,45,39,127,17,18,16,127,0,0,0,127,52,59,52,127,105,118,105,127,105,118,105,127,105,118,105,127,81,92,81,127,0,0,0,127,8,6,3,127,111,85,37,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,121,92,40,127,50,38,17,127,16,12,5,127,33,25,11,127,103,79,34,127,122,94,41,127,122,94,41,127,122,94,41,127,121,92,40,127,23,18,8,127,0,0,0,127,69,53,23,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,77,59,26,127,27,21,9,127,0,0,0,127,0,0,0,127,0,0,0,127,92,71,31,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,61,47,21,127,18,14,6,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,117,90,39,127,88,68,29,127,54,41,18,127,14,11,5,127,0,0,0,127,0,0,0,127,17,18,17,127,68,76,68,127,0,0,0,127,21,16,7,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,31,24,11,127,0,0,0,127,0,0,0,127,0,0,0,127,0,0,0,127,0,0,0,127,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
[0,0,0,0,0,0,0,95,0,0,0,127,37,43,37,127,89,100,89,127,86,97,86,127,86,97,86,127,86,97,86,127,86,97,86,127,86,97,86,127,86,97,86,127,86,97,86,127,87,97,87,127,88,99,88,127,82,92,82,127,61,69,61,127,36,42,36,127,27,32,27,127,23,29,23,127,23,29,23,127,25,31,25,127,25,31,25,127,25,31,25,127,25,31,25,127,25,31,25,127,23,29,23,127,78,80,76,127,102,102,102,127,58,58,57,127,60,60,58,127,60,60,58,127,58,58,56,127,40,47,40,127,56,64,56,127,24,29,23,127,44,45,40,127,49,49,43,127,49,49,43,127,46,46,41,127,41,42,37,127,0,0,0,127,38,43,38,127,105,118,105,127,105,118,105,127,105,118,105,127,33,37,33,127,0,0,0,127,61,47,21,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,77,59,26,127,0,0,0,127,0,0,0,127,0,0,0,127,12,9,4,127,113,87,38,127,122,94,41,127,122,94,41,127,122,94,41,127,84,65,28,127,4,3,2,127,115,88,38,127,122,94,41,127,122,94,41,127,122,94,41,127,121,92,40,127,42,33,14,127,0,0,0,127,119,91,40,127,102,78,34,127,75,57,25,127,52,40,17,127,88,68,29,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,61,47,21,127,31,24,11,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,121,92,40,127,84,65,28,127,19,15,7,127,0,0,0,127,4,5,4,127,0,0,0,127,31,24,11,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,111,85,37,127,115,88,38,127,122,94,41,127,122,94,41,127,48,37,16,127,0,0,0,127,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
[0,0,0,0,0,0,0,32,0,0,0,127,6,7,5,127,67,75,67,127,89,100,89,127,87,97,87,127,87,97,87,127,87,98,87,127,88,99,88,127,88,98,88,127,80,90,80,127,62,71,62,127,45,52,45,127,39,46,39,127,57,65,57,127,65,74,65,127,59,67,59,127,54,61,54,127,55,61,55,127,28,34,28,127,25,31,25,127,25,31,25,127,25,31,25,127,25,31,25,127,24,30,24,127,64,67,64,127,109,109,108,127,58,58,57,127,60,60,58,127,61,60,59,127,50,50,47,127,47,55,47,127,33,39,33,127,44,44,39,127,48,48,42,127,48,48,42,127,28,30,25,127,36,37,31,127,48,48,42,127,1,2,1,127,36,41,36,127,105,118,105,127,105,118,105,127,99,111,99,127,4,5,4,127,2,2,1,127,113,87,38,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,65,50,22,127,0,0,0,127,30,34,30,127,27,30,27,127,0,0,0,127,67,51,22,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,58,44,19,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,71,54,24,127,0,0,0,127,18,14,6,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,54,41,18,127,31,24,11,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,121,92,40,127,56,43,19,127,0,0,0,127,0,0,0,127,31,24,11,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,37,28,12,127,0,0,0,127,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
[0,0,0,0,0,0,0,0,0,0,0,95,0,0,0,127,2,3,2,127,28,32,28,127,58,65,58,127,56,64,56,127,50,57,50,127,46,54,46,127,42,49,42,127,43,50,43,127,62,71,62,127,80,90,80,127,87,98,87,127,87,98,87,127,87,97,87,127,87,98,87,127,86,97,87,127,78,85,78,127,46,52,46,127,24,30,24,127,25,31,25,127,25,31,25,127,25,31,25,127,24,30,24,127,64,67,64,127,104,104,104,127,58,58,57,127,60,60,58,127,62,61,60,127,34,38,33,127,37,43,37,127,50,51,44,127,48,48,42,127,48,48,42,127,23,27,22,127,32,36,30,127,95,95,82,127,43,45,39,127,0,0,0,127,45,51,45,127,105,118,105,127,105,118,105,127,71,80,71,127,0,0,0,127,35,27,12,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,103,79,35,127,2,2,1,127,0,0,0,127,11,13,11,127,0,0,0,127,65,50,22,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,121,92,40,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,23,18,8,127,0,0,0,127,35,27,12,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,46,36,16,127,41,31,14,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,119,91,40,127,37,28,12,127,50,38,17,127,73,56,24,127,107,82,36,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,69,53,23,127,0,0,0,127,44,34,15,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,27,21,9,127,0,0,0,127,0,0,0,64,0,0,0,64,0,0,0,64,0,0,0,0,0,0,0,0],
[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,64,0,0,0,127,0,0,0,127,0,0,0,127,0,0,0,127,0,0,0,127,8,10,8,127,51,59,51,127,84,95,84,127,87,98,87,127,86,97,86,127,86,97,86,127,86,97,86,127,86,97,86,127,86,97,86,127,86,97,86,127,86,97,87,127,63,71,63,127,23,29,23,127,25,31,25,127,25,31,25,127,25,31,25,127,23,29,23,127,76,78,75,127,100,100,99,127,58,58,57,127,61,60,59,127,53,54,51,127,24,30,24,127,29,33,28,127,77,76,63,127,47,48,42,127,29,32,27,127,24,30,24,127,30,35,29,127,90,91,84,127,28,29,25,127,0,0,0,127,77,86,76,127,105,118,105,127,105,118,105,127,44,50,44,127,0,0,0,127,69,53,23,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,81,62,27,127,4,3,2,127,0,0,0,127,12,9,4,127,107,82,36,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,4,3,2,127,0,0,0,127,54,41,18,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,46,36,16,127,46,36,16,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,100,76,33,127,0,0,0,127,0,0,0,127,0,0,0,127,0,0,0,127,48,37,16,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,42,33,14,127,46,36,16,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,16,12,5,127,0,0,0,127,0,0,0,127,4,3,2,127,6,5,2,127,0,0,0,95,0,0,0,0],
[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,64,0,0,0,64,0,0,0,95,1,1,1,127,60,68,60,127,87,98,87,127,86,97,86,127,86,97,86,127,86,97,86,127,86,97,86,127,86,97,86,127,86,97,86,127,86,97,86,127,87,97,87,127,73,82,73,127,24,30,24,127,25,31,25,127,25,31,25,127,25,31,25,127,22,28,22,127,89,92,89,127,87,87,86,127,59,59,58,127,60,59,58,127,31,35,31,127,25,31,25,127,43,45,38,127,74,74,62,127,43,43,38,127,22,28,22,127,25,31,25,127,24,30,24,127,26,32,26,127,13,14,12,127,0,0,0,127,100,113,100,127,105,118,105,127,105,118,105,127,21,24,21,127,0,0,0,127,98,75,33,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,113,87,38,127,92,71,31,127,117,90,39,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,19,15,7,127,0,0,0,127,71,54,24,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,39,30,13,127,50,38,17,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,82,63,28,127,0,0,0,127,23,26,23,127,38,42,38,127,5,7,5,127,0,0,0,127,96,73,32,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,111,85,37,127,54,41,18,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,82,63,28,127,16,12,5,127,16,12,5,127,16,12,5,127,12,9,4,127,46,35,16,127,82,63,28,127,117,90,39,127,46,36,16,127,0,0,0,127,0,0,0,0],
[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,32,0,0,0,127,33,38,33,127,89,99,89,127,86,97,86,127,86,97,86,127,86,97,86,127,86,97,86,127,86,97,86,127,86,97,86,127,86,97,86,127,86,97,86,127,84,94,84,127,28,35,28,127,25,31,25,127,25,31,25,127,25,31,25,127,22,28,22,127,100,101,100,127,73,73,71,127,61,60,59,127,35,38,35,127,24,30,24,127,24,30,24,127,48,51,41,127,69,69,57,127,36,37,32,127,24,30,24,127,28,34,28,127,25,31,25,127,25,31,25,127,17,21,17,127,0,0,0,127,80,90,80,127,105,118,105,127,105,118,105,127,6,7,6,127,0,0,0,127,115,88,38,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,56,43,19,127,0,0,0,127,88,68,29,127,117,90,39,127,107,82,36,127,92,71,31,127,80,62,27,127,69,53,23,127,60,46,20,127,46,36,16,127,33,25,11,127,23,18,8,127,4,3,2,127,61,47,21,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,65,50,22,127,0,0,0,127,20,22,20,127,26,30,26,127,0,0,0,127,2,2,1,127,109,84,36,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,100,76,33,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,77,59,26,127,21,16,7,127,60,46,20,127,94,72,31,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,54,41,18,127,0,0,0,127,0,0,0,0],
[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,95,6,7,6,127,81,91,81,127,86,97,86,127,86,97,86,127,86,97,86,127,86,97,86,127,86,97,86,127,86,97,86,127,86,97,86,127,86,97,86,127,88,98,88,127,60,68,60,127,27,33,27,127,24,30,24,127,25,31,25,127,22,28,22,127,91,91,91,127,57,58,56,127,31,36,31,127,24,30,24,127,25,31,25,127,25,31,25,127,27,31,26,127,70,71,58,127,41,42,36,127,37,43,37,127,66,74,66,127,23,29,23,127,25,31,25,127,19,22,19,127,0,0,0,127,75,84,75,127,105,118,105,127,102,114,102,127,0,0,0,127,4,3,2,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,117,90,39,127,31,24,10,127,2,2,1,127,0,0,0,127,0,0,0,127,0,0,0,127,0,0,0,127,0,0,0,127,0,0,0,127,0,0,0,127,0,0,0,127,0,0,0,127,4,3,2,127,61,47,21,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,46,36,16,127,0,0,0,127,0,0,0,127,0,0,0,127,8,6,3,127,73,56,24,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,121,92,40,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,61,47,21,127,0,0,0,127,0,0,0,0],
[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,32,0,0,0,127,45,52,45,127,87,98,88,127,86,97,86,127,86,97,86,127,86,97,86,127,86,97,86,127,86,97,86,127,86,97,86,127,86,97,86,127,86,97,86,127,82,92,82,127,46,54,46,127,34,41,34,127,25,31,25,127,25,31,25,127,26,30,26,127,24,30,24,127,25,31,25,127,25,31,25,127,25,31,25,127,25,31,25,127,24,30,24,127,33,37,31,127,48,48,42,127,43,43,38,127,66,74,65,127,23,29,23,127,25,31,25,127,20,25,20,127,0,0,0,127,70,78,70,127,105,118,105,127,92,103,92,127,0,0,0,127,16,12,5,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,86,66,29,127,48,37,16,127,31,24,11,127,16,12,5,127,23,18,8,127,33,25,11,127,52,40,17,127,71,54,24,127,96,73,32,127,117,90,39,127,63,49,21,127,73,56,24,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,88,68,29,127,77,59,26,127,77,59,26,127,90,69,30,127,117,90,39,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,73,56,24,127,0,0,0,127,0,0,0,32],
[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,95,25,28,25,127,88,99,88,127,86,97,86,127,86,97,86,127,86,97,86,127,86,97,86,127,86,97,86,127,86,97,86,127,86,97,86,127,87,98,87,127,70,79,70,127,46,54,46,127,47,55,47,127,45,52,45,127,30,37,30,127,25,31,25,127,25,31,25,127,25,31,25,127,25,31,25,127,25,31,25,127,25,31,25,127,25,31,25,127,24,30,24,127,44,52,44,127,72,81,72,127,70,79,70,127,23,29,23,127,25,31,25,127,21,25,21,127,0,0,0,127,66,73,65,127,105,118,105,127,92,103,92,127,0,0,0,127,16,12,5,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,80,62,27,127,77,59,26,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,77,59,26,127,0,0,0,127,0,0,0,64],
[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,32,0,1,0,127,64,72,64,127,87,97,87,127,86,97,86,127,86,97,86,127,87,97,87,127,86,97,86,127,86,96,86,127,85,95,85,127,71,80,71,127,47,55,47,127,46,54,46,127,46,54,46,127,46,54,46,127,47,55,47,127,31,38,31,127,25,31,25,127,25,31,25,127,25,31,25,127,25,31,25,127,25,31,25,127,25,31,25,127,23,29,23,127,59,67,59,127,77,87,77,127,58,66,58,127,25,31,25,127,25,31,25,127,22,27,22,127,0,0,0,127,48,54,48,127,105,118,105,127,92,103,92,127,0,0,0,127,16,12,5,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,98,75,33,127,80,62,27,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,92,71,31,127,0,0,0,127,0,0,0,64],
[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,127,14,16,14,127,88,99,88,127,88,98,88,127,88,98,88,127,72,82,72,127,51,59,51,127,52,61,52,127,55,63,55,127,47,55,47,127,45,53,45,127,45,53,45,127,46,54,46,127,46,54,46,127,46,54,46,127,45,53,45,127,25,31,25,127,25,31,25,127,25,31,25,127,25,31,25,127,25,31,25,127,25,31,25,127,25,31,25,127,25,31,25,127,37,44,37,127,76,86,76,127,73,82,73,127,32,39,32,127,23,29,23,127,2,2,2,127,30,34,30,95,105,118,105,64,98,111,98,64,0,0,0,95,4,3,2,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,115,88,38,127,92,71,31,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,119,91,40,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,98,75,33,127,0,0,0,127,0,0,0,64],
[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,127,21,24,21,127,55,62,55,127,51,57,50,127,64,72,64,127,86,96,86,127,85,95,85,127,84,94,84,127,86,96,86,127,84,95,84,127,82,92,82,127,75,85,75,127,52,60,52,127,46,54,46,127,46,54,46,127,45,53,45,127,26,32,26,127,25,31,25,127,25,31,25,127,25,31,25,127,25,31,25,127,25,31,25,127,29,36,29,127,28,34,28,127,24,30,24,127,62,71,62,127,88,99,88,127,66,75,66,127,24,30,24,127,8,11,8,127,0,0,0,64,0,0,0,0,0,0,0,0,0,0,0,64,0,0,0,127,105,81,35,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,98,75,33,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,121,92,40,127,100,76,33,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,107,82,36,127,0,0,0,127,0,0,0,64],
[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,64,0,0,0,127,31,36,31,127,35,40,35,127,33,36,32,127,31,34,31,127,47,55,47,127,51,59,51,127,47,55,47,127,39,46,39,127,29,36,29,127,37,43,37,127,52,60,52,127,77,87,77,127,49,58,49,127,46,54,46,127,40,48,40,127,24,30,24,127,25,31,25,127,25,31,25,127,25,31,25,127,25,31,25,127,29,35,29,127,80,90,80,127,59,67,59,127,24,30,24,127,24,30,24,127,76,86,76,127,87,98,87,127,39,46,39,127,17,22,17,127,0,0,0,127,0,0,0,0,0,0,0,0,0,0,0,32,0,0,0,127,75,57,25,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,79,60,26,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,113,87,38,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,71,55,24,127,103,79,35,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,117,90,39,127,0,0,0,127,0,0,0,64],
[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,127,41,48,41,127,69,79,69,127,39,45,39,127,47,54,47,127,77,87,77,127,86,97,86,127,88,97,87,127,87,97,86,127,82,93,83,127,57,65,57,127,25,31,25,127,24,30,24,127,26,32,26,127,26,32,26,127,26,32,26,127,25,31,25,127,25,31,25,127,25,31,25,127,25,31,25,127,25,31,25,127,75,85,75,127,87,98,87,127,67,75,67,127,23,29,23,127,23,29,23,127,56,64,56,127,85,95,85,127,75,84,75,127,24,30,24,127,3,3,3,127,0,0,0,64,0,0,0,0,0,0,0,0,0,0,0,127,29,22,10,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,119,91,40,127,8,6,3,127,109,84,36,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,119,91,40,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,98,75,33,127,6,5,2,127,107,82,36,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,0,0,0,127,0,0,0,64],
[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,64,0,0,0,127,12,15,12,127,45,53,46,127,48,56,48,127,65,72,63,127,98,81,79,127,123,119,119,127,117,108,108,127,94,79,76,127,88,88,80,127,64,73,64,127,24,30,24,127,25,31,25,127,25,31,25,127,25,31,25,127,25,31,25,127,25,31,25,127,25,31,25,127,25,31,25,127,35,41,35,127,86,96,86,127,87,98,87,127,61,69,61,127,23,29,23,127,24,30,24,127,46,53,46,127,84,94,84,127,87,98,87,127,55,63,55,127,10,12,10,127,0,0,0,95,0,0,0,0,0,0,0,0,0,0,0,64,0,0,0,127,92,71,31,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,75,57,25,127,0,0,0,127,52,40,17,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,98,75,33,127,12,9,4,127,0,0,0,127,109,84,36,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,14,11,5,127,0,0,0,95],
[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,64,0,0,0,127,22,26,22,127,30,37,30,127,23,29,23,127,41,40,35,127,91,73,72,127,113,103,103,127,100,75,75,127,87,58,58,127,83,72,66,127,54,63,55,127,23,29,23,127,25,31,25,127,25,31,25,127,25,31,25,127,25,31,25,127,25,31,25,127,25,30,25,127,34,41,34,127,69,78,69,127,81,91,81,127,34,41,34,127,25,31,25,127,23,29,23,127,61,69,61,127,82,92,82,127,75,85,75,127,82,92,82,127,24,29,24,127,1,1,1,127,0,0,0,32,0,0,0,0,0,0,0,0,0,0,0,127,23,18,8,127,119,91,40,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,121,92,40,127,17,14,6,127,0,0,0,127,2,2,1,127,96,73,32,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,75,58,25,127,6,5,2,127,0,0,0,127,0,0,0,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,18,14,6,127,0,0,0,127],
[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,32,0,0,0,127,24,29,24,127,48,56,48,127,28,34,28,127,24,30,24,127,25,31,25,127,36,37,32,127,68,55,52,127,82,63,62,127,80,52,52,127,81,82,74,127,28,34,28,127,25,31,25,127,25,31,25,127,25,31,25,127,25,31,25,127,25,31,25,127,25,31,25,127,24,30,24,127,23,29,23,127,25,31,25,127,24,30,24,127,25,31,25,127,24,29,24,127,56,64,56,127,87,97,87,127,70,79,70,127,88,99,88,127,49,57,49,127,10,12,10,127,0,0,0,95,0,0,0,0,0,0,0,0,0,0,0,32,0,0,0,127,44,34,15,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,67,52,23,127,0,0,0,127,0,0,0,95,0,0,0,127,12,9,4,127,109,84,36,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,100,76,33,127,33,25,11,127,0,0,0,127,0,0,0,127,0,0,0,95,0,0,0,127,107,82,36,127,117,90,39,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,31,24,11,127,0,0,0,127],
[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,95,14,16,14,127,81,91,81,127,72,81,72,127,43,51,43,127,23,29,23,127,24,30,24,127,23,30,24,127,23,30,23,127,25,31,25,127,26,31,25,127,25,31,25,127,25,31,25,127,25,31,25,127,25,31,25,127,25,31,25,127,25,31,25,127,25,31,25,127,26,32,26,127,32,39,32,127,30,37,30,127,24,30,24,127,25,31,25,127,25,31,25,127,25,32,25,127,83,93,83,127,77,86,77,127,87,97,87,127,80,90,80,127,22,27,22,127,1,1,1,127,0,0,0,32,0,0,0,0,0,0,0,0,0,0,0,64,0,0,0,127,46,35,15,127,121,92,40,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,96,73,32,127,4,3,2,127,0,0,0,95,0,0,0,0,0,0,0,32,0,0,0,127,12,9,4,127,98,75,33,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,96,73,32,127,40,31,14,127,2,2,1,127,0,0,0,127,0,0,0,64,0,0,0,0,0,0,0,32,0,0,0,127,0,0,0,127,0,0,0,127,2,2,1,127,16,12,5,127,25,19,9,127,33,25,11,127,46,36,16,127,56,43,19,127,61,47,21,127,77,59,26,127,84,65,28,127,92,71,31,127,107,82,36,127,115,88,38,127,122,94,41,127,122,94,41,127,39,30,13,127,0,0,0,127],
[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,32,0,0,0,127,18,21,18,127,83,93,83,127,89,100,89,127,71,81,71,127,54,61,54,127,37,44,37,127,24,30,24,127,23,29,23,127,25,31,25,127,25,31,25,127,25,31,25,127,25,31,25,127,25,31,25,127,25,31,25,127,25,31,25,127,24,30,24,127,42,50,42,127,70,79,70,127,87,98,87,127,74,83,74,127,28,35,28,127,25,31,25,127,24,30,24,127,42,49,42,127,76,86,76,127,86,97,86,127,88,99,88,127,41,49,41,127,11,14,11,127,0,0,0,95,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,64,0,0,0,127,27,21,9,127,105,81,35,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,98,75,33,127,12,9,4,127,0,0,0,95,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,32,0,0,0,127,2,2,1,127,58,44,19,127,113,87,38,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,105,81,35,127,63,49,21,127,21,16,7,127,0,0,0,127,0,0,0,127,0,0,0,64,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,32,0,0,0,64,0,0,0,64,0,0,0,64,0,0,0,127,0,0,0,127,0,0,0,127,0,0,0,127,0,0,0,127,0,0,0,127,0,0,0,127,0,0,0,127,0,0,0,127,0,0,0,127,0,0,0,127,0,0,0,127,16,12,5,127,6,5,2,127,0,0,0,95],
[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,32,0,0,0,127,13,17,13,127,61,70,61,127,85,96,85,127,89,100,89,127,88,98,88,127,77,87,77,127,60,67,60,127,26,32,26,127,25,31,25,127,25,31,25,127,25,31,25,127,25,31,25,127,25,31,25,127,25,31,25,127,25,31,25,127,12,16,12,127,12,15,12,127,40,46,40,127,80,90,80,127,80,89,80,127,34,40,34,127,24,30,24,127,23,29,23,127,51,59,51,127,88,99,88,127,86,97,86,127,76,85,76,127,22,27,22,127,1,2,1,127,0,0,0,32,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,32,0,0,0,127,4,3,2,127,59,46,20,127,111,85,37,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,119,91,40,127,65,50,22,127,4,3,2,127,0,0,0,127,0,0,0,32,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,95,0,0,0,127,4,3,2,127,44,34,15,127,80,62,27,127,111,85,37,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,122,94,41,127,121,92,40,127,100,76,33,127,75,57,25,127,48,37,16,127,18,13,6,127,0,0,0,127,0,0,0,127,0,0,0,127,0,0,0,64,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,64,0,0,0,64,0,0,0,64,0,0,0,64,0,0,0,64,0,0,0,64,0,0,0,127,0,0,0,64,0,0,0,0],
[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,64,0,0,0,127,19,23,19,127,46,53,46,127,64,72,64,127,80,90,80,127,85,96,85,127,74,84,74,127,28,34,28,127,25,31,25,127,25,31,25,127,25,30,25,127,25,31,25,127,25,31,25,127,25,31,25,127,17,21,17,127,1,3,1,127,0,1,0,127,0,0,0,127,9,11,9,127,51,59,52,127,82,93,83,127,45,52,45,127,23,29,23,127,24,30,24,127,59,67,59,127,88,99,88,127,85,96,85,127,30,37,30,127,12,15,12,127,0,0,0,95,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,32,0,0,0,95,0,0,0,127,4,3,2,127,42,33,14,127,82,63,28,127,107,82,36,127,103,79,35,127,84,65,28,127,54,41,18,127,12,9,4,127,0,0,0,127,0,0,0,95,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,32,0,0,0,95,0,0,0,127,0,0,0,127,0,0,0,127,10,8,3,127,25,19,9,127,31,24,11,127,31,24,11,127,31,24,11,127,31,24,11,127,18,14,6,127,35,27,12,127,105,81,35,127,80,62,27,127,54,41,18,127,29,22,10,127,6,5,2,127,0,0,0,127,0,0,0,127,0,0,0,127,0,0,0,95,0,0,0,64,0,0,0,32,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,32,0,0,0,127,8,10,8,127,33,39,33,127,44,51,44,127,46,53,46,127,44,52,44,127,39,46,39,127,25,30,25,127,25,31,25,127,25,31,25,127,24,30,24,127,15,19,15,127,5,7,5,127,0,1,0,127,0,0,0,127,0,0,0,95,0,0,0,64,0,0,0,64,0,1,0,127,21,24,21,127,66,74,66,127,57,66,57,127,24,30,24,127,23,29,23,127,52,60,52,127,40,47,40,127,24,30,24,127,23,28,23,127,1,2,1,127,0,0,0,32,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,32,0,0,0,95,0,0,0,127,0,0,0,127,0,0,0,127,0,0,0,127,0,0,0,127,0,0,0,127,0,0,0,95,0,0,0,32,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,32,0,0,0,64,0,0,0,95,0,0,0,127,0,0,0,127,0,0,0,127,0,0,0,127,0,0,0,127,0,0,0,127,0,0,0,127,0,0,0,127,0,0,0,127,0,0,0,127,0,0,0,127,0,0,0,64,0,0,0,64,0,0,0,32,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,32,0,0,0,95,0,0,0,127,11,13,11,127,23,28,23,127,33,39,33,127,36,43,36,127,23,29,23,127,20,26,20,127,11,15,11,127,3,4,3,127,0,1,0,127,0,0,0,127,0,0,0,95,0,0,0,32,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,32,0,0,0,95,3,5,3,127,37,41,37,127,58,66,58,127,27,33,27,127,24,30,24,127,26,32,26,127,25,31,25,127,25,31,25,127,8,9,8,127,0,0,0,64,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,64,0,0,0,64,0,0,0,64,0,0,0,64,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,64,0,0,0,64,0,0,0,32,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,32,0,0,0,95,0,0,0,127,0,0,0,127,0,0,0,127,0,1,0,127,0,0,0,127,0,0,0,127,0,0,0,127,0,0,0,64,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,32,0,0,0,127,12,15,12,127,42,49,42,127,32,39,32,127,24,30,24,127,25,31,25,127,25,31,25,127,18,22,18,127,0,0,0,127,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,64,0,0,0,64,0,0,0,64,0,0,0,64,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,64,2,2,2,127,23,27,23,127,37,43,37,127,26,33,26,127,25,31,25,127,24,30,24,127,4,4,4,127,0,0,0,32,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,32,0,0,0,95,4,5,4,127,24,28,23,127,29,35,29,127,25,31,25,127,12,16,12,127,0,0,0,95,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,32,0,0,0,95,4,4,4,127,11,14,11,127,16,20,16,127,0,0,0,127,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,32,0,0,0,64,0,0,0,127,0,0,0,32,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]])
def __init__(self, parent, title):
"""Constructor.
@param title Header title.
"""
Decorator.__init__(self, parent)
self.title = title
self.border = 10
return
def draw(self, screenRectangle):
rect = screenRectangle[:]
rect[0] += self.border
rect[1] += self.border
rect[2] -= self.border
rect[3] -= self.border
# title
glColor3ub(210, 236, 210)
glRecti(rect[0],rect[3]-41,rect[2],rect[3]-17)
glColor3ub(50, 62, 50)
glRasterPos2i(rect[0]+126, rect[3]-34)
Blender.Draw.Text(self.title)
glRasterPos2i(rect[0]+127, rect[3]-34)
Blender.Draw.Text(self.title)
# logo
glRasterPos2i(rect[0]+1, rect[3]-48)
glEnable(GL_BLEND)
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)
glDrawPixels(122, 48, GL_RGBA, GL_BYTE, OgreFrame.OGRE_LOGO)
rect[3] -= 48 + self.border
glDisable(GL_BLEND)
# child
self.childWidget.draw(rect)
return
def getSize(self):
width = 2*self.border + Blender.Draw.GetStringWidth(self.title) + 85
height = 48 + 3*self.border
minSize = self.childWidget.getSize().getMinimumSize()[:]
minSize[0] += 2*self.border
minSize[1] += 3*self.border + 48
if minSize[0] < width:
minSize[0] = width
if minSize[1] < height:
minSize[1] = height
prefSize = self.childWidget.getSize().getPreferredSize()[:]
prefSize[0] += 2*self.border
prefSize[1] += 3*self.border + 48
if prefSize[0] < width:
prefSize[0] = width
if prefSize[1] < height:
prefSize[1] = height
maxSize = self.childWidget.getSize().getMaximumSize()[:]
return Size(prefSize, minSize, maxSize)
class DirectionalLayout(Widget):
"""Common layout functionality for horizontal and vertical layout.
"""
def __init__(self, parent):
"""Constructor.
"""
Widget.__init__(self, parent, Size([0, 0]))
self.widgetList = []
return
def resize(self, size=None):
self.size = Size([0, 0])
for widget in self.widgetList:
self._addWidgetSize(widget)
self.parent.resize()
return
def eventFilter(self, event, value):
for widget in self.widgetList:
widget.eventFilter(event, value)
return
def _addWidget(self, widget):
"""Adds a child widget to this layout.
The child widget is appended below all other widgets. This
method gets called by the constructor of the child widget.
"""
self.widgetList.append(widget)
self._addWidgetSize(widget)
self.parent.resize()
return
def _removeWidget(self, widget):
"""Removes a child widget from this layout.
This method gets called by the removeFromParent()
method of the corresponding child widget.
"""
if widget in self.widgetList:
self.widgetList.remove(widget)
self.resize()
return
def _addWidgetSize(self, widget):
raise NotImplementedError
return
class HorizontalLayout(DirectionalLayout):
"""Widget that manages horizontally stacked child widgets.
"""
def draw(self, screenRectangle):
# split height for the child widgets
minimumSize = self.size.getMinimumSize()
width = screenRectangle[2]- screenRectangle[0]
additionalWidth = width - minimumSize[0]
stretchWidgetList = []
extraWidth = 0
# get widgets with unlimited preferred height
if (additionalWidth > 0):
stretchWidgetList = [w for w in self.widgetList if w.getSize().getPreferredSize()[0] >= Size.INFINITY]
if (len(stretchWidgetList) > 0):
# give equal extra height to widgets with unlimited preferred height
extraWidth = additionalWidth / len(stretchWidgetList)
# draw widgets with minimum or minimum plus extra size
x = screenRectangle[0]
dx = 0
for widget in self.widgetList:
dx = widget.getSize().getMinimumSize()[0]
if (widget in stretchWidgetList):
dx += extraWidth
widget.draw([x, screenRectangle[1], x+dx, screenRectangle[3]])
x += dx
return
def _addWidgetSize(self, widget):
"""Adds size of a widget but does not notify parent.
"""
wMinSize = widget.getSize().getMinimumSize()
wMaxSize = widget.getSize().getMaximumSize()
wPrefSize = widget.getSize().getPreferredSize()
minSize = self.getSize().getMinimumSize()
maxSize = self.getSize().getMaximumSize()
prefSize = self.getSize().getPreferredSize()
# add in x direction
minSize[0] += wMinSize[0]
maxSize[0] += wMaxSize[0]
if (prefSize[0] < Size.INFINITY):
if (wPrefSize[0] < Size.INFINITY):
prefSize[0] += wPrefSize[0]
else:
prefSize[0] = Size.INFINITY
# maximum in y direction
if (wMinSize[1] > minSize[1]):
minSize[1] = wMinSize[1]
if (wPrefSize[1] > prefSize[1]):
prefSize[1] = wPrefSize[1]
if (wMaxSize[1] > maxSize[1]):
maxSize[1] = wMaxSize[1]
self.size = Size(prefSize, minSize, maxSize)
return
class VerticalLayout(DirectionalLayout):
"""Widget that manages vertically stacked child widgets.
"""
def draw(self, screenRectangle):
# split height for the child widgets
minimumSize = self.getSize().getMinimumSize()
height = screenRectangle[3]- screenRectangle[1]
additionalHeight = height - minimumSize[1]
stretchWidgetList = []
extraHeight = 0
# get widgets with unlimited preferred height
if (additionalHeight > 0):
stretchWidgetList = [w for w in self.widgetList if w.getSize().getPreferredSize()[1] >= Size.INFINITY]
if (len(stretchWidgetList) > 0):
# give equal extra height to widgets with unlimited preferred height
extraHeight = additionalHeight / len(stretchWidgetList)
# draw widgets with minimum or minimum plus extra size
y = screenRectangle[3]
dy = 0
for widget in self.widgetList:
dy = widget.getSize().getMinimumSize()[1]
if (widget in stretchWidgetList):
dy += extraHeight
widget.draw([screenRectangle[0], y-dy, screenRectangle[2], y])
y -= dy
return
def _addWidgetSize(self, widget):
"""Adds size of a widget but does not notify parent.
"""
wMinSize = widget.getSize().getMinimumSize()
wMaxSize = widget.getSize().getMaximumSize()
wPrefSize = widget.getSize().getPreferredSize()
minSize = self.getSize().getMinimumSize()
maxSize = self.getSize().getMaximumSize()
prefSize = self.getSize().getPreferredSize()
# add in y direction
minSize[1] += wMinSize[1]
maxSize[1] += wMaxSize[1]
if (prefSize[1] < Size.INFINITY):
if (wPrefSize[1] < Size.INFINITY):
prefSize[1] += wPrefSize[1]
else:
prefSize[1] = Size.INFINITY
# maximum in x direction
if (wMinSize[0] > minSize[0]):
minSize[0] = wMinSize[0]
if (wPrefSize[0] > prefSize[0]):
prefSize[0] = wPrefSize[0]
if (wMaxSize[0] > maxSize[0]):
maxSize[0] = wMaxSize[0]
self.size = Size(prefSize, minSize, maxSize)
return
class AlternativesLayout(Widget):
"""Displays one widget out of a given set of alternatives.
"""
def __init__(self, parent):
"""Constructor.
"""
Widget.__init__(self, parent, Size())
self.widgetList = []
self.current = None
return
def getCurrent(self):
"""Returns name of current choosen widget.
"""
return self.current
def setCurrent(self, widget):
"""Sets current active widget to alternative called name.
@param widget A previously added widget or None
.
"""
if widget is None:
self.current = None
self.size = Size()
self.parent.resize()
elif widget in self.widgetList:
self.current = widget
self.size = widget.getSize()
self.parent.resize()
return
def removeAll(self):
self.setCurrent(None)
self.widgetList = []
return
def draw(self, screenRectangle):
if self.current:
self.current.draw(screenRectangle)
return
def eventFilter(self, event, value):
if self.current:
self.current.eventFilter(event, value)
return
def _addWidget(self, widget):
"""Adds a child widget to this layout.
The child widget is appended below all other widgets. This
method gets called by the constructor of the child widget.
"""
self.widgetList.append(widget)
return
def _removeWidget(self, widget):
"""Removes a child widget from this layout.
This method gets called by the removeFromParent()
method of the corresponding child widget.
"""
if widget in self.widgetList:
if (widget == self.current):
self.setCurrent(None)
self.widgetList.remove(widget)
return
class WidgetListLayout(Widget):
"""Displays a list of vertically stacked widgets using a scrollbar if necessary.
"""
def __init__(self, parent, size, scrollbarWidth=20):
"""Constructor.
@param size Minimum size should exceed 3*scrollbarWidth in both directions
"""
Widget.__init__(self, parent, size)
# mousewheel scrolling
self.listRect = [0, 0, 0, 0]
# list of child widgets
self.widgetList = []
# list of current displayed widgets
self.visibleList = []
# parent to register buttons to.
self.boundedRange = BoundedRangeModel()
self.scrollbarWidth = scrollbarWidth
self.scrollbar = VerticalScrollbar(WidgetListLayout.Mediator(self), Size([self.scrollbarWidth, self.scrollbarWidth]), self.boundedRange)
# mousewheel scrolling
self.mouseFocusX = 0
self.mouseFocusY = 0
# unused widget space
self.remainingHeight = 0
self.autoScroll = False
return
def setAutoScroll(self, autoScroll=True):
"""Scroll to newly added widgets.
"""
self.autoScroll = autoScroll
return
def _addWidget(self, widget):
self.widgetList.append(widget)
self.boundedRange.setMaximum(self.boundedRange.getMaximum() + 1)
if self.autoScroll:
# scroll into visible area
# Avoid call to Blender.Draw.Draw() to get the current
# scrollbar extend, as widget may be disabled
if( widget.getSize().getMinimumSize()[1] > self.remainingHeight):
self.boundedRange.setValue(self.boundedRange.getMaximum() - self.boundedRange.getExtend())
return
def _removeWidget(self, widget):
if widget in self.widgetList:
if widget in self.visibleList:
self.visibleList.remove(widget)
self.widgetList.remove(widget)
self.boundedRange.setMaximum(self.boundedRange.getMaximum() - 1)
return
def removeAll(self):
self.widgetList = []
self.boundedRangeModel = BoundedRangeModel()
return
def draw(self, rect):
self.listRect = [rect[0] + 2, rect[1] + 2, rect[2] - self.scrollbarWidth - 2, rect[3] - 2]
remainingHeight = self.listRect[3] - self.listRect[1]
# Box
glColor3f(0.0, 0.0, 0.0)
glBegin(GL_LINE_STRIP)
glVertex2i(rect[0], rect[3])
glVertex2i(rect[2], rect[3])
glVertex2i(rect[2], rect[1])
glVertex2i(rect[0], rect[1])
glVertex2i(rect[0], rect[3])
glEnd()
# Widgets
self.visibleList = []
if len(self.widgetList):
listIndex = self.boundedRange.getValue()
widgetRect = self.listRect[:]
while ((listIndex < len(self.widgetList)) \
and (remainingHeight >= self.widgetList[listIndex].getSize().getMinimumSize()[1])):
widgetRect[3] = self.listRect[1] + remainingHeight
remainingHeight -= self.widgetList[listIndex].getSize().getMinimumSize()[1]
widgetRect[1] = self.listRect[1] + remainingHeight
self.widgetList[listIndex].draw(widgetRect)
self.visibleList.append(self.widgetList[listIndex])
listIndex += 1
self.boundedRange.setExtend(len(self.visibleList), 1)
# Scrollbar
self.scrollbar.draw([rect[2]-self.scrollbarWidth-1, rect[1]+1, rect[2]-1, rect[3]-1])
self.remainingHeight = remainingHeight
return
def eventFilter(self, event, value):
for widget in self.visibleList:
widget.eventFilter(event, value)
# mousewheel scrolling
if (event == Blender.Draw.MOUSEX):
mousePositionX = value - ScreenManager.getSingleton().getScissorRectangle()[0]
if (mousePositionX >= self.listRect[0]) and (mousePositionX <= self.listRect[2]):
self.mouseFocusX = 1
else:
self.mouseFocusX = 0
elif (event == Blender.Draw.MOUSEY):
mousePositionY = value - ScreenManager.getSingleton().getScissorRectangle()[1]
if (mousePositionY >= self.listRect[1]) and (mousePositionY <= self.listRect[3]):
self.mouseFocusY = 1
else:
self.mouseFocusY = 0
elif (event == Blender.Draw.WHEELUPMOUSE) \
and self.mouseFocusX and self.mouseFocusY:
self.scrollbar._dec(1)
elif (event == Blender.Draw.WHEELDOWNMOUSE) \
and self.mouseFocusX and self.mouseFocusY:
self.scrollbar._inc(1)
# scrollbar
self.scrollbar.eventFilter(event, value)
return
class Mediator(Widget):
def __init__(self, parent):
self.parent = parent
return
def resize(self, size=None):
self.parent.resize()
return
def _addWidget(self, widget):
return
def _removeWidget(self, widget):
return
def _addButtonAction(self, action):
return self.parent._addButtonAction(action)
def _removeButtonAction(self, eventNumber):
self.parent._removeButtonAction(eventNumber)
return
class AddWidgetListLayout(WidgetListLayout):
"""WidgetList with an additional button in the last row.
The first widget added to this layout is used as add-button. The
add-button is not specified in the constructor in order to not
complicate a reference from the button action to the parent layout.
"""
def __init__(self, parent, size, scrollbarWidth=20):
"""Constructor.
"""
WidgetListLayout.__init__(self, parent, size, scrollbarWidth)
# additional button
self.addButton = None
return
def removeAll(self):
"""Remove all widgets but the add-button.
"""
self.widgetList = []
self.boundedRangeModel = BoundedRangeModel(0, 0, 0, 1)
return
def draw(self, rect):
self.listRect = [rect[0] + 2, rect[1] + 2, rect[2] - self.scrollbarWidth - 2, rect[3] - 2]
self.visibleList = []
remainingHeight = self.listRect[3] - self.listRect[1]
widgetRect = self.listRect[:]
if len(self.widgetList):
listIndex = self.boundedRange.getValue()
while ((listIndex < len(self.widgetList)) \
and (remainingHeight >= self.widgetList[listIndex].getSize().getMinimumSize()[1])):
widgetRect[3] = self.listRect[1] + remainingHeight
remainingHeight -= self.widgetList[listIndex].getSize().getMinimumSize()[1]
widgetRect[1] = self.listRect[1] + remainingHeight
self.widgetList[listIndex].draw(widgetRect)
self.visibleList.append(self.widgetList[listIndex])
listIndex += 1
self.boundedRange.setExtend(len(self.visibleList), 1)
# add button
if remainingHeight >= self.addButton.getSize().getMinimumSize()[1]:
# draw button
widgetRect[3] = self.listRect[1] + remainingHeight
remainingHeight -= self.addButton.getSize().getMinimumSize()[1]
widgetRect[1] = self.listRect[1] + remainingHeight
widgetRect[2] = widgetRect[0] + self.addButton.getSize().getMinimumSize()[0]
self.addButton.draw(widgetRect)
self.boundedRange.setExtend(self.boundedRange.getExtend() + 1, 1)
# Scrollbar
self.scrollbar.draw([rect[2]-self.scrollbarWidth-1, rect[1]+1, rect[2]-1, rect[3]-1])
self.remainingHeight = remainingHeight
return
def _addWidget(self, widget):
if self.addButton:
self.widgetList.append(widget)
self.boundedRange.setMaximum(self.boundedRange.getMaximum() + 1)
# scroll into visible area
# Avoid call to Blender.Draw.Draw() to get the current
# scrollbar extend, as widget may be disabled
if self.autoScroll:
if((widget.getSize().getMinimumSize()[1] + self.addButton.getSize().getMinimumSize()[1]) > self.remainingHeight):
self.boundedRange.setValue(self.boundedRange.getMaximum() - self.boundedRange.getExtend())
else:
self.addButton = widget
self.boundedRange.setMaximum(self.boundedRange.getMaximum() + 1)
return
class LogView(Decorator, View):
"""Shows the log messages.
"""
_COLOR = {Log.INFO:[0.0, 0.0, 0.0], Log.WARNING:[1.0, 1.0, 0.0], Log.ERROR:[1.0, 0.0, 0.0]}
def __init__(self, parent, size, scrollbarWidth=20, viewPrevious=True):
Decorator.__init__(self, parent)
WidgetListLayout(self, size, scrollbarWidth)
View.__init__(self, Log.getSingleton())
self.labelSize = Size([self.getSize().getMinimumSize()[0], LabelView._HEIGHTDICT['normal'] + 2])
# last considered log message
self.iMessages = 0
for entry in Log.getSingleton().getMessageList():
if viewPrevious:
self._addLogEntry(entry)
self.iMessages += 1
# first line to display
if viewPrevious:
self.firstLine = 0
else:
self.firstLine = self.iMessages
self.childWidget.setAutoScroll(True)
return
def update(self):
if (self.iMessages < len(Log.getSingleton().getMessageList())):
for entry in Log.getSingleton().getMessageList()[self.iMessages:]:
self._addLogEntry(entry)
self.iMessages += 1
Blender.Draw.Draw()
return
def _addLogEntry(self, entry):
LabelView(self.childWidget, LabelModel(entry[1], color=LogView._COLOR[entry[0]]), size=self.labelSize)
return
class Screen:
"""Represents the complete script window.
A screen represents the complete script window. It handles
drawing and events and can consist of several user interface
components. A screen has a single child widget.
"""
def __init__(self):
"""Constructor.
"""
# buttonHandler event number management
self.nButtonEvent = 0
# buttonEventDict key: iButtonEvent, value: Action
self.buttonEventDict = {}
# root widget of the screen
self.widget = None
Widget(self)
# scissor rectangle
self.scissorRectangle = [0, 0, 0, 0]
return
def activate(self):
"""Makes this the current active screen.
This method registers itself at the ScreenManager.
"""
ScreenManager.getSingleton().activate(self)
return
def deactivate(self):
"""Deactivates this screen.
"""
ScreenManager.getSingleton().deactivate(self)
return
def resize(self):
"""Resize notification from child widget.
"""
Blender.Draw.Redraw(1)
return
def getScissorRectangle(self):
return self.scissorRectangle
def _addWidget(self, widget):
"""Adds a child widget.
@param widget Child widget to add.
"""
if self.widget:
self.widget.removeFromParent()
self.widget = widget
return
def _removeWidget(self, widget):
"""Removes a child widget.
@param widget Child widget to remove.
"""
if (self.widget == widget):
self.widget = None
Widget(self)
return
def _addButtonAction(self, action):
"""Registers an action for a button event.
@param action Action to execute on receive of the returned button event number.
@return Event number to use for the button that corresponds to that action.
"""
# workaround for Blender 2.37 event 8 bug:
shiftEvents = 100
# get a free event number
if (len(self.buttonEventDict) == self.nButtonEvent):
self.nButtonEvent += 1
eventNumber = self.nButtonEvent + shiftEvents
else:
eventNumber = [(x+1+shiftEvents) for x in range(self.nButtonEvent) if (x+1+shiftEvents) not in self.buttonEventDict.keys()][0]
# assign action to that event
self.buttonEventDict[eventNumber] = action
return eventNumber
def _removeButtonAction(self, eventNumber):
"""Action for the given event number will no longer be called.
@param eventNumber Event number for the action.
"""
if self.buttonEventDict.has_key(eventNumber):
del self.buttonEventDict[eventNumber]
return
# callbacks for Blender.Draw.Register
def _draw(self):
"""Draws the screen.
Callback function for Blender.Draw.Register
"""
# clear background
theme = Blender.Window.Theme.Get()[0]
bgColor = [color/255.0 for color in theme.get('buts').back]
glClearColor(*bgColor)
glClear(GL_COLOR_BUFFER_BIT)
# scissor box: [lower-left-x, lower-left-y, width, height]
scissorBox = Blender.BGL.Buffer(GL_INT, 4)
Blender.BGL.glGetIntegerv(Blender.BGL.GL_SCISSOR_BOX, scissorBox)
self.scissorRectangle = [scissorBox[0], scissorBox[1], scissorBox[0] + scissorBox[2], scissorBox[1] + scissorBox[3]]
# size of the script window
size = list(Blender.Window.GetAreaSize())
minimumSize = self.widget.getSize().getMinimumSize()
if size[0] < minimumSize[0]:
size[0] = minimumSize[0]
if size[1] < minimumSize[1]:
size[1] = minimumSize[1]
screenRect = [0, 0, size[0]-1, size[1]-1]
# draw widgets
self.widget.draw(screenRect)
return
def _eventHandler(self, event, value):
"""Handles keyboard and mouse input events.
Callback function for Blender.Draw.Register
"""
self.widget.eventFilter(event, value)
return
def _buttonHandler(self, event):
"""Handles draw button events.
Callback function for Blender.Draw.Register
"""
if self.buttonEventDict.has_key(event):
self.buttonEventDict[event].execute()
return
class ScreenManager(Singleton):
"""Manages screens.
"""
def __init__(self):
Singleton.__init__(self)
# current active screen is on top
self.screenStack = []
return
def activate(self, screen):
"""Activates a screen.
This method calls Blender.Draw.Register to register a screen to
be responsible for windowing.
"""
self.screenStack.append(screen)
Blender.Draw.Register(screen._draw, screen._eventHandler, screen._buttonHandler)
Blender.Draw.Draw()
return
def deactivate(self, screen):
"""Deactivates a screen.
If the screen is the current displayed screen, the next screen on the stack
of activated screens will be reactivated. If there is no screen left, an empty
screen will be displayed.
"""
if screen in self.screenStack:
position = self.screenStack.index(screen)
self.screenStack.remove(screen)
if (position == len(self.screenStack)):
# screen was current active
if len(self.screenStack):
screen = self.screenStack.pop()
self.activate(screen)
else:
# empty screen
Blender.Draw.Register()
Blender.Draw.Draw()
return
def getScissorRectangle(self):
if len(self.screenStack):
scissorRectangle = self.screenStack[-1].getScissorRectangle()
else:
scissorRectangle = [0, 0, 0, 0]
return scissorRectangle