diff --git a/output/motorcycles_liked_1.svg b/output/motorcycles_liked_1.svg
new file mode 100644
index 0000000..5aab953
--- /dev/null
+++ b/output/motorcycles_liked_1.svg
@@ -0,0 +1,644 @@
+
+
diff --git a/output/motorcycles_liked_2.svg b/output/motorcycles_liked_2.svg
new file mode 100644
index 0000000..c246b4e
--- /dev/null
+++ b/output/motorcycles_liked_2.svg
@@ -0,0 +1,585 @@
+
+
diff --git a/quick_draw_api.py b/quick_draw_api.py
new file mode 100644
index 0000000..1074ed7
--- /dev/null
+++ b/quick_draw_api.py
@@ -0,0 +1,460 @@
+"""Quick draw dataset
+
+Example contributed by Blair Morrison (https://github.com/blrm) and adapted by Antoine Beyeler
+"""
+
+import pathlib
+import random
+import struct
+import urllib.request
+from itertools import islice
+
+import vpype as vp
+from shapely.geometry import MultiLineString
+
+import vsketch
+
+quick_draw_categories = (
+ "aircraft carrier",
+ "airplane",
+ "alarm clock",
+ "ambulance",
+ "angel",
+ "animal migration",
+ "ant",
+ "anvil",
+ "apple",
+ "arm",
+ "asparagus",
+ "axe",
+ "backpack",
+ "banana",
+ "bandage",
+ "barn",
+ "baseball",
+ "baseball bat",
+ "basket",
+ "basketball",
+ "bat",
+ "bathtub",
+ "beach",
+ "bear",
+ "beard",
+ "bed",
+ "bee",
+ "belt",
+ "bench",
+ "bicycle",
+ "binoculars",
+ "bird",
+ "birthday cake",
+ "blackberry",
+ "blueberry",
+ "book",
+ "boomerang",
+ "bottlecap",
+ "bowtie",
+ "bracelet",
+ "brain",
+ "bread",
+ "bridge",
+ "broccoli",
+ "broom",
+ "bucket",
+ "bulldozer",
+ "bus",
+ "bush",
+ "butterfly",
+ "cactus",
+ "cake",
+ "calculator",
+ "calendar",
+ "camel",
+ "camera",
+ "camouflage",
+ "campfire",
+ "candle",
+ "cannon",
+ "canoe",
+ "car",
+ "carrot",
+ "castle",
+ "cat",
+ "ceiling fan",
+ "cello",
+ "cell phone",
+ "chair",
+ "chandelier",
+ "church",
+ "circle",
+ "clarinet",
+ "clock",
+ "cloud",
+ "coffee cup",
+ "compass",
+ "computer",
+ "cookie",
+ "cooler",
+ "couch",
+ "cow",
+ "crab",
+ "crayon",
+ "crocodile",
+ "crown",
+ "cruise ship",
+ "cup",
+ "diamond",
+ "dishwasher",
+ "diving board",
+ "dog",
+ "dolphin",
+ "donut",
+ "door",
+ "dragon",
+ "dresser",
+ "drill",
+ "drums",
+ "duck",
+ "dumbbell",
+ "ear",
+ "elbow",
+ "elephant",
+ "envelope",
+ "eraser",
+ "eye",
+ "eyeglasses",
+ "face",
+ "fan",
+ "feather",
+ "fence",
+ "finger",
+ "fire hydrant",
+ "fireplace",
+ "firetruck",
+ "fish",
+ "flamingo",
+ "flashlight",
+ "flip flops",
+ "floor lamp",
+ "flower",
+ "flying saucer",
+ "foot",
+ "fork",
+ "frog",
+ "frying pan",
+ "garden",
+ "garden hose",
+ "giraffe",
+ "goatee",
+ "golf club",
+ "grapes",
+ "grass",
+ "guitar",
+ "hamburger",
+ "hammer",
+ "hand",
+ "harp",
+ "hat",
+ "headphones",
+ "hedgehog",
+ "helicopter",
+ "helmet",
+ "hexagon",
+ "hockey puck",
+ "hockey stick",
+ "horse",
+ "hospital",
+ "hot air balloon",
+ "hot dog",
+ "hot tub",
+ "hourglass",
+ "house",
+ "house plant",
+ "hurricane",
+ "ice cream",
+ "jacket",
+ "jail",
+ "kangaroo",
+ "key",
+ "keyboard",
+ "knee",
+ "knife",
+ "ladder",
+ "lantern",
+ "laptop",
+ "leaf",
+ "leg",
+ "light bulb",
+ "lighter",
+ "lighthouse",
+ "lightning",
+ "line",
+ "lion",
+ "lipstick",
+ "lobster",
+ "lollipop",
+ "mailbox",
+ "map",
+ "marker",
+ "matches",
+ "megaphone",
+ "mermaid",
+ "microphone",
+ "microwave",
+ "monkey",
+ "moon",
+ "mosquito",
+ "motorbike",
+ "mountain",
+ "mouse",
+ "moustache",
+ "mouth",
+ "mug",
+ "mushroom",
+ "nail",
+ "necklace",
+ "nose",
+ "ocean",
+ "octagon",
+ "octopus",
+ "onion",
+ "oven",
+ "owl",
+ "paintbrush",
+ "paint can",
+ "palm tree",
+ "panda",
+ "pants",
+ "paper clip",
+ "parachute",
+ "parrot",
+ "passport",
+ "peanut",
+ "pear",
+ "peas",
+ "pencil",
+ "penguin",
+ "piano",
+ "pickup truck",
+ "picture frame",
+ "pig",
+ "pillow",
+ "pineapple",
+ "pizza",
+ "pliers",
+ "police car",
+ "pond",
+ "pool",
+ "popsicle",
+ "postcard",
+ "potato",
+ "power outlet",
+ "purse",
+ "rabbit",
+ "raccoon",
+ "radio",
+ "rain",
+ "rainbow",
+ "rake",
+ "remote control",
+ "rhinoceros",
+ "rifle",
+ "river",
+ "roller coaster",
+ "rollerskates",
+ "sailboat",
+ "sandwich",
+ "saw",
+ "saxophone",
+ "school bus",
+ "scissors",
+ "scorpion",
+ "screwdriver",
+ "sea turtle",
+ "see saw",
+ "shark",
+ "sheep",
+ "shoe",
+ "shorts",
+ "shovel",
+ "sink",
+ "skateboard",
+ "skull",
+ "skyscraper",
+ "sleeping bag",
+ "smiley face",
+ "snail",
+ "snake",
+ "snorkel",
+ "snowflake",
+ "snowman",
+ "soccer ball",
+ "sock",
+ "speedboat",
+ "spider",
+ "spoon",
+ "spreadsheet",
+ "square",
+ "squiggle",
+ "squirrel",
+ "stairs",
+ "star",
+ "steak",
+ "stereo",
+ "stethoscope",
+ "stitches",
+ "stop sign",
+ "stove",
+ "strawberry",
+ "streetlight",
+ "string bean",
+ "submarine",
+ "suitcase",
+ "sun",
+ "swan",
+ "sweater",
+ "swing set",
+ "sword",
+ "syringe",
+ "table",
+ "teapot",
+ "teddy-bear",
+ "telephone",
+ "television",
+ "tennis racquet",
+ "tent",
+ "The Eiffel Tower",
+ "The Great Wall of China",
+ "The Mona Lisa",
+ "tiger",
+ "toaster",
+ "toe",
+ "toilet",
+ "tooth",
+ "toothbrush",
+ "toothpaste",
+ "tornado",
+ "tractor",
+ "traffic light",
+ "train",
+ "tree",
+ "triangle",
+ "trombone",
+ "truck",
+ "trumpet",
+ "t-shirt",
+ "umbrella",
+ "underwear",
+ "van",
+ "vase",
+ "violin",
+ "washing machine",
+ "watermelon",
+ "waterslide",
+ "whale",
+ "wheel",
+ "windmill",
+ "wine bottle",
+ "wine glass",
+ "wristwatch",
+ "yoga",
+ "zebra",
+ "zigzag",
+)
+
+
+def unpack_drawing(file_handle):
+ (key_id,) = struct.unpack("Q", file_handle.read(8))
+ (country_code,) = struct.unpack("2s", file_handle.read(2))
+ (recognized,) = struct.unpack("b", file_handle.read(1))
+ (timestamp,) = struct.unpack("I", file_handle.read(4))
+ (n_strokes,) = struct.unpack("H", file_handle.read(2))
+ image = []
+ for i in range(n_strokes):
+ (n_points,) = struct.unpack("H", file_handle.read(2))
+ fmt = str(n_points) + "B"
+ x = struct.unpack(fmt, file_handle.read(n_points))
+ y = struct.unpack(fmt, file_handle.read(n_points))
+ image.append((x, y))
+
+ return {
+ "key_id": key_id,
+ "country_code": country_code,
+ "recognized": recognized,
+ "timestamp": timestamp,
+ "image": image,
+ }
+
+
+def unpack_drawings(filename):
+ with open(filename, "rb") as f:
+ while True:
+ try:
+ yield unpack_drawing(f)
+ except struct.error:
+ break
+
+
+def quickdraw_to_linestring(qd_image):
+ """Returns a Shapely MultiLineString for the provided quickdraw image.
+ This MultiLineString can be passed to vsketch
+ """
+ linestrings = []
+ for i in range(0, len(qd_image["image"])):
+ line = zip(qd_image["image"][i][0], qd_image["image"][i][1])
+ linestrings.append(tuple(line))
+ return MultiLineString(linestrings)
+
+
+class QuickDrawSketch(vsketch.SketchClass):
+ category = vsketch.Param("crab", choices=quick_draw_categories)
+ page_size = vsketch.Param("a4", choices=vp.PAGE_SIZES.keys())
+ landscape = vsketch.Param(False)
+ margins = vsketch.Param(10, 0, unit="mm")
+ layer_count = vsketch.Param(2, 1)
+ columns = vsketch.Param(9, 1)
+ rows = vsketch.Param(13, 1)
+ scale_factor = vsketch.Param(3.0)
+
+ def draw(self, vsk: vsketch.Vsketch) -> None:
+ vsk.size(self.page_size, landscape=self.landscape)
+ vsk.penWidth("0.5mm")
+
+ # obtain the datafile
+ file_name = self.category + ".bin"
+ file_path = pathlib.Path(file_name)
+ url = "https://storage.googleapis.com/quickdraw_dataset/full/binary/"
+ url += file_name.replace(" ", "%20")
+ if not file_path.exists():
+ urllib.request.urlretrieve(url, file_name)
+
+ # extract some drawings
+ drawing_set = unpack_drawings(file_name)
+ drawing_subset = list(islice(drawing_set, 10000))
+
+ # draw stuff
+
+ width = vsk.width - 2 * self.margins
+ height = vsk.height - 2 * self.margins
+
+ n = self.columns * self.rows
+ samples = random.sample(drawing_subset, n)
+ for j in range(self.rows):
+ with vsk.pushMatrix():
+ for i in range(self.columns):
+ idx = j * self.columns + i
+ with vsk.pushMatrix():
+ vsk.scale(self.scale_factor * min(1 / self.columns, 1 / self.rows))
+ drawing = quickdraw_to_linestring(samples[idx])
+ vsk.stroke((idx % self.layer_count) + 1)
+ vsk.geometry(drawing)
+ vsk.translate(width / self.columns, 0)
+
+ vsk.translate(0, height / self.rows)
+
+ def finalize(self, vsk: vsketch.Vsketch) -> None:
+ vsk.vpype("linemerge linesort")
+
+
+if __name__ == "__main__":
+ QuickDrawSketch.display()
\ No newline at end of file