docs: def on_touch_up(self, touch):
          """Delegate touch handling if possible, else select something."""
          if hasattr(self, '_lasttouch') and self._lasttouch == touch:
              return
          self._lasttouch = touch
          touch.push()
          touch.apply_transform_2d(self.to_local)
          if hasattr(self, 'protodest'):
              Logger.debug("Board: on_touch_up making a portal")
              touch.ungrab(self)
              ret = self.portal_touch_up(touch)
              touch.pop()
              return ret
          if self.app.selection and hasattr(self.app.selection, 'on_touch_up'):
              self.app.selection.dispatch('on_touch_up', touch)
          for candidate in self.selection_candidates:
              if candidate == self.app.selection:
                  continue
              if candidate.collide_point(*touch.pos):
                  Logger.debug("Board: selecting " + repr(candidate))
                  if hasattr(candidate, 'selected'):
                      candidate.selected = True
                  if hasattr(self.app.selection, 'selected'):
                      self.app.selection.selected = False
                  self.app.selection = candidate
                  self.keep_selection = True
                  parent = candidate.parent
                  parent.remove_widget(candidate)
                  parent.add_widget(candidate)
                  break
          if not self.keep_selection:
              Logger.debug("Board: deselecting " + repr(self.app.selection))
              if hasattr(self.app.selection, 'selected'):
                  self.app.selection.selected = False
              self.app.selection = None
          self.keep_selection = False
          touch.ungrab(self)
          touch.pop()
          return