prompt: You will be provided with a partial code base and an issue statement explaining a problem to resolve.
  <issue>
  Spider superdrug is broken
  During the global build at 2021-06-30-14-42-26, spider **superdrug** failed with **0 features** and **2 errors**.
  
  Here's [the log](https://data.alltheplaces.xyz/runs/2021-06-30-14-42-26/logs/superdrug.txt) and [the output](https://data.alltheplaces.xyz/runs/2021-06-30-14-42-26/output/superdrug.geojson) ([on a map](https://data.alltheplaces.xyz/map.html?show=https://data.alltheplaces.xyz/runs/2021-06-30-14-42-26/output/superdrug.geojson))
  
  </issue>
  <code>
  [start of locations/spiders/superdrug.py]
  1 # -*- coding: utf-8 -*-
  2 import json
  3 
  4 import scrapy
  5 
  6 from locations.items import GeojsonPointItem
  7 
  8 
  9 class SuperdrugSpider(scrapy.Spider):
  10     name = "superdrug"
  11     item_attributes = {"brand": "Superdrug", "brand_wikidata": "Q7643261"}
  12     allowed_domains = ["superdrug.com"]
  13     download_delay = 0.5
  14 
  15     start_urls = ["https://www.superdrug.com/stores/a-to-z"]
  16 
  17     def parse(self, response):
  18         urls = response.xpath('//a[@class="row store-link"]/@href').extract()
  19 
  20         for url in urls:
  21             yield scrapy.Request(response.urljoin(url), callback=self.parse_location)
  22 
  23     def parse_location(self, response):
  24         data = json.loads(
  25             response.xpath(
  26                 '//script[@type="application/ld+json" and contains(text(), "streetAddress")]/text()'
  27             ).extract_first()
  28         )
  29 
  30         properties = {
  31             "name": data["name"],
  32             "ref": data["name"],
  33             "addr_full": data["address"]["streetAddress"],
  34             "city": data["address"]["addressLocality"],
  35             "state": data["address"]["addressRegion"],
  36             "postcode": data["address"]["postalCode"],
  37             "country": data["address"]["addressCountry"],
  38             "phone": data.get("telephone"),
  39             "website": response.url,
  40             "lat": float(
  41                 response.xpath(
  42                     '//div[@class="store-locator store-locator__overview"]/@data-lat'
  43                 ).extract_first()
  44             ),
  45             "lon": float(
  46                 response.xpath(
  47                     '//div[@class="store-locator store-locator__overview"]/@data-lng'
  48                 ).extract_first()
  49             ),
  50         }
  51         yield GeojsonPointItem(**properties)
  52
  [end of locations/spiders/superdrug.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/locations/spiders/superdrug.py b/locations/spiders/superdrug.py
  --- a/locations/spiders/superdrug.py
  +++ b/locations/spiders/superdrug.py
  @@ -4,6 +4,7 @@
   import scrapy
   
   from locations.items import GeojsonPointItem
  +from locations.hours import OpeningHours
   
   
   class SuperdrugSpider(scrapy.Spider):
  @@ -14,6 +15,10 @@
   
       start_urls = ["https://www.superdrug.com/stores/a-to-z"]
   
  +    custom_settings = {
  +        "USER_AGENT": "Mozilla/5.0 (X11; Linux x86_64; rv:99.0) Gecko/20100101 Firefox/99.0"
  +    }
  +
       def parse(self, response):
           urls = response.xpath('//a[@class="row store-link"]/@href').extract()
   
  @@ -28,9 +33,11 @@
           )
   
           properties = {
  -            "name": data["name"],
  -            "ref": data["name"],
  -            "addr_full": data["address"]["streetAddress"],
  +            "name": data["name"].replace("Superdrug", "").strip(),
  +            "ref": data["@id"],
  +            "street_address": data["address"]["streetAddress"]
  +            .replace("Superdrug", "")
  +            .strip(),
               "city": data["address"]["addressLocality"],
               "state": data["address"]["addressRegion"],
               "postcode": data["address"]["postalCode"],
  @@ -48,4 +55,15 @@
                   ).extract_first()
               ),
           }
  +
  +        oh = OpeningHours()
  +
  +        for rule in data["OpeningHoursSpecification"]:
  +            oh.add_range(
  +                day=rule["dayOfWeek"][0:2],
  +                open_time=rule["opens"],
  +                close_time=rule["closes"],
  +                time_format="%I:%M %p",
  +            )
  +
           yield GeojsonPointItem(**properties)
  
verification_info: {"golden_diff": "diff --git a/locations/spiders/superdrug.py b/locations/spiders/superdrug.py\n--- a/locations/spiders/superdrug.py\n+++ b/locations/spiders/superdrug.py\n@@ -4,6 +4,7 @@\n import scrapy\n \n from locations.items import GeojsonPointItem\n+from locations.hours import OpeningHours\n \n \n class SuperdrugSpider(scrapy.Spider):\n@@ -14,6 +15,10 @@\n \n     start_urls = [\"https://www.superdrug.com/stores/a-to-z\"]\n \n+    custom_settings = {\n+        \"USER_AGENT\": \"Mozilla/5.0 (X11; Linux x86_64; rv:99.0) Gecko/20100101 Firefox/99.0\"\n+    }\n+\n     def parse(self, response):\n         urls = response.xpath('//a[@class=\"row store-link\"]/@href').extract()\n \n@@ -28,9 +33,11 @@\n         )\n \n         properties = {\n-            \"name\": data[\"name\"],\n-            \"ref\": data[\"name\"],\n-            \"addr_full\": data[\"address\"][\"streetAddress\"],\n+            \"name\": data[\"name\"].replace(\"Superdrug\", \"\").strip(),\n+            \"ref\": data[\"@id\"],\n+            \"street_address\": data[\"address\"][\"streetAddress\"]\n+            .replace(\"Superdrug\", \"\")\n+            .strip(),\n             \"city\": data[\"address\"][\"addressLocality\"],\n             \"state\": data[\"address\"][\"addressRegion\"],\n             \"postcode\": data[\"address\"][\"postalCode\"],\n@@ -48,4 +55,15 @@\n                 ).extract_first()\n             ),\n         }\n+\n+        oh = OpeningHours()\n+\n+        for rule in data[\"OpeningHoursSpecification\"]:\n+            oh.add_range(\n+                day=rule[\"dayOfWeek\"][0:2],\n+                open_time=rule[\"opens\"],\n+                close_time=rule[\"closes\"],\n+                time_format=\"%I:%M %p\",\n+            )\n+\n         yield GeojsonPointItem(**properties)\n", "issue": "Spider superdrug is broken\nDuring the global build at 2021-06-30-14-42-26, spider **superdrug** failed with **0 features** and **2 errors**.\n\nHere's [the log](https://data.alltheplaces.xyz/runs/2021-06-30-14-42-26/logs/superdrug.txt) and [the output](https://data.alltheplaces.xyz/runs/2021-06-30-14-42-26/output/superdrug.geojson) ([on a map](https://data.alltheplaces.xyz/map.html?show=https://data.alltheplaces.xyz/runs/2021-06-30-14-42-26/output/superdrug.geojson))\n", "before_files": [{"content": "# -*- coding: utf-8 -*-\nimport json\n\nimport scrapy\n\nfrom locations.items import GeojsonPointItem\n\n\nclass SuperdrugSpider(scrapy.Spider):\n    name = \"superdrug\"\n    item_attributes = {\"brand\": \"Superdrug\", \"brand_wikidata\": \"Q7643261\"}\n    allowed_domains = [\"superdrug.com\"]\n    download_delay = 0.5\n\n    start_urls = [\"https://www.superdrug.com/stores/a-to-z\"]\n\n    def parse(self, response):\n        urls = response.xpath('//a[@class=\"row store-link\"]/@href').extract()\n\n        for url in urls:\n            yield scrapy.Request(response.urljoin(url), callback=self.parse_location)\n\n    def parse_location(self, response):\n        data = json.loads(\n            response.xpath(\n                '//script[@type=\"application/ld+json\" and contains(text(), \"streetAddress\")]/text()'\n            ).extract_first()\n        )\n\n        properties = {\n            \"name\": data[\"name\"],\n            \"ref\": data[\"name\"],\n            \"addr_full\": data[\"address\"][\"streetAddress\"],\n            \"city\": data[\"address\"][\"addressLocality\"],\n            \"state\": data[\"address\"][\"addressRegion\"],\n            \"postcode\": data[\"address\"][\"postalCode\"],\n            \"country\": data[\"address\"][\"addressCountry\"],\n            \"phone\": data.get(\"telephone\"),\n            \"website\": response.url,\n            \"lat\": float(\n                response.xpath(\n                    '//div[@class=\"store-locator store-locator__overview\"]/@data-lat'\n                ).extract_first()\n            ),\n            \"lon\": float(\n                response.xpath(\n                    '//div[@class=\"store-locator store-locator__overview\"]/@data-lng'\n                ).extract_first()\n            ),\n        }\n        yield GeojsonPointItem(**properties)\n", "path": "locations/spiders/superdrug.py"}]}