We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
RecycleBoxLayout NameError
``` python
from random import sample
from string import ascii_lowercase

from kivy.app import App
from kivy.lang import Builder
from kivy.uix.boxlayout import BoxLayout


kv = """
<Row@BoxLayout>:
    value: ''
    size_hint: None, None
    size: self.minimum_size
    Label:
        text: root.value
        size_hint: None, None
        size: self.texture_size

<Test>:
    rv: rv
    orientation: 'vertical'
    Button:
        text: 'Populate list'
        on_press: root.populate()
    RecycleView:
        id: rv
        viewclass: 'Row'
        RecycleBoxLayout:
            default_size: None, None
            size_hint_y: None
            height: self.minimum_height
            orientation: 'vertical'
"""

Builder.load_string(kv)


class Test(BoxLayout):

    def populate(self):
        self.rv.data = [{'value': ''.join(sample(ascii_lowercase, 6))}
                        for x in range(50)]


class TestApp(App):
    def build(self):
        return Test()

if __name__ == '__main__':
    TestApp().run()
```

``` python
 Traceback (most recent call last):
   File "E:\dev\prs\kivy\examples\widgets\recycleview\basic_data.py", line 49, in <module>
     TestApp().run()
   File "E:\dev\prs\kivy\kivy\app.py", line 828, in run
     runTouchApp()
   File "E:\dev\prs\kivy\kivy\base.py", line 487, in runTouchApp
     EventLoop.window.mainloop()
   File "E:\dev\prs\kivy\kivy\core\window\window_sdl2.py", line 633, in mainloop
     self._mainloop()
   File "E:\dev\prs\kivy\kivy\core\window\window_sdl2.py", line 388, in _mainloop
     EventLoop.idle()
   File "E:\dev\prs\kivy\kivy\base.py", line 336, in idle
     Clock.tick_draw()
   File "E:\dev\prs\kivy\kivy\clock.py", line 528, in tick_draw
     self._process_events_before_frame()
   File "E:\dev\prs\kivy\kivy\clock.py", line 678, in _process_events_before_frame
     event.tick(self._last_tick, remove)
   File "E:\dev\prs\kivy\kivy\clock.py", line 412, in tick
     ret = callback(self._dt)
   File "E:\dev\prs\kivy\kivy\uix\recycleview\__init__.py", line 109, in refresh_views
     lm.compute_layout(data, f)
   File "E:\dev\prs\kivy\kivy\uix\recycleboxlayout.py", line 88, in compute_layout
     changed and not self._update_sizes(changed)):
   File "E:\dev\prs\kivy\kivy\uix\recycleboxlayout.py", line 81, in _update_sizes
     return relayout
 NameError: name 'relayout' is not defined
```


--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `kivy/uix/recycleboxlayout.py`
Content:
```
1 """
2 RecycleBoxLayout
3 ================
4 
5 .. versionadded:: 1.9.2
6 
7 .. warning::
8     This module is highly experimental, its API may change in the future and
9     the documentation is not complete at this time.
10 
11 The RecycleBoxLayout is designed to provide a
12 :class:`~kivy.uix.boxlayout.BoxLayout` type layout when used with the
13 :class:`~kivy.uix.recycleview.RecycleView` widget. Please refer to the
14 :mod:`~kivy.uix.recycleview` module documentation for more information.
15 
16 """
17 
18 from kivy.uix.recyclelayout import RecycleLayout
19 from kivy.uix.boxlayout import BoxLayout
20 
21 __all__ = ('RecycleBoxLayout', )
22 
23 
24 class RecycleBoxLayout(RecycleLayout, BoxLayout):
25 
26     _rv_positions = None
27 
28     def __init__(self, **kwargs):
29         super(RecycleBoxLayout, self).__init__(**kwargs)
30         self.funbind('children', self._trigger_layout)
31 
32     def _update_sizes(self, changed):
33         horizontal = self.orientation == 'horizontal'
34         padding_left, padding_top, padding_right, padding_bottom = self.padding
35         padding_x = padding_left + padding_right
36         padding_y = padding_top + padding_bottom
37         selfw = self.width
38         selfh = self.height
39         layout_w = max(0, selfw - padding_x)
40         layout_h = max(0, selfh - padding_y)
41         cx = self.x + padding_left
42         cy = self.y + padding_bottom
43         view_opts = self.view_opts
44         remove_view = self.remove_view
45 
46         for (index, widget, (w, h), (wn, hn), (shw, shh), (shnw, shnh),
47              (shw_min, shh_min), (shwn_min, shhn_min), (shw_max, shh_max),
48              (shwn_max, shhn_max), ph, phn) in changed:
49             if (horizontal and
50                 (shw != shnw or w != wn or shw_min != shwn_min or
51                  shw_max != shwn_max) or
52                 not horizontal and
53                 (shh != shnh or h != hn or shh_min != shhn_min or
54                  shh_max != shhn_max)):
55                 return True
56 
57             remove_view(widget, index)
58             opt = view_opts[index]
59             if horizontal:
60                 wo, ho = opt['size']
61                 if shnh is not None:
62                     _, h = opt['size'] = [wo, shnh * layout_h]
63                 else:
64                     h = ho
65 
66                 xo, yo = opt['pos']
67                 for key, value in phn.items():
68                     posy = value * layout_h
69                     if key == 'y':
70                         yo = posy + cy
71                     elif key == 'top':
72                         yo = posy - h
73                     elif key == 'center_y':
74                         yo = posy - (h / 2.)
75                 opt['pos'] = [xo, yo]
76             else:
77                 wo, ho = opt['size']
78                 if shnw is not None:
79                     w, _ = opt['size'] = [shnw * layout_w, ho]
80                 else:
81                     w = wo
82 
83                 xo, yo = opt['pos']
84                 for key, value in phn.items():
85                     posx = value * layout_w
86                     if key == 'x':
87                         xo = posx + cx
88                     elif key == 'right':
89                         xo = posx - w
90                     elif key == 'center_x':
91                         xo = posx - (w / 2.)
92                 opt['pos'] = [xo, yo]
93 
94         return relayout
95 
96     def compute_layout(self, data, flags):
97         super(RecycleBoxLayout, self).compute_layout(data, flags)
98 
99         changed = self._changed_views
100         if (changed is None or
101                 changed and not self._update_sizes(changed)):
102             return
103 
104         self.clear_layout()
105         self._rv_positions = None
106         if not data:
107             l, t, r, b = self.padding
108             self.minimum_size = l + r, t + b
109             return
110 
111         view_opts = self.view_opts
112         n = len(view_opts)
113         for i, x, y, w, h in self._iterate_layout(
114                 [(opt['size'], opt['size_hint'], opt['pos_hint'],
115                   opt['size_hint_min'], opt['size_hint_max']) for
116                  opt in reversed(view_opts)]):
117             opt = view_opts[n - i - 1]
118             shw, shh = opt['size_hint']
119             opt['pos'] = x, y
120             wo, ho = opt['size']
121             # layout won't/shouldn't change previous size if size_hint is None
122             # which is what w/h being None means.
123             opt['size'] = [(wo if shw is None else w),
124                            (ho if shh is None else h)]
125 
126         spacing = self.spacing
127         pos = self._rv_positions = [None, ] * len(data)
128 
129         if self.orientation == 'horizontal':
130             pos[0] = self.x
131             last = pos[0] + self.padding[0] + view_opts[0]['size'][0] + \
132                 spacing / 2.
133             for i, val in enumerate(view_opts[1:], 1):
134                 pos[i] = last
135                 last += val['size'][0] + spacing
136         else:
137             last = pos[-1] = \
138                 self.y + self.height - self.padding[1] - \
139                 view_opts[0]['size'][1] - spacing / 2.
140             n = len(view_opts)
141             for i, val in enumerate(view_opts[1:], 1):
142                 last -= spacing + val['size'][1]
143                 pos[n - 1 - i] = last
144 
145     def get_view_index_at(self, pos):
146         calc_pos = self._rv_positions
147         if not calc_pos:
148             return 0
149 
150         x, y = pos
151 
152         if self.orientation == 'horizontal':
153             if x >= calc_pos[-1] or len(calc_pos) == 1:
154                 return len(calc_pos) - 1
155 
156             ix = 0
157             for val in calc_pos[1:]:
158                 if x < val:
159                     return ix
160                 ix += 1
161         else:
162             if y >= calc_pos[-1] or len(calc_pos) == 1:
163                 return 0
164 
165             iy = 0
166             for val in calc_pos[1:]:
167                 if y < val:
168                     return len(calc_pos) - iy - 1
169                 iy += 1
170 
171         assert False
172 
173     def compute_visible_views(self, data, viewport):
174         if self._rv_positions is None or not data:
175             return []
176 
177         x, y, w, h = viewport
178         at_idx = self.get_view_index_at
179         if self.orientation == 'horizontal':
180             a, b = at_idx((x, y)), at_idx((x + w, y))
181         else:
182             a, b = at_idx((x, y + h)), at_idx((x, y))
183         return list(range(a, b + 1))
184
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/kivy/uix/recycleboxlayout.py b/kivy/uix/recycleboxlayout.py
--- a/kivy/uix/recycleboxlayout.py
+++ b/kivy/uix/recycleboxlayout.py
@@ -91,7 +91,7 @@
                         xo = posx - (w / 2.)
                 opt['pos'] = [xo, yo]
 
-        return relayout
+        return False
 
     def compute_layout(self, data, flags):
         super(RecycleBoxLayout, self).compute_layout(data, flags)

{"golden_diff": "diff --git a/kivy/uix/recycleboxlayout.py b/kivy/uix/recycleboxlayout.py\n--- a/kivy/uix/recycleboxlayout.py\n+++ b/kivy/uix/recycleboxlayout.py\n@@ -91,7 +91,7 @@\n                         xo = posx - (w / 2.)\n                 opt['pos'] = [xo, yo]\n \n-        return relayout\n+        return False\n \n     def compute_layout(self, data, flags):\n         super(RecycleBoxLayout, self).compute_layout(data, flags)\n", "issue": "RecycleBoxLayout NameError\n``` python\nfrom random import sample\nfrom string import ascii_lowercase\n\nfrom kivy.app import App\nfrom kivy.lang import Builder\nfrom kivy.uix.boxlayout import BoxLayout\n\n\nkv = \"\"\"\n<Row@BoxLayout>:\n    value: ''\n    size_hint: None, None\n    size: self.minimum_size\n    Label:\n        text: root.value\n        size_hint: None, None\n        size: self.texture_size\n\n<Test>:\n    rv: rv\n    orientation: 'vertical'\n    Button:\n        text: 'Populate list'\n        on_press: root.populate()\n    RecycleView:\n        id: rv\n        viewclass: 'Row'\n        RecycleBoxLayout:\n            default_size: None, None\n            size_hint_y: None\n            height: self.minimum_height\n            orientation: 'vertical'\n\"\"\"\n\nBuilder.load_string(kv)\n\n\nclass Test(BoxLayout):\n\n    def populate(self):\n        self.rv.data = [{'value': ''.join(sample(ascii_lowercase, 6))}\n                        for x in range(50)]\n\n\nclass TestApp(App):\n    def build(self):\n        return Test()\n\nif __name__ == '__main__':\n    TestApp().run()\n```\n\n``` python\n Traceback (most recent call last):\n   File \"E:\\dev\\prs\\kivy\\examples\\widgets\\recycleview\\basic_data.py\", line 49, in <module>\n     TestApp().run()\n   File \"E:\\dev\\prs\\kivy\\kivy\\app.py\", line 828, in run\n     runTouchApp()\n   File \"E:\\dev\\prs\\kivy\\kivy\\base.py\", line 487, in runTouchApp\n     EventLoop.window.mainloop()\n   File \"E:\\dev\\prs\\kivy\\kivy\\core\\window\\window_sdl2.py\", line 633, in mainloop\n     self._mainloop()\n   File \"E:\\dev\\prs\\kivy\\kivy\\core\\window\\window_sdl2.py\", line 388, in _mainloop\n     EventLoop.idle()\n   File \"E:\\dev\\prs\\kivy\\kivy\\base.py\", line 336, in idle\n     Clock.tick_draw()\n   File \"E:\\dev\\prs\\kivy\\kivy\\clock.py\", line 528, in tick_draw\n     self._process_events_before_frame()\n   File \"E:\\dev\\prs\\kivy\\kivy\\clock.py\", line 678, in _process_events_before_frame\n     event.tick(self._last_tick, remove)\n   File \"E:\\dev\\prs\\kivy\\kivy\\clock.py\", line 412, in tick\n     ret = callback(self._dt)\n   File \"E:\\dev\\prs\\kivy\\kivy\\uix\\recycleview\\__init__.py\", line 109, in refresh_views\n     lm.compute_layout(data, f)\n   File \"E:\\dev\\prs\\kivy\\kivy\\uix\\recycleboxlayout.py\", line 88, in compute_layout\n     changed and not self._update_sizes(changed)):\n   File \"E:\\dev\\prs\\kivy\\kivy\\uix\\recycleboxlayout.py\", line 81, in _update_sizes\n     return relayout\n NameError: name 'relayout' is not defined\n```\n\n", "before_files": [{"content": "\"\"\"\nRecycleBoxLayout\n================\n\n.. versionadded:: 1.9.2\n\n.. warning::\n    This module is highly experimental, its API may change in the future and\n    the documentation is not complete at this time.\n\nThe RecycleBoxLayout is designed to provide a\n:class:`~kivy.uix.boxlayout.BoxLayout` type layout when used with the\n:class:`~kivy.uix.recycleview.RecycleView` widget. Please refer to the\n:mod:`~kivy.uix.recycleview` module documentation for more information.\n\n\"\"\"\n\nfrom kivy.uix.recyclelayout import RecycleLayout\nfrom kivy.uix.boxlayout import BoxLayout\n\n__all__ = ('RecycleBoxLayout', )\n\n\nclass RecycleBoxLayout(RecycleLayout, BoxLayout):\n\n    _rv_positions = None\n\n    def __init__(self, **kwargs):\n        super(RecycleBoxLayout, self).__init__(**kwargs)\n        self.funbind('children', self._trigger_layout)\n\n    def _update_sizes(self, changed):\n        horizontal = self.orientation == 'horizontal'\n        padding_left, padding_top, padding_right, padding_bottom = self.padding\n        padding_x = padding_left + padding_right\n        padding_y = padding_top + padding_bottom\n        selfw = self.width\n        selfh = self.height\n        layout_w = max(0, selfw - padding_x)\n        layout_h = max(0, selfh - padding_y)\n        cx = self.x + padding_left\n        cy = self.y + padding_bottom\n        view_opts = self.view_opts\n        remove_view = self.remove_view\n\n        for (index, widget, (w, h), (wn, hn), (shw, shh), (shnw, shnh),\n             (shw_min, shh_min), (shwn_min, shhn_min), (shw_max, shh_max),\n             (shwn_max, shhn_max), ph, phn) in changed:\n            if (horizontal and\n                (shw != shnw or w != wn or shw_min != shwn_min or\n                 shw_max != shwn_max) or\n                not horizontal and\n                (shh != shnh or h != hn or shh_min != shhn_min or\n                 shh_max != shhn_max)):\n                return True\n\n            remove_view(widget, index)\n            opt = view_opts[index]\n            if horizontal:\n                wo, ho = opt['size']\n                if shnh is not None:\n                    _, h = opt['size'] = [wo, shnh * layout_h]\n                else:\n                    h = ho\n\n                xo, yo = opt['pos']\n                for key, value in phn.items():\n                    posy = value * layout_h\n                    if key == 'y':\n                        yo = posy + cy\n                    elif key == 'top':\n                        yo = posy - h\n                    elif key == 'center_y':\n                        yo = posy - (h / 2.)\n                opt['pos'] = [xo, yo]\n            else:\n                wo, ho = opt['size']\n                if shnw is not None:\n                    w, _ = opt['size'] = [shnw * layout_w, ho]\n                else:\n                    w = wo\n\n                xo, yo = opt['pos']\n                for key, value in phn.items():\n                    posx = value * layout_w\n                    if key == 'x':\n                        xo = posx + cx\n                    elif key == 'right':\n                        xo = posx - w\n                    elif key == 'center_x':\n                        xo = posx - (w / 2.)\n                opt['pos'] = [xo, yo]\n\n        return relayout\n\n    def compute_layout(self, data, flags):\n        super(RecycleBoxLayout, self).compute_layout(data, flags)\n\n        changed = self._changed_views\n        if (changed is None or\n                changed and not self._update_sizes(changed)):\n            return\n\n        self.clear_layout()\n        self._rv_positions = None\n        if not data:\n            l, t, r, b = self.padding\n            self.minimum_size = l + r, t + b\n            return\n\n        view_opts = self.view_opts\n        n = len(view_opts)\n        for i, x, y, w, h in self._iterate_layout(\n                [(opt['size'], opt['size_hint'], opt['pos_hint'],\n                  opt['size_hint_min'], opt['size_hint_max']) for\n                 opt in reversed(view_opts)]):\n            opt = view_opts[n - i - 1]\n            shw, shh = opt['size_hint']\n            opt['pos'] = x, y\n            wo, ho = opt['size']\n            # layout won't/shouldn't change previous size if size_hint is None\n            # which is what w/h being None means.\n            opt['size'] = [(wo if shw is None else w),\n                           (ho if shh is None else h)]\n\n        spacing = self.spacing\n        pos = self._rv_positions = [None, ] * len(data)\n\n        if self.orientation == 'horizontal':\n            pos[0] = self.x\n            last = pos[0] + self.padding[0] + view_opts[0]['size'][0] + \\\n                spacing / 2.\n            for i, val in enumerate(view_opts[1:], 1):\n                pos[i] = last\n                last += val['size'][0] + spacing\n        else:\n            last = pos[-1] = \\\n                self.y + self.height - self.padding[1] - \\\n                view_opts[0]['size'][1] - spacing / 2.\n            n = len(view_opts)\n            for i, val in enumerate(view_opts[1:], 1):\n                last -= spacing + val['size'][1]\n                pos[n - 1 - i] = last\n\n    def get_view_index_at(self, pos):\n        calc_pos = self._rv_positions\n        if not calc_pos:\n            return 0\n\n        x, y = pos\n\n        if self.orientation == 'horizontal':\n            if x >= calc_pos[-1] or len(calc_pos) == 1:\n                return len(calc_pos) - 1\n\n            ix = 0\n            for val in calc_pos[1:]:\n                if x < val:\n                    return ix\n                ix += 1\n        else:\n            if y >= calc_pos[-1] or len(calc_pos) == 1:\n                return 0\n\n            iy = 0\n            for val in calc_pos[1:]:\n                if y < val:\n                    return len(calc_pos) - iy - 1\n                iy += 1\n\n        assert False\n\n    def compute_visible_views(self, data, viewport):\n        if self._rv_positions is None or not data:\n            return []\n\n        x, y, w, h = viewport\n        at_idx = self.get_view_index_at\n        if self.orientation == 'horizontal':\n            a, b = at_idx((x, y)), at_idx((x + w, y))\n        else:\n            a, b = at_idx((x, y + h)), at_idx((x, y))\n        return list(range(a, b + 1))\n", "path": "kivy/uix/recycleboxlayout.py"}], "after_files": [{"content": "\"\"\"\nRecycleBoxLayout\n================\n\n.. versionadded:: 1.9.2\n\n.. warning::\n    This module is highly experimental, its API may change in the future and\n    the documentation is not complete at this time.\n\nThe RecycleBoxLayout is designed to provide a\n:class:`~kivy.uix.boxlayout.BoxLayout` type layout when used with the\n:class:`~kivy.uix.recycleview.RecycleView` widget. Please refer to the\n:mod:`~kivy.uix.recycleview` module documentation for more information.\n\n\"\"\"\n\nfrom kivy.uix.recyclelayout import RecycleLayout\nfrom kivy.uix.boxlayout import BoxLayout\n\n__all__ = ('RecycleBoxLayout', )\n\n\nclass RecycleBoxLayout(RecycleLayout, BoxLayout):\n\n    _rv_positions = None\n\n    def __init__(self, **kwargs):\n        super(RecycleBoxLayout, self).__init__(**kwargs)\n        self.funbind('children', self._trigger_layout)\n\n    def _update_sizes(self, changed):\n        horizontal = self.orientation == 'horizontal'\n        padding_left, padding_top, padding_right, padding_bottom = self.padding\n        padding_x = padding_left + padding_right\n        padding_y = padding_top + padding_bottom\n        selfw = self.width\n        selfh = self.height\n        layout_w = max(0, selfw - padding_x)\n        layout_h = max(0, selfh - padding_y)\n        cx = self.x + padding_left\n        cy = self.y + padding_bottom\n        view_opts = self.view_opts\n        remove_view = self.remove_view\n\n        for (index, widget, (w, h), (wn, hn), (shw, shh), (shnw, shnh),\n             (shw_min, shh_min), (shwn_min, shhn_min), (shw_max, shh_max),\n             (shwn_max, shhn_max), ph, phn) in changed:\n            if (horizontal and\n                (shw != shnw or w != wn or shw_min != shwn_min or\n                 shw_max != shwn_max) or\n                not horizontal and\n                (shh != shnh or h != hn or shh_min != shhn_min or\n                 shh_max != shhn_max)):\n                return True\n\n            remove_view(widget, index)\n            opt = view_opts[index]\n            if horizontal:\n                wo, ho = opt['size']\n                if shnh is not None:\n                    _, h = opt['size'] = [wo, shnh * layout_h]\n                else:\n                    h = ho\n\n                xo, yo = opt['pos']\n                for key, value in phn.items():\n                    posy = value * layout_h\n                    if key == 'y':\n                        yo = posy + cy\n                    elif key == 'top':\n                        yo = posy - h\n                    elif key == 'center_y':\n                        yo = posy - (h / 2.)\n                opt['pos'] = [xo, yo]\n            else:\n                wo, ho = opt['size']\n                if shnw is not None:\n                    w, _ = opt['size'] = [shnw * layout_w, ho]\n                else:\n                    w = wo\n\n                xo, yo = opt['pos']\n                for key, value in phn.items():\n                    posx = value * layout_w\n                    if key == 'x':\n                        xo = posx + cx\n                    elif key == 'right':\n                        xo = posx - w\n                    elif key == 'center_x':\n                        xo = posx - (w / 2.)\n                opt['pos'] = [xo, yo]\n\n        return False\n\n    def compute_layout(self, data, flags):\n        super(RecycleBoxLayout, self).compute_layout(data, flags)\n\n        changed = self._changed_views\n        if (changed is None or\n                changed and not self._update_sizes(changed)):\n            return\n\n        self.clear_layout()\n        self._rv_positions = None\n        if not data:\n            l, t, r, b = self.padding\n            self.minimum_size = l + r, t + b\n            return\n\n        view_opts = self.view_opts\n        n = len(view_opts)\n        for i, x, y, w, h in self._iterate_layout(\n                [(opt['size'], opt['size_hint'], opt['pos_hint'],\n                  opt['size_hint_min'], opt['size_hint_max']) for\n                 opt in reversed(view_opts)]):\n            opt = view_opts[n - i - 1]\n            shw, shh = opt['size_hint']\n            opt['pos'] = x, y\n            wo, ho = opt['size']\n            # layout won't/shouldn't change previous size if size_hint is None\n            # which is what w/h being None means.\n            opt['size'] = [(wo if shw is None else w),\n                           (ho if shh is None else h)]\n\n        spacing = self.spacing\n        pos = self._rv_positions = [None, ] * len(data)\n\n        if self.orientation == 'horizontal':\n            pos[0] = self.x\n            last = pos[0] + self.padding[0] + view_opts[0]['size'][0] + \\\n                spacing / 2.\n            for i, val in enumerate(view_opts[1:], 1):\n                pos[i] = last\n                last += val['size'][0] + spacing\n        else:\n            last = pos[-1] = \\\n                self.y + self.height - self.padding[1] - \\\n                view_opts[0]['size'][1] - spacing / 2.\n            n = len(view_opts)\n            for i, val in enumerate(view_opts[1:], 1):\n                last -= spacing + val['size'][1]\n                pos[n - 1 - i] = last\n\n    def get_view_index_at(self, pos):\n        calc_pos = self._rv_positions\n        if not calc_pos:\n            return 0\n\n        x, y = pos\n\n        if self.orientation == 'horizontal':\n            if x >= calc_pos[-1] or len(calc_pos) == 1:\n                return len(calc_pos) - 1\n\n            ix = 0\n            for val in calc_pos[1:]:\n                if x < val:\n                    return ix\n                ix += 1\n        else:\n            if y >= calc_pos[-1] or len(calc_pos) == 1:\n                return 0\n\n            iy = 0\n            for val in calc_pos[1:]:\n                if y < val:\n                    return len(calc_pos) - iy - 1\n                iy += 1\n\n        assert False\n\n    def compute_visible_views(self, data, viewport):\n        if self._rv_positions is None or not data:\n            return []\n\n        x, y, w, h = viewport\n        at_idx = self.get_view_index_at\n        if self.orientation == 'horizontal':\n            a, b = at_idx((x, y)), at_idx((x + w, y))\n        else:\n            a, b = at_idx((x, y + h)), at_idx((x, y))\n        return list(range(a, b + 1))\n", "path": "kivy/uix/recycleboxlayout.py"}]}