One task compositors are often asked to complete is to create a starry night sky. Whether you are working on an Epic Space Odyssey or the newest Rom-Com miniseries, you might be asked to sprinkle some stars in the sky. Some directors are a bit pickier than others, and you might be asked to ensure the constellations visible are appropriate for the geographic location and time of year. I’ve seen many techniques used, and I wondered if I could achieve something decent using the PointRender. In this post and the next, I will break-down my (still ongoing as of the time of writing) journey.

Since PointRender is a paid Gizmo, I can’t include it with the tool, so I decided instead to keep it modular and design a gizmo that will orient your camera in the world in such a way that it will look at the right part of the sky, and that modified camera can then be used with PointRender (we’ll see in part 2 how to load accurate stars in there) or with Maas Digital’s Starpro (which is a cool plugin for stars but requires you to orient your camera yourself). You could even use it with a good old latlong map on a sphere and a scanlineRender if you’d like to keep it free (but I wouldn’t recommend it).

As always, before starting to write the actual tool, a quick check-list of the requirements is a good idea:

  • Needs to orient the sky accurately: This is dependent on location, date, and time.
  • Should accept any Nuke camera as input, and output a new camera oriented properly in space (literally).
  • Probably needs a way to indicate the North as well.
  • The time of day will just be UTC to make it easier for me.  An extended experiment could be to implement time zones, but out of scope right now.

How to easily enter location data?

The first idea that comes to my mind to let users enter a geographic location is to provide them with a Latitude and a Longitude knob.
While making a Longitude knob which accepts values from -180 to 180, and a Latitude knob that would accept values from -90 to 90 is an acceptable solution, it is not necessarily the best for user experience.
Wouldn’t it be cooler if we could just click on a world map directly, rather than having to google the coordinates of your location?

I think this would be better, so let’s see how to achieve that. This is what we’re going to make:

World Map Knob

That is not a default knob in Nuke, so we’ll have to create a custom knob using QT. Some basic understanding of Python and QT (PySide2) will be required to follow along, as I will not cover the fundamentals, but I will do my best to keep the narration accessible to even beginners.

Nuke’s PyCustom_Knob

Nuke offers a Knob called PyCustom_Knob. It doesn’t really do much by itself but is there to allow us to create custom knobs without having to dig into the C++ API.

This knob is not very well documented. There is a short tutorial by Brent Tyler which quickly touches on the subject, a few posts on the nuke forum (this one has really good info if you don’t mind reading through code, but I’ll cover most of it here), and some examples in a few Nukepedia tools such as LUE.

User Interface of LUE, featuring custom color wheels by Mads Hagbarth.

Adding a custom knob on the selected node takes a single (long) line of python:

nuke.selectedNode().addKnob(nuke.PyCustom_Knob("name", "label", "some_code()"))

If you read the PyCustom_Knob entry on the API reference, you will notice that the knob has the “command” and “setCommand” methods, as well as the regular “value” and “setValue” methods. From this, you could conclude that you can independently set the command to run for the knob and the value. Wrong! The command is stored as the knob’s value, and setCommand and setValue seem to be doing the exact same thing. This will cause us a few headaches later, but for now, just remember that the knob’s value contains the code necessary to create the custom widget.

In order to successfully create a custom widget, the minimum you need to do is create a python class with a makeUI method.

from PySide2 import QtWidgets

# Create a simple class
class SimpleClass(object):
    def makeUI(self):
        return QtWidgets.QPushButton('Test')

# Create a NoOp node on which we'll add the knob
node = nuke.createNode("NoOp")
knob = nuke.PyCustom_Knob("test", "Test", "SimpleClass()")
node.addKnob(knob)

As long as your makeUI method returns a QWidget or a subclass of it, you’ll now see the widget appear in the properties panel.

You might also notice in your terminal:

AttributeError: 'PySide2.QtWidgets.QPushButton' object has no attribute 'updateValue'

Nuke is expecting the QT widget to have a method called “updateValue”, which it is calling after is calls the main class’s makeUI method. You could think of it as nuke doing:

exec(knob.value()).makeUI().updateValue()  #This makes me wince a bit

It is doing this every time you open the properties panel for the node containing the knob. This means every time you show the knob, it will actually be a new instance of the class. It doesn’t seem to call these functions at any other time, so I am not too sure what advantage having these methods provides over putting code in the __init__, I’m wondering if maybe Foundry originally had bigger plans for the knob and that somehow it got cut short. A working piece of code would be something like this:

from PySide2 import QtWidgets

# Subclass QT Button
class MyButton(QtWidgets.QPushButton):
    def updateValue(self):
        return

# Create a simple class
class SimpleClass(object):
    def makeUI(self):
        return MyButton('Test')

# Create a NoOp node on which we'll add the knob
node = nuke.createNode("NoOp")
knob = nuke.PyCustom_Knob("test", "Test", "SimpleClass()")
node.addKnob(knob)

Once the objects have been created, they can be accessed using:

knob.getObject()

Because the code is only run when the knob needs to be shown, your object will not have been created if the knob was never shown. Also due to QT’s garbage collection, the QT object will get destroyed as soon as the properties are closed, and as we have seen above, a new instance of your object gets created every time, which makes this whole ordeal quite unsuitable for storing data.

On top of that, you may remember earlier I mentioned that the code to run is stored as our knob’s value, so how do we store the actual value that we’re interested in?

Storing our custom knob’s value

So far, I have used a button as an example. What if we now want to make a custom SpinBox instead:

from PySide2 import QtWidgets

# Notice that we can actually condense the 2 classes into a single one if we return self in makeUI
class MyBox(QtWidgets.QSpinBox):
    def __init__(self):
        super(MyBox, self).__init__()
        self.setSuffix(" Frame of Roto")
    
    def updateValue(self):
        return
    
    def makeUI(self):
        return self

# Create a NoOp node on which we'll add the knob
node = nuke.createNode("NoOp")
knob = nuke.PyCustom_Knob("todo", "To Do:", "MyBox()")
node.addKnob(knob)

This is visually functional, but really that Spin Box doesn’t do anything. Also, notice how if you set a value, close the properties, and re-open them, the value will go back to 0.
While there is a hack that allows you to store the values directly without creating other knobs, I believe the most reliable way to handle this is to use a regular knob to store value. You can pick the most suitable knob for the job. In this situation, an Int_Knob would be perfect. Also, to avoid confusion, I like to make the storage knob invisible if the user isn’t meant to interact with it directly.

from PySide2 import QtWidgets

class MyBox(QtWidgets.QSpinBox):
    def __init__(self, node):
        super(MyBox, self).__init__()
        self.node = node
        self.setSuffix(" Frame of Roto")
        self.valueChanged.connect(self.store_value)

    def updateValue(self):
        self.setValue(self.node.knob('storage_knob').value())

    def store_value(self, value):  # This could be named anything I want
        self.node.knob('storage_knob').setValue(value)
    
    def makeUI(self):
        return self

# Create a NoOp node on which we'll add the knobs
node = nuke.createNode("NoOp")
storage = nuke.Int_Knob('storage_knob')
storage.setFlag(nuke.INVISIBLE)
node.addKnob(storage)
knob = nuke.PyCustom_Knob("todo", "To Do:", "MyBox(nuke.thisNode())")
node.addKnob(knob)

Okay, I have added quite a bit at once, but here are the key points:

  • Lines 21 to 23: I added a hidden knob
  • Line 24: Notice how I changed the code to call “MyBox(nuke.thisNode())”. When Nuke creates the custom knob, it will now pass the nuke node to the object’s init method.
  • Line 4: My init method now accepts a node argument.
  • Line 6: I store the node passed as an argument as self.node. This means the node is now accessible from any method of my class (yeah I hear the guys in the back saying “Not on static methods”, let’s not get there).
  • Line 13: I added a method that can store an arbitrary value onto our newly added storage knob.
  • Line 8: I connect the valueChanged QT signal to the new store_value method. This means every time we change the value of the widget, it will change the value of the hidden knob.
  • Line 11: In the updateValue method that nuke calls every time we open nuke, I read the value from the hidden knob and set it on the widget.

That’s about it, the custom knob can now store and retrieve values, and it should be robust enough to be able to copy and paste the node, or even save the nuke script, close it, and re-open it.

As long as you don’t close nuke… do not close nuke… do not crash…

Surviving a restart of Nuke

If you do close nuke, upon re-opening your script, you will be greeted with the error:

Traceback (most recent call last):
  File "string", line 1, in module;
NameError: name 'MyBox' is not defined

The problem we are having here is that our tool calls a class named “MyBox”, but that doesn’t exist until we run our code to define that class.

Now comes our first big architecture question: Do we want to make the tool self-contained, or do we require installation?

Both methods would solve the issue and have pros and cons. I’ll go quickly over both methods so you can make your own decision when the time comes.

Self contained code

The idea with the self-contained code would be that you include the whole class definition directly in the knob, for example:

# Create a NoOp node on which we'll add the knobs
node = nuke.createNode("NoOp")
storage = nuke.Int_Knob('storage_knob')
storage.setFlag(nuke.INVISIBLE)
node.addKnob(storage)
knob = nuke.PyCustom_Knob("todo", "To Do:", """
from PySide2 import QtWidgets

class MyBox(QtWidgets.QSpinBox):
    def __init__(self, node):
        super(MyBox, self).__init__()
        self.node = node
        self.setSuffix(" Frames of Roto")
        self.valueChanged.connect(self.store_value)

    def updateValue(self):
        self.setValue(self.node.knob('storage_knob').value())

    def store_value(self, value):  # This could be named anything I want
        self.node.knob('storage_knob').setValue(value)
    
    def makeUI(self):
        return self
MyBox(nuke.thisNode())""")
node.addKnob(knob)

Sadly, this fails, as the code in the knob is being evaluated by python not executed (see exec vs eval for details). In short, that means we need a python one-liner. We could try defining the class in an onCreate knob (I haven’t tried what would happen in a non-GUI session with the PySide imports, but it might be okay and shorter, if you try let me know) but the suggested way in the forum thread is to define the class in a hidden python button and have another PyCustom_Knob to execute the button before running our real PyCustom_Knob. That’s a mouthful, so let’s put that in code:

# I put all my definition code into a multiline string (using """)
the_code = """from PySide2 import QtWidgets

class MyBox(QtWidgets.QSpinBox):
    def __init__(self, node):
        super(MyBox, self).__init__()
        self.node = node
        self.setSuffix(" Frame of Roto")
        self.valueChanged.connect(self.store_value)

    def updateValue(self):
        self.setValue(self.node.knob('storage_knob').value())

    def store_value(self, value):  # This could be named anything I want
        self.node.knob('storage_knob').setValue(value)
    
    def makeUI(self):
        return self
"""

# Create a NoOp node on which we'll add the knobs
node = nuke.createNode("NoOp")
# Storage knob as previously
storage = nuke.Int_Knob('storage_knob')
storage.setFlag(nuke.INVISIBLE)
node.addKnob(storage)
# A hidden python script button
button = nuke.PyScript_Knob('class_definitions', '', the_code)
button.setFlag(nuke.INVISIBLE)
node.addKnob(button)
# A PyCustom knob that will execute the button
init_knob = nuke.PyCustom_Knob("initialization", "", "nuke.thisNode()['class_definitions'].execute()")
node.addKnob(init_knob)
# Our real knob that will execute AFTER the init knob
knob = nuke.PyCustom_Knob("todo", "To Do:", "MyBox(nuke.thisNode())")
node.addKnob(knob)

As I mentioned previously, this code is being executed evaluated every time we open the properties, so we would basically be re-defining the whole class every time. In this case, it is fairly fast, but for heavier code, it could end up taking some time. There are ways to ensure the definition code only runs once. In the nuke forum post linked above, Wouter Gilsing suggests adding a variable, with a condition to check if things have already been initialized. I prefer skipping this variable and directly checking if my class is defined. It’s only one line change in the code above:

init_knob = nuke.PyCustom_Knob("initialization", "", "None if 'MyBox' in globals() else nuke.thisNode()['class_definitions'].execute()")

Luckily Nuke doesn’t complain if our eval returns None in this case, so we can use this to our advantage to skip executing the button. Still, the code/tool became a lot more complicated, adding 2 extra knobs to achieve the desired effect.

Pros:

  • Portability: Anyone opening the nuke script in any Nuke will be able to see your custom knob

Cons:

  • File Size: Every copy of your node in a script will contain a full copy of the required code, which could quickly add to the nk file size.
  • Hard to maintain: There are many knobs, each making assumptions of what the other knobs contain. It’s easy to make mistakes, and once the node starts spreading, it’s nearly impossible to do a quick fix to the code.

Both cons could be reduced by wrapping the whole thing into a .gizmo, but that would also reduce portability.

Installing the code in a menu.py

The other common method is to define your class in a menu.py or another python module and call it a day.
If you were to put the definition of our class definition in your menu.py, you wouldn’t need to make too many further changes and it would work perfectly fine… for you.

However, anyone who doesn’t have your class in their menu.py would get the error message we got earlier and the custom widget wouldn’t show.

We can mitigate at least the error message by cheating nuke into believing a class was properly created. Ideally, I would prefer to use “MyClass if ‘MyClass’ in globals() else None” but it errors in this case for some reason. I can’t quite wrap my head around why it works above but not here, the only difference being a single custom knob vs two above. The code below assumes that MyBox is defined in the menu.py, and swallows the error if it wasn’t.

# Create a NoOp node on which we'll add the knobs
node = nuke.createNode("NoOp")
storage = nuke.Int_Knob('storage_knob')
storage.setFlag(nuke.INVISIBLE)
node.addKnob(storage)
knob = nuke.PyCustom_Knob("todo", "To Do:", "MyBox(nuke.thisNode()) if 'MyBox' in globals() else type('Dummy', (), {'makeUI': classmethod(lambda self: None)})")
node.addKnob(knob)

Pros:

  • File Size: The code isn’t embedded in the nk file, and less knobs are created, keeping the files lighter.
  • Easy to maintain: Changing the definition of ‘MyBox’ in the menu.py would reflect on all the nodes using this custom knob.
  • Safety: Less arbitrary code being run from nodes, easier to control what is happening when the code is legible in a python file rather than stuffed into a string somewhere in a .nk file. Can also be namespaced to avoid accidentally overwriting other classes or variables.

Cons:

  • Portability: Opening the node somewhere the class isn’t defined would not show the knob, which could be problematic for your tool.

My Decision for this widget

Because my custom widget is there for convenience but not fully required, I have decided to go with the second method and requiring an installation. My storage knobs “latitude” and “longitude” will not be hidden, and can be interacted with directly. If a script is shared with someone who doesn’t have the code installed, they will just never know that there was supposed to be a map there.

Customizing the widget further

We can now put as many default QT widgets as we want into our node, but what we’re aiming for here isn’t a default widget, we need to create our own graphical elements.

In Qt, this is achieved by re-defining the paintEvent method of our class. I’m not going to explain in detail how that works, there is plenty on google about it, but basically, you can combine basic shapes such as dots, rectangles, lines, ellipses, text, ramps, etc to draw the look of your desired widget.

from PySide2 import QtCore, QtGui, QtWidgets

class MyBox(QtWidgets.QWidget):

    def updateValue(self):
        pass

    def paintEvent(self, e):
        painter = QtGui.QPainter(self)

        # We can define brushes (draws filled areas) and pens (draws borders)
        yellow_brush = QtGui.QBrush()
        yellow_brush.setColor(QtGui.QColor('yellow'))
        yellow_brush.setStyle(QtCore.Qt.SolidPattern)

        black_brush = QtGui.QBrush()
        black_brush.setColor(QtGui.QColor('black'))
        black_brush.setStyle(QtCore.Qt.SolidPattern)

        black_pen = QtGui.QPen()
        black_pen.setColor(QtGui.QColor('black'))
        black_pen.setWidth(5)

        # Now we can set our brush and pen and start drawing
        painter.setPen(black_pen)
        painter.setBrush(yellow_brush)
        painter.drawEllipse(0, 0, 100, 100)

        painter.setBrush(QtCore.Qt.NoBrush)  # This removed the brush (fill)
        painter.drawArc(25, 55, 50, 15, 16*-15, 16*-165)
    
        painter.setBrush(black_brush)
        painter.drawChord(25, 35, 10, 10, 16*0, 16*180)
        painter.drawChord(65, 35, 10, 10, 16*0, 16*180)

    def makeUI(self):
        return self

    def sizeHint(self):
        return QtCore.QSize(self.size().width(), 100)  # This is required to define the height of our widget. Keeping the width allows the width to adapt to the Nuke properties width.

# Create a NoOp node on which we'll add the knobs
node = nuke.createNode("NoOp")
knob = nuke.PyCustom_Knob("test", "", "MyBox()")
node.addKnob(knob)

This gives us:

By the way, it took me a few iterations to draw this little guy, when I first entered the numbers out of my head he looked like this:

Don’t give up if things don’t look the way you want on the first try.

You can enable anti-aliasing by adding the line:

painter.setRenderHint(painter.Antialiasing)

If you would like to learn how to make custom widgets and get introduced to some of the other concepts I will use later on to add interactivity to the widget, I highly recommend reading the tutorial “Create custom GUI Widgets for your Python apps with PyQt5“. It shows all the code snippets in both PyQt5 and PySide2, so you should not have any problems following along for Nuke. Just keep in mind you don’t need to create a QApplication, as you are already in one: Nuke. There is also a great into to QPainter there and other Qt resources if you want.

Drawing a world map

I could possibly attempt to draw the world map this way, but it would be extremely painful. I could also load an image (jpg or png) but I would prefer to use vector graphics over rasterized images.

Luckily, PySide2 supports the SVG image format, which allows us to draw a wide range of vector graphics in the software of our choice, and load the files directly into our widget.

I downloaded a copyright-free equirectangular map of the world on Wikipedia, and traced it quickly in Krita (Side note: I have been using Krita exclusively as a Photoshop alternative over the last couple of years at home, definitely worth checking out). I didn’t need a super detailed map, so I kept it really rough so that the file size would be smaller.

I ended up with this world map: (58kb in SVG and in 53kb in PNG at 800*400px, not a huge difference, but SVG is size independent)

Another advantage of SVG is that it is text-based, and could be directly embedded in Python code. Whether it is a good practice could be debated, but it sure is convenient for me right now.
Here is a python string of my SVG map. I will only paste it here once but will use it multiple times in the code further, so keep that in mind. For the final tool, I think I will not embed the SVG directly in Python as I think it might be less memory efficient, but right now it allows you to simply copy and paste the following few lines.

SVG_MAP = """<?xml version="1.0" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 20010904//EN" "http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd">
<!-- Created using Krita: http://krita.org -->
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:krita="http://krita.org/namespaces/svg/krita" xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" width="1440pt" height="720pt" viewBox="0 0 1440 720">
<defs/>
<path id="shape0" transform="translate(39.5457469778519, 63.7055088720791)" fill="#444444" fill-rule="evenodd" stroke="#000000" stroke-opacity="0" stroke-width="0" stroke-linecap="square" stroke-linejoin="bevel" d="M0 84.6299L36.139 71.4692L44.5462 67.5246L48.3713 63.2573L39.8047 61.3208L31.796 57.3403L26.6162 56.8383L19.9621 55.2246L17.1332 49.6663L21.1973 44.108L29.6045 43.068L35.9398 40.8088L34.346 38.0117L28.5287 37.8324L17.0136 37.9042L10.6385 34.6409L14.9019 29.6563L23.4286 29.7639L27.2935 31.8079L36.0992 31.9872L33.9874 30.1225L27.5725 28.3654L19.8426 24.2056L15.6988 20.1534L23.588 19.5796L29.4451 17.2487L34.9039 15.7785L49.0487 10.2201L65.2654 11.6545L100.647 15.1688L131.686 20.2251L140.452 17.679L167.546 14.3082L176.511 18.5038L181.532 16.7467L186.871 18.7548L198.386 16.9977L223.927 22.6636L225.959 25.2097L242.893 25.389L252.694 21.6954L265.285 24.4925L284.769 25.4607L285.885 22.7712L283.375 19.8665L287.638 17.2487L296.882 20.8347L294.412 24.3132L296.284 27.2178L300.707 24.7076L304.094 21.1933L297.48 18.6831L293.655 13.4475L297.4 7.38719L297.798 5.16386L299.95 0L311.784 0.0358601L315.928 2.07989L307.959 6.70584L309.553 11.6545L314.095 14.3799L314.095 17.1053L318.199 20.261L319.075 23.4167L324.813 19.7231L327.682 24.6L331.228 27.1461L334.734 23.5601L337.005 18.5038L340.472 16.2446L353.621 18.7907L355.493 22.1616L353.501 23.9187L356.211 27.3254L348.202 30.0508L342.066 32.5969L334.296 30.5528L334.017 33.5651L330.431 36.2904L319.514 41.2033L306.724 47.945L303.656 54.1488L303.775 58.9899L308.158 61.8946L312.342 67.7398L320.948 66.6998L339.954 75.7366L349.875 76.4179L350.832 82.5859L358.282 89.9013L364.02 88.8614L364.538 83.6975L361.271 78.8206L370.674 74.8401L373.623 69.3176L369.479 63.5441L366.291 60.5677L369.08 56.4797L367.367 49.0208L370.037 46.4389L386.732 46.8333L398.286 53.1447L402.43 54.6508L403.745 61.0698L409.881 62.8987L416.296 61.0698L421.197 54.8301L433.589 67.166L435.143 70.6444L448.69 78.0675L456.34 83.5899L456.3 89.0048L447.654 91.5509L440.402 94.9576L421.675 92.7343L412.87 96.4279L406.335 100.193L397.729 106.827L412.87 99.0457L422.711 98.6512L422.552 103.241L419.763 103.815L421.994 108.369L422.99 110.808L428.608 111.382L434.386 110.377L438.848 108.871L440.283 113.031L433.071 115.254L416.535 121.458L414.463 118.84L415.22 115.972L405.777 118.267L399.402 121.96L397.768 125.295L398.725 128.881L387.09 131.714L383.903 138.564L381.352 141.396L377.806 139.101L375.097 141.181L377.248 149.931L374.938 155.31L365.016 161.729L356.968 167.754L355.135 173.204L357.247 182.994L359.757 191.35L358.84 195.904L353.9 191.816L348.401 185.325L347.684 180.197L341.468 176.683L339.755 177.436L335.133 174.459L320.032 174.711L321.386 178.512L317.92 178.799L308.596 177.543L296.683 181.345L290.467 186.222L290.826 193.752L288.873 204.259L290.985 213.009L297.759 221.078L309.393 223.05L316.844 220.325L320.231 213.045L328.479 209.997L332.224 211.575L329.873 219.321L329.395 224.807L327.084 228.931L326.486 232.66L338.998 233.629L346.01 234.597L346.688 243.419L345.931 252.886L350.433 258.803L359.239 260.237L365.813 257.44L371.63 263.536L376.85 257.332L380.476 253.639L391.075 246.467L394.661 247.148L392.419 252.384L392.18 256.472L392.937 260.56L394.611 254.428L398.396 251.595L404.612 250.232L410.588 254.894L417.003 254.894L426.048 254.248L430.59 255.683L441.388 262.675L449.357 270.17L459.199 272.896L471.232 276.374L477.488 287.24L482.508 290.18L479.759 296.294L481.233 296.294L483.982 296.294L486.652 296.294L496.772 301.046L503.347 304.345L512.551 306.389L522.95 308.863L531.915 315.067L537.374 318.832L541.438 329.555L533.708 339.954L530.122 347.52L525.699 353.15L523.787 362.187L519.882 378.396L513.587 387.756L506.694 388.544L494.382 390.481L486.532 397.545L485.775 402.781L485.735 411.351L477.507 420.101L472.128 426.807L465.873 430.895L457.585 435.88L452.844 434.589L446.389 431.756L448.66 435.952L452.804 441.115L450.294 446.745L445.472 451.013L438.699 452.375L431.088 451.407L431.806 456.141L428.26 460.731L422.123 460.659L419.374 460.731L422.283 466.935L421.087 469.875L418.737 473.748L414.991 477.37L410.847 480.633L414.792 483.287L418.259 485.438L413.915 491.427L408.576 496.483L405.11 499.783L405.588 505.341L409.533 510.576L418.059 514.27L425.51 514.987L410.17 515.955L398.695 516.422L389.252 513.768L380.326 504.05L378.733 491.14L380.805 483.072L381.92 476.581L384.948 473.856L384.55 470.341L383.793 466.253L385.626 459.87L386.662 453.344L385.945 447.247L390.407 440.111L393.913 432.581L394.272 422.253L393.595 416.444L394.71 409.451L398.137 394.39L398.854 385.927L397.778 372.085L391.642 365.702L377.896 356.844L371.879 346.445L362.157 325.682L355.105 318.545L353.352 309.545L358.93 308.182L356.579 296.294L360.404 296.294L368.054 283.187L368.532 271.927L365.225 263.5L361.6 259.125L358.731 264.935L356.26 267.05L349.407 263.285L340.562 257.368L332.473 249.658L326.855 243.634L310.539 240.747L300.578 232.822L293.326 234.973L265.913 222.602L256.948 213.959L255.872 208.688L246.668 195.205L238.54 187.244L228.658 174.693L222.442 171.896L221.765 173.617L228.778 184.626L235.033 194.595L238.818 198.97L240.412 202.412L236.667 200.153L231.646 193.268L223.757 187.997L221.127 183.55L216.505 173.33L209.971 168.274L197.998 157.336L188.156 143.458L182.578 131.015L183.494 116.205L183.893 109.069L180.665 103.618L186.801 103.905L186.961 99.8884L181.741 96.6251L167.098 89.2917L158.452 79.1792L151.24 72.294L143.59 69.9272L135.86 65.3013L126.377 59.9223L113.428 56.5156L93.067 53.5033L88.3653 53.0371L86.0145 56.2287L76.8104 58.954L74.2205 58.201L72.8658 54.0771L64.6578 57.4121L65.0164 61.7511L55.2943 66.3771L30.7501 77.3503Z"/><path id="shape1" transform="translate(380.51292369053, 267.017888614435)" fill="#444444" fill-rule="evenodd" d="M0 5.21402L5.53002 1.09385L15.638 0L31.9647 6.39902L39.966 10.6468L42.4981 12.397L33.7473 13.4726L29.0478 12.9439L29.068 11.686L16.509 5.06817L9.86491 3.40917Z"/><path id="shape2" transform="translate(406.583014204894, 285.977954443064)" fill="#444444" fill-rule="evenodd" d="M0 0.455771L3.72719 0L8.46721 2.67993L4.74002 3.06278L1.15462 2.11478Z"/><path id="shape3" transform="translate(423.314867169047, 280.198780531837)" fill="#444444" fill-rule="evenodd" d="M3.20052 0.783926L5.57053 4.97702L1.37744 5.39633L0 6.90949L8.69003 7.20118L11.9513 8.93311L14.139 7.31056L22.7075 6.50841L17.5826 2.91693L11.8298 0Z"/><path id="shape4" transform="translate(450.458551154478, 285.795646117788)" fill="#444444" fill-rule="evenodd" d="M0 0.492232L0.911542 2.20593L6.19848 2.22416L5.20592 0Z"/><path id="shape5" transform="translate(216.852344605004, 61.7199383949828)" fill="#444444" fill-rule="evenodd" d="M0 10.4121L6.50265 4.07678L4.64024 0.738651L17.0773 0L25.5213 1.42048L30.856 0.497169L40.3575 3.8211L24.3692 8.70755L20.234 12.6423L12.6423 13.3241L9.99072 14.1764L5.49253 11.5911Z"/><path id="shape6" transform="translate(243.936199428118, 65.2711431357758)" fill="#444444" fill-rule="evenodd" d="M0 7.51435L2.55687 4.53134L16.446 1.23582L18.6083 1.81822L21.0863 3.46598L25.7423 2.68471L32.9236 3.60802L34.3283 2.358L41.1466 6.46319L45.1082 8.11095L46.4182 6.39217L43.1511 2.14493L47.9649 0.724446L51.0269 0L56.5352 0.41194L55.0831 3.92053L58.1135 9.16211L59.2025 11.0513L71.829 14.5031L71.2608 16.7475L68.1516 19.2475L63.4482 19.3896L49.922 18.1964L39.4263 19.2049L23.4537 20.4833L20.0761 18.3668L9.29626 16.8469L7.62325 15.1139L25.3793 12.9406L19.7131 12.0031L3.01458 11.4207L1.72036 10.0712Z"/><path id="shape7" transform="translate(228.437163626079, 49.0208302419069)" fill="#444444" fill-rule="evenodd" d="M0 6.05125L7.10241 4.27565L15.578 1.84663L23.217 1.53412L26.7208 0L28.6148 1.23582L26.4999 3.73587L23.7378 5.78136L20.7548 8.8496L16.6354 9.51723L13.9996 7.31548L9.86446 8.09675L6.55 7.85526Z"/><path id="shape8" transform="translate(250.549331812084, 53.4527337584166)" fill="#444444" fill-rule="evenodd" d="M0 5.45465L5.65036 1.80401L11.0008 0L18.5294 1.30684L25.3635 4.74441L30.9349 5.0001L32.387 3.46598L30.6982 0.965928L33.839 0.0284096L38.0689 2.81255L42.0936 4.57395L45.9447 2.6563L46.3551 5.42624L42.283 6.59104L28.7253 7.50014L19.2396 9.24734L13.0369 9.78712L7.60747 7.89788Z"/><path id="shape9" transform="translate(261.202946034463, 44.9156375615502)" fill="#444444" fill-rule="evenodd" d="M1.87819 1.96027L0 4.1194L4.59289 6.15069L14.8204 5.22737L18.561 2.9546L19.9183 0.681831L15.7042 0L9.20157 0.482964Z"/><path id="shape10" transform="translate(295.957403097691, 48.2111555610061)" fill="#444444" fill-rule="evenodd" d="M0 0L3.66169 4.58816L4.90855 2.99722L1.15217 1.03695Z"/><path id="shape11" transform="translate(300.045234332648, 58.3391914817478)" fill="#444444" fill-rule="evenodd" d="M0.994337 0.298301L0 1.57673L3.99313 1.96027L4.90855 0.0710241L2.87253 0Z"/><path id="shape12" transform="translate(302.160174044943, 52.0322518620994)" fill="#444444" fill-rule="evenodd" d="M0.457711 0.681831L0 1.96027L1.81506 3.45177L6.75518 5.42624L11.3323 6.81831L15.2623 5.68193L15.8305 8.60812L25.0636 7.42912L27.8257 4.48872L26.7208 0L18.5294 1.33525L11.9005 1.80401L7.70217 2.9546L4.08783 1.64776Z"/><path id="shape13" transform="translate(308.568125710551, 64.1631672566484)" fill="#444444" fill-rule="evenodd" d="M0 4.17622L1.81506 3.537L7.10241 5.04271L9.32783 3.92053L7.32337 2.76994L7.51277 1.69037L15.7516 0.724446L21.5755 0L24.1324 7.75583L20.0761 10.8809L14.6625 10.2275L8.85434 7.88367L1.92554 6.33535Z"/><path id="shape14" transform="translate(334.24728176953, 57.7141794473683)" fill="#444444" fill-rule="evenodd" d="M0.915422 0L0 2.42902L3.31446 4.55975L9.67506 3.93473L11.206 2.27277L8.03361 0L3.10928 0.440349Z"/><path id="shape15" transform="translate(298.719451229419, 42.3729749671424)" fill="#444444" fill-rule="evenodd" d="M0 0.965928L5.80819 4.30406L16.304 6.87513L24.1324 6.44899L21.102 3.26711L12.516 1.06536L4.70337 0Z"/><path id="shape16" transform="translate(326.592462661599, 44.5889267253972)" fill="#444444" fill-rule="evenodd" d="M0 0L4.37193 3.35234L11.1271 3.79269L12.9264 2.40061L8.1441 0.539783Z"/><path id="shape17" transform="translate(332.716317947944, 51.748155482836)" fill="#444444" fill-rule="evenodd" d="M0 0L0.599759 1.74719L8.03361 3.59382L14.6467 3.73587L17.7876 5.35522L18.6872 7.98311L23.0749 9.75871L61.3017 10.7815L67.031 8.73596L67.3151 6.98877L63.1641 5.58249L54.7675 4.81543L38.2899 6.05125L28.5201 4.716L22.5541 0.894904L15.6727 1.20741L10.7325 0.0568193Z"/><path id="shape18" transform="translate(372.53716044137, 96.4933352168281)" fill="#444444" fill-rule="evenodd" d="M3.26711 0L2.05181 3.57961L0.536626 6.57683L0 8.38084L4.27723 9.07688L7.35494 10.6536L13.9207 7.34389L18.3242 8.92063L24.0061 9.64507L26.0737 7.91208L19.1134 6.42058L14.6625 3.60802L9.0753 1.83242Z"/><path id="shape19" transform="translate(384.769087881879, 108.112877128703)" fill="#444444" fill-rule="evenodd" d="M0 3.08245L2.17807 0.965928L6.29747 0L5.6188 2.23016L3.97735 3.29552Z"/><path id="shape20" transform="translate(398.153183971624, 110.38564816281)" fill="#444444" fill-rule="evenodd" d="M0 1.4631L2.27277 0L4.27723 0.468759L3.33024 3.2387L1.6888 3.537Z"/><path id="shape21" transform="translate(319.742583294914, 39.9865653813295)" fill="#444444" fill-rule="evenodd" d="M0 0L4.73494 2.9546L5.00325 1.23582Z"/><path id="shape22" transform="translate(-4.18549421235788, 71.6955455109144)" fill="#444444" fill-rule="evenodd" d="M11.2489 1.01025L14.4253 4.32043L4.18549 5.97552L0 3.15972L4.18549 0Z"/><path id="shape23" transform="translate(0, 83.603604936202)" fill="#444444" fill-rule="evenodd" d="M0 0L3.71978 0.73082L18.0018 5.63161L21.7753 9.99503L24.2591 11.8866L25.6205 8.76983L35.1737 10.4034L39.592 13.0258L30.9703 16.293L26.2176 18.3995L15.3508 16.7659L6.32302 14.208L0 12.037L0 15.0893L0 16.6584Z"/><path id="shape24" transform="translate(32.2838333897562, 103.52918451606)" fill="#444444" fill-rule="evenodd" d="M0 1.03175L2.91372 0L11.1295 2.29993L9.93532 4.16997Z"/><path id="shape25" transform="translate(50.1005448443581, 117.97361760955)" fill="#444444" fill-rule="evenodd" d="M0 1.39715L4.27506 0L6.735 1.89153L4.65718 2.8373Z"/><path id="shape26" transform="translate(100.780252225947, 125.926653687811)" fill="#444444" fill-rule="evenodd" d="M0 4.51389L8.16798 0L9.33825 3.86904L5.27814 6.53439Z"/><path id="shape27" transform="translate(186.711254657123, 142.509808645589)" fill="#444444" fill-rule="evenodd" d="M0 0L4.06011 0.300926L5.30202 4.55687L9.2666 9.3287L4.80048 6.70634Z"/><path id="shape28" transform="translate(206.032594558964, 156.545842589114)" fill="#444444" fill-rule="evenodd" d="M0 0L6.0424 1.48313L15.9061 5.50264L18.6526 8.29695L14.8791 9.35019L8.98 7.07175Z"/><path id="shape29" transform="translate(95.1737200356415, 279.893133224516)" fill="#444444" fill-rule="evenodd" d="M0 0L0.883671 4.23445L5.03931 2.77282L3.60633 0.644841Z"/><path id="shape30" transform="translate(79.4825948001543, 270.52144746743)" fill="#444444" fill-rule="evenodd" d="M0 1.44014L2.79431 1.74107L2.72266 0Z"/><path id="shape31" transform="translate(91.0180795623161, 276.496971872177)" fill="#444444" fill-rule="evenodd" d="M0 0L3.41527 1.59061L3.84516 0.236442Z"/><path id="shape32" transform="translate(353.96038487069, 359.999999999971)" fill="#444444" fill-rule="evenodd" d="M0.0963518 0L0 0L0.944248 1.49558L0.0770814 3.12585L1.03096 4.84284L2.37989 3.52475L2.87128 2.45813L3.70954 3.29061L4.8465 3.18655L5.09701 1.8251L3.84444 1.40019L2.62077 0Z"/><path id="shape33" transform="translate(473.566006718545, 316.618111833878)" fill="#444444" fill-rule="evenodd" d="M0.513368 0L0.357674 1.31035L0 2.77976L1.93144 3.00699L2.15867 1.43533L1.46436 0.306758Z"/><path id="shape34" transform="translate(472.673924984742, 294.027825098406)" fill="#444444" fill-rule="evenodd" d="M1.26238 0L0.290347 0.738492L0 1.71557L0.711141 1.73451L1.79679 1.27248L2.42377 0.829384L1.93986 0.31812Z"/><path id="shape35" transform="translate(474.066750710632, 297.508206240049)" fill="#444444" fill-rule="evenodd" d="M0 0.325694L0.458665 1.21188L1.06461 0.560497L0.563863 0Z"/><path id="shape36" transform="translate(475.316506724497, 300.602299159224)" fill="#444444" fill-rule="evenodd" d="M0 0L0.673269 1.50349L0.462873 4.01815L0.576487 4.35521L0.929953 3.16226L0.892082 1.27627Z"/><path id="shape37" transform="translate(406.837789075055, 259.537857898888)" fill="#444444" fill-rule="evenodd" d="M0.819009 0L0 2.33511L2.26321 4.94594Z"/><path id="shape38" transform="translate(410.226358641448, 252.448120097616)" fill="#444444" fill-rule="evenodd" d="M0 0L0.625197 1.46296L0.831512 2.30135L1.21288 1.43483Z"/><path id="shape39" transform="translate(425.262354595646, 274.375666297266)" fill="#444444" fill-rule="evenodd" d="M0 0L0.587685 2.03127L2.53205 0.50641Z"/><path id="shape40" transform="translate(388.175648566414, 272.805795784127)" fill="#444444" fill-rule="evenodd" d="M0 0.0450142L0.300095 1.52486L1.23789 0Z"/><path id="shape41" transform="translate(476.359921350102, 564.724837019582)" fill="#444444" fill-rule="evenodd" d="M3.12151 0.191944L0 3.73418L7.46448 4.10062L11.1676 0.471135L8.93799 0Z"/><path id="shape42" transform="translate(462.613643068605, 528.866245084988)" fill="#444444" fill-rule="evenodd" d="M0.911248 0L0 2.14628L2.3072 1.04697Z"/><path id="shape43" transform="translate(482.520541835215, 153.773158843607)" fill="#444444" fill-rule="evenodd" d="M0 13.9944L11.6136 0.366438L14.929 0L12.4473 4.29256L11.633 5.72342L13.4748 5.39188L14.929 7.90459L18.225 8.93411L20.4352 7.8348L23.4986 10.6267L22.8782 12.5636L24.0221 13.2441L23.6537 15.5474L25.0302 15.7394L25.4762 16.6817L27.764 16.3152L24.1772 20.4856L20.3577 18.3917L19.4077 16.4025L19.4077 15.5998L15.2973 19.1595L14.4055 18.0078L14.5218 15.9488L3.68377 16.4199L0.523483 15.9837Z"/><path id="shape44" transform="translate(360.117007633184, 64.8858752338071)" fill="#444444" fill-rule="evenodd" d="M4.69434 1.16825L1.31584 4.08087L0 7.98571L1.29806 9.26598L7.25488 9.05794L5.4056 10.6743L2.96952 11.6185L6.33024 12.6107L13.4962 13.7949L17.6215 14.8672L35.7232 15.9074L42.7647 15.9234L43.796 13.2668L56.8121 17.3477L57.1678 19.6042L61.222 20.8685L65.7563 22.0687L68.6725 25.5735L65.8096 28.134L64.3338 30.6145L63.9781 32.871L61.0975 33.8312L56.7766 33.6072L51.4777 33.4792L48.437 36.6958L53.7893 38.2802L61.0975 36.0877L65.6674 36.7279L72.1577 39.1124L78.0611 44.2815L84.6048 47.2741L95.2559 46.778L86.8097 40.2326L98.2966 43.7213L100.537 39.4964L98.51 36.0877L89.6014 32.4069L90.7394 29.2703L95.5049 28.9982L99.7724 32.839L101.995 35.0315L106.618 32.3429L112.806 28.3901L106.192 24.8533L93.7623 22.4528L88.3389 18.74L88.1966 14.131L81.493 12.1946L73.6157 9.45802L64.6005 6.24133L58.0569 4.2089L52.9713 2.04844L42.6758 0L32.3803 0.0480103L22.4937 0.768164L18.0839 4.80103L17.1592 8.52982L13.8696 4.25691L15.8434 1.60034L18.0483 0.304065Z"/><path id="shape45" transform="translate(409.425329531581, 87.4346970871636)" fill="#444444" fill-rule="evenodd" d="M2.47164 0L0 2.96063L4.7299 4.72101L9.95768 3.04065L8.17953 0L3.87638 0.144031Z"/><path id="shape46" transform="translate(464.530446575625, 160.23426458959)" fill="#444444" fill-rule="evenodd" d="M0 0L2.8984 4.25691L6.89925 1.79238L2.80949 0Z"/><path id="shape47" transform="translate(334.138118958983, 34.4953765116466)" fill="#444444" fill-rule="evenodd" d="M0 5.79324L7.64608 1.02422L13.674 0L23.6673 3.37672L31.7757 3.90484L37.2702 6.0973L40.8621 8.48181L31.3845 11.5705L21.7824 14.179L13.4429 11.8745Z"/><path id="shape48" transform="translate(353.893454562705, 26.3656380435805)" fill="#444444" fill-rule="evenodd" d="M1.93819 6.84946L12.1626 11.2824L19.7198 10.9463L21.4624 12.0186L20.9467 13.811L28.2016 16.3555L30.0864 18.2119L20.8756 18.74L16.1812 20.2603L15.3455 23.6371L9.58427 27.3338L15.3811 28.038L38.835 27.0778L47.868 29.2863L56.3676 24.9333L65.614 19.3161L69.8283 15.8914L77.4388 14.3711L88.3389 11.3304L111.544 6.22533L119.866 3.95285L84.1247 0L47.5124 1.8884L34.354 5.16911L28.6106 3.08866L17.7105 5.29713L5.93905 5.24912L0 7.20154Z"/><path id="shape49" transform="translate(428.36271244604, 25.7014960230594)" fill="#444444" fill-rule="evenodd" d="M0 21.0685L6.89925 23.261L10.1177 25.7735L18.1016 30.7346L44.2228 29.3743L57.3634 31.8868L64.8316 36.7999L70.0061 41.4089L70.8596 46.946L74.6115 48.1623L78.4879 47.2981L83.7157 49.8587L84.7648 51.8111L78.5946 50.0987L72.8689 51.363L72.0865 55.1398L76.5497 56.324L81.1551 55.8759L85.1738 55.0598L87.9299 55.956L83.2889 58.1804L78.8257 59.9088L76.3363 65.558L79.946 70.6151L83.2356 75.7362L86.543 80.8253L92.8021 86.8426L96.6785 91.1475L109.766 92.6518L114.78 93.74L120.221 93.532L126.854 81.4334L132.313 74.0078L144.595 70.5271L157.576 65.326L163.515 61.021L179.305 60.5569L194.828 57.2122L202.012 53.9475L193.761 53.0033L188.285 52.6993L189.814 49.4506L195.362 50.2347L197.976 52.5232L203.559 52.3952L205.604 49.0665L203.275 47.2421L199.594 46.4579L198.847 45.4657L203.612 44.2335L203.043 42.4731L200.696 41.0488L204.537 40.5687L210.281 40.6327L216.184 36.3918L213.961 32.3589L211.49 29.6703L205.231 29.1102L207.275 27.1258L213.783 27.3018L215.544 29.2062L219.402 26.8217L219.029 25.1254L213.695 25.6535L208.485 25.3334L205.782 23.0289L209.534 19.8282L212.717 18.0519L215.473 15.2353L212.77 12.3706L216.575 11.9386L221.412 12.1466L228.24 11.1064L238.856 10.3702L243.408 8.4178L233.894 7.37758L223.617 7.50561L217.589 7.45759L210.601 7.07351L204.395 9.15396L205.764 6.22533L203.346 4.43295L200.91 2.75259L177.669 0L136.949 0.352075L113.389 0.880188L108.623 1.64835L110.828 3.95285L106.187 3.60077L102.293 3.18468L98.8611 3.92084L92.1397 3.00864L88.1033 5.31314L89.2057 6.51339L85.525 5.82525L79.7815 5.16911L78.1456 7.56962L77.381 6.5294L75.834 5.00907L71.922 4.57698L46.9389 7.24955L43.756 8.68986L31.789 10.3222L22.8982 12.8027L24.2318 14.2751L31.4334 13.923L29.4063 16.8356L22.0981 17.2677Z"/><path id="shape50" transform="translate(622.521328182733, 94.2522966406266)" fill="#444444" fill-rule="evenodd" d="M0 3.5877L5.65549 0L9.1509 0.229754L10.7808 2.58032L14.0405 3.41097L17.5949 1.37853L22.8183 1.25481L31.3998 0.388815L35.4843 0.477182L41.5718 5.16064L36.6036 8.81903L26.8243 12.124L18.5178 12.0709L11.743 10.0032L7.89412 9.33156L9.19017 7.90001L6.75517 6.66288L1.51206 5.77921L8.07086 4.06488L5.69477 3.41097Z"/><path id="shape51" transform="translate(679.421478768447, 138.862262259105)" fill="#444444" fill-rule="evenodd" d="M0.585829 4.12493L0.999356 7.75363L3.10145 8.60136L1.99871 11.0929L0 13.1605L1.49329 14.6802L5.61707 15.1351L10.5449 13.0571L15.4843 12.5505L15.7944 6.95759L16.5755 5.07604L18.1377 3.02908L15.6681 0.0103382L9.56855 0L5.11165 1.43701L5.54815 3.95952Z"/><path id="shape52" transform="translate(691.069147183073, 126.125640229384)" fill="#444444" fill-rule="evenodd" d="M2.67644 0.0206763L0 1.77816L1.70005 2.88435L3.8481 1.61275L3.35416 0Z"/><path id="shape53" transform="translate(695.032111288641, 124.554238810133)" fill="#444444" fill-rule="evenodd" d="M4.33054 1.80918L2.25142 4.05256L0.413527 4.86928L0 6.24425L1.88384 7.11266L0.229737 9.96599L2.33183 9.45942L3.1474 9.74889L2.64198 11.3927L4.44541 11.9923L4.41095 14.6699L6.65089 15.5176L9.18948 15.0937L11.2571 15.9001L10.3267 17.6679L12.7619 19.1773L11.7855 22.1857L9.21246 22.6302L7.11036 22.2374L7.14482 23.8295L7.91444 25.4836L5.67451 26.4347L3.68728 27.1067L4.07783 29.1226L6.52453 28.9675L9.87869 29.3294L12.4058 29.6705L13.945 29.867L11.1767 31.0869L8.13269 31.2626L4.38798 33.3303L3.42308 34.7569L5.3299 35.3462L9.18948 34.2607L12.1416 33.3303L16.7019 33.2269L20.4466 33.3923L24.9679 32.0483L30.0381 31.2109L28.43 29.5258L31.1983 27.148L32.2321 23.6641L28.5563 22.806L26.3968 22.1547L24.9679 18.8982L21.3196 16.9236L18.6776 14.5872L17.2418 12.5195L13.4741 10.731L15.1741 8.65305L17.2073 5.83073L15.8289 4.24899L11.5558 4.4971L9.56855 3.83546L11.9119 1.90222L11.4754 0.754686L7.93742 0Z"/><path id="shape54" transform="translate(713.158364501935, 117.482932423502)" fill="#444444" fill-rule="evenodd" d="M0 0L0.80408 2.38812L3.03253 0.84773L2.03317 0Z"/><path id="shape55" transform="translate(690.839410133475, 110.6804183849)" fill="#444444" fill-rule="evenodd" d="M0 1.51971L2.64198 1.23024L2.37778 0L0.356092 0.175749Z"/><path id="shape56" transform="translate(-3.02234086346822, 611.903893953643)" fill="#444444" fill-rule="evenodd" d="M3.02234 85.6533L56.0897 86.7517L96.6863 88.3134L65.2425 84.7094L63.2785 83.7999L48.1572 82.5814L40.3392 80.1101L68.3697 81.0884L87.133 82.427L103.589 79.1491L108.738 77.9306L104.295 75.2191L96.9533 72.7135L129.942 71.598L122.772 67.565L130.495 66.9472L97.1821 63.5149L89.1162 58.5896L92.8726 56.3586L115.774 58.5724L127.1 58.1605L135.796 55.9295L143.385 51.6048L153.319 50.4893L171.32 48.7731L187.833 46.4049L216.76 46.628L258.358 46.0187L266.176 43.2557L268.388 45.7785L269.837 47.4603L275.92 48.0095L277.788 44.8346L281.488 45.9501L278.227 48.8332L314.781 48.9362L327.271 49.0735L320.216 47.2543L320.635 46.5679L311.539 42.6036L317.756 41.7283L309.213 39.7719L310.567 38.6049L314.343 38.4333L343.021 41.7798L356.16 40.6128L358.104 37.8327L363.653 38.3303L369.488 39.1713L371.109 40.3211L380.743 41.9514L397.219 43.3072L402.825 39.8234L409.251 41.8141L416.23 42.5521L422.16 41.7112L420.196 40.5442L425.516 39.9435L426.889 43.0154L443.192 40.6815L454.29 39.1198L455.53 36.0993L452.669 33.8168L452.078 30.6934L448.417 26.1456L450.095 25.3047L455.072 24.6869L455.968 20.8255L454.557 17.7193L452.708 18.4229L453.661 16.1061L455.053 16.1919L456.845 17.479L458.829 14.0124L461.651 11.7642L465.579 9.85931L469.602 7.79993L476.886 4.91679L482.588 3.15773L489.777 0.978209L495.611 0L499.425 0.377554L498.071 1.47589L489.109 4.56497L481.234 6.64152L476.143 9.66196L474.274 11.4296L478.011 11.361L479.461 12.2705L474.541 13.5233L471.28 13.918L466.208 14.9649L461.555 17.4361L461.899 19.3068L469.812 23.3054L475.78 26.8407L479.327 33.3792L480.872 38.4247L480.09 43.2643L476.905 46.7824L471.376 48.8418L466.17 50.6438L451.468 52.8233L443.459 53.6127L433.735 54.3507L420.139 54.4708L414.723 55.6721L418.213 58.0747L423.571 57.6628L429.196 57.7143L430.15 59.379L427.614 60.546L415.143 60.9235L401.871 59.0014L412.721 61.8159L410.185 63.3948L402.31 63.4291L395.483 63.0001L389.973 62.9314L396.132 65.4713L405.056 64.3044L413.503 63.0516L418.785 67.0502L421.664 70.3967L432.381 71.2891L444.203 71.5637L459.324 72.868L471.051 72.3531L480.49 80.1788L492.675 78.3082L508.826 77.3471L534.397 75.5623L543.492 77.6904L560.139 73.4171L588.513 69.7102L628.88 68.4403L599.687 66.0892L582.792 64.3044L580.237 61.7644L588.112 57.5255L606.323 54.6424L625.906 50.6952L644.269 49.717L651.686 46.3019L655.176 45.5639L664.176 44.2768L660.095 42.7838L659.276 40.6901L664.043 39.3L677.19 38.0214L682.091 32.7357L686.877 32.667L691.511 34.6749L692.807 32.2208L694.199 30.8651L703.142 30.642L701.026 33.5079L711.17 32.4782L713.363 30.4875L716.586 33.3363L723.022 33.6452L723.022 34.263L731.383 31.9806L750.851 30.4789L759.432 28.5225L771.75 30.702L779.492 28.677L794.995 30.6677L807.504 30.3931L811.889 29.4492L816.542 32.1436L819.917 30.1872L824.322 33.139L834.7 31.2855L851.842 27.939L854.855 25.3991L861.586 24.4552L867.536 27.0123L876.67 28.145L880.922 26.4974L886.051 22.5503L907.045 17.8137L928.474 13.0085L946.798 12.1161L957.267 15.8916L973.399 18.3114L1000.57 18.9464L1003.15 21.6407L1001.39 27.836L991.209 38.3561L990.751 41.1363L994.469 40.4841L1012.85 29.6552L1022.27 27.4585L1037.03 24.1291L1048.18 18.586L1066.36 16.2005L1086.25 14.9992L1113.87 14.7418L1128.02 13.5748L1136.1 10.9662L1162.87 15.5999L1169.58 11.8758L1181.27 12.322L1185.48 15.6685L1182.98 17.2645L1204.17 16.5781L1222.36 14.7933L1231.09 13.8151L1238.24 16.9899L1246.6 13.1114L1269.1 10.3313L1301.02 15.9774L1301.21 19.0493L1306.48 17.4018L1315.51 21.6922L1330.14 23.3569L1338.61 21.5549L1361.81 26.446L1368.98 31.3713L1370.97 32.3324L1373.06 28.5568L1379.05 30.2558L1398.44 33.0532L1404.1 33.9627L1402.21 38.8194L1394.34 41.428L1388.22 43.4187L1383.11 42.8524L1385.43 46.2676L1378.19 47.057L1372.92 49.1335L1374.13 55.5005L1380 59.5163L1386.14 60.6146L1391.54 57.4226L1398.23 59.2417L1390.52 62.9829L1379.29 62.8971L1364.5 65.0766L1364.55 71.2376L1374.49 75.5623L1387.53 77.0726L1405.07 81.5517L1425.31 83.0448L1443.02 85.2586L1445.82 108.096L1315.69 112.005L875.435 111.267L342.764 113.249L3.02234 112.245L0 99.2882Z"/><path id="shape57" transform="translate(502.658838668914, 670.889311830287)" fill="#444444" fill-rule="evenodd" d="M0 11.552L2.5428 10.1789L13.2336 8.89537L14.9693 4.98499L29.4412 0L42.5311 0.855707L43.9462 4.79594L41.5361 10.4277L30.6241 12.1192L12.316 12.4277L0.243224 12.5272Z"/><path id="shape58" transform="translate(433.461540206236, 672.879328402149)" fill="#444444" fill-rule="evenodd" d="M0 4.44769L2.4433 6.30835L6.87661 5.34319L12.8688 3.32333L18.883 0.786057L10.735 0L2.25535 2.23877Z"/><path id="shape59" transform="translate(447.822826466505, 677.307115274541)" fill="#444444" fill-rule="evenodd" d="M0.840229 0.616905L6.05849 2.73627L9.47469 3.98998L21.9455 5.36309L31.8734 6.0596L33.8524 2.87557L30.392 1.69151L25.5938 3.50243L14.9804 3.69148L8.86663 2.19897L4.94187 0L0 0.179101Z"/><path id="shape60" transform="translate(568.77714711212, 575.76306974032)" fill="#444444" fill-rule="evenodd" d="M0 0L5.85774 3.43119L8.67207 1.75241L4.3524 0.103083Z"/><path id="shape61" transform="translate(633.596928462392, 654.297741232211)" fill="#444444" fill-rule="evenodd" d="M0 1.63677L4.0414 0L5.27908 4.09192Z"/><path id="shape62" transform="translate(994.885040467576, 554.785875947627)" fill="#444444" fill-rule="evenodd" d="M0.446413 0L0 2.99097L6.15059 3.50435L6.7954 1.71869Z"/><path id="shape63" transform="translate(1299.21681100235, 522.966056511798)" fill="#444444" fill-rule="evenodd" d="M0 0L5.27523 1.20057L11.4398 0.218285L15.0172 0.745808L10.8334 8.47675L5.61882 12.8243L2.40518 10.0775L0.444655 5.38437Z"/><path id="shape64" transform="translate(1385.47486718799, 522.265724569479)" fill="#444444" fill-rule="evenodd" d="M0.343597 18.7907L0 21.8831L3.69872 22.3015L8.85268 23.3383L14.2492 23.0837L18.9383 17.3537L21.4445 14.3523L27.8516 12.8606L27.4474 10.696L31.9748 3.12876L29.4281 0.0181904L26.8612 2.8559L24.5369 0L21.5051 3.51075L18.2107 7.89465L7.86231 13.8065Z"/><path id="shape65" transform="translate(1410.43619327065, 497.763201808339)" fill="#444444" fill-rule="evenodd" d="M4.40613 20.2642L10.6919 22.6835L10.126 24.9937L7.01343 27.031L11.2174 28.5044L13.663 26.6308L17.8468 20.3187L19.3829 18.6088L22.2328 16.9717L23.9912 12.6424L20.6158 11.2417L16.0278 14.0066L13.5013 11.7328L11.8844 8.13113L10.2675 10.7142L8.73141 8.69503L7.03364 3.45618L0 0L5.41671 6.76684L8.38781 11.9875L8.22612 15.0981L7.76125 17.5174Z"/><path id="shape66" transform="translate(1389.86356828363, 546.953545931554)" fill="#444444" fill-rule="evenodd" d="M1.10904 0L0 2.26849L2.3045 1.5685Z"/><path id="shape67" transform="translate(1376.06341996683, 440.791631205666)" fill="#444444" fill-rule="evenodd" d="M0 0L0.72376 2.39709L9.94446 8.71552L11.8697 7.3867L3.24245 1.27671Z"/><path id="shape68" transform="translate(1385.7183800842, 418.657598948582)" fill="#444444" fill-rule="evenodd" d="M0 0L2.76476 1.35488L3.4451 2.00626L3.12664 3.94739L5.0808 6.33145L4.68997 8.01202L2.85161 6.08393L1.53437 3.67381Z"/><path id="shape69" transform="translate(1392.55067569949, 429.679018189014)" fill="#444444" fill-rule="evenodd" d="M0 0L0.463206 1.57635L2.20023 0.977076Z"/><path id="shape70" transform="translate(1396.57478201528, 437.482599897073)" fill="#444444" fill-rule="evenodd" d="M0 0L0.289504 1.18552L1.9831 0.521107Z"/><path id="shape71" transform="translate(1428.72420693385, 428.714969697534)" fill="#444444" fill-rule="evenodd" d="M2.22918 0L0 3.11362L2.12785 5.05474L6.09406 3.92133L5.57295 1.6024Z"/><path id="shape72" transform="translate(1433.55892459382, 424.520055991365)" fill="#444444" fill-rule="evenodd" d="M1.31724 0.990104L0 2.90517L2.70686 3.30903L6.44108 2.85306L4.50179 0Z"/><path id="shape73" transform="translate(1365.29304993642, 400.508895796076)" fill="#444444" fill-rule="evenodd" d="M0 0L0.876907 1.44487L2.81959 2.9201L3.13663 1.32953L0.114672 0.485671Z"/><path id="shape74" transform="translate(1362.05524079884, 392.908138845602)" fill="#444444" fill-rule="evenodd" d="M0 0L0.775725 3.16901L2.92077 5.72485L3.87188 4.76565L2.08434 2.18552L1.18045 0.558522Z"/><path id="shape75" transform="translate(1358.00123394116, 396.969565682556)" fill="#444444" fill-rule="evenodd" d="M0 0L0.809452 1.66342L3.94608 3.00509L5.18724 2.38586L3.43343 0.625302L0.31029 0.394608Z"/><path id="shape76" transform="translate(1354.02817231192, 389.824125642054)" fill="#444444" fill-rule="evenodd" d="M0 0L0.944361 1.76056L4.58015 4.41354L4.99162 3.04759L1.44352 0.710294Z"/><path id="shape77" transform="translate(1345.58288681139, 390.437285747484)" fill="#444444" fill-rule="evenodd" d="M0 0L1.08602 1.38416L5.98995 4.47425L5.6864 3.13865L3.55484 1.67557Z"/><path id="shape78" transform="translate(1346.08204905344, 386.321220881333)" fill="#444444" fill-rule="evenodd" d="M0 0L1.01856 1.78484L2.91403 2.99902L3.43343 2.28873L2.23948 0.758862Z"/><path id="shape79" transform="translate(1338.10894405214, 381.088111862715)" fill="#444444" fill-rule="evenodd" d="M0 0L1.10625 3.14472L3.59532 5.91305L5.03884 5.91305L4.62737 4.00072L1.63914 1.01991Z"/><path id="shape80" transform="translate(1313.48810373511, 376.917408967367)" fill="#444444" fill-rule="evenodd" d="M0 5.08134L5.44357 4.92956L6.53633 3.72753L7.2446 4.94778L11.6359 3.41791L12.5533 1.15347L13.6123 0L16.0474 0.528168L16.0676 2.398L13.6595 5.00242L10.3273 7.36399L5.64593 8.66923L2.13156 7.4672L0.209109 6.52621Z"/><path id="shape81" transform="translate(1323.53773036763, 370.566193207189)" fill="#444444" fill-rule="evenodd" d="M0 0.571443L6.18261 4.58309L7.06768 6.79382L7.45249 8.3523L8.36962 8.59473L8.71594 5.60476L5.41299 2.83413L0.160337 0Z"/><path id="shape82" transform="translate(1319.61908255122, 369.365586216627)" fill="#444444" fill-rule="evenodd" d="M0 0.109671L1.09029 1.51808L2.51409 1.07939L1.7573 0L0.301434 0.490633Z"/><path id="shape83" transform="translate(1306.44575584922, 367.789789541514)" fill="#444444" fill-rule="evenodd" d="M0 0.369418L1.78295 0L3.15544 0.877367L2.14852 1.81245L0.205232 1.67392Z"/><path id="shape84" transform="translate(1242.37140526939, 361.527756689762)" fill="#444444" fill-rule="evenodd" d="M0.945295 1.45846L2.74907 2.23109L5.44027 0L10.1475 0.208351L13.9093 1.80571L14.1505 5.31295L14.8257 7.80447L17.9896 12.0236L22.8318 9.35842L26.7287 6.04217L28.5711 4.29724L37.0305 7.59612L42.3936 8.27326L50.5154 11.876L55.0297 12.5358L60.6147 18.0484L62.0712 19.8281L67.9069 23.1703L67.9841 25.2886L65.3026 26.4692L68.4278 30.2456L71.582 33.9265L74.4372 35.3589L76.405 37.043L79.7328 39.6908L78.8454 40.5763L72.8553 39.7082L67.8105 38.0674L59.515 29.7334L53.8047 29.4296L51.1328 31.4783L50.5733 33.6573L47.5156 35.0811L42.2971 34.5776L37.0016 30.697L32.1304 31.27L28.9569 30.7491L30.4038 28.1881L31.8603 26.9641L29.825 21.1302L24.6741 18.1352L16.2147 14.9839L13.755 13.4039L10.7937 13.8987L5.9515 10.322L8.12182 8.16041L4.81329 5.73833L2.13174 4.09757L0 2.98636Z"/><path id="shape85" transform="translate(1262.20331765356, 362.230940742683)" fill="#444444" fill-rule="evenodd" d="M0 0L0.405127 2.00538L3.47251 3.35966L2.13174 0.729228Z"/><path id="shape86" transform="translate(1263.14013872993, 366.510869345839)" fill="#444444" fill-rule="evenodd" d="M0 0L3.66362 0.13617L2.69098 1.50759L1.15636 1.22553Z"/><path id="shape87" transform="translate(1171.98387703304, 402.899846866361)" fill="#444444" fill-rule="evenodd" d="M109.709 28.2733L113.029 23.4576L114.536 14.8607L115.545 5.48226L118.073 0L120.628 5.11447L123.169 12.5851L123.616 14.7917L127.575 15.4813L130.627 21.3544L132.248 29.0778L133.883 33.4222L143.154 39.3872L146.564 45.8349L150.804 48.168L153.115 52.6044L159.012 59.0578L160.965 57.1729L161.093 61.276L161.91 69.758L160.697 78.6192L157.811 87.0323L152.026 93.5489L149.357 100.514L147.94 106.444L144.019 107.019L135.336 112.478L128.44 111.582L120.892 112.421L108.276 109.053L106.156 105.318L105.581 101.134L103.857 99.9621L101.29 98.7438L101.252 95.9395L99.3108 95.9625L96.578 99.2955L95.9778 97.1922L97.7018 93.296L98.8766 90.6871L97.6124 90.3998L91.7508 95.7441L88.7626 92.8018L85.3402 87.9977L81.6624 85.6416L75.903 83.4809L62.4208 84.4635L49.9954 86.9575L43.4443 91.302L38.234 92.4858L27.5454 93.3248L19.3213 97.4279L12.8724 96.7498L7.59828 93.3133L9.6926 90.5089L10.5993 86.6587L7.95585 78.7514L3.93323 67.4421L1.13655 63.1666L0 59.8681L3.97154 61.7645L2.7456 57.5005L1.3281 53.0871L2.86053 48.5932L3.62674 45.7889L5.50397 44.8924L9.0924 43.3409L13.7918 39.5021L19.0404 39.3182L27.8646 36.5369L34.3519 33.859L36.7016 28.9514L37.6338 24.6414L39.9963 23.584L42.0268 26.7332L43.4571 24.8253L42.1258 22.1129L44.4372 21.113L46.391 21.09L47.1445 18.0673L51.7417 14.5159L57.1435 13.0448L61.7025 15.7572L66.1466 16.6881L67.1171 12.5161L71.0631 6.84995L75.7115 5.37882L78.4443 5.51674L80.2321 4.11457L87.6771 6.17185L91.0485 6.41321L93.9601 6.5971L94.9817 8.03375L91.9552 10.5623L90.8952 13.0448L90.7931 16.3893L94.6114 19.5269L104.805 26.1643Z"/><path id="shape88" transform="translate(1265.55128927901, 414.663136315027)" fill="#444444" fill-rule="evenodd" d="M0.523579 0L0 2.64344L1.40472 2.81583L1.27702 0.494208Z"/><path id="shape89" transform="translate(1240.21517000837, 404.939889736061)" fill="#444444" fill-rule="evenodd" d="M0 1.32172L0.753443 2.74687L4.81437 2.93077L6.58943 0.218371L4.21417 0L1.13655 0.701085Z"/><path id="shape90" transform="translate(1255.89244435248, 381.443893033101)" fill="#444444" fill-rule="evenodd" d="M1.47592 0.742607L0.197564 2.98089L0 5.84672L3.12616 4.8531L4.00938 1.95588L1.96402 0Z"/><path id="shape91" transform="translate(1243.75970560041, 388.315625240089)" fill="#444444" fill-rule="evenodd" d="M2.56833 0L0 2.29058L0.0813498 4.36151L2.54509 2.99135L3.81182 0.962252Z"/><path id="shape92" transform="translate(1213.77650063842, 393.147802225825)" fill="#444444" fill-rule="evenodd" d="M0 8.20006L1.56889 4.87401L5.03207 3.40972L8.44876 0.972711L12.6208 0L15.8283 0.345155L12.3652 2.23828L7.76309 4.99953L4.2883 6.95541Z"/><path id="shape93" transform="translate(1195.48442133214, 396.954971972163)" fill="#444444" fill-rule="evenodd" d="M0 0.70077L2.94021 0L6.28718 1.1819L7.84444 4.30921L5.35746 3.85947L2.83562 2.86584Z"/><path id="shape94" transform="translate(1199.08705448649, 391.798558002535)" fill="#444444" fill-rule="evenodd" d="M0 2.32196L2.9867 0.784444L5.90367 2.14415L9.36685 1.95588L12.6789 0L19.3612 0.753067L17.188 2.2069L11.6679 3.25283L6.39177 3.6189L1.1389 4.34059L0.708905 3.00181Z"/><path id="shape95" transform="translate(1187.27099881009, 392.389506053821)" fill="#444444" fill-rule="evenodd" d="M0.429992 1.54797L0 3.08548L2.24293 3.59798L5.07855 2.93905L7.84444 2.29058L7.29824 0.679852L3.99776 0L1.44105 0.42883Z"/><path id="shape96" transform="translate(1184.02862897118, 392.839254128251)" fill="#444444" fill-rule="evenodd" d="M0.058107 1.05639L0 2.86584L1.7897 1.98726L2.4986 0L0.790255 0.345155Z"/><path id="shape97" transform="translate(1141.33161539351, 383.750159321748)" fill="#444444" fill-rule="evenodd" d="M0 3.11686L1.24349 1.6421L3.17264 0L7.30986 0.0522963L12.6906 3.53523L17.8621 3.68166L21.1277 2.91813L22.9523 2.22782L30.4248 3.76533L31.0059 6.8299L34.8526 6.95541L37.2233 7.23781L39.1641 9.11001L41.4884 9.39241L39.4314 11.8294L35.6661 11.0241L31.1221 10.5848L25.0092 9.20415L19.1056 8.44062L16.0259 7.64572L12.0979 8.34649L5.22963 6.70438Z"/><path id="shape98" transform="translate(1230.08443870637, 349.97114525228)" fill="#444444" fill-rule="evenodd" d="M2.07049 0.126335L0 3.91638L0.245651 10.0289L1.45636 10.0289L2.29859 10.0289L4.527 5.49556L4.93057 2.11611L3.15837 0Z"/><path id="shape99" transform="translate(1232.03210054851, 370.421594594684)" fill="#444444" fill-rule="evenodd" d="M0 1.32652L2.24595 2.74778L6.28165 2.54249L10.3173 5.2429L11.9141 3.64792L9.56284 0.410588L5.63243 0Z"/><path id="shape100" transform="translate(1224.32479906961, 372.206073958153)" fill="#444444" fill-rule="evenodd" d="M1.05279 0L0 1.32652L2.87763 3.39525L4.21116 2.7162L2.42142 0.268461Z"/><path id="shape101" transform="translate(1194.28518579274, 354.108610679083)" fill="#444444" fill-rule="evenodd" d="M1.08788 13.9916L0 18.3343L2.14067 20.4189L3.86023 21.6506L4.38663 25.2985L3.79004 28.4095L6.96596 28.4569L8.07139 24.8248L7.94857 20.1978L8.2995 16.5183L9.68567 17.3237L10.0717 20.4662L11.493 23.6404L13.4231 25.0775L16.7218 22.7719L13.4231 17.5921L11.879 14.4811L11.6509 13.3599L19.0029 9.33298L16.2481 8.9066L11.0192 9.98045L8.07139 9.85412L5.79035 5.89139L7.38708 3.42683L11.1947 5.89139L13.9144 5.89139L22.3893 3.50579L26.3198 0.347421L24.2844 0L19.0555 2.5267L12.4931 2.70041L7.24671 1.37389L4.38663 5.89139L3.66722 10.0594Z"/><path id="shape102" transform="translate(1155.45477447164, 332.900152403523)" fill="#444444" fill-rule="evenodd" d="M1.05279 20.6557L0.0526395 27.0998L3.36893 29.9571L4.89547 33.6998L6.21146 37.0161L10.1243 39.7323L16.5814 40.9009L21.9507 41.2483L26.232 43.4118L30.2853 39.2743L31.8995 33.1155L34.1104 29.0886L36.409 23.2614L39.4972 22.8034L36.216 17.8764L33.4612 11.9386L36.795 9.71199L39.8657 7.09054L38.5321 3.85321L33.8823 0L27.7586 2.58986L20.389 8.32231L14.4408 14.1653L9.79095 15.7919L8.28195 20.3715L1.71956 20.3241L0.456209 22.835L0.0526395 23.8299L0 23.4509Z"/><path id="shape103" transform="translate(1187.93335167695, 316.366082549085)" fill="#444444" fill-rule="evenodd" d="M0 9.17507L9.36983 0L9.73831 1.70552Z"/><path id="shape104" transform="translate(1198.53143953865, 284.577082914907)" fill="#444444" fill-rule="evenodd" d="M4.0006 0.947511L3.07064 7.91172L0 11.7176L1.49145 17.15L4.22871 17.7185L4.527 20.1188L7.12388 20.2767L8.45741 20.3399L10.7034 22.1244L12.5107 21.319L18.0378 25.5354L16.0024 20.0714L12.458 18.3975L9.36983 18.4133L7.31689 15.0181L9.0189 11.5123L11.6333 7.18529L9.89623 1.72131L6.14128 0Z"/><path id="shape105" transform="translate(1201.88282162737, 306.480382712525)" fill="#444444" fill-rule="evenodd" d="M0 0L3.26365 4.8481L3.7725 1.62656L1.94766 0.300045Z"/><path id="shape106" transform="translate(1207.53279561986, 313.286671258144)" fill="#444444" fill-rule="evenodd" d="M0 0L0.070186 4.6586L3.00045 3.50579L4.57964 1.83185L3.59703 0.25267Z"/><path id="shape107" transform="translate(1209.76120151131, 317.945267826491)" fill="#444444" fill-rule="evenodd" d="M2.35123 0L0.315837 1.72131L0 4.04271L1.84238 5.57452L3.36893 3.97955L4.22871 0.60009Z"/><path id="shape108" transform="translate(1215.27080347915, 319.4612856928)" fill="#444444" fill-rule="evenodd" d="M0 0L0.0175465 2.28982L2.01785 2.17928L2.87763 0.410588Z"/><path id="shape109" transform="translate(1217.63958139526, 308.707033953667)" fill="#444444" fill-rule="evenodd" d="M0 2.70041L2.03539 6.42728L4.22871 7.50113L4.21116 1.76869L2.43896 0Z"/><path id="shape110" transform="translate(1217.09563979971, 315.355403971545)" fill="#444444" fill-rule="evenodd" d="M0 0L1.54409 3.03204L3.36893 3.75846L0.543942 0.85276Z"/><path id="shape111" transform="translate(1207.37487709212, 320.835176884143)" fill="#444444" fill-rule="evenodd" d="M0 10.3121L2.61443 6.53783L7.45726 4.48489L10.1945 5.11656L14.0898 2.63724L16.0726 0L18.4063 5.73244L18.3185 11.1175L14.4934 10.9122L14.4232 16.3762L10.0191 15.1918L8.2644 10.6911L5.73771 8.68552L2.73725 9.19086Z"/><path id="shape112" transform="translate(1101.21853344429, 337.290287474711)" fill="#444444" fill-rule="evenodd" d="M0.193012 0L0 3.3005L7.58009 8.35389L12.8089 16.5657L19.1783 26.8461L26.3198 36.4318L34.9877 45.291L40.4447 45.5437L43.3048 40.6482L42.1642 34.6631L39.1112 30.3361L34.0578 26.325L31.1801 20.3399L23.4948 14.2443L14.8092 7.65905L9.84359 3.52158L3.07064 0.552715Z"/><path id="shape113" transform="translate(1141.36493249656, 365.320826148664)" fill="#444444" fill-rule="evenodd" d="M0 0L2.40387 0.647466L5.57979 4.75335L5.33414 6.7747L3.07064 5.25869Z"/><path id="shape114" transform="translate(1150.47156759627, 371.005893147325)" fill="#444444" fill-rule="evenodd" d="M0 0L0.333384 2.05294L1.98275 1.92661L2.21086 0.0631674Z"/><path id="shape115" transform="translate(1102.34150964156, 349.102593349707)" fill="#444444" fill-rule="evenodd" d="M0 0.0157919L3.93042 1.92661L3.52685 0Z"/><path id="shape116" transform="translate(1109.25483185598, 355.514085575974)" fill="#444444" fill-rule="evenodd" d="M0 0L1.75465 2.03715L2.40387 0.710633Z"/><path id="shape117" transform="translate(1114.36086425292, 363.820600135128)" fill="#444444" fill-rule="evenodd" d="M0 0.647466L1.10543 3.37946L2.57934 1.50023L0.894872 0Z"/><path id="shape118" transform="translate(1089.46237637916, 305.943459718207)" fill="#444444" fill-rule="evenodd" d="M0 8.51181L1.66692 0L2.87763 1.78448Z"/><path id="shape119" transform="translate(652.076307421237, 47.9598568748132)" fill="#444444" fill-rule="evenodd" d="M485.113 305.817L483.551 301.316L481.252 295.837L481.059 290.799L474.462 284.893L468.338 281.419L468.356 277.771L466.215 274.312L465.689 269.922L468.566 258.047L471.496 257.763L472.672 261.695L478.076 263.921L480.849 268.548L484.972 271.186L487.727 272.954L487.481 277.344L491.886 276.46L494.921 272.149L498.29 269.085L505.73 263.448L505.607 255.315L501.203 247.056L492.815 239.665L491.166 234.343L496.641 228.405L501.343 225.326L505.484 226.131L507.537 228.863L510.59 226.258L521.943 223.305L535.927 218.772L544.49 210.545L553.439 197.596L556.018 193.174L551.21 191.863L555.369 187.362L554.421 182.041L548.508 174.903L545.227 171.002L550.052 166.359L556.141 164.369L558.088 162.838L553.281 161.085L548.052 162.411L544.858 161.337L543.946 159.158L537.928 157.279L541.419 153.599L547.438 152.526L551.28 149.446L555.597 148.578L553.667 151.878L552.456 154.326L554.807 156.584L566.002 152.305L569.037 156.363L569.178 159.506L573.74 161.385L574.74 165.238L573.178 168.649L574.161 175.329L582.197 171.902L586.97 167.638L585.549 161.085L579.548 152.857L585.268 149.525L588.725 143.587L592.901 140.587L599.086 139.703L606.368 138.976L616.088 131.207L624.897 121.684L629.038 114.562L631.652 106.682L633.021 100.207L626.888 95.517L621.923 96.4172L617.501 96.3698L616.501 94.6485L612.746 92.9429L611.939 90.6373L625.186 83.91L635.416 76.8668L641.522 75.414L664.14 73.6137L675.843 74.8455L685.722 74.1664L699.408 64.5018L709.445 64.6755L710.375 69.3657L718.499 65.4335L724.745 60.0011L727.535 60.3328L722.727 67.4549L714.919 69.5868L707.146 73.5663L700.654 79.5199L691.126 85.4102L690.652 93.5904L692.898 102.481L698.004 106.255L701.566 101.676L705.988 98.8175L711.691 94.1589L716.586 89.4372L720.06 83.91L716.305 79.204L721.727 73.7401L725.236 71.5608L732.518 70.2343L733.571 71.9714L739.87 69.7131L746.608 70.7396L750.31 71.3871L752.995 68.7182L768.234 63.1279L779.446 61.454L785.64 61.4224L787.924 59.18L777.569 53.9213L782.289 52.1684L787.924 50.6997L791.922 40.6087L787.924 36.7555L781.605 34.1499L765.567 32.3022L750.126 31.7495L749.6 33.5972L750.547 36.3449L745.125 36.8819L741.195 36.0291L739.861 32.4286L735.878 32.5233L711.173 33.5972L707.453 31.0231L705.997 28.449L698.346 26.9646L678.115 28.6543L671.921 26.3013L663.06 21.6112L651.462 21.6901L633.038 19.6056L625.616 23.2851L624.265 26.6488L604.223 26.854L597.204 24.659L592.695 28.0542L581.974 23.9326L582.447 19.7003L574.937 18.1527L561.028 16.9131L560.606 19.0766L552.763 19.9293L543.762 18.8397L540.516 17.9395L524.197 16.9447L517.565 16.1235L497.685 18.0501L492.807 18.0185L519.688 10.9911L521.758 7.69063L512.704 5.21131L499.422 4.05851L483.525 0L470.312 3.41104L459.24 6.60099L416.804 10.3595L411.435 11.4491L413.751 15.7129L388.923 16.2024L390.59 19.7872L400.135 24.4616L401.749 29.5781L397.275 30.0045L396.924 25.4249L381.939 20.94L375.798 20.4347L372.727 23.9404L371.78 26.8935L368.902 24.0668L365.919 19.4398L363.445 23.7667L362.498 26.8146L363.708 30.0045L363.024 33.305L366.323 34.1578L375.622 35.4053L380.553 37.9636L379.816 40.8061L375.201 38.7848L369.323 36.9845L365.445 37.2056L366.796 41.4852L357.602 47.644L349.11 47.5651L343.091 44.5646L354.724 43.7908L360.217 38.7848L358.392 34.0788L356.83 26.3724L356.251 23.8615L358.234 20.6715L350.004 16.8341L343.372 18.7607L337.02 26.5461L336.055 31.6785L342.249 37.7899L337.564 38.0584L316.385 32.5786L306.138 31.0468L302.471 30.3993L309.937 37.861L305.428 38.8874L299.988 37.4346L284.214 37.4504L280.529 36.6292L267.369 39.1875L258.912 42.3143L251.033 44.3198L248.823 41.0667L251.7 39.8349L246.542 37.7504L242.295 38.4611L242.944 41.7616L243.752 46.7676L241.242 47.0992L236.944 45.6464L226.81 49.5627L226.161 51.5683L215.493 50.8103L216.283 52.8001L216.844 55.8479L210.703 54.5372L205.948 50.2418L204.018 47.415L198.859 43.925L215.651 47.3361L229.846 46.4044L231.197 41.4615L218.686 38.3189L196.753 32.8234L185.664 32.1759L169.78 28.528L142.565 32.1127L122.843 39.0138L127.826 41.0351L120.439 45.2516L113.701 51.1735L104.314 55.5321L93.9791 59.559L87.6448 63.9333L87.2061 71.1186L89.2591 76.3615L96.0671 79.283L103.191 78.9356L110.227 73.6453L113.175 76.7563L118.965 84.9839L118.86 88.4739L121.72 90.2268L127.546 87.9685L134.283 85.6155L135.95 78.4144L142.092 73.6295L142.864 71.8924L138.249 66.5706L142.267 59.3063L151.725 55.1057L156.445 49.5469L163.498 49.1048L168.92 50.984L162.989 55.8321L153.69 61.2803L153.497 67.3444L157.708 72.4767L163.533 72.1451L180.922 70.3764L187.081 72.0977L180.045 73.8348L173.868 73.9769L168.008 73.0294L162.358 75.7772L162.024 78.7303L165.341 80.1831L165.639 83.9574L162.13 84.4311L158.655 82.0308L153.514 82.694L151.672 87.1631L151.988 91.5217L147.742 93.8273L143.478 94.7274L139.951 93.4167L125.089 97.3489L120.158 94.301L111.157 95.975L105.963 92.2165L107.999 86.3893L109.683 83.6415L108.279 81.7307L102.787 84.2101L99.6641 86.2946L101.77 90.59L104.665 96.6067L101.261 97.7753L92.6104 98.7544L86.8552 102.26L78.9593 106.887L74.3796 109.098L73.3882 112.367L67.9237 112.762L67.9237 114.372L61.3864 113.52L60.3337 115.146L61.4917 117.768L55.5785 118.226L50.8059 116.504L46.4017 118.131L49.7882 119.726L49.7005 121.21L54.9118 121.526L59.4914 124.764L62.2989 128.838L62.5971 133.67L61.6672 137.523L59.3335 138.802L41.6993 137.855L35.8914 136.702L32.1364 139.782L31.031 140.998L33.1366 143.43L33.3296 147.709L32.4347 152.241L30.101 156.268L32.3821 158.527L32.7155 163.769L40.8921 163.327L44.7173 168.175L51.0516 165.396L60.0705 164.275L67.9237 157.547L67.9237 152.715L75.5816 145.435L80.2314 144.156L81.3895 138.502L87.443 137.823L92.7947 140.176L103.34 135.139L107.972 135.613L108.85 137.823L112.622 142.75L120.553 146.983L129.993 152.841L132.66 156.647L131.643 161.006L135.169 157.769L136.292 155.368L134.994 150.41L137.942 152.257L141.398 152.162L138.995 149.367L130.537 144.709L123.378 139.197L120.027 135.597L116.553 131.538L117.886 129.738L126.238 132.912L134.468 139.355L144.452 144.582L145.732 150.157L149.47 154.989L152.646 159.348L154.734 163.122L158.594 166.959L160.84 164.796L162.121 160.769L165.42 161.369L161.981 155.763L159.103 150.204L162.858 151.057L165.121 148.404L168.859 148.23L175.105 149.809L178.615 148.357L183.44 149.73L180.492 150.789L174.105 151.436L174.07 154.989L175.948 162.001L180.246 165.301L186.353 168.175L190.072 166.58L192.582 165.001L202.026 167.97L206.518 165.191L210.747 165.664L212.993 166.438L211.22 171.65L208.045 178.456L205.588 184.788L202.903 188.31L196.095 188.041L193.92 185.231L187.269 187.11L183.444 188.831L167.67 185.515L161.739 182.578L157.686 181.03L151.352 181.456L147.281 186.383L145.772 189.842L138.894 188.831L129.524 185.404L127.857 182.277L115.013 179.909L109.767 176.75L109.065 174.697L111.837 172.076L110.433 169.723L112.363 165.507L109.31 164.085L104.152 163.517L79.9901 164.772L70.6203 167.536L60.7416 170.915L54.6881 171.831L46.915 171.184L43.546 169.652L40.6333 175.021L32.79 179.095L29.0526 183.944L29.2983 190.276L23.7711 196.845L17.4719 201.441L10.8744 208.547L6.96158 215.338L1.94328 222.744L1.57919 229.519L3.45666 238.489L2.66707 245.69L0 250.901L0.7545 256.381L4.63228 265.508L12.9493 273.341L16.4762 281L28.6183 289.686L37.7601 294.771L50.762 290.507L60.1494 293.27L73.6427 287.838L86.6271 287.933L90.1013 293.997L101.12 293.286L107.56 298.04L107.227 306.788L105.507 312.04L103.717 316.216L116.829 332.766L119.549 340.551L120.426 346.189L119.777 349.995L122.479 357.528L119.812 364.95L116.145 374.788L115.829 384.058L123.918 401.239L126.633 417.702L131.739 425.361L138.67 434.521L140.758 441.927L140.881 445.133L145.654 449.57L159.357 449.76L178.852 444.959L195.293 429.388L200.118 421.034L200.171 414.37L210.523 408.638L208.47 389.34L228.754 375.428L230.35 359.967L228.175 350.65L224.701 341.349L222.7 334.764L232.653 318.316L246.217 304.688L256.692 299.619L271.852 272.457L272.168 265.398L263.676 265.398L250.235 268.051L242.199 268.43L238.935 266.109L238.707 260.708L225.688 248.643L222.301 241.347L216.651 234.777L215.879 226.566L209.65 218.543L209.439 214.611L196.863 194.342L197.617 191.121L205.075 201.165L208.338 195.021L208.514 199.633L217.761 213.198L218.41 215.693L223.13 219.009L225.183 229.637L232.254 235.117L238.536 245.35L240.554 253.262L241.028 260.068L245.326 261.253L258.679 257.589L275.348 249.709L278.893 246.029L286.631 243.36L292.404 238.749L298.615 235.796L300.001 229.037L306.897 222.499L300.072 218.109L293.632 212.977L291.737 206.581L285.175 214.051L277.086 215.804L274.015 213.151L272.19 207.418L269.014 209.36L267.4 204.907L260.574 197.406L263.259 191.689L268.33 192.969L274.366 199.806L284.946 205.334L289.982 206.265L295.457 205.76L298.913 208.287L320.039 211.445L332.094 210.64L341.082 217.375L348.89 220.707L344.363 223.265L351.557 228.54L355.663 226.234L357.664 224.418L358.102 231.24L362.629 250.048L371.315 269.409L377.158 279.847L381.527 278.695L387.335 267.261L389.616 256.27L390.16 247.458L402.6 240.889L409.706 234.32L415.62 230.285L417.357 225.926L427.709 224.505L433.219 222.531L439.027 228.958L445.94 237.738L445.484 246.85L450.713 249.251L455.275 245.524L458.275 250.103L462.03 259.373L462.627 268.351L461.591 275.757L460.942 279.753L467.61 287.396L470.4 296.034L477.945 304.562L483.068 307.783Z"/><path id="shape120" transform="translate(892.383320934284, 408.821871991416)" fill="#444444" fill-rule="evenodd" d="M4.87594 29.0147L4.07285 18.3622L9.33121 14.4902L17.6299 9.60274L22.85 4.83579L26.158 0L28.835 9.75762L25.9668 17.5362L22.6588 26.485L18.5286 44.3997L14.3028 52.0062L7.55293 52.9183L1.98862 46.809L0 39.1682L5.64079 31.5617L5.23925 26.6743Z"/><path id="shape121" transform="translate(1038.47689674505, 322.987249148473)" fill="#444444" fill-rule="evenodd" d="M1.66957 0L0 7.91516L3.08047 13.3119L8.48893 11.005L9.02977 6.26441Z"/><path id="shape122" transform="translate(1238.44094420205, 224.705058966222)" fill="#444444" fill-rule="evenodd" d="M0.878784 2.02999L4.53062 0L8.77808 1.38848L8.71949 5.26392L5.99526 10.0269L3.84712 10.1324L2.7047 6.83694L2.69494 3.46241L0 2.48696Z"/><path id="shape123" transform="translate(1244.24091834823, 195.872157188038)" fill="#444444" fill-rule="evenodd" d="M0 26.9172L7.93835 21.5741L16.238 21.2138L19.2063 21.8554L22.8972 15.1063L24.5474 16.8902L32.7982 11.8196L35.7763 6.90724L35.747 1.43242L37.8756 0L40.4241 0.219696L42.3867 3.38332L43.8513 6.52058L41.0978 9.42935L40.2776 14.5702L38.7739 20.3438L37.2409 22.4881L34.2433 23.6305L32.4759 23.2878L29.7712 25.1508L25.6117 25.5023L22.3406 24.2369L22.4383 26.2493L22.4188 27.8575L19.5676 29.8347L16.4626 29.0262L16.0427 26.2405L13.8848 24.7905L6.503 27.1544L3.60301 28.6308Z"/><path id="shape124" transform="translate(1249.95301409825, 222.894764005446)" fill="#444444" fill-rule="evenodd" d="M0.361278 2.64514L0 4.67513L1.84545 5.5627L3.76901 2.91756L6.52253 3.85786L8.56326 1.69605L6.71782 0L4.55015 0.703027L2.49965 1.40605Z"/><path id="shape125" transform="translate(1279.8780490553, 178.929202409513)" fill="#444444" fill-rule="evenodd" d="M3.95453 13.7969L1.17171 15.0096L0 11.9778L2.0505 8.89329L4.73567 7.64542L6.39559 6.81058L7.64542 3.14605L6.93263 0.0351514L9.30535 0L14.373 3.76998L19.6262 3.85786L20.1925 5.43088L21.0322 7.74209L16.1696 9.93026L13.1525 12.0306L8.15316 11.433L2.38248 11.1254L1.93332 12.3909Z"/><path id="shape126" transform="translate(1286.8985564814, 142.222396335915)" fill="#444444" fill-rule="evenodd" d="M2.93904 0L3.10504 2.52211L0.322221 5.04422L0.302692 10.7563L1.75757 15.036L0 22.6111L1.27912 28.8505L0.156228 33.4026L3.7983 31.7153L7.48919 32.9456L3.53466 24.9311L6.32724 20.5723L8.7976 20.9238L12.1467 23.1911L5.28247 7.99693L6.43465 6.44149L4.8626 2.89999L3.89594 0.237272Z"/><path id="shape127" transform="translate(928.014779922195, 51.9736067249715)" fill="#444444" fill-rule="evenodd" d="M0 21.6445L0.944248 19.0343L9.67372 11.8021L23.9338 4.91683L38.5504 2.61017L55.3348 1.48285L62.2144 0L66.1455 3.0611L61.7326 4.19708L45.5359 4.99488L23.5773 11.542L14.1348 17.4127L14.3853 20.916L20.8313 24.6362L13.0942 25.2692L5.81001 24.8183Z"/><path id="shape128" transform="translate(763.686149445708, 36.56223914494)" fill="#444444" fill-rule="evenodd" d="M0 4.66643L16.4949 15.0505L23.6455 15.6915L36.8927 9.02518L48.2312 13.7429L53.5015 11.1276L40.7956 5.69202L57.7463 6.58941L62.8458 2.20502L47.9463 0.666633L30.5113 0L19.942 4.17927Z"/><path id="shape129" transform="translate(938.952551986355, 33.4543091624825)" fill="#444444" fill-rule="evenodd" d="M9.76382 0L0 3.63903L5.16908 5.56193L13.2099 5.27247L24.6967 3.82512L29.0388 2.95672L20.998 0.0206763Z"/><path id="shape130" transform="translate(905.594732384704, 34.2813625410358)" fill="#444444" fill-rule="evenodd" d="M0 2.31575L6.70832 5.78937L14.1288 4.90029L15.1626 0L1.95276 2.97739Z"/><path id="shape131" transform="translate(1087.84560659632, 33.3407292761394)" fill="#444444" fill-rule="evenodd" d="M0 4.71565L6.88803 0.87425L17.1023 0L25.0795 5.6164L31.4671 9.40481L25.5799 11.7626L9.83164 11.0473Z"/><path id="shape132" transform="translate(1118.7534472708, 41.1030126912437)" fill="#444444" fill-rule="evenodd" d="M0 6.14624L11.6272 0L21.3706 4.42424Z"/><path id="shape133" transform="translate(1267.53608686259, 53.1828190415115)" fill="#444444" fill-rule="evenodd" d="M5.51131 1.13574L0 4.51979L5.87186 6.79127L13.6495 6.16545L26.2946 7.41709L31.2136 4.6125L23.6162 2.31784L14.2418 1.69202L11.924 3.19862L2.88442 0Z"/><path id="shape134" transform="translate(1304.8532969985, 58.1661731900951)" fill="#444444" fill-rule="evenodd" d="M0 0L0.20603 1.57613L17.2808 2.01652Z"/><path id="shape135" transform="translate(420.768134455579, 634.824693053502)" fill="#444444" fill-rule="evenodd" d="M11.6494 0L10.3448 3.42266L12.2046 5.58785L16.0724 7.81966L12.1028 9.6101L3.78445 10.243L0 13.1743L7.865 14.8898L20.3102 14.3985L24.9829 11.9752L22.4199 7.01188L18.765 1.75713L15.3506 0.0832764Z"/><path id="shape136" transform="translate(1154.92508001971, 280.092185520219)" fill="#444444" fill-rule="evenodd" d="M2.64188 0L0 3.07644L1.31555 6.3761L4.37797 5.72587L7.88251 3.14438L8.4648 1.11606L6.58853 0.262031L1.73609 0.679341L1.89784 0.708455Z"/><path id="shape137" transform="translate(1200.10663056773, 258.634723125112)" fill="#444444" fill-rule="evenodd" d="M4.64755 0.223212L1.66061 3.69755L0 8.3753L0.657774 11.8593L2.92224 11.8011L5.18671 7.83183L7.42962 3.09585L6.90124 0Z"/><path id="shape138" transform="translate(729.707331713763, 200.063699968501)" fill="#444444" fill-rule="evenodd" d="M1.92449 0L0 1.24474L2.41885 2.6113L3.23102 1.39834Z"/><path id="shape139" transform="translate(754.372550078469, 187.256148499812)" fill="#444444" fill-rule="evenodd" d="M2.90144 0L2.89556 1.69496L0 2.29349L0.0588528 4.75119L1.88329 6.3561L3.24868 3.86133L3.80778 1.33478Z"/><path id="shape140" transform="translate(752.936541182981, 195.031783551936)" fill="#444444" fill-rule="evenodd" d="M3.04269 0.201277L1.28299 1.23944L0 2.18756L0.876907 4.45457L0.570872 8.21527L3.14863 8.55955L5.37326 6.99172L5.67341 3.78188L6.4797 1.56784L4.33745 0Z"/><path id="shape141" transform="translate(769.831715513804, 207.272582329496)" fill="#444444" fill-rule="evenodd" d="M0.682693 0.365476L7.16239 0.58794L11.5822 0L10.2992 3.03504L10.8054 5.90588L7.81565 5.61986L1.76558 2.82847L0 1.98099Z"/><path id="shape142" transform="translate(814.66873916246, 217.89522272257)" fill="#444444" fill-rule="evenodd" d="M0 0L3.64888 0.190683L9.66952 1.09643L7.60378 2.65897L3.50174 2.65367Z"/><path id="shape143" transform="translate(849.87008426957, 217.410569720343)" fill="#444444" fill-rule="evenodd" d="M0 2.56363L2.41297 1.17058L5.6793 1.35597L7.45077 0L4.93187 3.05623L2.09516 4.10498Z"/><path id="shape144" transform="translate(62.288882574212, 673.678895969065)" fill="#444444" fill-rule="evenodd" d="M0 2.81121L5.19621 0L21.1935 4.19054L19.1209 5.81947L7.8673 4.37445Z"/>
</svg>
"""

In order to get the map to display, we need to setup an SVG Renderer. It lives in a separate module of PySide2 that we need to import. Then we can modify the paintEvent like this:

from PySide2 import QtCore, QtGui, QtWidgets, QtSvg

# SVG_MAP = [...] This is the content of the SVG file as shown earlier in the article

class LatLongPicker(QtWidgets.QWidget):

    def updateValue(self):
        pass

    def paintEvent(self, e):
        # Initialize Painter
        painter = QtGui.QPainter(self)
        painter.setRenderHint(painter.Antialiasing)

        width = painter.device().width()
        height = painter.device().height()

        # Render Map
        rect = QtCore.QRect(0, 0, width, height)
        # renderer = QtSvg.QSvgRenderer('/path/to/file.svg', self)  # This is how you would load an external SVG
        renderer = QtSvg.QSvgRenderer(QtCore.QXmlStreamReader(SVG_MAP), self)
        renderer.render(painter, rect)

    def makeUI(self):
        return self

    def sizeHint(self):
        return QtCore.QSize(self.size().width(), 300) 

# Create a NoOp node on which we'll add the knobs
node = nuke.createNode("NoOp")
knob = nuke.PyCustom_Knob("map", "", "LatLongPicker()")
node.addKnob(knob)

That is our background picture, let’s add 2 lines and a small circle to represent our selected position:

    def paintEvent(self, e):
        # Initialize Painter
        painter = QtGui.QPainter(self)
        painter.setRenderHint(painter.Antialiasing)

        width = painter.device().width()
        height = painter.device().height()

        # Render Map
        rect = QtCore.QRect(0, 0, width, height)
        # renderer = QtSvg.QSvgRenderer('/path/to/file.svg', self)  # This is how you would load an external SVG
        renderer = QtSvg.QSvgRenderer(QtCore.QXmlStreamReader(SVG_MAP), self)
        renderer.render(painter, rect)

        # Draw Lines
        painter.drawLine(0, 150, width, 150)
        painter.drawLine(150, 0, 150, height)

        # Draw Dot
        brush = QtGui.QBrush()
        brush.setStyle(QtCore.Qt.SolidPattern)
        painter.setPen(QtCore.Qt.NoPen)
        painter.setBrush(brush)
        painter.drawEllipse(QtCore.QPoint(150, 150), 5, 5)

Adding interactivity

Now that we have our graphical elements, we need to add some interactivity to the widget. At the moment the crosshair is hardcoded to always be 150px from the top and 150px from the left, not very useful.

The logic of doing that is explained in the tutorial I liked a bit earlier in this article, so I will skip the detailed explanation and post the code with added interactivity.

from PySide2 import QtCore, QtGui, QtWidgets, QtSvg

class LatLongPicker(QtWidgets.QWidget):

    def __init__(self, node):
        super(LatLongPicker, self).__init__()
        self.node = node
        self.dot_x = 0
        self.dot_y = 0

        self.setSizePolicy(
            QtWidgets.QSizePolicy.MinimumExpanding,
            QtWidgets.QSizePolicy.MinimumExpanding
        )

    def paintEvent(self, e):
        # Initialize Painter
        painter = QtGui.QPainter(self)
        painter.setRenderHint(painter.Antialiasing)

        width = painter.device().width()
        height = painter.device().height()

        # Render Map
        rect = QtCore.QRect(0, 0, width, height)
        # renderer = QtSvg.QSvgRenderer('/path/to/file.svg', self)  # This is how you would load an external SVG
        renderer = QtSvg.QSvgRenderer(QtCore.QXmlStreamReader(SVG_MAP), self)
        renderer.render(painter, rect)

        # Draw Lines
        painter.drawLine(0, int(height * self.dot_y), width, int(height * self.dot_y))
        painter.drawLine(int(width * self.dot_x), 0, int(width * self.dot_x), height)
        # Draw Dot
        brush = QtGui.QBrush()
        brush.setStyle(QtCore.Qt.SolidPattern)
        painter.setPen(QtCore.Qt.NoPen)
        painter.setBrush(brush)
        painter.drawEllipse(QtCore.QPoint(int(width * self.dot_x), int(height * self.dot_y)), 5, 5)

    def makeUI(self):
        return self

    def sizeHint(self):
        return QtCore.QSize(self.size().width(), 300) 

    def updateValue(self):
        """ Calculate a latlong value based and set it on the respective knobs """
        # Load the values from the nuke node:
        self.set_lat(node['lat'].value())
        self.set_long(node['long'].value())

    def store_value(self):
        """ Save the value of the custom knob into native nuke knobs """
        self.node['lat'].setValue(self.dot_y)
        self.node['long'].setValue(self.dot_x)

    def set_lat(self, value):
        """ Set the knob value based on latitude """
        self.dot_y = value
        self.update()

    def set_long(self, value):
        """ Set the knob value based on longitude """
        self.dot_x = value
        self.update()

    def _calculate_clicked_value(self, e):
        self.dot_y = float(e.y()) / self.size().height()
        self.dot_x = float(e.x()) / self.size().width()
        self.update()
        self.store_value()

    def mouseMoveEvent(self, e):
        self._calculate_clicked_value(e)

    def mousePressEvent(self, e):
        self._calculate_clicked_value(e)

# Create a NoOp node on which we'll add the knobs
node = nuke.createNode("NoOp", inpanel=False)  # I want to add my custom knob before the storage knobs, so don't show the UI yet so the custom one doesn't initialize as soon as it's added

# Custom knob
knob = nuke.PyCustom_Knob("map", "", "LatLongPicker(nuke.thisNode())")
node.addKnob(knob)

# Storage Knobs
lat = nuke.Double_Knob('lat', 'Latitude')
lat.setRange(-90.0, 90.0)
long = nuke.Double_Knob('long', 'Longitude')
long.setRange(-180.0, 180.0)
node.addKnob(lat)
node.addKnob(long)
node.showControlPanel()

We are almost there but, obviously, the latitude and longitude values being set aren’t accurate at all because I am using 0 to 1 coordinate, where on a real map it would go from 90 to -90 for the latitude (north to south) and from -180 to 180 for the longitude (east to west). That means we need to remap our 0 to 1 values to the correct ranges. Linear interpolation is there to the rescue, and I can write a small lerp function to allow me to do it easily.

def lerp(value1, value2, mix_amount):
    """ Simple linear interpolation function"""
    return value1 * (1 - mix_amount) + value2 * mix_amount

While we are at it, let’s also address the problem that modifying my custom knob adjusts my storage knobs, but not the other way around. I will need an inverted lerp function to extract the proper value, and a knobChanged knob on my node to update the custom knob when changing.

def inv_lerp(value1, value2, lerped_value):
    return (lerped_value - value1) / (value2 - value1)

We can use the getObject() method of our custom knob to access our custom class:

node['knobChanged'].setValue("""knob = nuke.thisKnob()
if knob.name()=='lat':
    nuke.thisNode()['map'].getObject().set_lat(knob.value())
if knob.name()=='long':
    nuke.thisNode()['map'].getObject().set_long(knob.value())""")

The behavior is getting there, and the coordinates are quite close to being accurate (I have checked a few locations by setting them on the map and comparing the values with actual coordinates, and it’s always roughly matching.

There are a few more tweaks that I would like to do before calling it done.
First I’d like to use some of the colors from the nuke UI to make the map feel a bit more like a native knob.
We can access the colors through the properties, and format the colors as a hex value that PySide will accept:

# Extract some colors from nuke to match look
highlight_color = "#{:X}".format(nuke.toNode('preferences')['UIHighlightColor'].value())[:7]
line_color = "#{:X}".format(nuke.toNode('preferences')['UILabelColor'].value())[:7]
# Then in the paintEvent method, we can use them to define brush or pen color
pen.setColor(QtGui.QColor(self.line_color))
brush.setColor(QtGui.QColor(highlight_color))

Finally, if I set my storage knobs to be animated, the knob does not update when I change frames, which really breaks the feeling of the knob being integrated. For this, there has been some discussion regarding the best way to make this work. I have settled on sending a Qt Signal whenever the frame knob of a viewer is changed, via a global knobChanged callback. It’s a bit hack-ish, but fairly efficient. If anyone has other suggestions, I invite you to suggest it in the forum post.

class FrameSignaller(QtCore.QObject):
    """ Mini Class to emit a signal"""
    frame_changed = QtCore.Signal()


# Create a global FrameSignaller
FRAME_SIGNALLER = FrameSignaller()


def frame_changed():
    if "FRAME_SIGNALLER" not in globals():
        return

    knob = nuke.thisKnob()
    if knob.name() == 'frame':
        FRAME_SIGNALLER.frame_changed.emit()


nuke.addKnobChanged(frame_changed, nodeClass="Viewer")

It works but I’m not very happy about the behavior when hitting play (it updates on play, not on stop). Still, changing the frame refreshes the widget, which is better than the previous behavior. I can think of a few ways to possibly improve the behavior a bit further, maybe updating when the mouse enters the widget or every X seconds, but as of now, I am not sure which changes would improve the user experience or worsen it. Once the tool is in a more complete state, I will be testing it with a few different changes to see which feels like the best solution.

This concludes part 1 of this tutorial. Because I’m writing at the same time as I’m thinking about the tool and developing it, things might change, or I may even completely fail and get stuck on a further step. The finished product isn’t necessarily my main goal here, I just hope that the process we have just been through can be helpful to others in the future. If anyone has more information on the custom knob I would love to hear it, and if anyone at Foundry is reading, I’d love to have a chat about knobs in general.

Stay posted for part 2 in a few weeks.