diff --git a/python/pcb.py b/python/pcb.py
index 666eefdb2393a9c51405cc67f3a1d3f981e2ae17..94e10920e303f391fcd6ce4d619009f559c036b8 100755
--- a/python/pcb.py
+++ b/python/pcb.py
@@ -6,8 +6,7 @@
 # usage:
 #    pcb.py | frep.py [dpi [filename]]
 #
-# Neil Gershenfeld 12/1/19
-# (c) Massachusetts Institute of Technology 2019
+# Neil Gershenfeld 1/5/21
 #
 # This work may be reproduced, modified, distributed,
 # performed, and displayed for any purpose, but must
@@ -16,14 +15,14 @@
 # warranty is provided, and users accept all liability.
 #
 
-#
-# uncomment for desired output:
-#
+############################################################
+# uncomment for desired output
+############################################################
 
-#output = "top, labels, and exterior"
+output = "top, labels, and exterior"
 #output = "top, labels, holes, and exterior"
 #output = "top, bottom, labels, and exterior"
-output = "top, bottom, labels, holes, and exterior"
+#output = "top, bottom, labels, holes, and exterior"
 #output = "top traces"
 #output = "top traces and exterior"
 #output = "bottom traces reversed"
@@ -34,15 +33,15 @@ output = "top, bottom, labels, holes, and exterior"
 #output = "exterior"
 #output = "solder mask"
 
-#
+############################################################
 # import
-#
+############################################################
 
 import math,json,sys
 
-#
+############################################################
 # define shapes and transformations
-#
+############################################################
 
 # color(color,part)
 # circle(x,y,r)
@@ -461,9 +460,9 @@ def coshear_x_z(part,z0,z1,angle0,angle1,amplitude,offset):
    part = part.replace('offset',str(offset))
    return part
 
-#
+############################################################
 # text classes and definitions
-#
+############################################################
 
 class text:
    #
@@ -947,9 +946,9 @@ class text:
       #
       self.shape = '('+str(color)+'*(('+self.shape+')!=0))'
 
-#
+############################################################
 # PCB classes and definitions
-#
+############################################################
 
 class PCB:
    def __init__(self,x0,y0,width,height,mask):
@@ -1078,9 +1077,9 @@ def wirer(pcb,width,*points):
          pcb.board = add(pcb.board,cube(x1-width/2,x1+width/2,y1-width/2,y0+width/2,z0,z0))
    return pcb
 
-#
+############################################################
 # PCB library
-#
+############################################################
 
 class via(part):
    #
@@ -1109,9 +1108,9 @@ class SJ(part):
       self.shape = add(self.shape,translate(pad_SJ,.029,0,0))
       self.pad.append(point(.029,0,0))
 
-#
+############################################################
 # discretes
-#
+############################################################
 
 pad_0402 = cube(-.0175,.0175,-.014,.014,0,0)
 
@@ -1186,9 +1185,225 @@ class choke(part):
       self.shape = add(self.shape,translate(pad_choke,.177,.177,0))
       self.pad.append(point(.177,.177,0))
 
-#
+############################################################
 # connectors
-#
+############################################################
+
+class header_NEO_6M(part):
+   #
+   # NEO_6M GPS module
+   #
+   def __init__(self,value=''):
+      pad_header = cylinder(0,0,0,0,.03)
+      self.value = value
+      self.pad = [point(0,0,0)]
+      self.labels = []
+      #
+      # pin 1
+      #
+      self.shape = translate(pad_header,0,.2,0)
+      self.pad.append(point(0,.2,0))
+      self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'PPS'))
+      #
+      # pin 2
+      #
+      self.shape = add(self.shape,translate(pad_header,0,.1,0))
+      self.pad.append(point(0,.1,0))
+      self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'TXD'))
+      #
+      # pin 3
+      #
+      self.shape = add(self.shape,translate(pad_header,0,0,0))
+      self.pad.append(point(0,0,0))
+      self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'RXD'))
+      #
+      # pin 4
+      #
+      self.shape = add(self.shape,translate(pad_header,0,-.1,0))
+      self.pad.append(point(0,-.1,0))
+      self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'GND'))
+      #
+      # pin 5
+      #
+      self.shape = add(self.shape,translate(pad_header,0,-.2,0))
+      self.pad.append(point(0,-.2,0))
+      self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'VCC'))
+
+class header_MFRC522(part):
+   #
+   # MFCR522 RFID module
+   #
+   def __init__(self,value=''):
+      pad_header = cylinder(0,0,0,0,.03)
+      self.value = value
+      self.pad = [point(0,0,0)]
+      self.labels = []
+      #
+      # pin 1
+      #
+      self.shape = translate(pad_header,0,.35,0)
+      self.pad.append(point(0,.35,0))
+      self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'1SDA'))
+      #
+      # pin 2
+      #
+      self.shape = add(self.shape,translate(pad_header,0,.25,0))
+      self.pad.append(point(0,.25,0))
+      self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'SCK'))
+      #
+      # pin 3
+      #
+      self.shape = add(self.shape,translate(pad_header,0,.15,0))
+      self.pad.append(point(0,.15,0))
+      self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'COPI'))
+      #
+      # pin 4
+      #
+      self.shape = add(self.shape,translate(pad_header,0,0.05,0))
+      self.pad.append(point(0,0.05,0))
+      self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'CIPO'))
+      #
+      # pin 5
+      #
+      self.shape = add(self.shape,translate(pad_header,0,-.05,0))
+      self.pad.append(point(0,-.05,0))
+      self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'IRQ'))
+      #
+      # pin 6
+      #
+      self.shape = add(self.shape,translate(pad_header,0,-.15,0))
+      self.pad.append(point(0,-.15,0))
+      self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'GND'))
+      #
+      # pin 7
+      #
+      self.shape = add(self.shape,translate(pad_header,0,-.25,0))
+      self.pad.append(point(0,-.25,0))
+      self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'RST'))
+      #
+      # pin 8
+      #
+      self.shape = add(self.shape,translate(pad_header,0,-.35,0))
+      self.pad.append(point(0,-.35,0))
+      self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'3.3V'))
+
+class header_LSM6DS33_2736(part):
+   #
+   # LSD6DS33 carrier
+   #    Pololu 2736
+   #
+   def __init__(self,value=''):
+      pad_header = cylinder(0,0,0,0,.03)
+      self.value = value
+      self.pad = [point(0,0,0)]
+      self.labels = []
+      #
+      # pin 1
+      #
+      self.shape = translate(pad_header,0,.4,0)
+      self.pad.append(point(0,.4,0))
+      self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'1VDD'))
+      #
+      # pin 2
+      #
+      self.shape = add(self.shape,translate(pad_header,0,.3,0))
+      self.pad.append(point(0,.3,0))
+      self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'VIN'))
+      #
+      # pin 3
+      #
+      self.shape = add(self.shape,translate(pad_header,0,.2,0))
+      self.pad.append(point(0,.2,0))
+      self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'GND'))
+      #
+      # pin 4
+      #
+      self.shape = add(self.shape,translate(pad_header,0,0.1,0))
+      self.pad.append(point(0,0.1,0))
+      self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'SDA'))
+      #
+      # pin 5
+      #
+      self.shape = add(self.shape,translate(pad_header,0,0,0))
+      self.pad.append(point(0,0,0))
+      self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'SCL'))
+      #
+      # pin 6
+      #
+      self.shape = add(self.shape,translate(pad_header,0,-.1,0))
+      self.pad.append(point(0,-.1,0))
+      self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'SDO'))
+      #
+      # pin 7
+      #
+      self.shape = add(self.shape,translate(pad_header,0,-.2,0))
+      self.pad.append(point(0,-.2,0))
+      self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'CS'))
+      #
+      # pin 8
+      #
+      self.shape = add(self.shape,translate(pad_header,0,-.3,0))
+      self.pad.append(point(0,-.3,0))
+      self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'INT2'))
+      #
+      # pin 9
+      #
+      self.shape = add(self.shape,translate(pad_header,0,-.4,0))
+      self.pad.append(point(0,-.4,0))
+      self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'INT1'))
+
+class header_VL53L1X_3415(part):
+   #
+   # VL53L1X carrier
+   #    Pololu 3415
+   #
+   def __init__(self,value=''):
+      pad_header = cylinder(0,0,0,0,.03)
+      self.value = value
+      self.pad = [point(0,0,0)]
+      self.labels = []
+      #
+      # pin 1
+      #
+      self.shape = translate(pad_header,0,.3,0)
+      self.pad.append(point(0,.3,0))
+      self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'1VDD'))
+      #
+      # pin 2
+      #
+      self.shape = add(self.shape,translate(pad_header,0,.2,0))
+      self.pad.append(point(0,.2,0))
+      self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'VIN'))
+      #
+      # pin 3
+      #
+      self.shape = add(self.shape,translate(pad_header,0,.1,0))
+      self.pad.append(point(0,.1,0))
+      self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'GND'))
+      #
+      # pin 4
+      #
+      self.shape = add(self.shape,translate(pad_header,0,0,0))
+      self.pad.append(point(0,0,0))
+      self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'SDA'))
+      #
+      # pin 5
+      #
+      self.shape = add(self.shape,translate(pad_header,0,-.1,0))
+      self.pad.append(point(0,-.1,0))
+      self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'SCL'))
+      #
+      # pin 6
+      #
+      self.shape = add(self.shape,translate(pad_header,0,-.2,0))
+      self.pad.append(point(0,-.2,0))
+      self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'XSHUT'))
+      #
+      # pin 7
+      #
+      self.shape = add(self.shape,translate(pad_header,0,-.3,0))
+      self.pad.append(point(0,-.3,0))
+      self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'GPIO1'))
 
 class ESP_WROOM_02D(part):
    #
@@ -4161,9 +4376,9 @@ class Molex_serial(part):
       self.shape = add(self.shape,translate(pad_Molex_solder,-.16,-.065,0))
       self.shape = add(self.shape,translate(pad_Molex_solder,.16,-.065,0))
 
-#
+############################################################
 # switches
-#
+############################################################
 
 class slide_switch(part):
    # 
@@ -4234,9 +4449,9 @@ class button_6mm(part):
       self.pad.append(point(.125,.08,0))
       self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'L2'))
 
-#
+############################################################
 # crystals and resonators
-#
+############################################################
 
 pad_XTAL_EFOBM = cube(-.016,.016,-.085,.085,0,0)
 
@@ -4307,94 +4522,269 @@ class XTAL_CSM_7(part):
       self.shape = add(self.shape,translate(pad_XTAL_CSM_7,.187,0,0))
       self.pad.append(point(.187,0,0))
 
-#
+############################################################
 # diodes, transistors, regulators, sensors
-#
+############################################################
 
-class D_1206(part):
+class LED_3014_1100(part):
    #
-   # 1206 diode
+   # Luminus MP-3014-1100-50-80
    #
    def __init__(self,value=''):
+      anode = cube(-.011,.011,-.027,.027,0,0)
+      cathode = cube(-.036,.036,-.027,.027,0,0)
       self.value = value
       self.pad = [point(0,0,0)]
       self.labels = []
       #
       # anode
       #
-      self.shape = translate(pad_1206,-.06,0,0)
-      self.pad.append(point(-.055,0,0))
+      self.shape = translate(anode,-.047,0,0)
+      self.pad.append(point(-.047,0,0))
       self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'A'))
       #
       # cathode
       #
-      self.shape = add(self.shape,translate(pad_1206,.06,0,0))
-      self.pad.append(point(.055,0,0))
+      self.shape = add(self.shape,translate(cathode,.022,0,0))
+      self.pad.append(point(.022,0,0))
       self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'C'))
 
-class LED_1206(part):
+class CMM4030D261I2STR(part):
    #
-   # 1206 LED
+   # CUI CMM-4030D-261-I2S-TR I2S microphone
    #
    def __init__(self,value=''):
+      pad = cube(-.018,.018,-.011,.011,0,0)
       self.value = value
+      self.x = 0
+      self.y = 0
+      self.z = 0
       self.pad = [point(0,0,0)]
       self.labels = []
+      s = 0.004
       #
-      # anode
+      # pin 1
       #
-      self.shape = translate(pad_1206,-.06,0,0)
-      self.pad.append(point(-.055,0,0))
-      self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'A'))
+      self.shape = translate(pad,.037,-.059,0)
+      self.pad.append(point(.037,-.059,0))
+      self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'GND.',line=s))
       #
-      # cathode
+      # pin 2
       #
-      self.shape = add(self.shape,translate(pad_1206,.06,0,0))
-      self.pad.append(point(.055,0,0))
-      self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'C'))
-
-pad_RGB = cube(-.02,.02,-.029,.029,0,0)
+      self.shape = add(self.shape,translate(pad,.037,-.019,0))
+      self.pad.append(point(.037,-.019,0))
+      self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'N/C',line=s))
+      #
+      # pin 3
+      #
+      self.shape = add(self.shape,translate(pad,.037,.019,0))
+      self.pad.append(point(.037,.019,0))
+      self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'WS',line=s))
+      #
+      # pin 4
+      #
+      self.shape = add(self.shape,translate(pad,.037,.059,0))
+      self.pad.append(point(.037,.059,0))
+      self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'EN',line=s))
+      #
+      # pin 5
+      #
+      self.shape = add(self.shape,translate(pad,-.037,.059,0))
+      self.pad.append(point(-.037,.059,0))
+      self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'L/R',line=s))
+      #
+      # pin 6
+      #
+      self.shape = add(self.shape,translate(pad,-.037,.019,0))
+      self.pad.append(point(-.037,.019,0))
+      self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'SCK',line=s))
+      #
+      # pin 7
+      #
+      self.shape = add(self.shape,translate(pad,-.037,-.019,0))
+      self.pad.append(point(-.037,-.019,0))
+      self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'SD',line=s))
+      #
+      # pin 8
+      #
+      self.shape = add(self.shape,translate(pad,-.037,-.059,0))
+      self.pad.append(point(-.037,-.059,0))
+      self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'VDD',line=s))
 
-class LED_RGB(part):
+class SPG08P4HM4H(part):
    #
-   # CREE CLV1A-FKB
+   # Knowles SPG08P4HM4H-1 PDM microphone
    #
    def __init__(self,value=''):
+      pad = cube(-.011,.011,-.011,.011,0,0)
       self.value = value
       self.x = 0
       self.y = 0
       self.z = 0
       self.pad = [point(0,0,0)]
       self.labels = []
-      dx = .029
-      dy = .059
+      s = 0.004
       #
-      # pin 1: red
+      # pin 1
       #
-      self.shape = translate(pad_RGB,-dx,-dy,0)
-      self.shape = add(self.shape,cylinder(-dx,-dy-.029,0,0,.02))
-      self.pad.append(point(-dx,-dy,0))
-      self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'R'))
+      self.shape = translate(pad,.023,-.037,0)
+      self.pad.append(point(.023,-.037,0))
+      self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'V.',line=s))
       #
-      # pin 2: anode
+      # pin 2
       #
-      self.shape = add(self.shape,translate(pad_RGB,dx,-dy,0))
-      self.pad.append(point(dx,-dy,0))
-      self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'A'))
+      self.shape = add(self.shape,translate(pad,.023,0,0))
+      self.pad.append(point(.023,0,0))
+      self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'G',line=s))
       #
-      # pin 3: blue
+      # pin 3
       #
-      self.shape = add(self.shape,translate(pad_RGB,dx,dy,0))
-      self.pad.append(point(dx,dy,0))
-      self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'B'))
+      self.shape = add(self.shape,translate(pad,.023,.037,0))
+      self.pad.append(point(.023,.037,0))
+      self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'DAT',line=s))
       #
-      # pin 4: green
+      # pin 4
       #
-      self.shape = add(self.shape,translate(pad_RGB,-dx,dy,0))
-      self.pad.append(point(-dx,dy,0))
-      self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'G'))
+      self.shape = add(self.shape,translate(pad,-.023,.037,0))
+      self.pad.append(point(-.023,.037,0))
+      self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'CK',line=s))
+      #
+      # pin 5
+      #
+      self.shape = add(self.shape,translate(pad,-.023,0,0))
+      self.pad.append(point(-.023,0,0))
+      self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'G',line=s))
+      #
+      # pin 6
+      #
+      self.shape = add(self.shape,translate(pad,-.023,-.037,0))
+      self.pad.append(point(-.023,-.037,0))
+      self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'SEL',line=s))
 
-class phototransistor_1206(part):
+class VEML6040(part):
+   #
+   # Vishay VEML6040 color sensor 
+   #
+   def __init__(self,value=''):
+      pad12 = cube(-.016,.019,-.006,.006,0,0)
+      pad3 = cube(-.023,.016,-.006,.006,0,0)
+      pad4 = cube(-.019,.016,-.006,.006,0,0)
+      self.value = value
+      self.x = 0
+      self.y = 0
+      self.z = 0
+      self.pad = [point(0,0,0)]
+      self.labels = []
+      s = 0.004
+      #
+      # pin 1
+      #
+      self.shape = translate(pad12,-.039,.014,0)
+      self.pad.append(point(-.039,.014,0))
+      self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'1GND',line=s))
+      #
+      # pin 2
+      #
+      self.shape = add(self.shape,translate(pad12,-.039,-.014,0))
+      self.pad.append(point(-.039,-.014,0))
+      self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'SDA',line=s))
+      #
+      # pin 3
+      #
+      self.shape = add(self.shape,translate(pad3,.039,-.014,0))
+      self.pad.append(point(.039,-.014,0))
+      self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'SCL',line=s))
+      #
+      # pin 4
+      #
+      self.shape = add(self.shape,translate(pad4,.039,.014,0))
+      self.pad.append(point(.039,.014,0))
+      self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'VDD',line=s))
+
+class D_1206(part):
+   #
+   # 1206 diode
+   #
+   def __init__(self,value=''):
+      self.value = value
+      self.pad = [point(0,0,0)]
+      self.labels = []
+      #
+      # anode
+      #
+      self.shape = translate(pad_1206,-.06,0,0)
+      self.pad.append(point(-.055,0,0))
+      self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'A'))
+      #
+      # cathode
+      #
+      self.shape = add(self.shape,translate(pad_1206,.06,0,0))
+      self.pad.append(point(.055,0,0))
+      self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'C'))
+
+class LED_1206(part):
+   #
+   # 1206 LED
+   #
+   def __init__(self,value=''):
+      self.value = value
+      self.pad = [point(0,0,0)]
+      self.labels = []
+      #
+      # anode
+      #
+      self.shape = translate(pad_1206,-.06,0,0)
+      self.pad.append(point(-.055,0,0))
+      self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'A'))
+      #
+      # cathode
+      #
+      self.shape = add(self.shape,translate(pad_1206,.06,0,0))
+      self.pad.append(point(.055,0,0))
+      self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'C'))
+
+pad_RGB = cube(-.02,.02,-.029,.029,0,0)
+
+class LED_RGB(part):
+   #
+   # CREE CLV1A-FKB
+   #
+   def __init__(self,value=''):
+      self.value = value
+      self.x = 0
+      self.y = 0
+      self.z = 0
+      self.pad = [point(0,0,0)]
+      self.labels = []
+      dx = .029
+      dy = .059
+      #
+      # pin 1: red
+      #
+      self.shape = translate(pad_RGB,-dx,-dy,0)
+      self.shape = add(self.shape,cylinder(-dx,-dy-.029,0,0,.02))
+      self.pad.append(point(-dx,-dy,0))
+      self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'R'))
+      #
+      # pin 2: anode
+      #
+      self.shape = add(self.shape,translate(pad_RGB,dx,-dy,0))
+      self.pad.append(point(dx,-dy,0))
+      self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'A'))
+      #
+      # pin 3: blue
+      #
+      self.shape = add(self.shape,translate(pad_RGB,dx,dy,0))
+      self.pad.append(point(dx,dy,0))
+      self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'B'))
+      #
+      # pin 4: green
+      #
+      self.shape = add(self.shape,translate(pad_RGB,-dx,dy,0))
+      self.pad.append(point(-dx,dy,0))
+      self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'G'))
+
+class phototransistor_1206(part):
    #
    # 1206 phototransistor
    # OPTEK 520,521
@@ -5023,9 +5413,303 @@ class ADXL343(part):
       self.pad.append(point(0,2.5*d,0))
       self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'SCL',angle=90,line=s))
 
-#
+class VL53L1X(part):
+   #
+   # ST VL53L1X time of flight sensor 
+   #
+   def __init__(self,value=''):
+      pad = cube(-.0075,.0075,-.0075,.0075,0,0)
+      d = 0.8/25.4
+      w = 0.8/25.4
+      s = 0.004
+      self.value = value
+      self.pad = [point(0,0,0)]
+      self.labels = []
+      #
+      # pin 1
+      #
+      self.shape = translate(pad,-w,-2*d,0)
+      self.pad.append(point(-w,-2*d,0))
+      self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,"1V",line=s))
+      #
+      # pin 2
+      #
+      self.shape = add(self.shape,translate(pad,-w,-1*d,0))
+      self.pad.append(point(-w,-1*d,0))
+      self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'G',line=s))
+      #
+      # pin 3
+      #
+      self.shape = add(self.shape,translate(pad,-w,0*d,0))
+      self.pad.append(point(-w,0*d,0))
+      self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'G',line=s))
+      #
+      # pin 4
+      #
+      self.shape = add(self.shape,translate(pad,-w,1*d,0))
+      self.pad.append(point(-w,1*d,0))
+      self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'G',line=s))
+      #
+      # pin 5
+      #
+      self.shape = add(self.shape,translate(pad,-w,2*d,0))
+      self.pad.append(point(-w,2*d,0))
+      self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'XS',line=s))
+      #
+      # pin 6
+      #
+      self.shape = add(self.shape,translate(pad,0,2*d,0))
+      self.pad.append(point(0,2*d,0))
+      self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'G',line=s))
+      #
+      # pin 7
+      #
+      self.shape = add(self.shape,translate(pad,w,2*d,0))
+      self.pad.append(point(w,2*d,0))
+      self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'IO',line=s))
+      #
+      # pin 8
+      #
+      self.shape = add(self.shape,translate(pad,w,1*d,0))
+      self.pad.append(point(w,1*d,0))
+      self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'NC',line=s))
+      #
+      # pin 9
+      #
+      self.shape = add(self.shape,translate(pad,w,0*d,0))
+      self.pad.append(point(w,0*d,0))
+      self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'SDA',line=s))
+      #
+      # pin 10
+      #
+      self.shape = add(self.shape,translate(pad,w,-1*d,0))
+      self.pad.append(point(w,-1*d,0))
+      self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'SCL',line=s))
+      #
+      # pin 11
+      #
+      self.shape = add(self.shape,translate(pad,w,-2*d,0))
+      self.pad.append(point(w,-2*d,0))
+      self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'V',line=s))
+      #
+      # pin 12
+      #
+      self.shape = add(self.shape,translate(pad,0,-2*d,0))
+      self.pad.append(point(0,-2*d,0))
+      self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'G',line=s))
+
+############################################################
 # ICs
-#
+############################################################
+
+class AVRDB28(part):
+   #
+   # AVR*DB28
+   #
+   def __init__(self,value=''):
+      self.value = value
+      self.pad = [point(0,0,0)]
+      self.labels = []
+      d = 9.01/2/25.4 # spacing
+      w = 0.4/2/25.4 # width
+      h = 1.4/2/25.4 # height
+      p = 0.8/25.4 # pitch
+      l = 0.004 # text
+      pad = cube(-h,h,-w,w,0,0)
+      padv = cube(-w,w,-h,h,0,0)
+      #
+      # pin 1
+      #
+      self.shape = translate(pad,-d,3.5*p,0)
+      self.shape = add(self.shape,cylinder(-d-h,3.5*p,0,0,w))
+      self.pad.append(point(-d,3.5*p,0))
+      self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'.PA3',line=l))
+      #
+      # pin 2
+      #
+      self.shape = add(self.shape,translate(pad,-d,2.5*p,0))
+      self.pad.append(point(-d,2.5*p,0))
+      self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'PA4',line=l))
+      #
+      # pin 3
+      #
+      self.shape = add(self.shape,translate(pad,-d,1.5*p,0))
+      self.pad.append(point(-d,1.5*p,0))
+      self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'PA5',line=l))
+      #
+      # pin 4
+      #
+      self.shape = add(self.shape,translate(pad,-d,.5*p,0))
+      self.pad.append(point(-d,.5*p,0))
+      self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'PA6',line=l))
+      #
+      # pin 5
+      #
+      self.shape = add(self.shape,translate(pad,-d,-.5*p,0))
+      self.pad.append(point(-d,-.5*p,0))
+      self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'PA7',line=l))
+      #
+      # pin 6
+      #
+      self.shape = add(self.shape,translate(pad,-d,-1.5*p,0))
+      self.pad.append(point(-d,-1.5*p,0))
+      self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'PC0',line=l))
+      #
+      # pin 7
+      #
+      self.shape = add(self.shape,translate(pad,-d,-2.5*p,0))
+      self.pad.append(point(-d,-2.5*p,0))
+      self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'PC1',line=l))
+      #
+      # pin 8
+      #
+      self.shape = add(self.shape,translate(pad,-d,-3.5*p,0))
+      self.pad.append(point(-d,-3.5*p,0))
+      self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'PC2',line=l))
+      #
+      # pin 9
+      #
+      self.shape = add(self.shape,translate(padv,-3.5*p,-d,0))
+      self.pad.append(point(-3.5*p,-d,0))
+      self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'PC3',line=l,angle=-90))
+      #
+      # pin 10
+      #
+      self.shape = add(self.shape,translate(padv,-2.5*p,-d,0))
+      self.pad.append(point(-2.5*p,-d,0))
+      self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'VIO2',line=l,angle=-90))
+      #
+      # pin 11
+      #
+      self.shape = add(self.shape,translate(padv,-1.5*p,-d,0))
+      self.pad.append(point(-1.5*p,-d,0))
+      self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'PD1',line=l,angle=-90))
+      #
+      # pin 12
+      #
+      self.shape = add(self.shape,translate(padv,-.5*p,-d,0))
+      self.pad.append(point(-.5*p,-d,0))
+      self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'PD2',line=l,angle=-90))
+      #
+      # pin 13
+      #
+      self.shape = add(self.shape,translate(padv,.5*p,-d,0))
+      self.pad.append(point(.5*p,-d,0))
+      self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'PD3',line=l,angle=-90))
+      #
+      # pin 14
+      #
+      self.shape = add(self.shape,translate(padv,1.5*p,-d,0))
+      self.pad.append(point(1.5*p,-d,0))
+      self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'PD4',line=l,angle=-90))
+      #
+      # pin 15
+      #
+      self.shape = add(self.shape,translate(padv,2.5*p,-d,0))
+      self.pad.append(point(2.5*p,-d,0))
+      self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'PD5',line=l,angle=-90))
+      #
+      # pin 16
+      #
+      self.shape = add(self.shape,translate(padv,3.5*p,-d,0))
+      self.pad.append(point(3.5*p,-d,0))
+      self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'PD6',line=l,angle=-90))
+      #
+      # pin 17
+      #
+      self.shape = add(self.shape,translate(pad,d,-3.5*p,0))
+      self.pad.append(point(d,-3.5*p,0))
+      self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'PD7',line=l))
+      #
+      # pin 18
+      #
+      self.shape = add(self.shape,translate(pad,d,-2.5*p,0))
+      self.pad.append(point(d,-2.5*p,0))
+      self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'AVDD',line=l))
+      #
+      # pin 19
+      #
+      self.shape = add(self.shape,translate(pad,d,-1.5*p,0))
+      self.pad.append(point(d,-1.5*p,0))
+      self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'GND',line=l))
+      #
+      # pin 20
+      #
+      self.shape = add(self.shape,translate(pad,d,-.5*p,0))
+      self.pad.append(point(d,-.5*p,0))
+      self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'PF0',line=l))
+      #
+      # pin 21
+      #
+      self.shape = add(self.shape,translate(pad,d,.5*p,0))
+      self.pad.append(point(d,.5*p,0))
+      self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'PF1',line=l))
+      #
+      # pin 22
+      #
+      self.shape = add(self.shape,translate(pad,d,1.5*p,0))
+      self.pad.append(point(d,1.5*p,0))
+      self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'PF2',line=l))
+      #
+      # pin 23
+      #
+      self.shape = add(self.shape,translate(pad,d,2.5*p,0))
+      self.pad.append(point(d,2.5*p,0))
+      self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'PF3',line=l))
+      #
+      # pin 24
+      #
+      self.shape = add(self.shape,translate(pad,d,3.5*p,0))
+      self.pad.append(point(d,3.5*p,0))
+      self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'PF4',line=l))
+      #
+      # pin 25
+      #
+      self.shape = add(self.shape,translate(padv,3.5*p,d,0))
+      self.pad.append(point(3.5*p,d,0))
+      self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'PF5',line=l,angle=-90))
+      #
+      # pin 26
+      #
+      self.shape = add(self.shape,translate(padv,2.5*p,d,0))
+      self.pad.append(point(2.5*p,d,0))
+      self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'PF6',line=l,angle=-90))
+      #
+      # pin 27
+      #
+      self.shape = add(self.shape,translate(padv,1.5*p,d,0))
+      self.pad.append(point(1.5*p,d,0))
+      self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'UPDI',line=l,angle=-90))
+      #
+      # pin 28
+      #
+      self.shape = add(self.shape,translate(padv,.5*p,d,0))
+      self.pad.append(point(.5*p,d,0))
+      self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'VDD',line=l,angle=-90))
+      #
+      # pin 29
+      #
+      self.shape = add(self.shape,translate(padv,-.5*p,d,0))
+      self.pad.append(point(-.5*p,d,0))
+      self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'GND',line=l,angle=-90))
+      #
+      # pin 30
+      #
+      self.shape = add(self.shape,translate(padv,-1.5*p,d,0))
+      self.pad.append(point(-1.5*p,d,0))
+      self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'PA0',line=l,angle=-90))
+      #
+      # pin 31
+      #
+      self.shape = add(self.shape,translate(padv,-2.5*p,d,0))
+      self.pad.append(point(-2.5*p,d,0))
+      self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'PA1',line=l,angle=-90))
+      #
+      # pin 32
+      #
+      self.shape = add(self.shape,translate(padv,-3.5*p,d,0))
+      self.pad.append(point(-3.5*p,d,0))
+      self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'PA2',line=l,angle=-90))
 
 class ATtiny3216(part):
    #
@@ -5522,7 +6206,7 @@ class ATtiny1614(part):
       self.shape = translate(pad,-d,.15,0)
       self.shape = add(self.shape,cylinder(-d-h,.15,0,0,w))
       self.pad.append(point(-d,.15,0))
-      self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'1VCC'))
+      self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'.VCC'))
       #
       # pin 2
       #
@@ -7047,9 +7731,9 @@ class fab(part):
       self.shape = add(self.shape,circle(l,0,r))
       self.shape = add(self.shape,circle(-l,0,r))
 
-#
+############################################################
 # define board
-#
+############################################################
 
 width = 1.02 # board width
 height = .87 # board height
@@ -7215,9 +7899,9 @@ pcb = wire(pcb,w,
    point(V7.x,V6.y,zb),
    V7.pad[2])
 
-#
+############################################################
 # select output
-#
+############################################################
 
 outputs = {}
 if (output == "top, labels, and exterior"):
@@ -7270,9 +7954,9 @@ elif (output == "solder mask"):
 else:
    print("oops -- don't recognize output")
 
-#
+############################################################
 # set limits and parameters
-#
+############################################################
 
 border = 0.05
 outputs["xmin"] = x-border # min x to render
@@ -7282,9 +7966,9 @@ outputs["ymax"] = y+height+border # max y to render
 outputs["mm_per_unit"] = 25.4 # use inch units
 outputs["type"] = "RGB" # use RGB color
 
-#
+############################################################
 # send output
-#
+############################################################
 
 json.dump(outputs,sys.stdout)