Edit in JSFiddle

/* xported ARC_RES, CORNER_RAD */
/* xported calcArea */
/* xported rotateSegment180, reflectSegment45 */
/* xported mirrorSegmentV, mirrorSegmentH */
/* xported offsetSegment */
/* xported createArcSegment */

/**
 * Create an arc segment
 * @nosideeffects
 * @param {Number} cx X position of center
 * @param {Number} cy Y position of center
 * @param {Number} r Radius
 * @param {Number} startAngle Starting angle
 * @param {Number} stepAngle Angle increament
 * @param {Number} nSteps Number of steps
 * @return {Array.<Number>}
 */
function createArcSegment(cx, cy, r, startAngle, stepAngle, nSteps) {
  /*
  console.log('cx:' + cx + ',cy:'+ cx + ',r:'+ r
      + ',from:'+ (startAngle*180/Math.PI) + ',step:'+ (stepAngle*180/Math.PI)+
      ',n:'+ nSteps);
  */
  const ROUNDING_F = 10000; // Round all points to 0.0001
  const newArc = new Array(nSteps * 2);
  let i = 0;
  let alpha = startAngle;
  for (let n = nSteps; n > 0; n--) {
    const x = cx + r * Math.cos(alpha);
    const y = cy + r * Math.sin(alpha);
    newArc[i] = Math.round( x * ROUNDING_F ) / ROUNDING_F;
    newArc[i+1] = Math.round( y * ROUNDING_F ) / ROUNDING_F;
    alpha += stepAngle;
    i+=2;
  }
  return newArc;
}

/**
 * Horizontally mirror a segment (with respect to local origin)
 * [x1, y1, x2, y2, ..., xn, yn] => [-xn, yn, ..., -x2, y2, -x1, y1]
 * @nosideeffects
 * @param {Array.<Number>} srcSeg
 * @return {Array.<Number>}
 */
function mirrorSegmentH(srcSeg) {
  const len = srcSeg.length;
  const newSeg = new Array(len);
  let j = len-1;
  for (let i = 0; i < len; i += 2) {
    newSeg[i] = -srcSeg[j-1]; // x1 = -xn
    newSeg[i+1] = srcSeg[j]; // y1 = yn
    j -= 2;
  }
  return newSeg;
}

/**
 * Vertically mirror a segment (with respect to local origin)
 * [x1, y1, x2, y2, ..., xn, yn] => [xn, -yn, ..., x2, -y2, x1, -y1]
 * @nosideeffects
 * @param {Array.<Number>} srcSeg
 * @return {Array.<Number>}
 */
function mirrorSegmentV(srcSeg) {
  const len = srcSeg.length;
  const newSeg = new Array(len);
  let j = len-1;
  for (let i = 0; i < len; i += 2) {
    newSeg[i] = srcSeg[j-1]; // x1 = xn
    newSeg[i+1] = -srcSeg[j]; // y1 = -yn
    j -= 2;
  }
  return newSeg;
}

/**
 * Rotate a segment by 180 degree (with respect to local origin)
 * [x1, y1, x2, y2, ..., xn, yn] => [-x1, -y1, -x2, -y2, ..., -xn, -yn]
 * @nosideeffects
 * @param {Array.<Number>} srcSeg
 * @return {Array.<Number>}
 */
function rotateSegment180(srcSeg) {
  const len = srcSeg.length;
  const newSeg = new Array(len);
  for (let i = 0; i < len; i++) {
    newSeg[i] = -srcSeg[i];
  }
  return newSeg;
}

/**
 * Reflect a segment by 45 degree line
 * [x1, y1, x2, y2, ..., xn, yn] => [yn, xn, ..., y2, x2, y1, x1]
 * @nosideeffects
 * @param {Array.<Number>} srcSeg
 * @return {Array.<Number>}
 */
function reflectSegment45(srcSeg) {
  const len = srcSeg.length;
  const newSeg = new Array(len);
  let j = len-1;
  for (let i = 0; i < len; i += 2) {
    newSeg[i] = srcSeg[j]; // x1 = yn
    newSeg[i+1] = srcSeg[j-1]; // y1 = xn
    j -= 2;
  }
  return newSeg;
}

/**
 * Offset a segment
 * [x1, y1, ...] => [x1 + offsetX, y1 + offsetY...]
 * @nosideeffects
 * @param {Array.<Number>} srcSeg
 * @param {number} offsetX
 * @param {number} offsetY
 * @return {Array.<Number>}
 */
function offsetSegment(srcSeg, offsetX, offsetY) {
  const len = srcSeg.length;
  const newSeg = new Array(len);
  for (let i = 0; i < len; i += 2) {
    newSeg[i] = srcSeg[i] + offsetX;
    newSeg[i+1] = srcSeg[i+1] + offsetY;
  }
  return newSeg;
}

/**
 * Calculate the area of any polygon (do not close the polyline)
 * Area = 0.5 ( ( x1y2 - y1x2 ) + ( x2y3 - y2x3 ) + ... + ( xny1 - ynx1) )
 * See https://www.mathopenref.com/coordpolygonarea.html
 * @nosideeffects
 * @param {Array.<Number>} segment
 * @return {Number}
*/
function calcArea(segment) {
  const len = segment.length;
  const x1 = segment[0];
  const y1 = segment[1];
  const xn = segment[len-2];
  const yn = segment[len-1];
  let area = xn * y1 - yn * x1;
  for (let i = 2; i < len; i+=2) {
    const x2 = segment[i];
    const y2 = segment[i+1];
    const x1 = segment[i-2];
    const y1 = segment[i-1];
    area += x1 * y2 - y1 * x2;
  }
  return Math.abs(area / 2);
}

/* SVG functions */

/**
 * Remove all children
 * @param {DOMElement} el Parent element
*/
function clearElement(el) {
  while (el.lastChild) {
    el.removeChild(el.lastChild);
  }
}

const SVGNS = 'http://www.w3.org/2000/svg';

/**
 * Construct a path data from a segment
 * @param {Array.<Number>} segment
 * @return {String}
*/
function getPathDataFromSegment(segment) {
  let pathData = 'M' + segment[0] + ' ' + (-segment[1]) + ' L';
  const len = segment.length;
  for (let i = 2; i < len; i+=2) {
    pathData += ' ' + segment[i] + ' ' + (-segment[i+1]);
  }
  pathData += 'z'; // close path
  return pathData;
}

/**
 * Create a path element
 * @param {Array.<Number>} segment
 * @return {Element}
*/
function createPathFromSegment(segment) {
  const newPath = document.createElementNS(SVGNS, 'path');
  const pathData = getPathDataFromSegment(segment);
  newPath.setAttributeNS(null, 'd', pathData);
  return newPath;
}

/**
 * Construct a compositie path data from an array of segments
 * @param {Array.<Array.<number>>} segments
 * @return {String}
*/
function getCompositePathDataFromSegments(segments) {
  let pathData = '';
  segments.forEach(function(seg) {
    pathData += getPathDataFromSegment(seg);
  });
  return pathData;
}

/**
 * Create a path element with composite path
 * from an array of segments
 * @param {Array.<Array.<number>>} segments
 * @return {Element}
*/
function createCompositePath(segments) {
  const newPath = document.createElementNS(SVGNS, 'path');
  const pathData = getCompositePathDataFromSegments(segments);
  newPath.setAttributeNS(null, 'd', pathData);
  return newPath;
}

/**
 * Create a circle element
 * @param {Number} cx X position of center
 * @param {Number} cy Y position of center
 * @param {Number} r Radius
 * @return {Element}
*/
function createCircle(cx, cy, r) {
  const newCircle = document.createElementNS(SVGNS, 'circle');
  newCircle.setAttributeNS(null, 'cx', cx);
  newCircle.setAttributeNS(null, 'cy', -cy);
  newCircle.setAttributeNS(null, 'r', r);
  return newCircle;
}

/**
 * Update pad properties
*/
function updateProps() {
  const fPadLength = document.getElementById('fPadLength');
  const fPadWidth = document.getElementById('fPadWidth');
  const fMaskSwell = document.getElementById('fMaskSwell');
  const fPasteShrink = document.getElementById('fPasteShrink');
  const fPasteSpacing = document.getElementById('fPasteSpacing');
  const fViaRingWidth = document.getElementById('fViaRingWidth');
  const fViaDiameter = document.getElementById('fViaDiameter');
  const fViaPitchH = document.getElementById('fViaPitchH');
  const fViaPitchV = document.getElementById('fViaPitchV');
  const fViaLayout = document.getElementById('fViaLayout');
  const fViaTenting = document.getElementById('fViaTenting');

  let padInfo = {
    padLength: fPadLength.value,
    padWidth: fPadWidth.value,
    viaPitchV: fViaPitchV.value,
    viaPitchH: fViaPitchH.value,
    viaRingWidth: fViaRingWidth.value,
    viaDiameter: fViaDiameter.value,
    viaLayout: fViaLayout.value,
    viaTenting: fViaTenting.checked,
    maskSwell: fMaskSwell.value,
    pasteShrink: fPasteShrink.value,
    pasteSpacing: fPasteSpacing.value,
  };

  padInfo = thermalTab.setProps( padInfo );
  resetProps();

  const solderMasks = thermalTab.updateSolderMasks();
  /*
  const pathElement = document.getElementById('solderMaskFG');
  solderMasks.push(padDMask);
  const maskPathData = getCompositePathDataFromSegments(solderMasks);
  pathElement.setAttributeNS(null, 'd', maskPathData);
  */
  let rootElement = document.getElementById('solderMaskFG');
  clearElement(rootElement);
  rootElement.appendChild(createCompositePath(solderMasks));
  /* aaaaaaaaaaaaaa */
  dSolderMasks.forEach(function(item) {
    rootElement.appendChild( createPathFromSegment(item) );
  });
  dSolderMasks2.forEach(function(item) {
    rootElement.appendChild( createPathFromSegment(item) );
  });
  dSolderMasks3.forEach(function(item) {
    rootElement.appendChild( createPathFromSegment(item) );
  });
  dSolderMasks4.forEach(function(item) {
    rootElement.appendChild( createPathFromSegment(item) );
  });

  rootElement = document.getElementById('pl_assy');
  clearElement(rootElement);
  /*
  rootElement.appendChild( createCircle(1.4, 1.4, padInfo.viaDiameter/2) );
  rootElement.appendChild( createCircle(0.7, 1.4, padInfo.viaDiameter/2) );
  rootElement.appendChild( createCircle(1.4, 0.7, padInfo.viaDiameter/2) );
  */
  const viaPositions = thermalTab.getViaPositions();
  viaPositions.forEach(function(item) {
    rootElement
        .appendChild( createCircle(item[0], item[1], padInfo.viaDiameter/2) );
  });

  const pasteMasks = thermalTab.updatePasteMasks();
  const pasteArea = thermalTab.getPasteArea();

  rootElement = document.getElementById('pl_paste');
  clearElement(rootElement);
  rootElement.appendChild( createCompositePath(pasteMasks) );
  /* aaaaaaaaaaaaaa */
  dPasteMasks.forEach(function(item) {
    rootElement.appendChild( createPathFromSegment(item) );
  });
  dPasteMasks2.forEach(function(item) {
    rootElement.appendChild( createPathFromSegment(item) );
  });
  dPasteMasks3.forEach(function(item) {
    rootElement.appendChild( createPathFromSegment(item) );
  });
  dPasteMasks4.forEach(function(item) {
    rootElement.appendChild( createPathFromSegment(item) );
  });

  rootElement = document.getElementById('pl_top');
  clearElement(rootElement);
  const newRect = document.createElementNS(SVGNS, 'rect');
  newRect.setAttributeNS(null, 'width', padInfo.padLength);
  newRect.setAttributeNS(null, 'height', padInfo.padWidth);
  newRect.setAttributeNS(null, 'x', -padInfo.padLength/2);
  newRect.setAttributeNS(null, 'y', -padInfo.padWidth/2);

  rootElement.appendChild(newRect);
  /* aaaaaaaaaaaaaa */
  dPads.forEach(function(item) {
    rootElement.appendChild( createPathFromSegment(item) );
  });
  dPads2.forEach(function(item) {
    rootElement.appendChild( createPathFromSegment(item) );
  });
  dPads3.forEach(function(item) {
    rootElement.appendChild( createPathFromSegment(item) );
  });
  dPads4.forEach(function(item) {
    rootElement.appendChild( createPathFromSegment(item) );
  });

  // ************************************************************
  // Show coverage information
  // ************************************************************

  const epadArea = padInfo.padLength * padInfo.padWidth;
  const r1 = (padInfo.viaDiameter/2) +
      (padInfo.viaTenting?padInfo.viaRingWidth:0);
  const area2 = epadArea - Math.PI * r1 * r1 * viaPositions.length;
  document.getElementById('info').innerHTML =
`<p>E-pad area: ${epadArea.toFixed(2)}mm²</p>
<p>SMD area: ${(area2).toFixed(2)}mm²</p>
<p>Paste area: ${pasteArea.toFixed(2)}mm²</p>
<p>Paste/E-pad ratio: ${(100*pasteArea/epadArea).toFixed(0)}%</p>
<p>Paste/SMD area ratio: ${(100*pasteArea/area2).toFixed(0)}%<br />
(target: 50~70% [<a href="http://www.ti.com/lit/an/slua271b/slua271b.pdf"
title="TI App Report: QFN and SON PCB attachment">1</a>,
<a href="https://www.psemi.com/pdf/app_notes/an62.pdf"
title="Peregrine Semi App Report: Soldering guidelines for mounting bottom-terminated components">2</a>])</p>`;
}

/**
 * Get pad properites
*/
function resetProps() {
  const fPadLength = document.getElementById('fPadLength');
  const fPadWidth = document.getElementById('fPadWidth');
  const fMaskSwell = document.getElementById('fMaskSwell');
  const fPasteShrink = document.getElementById('fPasteShrink');
  const fPasteSpacing = document.getElementById('fPasteSpacing');
  const fViaRingWidth = document.getElementById('fViaRingWidth');
  const fViaDiameter = document.getElementById('fViaDiameter');
  const fViaPitchH = document.getElementById('fViaPitchH');
  const fViaPitchV = document.getElementById('fViaPitchV');
  const fViaLayout = document.getElementById('fViaLayout');
  const fViaTenting = document.getElementById('fViaTenting');

  const padInfo = thermalTab.getProps();

  fPadLength.value = padInfo.padLength;
  fPadWidth.value = padInfo.padWidth;
  fMaskSwell.value = padInfo.maskSwell;
  fPasteShrink.value = padInfo.pasteShrink;
  fPasteSpacing.value = padInfo.pasteSpacing;
  fViaRingWidth.value = padInfo.viaRingWidth;
  fViaDiameter.value = padInfo.viaDiameter;
  fViaPitchH.value = padInfo.viaPitchH.toFixed(1);
  fViaPitchV.value = padInfo.viaPitchV.toFixed(1);
  fViaTenting.checked = padInfo.viaTenting;
  fViaLayout.value = padInfo.viaLayout;
}

window.addEventListener('load', updateProps);

/*
C1 column spacing
X1 pad width
Y1 pad length

e pad row pitch

overall width E
overall length D

ZD toe to toe
GD heel to heel
CPL clearance pad to epad
CLL clearance pad to pad

L terminal length
b terminal width

EV thermal via pitch
V thermal via diameter
*/

/* eslint-disable */
// source https://gist.github.com/branneman/8436956
if(SVGElement&&SVGElement.prototype){SVGElement.prototype.hasClass=function(className){return new RegExp('(\\s|^)'+className+'(\\s|$)').test(this.getAttribute('class'))};SVGElement.prototype.addClass=function(className){if(!this.hasClass(className)){this.setAttribute('class',this.getAttribute('class')+' '+className)}};SVGElement.prototype.removeClass=function(className){var removedClass=this.getAttribute('class').replace(new RegExp('(\\s|^)'+className+'(\\s|$)','g'),'$2');if(this.hasClass(className)){this.setAttribute('class',removedClass)}};SVGElement.prototype.toggleClass=function(className){if(this.hasClass(className)){this.removeClass(className)}else{this.addClass(className)}}}

/** Highlight a dimension group
  * @param {String} id
  */
function dim_highlight(id) {
  document.getElementById(id).addClass('dgrpH');
}
/** Un-highlight a dimension group
  * @param {String} id
  */
function dim_unhighlight(id) {
  document.getElementById(id).removeClass('dgrpH');
}

function switchMode() {
  viewMode = document.getElementById('viewMode').value;
  svg1 = document.getElementById('RePG');
  svg2 = document.getElementById('pad');
  if (viewMode == 'dark') {
    svg1.setAttribute('class','drdrk');
    svg2.setAttribute('class','drk');
  } else {
    svg1.setAttribute('class','drnat');
    svg2.setAttribute('class','nat');
  }
}

function toggleLayer(idName, visibility) {
  document.getElementById(idName).setAttributeNS(null, 'visibility', visibility);
}

'use strict';

PSPadD=function(){var a={I:.55,J:.24,M:.4,K:.05,L:0,j:.08,c:.08,G:[],F:[],H:[],update:function(){function c(a){var b=Math.floor(Math.PI*a/.02);return createArcSegment(l,0,a,Math.PI/2,-(Math.PI/b),b+1)}function d(a){var b=Math.floor(.5*Math.PI*a/.02);return createArcSegment(l,r,a,-Math.PI/2,-(.5*Math.PI/b),b+1)}var b=a.J/2-a.L,e=a.M;var l=a.I+a.K-b;var m=c(b),t=c(b+a.j),n=c(b-a.c),f=Math.min(.5*b,.25,e);l=-(e-f);var r=-(b-f);if(0<e){var h=d(f);m=m.concat(h,mirrorSegmentV(h));h=
d(f+a.j);t=t.concat(h,mirrorSegmentV(h));b-=a.c;e-=a.c;f=Math.max(.5*b,.06);b>f?(l=-e+f,r=-b+f,h=d(f),n=n.concat(h,mirrorSegmentV(h))):n.push(-e,-b,-e,b)}else m.push(0,-b,0,b);a.F=m;a.G=n;a.H=t},getPasteMask:function(){return a.G},getPad:function(){return a.F},getSolderMask:function(){return a.H},setProps:function(c){a.I=c.termLength;a.J=c.termWidth;a.O=c.toe;a.N=c.heel}};return a};

PSThermalTab=function(){var a={m:3.15,o:3.15,b:1,a:1,u:.08,s:.3,B:!1,j:.08,c:.08,g:.25,h:3,f:3,l:1,i:1,w:2,C:2,D:[],v:[],A:[],P:[],updateSolderMasks:function(){var c=a.m/2+a.j,d=a.o/2+a.j;if(a.B){var b=a.s/2+a.u;var e=Math.floor(Math.PI*b/.02);var l=createArcSegment(0,0,b,0,Math.PI/e,e+1);b=[];for(var m=0;m<a.h;m+=1)e=a.l-m*a.b,b=b.concat(offsetSegment(l,e,0));d=[].concat([c,d,c,a.i],offsetSegment(b,0,a.i),[-c,a.i,-c,d]);a.D=[d,mirrorSegmentV(d)];if(1<a.f)for(d=[].concat([c,a.a,c,0],b,[-c,
0,-c,a.a],offsetSegment(mirrorSegmentV(b),0,a.a)),b=1;b<a.f;b++)c=a.i-b*a.a,a.D.push(offsetSegment(d,0,c))}else a.D=[[c,d,c,-d,-c,-d,-c,d]];return a.D},updatePasteMasks:function(){function c(a,b){b-=a;var c=Math.abs(Math.floor(b*n/.02));return createArcSegment(0,0,n,a,b/c,c+1)}function d(a,b,c,d){b-=a;var e=Math.abs(Math.floor(.06*b/.02));return createArcSegment(c,d,.06,a,b/e,e)}function b(){return E.concat(offsetSegment(z,0,-a.a),offsetSegment(w,-a.b,-a.a),offsetSegment(A,-a.b,0))}function e(){var b=
m-.06;return offsetSegment(x,b,t-.06).concat(offsetSegment(B,b,a.g/2+.06),w,offsetSegment(C,a.g/2+.06,t-.06))}function l(){var b=m-.06;return offsetSegment(x,b,-a.g/2-.06).concat(offsetSegment(B,b,-a.a+a.g/2+.06),offsetSegment(w,0,-a.a),A)}var m=a.m/2-a.l-a.c,t=a.o/2-a.i-a.c,n=a.s/2+(a.B?a.u:0)+a.c,f=.06+n,r=.06+a.g/2,h=Math.asin(r/f),k=d(-Math.PI/2,-Math.PI+h,Math.cos(h)*f,r),v=reflectSegment45(k),w=[].concat(k,c(h,Math.PI/2-h),v),z=mirrorSegmentH(w),E=rotateSegment180(w),A=mirrorSegmentV(w),x=[0,
.06,.0185,.0571,.0353,.0485,.0485,.0353,.0571,.0185,.06,0],C=[-.06,0,-.0571,.0185,-.0485,.0353,-.0353,.0485,-.0185,.0571,-0,.06],B=[.06,-0,.0571,-.0185,.0485,-.0353,.0353,-.0485,.0185,-.0571,0,-.06];if(f=2==a.C){var g=r=0;if(.06<=m){var p=m-.06;p=offsetSegment(x.slice(.0185>p?2:0),p,-n-.06)}else p=.06+n,g=m-.06,r=-Math.asin(g/p),p=d(Math.PI/2-r,0,g,-(Math.cos(r)*p));if(.06<=t){g=0;var q=t-.06;var u=offsetSegment(x.slice(0,x.length-(.0185>q?2:0)),-n-.06,q)}else q=.06+n,u=t-.06,g=-Math.asin(u/q),u=
d(Math.PI/2,g,-(Math.cos(g)*q),u);k=rotateSegment180(k).concat(c(Math.PI+h,1.5*Math.PI-r),p);q=offsetSegment(mirrorSegmentV(k),0,-a.a);v=u.concat(c(Math.PI+g,1.5*Math.PI-h),rotateSegment180(v));var y=offsetSegment(mirrorSegmentH(v),-a.b,0);h=offsetSegment(w,-a.b,-a.a);p=u.concat(c(Math.PI+g,1.5*Math.PI-r),p).concat(q,h,y);g=v.concat(offsetSegment(z,0,-a.a),h,y);u=k.concat(q,h,offsetSegment(A,-a.b,0));r=b();a.v=[p,g,r,u]}else r=b(),p=e(),g=offsetSegment(x,-a.g/2-.06,t-.06).concat(z,offsetSegment(w,
-a.b,0),offsetSegment(C,-a.b+a.g/2+.06,t-.06)),u=l(),a.v=[p,g,r,u];k=offsetSegment(p,a.l,a.i);a.A=[k,mirrorSegmentH(k),rotateSegment180(k),mirrorSegmentV(k)];f?(q=h=1,v=a.h-2,p=a.f-2):(q=h=0,v=a.h-1,p=a.f-1);k=offsetSegment(g,a.l,a.i);y=mirrorSegmentV(k);g=f?-a.b:0;for(var D=q;D<v;D++)a.A.push(offsetSegment(k,g,0),offsetSegment(y,g,0)),g-=a.b;k=offsetSegment(u,a.l,a.i);y=mirrorSegmentH(k);f=f?-a.a:0;for(g=q;g<p;g++)a.A.push(offsetSegment(k,0,f),offsetSegment(y,0,f)),f-=a.a;for(k=q;k<v;k++)for(g=a.l-
k*a.b,q=h;q<p;q++)f=a.i-q*a.a,a.A.push(offsetSegment(r,g,f));return a.A},getPasteArea:function(){var c=calcArea(a.v[0]),d=calcArea(a.v[1]),b=calcArea(a.v[2]),e=calcArea(a.v[3]);return 2==a.C?4*c+d*(a.h-3)*2+b*(a.h-3)*(a.f-3)+e*(a.f-3)*2:4*c+d*(a.h-1)*2+b*(a.h-1)*(a.f-1)+e*(a.f-1)*2},getViaPositions:function(){var c,d,b=[];for(c=0;c<a.h;c+=1){var e=a.l-c*a.b;for(d=0;d<a.f;d+=1){var l=a.i-d*a.a;b.push([e,l])}}return b},getProps:function(){switch(a.w){case 2:var c="dense";break;case 1:c="grid";break;
case 0:c="none"}return{padLength:a.m,padWidth:a.o,viaPitchH:a.b,viaPitchV:a.a,viaRingWidth:a.u,viaDiameter:a.s,maskSwell:a.j,pasteShrink:a.c,pasteSpacing:a.g,viaTenting:a.B,viaLayout:c}},setProps:function(c){function d(a,b,d,e){return c.hasOwnProperty(a)&&(a=parseFloat(c[a]),!isNaN(a))?a<d?d:a>e?e:a:b}a.m=.01*Math.round(100*d("padLength",a.m,1,100));a.o=.01*Math.round(100*d("padWidth",a.o,1,100));a.j=.001*Math.round(1E3*d("maskSwell",a.j,0,1));a.c=.001*Math.round(1E3*d("pasteShrink",a.c,0,.5));a.s=
.01*Math.round(100*d("viaDiameter",a.s,.1,.5));a.u=.001*Math.round(1E3*d("viaRingWidth",a.u,.015,1));a.a=.1*Math.round(10*d("viaPitchV",a.a,.1,a.o/2));a.b=.1*Math.round(10*d("viaPitchH",a.b,.1,a.m/2));c.hasOwnProperty("viaTenting")&&(a.B=1==c.viaTenting);if("string"==typeof c.viaLayout)switch(c.viaLayout.toLowerCase()){case "dense":a.w=2;break;case "grid":a.w=1;break;default:a.w=0}var b=Math.max(a.s/2+(a.B?a.u:0)+a.c+.06);a.g=.01*Math.round(100*d("pasteSpacing",a.g,0,.01*Math.round(100*(1.28*b-.06))));
var e=a.g/2+.06,l=Math.sqrt(b*b-e*e);b=Math.ceil(10*(.02+2*l))/10;a.a<b&&(a.a=b);a.b<b&&(a.b=b);b=a.b;e=a.a;var m=a.m,t=a.o;l=2*(a.c+.08+l);if(1==a.w)a.h=1+Math.floor((m-l)/b),a.f=1+Math.floor((t-l)/e),a.C=1;else if(2==a.w){var n=2*(a.s/2+a.u),f=Math.floor((m-n)/b);n=Math.floor((t-n)/e);a.C=m-f*b>=l&&t-n*e>=l?1:2;a.h=f+1;a.f=n+1}a.l=.5*(a.h-1)*b;a.i=.5*(a.f-1)*e;return a.getProps()}};return a};


/* eslint-enable */
const padD = new PSPadD();
padD.update();
/*
const padDPad = offsetSegment(padD.getPad(), -2.5, 0);
const padDMask = offsetSegment(padD.getSolderMask(), -2.5, 0);
const padDPaste = offsetSegment(padD.getPasteMask(), -2.5, 0);
*/
const pad1 = padD.getPad();
const mask1 = padD.getSolderMask();
const paste1 = padD.getPasteMask();
// 28/4 = 7, pitch 0.5
const pitch = 0.5;
let cy = 0.5 * (7-1) * pitch;
const dPads = new Array(7);
const dSolderMasks = new Array(7);
const dPasteMasks = new Array(7);
for (let j=0; j<7; j++) {
  dPads[j] = offsetSegment(pad1, -2.5, cy);
  dSolderMasks[j] = offsetSegment(mask1, -2.5, cy);
  dPasteMasks[j] = offsetSegment(paste1, -2.5, cy);
  cy -= pitch;
}

const pad2 = reflectSegment45(pad1);
const mask2 = reflectSegment45(mask1);
const paste2 = reflectSegment45(paste1);
let cx = 0.5 * (7-1) * pitch;
const dPads2 = new Array(7);
const dSolderMasks2 = new Array(7);
const dPasteMasks2 = new Array(7);
for (let j=0; j<7; j++) {
  dPads2[j] = offsetSegment(pad2, cx, -2.5);
  dSolderMasks2[j] = offsetSegment(mask2, cx, -2.5);
  dPasteMasks2[j] = offsetSegment(paste2, cx, -2.5);
  cx -= pitch;
}

const pad3 = rotateSegment180(pad1);
const mask3 = rotateSegment180(mask1);
const paste3 = rotateSegment180(paste1);
cy = 0.5 * (7-1) * pitch;
const dPads3 = new Array(7);
const dSolderMasks3 = new Array(7);
const dPasteMasks3 = new Array(7);
for (let j=0; j<7; j++) {
  dPads3[j] = offsetSegment(pad3, 2.5, cy);
  dSolderMasks3[j] = offsetSegment(mask3, 2.5, cy);
  dPasteMasks3[j] = offsetSegment(paste3, 2.5, cy);
  cy -= pitch;
}

const pad4 = rotateSegment180(pad2);
const mask4 = rotateSegment180(mask2);
const paste4 = rotateSegment180(paste2);
cx = 0.5 * (7-1) * pitch;
const dPads4 = new Array(7);
const dSolderMasks4 = new Array(7);
const dPasteMasks4 = new Array(7);
for (let j=0; j<7; j++) {
  dPads4[j] = offsetSegment(pad4, cx, 2.5);
  dSolderMasks4[j] = offsetSegment(mask4, cx, 2.5);
  dPasteMasks4[j] = offsetSegment(paste4, cx, 2.5);
  cx -= pitch;
}


const thermalTab = new PSThermalTab();
<div id="appWindow">
  <nav id="appHeader">
    <a href="#">Libraries</a>
    <a class="active" href="#">QFN-28</a>
    <select style="margin:0.25em;float:right;" onchange="switchMode()" id="viewMode">
      <option value="dark" selected="selected">Dark mode</option>
      <option value="natural">Natural mode</option>
    </select>
  </nav>

  <section id="appMain">
    <aside id="appSidebar">
      <div class="propEditor">
        <form>
          <select>
            <option>E-pad ts315</option>
            <option>Pad D d100_28</option>
          </select>
          <div class="field">
            <label for="fPadLength"><span class="sym">D<sub>2</sub> </span>E-pad length</label>
            <input  id="fPadLength" type="number" min="1" step="0.01" value="3.15"
                   onfocus="dim_highlight('RePG_d_D2')" onblur="dim_unhighlight('RePG_d_D2')">
          </div>
          <div class="field">
            <label for="fPadWidth"><span class="sym">E<sub>2</sub> </span>E-pad width</label>
            <input  id="fPadWidth" type="number" min="1" step="0.01" value="3.15"
                   onfocus="dim_highlight('RePG_d_E2')" onblur="dim_unhighlight('RePG_d_E2')">
          </div>
          <div class="field">
            <label for="fViaDiameter"><span class="sym">ϕV<sub></sub> </span>Via hole diameter</label>
            <input  id="fViaDiameter" type="number" step="0.01" min="0.1" max="0.5" value="0.3"
                   onfocus="dim_highlight('RePG_d_ϕV')" onblur="dim_unhighlight('RePG_d_ϕV')">
          </div>
          <div class="field">
            <label for="fViaPitchH"><span class="sym">d<sub>V</sub> </span>Via horizontal pitch</label>
            <input  id="fViaPitchH" type="number" step="0.1" min="0.1" value="1"
                   onfocus="dim_highlight('RePG_d_dV')" onblur="dim_unhighlight('RePG_d_dV')">
          </div>
          <div class="field">
            <label for="fViaPitchV"><span class="sym">e<sub>V</sub> </span>Via vertical pitch</label>
            <input  id="fViaPitchV" type="number" step="0.1" min="0.1" value="1"
                   onfocus="dim_highlight('RePG_d_eV')" onblur="dim_unhighlight('RePG_d_eV')">
          </div>
          <div class="field">
            <label for="fViaRingWidth"><span class="sym">k<sub>V</sub> </span>Via ring width</label>
            <input  id="fViaRingWidth" type="number" step="0.001" min="0" value="0.08"
                   onfocus="dim_highlight('RePG_d_kV')" onblur="dim_unhighlight('RePG_d_kV')">
          </div>
          <div class="field">
            <label for="fViaTenting"><span class="sym"></span>Via tenting</label>
            <input  id="fViaTenting" type="checkbox" checked>
          </div>
          <div class="field">
            <label for="fViaLayout"><span class="sym"></span>Via layout</label>
            <select id="fViaLayout">
              <option value="grid" dselected="selected">Grid</option>
              <option value="dense">Dense</option>
            </select>
          </div>
          <div class="field">
            <label for="fMaskSwell"><span class="sym">M<sub>1</sub> </span>Solder mask swell</label>
            <input  id="fMaskSwell" type="number" step="0.001" min="0" value="0.075"
                   onfocus="dim_highlight('RePG_d_M1')" onblur="dim_unhighlight('RePG_d_M1')">
          </div>
          <div class="field">
            <label for="fPasteShrink"><span class="sym">P<sub>1</sub> </span>Paste shrink</label>
            <input  id="fPasteShrink"type="number" step="0.001" min="0" value="0.075"
                   onfocus="dim_highlight('RePG_d_P1')" onblur="dim_unhighlight('RePG_d_P1')">
          </div>
          <div class="field">
            <label for="fPasteSpacing"><span class="sym">P<sub>2</sub> </span>Paste window spacing</label>
            <input  id="fPasteSpacing" type="number" step="0.01" min="0" value="0.25"
                   onfocus="dim_highlight('RePG_d_P2')" onblur="dim_unhighlight('RePG_d_P2')">
          </div>
          <div class="action">
            <button type="button" onclick="resetProps()">Reset</button>
            <button type="button" onclick="updateProps()">Update</button>
          </div>
        </form>
      </div>
      <svg id="RePG" class="drdrk" viewBox="-220 -235 470 470" width="300" height="300" style="display:block;margin:auto;">
        <defs>
          <marker id="arrowN" markerWidth="20" markerHeight="8" refX="20" refY="4" orient="auto" markerUnits="userSpaceOnUse">
            <path d="M20 0L0 4 20 8z"/>
          </marker>
          <marker id="arrowH" markerWidth="20" markerHeight="8" refX="20" refY="4" orient="auto" markerUnits="userSpaceOnUse">
            <path d="M20 0L0 4 20 8z"/>
          </marker>
        </defs>
        <rect class="bkground" width="500" height="500" x="-250" y="-250"/>
        <path class="top" d="M158-158L158 158 -158 158 -158-158z"/>
        <path class="mask" d="M295-295L295 295 -295 295 -295-295zM168-168L168 168 -168 168 -168-168zM100-125A25 25 0 0 0 100-75 25 25 0 0 0 100-125zM100-25A25 25 0 0 0 100 25 25 25 0 0 0 100-25zM100 75A25 25 0 0 0 100 125 25 25 0 0 0 100 75zM0-125A25 25 0 0 0 0-75 25 25 0 0 0 0-125zM0-25A25 25 0 0 0 0 25 25 25 0 0 0 0-25zM0 75A25 25 0 0 0 0 125 25 25 0 0 0 0 75zM-100-125A25 25 0 0 0-100-75 25 25 0 0 0-100-125zM-100-25A25 25 0 0 0-100 25 25 25 0 0 0-100-25zM-100 75A25 25 0 0 0-100 125 25 25 0 0 0-100 75z"/>
        <path class="vias" d="M100-115A15 15 0 0 0 100-85 15 15 0 0 0 100-115zM100-15A15 15 0 0 0 100 15 15 15 0 0 0 100-15zM100 85A15 15 0 0 0 100 115 15 15 0 0 0 100 85zM0-115A15 15 0 0 0 0-85 15 15 0 0 0 0-115zM0-15A15 15 0 0 0 0 15 15 15 0 0 0 0-15zM0 85A15 15 0 0 0 0 115 15 15 0 0 0 0 85zM-100-115A15 15 0 0 0-100-85 15 15 0 0 0-100-115zM-100-15A15 15 0 0 0-100 15 15 15 0 0 0-100-15zM-100 85A15 15 0 0 0-100 115 15 15 0 0 0-100 85z"/>
        <path class="paste" d="M147-147L147-113 133-113A35 35 0 0 0 113-133L113-147zM87-147L87-133A35 35 0 0 0 67-113L33-113A35 35 0 0 0 13-133L13-147zM67-87A35 35 0 0 0 87-67L87-33A35 35 0 0 0 67-13L33-13A35 35 0 0 0 13-33L13-67A35 35 0 0 0 33-87zM147-87L147-13 133-13A35 35 0 0 0 113-33L113-67A35 35 0 0 0 133-87zM-147-147L-147-113 -133-113A35 35 0 0 1-113-133L-113-147zM-87-147L-87-133A35 35 0 0 1-67-113L-33-113A35 35 0 0 1-13-133L-13-147zM-67-87A35 35 0 0 1-87-67L-87-33A35 35 0 0 1-67-13L-33-13A35 35 0 0 1-13-33L-13-67A35 35 0 0 1-33-87zM-147-87L-147-13 -133-13A35 35 0 0 1-113-33L-113-67A35 35 0 0 1-133-87zM-147 147L-147 113 -133 113A35 35 0 0 0-113 133L-113 147zM-87 147L-87 133A35 35 0 0 0-67 113L-33 113A35 35 0 0 0-13 133L-13 147zM-67 87A35 35 0 0 0-87 67L-87 33A35 35 0 0 0-67 13L-33 13A35 35 0 0 0-13 33L-13 67A35 35 0 0 0-33 87zM-147 87L-147 13 -133 13A35 35 0 0 0-113 33L-113 67A35 35 0 0 0-133 87zM147 147L147 113 133 113A35 35 0 0 1 113 133L113 147zM87 147L87 133A35 35 0 0 1 67 113L33 113A35 35 0 0 1 13 133L13 147zM67 87A35 35 0 0 1 87 67L87 33A35 35 0 0 1 67 13L33 13A35 35 0 0 1 13 33L13 67A35 35 0 0 1 33 87zM147 87L147 13 133 13A35 35 0 0 1 113 33L113 67A35 35 0 0 1 133 87z"/><path d="M105-100L95-100M100-95L100-105M111-100l22 0M89-100l-22 0M100-89l0 22M100-111l0-22" class="cntline"/><path d="M105 0L95 0M100 5L100-5M111 0l22 0M89 0l-22 0M100 11l0 22M100-11l0-22" class="cntline"/>
        <path d="M105 100L95 100M100 105L100 95M111 100l22 0M89 100l-22 0M100 111l0 22M100 89l0-22" class="cntline"/>
        <path d="M5-100L-5-100M0-95L0-105M11-100l22 0M-11-100l-22 0M0-89l0 22M0-111l0-22" class="cntline"/>
        <path d="M5 0L-5 0M0 5L0-5M11 0l22 0M-11 0l-22 0M0 11l0 22M0-11l0-22" class="cntline"/>
        <path d="M5 100L-5 100M0 105L0 95M11 100l22 0M-11 100l-22 0M0 111l0 22M0 89l0-22" class="cntline"/>
        <path d="M-95-100L-105-100M-100-95L-100-105M-89-100l22 0M-111-100l-22 0M-100-89l0 22M-100-111l0-22" class="cntline"/>
        <path d="M-95 0L-105 0M-100 5L-100-5M-89 0l22 0M-111 0l-22 0M-100 11l0 22M-100-11l0-22" class="cntline"/>
        <path d="M-95 100L-105 100M-100 105L-100 95M-89 100l22 0M-111 100l-22 0M-100 111l0 22M-100 89l0-22" class="cntline"/>
        <g class="dgrp" id="RePG_d_D2">
          <line x1="158" y1="-163" x2="158" y2="-198" class="extline"/>
          <line x1="-157" y1="-163" x2="-157" y2="-198" class="extline"/>
          <line x1="138" y1="-190" x2="21" y2="-190" class="arrowline"/>
          <line x1="-137" y1="-190" x2="-20" y2="-190" class="arrowline"/>
          <text x="0.5" y="-190" class="c">D<tspan class="sub">2</tspan></text>
        </g>
        <g class="dgrp" id="RePG_d_E2">
          <line x1="-162" y1="-158" x2="-198" y2="-158" class="extline"/>
          <line x1="-162" y1="157" x2="-198" y2="157" class="extline"/>
          <line x1="-190" y1="-138" x2="-190" y2="-19" class="arrowline"/>
          <line x1="-190" y1="137" x2="-190" y2="18" class="arrowline"/>
          <text x="-190" y="-0.5" class="c">E<tspan class="sub">2</tspan></text>
        </g>
        <g class="dgrp" id="RePG_d_dV">
          <line x1="100" y1="138" x2="100" y2="198" class="extline"/>
          <line y1="138" y2="198" class="extline"/>
          <line x1="80" y1="190" x2="70" y2="190" class="arrowline"/>
          <line x1="20" y1="190" x2="30" y2="190" class="arrowline"/>
          <text x="50" y="190" class="c">d<tspan class="sub">V</tspan></text>
        </g>
        <g class="dgrp" id="RePG_d_eV">
          <line x1="138" x2="198" class="extline"/>
          <line x1="138" y1="100" x2="198" y2="100" class="extline"/>
          <line x1="190" y1="20" x2="190" y2="31" class="arrowline"/>
          <line x1="190" y1="80" x2="190" y2="69" class="arrowline"/>
          <text x="190" y="50" class="c">e<tspan class="sub">V</tspan></text>
        </g>
        <g class="dgrp" id="RePG_d_kV">
          <line x1="105" y1="-85" x2="198" y2="-85" class="extline"/>
          <line x1="105" y1="-75" x2="198" y2="-75" class="extline"/>
          <line x1="190" y1="-105" x2="190" y2="-115" class="arrowline"/>
          <path d="M190-55l0 10 20 0" class="arrowline"/>
          <text x="215" y="-45" class="l">k<tspan class="sub">V</tspan></text>
        </g>
        <g class="dgrp" id="RePG_d_M1">
          <line x1="168" y1="172" x2="168" y2="198" class="extline"/>
          <line x1="158" y1="162" x2="158" y2="198" class="extline"/>
          <line x1="188" y1="190" x2="198" y2="190" class="arrowline"/>
          <line x1="138" y1="190" x2="128" y2="190" class="arrowline"/>
          <text x="203" y="190" class="l">M<tspan class="sub">1</tspan></text>
        </g>
        <g class="dgrp" id="RePG_d_P1">
          <line x1="153" y1="147" x2="198" y2="147" class="extline"/>
          <line x1="163" y1="157" x2="198" y2="157" class="extline"/>
          <path d="M190 127l0-10 20 0" class="arrowline"/>
          <line x1="190" y1="177" x2="190" y2="187" class="arrowline"/>
          <text x="215" y="117" class="l">P<tspan class="sub">1</tspan></text>
        </g>
        <g class="dgrp" id="RePG_d_P2">
          <line x1="-87" y1="152" x2="-87" y2="198" class="extline"/>
          <line x1="-112" y1="152" x2="-112" y2="198" class="extline"/>
          <line x1="-67" y1="190" x2="-57" y2="190" class="arrowline"/>
          <line x1="-132" y1="190" x2="-142" y2="190" class="arrowline"/>
          <text x="-147" y="190" class="r">P<tspan class="sub">2</tspan></text>
        </g>
        <g class="dgrp" id="RePG_d_ϕV">
          <line x1="70" y1="-81" x2="62" y2="-76" class="arrowline"/>
          <path d="M130-119L180-150 200-150" class="arrowline"/>
          <text x="205" y="-150" class="l">ϕV<tspan class="sub"/></text>
        </g>
      </svg>
    </aside>

    <div id="appContent">
      <svg id="pad" class="drk" viewBox="-3.5 -3.5 7 7">
        <mask id="solderMask">
          <rect id="solderMaskBG" width="200%" height="200%" x="-100%" y="-100%" />
          <g id="solderMaskFG"></g>
        </mask>
        <g id="pl_top" onclick="console.log('top clicked')">
          <rect width="3.15" height="3.15" x="-1.575" y="-1.575"  />
        </g>
        <g id="pl_paste"></g>
        <g id="pl_mask" mask="url(#solderMask)">
          <rect width="200%" height="200%" x="-100%" y="-100%"  />
        </g>
        <g id="pl_assy"></g>
      </svg>
    </div>

    <div style="position:absolute; right:0; display:block;"><!---->
      <div id="layers">
        <input type="checkbox" checked="checked" onchange="toggleLayer('pl_assy',this.checked)"/>
        <span style="color:#8A8A8A">■</span> Assembly<br />
        <input type="checkbox" checked="checked" />
        <span style="color:#00B400">■</span> Silk<br />
        <input type="checkbox" checked="checked" onchange="toggleLayer('pl_mask',this.checked)" />
        <span style="color:#2E4756">■</span> Solder mask<br />
        <input type="checkbox" checked="checked" onchange="toggleLayer('pl_paste',this.checked)" />
        <span style="color:#99842F">■</span> Paste mask<br />
        <input type="checkbox" checked="checked" onchange="toggleLayer('pl_top',this.checked)" />
        <span style="color:#FFFFAA">■</span> Top
      </div>
      <div id="info"></div>
    </div>
  </section>
</div>

<script>

  function toggleLayer(layer, show) {
    document.getElementById(layer).style.display = show?'block':'none';
  }

  window.addEventListener("load", updateProps);

</script>
html, body, #appWindow { height: 100%; }

body {
  margin: 0;
  font-family: Helvetica, Arial, Sans-Serif;
  font-size: 10pt;
}

/*
  appWindow
  - appHeader
  - appMain
    - appSidebar
    - appContent
*/

#appHeader {
  font-size: 12pt;
  height: 2em;
  padding: 0;
  background: #333;
  overflow: hidden;
}
#appMain {
  display: flex;
  height: calc(100% - 2em);
}
#appSidebar {
  overflow-y: auto;
  height: 100%;
  min-width: 300px;
  width: 26em;
}
#appContent {
  height: 100%;
  width: 100%;
  padding: 0;
  margin: 0;
  overflow: hidden;
}

#appHeader a {
  height: 2em;
  float: left;
  color: #f2f2f2;
  text-align: center;
  padding: 0.2em 0.5em;
  text-decoration: none;
}
#appHeader a:hover {
  background-color: #ddd;
  color: black;
}
#appHeader a.active {
  background: #4CAF50;
  color: white;
}

.propEditor {
  background-color:#4CAF50;
  margin: 0;
  padding: 0;
}


#pad {
  display:block;
  margin:0;
  width:100%;
  height: 100%;
}

#info {
  padding: 0.5em;
  border: 1px solid #909090;
  background-color: #f9f966;
}

#layers {
  padding: 0.5em;
  margin-bottom:0.25em;
  border: 1px solid #909090;
  background-color: #e0e0e0;
}

.field {
  display: block;
  padding: 0.2em;
}

.field label {
  display: inline-block;
  width: 15em;
}

.field label .sym {
  display: inline-block;
  width: 2em;
}

.field input[type='number'],
.field input[type='text'],
.field select {
  width: 5em;
  height: 1.2em;
  line-height: 1.2em;
  padding: 0 0.1em;
}

.field input,
.field select {
  vertical-align:middle;
}

.field input:focus,
.field select:focus {
  background-color:#ffa;
}

.field select {
  -webkit-appearance: menulist-button;
  height: 1.5em;
  background: #fff;
  font: inherit;
}

.field input:invalid:not(:focus) {
  background: pink;
}

.field:focus-within {
  background-color: #71c174;
}


.propEditor .action {
  display: block;
  padding: 0.2em;
  text-align: right;
}

.propEditor .action button {
  width: 8em;
  height: 2em;
}

.propEditor .action button:focus {
  background-color:#ffa;
}


#pad {
  fill: none;
  stroke: none;
  stroke-width:0.01;
  /*vector-effect: non-scaling-stroke;*/
}

#pad.drk #solderMask { stroke: none; stroke-width:0.02;}
#pad.drk #pl_top   * { fill: #FFFFAA; stroke: none; }
#pad.drk #pl_mask  * { fill: #2E4756; stroke: none; }
#pad.drk #pl_assy circle { stroke: #8A8A8A; fill: none; stroke-width: 0.02; }
#pad.drk #pl_paste * { fill: #99842F; stroke: none; }
#pad.drk #solderMaskFG { stroke: none; fill: black; }
#pad.drk #solderMaskBG { stroke: none; fill: white; }

#pad.nat #solderMask { stroke: none; stroke-width:0.02;}
#pad.nat #pl_top   * { fill: rgb(252,224,131); stroke: rgb(216,168,5); }
#pad.nat #pl_mask  * { fill: green; stroke: none; opacity:0.4; }
#pad.nat #pl_assy circle { stroke: none; fill: gray; }
#pad.nat #pl_paste * { fill: #c0c0c0; stroke: none; }
#pad.nat #solderMaskFG { stroke: none; fill: black; }
#pad.nat #solderMaskBG { stroke: none; fill: white; }

#arrowN path, #arrowH {
    stroke: none;
}
svg g.dgrp .arrowline {
    marker-start: url("#arrowN");
}
svg g.dgrpH .arrowline {
    marker-start: url("#arrowH");
}
svg .extline {
}
svg .cntline {
}
svg g.dgrp text, svg g.dgrpH text {
    font: 28px serif;
    alignment-baseline: middle;
    stroke: none;
}
svg g.dgrp tspan.sub, svg g.dgrpH tspan.sub {
    font: 21px serif;
    baseline-shift: sub;
}
svg g.dgrp text.l, svg g.dgrpH text.l {
    text-anchor: start;
}
svg g.dgrp text.c, svg g.dgrpH text.c {
    text-anchor: middle;
}
svg g.dgrp text.r, svg g.dgrpH text.r {
    text-anchor: end;
}
svg.drnat {
    stroke: black;
    stroke-width: 2;
    fill: none;
}
svg.drnat .bkground {
    stroke: none;
    fill: none;
}
svg.drnat .top {
    stroke:rgb(216,168,5);
    fill: rgb(252,224,131);
}
svg.drnat .mask {
    stroke: none;
    fill: green;
    fill-rule: evenodd;
    fill-opacity:0.4;
}
svg.drnat .vias {
    stroke: none;
    fill: gray;
}
svg.drnat .paste {
    stroke: none;
    fill: #c0c0c0;
}
svg.drnat .cntline {
    stroke: rgb(0,0,120);
}
svg.drnat #arrowN {
    fill: rgb(0,0,120);
}
svg.drnat g.dgrp {
    stroke: rgb(0,0,120);
}
svg.drnat g.dgrp text {
    fill: rgb(0,0,120);
}
svg.drnat #arrowH {
    fill: rgb(220,0,0);
}
svg.drnat g.dgrpH {
    stroke: rgb(220,0,0);
}
svg.drnat g.dgrpH text {
    fill: rgb(220,0,0);
}
svg.drdrk {
    stroke: white;
    stroke-width: 2;
    fill: none;
}
svg.drdrk .bkground {
    stroke: none;
    fill: black;
}
svg.drdrk .top {
    stroke: #FFFFAA;
    fill: none;
}
svg.drdrk .mask {
    stroke: #2E4756;
    fill: none;
}
svg.drdrk .vias {
    stroke: #8A8A8A;
    fill: none;
}
svg.drdrk .paste {
    stroke: #99842F;
    fill: none;
}
svg.drdrk .cntline {
    stroke: #8A8A8A;
}
svg.drdrk #arrowN {
    fill: #8A8A8A;
}
svg.drdrk g.dgrp {
    stroke: #8A8A8A;
}
svg.drdrk g.dgrp text {
    fill: #8A8A8A;
}
svg.drdrk #arrowH {
    fill: #ffff99;
}
svg.drdrk g.dgrpH {
    stroke: #ffff99;
}
svg.drdrk g.dgrpH text {
    fill: #ffff99;
}