prompt: You will be provided with a partial code base and an issue statement explaining a problem to resolve.
  <issue>
  [BUG] Grouped video datasets: labels shown only in default group slice
  ### System information
  
  -   **OS Platform and Distribution** Linux Ubuntu 20.04
  -   **Python version** (`python --version`): 3.10
  -   **FiftyOne version** (`fiftyone --version`): 0.21.2
  -   **FiftyOne installed from** (pip or source): pip
  
  ### Commands to reproduce
  
  ```
  import fiftyone as fo
  import fiftyone.zoo as foz
  
  ds = foz.load_zoo_dataset('quickstart-video')
  
  fps = ds.values('filepath')
  fp_pairs = zip(fps[:2],fps[2:4])
  
  ds2 = fo.Dataset(name='qsv-test')
  ds2.add_group_field('group',default='left')
  
  samples = []
  for fpl,fpr in fp_pairs:
      g = fo.Group()    
      s1 = fo.Sample(filepath=fpl, group=g.element('left'))
      s2 = fo.Sample(filepath=fpr, group=g.element('rigt'))
      samples.append(s1)
      samples.append(s2)
  
  ds2.add_samples(samples)
  
  ds2.group_slice = 'left'
  ds2.ensure_frames()
  samp = ds2.first()
  for f,frame in samp.frames.items():
      d1 = fo.Detection(bounding_box=[0.25,0.25,0.5,0.5])
      frame['dets'] = fo.Detections(detections=[d1])
      frame.save()
  samp.save()
  
  ds2.group_slice = 'rigt'
  ds2.ensure_frames()
  samp = ds2.first()
  for f,frame in samp.frames.items():
      d2 = fo.Detection(bounding_box=[0.25,0.25,0.25,0.25])
      frame['dets2'] = fo.Detections(detections=[d2])
      frame.save()
  samp.save()
  
  session = fo.launch_app(ds2,auto=False)
  
  # With default_group_slice = 'left', detection shows only in left slice (detection "flashes" in right slice)
  
  # With default_group_slice = 'right', detection shows only in right slice (detection "flashes" in left slice)
  ds2.default_group_slice = 'rigt'
  ```
  
  ### Describe the problem
  
  Frame-level labels (eg obj detections) are shown only for the default group slice within the group modal, for grouped video datasets.
  
  Non-default-slices flash labels in eg the first frame of playback, but then labels are not shown for remaining frames.
  
  Data(set) structure in SDK appears as expected.
  
  See OSS Slack: https://fiftyone-users.slack.com/archives/C0189A476EQ/p1687962462949109
  
  
  ### Other info/logs
  
  ### What areas of FiftyOne does this bug affect?
  
  -   [x] `App`: FiftyOne application issue
  -   [ ] `Core`: Core Python library issue
  -   [ ] `Server`: FiftyOne server issue
  
  
  
  </issue>
  <code>
  [start of fiftyone/server/routes/frames.py]
  1 """
  2 FiftyOne Server /frames route
  3 
  4 | Copyright 2017-2023, Voxel51, Inc.
  5 | `voxel51.com <https://voxel51.com/>`_
  6 |
  7 """
  8 from starlette.endpoints import HTTPEndpoint
  9 from starlette.requests import Request
  10 
  11 from fiftyone.core.expressions import ViewField as F
  12 import fiftyone.core.json as foj
  13 import fiftyone.core.odm as foo
  14 import fiftyone.core.view as fov
  15 
  16 from fiftyone.server.decorators import route
  17 import fiftyone.server.view as fosv
  18 
  19 
  20 class Frames(HTTPEndpoint):
  21     @route
  22     async def post(self, request: Request, data: dict):
  23         start_frame = int(data.get("frameNumber", 1))
  24         frame_count = int(data.get("frameCount", 1))
  25         num_frames = int(data.get("numFrames"))
  26         extended = data.get("extended", None)
  27         dataset = data.get("dataset")
  28         stages = data.get("view")
  29         sample_id = data.get("sampleId")
  30 
  31         view = fosv.get_view(dataset, stages=stages, extended_stages=extended)
  32         view = fov.make_optimized_select_view(view, sample_id)
  33 
  34         end_frame = min(num_frames + start_frame, frame_count)
  35         support = None if stages else [start_frame, end_frame]
  36         if not support:
  37             view = view.set_field(
  38                 "frames",
  39                 F("frames").filter(
  40                     (F("frame_number") >= start_frame)
  41                     & (F("frame_number") <= end_frame)
  42                 ),
  43             )
  44 
  45         frames = await foo.aggregate(
  46             foo.get_async_db_conn()[view._dataset._sample_collection_name],
  47             view._pipeline(frames_only=True, support=support),
  48         ).to_list(end_frame - start_frame + 1)
  49 
  50         return {
  51             "frames": foj.stringify(frames),
  52             "range": [start_frame, end_frame],
  53         }
  54
  [end of fiftyone/server/routes/frames.py]
  </code>
  
  I need you to solve this issue by generating a single patch file that I can apply directly to this repository using git apply. Please respond with a single patch file in the following format.
  <patch>
  diff --git a/file.py b/file.py
  --- a/file.py
  +++ b/file.py
  @@ -1,27 +1,35 @@
   def euclidean(a, b):
  -    while b:
  -        a, b = b, a % b
  -    return a
  +    if b == 0:
  +        return a
  +    return euclidean(b, a % b)
   
   
   def bresenham(x0, y0, x1, y1):
       points = []
       dx = abs(x1 - x0)
       dy = abs(y1 - y0)
  -    sx = 1 if x0 < x1 else -1
  -    sy = 1 if y0 < y1 else -1
  -    err = dx - dy
  +    x, y = x0, y0
  +    sx = -1 if x0 > x1 else 1
  +    sy = -1 if y0 > y1 else 1
   
  -    while True:
  -        points.append((x0, y0))
  -        if x0 == x1 and y0 == y1:
  -            break
  -        e2 = 2 * err
  -        if e2 > -dy:
  -            err -= dy
  -            x0 += sx
  -        if e2 < dx:
  -            err += dx
  -            y0 += sy
  +    if dx > dy:
  +        err = dx / 2.0
  +        while x != x1:
  +            points.append((x, y))
  +            err -= dy
  +            if err < 0:
  +                y += sy
  +                err += dx
  +            x += sx
  +    else:
  +        err = dy / 2.0
  +        while y != y1:
  +            points.append((x, y))
  +            err -= dx
  +            if err < 0:
  +                x += sx
  +                err += dy
  +            y += sy
  +
  +    points.append((x, y))
       return points
  
  </patch>
golden_diff: diff --git a/fiftyone/server/routes/frames.py b/fiftyone/server/routes/frames.py
  --- a/fiftyone/server/routes/frames.py
  +++ b/fiftyone/server/routes/frames.py
  @@ -6,6 +6,7 @@
   |
   """
   from starlette.endpoints import HTTPEndpoint
  +from starlette.responses import JSONResponse
   from starlette.requests import Request
   
   from fiftyone.core.expressions import ViewField as F
  @@ -27,10 +28,14 @@
           dataset = data.get("dataset")
           stages = data.get("view")
           sample_id = data.get("sampleId")
  +        group_slice = data.get("slice", None)
   
           view = fosv.get_view(dataset, stages=stages, extended_stages=extended)
           view = fov.make_optimized_select_view(view, sample_id)
   
  +        if group_slice is not None:
  +            view.group_slice = group_slice
  +
           end_frame = min(num_frames + start_frame, frame_count)
           support = None if stages else [start_frame, end_frame]
           if not support:
  @@ -47,7 +52,9 @@
               view._pipeline(frames_only=True, support=support),
           ).to_list(end_frame - start_frame + 1)
   
  -        return {
  -            "frames": foj.stringify(frames),
  -            "range": [start_frame, end_frame],
  -        }
  +        return JSONResponse(
  +            {
  +                "frames": foj.stringify(frames),
  +                "range": [start_frame, end_frame],
  +            }
  +        )
  
verification_info: {"golden_diff": "diff --git a/fiftyone/server/routes/frames.py b/fiftyone/server/routes/frames.py\n--- a/fiftyone/server/routes/frames.py\n+++ b/fiftyone/server/routes/frames.py\n@@ -6,6 +6,7 @@\n |\n \"\"\"\n from starlette.endpoints import HTTPEndpoint\n+from starlette.responses import JSONResponse\n from starlette.requests import Request\n \n from fiftyone.core.expressions import ViewField as F\n@@ -27,10 +28,14 @@\n         dataset = data.get(\"dataset\")\n         stages = data.get(\"view\")\n         sample_id = data.get(\"sampleId\")\n+        group_slice = data.get(\"slice\", None)\n \n         view = fosv.get_view(dataset, stages=stages, extended_stages=extended)\n         view = fov.make_optimized_select_view(view, sample_id)\n \n+        if group_slice is not None:\n+            view.group_slice = group_slice\n+\n         end_frame = min(num_frames + start_frame, frame_count)\n         support = None if stages else [start_frame, end_frame]\n         if not support:\n@@ -47,7 +52,9 @@\n             view._pipeline(frames_only=True, support=support),\n         ).to_list(end_frame - start_frame + 1)\n \n-        return {\n-            \"frames\": foj.stringify(frames),\n-            \"range\": [start_frame, end_frame],\n-        }\n+        return JSONResponse(\n+            {\n+                \"frames\": foj.stringify(frames),\n+                \"range\": [start_frame, end_frame],\n+            }\n+        )\n", "issue": "[BUG] Grouped video datasets: labels shown only in default group slice\n### System information\r\n\r\n-   **OS Platform and Distribution** Linux Ubuntu 20.04\r\n-   **Python version** (`python --version`): 3.10\r\n-   **FiftyOne version** (`fiftyone --version`): 0.21.2\r\n-   **FiftyOne installed from** (pip or source): pip\r\n\r\n### Commands to reproduce\r\n\r\n```\r\nimport fiftyone as fo\r\nimport fiftyone.zoo as foz\r\n\r\nds = foz.load_zoo_dataset('quickstart-video')\r\n\r\nfps = ds.values('filepath')\r\nfp_pairs = zip(fps[:2],fps[2:4])\r\n\r\nds2 = fo.Dataset(name='qsv-test')\r\nds2.add_group_field('group',default='left')\r\n\r\nsamples = []\r\nfor fpl,fpr in fp_pairs:\r\n    g = fo.Group()    \r\n    s1 = fo.Sample(filepath=fpl, group=g.element('left'))\r\n    s2 = fo.Sample(filepath=fpr, group=g.element('rigt'))\r\n    samples.append(s1)\r\n    samples.append(s2)\r\n\r\nds2.add_samples(samples)\r\n\r\nds2.group_slice = 'left'\r\nds2.ensure_frames()\r\nsamp = ds2.first()\r\nfor f,frame in samp.frames.items():\r\n    d1 = fo.Detection(bounding_box=[0.25,0.25,0.5,0.5])\r\n    frame['dets'] = fo.Detections(detections=[d1])\r\n    frame.save()\r\nsamp.save()\r\n\r\nds2.group_slice = 'rigt'\r\nds2.ensure_frames()\r\nsamp = ds2.first()\r\nfor f,frame in samp.frames.items():\r\n    d2 = fo.Detection(bounding_box=[0.25,0.25,0.25,0.25])\r\n    frame['dets2'] = fo.Detections(detections=[d2])\r\n    frame.save()\r\nsamp.save()\r\n\r\nsession = fo.launch_app(ds2,auto=False)\r\n\r\n# With default_group_slice = 'left', detection shows only in left slice (detection \"flashes\" in right slice)\r\n\r\n# With default_group_slice = 'right', detection shows only in right slice (detection \"flashes\" in left slice)\r\nds2.default_group_slice = 'rigt'\r\n```\r\n\r\n### Describe the problem\r\n\r\nFrame-level labels (eg obj detections) are shown only for the default group slice within the group modal, for grouped video datasets.\r\n\r\nNon-default-slices flash labels in eg the first frame of playback, but then labels are not shown for remaining frames.\r\n\r\nData(set) structure in SDK appears as expected.\r\n\r\nSee OSS Slack: https://fiftyone-users.slack.com/archives/C0189A476EQ/p1687962462949109\r\n\r\n\r\n### Other info/logs\r\n\r\n### What areas of FiftyOne does this bug affect?\r\n\r\n-   [x] `App`: FiftyOne application issue\r\n-   [ ] `Core`: Core Python library issue\r\n-   [ ] `Server`: FiftyOne server issue\r\n\r\n\n", "before_files": [{"content": "\"\"\"\nFiftyOne Server /frames route\n\n| Copyright 2017-2023, Voxel51, Inc.\n| `voxel51.com <https://voxel51.com/>`_\n|\n\"\"\"\nfrom starlette.endpoints import HTTPEndpoint\nfrom starlette.requests import Request\n\nfrom fiftyone.core.expressions import ViewField as F\nimport fiftyone.core.json as foj\nimport fiftyone.core.odm as foo\nimport fiftyone.core.view as fov\n\nfrom fiftyone.server.decorators import route\nimport fiftyone.server.view as fosv\n\n\nclass Frames(HTTPEndpoint):\n    @route\n    async def post(self, request: Request, data: dict):\n        start_frame = int(data.get(\"frameNumber\", 1))\n        frame_count = int(data.get(\"frameCount\", 1))\n        num_frames = int(data.get(\"numFrames\"))\n        extended = data.get(\"extended\", None)\n        dataset = data.get(\"dataset\")\n        stages = data.get(\"view\")\n        sample_id = data.get(\"sampleId\")\n\n        view = fosv.get_view(dataset, stages=stages, extended_stages=extended)\n        view = fov.make_optimized_select_view(view, sample_id)\n\n        end_frame = min(num_frames + start_frame, frame_count)\n        support = None if stages else [start_frame, end_frame]\n        if not support:\n            view = view.set_field(\n                \"frames\",\n                F(\"frames\").filter(\n                    (F(\"frame_number\") >= start_frame)\n                    & (F(\"frame_number\") <= end_frame)\n                ),\n            )\n\n        frames = await foo.aggregate(\n            foo.get_async_db_conn()[view._dataset._sample_collection_name],\n            view._pipeline(frames_only=True, support=support),\n        ).to_list(end_frame - start_frame + 1)\n\n        return {\n            \"frames\": foj.stringify(frames),\n            \"range\": [start_frame, end_frame],\n        }\n", "path": "fiftyone/server/routes/frames.py"}]}