diff --git a/logo/vector-logo-R2000.dxf b/logo/vector-logo-R2000.dxf
new file mode 100644
index 0000000000000000000000000000000000000000..4b28e7a23db2faa41a63418905adaca995dbfa5e
Binary files /dev/null and b/logo/vector-logo-R2000.dxf differ
diff --git a/logo/vector-logo.svg b/logo/vector-logo.svg
new file mode 100644
index 0000000000000000000000000000000000000000..d5fb7347d1515a4c888a96819bc47e88d7156889
--- /dev/null
+++ b/logo/vector-logo.svg
@@ -0,0 +1,523 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://creativecommons.org/ns#"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   version="1.1"
+   width="765.09448"
+   height="779.328"
+   id="svg2">
+  <defs
+     id="defs4">
+    <symbol
+       id="*Paper_Space0" />
+    <symbol
+       id="*Paper_Space" />
+    <symbol
+       id="*Model_Space" />
+    <pattern
+       height="8"
+       id="Hatch"
+       patternUnits="userSpaceOnUse"
+       width="8"
+       x="0"
+       y="0">
+      <path
+         d="M8 4 l-4,4"
+         linecap="square"
+         stroke="#000000"
+         stroke-width="0.25"
+         id="path3049" />
+      <path
+         d="M6 2 l-4,4"
+         linecap="square"
+         stroke="#000000"
+         stroke-width="0.25"
+         id="path3051" />
+      <path
+         d="M4 0 l-4,4"
+         linecap="square"
+         stroke="#000000"
+         stroke-width="0.25"
+         id="path3053" />
+    </pattern>
+    <marker
+       refX="0"
+       refY="0"
+       orient="auto"
+       id="DistanceX"
+       style="overflow:visible">
+      <path
+         d="M 3,-3 -3,3 M 0,-5 0,5"
+         id="path3046"
+         style="stroke:#000000;stroke-width:0.5" />
+    </marker>
+  </defs>
+  <metadata
+     id="metadata7">
+    <rdf:RDF>
+      <cc:Work
+         rdf:about="">
+        <dc:format>image/svg+xml</dc:format>
+        <dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+        <dc:title></dc:title>
+      </cc:Work>
+    </rdf:RDF>
+  </metadata>
+  <g
+     transform="translate(-1595.2072,-3900.1734)"
+     id="layer1">
+    <g
+       transform="translate(1605.7072,3616.6359)"
+       id="g3058" />
+    <g
+       transform="translate(1605.7072,3616.6359)"
+       id="g3060">
+      <path
+         d="m 376.28676,565.33282 a 50.505437,50.505437 0 0 0 2.94079,-22.54604 4.006761,4.006761 0 1 0 -7.97559,0.77878 42.491917,42.491917 0 0 1 -2.47419,18.96875 4.0067627,4.0067627 0 0 0 7.50899,2.79851 z"
+         id="path3062"
+         style="fill:none;stroke:#00ff00" />
+      <path
+         d="m 310.44438,550.74978 a 59.389614,59.389614 0 0 1 1.23877,-16.00076 4.0067628,4.0067628 0 0 1 7.83278,1.69238 51.376093,51.376093 0 0 0 -1.07162,13.84176 4.0067635,4.0067635 0 0 1 -7.99993,0.46662 z"
+         id="path3064"
+         style="fill:none;stroke:#00ff00" />
+      <path
+         d="m 392.10618,427.13329 a 12.200345,12.200345 0 0 0 12.0626,-15.93766 22.471543,22.471543 0 0 0 -5.15835,-8.6452 11.14774,11.14774 0 0 0 -16.96297,10.95558 4.0067603,4.0067603 0 0 0 7.93984,-1.08418 3.13422,3.13422 0 0 1 4.03924,-3.41591 14.458023,14.458023 0 0 1 2.51573,4.64997 4.186825,4.186825 0 0 1 -4.13955,5.46937 4.0067602,4.0067602 0 0 0 -0.29654,8.00803 z"
+         id="path3066"
+         style="fill:none;stroke:#00ff00" />
+      <path
+         d="m 371.77724,411.5205 a 15.711594,15.711594 0 0 0 -0.4822,-3.9744 3.414554,3.414554 0 0 0 -6.42324,-0.56196 8.601878,8.601878 0 0 0 3.73033,11.08591 4.00676,4.00676 0 0 1 -3.83196,7.03793 16.615399,16.615399 0 0 1 -7.20551,-21.41355 11.428075,11.428075 0 0 1 21.49777,1.88081 23.725114,23.725114 0 0 1 0.72814,6.0015 4.0067635,4.0067635 0 0 1 -8.01333,-0.0562 z"
+         id="path3068"
+         style="fill:none;stroke:#00ff00" />
+      <path
+         d="m 379.3526,301.76746 a 23.936355,23.936355 0 0 0 -9.95309,7.37952 4.0067642,4.0067642 0 1 1 -6.27618,-4.98259 31.949875,31.949875 0 0 1 13.28523,-9.85006 4.0067605,4.0067605 0 0 1 2.94404,7.45313 z"
+         id="path3070"
+         style="fill:none;stroke:#00ff00" />
+      <path
+         d="m 445.68236,329.11654 a 17.364203,17.364203 0 0 0 -11.77173,-12.76486 4.0067634,4.0067634 0 1 1 2.3854,-7.65026 25.377723,25.377723 0 0 1 17.20435,18.65581 4.0067633,4.0067633 0 0 1 -7.81802,1.75931 z"
+         id="path3072"
+         style="fill:none;stroke:#00ff00" />
+      <path
+         d="m 573.77832,824.21829 a 231.49358,231.49358 0 0 0 42.29005,-25.76377 97.552014,97.552014 0 0 1 -10.48364,37.94069 29.283353,29.283353 0 0 1 -12.73834,12.73834 208.98141,208.98141 0 0 1 -37.85329,14.91063 102.01883,102.01883 0 0 0 18.78522,-39.82589 z"
+         id="path3074"
+         style="fill:none;stroke:#00ff00" />
+      <path
+         d="m 409.47237,828.37833 a 223.48006,223.48006 0 0 0 206.73547,-40.24557 97.552014,97.552014 0 0 0 -0.19497,-3.41849 80.161845,80.161845 0 0 0 -11.72761,-36.13952 26.25055,26.25055 0 0 0 -21.76496,-12.45524 215.19714,215.19714 0 0 1 -186.57181,44.02404 217.80817,217.80817 0 0 0 13.52388,48.23478 z"
+         id="path3076"
+         style="fill:none;stroke:#00ff00" />
+      <path
+         d="m 517.45426,842.3746 a 107.84051,107.84051 0 0 1 -13.06728,29.83277 381.1671,381.1671 0 0 0 15.49202,-1.3351 208.98141,208.98141 0 0 0 21.55961,-3.44895 94.005315,94.005315 0 0 0 22.97314,-39.0461 231.49358,231.49358 0 0 1 -46.95749,13.99738 z"
+         id="path3078"
+         style="fill:none;stroke:#00ff00" />
+      <path
+         d="m 450.45349,871.92484 a 82.150232,82.150232 0 0 0 12.01617,-26.0055 231.49358,231.49358 0 0 0 46.23144,-2.09169 99.826988,99.826988 0 0 1 -14.33124,28.90521 381.1671,381.1671 0 0 1 -43.91637,-0.80802 z"
+         id="path3080"
+         style="fill:none;stroke:#00ff00" />
+      <path
+         d="m 413.65999,837.94547 a 231.49358,231.49358 0 0 0 40.66298,7.38175 74.136712,74.136712 0 0 1 -12.82798,25.25052 39.270306,39.270306 0 0 1 -20.00183,-17.43165 217.80817,217.80817 0 0 1 -7.83317,-15.20062 z"
+         id="path3082"
+         style="fill:none;stroke:#00ff00" />
+      <path
+         d="m 394.76071,771.6117 a 207.18362,207.18362 0 0 0 23.71188,4.47646 73.871194,73.871194 0 0 0 1.94716,-13.81518 232.6189,232.6189 0 0 1 -26.66931,-1.40174 217.80817,217.80817 0 0 0 1.01027,10.74046 z"
+         id="path3084"
+         style="fill:none;stroke:#00ff00" />
+      <path
+         d="m 426.49583,776.96489 a 207.18362,207.18362 0 0 0 44.08456,-0.76029 79.152083,79.152083 0 0 0 9.83174,-22.10671 232.6189,232.6189 0 0 1 -51.96427,7.99697 81.884715,81.884715 0 0 1 -1.95203,14.87003 z"
+         id="path3086"
+         style="fill:none;stroke:#00ff00" />
+      <path
+         d="m 489.28386,751.49075 a 87.165603,87.165603 0 0 1 -8.50621,23.18584 207.18362,207.18362 0 0 0 55.05061,-17.86255 77.758554,77.758554 0 0 0 2.10781,-27.07964 232.6189,232.6189 0 0 1 -48.65221,21.75635 z"
+         id="path3088"
+         style="fill:none;stroke:#00ff00" />
+      <path
+         d="m 393.3415,752.76013 a 217.80817,217.80817 0 0 1 1.1775,-30.55375 283.78976,283.78976 0 0 1 1.37461,-10.69942 202.37681,202.37681 0 0 0 114.74785,-44.62022 l 13.46305,-9.42693 a 30.662014,30.662014 0 0 1 30.54534,-2.67237 43.31958,43.31958 0 0 1 24.50085,32.62626 224.60538,224.60538 0 0 1 -185.8092,65.34643 z"
+         id="path3090"
+         style="fill:none;stroke:#00ff00" />
+      <path
+         d="m 397.2145,703.38787 a 194.36329,194.36329 0 0 0 108.49341,-42.81743 23.586902,23.586902 0 0 0 7.177,-26.78491 9.918601,9.918601 0 0 0 -9.0861,-6.36216 46.235274,46.235274 0 0 0 -20.07565,4.19848 368.58869,368.58869 0 0 0 -82.20858,51.76929 283.78976,283.78976 0 0 0 -4.30008,19.99673 z"
+         id="path3092"
+         style="fill:none;stroke:#00ff00" />
+      <path
+         d="m 330.50955,405.93841 a 43.354257,43.354257 0 0 0 -21.50063,22.02808 209.96578,209.96578 0 0 0 -17.42053,85.99371 70.711924,70.711924 0 0 0 11.83735,38.4211 73.780204,73.780204 0 0 0 36.19311,28.46005 56.856184,56.856184 0 0 0 26.52196,2.98592 76.570466,76.570466 0 0 0 22.51248,-6.43214 134.78926,134.78926 0 0 0 31.95362,-20.63291 86.740478,86.740478 0 0 0 29.81077,-62.11513 288.53091,288.53091 0 0 0 -2.17155,-48.33622 33.216431,33.216431 0 0 0 -13.19493,-22.44209 85.769489,85.769489 0 0 1 -11.32318,18.65937 20.678757,20.678757 0 0 1 -29.15081,3.20659 l -12.48299,-10.06693 -5.83399,3.19814 a 20.393506,20.393506 0 0 1 -20.81496,1.9248 43.705101,43.705101 0 0 1 -23.03486,-26.94516 75.590657,75.590657 0 0 1 -1.90086,-7.90718 z"
+         id="path3094"
+         style="fill:none;stroke:#00ff00" />
+      <path
+         d="m 382.94763,426.06136 16.66009,13.43555 a 12.665237,12.665237 0 0 0 17.85416,-1.96395 77.755969,77.755969 0 0 0 11.39889,-77.33361 16.166727,16.166727 0 0 0 -27.11236,-4.71923 57.567866,57.567866 0 0 0 -9.01787,14.03492 4.00676,4.00676 0 0 1 -7.47927,-2.8312 l 3.66419,-11.92814 a 20.187638,20.187638 0 0 0 -4.10085,-15.3254 13.55444,13.55444 0 0 0 -18.36656,-2.78633 67.577137,67.577137 0 0 0 -26.35813,74.91214 35.691581,35.691581 0 0 0 18.81131,22.00464 12.379986,12.379986 0 0 0 12.99693,-1.44218 l 11.04947,-6.05721 z"
+         id="path3096"
+         style="fill:none;stroke:#00ff00" />
+      <path
+         d="m 179.88519,850.89001 a 143.93977,143.93977 0 0 0 -60.7871,11.41043 39.086677,39.086677 0 0 1 31.634,-33.28021 75.323314,75.323314 0 0 0 2.87715,2.61567 204.7432,204.7432 0 0 0 26.27595,19.25411 z"
+         id="path3098"
+         style="fill:none;stroke:#00ff00" />
+      <path
+         d="m 180.7201,841.94194 a 63.377551,63.377551 0 0 1 -1.06614,-14.26533 168.39098,168.39098 0 0 0 36.56014,14.90295 79.890316,79.890316 0 0 0 10.90348,21.32858 196.72968,196.72968 0 0 1 -46.39748,-21.9662 z"
+         id="path3100"
+         style="fill:none;stroke:#00ff00" />
+      <path
+         d="m 155.0269,736.60456 a 82.876006,82.876006 0 0 0 27.62666,25.09115 130.32087,130.32087 0 0 0 74.55456,16.14168 164.72099,164.72099 0 0 0 15.34776,62.39714 160.37746,160.37746 0 0 1 -136.796,-59.85916 67.309794,67.309794 0 0 1 -0.20129,-8.24674 45.220678,45.220678 0 0 1 19.46831,-35.52407 z"
+         id="path3102"
+         style="fill:none;stroke:#00ff00" />
+      <path
+         d="m 139.14621,796.42854 a 168.39098,168.39098 0 0 0 32.78872,26.71342 71.391072,71.391072 0 0 0 -0.11078,12.70846 196.72968,196.72968 0 0 1 -12.97919,-10.28113 67.309794,67.309794 0 0 1 -19.69875,-29.14075 z"
+         id="path3104"
+         style="fill:none;stroke:#00ff00" />
+      <path
+         d="m 341.4891,589.85722 a 55.435829,55.435829 0 0 0 -3.2324,14.50355 71.84369,71.84369 0 0 1 11.19892,-6.75508 18.566982,18.566982 0 0 1 23.47316,6.28961 55.133466,55.133466 0 0 1 9.2031,25.28531 115.24382,115.24382 0 0 1 -6.52826,51.71425 126.76861,126.76861 0 0 0 -6.84034,27.96367 258.78206,258.78206 0 0 0 9.55239,109.18435 88.989436,88.989436 0 0 0 27.4297,41.50727 115.2534,115.2534 0 0 0 7.14653,-5.382 225.82169,225.82169 0 0 1 -26.33907,-132.83166 291.80328,291.80328 0 0 1 25.82839,-92.10092 8852.0265,8852.0265 0 0 0 12.90415,-27.67305 271.41458,271.41458 0 0 0 20.23505,-62.43919 94.753998,94.753998 0 0 1 -19.66016,23.69024 142.80278,142.80278 0 0 1 -33.85334,21.85959 84.583986,84.583986 0 0 1 -24.86854,7.10529 64.869704,64.869704 0 0 1 -25.64928,-1.92123 z"
+         id="path3106"
+         style="fill:none;stroke:#00ff00" />
+      <path
+         d="m 369.13833,815.32419 a 74.028904,74.028904 0 0 1 -95.89339,5.11915 156.70747,156.70747 0 0 0 7.87587,19.12 72.321745,72.321745 0 0 0 10.15696,15.35524 101.22787,101.22787 0 0 0 67.15775,-1.90467 4.00676,4.00676 0 1 1 2.87252,7.48098 109.24139,109.24139 0 0 1 -57.82815,5.65243 72.321745,72.321745 0 0 0 22.40696,10.97918 68.754331,68.754331 0 0 0 26.53851,2.32182 115.2534,115.2534 0 0 0 46.29388,-15.39035 97.002956,97.002956 0 0 1 -28.05765,-43.64199 266.79558,266.79558 0 0 1 -1.52326,-5.09179 z"
+         id="path3108"
+         style="fill:none;stroke:#00ff00" />
+      <path
+         d="m 331.35491,621.89163 a 63.83017,63.83017 0 0 0 -6.26256,9.21212 593.88382,593.88382 0 0 0 -3.81437,6.93228 23.165032,23.165032 0 0 0 9.50587,5.45484 4.00676,4.00676 0 0 1 -2.23105,7.69668 31.178552,31.178552 0 0 1 -11.14625,-5.8833 593.88382,593.88382 0 0 0 -6.91493,13.6255 407.95821,407.95821 0 0 1 -4.08498,8.0845 48.659079,48.659079 0 0 0 46.84863,19.18747 4.0067617,4.0067617 0 1 1 1.2638,7.91324 56.672599,56.672599 0 0 1 -52.22496,-19.38464 407.95821,407.95821 0 0 1 -16.52659,27.58179 65.112051,65.112051 0 0 0 52.57372,21.39817 4.0067601,4.0067601 0 1 1 0.51631,7.99687 73.125571,73.125571 0 0 1 -57.61157,-22.48672 105.69968,105.69968 0 0 0 -14.77227,40.38221 82.248315,82.248315 0 0 0 75.51268,24.07677 4.00676,4.00676 0 0 1 1.54551,7.86307 90.261836,90.261836 0 0 1 -78.11221,-21.76739 156.70747,156.70747 0 0 0 3.66136,45.9627 66.015383,66.015383 0 0 0 97.64216,0.62811 266.79558,266.79558 0 0 1 -5.90981,-98.5153 134.78213,134.78213 0 0 1 7.27275,-29.73136 107.2303,107.2303 0 0 0 6.07431,-48.11829 47.119946,47.119946 0 0 0 -7.86545,-21.61014 10.553462,10.553462 0 0 0 -13.34213,-3.57501 63.83017,63.83017 0 0 0 -14.61804,9.78433 55.435829,55.435829 0 0 0 2.04764,10.34614 80.71878,80.71878 0 0 0 10.60797,22.29072 29.900833,29.900833 0 0 1 0,33.65259 4.0067602,4.0067602 0 0 1 -6.62426,-4.50951 21.887312,21.887312 0 0 0 1.95062,-21.10962 31.201566,31.201566 0 0 1 -14.27347,19.66503 4.0067611,4.0067611 0 0 1 -4.14047,-6.86098 23.188046,23.188046 0 0 0 9.62936,-28.26012 88.732301,88.732301 0 0 1 -4.82714,-12.57156 63.449349,63.449349 0 0 1 -1.35018,-5.35119 z"
+         id="path3110"
+         style="fill:none;stroke:#00ff00" />
+      <path
+         d="m 269.57245,713.65446 a 113.7132,113.7132 0 0 0 -11.4262,37.77549 110.10404,110.10404 0 0 1 -96.97148,-61.264 49.107667,49.107667 0 0 1 17.58582,-15.78918 36.418066,36.418066 0 0 1 25.93358,-3.17223 30.817043,30.817043 0 0 0 2.53011,4.95806 72.633968,72.633968 0 0 0 22.72798,22.72798 103.55567,103.55567 0 0 0 39.62019,14.76388 z"
+         id="path3112"
+         style="fill:none;stroke:#00ff00" />
+      <path
+         d="m 215.86437,750.95726 a 106.24555,106.24555 0 0 0 1.67841,15.89514 122.30735,122.30735 0 0 1 -30.97555,-12.14953 74.862486,74.862486 0 0 1 -7.75035,-4.98777 64.183337,64.183337 0 0 1 2.26887,-20.3627 118.11756,118.11756 0 0 0 34.77862,21.60486 z"
+         id="path3114"
+         style="fill:none;stroke:#00ff00" />
+      <path
+         d="m 174.63302,723.11977 a 72.196858,72.196858 0 0 0 -3.81679,19.80765 74.862486,74.862486 0 0 1 -13.79039,-18.41208 28.198881,28.198881 0 0 1 -1.92017,-21.94772 49.107667,49.107667 0 0 1 1.46515,-3.93072 118.11756,118.11756 0 0 0 18.0622,24.48287 z"
+         id="path3116"
+         style="fill:none;stroke:#00ff00" />
+      <path
+         d="m 273.73824,706.13565 a 95.542154,95.542154 0 0 1 -39.51377,-14.0248 64.620448,64.620448 0 0 1 -20.22046,-20.22046 22.803523,22.803523 0 0 1 26.02263,-33.94491 149.61449,149.61449 0 0 1 55.90254,31.71704 399.94469,399.94469 0 0 1 -19.33967,31.99615 113.7132,113.7132 0 0 0 -2.85127,4.47698 z"
+         id="path3118"
+         style="fill:none;stroke:#00ff00" />
+      <path
+         d="m 545.05438,752.02278 a 85.772074,85.772074 0 0 0 0.38873,-26.93543 232.6189,232.6189 0 0 0 34.00718,-26.74347 119.25749,119.25749 0 0 1 -9.91732,37.83297 207.18362,207.18362 0 0 1 -24.47859,15.84593 z"
+         id="path3120"
+         style="fill:none;stroke:#00ff00" />
+      <path
+         d="m 240.84019,867.78115 a 71.876795,71.876795 0 0 1 -15.21004,-22.88963 168.39098,168.39098 0 0 0 50.89266,3.05759 80.335265,80.335265 0 0 0 20.63345,23.4764 154.30544,154.30544 0 0 1 -49.09939,-2.03029 196.72968,196.72968 0 0 1 -7.21668,-1.61407 z"
+         id="path3122"
+         style="fill:none;stroke:#00ff00" />
+      <path
+         d="m 224.02047,753.88817 a 118.11756,118.11756 0 0 0 33.39064,5.54325 164.72099,164.72099 0 0 0 -0.36757,10.377 122.30735,122.30735 0 0 1 -30.98247,-1.21337 98.23203,98.23203 0 0 1 -2.0406,-14.70688 z"
+         id="path3124"
+         style="fill:none;stroke:#00ff00" />
+      <path
+         d="m 581.2891,728.10608 a 34.26407,34.26407 0 0 1 29.81506,16.25927 88.175365,88.175365 0 0 1 12.89998,39.75227 105.56553,105.56553 0 0 1 -11.28476,55.92633 37.296873,37.296873 0 0 1 -16.22425,16.22424 216.99493,216.99493 0 0 1 -75.76537,22.57231 389.18062,389.18062 0 0 1 -78.68798,0.40113 47.283826,47.283826 0 0 1 -24.9978,-18.12609 123.26692,123.26692 0 0 1 -63.75725,26.29987 76.767852,76.767852 0 0 1 -29.63164,-2.59243 80.335265,80.335265 0 0 1 -16.39729,-6.79646 162.31896,162.31896 0 0 1 -60.80272,-0.7795 204.7432,204.7432 0 0 1 -48.82219,-16.5864 135.92625,135.92625 0 0 0 -81.12913,11.60923 4.00676,4.00676 0 0 1 -5.7421,-3.49872 47.100197,47.100197 0 0 1 33.74161,-46.48812 75.323314,75.323314 0 0 1 -16.95274,-50.45011 53.234199,53.234199 0 0 1 23.22968,-42.03299 82.876006,82.876006 0 0 1 -0.83023,-1.5231 36.212402,36.212402 0 0 1 -2.46585,-28.18481 57.121187,57.121187 0 0 1 27.515,-32.79109 44.431586,44.431586 0 0 1 27.61588,-4.68162 30.817043,30.817043 0 0 1 39.77667,-32.33039 157.62801,157.62801 0 0 1 57.39495,32.08215 399.94469,399.94469 0 0 0 3.51298,-6.97563 601.89734,601.89734 0 0 1 14.79775,-28.20148 71.84369,71.84369 0 0 1 11.98838,-15.82569 63.449349,63.449349 0 0 1 3.83179,-24.13961 81.793724,81.793724 0 0 1 -37.16337,-30.40815 78.725445,78.725445 0 0 1 -13.17884,-42.77522 217.9793,217.9793 0 0 1 18.0854,-89.27573 51.367777,51.367777 0 0 1 27.79302,-27.10727 75.590657,75.590657 0 0 1 32.44045,-67.61214 21.56796,21.56796 0 0 1 29.22504,4.43363 28.201159,28.201159 0 0 1 5.85316,14.40068 24.180247,24.180247 0 0 1 39.32928,8.34011 85.769489,85.769489 0 0 1 1.73021,58.95357 41.229951,41.229951 0 0 1 18.16135,29.10313 296.54442,296.54442 0 0 1 2.23278,49.6552 279.4281,279.4281 0 0 1 -25.87209,110.0002 8860.04,8860.04 0 0 1 -12.91584,27.69811 283.78976,283.78976 0 0 0 -14.4139,37.46509 376.60221,376.60221 0 0 1 75.15967,-45.76261 54.248794,54.248794 0 0 1 23.55518,-4.92616 17.932121,17.932121 0 0 1 16.42701,11.50232 31.600422,31.600422 0 0 1 1.24923,18.60663 38.675535,38.675535 0 0 1 36.42124,-1.99531 51.333101,51.333101 0 0 1 29.44345,50.99757 127.27101,127.27101 0 0 1 -6.19086,29.58379 z"
+         id="path3126"
+         style="fill:none;stroke:#00ff00" />
+      <path
+         d="m 8.01352,861.4055 0,50.1886 34.304866,12.48595 20.748018,-11.97887 a 4.00676,4.00676 0 0 1 4.00676,6.93991 l -14.92474,8.6168 6.564258,2.3892 20.748018,-11.97888 a 4.00676,4.00676 0 0 1 4.00676,6.93991 l -14.924741,8.61681 6.564258,2.38919 20.748018,-11.97887 a 4.0067603,4.0067603 0 0 1 4.006761,6.93991 l -14.924741,8.6168 6.564258,2.3892 20.748017,-11.97888 a 4.00676,4.00676 0 0 1 4.00676,6.93991 l -14.92474,8.61681 6.56426,2.38919 20.74802,-11.97887 a 4.00676,4.00676 0 0 1 4.00676,6.93991 l -14.92474,8.6168 6.56426,2.3892 20.74801,-11.97888 a 4.0067635,4.0067635 0 0 1 4.00676,6.93992 l -14.92474,8.6168 6.56426,2.38919 20.74802,-11.97887 a 4.0067603,4.0067603 0 0 1 4.00676,6.93991 l -14.92474,8.6168 6.56426,2.3892 20.74801,-11.97887 a 4.00676,4.00676 0 0 1 4.00676,6.93991 l -14.92474,8.6168 6.56426,2.38919 20.74802,-11.97887 a 4.00676,4.00676 0 0 1 4.00676,6.93991 l -14.92474,8.61681 6.56426,2.38919 20.74802,-11.97887 a 4.00676,4.00676 0 0 1 4.00676,6.93991 l -14.92475,8.6168 6.56426,2.3892 20.74802,-11.97888 a 4.0067635,4.0067635 0 0 1 4.00676,6.93992 l -14.92474,8.6168 6.56426,2.38919 20.74802,-11.97887 a 4.00676,4.00676 0 0 1 4.00676,6.93991 l -14.92474,8.6168 6.56425,2.3892 20.74802,-11.97888 a 4.0067635,4.0067635 0 0 1 4.00676,6.93992 l -14.92474,8.6168 6.56426,2.38918 20.74802,-11.97886 a 4.00676,4.00676 0 0 1 4.00676,6.93991 l -14.92474,8.61685 6.56426,2.3891 20.74801,-11.97883 a 4.0067678,4.0067678 0 0 1 4.00676,6.93993 l -14.92474,8.6168 6.56426,2.3892 20.74802,-11.9789 a 4.00676,4.00676 0 0 1 4.00676,6.9399 l -14.92474,8.6168 69.97762,25.4698 0,-50.1886 L 8.01352,861.4055 z"
+         id="path3128"
+         style="fill:none;stroke:#00ff00" />
+      <path
+         d="m 736.08097,861.4055 0,50.1886 -34.30487,12.48595 -20.74802,-11.97887 a 4.00676,4.00676 0 0 0 -4.00676,6.93991 l 14.92474,8.6168 -6.56425,2.3892 -20.74802,-11.97888 a 4.0067603,4.0067603 0 0 0 -4.00676,6.93991 l 14.92474,8.61681 -6.56426,2.38919 -20.74802,-11.97887 a 4.00676,4.00676 0 0 0 -4.00676,6.93991 l 14.92474,8.6168 -6.56426,2.3892 -20.74801,-11.97888 a 4.00676,4.00676 0 0 0 -4.00676,6.93991 l 14.92474,8.61681 -6.56426,2.38919 -20.74802,-11.97887 a 4.00676,4.00676 0 0 0 -4.00676,6.93991 l 14.92474,8.6168 -6.56426,2.3892 -20.74801,-11.97888 a 4.006766,4.006766 0 0 0 -4.00677,6.93992 l 14.92475,8.6168 -6.56426,2.38919 -20.74802,-11.97887 a 4.00676,4.00676 0 0 0 -4.00676,6.93991 l 14.92474,8.6168 -6.56426,2.3892 -20.74802,-11.97887 a 4.00676,4.00676 0 0 0 -4.00676,6.93991 l 14.92474,8.6168 -6.56425,2.38919 -20.74802,-11.97887 a 4.00676,4.00676 0 0 0 -4.00676,6.93991 l 14.92474,8.61681 -6.56426,2.38919 -20.74802,-11.97887 a 4.0067603,4.0067603 0 0 0 -4.00676,6.93991 l 14.92474,8.6168 -6.56426,2.3892 -20.74801,-11.97888 a 4.0067635,4.0067635 0 0 0 -4.00676,6.93992 l 14.92474,8.6168 -6.56426,2.38919 -20.74802,-11.97887 a 4.00676,4.00676 0 0 0 -4.00676,6.93991 l 14.92474,8.6168 -6.56426,2.3892 -20.74802,-11.97888 a 4.006761,4.006761 0 0 0 -4.00675,6.93992 l 14.92474,8.6168 -6.56426,2.38918 -20.74802,-11.97886 a 4.0067603,4.0067603 0 0 0 -4.00676,6.93991 l 14.92474,8.61685 -6.56426,2.3891 -20.74802,-11.97883 a 4.0067678,4.0067678 0 0 0 -4.00676,6.93993 l 14.92474,8.6168 -6.56425,2.3892 -20.74802,-11.9789 a 4.00676,4.00676 0 0 0 -4.00676,6.9399 l 14.92474,8.6168 -69.97763,25.4698 0,-50.1886 360.02697,-131.0391 z"
+         id="path3130"
+         style="fill:none;stroke:#00ff00" />
+      <path
+         d="m 0,914.39966 a 4.00676,4.00676 0 0 0 2.636367,3.76513 l 36.060572,13.12497 0,27.22772 a 4.00676,4.00676 0 0 0 8.01352,0 l 0,-24.31104 8.380775,3.05036 0,27.22771 a 4.0067605,4.0067605 0 0 0 8.013521,0 l 0,-24.31103 8.380775,3.05035 0,27.22772 a 4.00676,4.00676 0 0 0 8.01352,0 l 0,-24.31103 8.380776,3.05035 0,27.22772 a 4.00676,4.00676 0 0 0 8.01352,0 l 0,-24.31104 8.380774,3.05035 0,27.22772 a 4.00676,4.00676 0 0 0 8.01352,0 l 0,-24.31103 8.38078,3.05035 0,27.22772 a 4.0067605,4.0067605 0 0 0 8.01352,0 l 0,-24.31104 8.38077,3.05036 0,27.22771 a 4.00676,4.00676 0 0 0 8.01352,0 l 0,-24.31103 8.38078,3.05035 0,27.22769 a 4.00676,4.00676 0 0 0 8.01352,0 l 0,-24.31101 8.38077,3.05036 0,27.22775 a 4.00676,4.00676 0 0 0 8.01352,0 l 0,-24.31107 8.38078,3.05035 0,27.22772 a 4.0067605,4.0067605 0 0 0 8.01352,0 l 0,-24.31104 8.38078,3.05036 0,27.22768 a 4.00676,4.00676 0 0 0 8.01352,0 l 0,-24.311 8.38077,3.05035 0,27.22775 a 4.00676,4.00676 0 0 0 8.01352,0 l 0,-24.31106 8.38078,3.05036 0,27.2277 a 4.00676,4.00676 0 0 0 8.01352,0 l 0,-24.311 8.38077,3.0503 0,27.2277 a 4.0067605,4.0067605 0 0 0 8.01352,0 l 0,-24.311 8.38078,3.0504 0,27.2277 a 4.00676,4.00676 0 0 0 8.01352,0 l 0,-24.3111 8.38077,3.0504 0,27.2277 a 4.00676,4.00676 0 0 0 8.01352,0 l 0,-24.311 78.05196,28.4086 a 4.00676,4.00676 0 0 0 2.74079,0 l 78.05195,-28.4086 0,24.311 a 4.00676,4.00676 0 0 0 8.01352,0 l 0,-27.2277 8.38078,-3.0504 0,24.3111 a 4.00676,4.00676 0 0 0 8.01352,0 l 0,-27.2277 8.38078,-3.0504 0,24.311 a 4.00676,4.00676 0 0 0 8.01351,0 l 0,-27.2277 8.38078,-3.0503 0,24.311 a 4.00676,4.00676 0 0 0 8.01352,0 l 0,-27.2277 8.38078,-3.05036 0,24.31106 a 4.00676,4.00676 0 0 0 8.01352,0 l 0,-27.22775 8.38077,-3.05035 0,24.311 a 4.00676,4.00676 0 0 0 8.01352,0 l 0,-27.22768 8.38078,-3.05036 0,24.31104 a 4.00676,4.00676 0 0 0 8.01352,0 l 0,-27.22772 8.38077,-3.05035 0,24.31107 a 4.00676,4.00676 0 0 0 8.01352,0 l 0,-27.22775 8.38078,-3.05036 0,24.31101 a 4.00676,4.00676 0 0 0 8.01352,0 l 0,-27.22769 8.38077,-3.05035 0,24.31103 a 4.006765,4.006765 0 0 0 8.01353,0 l 0,-27.22771 8.38077,-3.05036 0,24.31104 a 4.00676,4.00676 0 0 0 8.01352,0 l 0,-27.22772 8.38078,-3.05035 0,24.31103 a 4.00676,4.00676 0 0 0 8.01352,0 l 0,-27.22772 8.38077,-3.05035 0,24.31104 a 4.00676,4.00676 0 0 0 8.01352,0 l 0,-27.22772 8.38078,-3.05035 0,24.31103 a 4.00676,4.00676 0 0 0 8.01352,0 l 0,-27.22772 8.38077,-3.05035 0,24.31103 a 4.00676,4.00676 0 0 0 8.01352,0 l 0,-27.22771 8.38078,-3.05036 0,24.31104 a 4.00676,4.00676 0 0 0 8.01352,0 l 0,-27.22772 36.06057,-13.12497 a 4.00676,4.00676 0 0 0 2.63637,-3.76513 l 0,-58.7164 a 4.00676,4.00676 0 0 0 -2.31343,-3.63136 L 637.06594,803.22244 a 4.0067602,4.0067602 0 0 0 -3.38666,7.26271 l 95.94824,44.7414 L 372.04724,985.37513 14.466964,855.22655 121.47719,805.32686 a 4.0067602,4.0067602 0 1 0 -3.38666,-7.26271 L 2.31343,852.0519 A 4.00676,4.00676 0 0 0 0,855.68326 l 0,58.7164 z"
+         id="path3132"
+         style="fill:none;stroke:#00ff00" />
+    </g>
+    <g
+       transform="translate(1605.7072,3616.6359)"
+       id="g3210">
+      <path
+         d="m 382.52092,430.86458 14.57154,11.75125 a 16.671997,16.671997 0 0 0 23.50249,-2.58528 81.762729,81.762729 0 0 0 11.98627,-81.3186 20.173487,20.173487 0 0 0 -33.84358,-5.87562 61.574626,61.574626 0 0 0 -9.65625,15.02408 l 3.75178,-12.2133 a 24.194398,24.194398 0 0 0 -4.86625,-18.69008 17.5612,17.5612 0 0 0 -23.7958,-3.60998 71.583897,71.583897 0 0 0 -27.92096,79.3538 39.698341,39.698341 0 0 0 20.92309,24.4749 16.386746,16.386746 0 0 0 16.9218,-1.69218 l 8.42587,-4.61899 z"
+         id="path3212"
+         style="fill:none;stroke:#0000ff" />
+      <path
+         d="m 372.53226,563.93357 a 46.498677,46.498677 0 0 0 2.70749,-20.7574"
+         id="path3214"
+         style="fill:none;stroke:#0000ff" />
+      <path
+         d="m 315.59954,535.59521 a 55.382854,55.382854 0 0 0 -1.1552,14.92126"
+         id="path3216"
+         style="fill:none;stroke:#0000ff" />
+      <path
+         d="m 333.7265,400.35197 a 47.361017,47.361017 0 0 0 -28.39168,26.01605 213.97254,213.97254 0 0 0 -17.75297,87.63472 74.718685,74.718685 0 0 0 12.5081,40.59816 77.786964,77.786964 0 0 0 38.15864,30.00562 60.862944,60.862944 0 0 0 28.391,3.19634 80.577226,80.577226 0 0 0 23.69051,-6.76872 138.79602,138.79602 0 0 0 32.90348,-21.24625 90.747238,90.747238 0 0 0 31.18781,-64.98437 292.53766,292.53766 0 0 0 -2.20171,-49.00746 37.223191,37.223191 0 0 0 -19.05684,-27.8772"
+         id="path3218"
+         style="fill:none;stroke:#0000ff" />
+      <path
+         d="M 341.21132,638.22132 A 27.194806,27.194806 0 0 1 329.9731,671.50499"
+         id="path3220"
+         style="fill:none;stroke:#0000ff" />
+      <path
+         d="m 339.16702,584.93246 a 59.442589,59.442589 0 0 0 -2.62324,41.16208 84.725541,84.725541 0 0 0 11.13454,23.3972 25.894073,25.894073 0 0 1 0,29.14308"
+         id="path3222"
+         style="fill:none;stroke:#0000ff" />
+      <path
+         d="M 543.44764,871.08733 A 98.012075,98.012075 0 0 0 570.2837,821.42548"
+         id="path3224"
+         style="fill:none;stroke:#0000ff" />
+      <path
+         d="m 514.2071,838.88789 a 103.83375,103.83375 0 0 1 -17.74383,37.76773"
+         id="path3226"
+         style="fill:none;stroke:#0000ff" />
+      <path
+         d="m 421.457,780.4836 a 77.877955,77.877955 0 0 0 3.04257,-22.27427"
+         id="path3228"
+         style="fill:none;stroke:#0000ff" />
+      <path
+         d="m 472.9134,779.94366 a 83.158843,83.158843 0 0 0 12.90414,-31.57337"
+         id="path3230"
+         style="fill:none;stroke:#0000ff" />
+      <path
+         d="m 539.22236,759.60757 a 81.765314,81.765314 0 0 0 1.84844,-36.48441"
+         id="path3232"
+         style="fill:none;stroke:#0000ff" />
+      <path
+         d="m 391.12429,774.81454 a 211.19038,211.19038 0 0 0 189.93266,-42.69491 30.25731,30.25731 0 0 1 26.63776,14.35042 84.168605,84.168605 0 0 1 12.3138,37.94589 101.55877,101.55877 0 0 1 -10.85646,53.80364 33.290113,33.290113 0 0 1 -14.48129,14.48129 212.98817,212.98817 0 0 1 -74.36638,22.15551 385.17386,385.17386 0 0 1 -77.47265,0.43588 43.277066,43.277066 0 0 1 -24.83099,-20.18217 221.81493,221.81493 0 0 1 -27.46482,-133.33866 287.79652,287.79652 0 0 1 25.47373,-90.83627 8856.0333,8856.0333 0 0 0 12.91,-27.68558 275.42134,275.42134 0 0 0 25.50174,-108.44606"
+         id="path3234"
+         style="fill:none;stroke:#0000ff" />
+      <path
+         d="m 392.25445,423.12927 a 8.193585,8.193585 0 0 0 8.10107,-10.70351 18.464783,18.464783 0 0 0 -3.87707,-6.71529 7.14098,7.14098 0 0 0 -10.46107,7.25345"
+         id="path3236"
+         style="fill:none;stroke:#0000ff" />
+      <path
+         d="m 366.68615,421.58902 a 12.608639,12.608639 0 0 1 -5.46792,-16.24974 7.421314,7.421314 0 0 1 13.9605,1.22139 19.718354,19.718354 0 0 1 0.60517,4.98795"
+         id="path3238"
+         style="fill:none;stroke:#0000ff" />
+      <path
+         d="M 389.47225,756.31817 A 228.61214,228.61214 0 0 0 583.37899,688.82115"
+         id="path3240"
+         style="fill:none;stroke:#0000ff" />
+      <path
+         d="m 459.3636,841.71136 a 78.143472,78.143472 0 0 1 -16.53187,33.5809"
+         id="path3242"
+         style="fill:none;stroke:#0000ff" />
+      <path
+         d="m 392.42787,707.68071 a 198.37005,198.37005 0 0 0 115.80144,-43.99632 27.593662,27.593662 0 0 0 8.39617,-31.33493 13.925361,13.925361 0 0 0 -12.75656,-8.93223 50.242034,50.242034 0 0 0 -21.81541,4.56232 372.59545,372.59545 0 0 0 -84.1007,53.16609"
+         id="path3244"
+         style="fill:none;stroke:#0000ff" />
+      <path
+         d="m 508.22931,663.68439 13.57702,-9.50673 a 34.668775,34.668775 0 0 1 34.53685,-3.02158 47.326341,47.326341 0 0 1 27.14527,47.017 123.26425,123.26425 0 0 1 -10.72617,40.58526"
+         id="path3246"
+         style="fill:none;stroke:#0000ff" />
+      <path
+         d="M 406.48872,831.64439 A 227.48682,227.48682 0 0 0 620.27078,789.98146"
+         id="path3248"
+         style="fill:none;stroke:#0000ff" />
+      <path
+         d="M 449.59137,328.23689 A 21.370963,21.370963 0 0 0 435.10333,312.52655"
+         id="path3250"
+         style="fill:none;stroke:#0000ff" />
+      <path
+         d="m 377.88058,298.04089 a 27.943115,27.943115 0 0 0 -11.61916,8.61479"
+         id="path3252"
+         style="fill:none;stroke:#0000ff" />
+      <path
+         d="m 405.51281,864.5415 a 92.996196,92.996196 0 0 1 -31.02418,-45.31207 262.78882,262.78882 0 0 1 -9.70029,-110.87486 130.77537,130.77537 0 0 1 7.05655,-28.84752 111.23706,111.23706 0 0 0 6.30128,-49.91627 51.126706,51.126706 0 0 0 -8.53427,-23.44772 14.560222,14.560222 0 0 0 -18.40765,-4.93232 67.83693,67.83693 0 0 0 -29.60939,27.93811 597.89058,597.89058 0 0 0 -14.69925,28.01374 403.95145,403.95145 0 0 1 -26.97769,46.72672 109.70644,109.70644 0 0 0 -17.9377,49.28344 160.71423,160.71423 0 0 0 15.54459,88.15775 76.328505,76.328505 0 0 0 47.24616,39.64424 72.761092,72.761092 0 0 0 28.08507,2.45713 119.26016,119.26016 0 0 0 65.1447,-28.32178"
+         id="path3254"
+         style="fill:none;stroke:#0000ff" />
+      <path
+         d="m 316.38638,638.66914 a 27.171792,27.171792 0 0 0 13.28194,8.67007"
+         id="path3256"
+         style="fill:none;stroke:#0000ff" />
+      <path
+         d="m 301.72732,667.31527 a 52.665839,52.665839 0 0 0 52.15985,22.84307"
+         id="path3258"
+         style="fill:none;stroke:#0000ff" />
+      <path
+         d="m 280.75734,702.63171 a 69.118811,69.118811 0 0 0 57.84206,25.07701"
+         id="path3260"
+         style="fill:none;stroke:#0000ff" />
+      <path
+         d="m 262.24527,750.93628 a 86.255075,86.255075 0 0 0 80.51388,26.67467"
+         id="path3262"
+         style="fill:none;stroke:#0000ff" />
+      <path
+         d="m 265.41082,807.63634 a 70.022143,70.022143 0 0 0 105.72256,-0.1937"
+         id="path3264"
+         style="fill:none;stroke:#0000ff" />
+      <path
+         d="m 359.87178,856.7544 a 105.23463,105.23463 0 0 1 -70.88249,1.63225"
+         id="path3266"
+         style="fill:none;stroke:#0000ff" />
+      <path
+         d="m 307.96308,873.8255 a 158.3122,158.3122 0 0 1 -60.70711,-0.50438 200.73644,200.73644 0 0 1 -91.02887,-44.71853 71.316554,71.316554 0 0 1 -24.67254,-56.62182 49.227439,49.227439 0 0 1 24.65824,-40.8605"
+         id="path3268"
+         style="fill:none;stroke:#0000ff" />
+      <path
+         d="m 261.07655,773.42067 a 126.31411,126.31411 0 0 1 -76.46616,-15.22138 78.869246,78.869246 0 0 1 -31.12248,-31.80322 32.205641,32.205641 0 0 1 -2.19301,-25.06626 53.114427,53.114427 0 0 1 25.58496,-30.49097 40.424826,40.424826 0 0 1 30.8812,-2.93695"
+         id="path3270"
+         style="fill:none;stroke:#0000ff" />
+      <path
+         d="m 275.88011,710.39411 a 99.548914,99.548914 0 0 1 -43.79174,-14.89339 68.627208,68.627208 0 0 1 -21.47423,-21.47423 26.810283,26.810283 0 0 1 30.59503,-39.9093 153.62125,153.62125 0 0 1 59.7228,34.69979"
+         id="path3272"
+         style="fill:none;stroke:#0000ff" />
+      <path
+         d="M 278.74109,843.70013 A 164.38422,164.38422 0 0 1 131.88286,781.93476"
+         id="path3274"
+         style="fill:none;stroke:#0000ff" />
+      <path
+         d="M 261.75187,755.43438 A 114.1108,114.1108 0 0 1 156.58875,689.88039"
+         id="path3276"
+         style="fill:none;stroke:#0000ff" />
+      <path
+         d="m 198.87079,856.80555 a 139.93301,139.93301 0 0 0 -84.10393,11.85358 43.093437,43.093437 0 0 1 37.33346,-43.91361"
+         id="path3278"
+         style="fill:none;stroke:#0000ff" />
+      <path
+         d="m 219.36836,839.27942 a 75.883556,75.883556 0 0 0 19.43078,32.12534"
+         id="path3280"
+         style="fill:none;stroke:#0000ff" />
+      <path
+         d="m 176.21099,821.06404 a 67.384312,67.384312 0 0 0 0.91717,23.32019"
+         id="path3282"
+         style="fill:none;stroke:#0000ff" />
+      <path
+         d="m 219.82446,748.19616 a 102.23879,102.23879 0 0 0 2.92741,23.87741"
+         id="path3284"
+         style="fill:none;stroke:#0000ff" />
+      <path
+         d="M 179.26009,722.11589 A 68.190098,68.190098 0 0 0 174.935,751.80737"
+         id="path3286"
+         style="fill:none;stroke:#0000ff" />
+      <path
+         d="m 372.04724,989.63904 0,58.71636"
+         id="path3288"
+         style="fill:none;stroke:#0000ff" />
+      <path
+         d="m 310.98422,1005.0767 -22.36609,12.913 0,30.0333"
+         id="path3290"
+         style="fill:none;stroke:#0000ff" />
+      <path
+         d="m 65.069784,915.57113 -22.366085,12.91307 0,30.03328"
+         id="path3292"
+         style="fill:none;stroke:#0000ff" />
+      <path
+         d="m 294.58992,999.10963 -22.36608,12.91307 0,30.0333"
+         id="path3294"
+         style="fill:none;stroke:#0000ff" />
+      <path
+         d="m 278.19563,993.1426 -22.36609,12.9131 0,30.0332"
+         id="path3296"
+         style="fill:none;stroke:#0000ff" />
+      <path
+         d="m 261.80133,987.17556 -22.36608,12.91304 0,30.0333"
+         id="path3298"
+         style="fill:none;stroke:#0000ff" />
+      <path
+         d="m 245.40704,981.20852 -22.36609,12.91307 0,30.03331"
+         id="path3300"
+         style="fill:none;stroke:#0000ff" />
+      <path
+         d="m 229.01274,975.24149 -22.36608,12.91306 0,30.03325"
+         id="path3302"
+         style="fill:none;stroke:#0000ff" />
+      <path
+         d="m 212.61845,969.27445 -22.36609,12.91307 0,30.03328"
+         id="path3304"
+         style="fill:none;stroke:#0000ff" />
+      <path
+         d="m 196.22415,963.30742 -22.36609,12.91306 0,30.03332"
+         id="path3306"
+         style="fill:none;stroke:#0000ff" />
+      <path
+         d="m 179.82985,957.34038 -22.36608,12.91307 0,30.03325"
+         id="path3308"
+         style="fill:none;stroke:#0000ff" />
+      <path
+         d="m 163.43556,951.37335 -22.36609,12.91306 0,30.03328"
+         id="path3310"
+         style="fill:none;stroke:#0000ff" />
+      <path
+         d="m 147.04126,945.40631 -22.36608,12.91307 0,30.03328"
+         id="path3312"
+         style="fill:none;stroke:#0000ff" />
+      <path
+         d="m 130.64697,939.43927 -22.36609,12.91307 0,30.03328"
+         id="path3314"
+         style="fill:none;stroke:#0000ff" />
+      <path
+         d="m 114.25267,933.47224 -22.366084,12.91306 0,30.03329"
+         id="path3316"
+         style="fill:none;stroke:#0000ff" />
+      <path
+         d="m 97.858375,927.5052 -22.366085,12.91307 0,30.03328"
+         id="path3318"
+         style="fill:none;stroke:#0000ff" />
+      <path
+         d="m 81.46408,921.53817 -22.366085,12.91306 0,30.03328"
+         id="path3320"
+         style="fill:none;stroke:#0000ff" />
+      <path
+         d="m 433.11027,1005.0767 22.36608,12.913 0,30.0333"
+         id="path3322"
+         style="fill:none;stroke:#0000ff" />
+      <path
+         d="m 465.89886,993.1426 22.36608,12.9131 0,30.0332"
+         id="path3324"
+         style="fill:none;stroke:#0000ff" />
+      <path
+         d="m 449.50456,999.10963 22.36609,12.91307 0,30.0333"
+         id="path3326"
+         style="fill:none;stroke:#0000ff" />
+      <path
+         d="m 515.08175,975.24149 22.36608,12.91306 0,30.03325"
+         id="path3328"
+         style="fill:none;stroke:#0000ff" />
+      <path
+         d="m 498.68745,981.20852 22.36609,12.91307 0,30.03331"
+         id="path3330"
+         style="fill:none;stroke:#0000ff" />
+      <path
+         d="m 482.29316,987.17556 22.36608,12.91304 0,30.0333"
+         id="path3332"
+         style="fill:none;stroke:#0000ff" />
+      <path
+         d="m 547.87034,963.30742 22.36608,12.91306 0,30.03332"
+         id="path3334"
+         style="fill:none;stroke:#0000ff" />
+      <path
+         d="m 531.47604,969.27445 22.36609,12.91307 0,30.03328"
+         id="path3336"
+         style="fill:none;stroke:#0000ff" />
+      <path
+         d="m 597.05322,945.40631 22.36609,12.91307 0,30.03328"
+         id="path3338"
+         style="fill:none;stroke:#0000ff" />
+      <path
+         d="m 564.26463,957.34038 22.36609,12.91307 0,30.03325"
+         id="path3340"
+         style="fill:none;stroke:#0000ff" />
+      <path
+         d="m 580.65893,951.37335 22.36609,12.91306 0,30.03328"
+         id="path3342"
+         style="fill:none;stroke:#0000ff" />
+      <path
+         d="m 679.0247,915.57113 22.36609,12.91307 0,30.03328"
+         id="path3344"
+         style="fill:none;stroke:#0000ff" />
+      <path
+         d="m 613.44752,939.43927 22.36609,12.91307 0,30.03328"
+         id="path3346"
+         style="fill:none;stroke:#0000ff" />
+      <path
+         d="m 629.84182,933.47224 22.36608,12.91306 0,30.03329"
+         id="path3348"
+         style="fill:none;stroke:#0000ff" />
+      <path
+         d="m 646.23611,927.5052 22.36609,12.91307 0,30.03328"
+         id="path3350"
+         style="fill:none;stroke:#0000ff" />
+      <path
+         d="m 662.63041,921.53817 22.36608,12.91306 0,30.03328"
+         id="path3352"
+         style="fill:none;stroke:#0000ff" />
+      <path
+         d="m 740.08773,855.68326 0,58.7164 L 372.04724,1048.3554 4.00676,914.39966 l 0,-58.7164"
+         id="path3354"
+         style="fill:none;stroke:#0000ff" />
+      <path
+         d="M 119.78386,801.69551 4.00676,855.68326 372.04724,989.63904 740.08773,855.68326 635.37261,806.85379"
+         id="path3356"
+         style="fill:none;stroke:#0000ff" />
+    </g>
+  </g>
+</svg>
diff --git a/py/builtin.c b/py/builtin.c
index 2b94163f166b1d351f4278cf0764e583c4ed8e38..d29a2bf8c3c92c96e7548c693f53c1d83a108807 100644
--- a/py/builtin.c
+++ b/py/builtin.c
@@ -16,30 +16,20 @@
 
 mp_obj_t mp_builtin___build_class__(mp_obj_t o_class_fun, mp_obj_t o_class_name) {
     // we differ from CPython: we set the new __locals__ object here
-    mp_map_t *old_locals = rt_get_map_locals();
+    mp_map_t *old_locals = rt_locals_get();
     mp_map_t *class_locals = mp_map_new(MP_MAP_QSTR, 0);
-    rt_set_map_locals(class_locals);
+    rt_locals_set(class_locals);
 
     // call the class code
     rt_call_function_1(o_class_fun, (mp_obj_t)0xdeadbeef);
 
     // restore old __locals__ object
-    rt_set_map_locals(old_locals);
+    rt_locals_set(old_locals);
 
     // create and return the new class
     return mp_obj_new_class(class_locals);
 }
 
-mp_obj_t mp_builtin___import__(int n, mp_obj_t *args) {
-    printf("import:\n");
-    for (int i = 0; i < n; i++) {
-    printf("  ");
-    mp_obj_print(args[i]);
-    printf("\n");
-    }
-    return mp_const_none;
-}
-
 mp_obj_t mp_builtin___repl_print__(mp_obj_t o) {
     if (o != mp_const_none) {
         mp_obj_print(o);
diff --git a/py/builtinimport.c b/py/builtinimport.c
new file mode 100644
index 0000000000000000000000000000000000000000..47dbf21216c450c81d0f7f3518da0c9f7d2be6ea
--- /dev/null
+++ b/py/builtinimport.c
@@ -0,0 +1,84 @@
+#include <stdint.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <stdarg.h>
+#include <string.h>
+#include <assert.h>
+
+#include "nlr.h"
+#include "misc.h"
+#include "mpconfig.h"
+#include "lexer.h"
+#include "lexerunix.h"
+#include "parse.h"
+#include "obj.h"
+#include "compile.h"
+#include "runtime0.h"
+#include "runtime.h"
+#include "map.h"
+#include "builtin.h"
+
+mp_obj_t mp_builtin___import__(int n, mp_obj_t *args) {
+    /*
+    printf("import:\n");
+    for (int i = 0; i < n; i++) {
+        printf("  ");
+        mp_obj_print(args[i]);
+        printf("\n");
+    }
+    */
+
+    // find the file to import
+    qstr mod_name = mp_obj_get_qstr(args[0]);
+    mp_lexer_t *lex = mp_import_open_file(mod_name);
+    if (lex == NULL) {
+        // TODO handle lexer error correctly
+        return mp_const_none;
+    }
+
+    // create a new module object
+    mp_obj_t module_obj = mp_obj_new_module(mp_obj_get_qstr(args[0]));
+
+    // save the old context
+    mp_map_t *old_locals = rt_locals_get();
+    mp_map_t *old_globals = rt_globals_get();
+
+    // set the new context
+    rt_locals_set(mp_obj_module_get_globals(module_obj));
+    rt_globals_set(mp_obj_module_get_globals(module_obj));
+
+    // parse the imported script
+    mp_parse_node_t pn = mp_parse(lex, MP_PARSE_FILE_INPUT);
+    mp_lexer_free(lex);
+
+    if (pn == MP_PARSE_NODE_NULL) {
+        // TODO handle parse error correctly
+        rt_locals_set(old_locals);
+        rt_globals_set(old_globals);
+        return mp_const_none;
+    }
+
+    if (!mp_compile(pn, false)) {
+        // TODO handle compile error correctly
+        rt_locals_set(old_locals);
+        rt_globals_set(old_globals);
+        return mp_const_none;
+    }
+
+    // complied successfully, execute it
+    mp_obj_t module_fun = rt_make_function_from_id(1); // TODO we should return from mp_compile the unique_code_id for the module
+    nlr_buf_t nlr;
+    if (nlr_push(&nlr) == 0) {
+        rt_call_function_0(module_fun);
+        nlr_pop();
+    } else {
+        // exception; restore context and re-raise same exception
+        rt_locals_set(old_locals);
+        rt_globals_set(old_globals);
+        nlr_jump(nlr.ret_val);
+    }
+    rt_locals_set(old_locals);
+    rt_globals_set(old_globals);
+
+    return module_obj;
+}
diff --git a/py/compile.c b/py/compile.c
index b00ab7ef64aed2f1a4af362a37a9f27bcbd28c76..68ac20804de09b974bc50d4ef0cc7977fa19b6fd 100644
--- a/py/compile.c
+++ b/py/compile.c
@@ -10,9 +10,11 @@
 #include "lexer.h"
 #include "parse.h"
 #include "scope.h"
-#include "compile.h"
 #include "runtime0.h"
 #include "emit.h"
+#include "obj.h"
+#include "compile.h"
+#include "runtime.h"
 
 // TODO need to mangle __attr names
 
@@ -3016,7 +3018,7 @@ void compile_scope_compute_things(compiler_t *comp, scope_t *scope) {
     }
 }
 
-bool mp_compile(mp_parse_node_t pn, bool is_repl) {
+mp_obj_t mp_compile(mp_parse_node_t pn, bool is_repl) {
     compiler_t *comp = m_new(compiler_t, 1);
 
     comp->qstr___class__ = qstr_from_str_static("__class__");
@@ -3146,7 +3148,19 @@ bool mp_compile(mp_parse_node_t pn, bool is_repl) {
         }
     }
 
+    bool had_error = comp->had_error;
     m_del_obj(compiler_t, comp);
 
-    return !comp->had_error;
+    if (had_error) {
+        // TODO return a proper error message
+        return mp_const_none;
+    } else {
+#if MICROPY_EMIT_CPYTHON
+        // can't create code, so just return true
+        return mp_const_true;
+#else
+        // return function that executes the outer module
+        return rt_make_function_from_id(1);
+#endif
+    }
 }
diff --git a/py/compile.h b/py/compile.h
index e283442bb066d465ead0c6bc4a410c58f6b47e71..770c2524dae39f40a23c6038ffc6901d3cfe8ae2 100644
--- a/py/compile.h
+++ b/py/compile.h
@@ -1 +1 @@
-bool mp_compile(mp_parse_node_t pn, bool is_repl);
+mp_obj_t mp_compile(mp_parse_node_t pn, bool is_repl);
diff --git a/py/emitbc.c b/py/emitbc.c
index 790fe3e4e5f14b15210014469658ea704e798e7f..dc1988582c49e9802e5a5f5e46b16e1bc4d19f12 100644
--- a/py/emitbc.c
+++ b/py/emitbc.c
@@ -9,7 +9,6 @@
 #include "mpconfig.h"
 #include "lexer.h"
 #include "parse.h"
-#include "compile.h"
 #include "scope.h"
 #include "runtime0.h"
 #include "emit.h"
diff --git a/py/emitcpy.c b/py/emitcpy.c
index b107c0bf1151305d18cdd6f733d4647eb25a0fd3..652617cc88c2bf30916246910fd4949b7c548a5e 100644
--- a/py/emitcpy.c
+++ b/py/emitcpy.c
@@ -9,7 +9,6 @@
 #include "mpconfig.h"
 #include "lexer.h"
 #include "parse.h"
-#include "compile.h"
 #include "scope.h"
 #include "runtime0.h"
 #include "emit.h"
diff --git a/py/emitpass1.c b/py/emitpass1.c
index 4ed05497273645cb8cdf29aafd151427a2650a39..1c11241e0dd536ad1a6d6e18136728ca45eb59cd 100644
--- a/py/emitpass1.c
+++ b/py/emitpass1.c
@@ -9,7 +9,6 @@
 #include "mpconfig.h"
 #include "lexer.h"
 #include "parse.h"
-#include "compile.h"
 #include "scope.h"
 #include "runtime0.h"
 #include "emit.h"
diff --git a/py/lexer.h b/py/lexer.h
index f58a38e92b7c0f88aab0947c5f85bf96cb642fa0..27244fde96b64712acd3f1a0fdf17749d0906817 100644
--- a/py/lexer.h
+++ b/py/lexer.h
@@ -138,3 +138,6 @@ bool mp_lexer_opt_str(mp_lexer_t *lex, const char *str);
 */
 bool mp_lexer_show_error(mp_lexer_t *lex, const char *msg);
 bool mp_lexer_show_error_pythonic(mp_lexer_t *lex, const char *msg);
+
+// used to import a module; must be implemented for a specific port
+mp_lexer_t *mp_import_open_file(qstr mod_name);
diff --git a/py/lexerunix.c b/py/lexerunix.c
index 398cb792a7ace443dd3c712f0475fc12e35920dd..14c28c16d92d2302901916db50520e810e8b1402 100644
--- a/py/lexerunix.c
+++ b/py/lexerunix.c
@@ -58,3 +58,23 @@ mp_lexer_t *mp_lexer_new_from_file(const char *filename) {
 
     return mp_lexer_new_from_str_len(filename, data, size, true);
 }
+
+/******************************************************************************/
+/* unix implementation of import                                              */
+
+// TODO properly!
+
+static const char *import_base_dir = NULL;
+
+void mp_import_set_directory(const char *dir) {
+    import_base_dir = dir;
+}
+
+mp_lexer_t *mp_import_open_file(qstr mod_name) {
+    vstr_t *vstr = vstr_new();
+    if (import_base_dir != NULL) {
+        vstr_printf(vstr, "%s/", import_base_dir);
+    }
+    vstr_printf(vstr, "%s.py", qstr_str(mod_name));
+    return mp_lexer_new_from_file(vstr_str(vstr)); // TODO does lexer need to copy the string? can we free it here?
+}
diff --git a/py/lexerunix.h b/py/lexerunix.h
index d86f202d53b4a8cc350c3f2b24b6c67929412bc9..b422a43062d682e72209af6fc6d85411912d4313 100644
--- a/py/lexerunix.h
+++ b/py/lexerunix.h
@@ -1,2 +1,4 @@
 mp_lexer_t *mp_lexer_new_from_str_len(const char *src_name, const char *str, uint len, bool free_str);
 mp_lexer_t *mp_lexer_new_from_file(const char *filename);
+
+void mp_import_set_directory(const char *dir);
diff --git a/py/malloc.c b/py/malloc.c
index c65d38a9687c43d96e76a0ddb85b176f4fafe991..4f01dc63f5208ccba6678b90fbf5f6a9999b4367 100644
--- a/py/malloc.c
+++ b/py/malloc.c
@@ -2,8 +2,15 @@
 #include <stdlib.h>
 
 #include "misc.h"
+#include "mpconfig.h"
 
+#if MICROPY_MEM_STATS
 static int total_bytes_allocated = 0;
+static int current_bytes_allocated = 0;
+static int peak_bytes_allocated = 0;
+
+#define UPDATE_PEAK() { if (current_bytes_allocated > peak_bytes_allocated) peak_bytes_allocated = current_bytes_allocated; }
+#endif
 
 void *m_malloc(int num_bytes) {
     if (num_bytes == 0) {
@@ -14,7 +21,11 @@ void *m_malloc(int num_bytes) {
         printf("could not allocate memory, allocating %d bytes\n", num_bytes);
         return NULL;
     }
+#if MICROPY_MEM_STATS
     total_bytes_allocated += num_bytes;
+    current_bytes_allocated += num_bytes;
+    UPDATE_PEAK();
+#endif
     return ptr;
 }
 
@@ -27,7 +38,11 @@ void *m_malloc0(int num_bytes) {
         printf("could not allocate memory, allocating %d bytes\n", num_bytes);
         return NULL;
     }
+#if MICROPY_MEM_STATS
     total_bytes_allocated += num_bytes;
+    current_bytes_allocated += num_bytes;
+    UPDATE_PEAK();
+#endif
     return ptr;
 }
 
@@ -41,7 +56,17 @@ void *m_realloc(void *ptr, int old_num_bytes, int new_num_bytes) {
         printf("could not allocate memory, reallocating %d bytes\n", new_num_bytes);
         return NULL;
     }
-    total_bytes_allocated += new_num_bytes;
+#if MICROPY_MEM_STATS
+    // At first thought, "Total bytes allocated" should only grow,
+    // after all, it's *total*. But consider for example 2K block
+    // shrunk to 1K and then grown to 2K again. It's still 2K
+    // allocated total. If we process only positive increments,
+    // we'll count 3K.
+    int diff = new_num_bytes - old_num_bytes;
+    total_bytes_allocated += diff;
+    current_bytes_allocated += diff;
+    UPDATE_PEAK();
+#endif
     return ptr;
 }
 
@@ -49,8 +74,31 @@ void m_free(void *ptr, int num_bytes) {
     if (ptr != NULL) {
         free(ptr);
     }
+#if MICROPY_MEM_STATS
+    current_bytes_allocated -= num_bytes;
+#endif
 }
 
 int m_get_total_bytes_allocated(void) {
+#if MICROPY_MEM_STATS
     return total_bytes_allocated;
+#else
+    return -1;
+#endif
+}
+
+int m_get_current_bytes_allocated(void) {
+#if MICROPY_MEM_STATS
+    return current_bytes_allocated;
+#else
+    return -1;
+#endif
+}
+
+int m_get_peak_bytes_allocated(void) {
+#if MICROPY_MEM_STATS
+    return peak_bytes_allocated;
+#else
+    return -1;
+#endif
 }
diff --git a/py/map.h b/py/map.h
index 8ee8429b5271ff4bf3584b8696f5682a580f110c..f8ca886aa49a8fbff56ac8c8fcb1fec6bd064857 100644
--- a/py/map.h
+++ b/py/map.h
@@ -23,10 +23,6 @@ typedef struct _mp_set_t {
     mp_obj_t *table;
 } mp_set_t;
 
-// these are defined in runtime.c
-mp_map_t *rt_get_map_locals(void);
-void rt_set_map_locals(mp_map_t *m);
-
 int get_doubling_prime_greater_or_equal_to(int x);
 void mp_map_init(mp_map_t *map, mp_map_kind_t kind, int n);
 mp_map_t *mp_map_new(mp_map_kind_t kind, int n);
diff --git a/py/misc.h b/py/misc.h
index 9f83ab526f0cb30022c9e6676f6af97506831329..153218ba2f8b6abf03eea3bb2b82d1d1a121cc1c 100644
--- a/py/misc.h
+++ b/py/misc.h
@@ -32,6 +32,8 @@ void *m_realloc(void *ptr, int old_num_bytes, int new_num_bytes);
 void m_free(void *ptr, int num_bytes);
 
 int m_get_total_bytes_allocated(void);
+int m_get_current_bytes_allocated(void);
+int m_get_peak_bytes_allocated(void);
 
 /** unichar / UTF-8 *********************************************/
 
diff --git a/py/mpconfig.h b/py/mpconfig.h
new file mode 100644
index 0000000000000000000000000000000000000000..17c5a770c4967af083a5479cfece9d5c064653c4
--- /dev/null
+++ b/py/mpconfig.h
@@ -0,0 +1,13 @@
+// This file contains default configuration settings for MicroPython.
+// You can override any of these options using mpconfigport.h file located
+// in a directory of your port.
+
+#include <mpconfigport.h>
+
+// Any options not explicitly set in mpconfigport.h will get default
+// values below.
+
+// Whether to collect memory allocation stats
+#ifndef MICROPY_MEM_STATS
+#define MICROPY_MEM_STATS (1)
+#endif
diff --git a/py/obj.h b/py/obj.h
index 6a0cefd915aef777289ec4123af27995d18720db..7b4b0656f2f8ce94d9c35ca73cab0eae50abfb46 100644
--- a/py/obj.h
+++ b/py/obj.h
@@ -215,11 +215,14 @@ mp_obj_t mp_obj_dict_store(mp_obj_t self_in, mp_obj_t key, mp_obj_t value);
 void mp_obj_set_store(mp_obj_t self_in, mp_obj_t item);
 
 // functions
-typedef struct _mp_obj_fun_native_t { // need this so we can define static objects
+typedef struct _mp_obj_fun_native_t { // need this so we can define const objects (to go in ROM)
     mp_obj_base_t base;
     machine_uint_t n_args_min; // inclusive
     machine_uint_t n_args_max; // inclusive
     void *fun;
+    // TODO add mp_map_t *globals
+    // for const function objects, make an empty, const map
+    // such functions won't be able to access the global scope, but that's probably okay
 } mp_obj_fun_native_t;
 extern const mp_obj_type_t fun_native_type;
 extern const mp_obj_type_t fun_bc_type;
diff --git a/py/objfun.c b/py/objfun.c
index cefc9a95fe36888e4164dd4d3b36e523c51ac936..e998bd28d261d39610c853ec51cc3c2e2ce3969d 100644
--- a/py/objfun.c
+++ b/py/objfun.c
@@ -7,6 +7,7 @@
 #include "misc.h"
 #include "mpconfig.h"
 #include "obj.h"
+#include "map.h"
 #include "runtime.h"
 #include "bc.h"
 
@@ -129,9 +130,10 @@ mp_obj_t rt_make_function_var_between(int n_args_min, int n_args_max, mp_fun_var
 
 typedef struct _mp_obj_fun_bc_t {
     mp_obj_base_t base;
-    int n_args;
-    uint n_state;
-    const byte *code;
+    mp_map_t *globals;      // the context within which this function was defined
+    int n_args;             // number of arguments this function takes
+    uint n_state;           // total state size for the executing function (incl args, locals, stack)
+    const byte *bytecode;   // bytecode for the function
 } mp_obj_fun_bc_t;
 
 // args are in reverse order in the array
@@ -142,15 +144,17 @@ mp_obj_t fun_bc_call_n(mp_obj_t self_in, int n_args, const mp_obj_t *args) {
         nlr_jump(mp_obj_new_exception_msg_2_args(rt_q_TypeError, "function takes %d positional arguments but %d were given", (const char*)(machine_int_t)self->n_args, (const char*)(machine_int_t)n_args));
     }
 
-    return mp_execute_byte_code(self->code, args, n_args, self->n_state);
-}
-
-void mp_obj_fun_bc_get(mp_obj_t self_in, int *n_args, uint *n_state, const byte **code) {
-    assert(MP_OBJ_IS_TYPE(self_in, &fun_bc_type));
-    mp_obj_fun_bc_t *self = self_in;
-    *n_args = self->n_args;
-    *n_state = self->n_state;
-    *code = self->code;
+    // optimisation: allow the compiler to optimise this tail call for
+    // the common case when the globals don't need to be changed
+    mp_map_t *old_globals = rt_globals_get();
+    if (self->globals == old_globals) {
+        return mp_execute_byte_code(self->bytecode, args, n_args, self->n_state);
+    } else {
+        rt_globals_set(self->globals);
+        mp_obj_t result = mp_execute_byte_code(self->bytecode, args, n_args, self->n_state);
+        rt_globals_set(old_globals);
+        return result;
+    }
 }
 
 const mp_obj_type_t fun_bc_type = {
@@ -170,12 +174,21 @@ const mp_obj_type_t fun_bc_type = {
 mp_obj_t mp_obj_new_fun_bc(int n_args, uint n_state, const byte *code) {
     mp_obj_fun_bc_t *o = m_new_obj(mp_obj_fun_bc_t);
     o->base.type = &fun_bc_type;
+    o->globals = rt_globals_get();
     o->n_args = n_args;
     o->n_state = n_state;
-    o->code = code;
+    o->bytecode = code;
     return o;
 }
 
+void mp_obj_fun_bc_get(mp_obj_t self_in, int *n_args, uint *n_state, const byte **code) {
+    assert(MP_OBJ_IS_TYPE(self_in, &fun_bc_type));
+    mp_obj_fun_bc_t *self = self_in;
+    *n_args = self->n_args;
+    *n_state = self->n_state;
+    *code = self->bytecode;
+}
+
 /******************************************************************************/
 /* inline assembler functions                                                 */
 
diff --git a/py/runtime.c b/py/runtime.c
index 3fae61f6fe91d64432fb29159f141f1cfe848e30..3144321f3a4cb55db25d5bbc0bb4c86f13830d08 100644
--- a/py/runtime.c
+++ b/py/runtime.c
@@ -281,14 +281,6 @@ void rt_assign_inline_asm_code(int unique_code_id, void *fun, uint len, int n_ar
 #endif
 }
 
-mp_map_t *rt_get_map_locals(void) {
-    return map_locals;
-}
-
-void rt_set_map_locals(mp_map_t *m) {
-    map_locals = m;
-}
-
 static bool fit_small_int(mp_small_int_t o) {
     return true;
 }
@@ -479,6 +471,16 @@ mp_obj_t rt_unary_op(int op, mp_obj_t arg) {
 
 mp_obj_t rt_binary_op(int op, mp_obj_t lhs, mp_obj_t rhs) {
     DEBUG_OP_printf("binary %d %p %p\n", op, lhs, rhs);
+
+    // TODO correctly distinguish inplace operators for mutable objects
+    // lookup logic that CPython uses for +=:
+    //   check for implemented +=
+    //   then check for implemented +
+    //   then check for implemented seq.inplace_concat
+    //   then check for implemented seq.concat
+    //   then fail
+    // note that list does not implement + or +=, so that inplace_concat is reached first for +=
+
     if (MP_OBJ_IS_SMALL_INT(lhs) && MP_OBJ_IS_SMALL_INT(rhs)) {
         mp_small_int_t lhs_val = MP_OBJ_SMALL_INT_VALUE(lhs);
         mp_small_int_t rhs_val = MP_OBJ_SMALL_INT_VALUE(rhs);
@@ -786,6 +788,7 @@ mp_obj_t rt_load_attr(mp_obj_t base, qstr attr) {
     } else if (MP_OBJ_IS_TYPE(base, &instance_type)) {
         return mp_obj_instance_load_attr(base, attr);
     } else if (MP_OBJ_IS_TYPE(base, &module_type)) {
+        DEBUG_OP_printf("lookup module map %p\n", mp_obj_module_get_globals(base));
         mp_map_elem_t *elem = mp_qstr_map_lookup(mp_obj_module_get_globals(base), attr, false);
         if (elem == NULL) {
             // TODO what about generic method lookup?
@@ -913,6 +916,24 @@ mp_obj_t rt_import_from(mp_obj_t module, qstr name) {
     return x;
 }
 
+mp_map_t *rt_locals_get(void) {
+    return map_locals;
+}
+
+void rt_locals_set(mp_map_t *m) {
+    DEBUG_OP_printf("rt_locals_set(%p)\n", m);
+    map_locals = m;
+}
+
+mp_map_t *rt_globals_get(void) {
+    return map_globals;
+}
+
+void rt_globals_set(mp_map_t *m) {
+    DEBUG_OP_printf("rt_globals_set(%p)\n", m);
+    map_globals = m;
+}
+
 // these must correspond to the respective enum
 void *const rt_fun_table[RT_F_NUMBER_OF] = {
     rt_load_const_dec,
diff --git a/py/runtime.h b/py/runtime.h
index 37b036852fd49902192853731eaffa8cd3141039..cf9180275e449772303cdc0c193f8a636a04e716 100644
--- a/py/runtime.h
+++ b/py/runtime.h
@@ -57,3 +57,9 @@ mp_obj_t rt_getiter(mp_obj_t o);
 mp_obj_t rt_iternext(mp_obj_t o);
 mp_obj_t rt_import_name(qstr name, mp_obj_t fromlist, mp_obj_t level);
 mp_obj_t rt_import_from(mp_obj_t module, qstr name);
+
+struct _mp_map_t;
+struct _mp_map_t *rt_locals_get(void);
+void rt_locals_set(struct _mp_map_t *m);
+struct _mp_map_t *rt_globals_get(void);
+void rt_globals_set(struct _mp_map_t *m);
diff --git a/py/showbc.c b/py/showbc.c
index 15cd0564270a681041136f37d39f51018ad8cee2..a3bfa2833b191ae9efa0c10191166489e90ae2c9 100644
--- a/py/showbc.c
+++ b/py/showbc.c
@@ -142,12 +142,10 @@ void mp_show_byte_code(const byte *ip, int len) {
                 printf("STORE_NAME %s", qstr_str(qstr));
                 break;
 
-                /*
             case MP_BC_STORE_GLOBAL:
                 DECODE_QSTR;
-                rt_store_global(qstr, POP());
+                printf("STORE_GLOBAL %s", qstr_str(qstr));
                 break;
-                */
 
             case MP_BC_STORE_ATTR:
                 DECODE_QSTR;
@@ -343,6 +341,16 @@ void mp_show_byte_code(const byte *ip, int len) {
                 printf("YIELD_VALUE");
                 break;
 
+            case MP_BC_IMPORT_NAME:
+                DECODE_QSTR;
+                printf("IMPORT NAME %s", qstr_str(qstr));
+                break;
+
+            case MP_BC_IMPORT_FROM:
+                DECODE_QSTR;
+                printf("IMPORT NAME %s", qstr_str(qstr));
+                break;
+
             default:
                 printf("code %p, byte code 0x%02x not implemented\n", ip, op);
                 assert(0);
diff --git a/py/vstr.c b/py/vstr.c
index 98cf0272505f516e6e654cdbfab15b92b62dd45a..80841b24cae972bb666048c09cdbe36d1233b198 100644
--- a/py/vstr.c
+++ b/py/vstr.c
@@ -167,8 +167,12 @@ void vstr_vprintf(vstr_t *vstr, const char *fmt, va_list ap) {
 
     while (1) {
         // try to print in the allocated space
+        // need to make a copy of the va_list because we may call vsnprintf multiple times
         int size = vstr->alloc - vstr->len;
-        int n = vsnprintf(vstr->buf + vstr->len, size, fmt, ap);
+        va_list ap2;
+        va_copy(ap2, ap);
+        int n = vsnprintf(vstr->buf + vstr->len, size, fmt, ap2);
+        va_end(ap2);
 
         // if that worked, return
         if (n > -1 && n < size) {
diff --git a/stm/Makefile b/stm/Makefile
index 6868f85ba7d66c23093b65bcb7a426c9e2b0c28f..d6c77e2bd7258b5f1317ca48998463c3b42ced8c 100644
--- a/stm/Makefile
+++ b/stm/Makefile
@@ -82,6 +82,7 @@ PY_O = \
 	objtuple.o \
 	objtype.o \
 	builtin.o \
+	builtinimport.o \
 	vm.o \
 	repl.o \
 
@@ -147,7 +148,7 @@ OBJ = $(addprefix $(BUILD)/, $(SRC_C:.c=.o) $(SRC_S:.s=.o) $(PY_O) $(SRC_FATFS:.
 all: $(BUILD) $(BUILD)/flash.dfu
 
 $(BUILD)/flash.dfu: $(BUILD)/flash0.bin $(BUILD)/flash1.bin
-	python2 $(DFU) -b 0x08000000:$(BUILD)/flash0.bin -b 0x08020000:$(BUILD)/flash1.bin $@
+	python $(DFU) -b 0x08000000:$(BUILD)/flash0.bin -b 0x08020000:$(BUILD)/flash1.bin $@
 
 $(BUILD)/flash0.bin: $(BUILD)/flash.elf
 	arm-none-eabi-objcopy -O binary -j .isr_vector $^ $@
@@ -186,7 +187,7 @@ $(BUILD)/%.o: $(PYSRC)/%.s
 $(BUILD)/%.o: $(PYSRC)/%.S
 	$(CC) $(CFLAGS) -c -o $@ $<
 
-$(BUILD)/%.o: $(PYSRC)/%.c mpconfig.h
+$(BUILD)/%.o: $(PYSRC)/%.c mpconfigport.h
 	$(CC) $(CFLAGS) -c -o $@ $<
 
 $(BUILD)/emitnthumb.o: $(PYSRC)/emitnative.c $(PYSRC)/emit.h
diff --git a/stm/audio.c b/stm/audio.c
index 38e0012b41222e4b8ee4902bd561fe41e5861318..34adefbcd6e02717e2b8cff8693f9016bd5f259d 100644
--- a/stm/audio.c
+++ b/stm/audio.c
@@ -8,7 +8,6 @@
 #include "misc.h"
 #include "mpconfig.h"
 #include "parse.h"
-#include "compile.h"
 #include "obj.h"
 #include "runtime.h"
 
diff --git a/stm/lcd.c b/stm/lcd.c
index 9f5a157d05a8fef7e17403f9d0f903e73be95ad9..70d1a26423e3acebf3de44559731d9dc460a218b 100644
--- a/stm/lcd.c
+++ b/stm/lcd.c
@@ -5,7 +5,6 @@
 #include "misc.h"
 #include "mpconfig.h"
 #include "parse.h"
-#include "compile.h"
 #include "obj.h"
 #include "runtime.h"
 
diff --git a/stm/lexerstm.c b/stm/lexerstm.c
index dfb84cca137370f452ca8260345cba7f23129d69..661dfb016032d08562ec4eb6758998ee9d9a700a 100644
--- a/stm/lexerstm.c
+++ b/stm/lexerstm.c
@@ -61,3 +61,8 @@ mp_lexer_t *mp_lexer_new_from_file(const char *filename, mp_lexer_file_buf_t *fb
     fb->pos = 0;
     return mp_lexer_new(filename, fb, (mp_lexer_stream_next_char_t)file_buf_next_char, (mp_lexer_stream_close_t)file_buf_close);
 }
+
+mp_lexer_t *mp_import_open_file(qstr mod_name) {
+    printf("import not implemented\n");
+    return NULL;
+}
diff --git a/stm/main.c b/stm/main.c
index f16ce252d2e1ff6e47e3abadbc3a01196caafafb..e8db2be2ca4d364098f54080d5ecf4b24329eb30 100644
--- a/stm/main.c
+++ b/stm/main.c
@@ -20,8 +20,8 @@
 #include "lexer.h"
 #include "lexerstm.h"
 #include "parse.h"
-#include "compile.h"
 #include "obj.h"
+#include "compile.h"
 #include "runtime0.h"
 #include "runtime.h"
 #include "repl.h"
@@ -489,25 +489,22 @@ void do_repl(void) {
         mp_lexer_free(lex);
 
         if (pn != MP_PARSE_NODE_NULL) {
-            bool comp_ok = mp_compile(pn, true);
-            if (comp_ok) {
-                mp_obj_t module_fun = rt_make_function_from_id(1);
-                if (module_fun != mp_const_none) {
-                    nlr_buf_t nlr;
-                    uint32_t start = sys_tick_counter;
-                    if (nlr_push(&nlr) == 0) {
-                        rt_call_function_0(module_fun);
-                        nlr_pop();
-                        // optional timing
-                        if (0) {
-                            uint32_t ticks = sys_tick_counter - start; // TODO implement a function that does this properly
-                            printf("(took %lu ms)\n", ticks);
-                        }
-                    } else {
-                        // uncaught exception
-                        mp_obj_print((mp_obj_t)nlr.ret_val);
-                        printf("\n");
+            mp_obj_t module_fun = mp_compile(pn, true);
+            if (module_fun != mp_const_none) {
+                nlr_buf_t nlr;
+                uint32_t start = sys_tick_counter;
+                if (nlr_push(&nlr) == 0) {
+                    rt_call_function_0(module_fun);
+                    nlr_pop();
+                    // optional timing
+                    if (0) {
+                        uint32_t ticks = sys_tick_counter - start; // TODO implement a function that does this properly
+                        printf("(took %lu ms)\n", ticks);
                     }
+                } else {
+                    // uncaught exception
+                    mp_obj_print((mp_obj_t)nlr.ret_val);
+                    printf("\n");
                 }
             }
         }
@@ -532,12 +529,7 @@ bool do_file(const char *filename) {
         return false;
     }
 
-    bool comp_ok = mp_compile(pn, false);
-    if (!comp_ok) {
-        return false;
-    }
-
-    mp_obj_t module_fun = rt_make_function_from_id(1);
+    mp_obj_t module_fun = mp_compile(pn, false);
     if (module_fun == mp_const_none) {
         return false;
     }
@@ -1133,17 +1125,15 @@ soft_reset:
             printf("pars;al=%u\n", m_get_total_bytes_allocated());
             sys_tick_delay_ms(1000);
             //parse_node_show(pn, 0);
-            bool comp_ok = mp_compile(pn, false);
+            mp_obj_t module_fun = mp_compile(pn, false);
             printf("comp;al=%u\n", m_get_total_bytes_allocated());
             sys_tick_delay_ms(1000);
 
-            if (!comp_ok) {
+            if (module_fun == mp_const_none) {
                 printf("compile error\n");
             } else {
                 // execute it!
 
-                mp_obj_t module_fun = rt_make_function_from_id(1);
-
                 // flash once
                 led_state(PYB_LED_G1, 1);
                 sys_tick_delay_ms(100);
diff --git a/stm/mpconfig.h b/stm/mpconfigport.h
similarity index 96%
rename from stm/mpconfig.h
rename to stm/mpconfigport.h
index 1f9529e11ba8df1afdb692e129061534878b9870..4cea332f3977f5c3206d5ee85523c5e8a08684e8 100644
--- a/stm/mpconfig.h
+++ b/stm/mpconfigport.h
@@ -1,3 +1,5 @@
+#include <stdint.h>
+
 // options to control how Micro Python is built
 
 #define MICROPY_ENABLE_FLOAT        (1)
diff --git a/stm/pybwlan.c b/stm/pybwlan.c
index 6341d0676b63b161f6e5b74011b3c164e2084903..6988f1c848167f742acdd329a1fb988ee25891a8 100644
--- a/stm/pybwlan.c
+++ b/stm/pybwlan.c
@@ -18,7 +18,6 @@
 #include "misc.h"
 #include "lexer.h"
 #include "parse.h"
-#include "compile.h"
 #include "obj.h"
 #include "map.h"
 #include "runtime.h"
diff --git a/stm/timer.c b/stm/timer.c
index 28148b0c1b91f44c1c786e613147a9fbaf086b24..2605d4b4bcc9dcd636102dba6508d7eb71a47046 100644
--- a/stm/timer.c
+++ b/stm/timer.c
@@ -9,7 +9,6 @@
 #include "misc.h"
 #include "mpconfig.h"
 #include "parse.h"
-#include "compile.h"
 #include "obj.h"
 #include "runtime.h"
 
diff --git a/tests/basics/run-tests b/tests/basics/run-tests
index 1b027c3e9ffadb943680b90c0ec4134b03abbeeb..72e69c2d8eff1cddfab9d83ebb76c8d91677140f 100755
--- a/tests/basics/run-tests
+++ b/tests/basics/run-tests
@@ -11,7 +11,7 @@ namefailed=
 
 for infile in tests/*.py
 do
-    basename=`basename $infile .c`
+    basename=`basename $infile .py`
     outfile=${basename}.out
     expfile=${basename}.exp
 
diff --git a/tests/basics/tests/import1a.py b/tests/basics/tests/import1a.py
new file mode 100644
index 0000000000000000000000000000000000000000..16b2d4d30f61c9170727a9a6d64969f01960a4a1
--- /dev/null
+++ b/tests/basics/tests/import1a.py
@@ -0,0 +1,2 @@
+import import1b
+print(import1b.var)
diff --git a/tests/basics/tests/import1b.py b/tests/basics/tests/import1b.py
new file mode 100644
index 0000000000000000000000000000000000000000..80479088f0ee45b3b79a74e04e3e6fcf8eaabfad
--- /dev/null
+++ b/tests/basics/tests/import1b.py
@@ -0,0 +1 @@
+var = 123
diff --git a/tools/dfu.py b/tools/dfu.py
index 875cc5c6e9114cbc4fbf47125cec84ba848e93d1..54b602438b38119c87e8a3a834faf174c6e56efa 100755
--- a/tools/dfu.py
+++ b/tools/dfu.py
@@ -20,11 +20,11 @@ def compute_crc(data):
   return 0xFFFFFFFF & -zlib.crc32(data) -1
 
 def parse(file,dump_images=False):
-  print 'File: "%s"' % file
+  print ('File: "%s"' % file)
   data = open(file,'rb').read()
   crc = compute_crc(data[:-4])
   prefix, data = consume('<5sBIB',data,'signature version size targets')
-  print '%(signature)s v%(version)d, image size: %(size)d, targets: %(targets)d' % prefix
+  print ('%(signature)s v%(version)d, image size: %(size)d, targets: %(targets)d' % prefix)
   for t in range(prefix['targets']):
     tprefix, data  = consume('<6sBI255s2I',data,'signature altsetting named name size elements')
     tprefix['num'] = t
@@ -32,40 +32,40 @@ def parse(file,dump_images=False):
       tprefix['name'] = cstring(tprefix['name'])
     else:
       tprefix['name'] = ''
-    print '%(signature)s %(num)d, alt setting: %(altsetting)s, name: "%(name)s", size: %(size)d, elements: %(elements)d' % tprefix
+    print ('%(signature)s %(num)d, alt setting: %(altsetting)s, name: "%(name)s", size: %(size)d, elements: %(elements)d' % tprefix)
     tsize = tprefix['size']
     target, data = data[:tsize], data[tsize:]
     for e in range(tprefix['elements']):
       eprefix, target = consume('<2I',target,'address size')
       eprefix['num'] = e
-      print '  %(num)d, address: 0x%(address)08x, size: %(size)d' % eprefix
+      print ('  %(num)d, address: 0x%(address)08x, size: %(size)d' % eprefix)
       esize = eprefix['size']
       image, target = target[:esize], target[esize:]
       if dump_images:
         out = '%s.target%d.image%d.bin' % (file,t,e)
         open(out,'wb').write(image)
-        print '    DUMPED IMAGE TO "%s"' % out
+        print ('    DUMPED IMAGE TO "%s"' % out)
     if len(target):
-      print "target %d: PARSE ERROR" % t
+      print ("target %d: PARSE ERROR" % t)
   suffix = named(struct.unpack('<4H3sBI',data[:16]),'device product vendor dfu ufd len crc')
-  print 'usb: %(vendor)04x:%(product)04x, device: 0x%(device)04x, dfu: 0x%(dfu)04x, %(ufd)s, %(len)d, 0x%(crc)08x' % suffix
+  print ('usb: %(vendor)04x:%(product)04x, device: 0x%(device)04x, dfu: 0x%(dfu)04x, %(ufd)s, %(len)d, 0x%(crc)08x' % suffix)
   if crc != suffix['crc']:
-    print "CRC ERROR: computed crc32 is 0x%08x" % crc
+    print ("CRC ERROR: computed crc32 is 0x%08x" % crc)
   data = data[16:]
   if data:
-    print "PARSE ERROR"
+    print ("PARSE ERROR")
 
 def build(file,targets,device=DEFAULT_DEVICE):
-  data = ''
+  data = b''
   for t,target in enumerate(targets):
-    tdata = ''
+    tdata = b''
     for image in target:
       tdata += struct.pack('<2I',image['address'],len(image['data']))+image['data']
-    tdata = struct.pack('<6sBI255s2I','Target',0,1,'ST...',len(tdata),len(target)) + tdata
+    tdata = struct.pack('<6sBI255s2I',b'Target',0,1, b'ST...',len(tdata),len(target)) + tdata
     data += tdata
-  data  = struct.pack('<5sBIB','DfuSe',1,len(data)+11,len(targets)) + data
+  data  = struct.pack('<5sBIB',b'DfuSe',1,len(data)+11,len(targets)) + data
   v,d=map(lambda x: int(x,0) & 0xFFFF, device.split(':',1))
-  data += struct.pack('<4H3sB',0,d,v,0x011a,'UFD',16)
+  data += struct.pack('<4H3sB',0,d,v,0x011a,b'UFD',16)
   crc   = compute_crc(data)
   data += struct.pack('<I',crc)
   open(file,'wb').write(data)
@@ -89,15 +89,15 @@ if __name__=="__main__":
       try:
         address,binfile = arg.split(':',1)
       except ValueError:
-        print "Address:file couple '%s' invalid." % arg
+        print ("Address:file couple '%s' invalid." % arg)
         sys.exit(1)
       try:
         address = int(address,0) & 0xFFFFFFFF
       except ValueError:
-        print "Address %s invalid." % address
+        print ("Address %s invalid." % address)
         sys.exit(1)
       if not os.path.isfile(binfile):
-        print "Unreadable file '%s'." % binfile
+        print ("Unreadable file '%s'." % binfile)
         sys.exit(1)
       target.append({ 'address': address, 'data': open(binfile,'rb').read() })
     outfile = args[0]
@@ -107,13 +107,13 @@ if __name__=="__main__":
     try:
       v,d=map(lambda x: int(x,0) & 0xFFFF, device.split(':',1))
     except:
-      print "Invalid device '%s'." % device
+      print ("Invalid device '%s'." % device)
       sys.exit(1)
     build(outfile,[target],device)
   elif len(args)==1:
     infile = args[0]
     if not os.path.isfile(infile):
-      print "Unreadable file '%s'." % infile
+      print ("Unreadable file '%s'." % infile)
       sys.exit(1)
     parse(infile, dump_images=options.dump_images)
   else:
diff --git a/unix-cpy/Makefile b/unix-cpy/Makefile
index 9399a765c3aa131ea2e7a213e8f9e8dffbd63408..48c31794600011cccbb833362fa36e2555b4fd59 100644
--- a/unix-cpy/Makefile
+++ b/unix-cpy/Makefile
@@ -47,6 +47,7 @@ PY_O = \
 	objtuple.o \
 	objtype.o \
 	builtin.o \
+	builtinimport.o \
 	vm.o \
 	showbc.o \
 	repl.o \
@@ -67,7 +68,7 @@ $(BUILD)/%.o: %.c
 $(BUILD)/%.o: $(PYSRC)/%.S
 	$(CC) $(CFLAGS) -c -o $@ $<
 
-$(BUILD)/%.o: $(PYSRC)/%.c mpconfig.h
+$(BUILD)/%.o: $(PYSRC)/%.c mpconfigport.h
 	$(CC) $(CFLAGS) -c -o $@ $<
 
 $(BUILD)/emitnx64.o: $(PYSRC)/emitnative.c $(PYSRC)/emit.h
@@ -80,7 +81,7 @@ $(BUILD)/emitnthumb.o: $(PYSRC)/emitnative.c $(PYSRC)/emit.h
 $(BUILD)/vm.o: $(PYSRC)/vm.c
 	$(CC) $(CFLAGS) -O3 -c -o $@ $<
 
-$(BUILD)/main.o: mpconfig.h
+$(BUILD)/main.o: mpconfigport.h
 $(BUILD)/parse.o: $(PYSRC)/grammar.h
 $(BUILD)/compile.o: $(PYSRC)/grammar.h
 $(BUILD)/emitcpy.o: $(PYSRC)/emit.h
diff --git a/unix-cpy/main.c b/unix-cpy/main.c
index 2b59df4f374e09966a55cfbb78c3a79f166aff7a..eba97f527ba1e85b33c344e9181345a1d50bfb7a 100644
--- a/unix-cpy/main.c
+++ b/unix-cpy/main.c
@@ -8,8 +8,8 @@
 #include "lexer.h"
 #include "lexerunix.h"
 #include "parse.h"
-#include "compile.h"
 #include "obj.h"
+#include "compile.h"
 #include "runtime0.h"
 #include "runtime.h"
 
@@ -37,10 +37,10 @@ void do_file(const char *file) {
             //printf("----------------\n");
             //parse_node_show(pn, 0);
             //printf("----------------\n");
-            bool comp_ok = mp_compile(pn, false);
+            mp_obj_t module_fun = mp_compile(pn, false);
             //printf("----------------\n");
 
-            if (!comp_ok) {
+            if (module_fun == mp_const_none) {
                 printf("compile error\n");
             }
         }
diff --git a/unix-cpy/mpconfig.h b/unix-cpy/mpconfigport.h
similarity index 100%
rename from unix-cpy/mpconfig.h
rename to unix-cpy/mpconfigport.h
diff --git a/unix/Makefile b/unix/Makefile
index b8955d11a834e3cfa172acd4d8555edfd65b77c8..fd5b6b43e0fc0928f7eb5be508e7fbaaa3fedcbb 100644
--- a/unix/Makefile
+++ b/unix/Makefile
@@ -54,6 +54,7 @@ PY_O = \
 	objtuple.o \
 	objtype.o \
 	builtin.o \
+	builtinimport.o \
 	vm.o \
 	showbc.o \
 	repl.o \
@@ -78,7 +79,7 @@ $(BUILD)/%.o: %.c
 $(BUILD)/%.o: $(PYSRC)/%.S
 	$(CC) $(CFLAGS) -c -o $@ $<
 
-$(BUILD)/%.o: $(PYSRC)/%.c mpconfig.h
+$(BUILD)/%.o: $(PYSRC)/%.c mpconfigport.h
 	$(CC) $(CFLAGS) -c -o $@ $<
 
 $(BUILD)/emitnx64.o: $(PYSRC)/emitnative.c $(PYSRC)/emit.h
@@ -91,7 +92,7 @@ $(BUILD)/emitnthumb.o: $(PYSRC)/emitnative.c $(PYSRC)/emit.h
 $(BUILD)/vm.o: $(PYSRC)/vm.c
 	$(CC) $(CFLAGS) -O3 -c -o $@ $<
 
-$(BUILD)/main.o: mpconfig.h
+$(BUILD)/main.o: mpconfigport.h
 $(BUILD)/parse.o: $(PYSRC)/grammar.h
 $(BUILD)/compile.o: $(PYSRC)/grammar.h
 $(BUILD)/emitcpy.o: $(PYSRC)/emit.h
diff --git a/unix/main.c b/unix/main.c
index 376dbc0c045d3ab21d0ed93a9e4f52a37053d178..1aa3331202893ad5c69ed6c3eda25c7a026617ab 100644
--- a/unix/main.c
+++ b/unix/main.c
@@ -9,8 +9,8 @@
 #include "lexer.h"
 #include "lexerunix.h"
 #include "parse.h"
-#include "compile.h"
 #include "obj.h"
+#include "compile.h"
 #include "runtime0.h"
 #include "runtime.h"
 #include "repl.h"
@@ -85,19 +85,16 @@ static void do_repl(void) {
 
         if (pn != MP_PARSE_NODE_NULL) {
             //mp_parse_node_show(pn, 0);
-            bool comp_ok = mp_compile(pn, true);
-            if (comp_ok) {
-                mp_obj_t module_fun = rt_make_function_from_id(1);
-                if (module_fun != mp_const_none) {
-                    nlr_buf_t nlr;
-                    if (nlr_push(&nlr) == 0) {
-                        rt_call_function_0(module_fun);
-                        nlr_pop();
-                    } else {
-                        // uncaught exception
-                        mp_obj_print((mp_obj_t)nlr.ret_val);
-                        printf("\n");
-                    }
+            mp_obj_t module_fun = mp_compile(pn, true);
+            if (module_fun != mp_const_none) {
+                nlr_buf_t nlr;
+                if (nlr_push(&nlr) == 0) {
+                    rt_call_function_0(module_fun);
+                    nlr_pop();
+                } else {
+                    // uncaught exception
+                    mp_obj_print((mp_obj_t)nlr.ret_val);
+                    printf("\n");
                 }
             }
         }
@@ -105,6 +102,18 @@ static void do_repl(void) {
 }
 
 void do_file(const char *file) {
+    // hack: set dir for import based on where this file is
+    {
+        const char * s = strrchr(file, '/');
+        if (s != NULL) {
+            int len = s - file;
+            char *dir = m_new(char, len + 1);
+            memcpy(dir, file, len);
+            dir[len] = '\0';
+            mp_import_set_directory(dir);
+        }
+    }
+
     mp_lexer_t *lex = mp_lexer_new_from_file(file);
     //const char *pysrc = "def f():\n  x=x+1\n  print(42)\n";
     //mp_lexer_t *lex = mp_lexer_from_str_len("<>", pysrc, strlen(pysrc), false);
@@ -130,7 +139,7 @@ void do_file(const char *file) {
             //printf("----------------\n");
             //parse_node_show(pn, 0);
             //printf("----------------\n");
-            bool comp_ok = mp_compile(pn, false);
+            mp_obj_t module_fun = mp_compile(pn, false);
             //printf("----------------\n");
 
 #if MICROPY_EMIT_CPYTHON
@@ -138,19 +147,16 @@ void do_file(const char *file) {
                 printf("compile error\n");
             }
 #else
-            if (1 && comp_ok) {
+            if (1 && module_fun != mp_const_none) {
                 // execute it
-                mp_obj_t module_fun = rt_make_function_from_id(1);
-                if (module_fun != mp_const_none) {
-                    nlr_buf_t nlr;
-                    if (nlr_push(&nlr) == 0) {
-                        rt_call_function_0(module_fun);
-                        nlr_pop();
-                    } else {
-                        // uncaught exception
-                        mp_obj_print((mp_obj_t)nlr.ret_val);
-                        printf("\n");
-                    }
+                nlr_buf_t nlr;
+                if (nlr_push(&nlr) == 0) {
+                    rt_call_function_0(module_fun);
+                    nlr_pop();
+                } else {
+                    // uncaught exception
+                    mp_obj_print((mp_obj_t)nlr.ret_val);
+                    printf("\n");
                 }
             }
 #endif
diff --git a/unix/mpconfig.h b/unix/mpconfigport.h
similarity index 100%
rename from unix/mpconfig.h
rename to unix/mpconfigport.h