var canvases = new Array;
var canvasesMap = new Array;

utils = {
 browserInfo: {
  matches: {
    webKit: navigator.userAgent.match(/AppleWebKit\/(\d+)/),
    opera: navigator.userAgent.match(/^Opera\/(\d+\.\d+)/),
    mozilla: navigator.userAgent.match(/^Mozilla\/(\d+\.\d+).*\srv:(\d+\.\d+)/),
    firefox: navigator.userAgent.match(/^Mozilla.*Firefox\/(\d+)\./)
  }
 },
 regex: { 
  colors: /\b(blueGrey|dkBlue|dkRed|ltGrey|ltGreyDown|lightToWhite|whiteToLight|pearl|glass|glassGrey|metal|alum|steel)\b/
 }
};

utils.browserInfo.webKit = (utils.browserInfo.matches.webKit != null) ? true : false;
if(utils.browserInfo.webKit == true) { utils.browserInfo.webKitVersion = utils.browserInfo.matches.webKit[1]; }

utils.browserInfo.opera = (utils.browserInfo.matches.opera != null) ? true : false;
if(utils.browserInfo.opera == true) { utils.browserInfo.operaVersion = utils.browserInfo.matches.opera[1]; }

utils.browserInfo.mozilla = (utils.browserInfo.matches.mozilla != null) ? true : false;
if(utils.browserInfo.mozilla == true) { utils.browserInfo.mozillaVersion = utils.browserInfo.matches.mozilla[1]; utils.browserInfo.geckoVersion = utils.browserInfo.matches.mozilla[2]; utils.browserInfo.firefoxVersion = utils.browserInfo.matches.firefox[1]; }

function doBezel(bezelDiv, radius) {
  var cue = canvasUnderElement(bezelDiv, radius, true);
  var w = cue.width, h = cue.height, r = cue.radius, ctx = cue.context;
  cue.clear();

  ctx.save();
  roundedRect(ctx,0,0,w,h,r);
  ctx.fillStyle="rgba(0,0,0,0.2)";
  var lingrad = ctx.createLinearGradient( 0, 0, 0, h);
  lingrad.addColorStop(0.0, 'rgba(0, 0, 0, 0.18)');
  lingrad.addColorStop(0.25, 'rgba(0, 0, 0, 0.20)');
  lingrad.addColorStop(0.66, 'rgba(0, 0, 0, 0.20)');
  lingrad.addColorStop(1.0, 'rgba(0, 0, 0, 0.22)');
  ctx.fillStyle = lingrad;
  ctx.fill();
  ctx.restore();

  ctx.save();
  ctx.translate(0.5,0.5);
  roundedRect(ctx,0,0,w-1,h-1,r);
  lingrad = ctx.createLinearGradient( 0, 0, 0, h);
  lingrad.addColorStop(0.0, 'rgba(0, 0, 0, 0.25)');
  lingrad.addColorStop(r/h, 'rgba(0, 0, 0, 0.175)');
  lingrad.addColorStop((h-r)/h, 'rgba(32, 32, 32, 0.15)');
  lingrad.addColorStop((h-1)/h, 'rgba(255, 255, 255, 0.66)');
  lingrad.addColorStop(1.0, 'rgba(255, 255, 255, 0.66)');
  ctx.strokeStyle = lingrad;
  ctx.stroke();
  ctx.restore();
}

function doSky(skyDiv) {
  var radius = (parseInt(document.defaultView.getComputedStyle(skyDiv, null).height.match(/(\d+)/)[1]) / 2) - 0;
  var cue = canvasUnderElement(skyDiv, radius, true);
  var w = cue.width, h = cue.height, r = cue.radius, ctx = cue.context, lingrad;
  cue.clear();

  ctx.save();
  roundedRect(ctx,0,0,w,h,r);
  lingrad = ctx.createLinearGradient( 0, 0, 0, h);
  lingrad.addColorStop(0.0, 'rgba(155, 194, 229, 1.0)');
  lingrad.addColorStop(1.0/h, 'rgba(155, 194, 229, 1.0)');
  lingrad.addColorStop(0.3, 'rgba(160, 202, 237, 1.0)');
  lingrad.addColorStop(0.45, 'rgba(160, 202, 237, 1.0)');
  lingrad.addColorStop(0.45, 'rgba(117, 174, 224, 1.0)');
  lingrad.addColorStop(0.7, 'rgba(117, 174, 224, 1.0)');
  lingrad.addColorStop(1.0-(2.0/h), 'rgba(131, 198, 233, 1.0)');
  lingrad.addColorStop(1.0, 'rgba(131, 198, 233, 1.0)');
  ctx.fillStyle = lingrad;
  ctx.fill();
  ctx.restore();
  delete(lingrad);

  ctx.save();
  ctx.translate(0.5,0.5);
  roundedRect(ctx,0,0,w-1,h-1,r);
  lingrad = ctx.createLinearGradient( 0, 0, 0, h);
  lingrad.addColorStop(0.0, 'rgba(71,111,152, 1)');
  lingrad.addColorStop(0.5, 'rgba(96, 139, 183, 1)');
  lingrad.addColorStop(1.0, 'rgba(113, 169, 218, 1)');
  ctx.strokeStyle = lingrad;
  ctx.stroke();
  ctx.restore();
  delete(lingrad);

  ctx.save();
  ctx.translate(0.5,0.5);
  roundedRect(ctx,0,0,w-1,h-1,r);
  ctx.clip();
  roundedRect(ctx,0,0,w-1,h-1,r);
  lingrad = ctx.createLinearGradient( 0, 0, 0, h);
  lingrad.addColorStop(0.0, 'rgba(71,111,152, 0.95)');
  lingrad.addColorStop(0.5, 'rgba(96, 139, 183, 0.35)');
  lingrad.addColorStop(1.0, 'rgba(113, 169, 218, 0)');
  ctx.strokeStyle = lingrad;
  ctx.lineWidth = 3;
  ctx.stroke();
  ctx.restore();
  delete(lingrad);
}

function doPearlButton(pearlButtonDiv) {
  var radius = (parseInt(document.defaultView.getComputedStyle(pearlButtonDiv, null).height.match(/(\d+)/)[1]) / 2) - 0;
  var cue = canvasUnderElement(pearlButtonDiv, radius, true);
  var w = cue.width, h = cue.height, r = cue.radius, ctx = cue.context, lingrad;
  cue.clear();
  cue.addShadow(1, 1, 1, "rgba(255, 255, 255, 0.175)");

  ctx.save();
  roundedRect(ctx,0.5,0,w-1.0,h+0,r);
  ctx.clip();
  roundedRect(ctx,0,0,w-0,h-0,r);
  lingrad = ctx.createLinearGradient( 0, 0, 0, h);
  lingrad.addColorStop(0.0, 'rgba(0, 0, 0, 0.0375)');
  lingrad.addColorStop(1.0/h, 'rgba(0, 0, 0, 0.0375)');
  lingrad.addColorStop(0.33, 'rgba(0, 0, 0, 0.0)');
  lingrad.addColorStop(0.75, 'rgba(0, 0, 0, 0.0)');
  lingrad.addColorStop(1.0-(1.0/h), 'rgba(0, 0, 0, 0.11)');
  lingrad.addColorStop(1.0, 'rgba(0, 0, 0, 0.11)');
  ctx.fillStyle = lingrad;
  ctx.fill();
  ctx.restore();
  delete(lingrad);

  ctx.save();
  roundedRect(ctx,0,1,w,h-2,r);
  lingrad = ctx.createLinearGradient( 0, 1, 0, h-2);
  lingrad.addColorStop(0.0, 'rgba(255, 255, 255, 1.0)');
  lingrad.addColorStop(1.0/h, 'rgba(255, 255, 255, 1.0)');
  lingrad.addColorStop(1.0, 'rgba(210, 210, 210, 1.0)');
  ctx.fillStyle = lingrad;
  ctx.fill();
  ctx.restore();
  delete(lingrad);

  ctx.save();
  ctx.translate(0.5,0.5);
  roundedRect(ctx,0,1,w-1,h-3,r);
  lingrad = ctx.createLinearGradient( 0, 1, 0, h-2);
  lingrad.addColorStop(0.0, 'rgba(223, 223, 223, 1)');
  lingrad.addColorStop(0.5, 'rgba(228, 228, 228, 1)');
  lingrad.addColorStop(1.0-(2.0/h), 'rgba(201, 201, 201, 1)');
  lingrad.addColorStop(1.0, 'rgba(201, 201, 201, 1)');
  ctx.strokeStyle = lingrad;
  ctx.stroke();
  ctx.restore();
  delete(lingrad);
}

function doRSSFeedIcon(rssFeedIconDiv) {
  var radius = Math.max(1, Math.floor((parseInt(document.defaultView.getComputedStyle(rssFeedIconDiv, null).height.match(/(\d+)/)[1]) * (1.9/13.0)) - 0));
  var cue = canvasUnderElement(rssFeedIconDiv, radius, true);
  cue.setPad(2,2);
  cue.setDeltaXY(-1,-1);
  var w = cue.width, h = cue.height, r = cue.radius, ctx = cue.context, lingrad;
  var cw = cue.width-1, ch = cue.height+1;
  cue.clear();

  ctx.save();
  ctx.moveTo(-1,-1);
  ctx.lineTo(-1,h+1);
  ctx.lineTo(w+1,-1);
  ctx.lineTo(-1,-1);
  ctx.clip();
  roundedRect(ctx,-1,-1,w+2,h+2,r+1);
  ctx.fillStyle = "rgba(200,200,200,0.5)";
  ctx.fill();
  ctx.restore();

  ctx.save();
  ctx.moveTo(w+1,h+1);
  ctx.lineTo(-1,h+1);
  ctx.lineTo(w+1,-1);
  ctx.lineTo(w+1,h+1);
  ctx.clip();
  roundedRect(ctx,-1,-1,w+2,h+2,r+1);
  ctx.fillStyle = "rgba(255,255,255,0.5)";
  ctx.fill();
  ctx.restore();

  ctx.save();
  roundedRect(ctx,0,0,w,h,r);
  lingrad = ctx.createLinearGradient( 0, 0, 0, h);
  lingrad.addColorStop(0.0, 'rgba(238, 150, 89, 1.0)');
  lingrad.addColorStop(1.0/h, 'rgba(238, 150, 89, 1.0)');
  lingrad.addColorStop(1.0/h, 'rgba(235, 140, 73, 1.0)');
  lingrad.addColorStop(1.0-(1.0/h), 'rgba(235, 113, 26, 1.0)');
  lingrad.addColorStop(1.0-(1.0/h), 'rgba(235, 99, 0, 1.0)');
  lingrad.addColorStop(1.0, 'rgba(235, 99, 0, 1.0)');
  ctx.fillStyle = lingrad;
  ctx.fill();
  ctx.restore();
  delete(lingrad);
}

function doRSSGraphic(rssGraphicDiv) {
  if(utils.browserInfo.opera == true) { rssGraphicDiv.style.position = "absolute"; rssGraphicDiv.style.height = "1.2em"; rssGraphicDiv.style.width = "1ex"; rssGraphicDiv.parentNode.style.paddingRight = "3ex"; }
  var cue = canvasUnderElement(rssGraphicDiv, 0, true);
  if(utils.browserInfo.mozilla == true) { cue.setSize(cue.element.offsetHeight, cue.element.offsetHeight); }
  else { cue.setSize(cue.height, cue.height); }
  cue.canvas.style.zIndex = 2;
  var w = cue.width, h = cue.height, r = cue.radius, ctx = cue.context, lingrad;

  ctx.save();
  ctx.arc( (68.0/256.0)*h, (189.0/256.0)*h, (24.0/256.0)*h, 0, Math.PI * 2.0, 0);

  ctx.moveTo( (160.0/256.0)*h, (213.0/256.0)*h);
  ctx.lineTo( (126.0/256.0)*h, (213.0/256.0)*h);
  ctx.quadraticCurveTo( (126.0/256.0)*h, (131.0/256.0)*h, (44.0/256.0)*h, (131.0/256.0)*h);
  ctx.lineTo( (44.0/256.0)*h, (97.0/256.0)*h);
  ctx.quadraticCurveTo( (160.0/256.0)*h, (97.0/256.0)*h, (160.0/256.0)*h, (213.0/256.0)*h);

  ctx.moveTo( (184.0/256.0)*h, (213.0/256.0)*h);
  ctx.quadraticCurveTo( (184.0/256.0)*h, (73.0/256.0)*h, (44.0/256.0)*h, (73.0/256.0)*h);
  ctx.lineTo( (44.0/256.0)*h, (39.0/256.0)*h);
  ctx.quadraticCurveTo( (219.0/256.0)*h, (39.0/256.0)*h, (219.0/256.0)*h, (213.0/256.0)*h);

  ctx.shadowColor = "rgba(0,0,0,0.15)";
  ctx.shadowOffsetX = 1;
  ctx.shadowOffsetY = 1;
  ctx.shadowBlur = 0;
  ctx.fillStyle="#fff";
  ctx.fill();
  ctx.restore();
}

function doCharcoal(charcoalDiv) {
  var radius = (parseInt(document.defaultView.getComputedStyle(charcoalDiv, null).height.match(/(\d+)/)[1]) / 2) - 0;
  var cue = canvasUnderElement(charcoalDiv, radius, true);
  var w = cue.width, h = cue.height, r = cue.radius, ctx = cue.context, lingrad;
  cue.clear();
  cue.addShadow(0, 1, 2, "rgba(0, 0, 0, 0.4)");

  ctx.save();
  roundedRect(ctx,0,0,w,h,r);
  lingrad = ctx.createLinearGradient( 0, 0, 0, h);
  lingrad.addColorStop(0.0, 'rgba(196, 196, 196, 1.0)');
  lingrad.addColorStop(1.0, 'rgba(138, 138, 138, 1.0)');
  ctx.fillStyle = lingrad;
  ctx.fill();
  ctx.restore();
  delete(lingrad);

  ctx.save();
  ctx.translate(0.5,0.5);
  roundedRect(ctx,0,0,w-1,h-1,r);
  ctx.clip();
  roundedRect(ctx,0,0,w-1,h-1,r);
  lingrad = ctx.createLinearGradient( 0, 0, 0, h);
  lingrad.addColorStop(0.0, 'rgba(236,236,236, 0.5)');
  lingrad.addColorStop(0.33, 'rgba(236,236,236, 0.25)');
  lingrad.addColorStop(0.50, 'rgba(236, 236, 236, 0)');
  ctx.strokeStyle = lingrad;
  ctx.lineWidth = 3;
  ctx.stroke();
  ctx.restore();
  delete(lingrad);

  ctx.save();
  ctx.translate(0.5,0.5);
  roundedRect(ctx,0,0,w-1,h-1,r);
  lingrad = ctx.createLinearGradient( 0, 0, 0, h);
  lingrad.addColorStop(0.0, 'rgba(185, 185, 185, 1)');
  lingrad.addColorStop(1.0, 'rgba(113, 113, 113, 1)');
  ctx.strokeStyle = lingrad;
  ctx.stroke();
  ctx.restore();
  delete(lingrad);
}

function doOcean(oceanDiv) {
  var radius = (parseInt(document.defaultView.getComputedStyle(oceanDiv, null).height.match(/(\d+)/)[1]) / 2) - 0;
  var cue = canvasUnderElement(oceanDiv, radius, true);
  var w = cue.width, h = cue.height, r = cue.radius, ctx = cue.context, lingrad;
  cue.clear();
  cue.addShadow(0, 1, 2, "rgba(0, 0, 0, 0.5)");

  ctx.save();
  roundedRect(ctx,0,0,w,h,r);
  var lingrad = ctx.createLinearGradient( 0, 0, 0, h);
  lingrad.addColorStop(0.0, 'rgba(64, 138, 197, 1.0)');
  lingrad.addColorStop(1.0, 'rgba(46, 101, 144, 1.0)');
  ctx.fillStyle = lingrad;
  ctx.fill();
  ctx.restore();
  delete(lingrad);

  ctx.save();
  ctx.translate(0.5,0.5);
  roundedRect(ctx,0,0,w-1,h-1,r);
  lingrad = ctx.createLinearGradient( 0, 0, 0, h);
  lingrad.addColorStop(0.0, 'rgba(105, 164, 210, 1)');
  lingrad.addColorStop(0.5, 'rgba(50, 113, 165, 1)');
  lingrad.addColorStop(1.0, 'rgba(38, 89, 131, 1)');
  ctx.strokeStyle = lingrad;
  ctx.stroke();
  ctx.restore();
  delete(lingrad);
}

function doInsetBox(insetBoxDiv, radius) {
    var cue = canvasUnderElement(insetBoxDiv, radius, true);
    var w = cue.width, h = cue.height, r = cue.radius, ctx = cue.context, lingrad;
    cue.canvas.style.zIndex = -5;
    cue.clear();
 
    ctx.save();
    roundedRect(ctx,0,0,w,h,r);
    ctx.fillStyle="rgba(0,0,0,0.03)";
    ctx.fill();
    ctx.restore();
 
    ctx.save();
    ctx.translate(0.5,0.5);
    ctx.beginPath();
    ctx.moveTo(1,r-1.0);
    ctx.quadraticCurveTo(1.5,1.5,r-1,1);
    ctx.lineTo(w-r-0, 1);
    ctx.quadraticCurveTo(w-2.5,1.5,w-2,r-1);
    ctx.strokeStyle="rgba(0,0,0,0.16)";
    ctx.stroke();
    ctx.restore();

    ctx.save();
    ctx.translate(0.5,0.5);
    ctx.beginPath();
    ctx.moveTo(1,r-1.0);
    ctx.quadraticCurveTo(2.5,2.5,r-2,2);
    ctx.lineTo(w-r+0, 2);
    ctx.quadraticCurveTo(w-3.5,1.5,w-3,r-1);
    ctx.strokeStyle="rgba(0,0,0,0.05)";
    ctx.stroke();
    ctx.restore();

    ctx.save();
    ctx.translate(0.5,0.5);
    ctx.beginPath();
    ctx.moveTo(1,r);
    ctx.lineTo(1, h-r-1);
    ctx.strokeStyle="rgba(0,0,0,0.025)";
    ctx.stroke();
    ctx.restore();

    ctx.save();
    ctx.translate(0.5,0.5);
    ctx.beginPath();
    ctx.moveTo(w-2,r);
    ctx.lineTo(w-2, h-r-1);
    ctx.strokeStyle="rgba(255,255,255,0.025)";
    ctx.stroke();
    ctx.restore();

    ctx.save();
    ctx.translate(0.5,0.5);
    roundedRect(ctx,0,0,w-1,h-1,r);
    lingrad = ctx.createLinearGradient( 0, 0, 0, h);
    lingrad.addColorStop(0.0, 'rgba(0, 0, 0, 0.25)');
    lingrad.addColorStop(Math.min(r/h, 1.0), 'rgba(0, 0, 0, 0.15)');
    lingrad.addColorStop(Math.min(Math.max((h-r), 0)/h, 1.0), 'rgba(0, 0, 0, 0.14)');
    lingrad.addColorStop(Math.min((h-1)/h, 1.0), 'rgba(0,0,0, 0.08)');
    lingrad.addColorStop(1.0, 'rgba(0,0,0, 0.08)');
    ctx.strokeStyle = lingrad;
    ctx.stroke();
    ctx.restore();
  delete(lingrad);
}

function doInsetLightenBox(insetBoxDiv, radius) {
    var cue = canvasUnderElement(insetBoxDiv, radius, true);
    var w = cue.width, h = cue.height, r = cue.radius, ctx = cue.context, lingrad;
    cue.clear();
 
    ctx.save();
    roundedRect(ctx,0,0,w,h,r);
    ctx.fillStyle="rgba(255,255,255,0.10)";
    ctx.fill();
    ctx.restore();
 
    ctx.save();
    ctx.translate(0.5,0.5);
    ctx.beginPath();
    ctx.moveTo(1,r-1.0);
    ctx.quadraticCurveTo(1.5,1.5,r-1,1);
    ctx.lineTo(w-r-0, 1);
    ctx.quadraticCurveTo(w-2.5,1.5,w-2,r-1);
    ctx.strokeStyle="rgba(255,255,255,0.16)";
    ctx.stroke();
    ctx.restore();


    ctx.save();
    ctx.translate(0.5,0.5);
    ctx.beginPath();
    ctx.moveTo(1,r-1.0);
    ctx.quadraticCurveTo(2.5,2.5,r-2,2);
    ctx.lineTo(w-r+0, 2);
    ctx.quadraticCurveTo(w-3.5,1.5,w-3,r-1);
    ctx.strokeStyle="rgba(255,255,255,0.05)";
    ctx.stroke();
    ctx.restore();

    ctx.save();
    ctx.translate(0.5,0.5);
    ctx.beginPath();
    ctx.moveTo(1,r);
    ctx.lineTo(1, h-r-1);
    ctx.strokeStyle="rgba(255,255,255,0.025)";
    ctx.stroke();
    ctx.restore();

    ctx.save();
    ctx.translate(0.5,0.5);
    ctx.beginPath();
    ctx.moveTo(w-2,r);
    ctx.lineTo(w-2, h-r-1);
    ctx.strokeStyle="rgba(255,255,255,0.025)";
    ctx.stroke();
    ctx.restore();

    ctx.save();
    ctx.translate(0.5,0.5);
    roundedRect(ctx,0,0,w-1,h-1,r);
    lingrad = ctx.createLinearGradient( 0, 0, 0, h);
    lingrad.addColorStop(0.0, 'rgba(0, 0, 0, 0.25)');
    lingrad.addColorStop(r/h, 'rgba(0, 0, 0, 0.15)');
    lingrad.addColorStop((h-r)/h, 'rgba(0, 0, 0, 0.14)');
    lingrad.addColorStop((h-1)/h, 'rgba(0,0,0, 0.08)');
    lingrad.addColorStop(1.0, 'rgba(0,0,0, 0.08)');
    ctx.strokeStyle = lingrad;
    ctx.stroke();
    ctx.restore();
  delete(lingrad);
}

function doButton(buttonDiv) {
  var cue = canvasUnderElement(buttonDiv, 8, true);
  var w = cue.width + cue.borderLeft + cue.borderRight, h = cue.height + cue.borderTop + cue.borderBottom, r = cue.radius, ctx = cue.context, lingrad
  cue.clear();
  cue.addShadow(1, 3, 8, "rgba(0, 0, 0, 0.75)");

  ctx.save();
  lingrad = ctx.createLinearGradient( 0, 0, 0, h);
  lingrad.addColorStop(0.0, 'rgba(167, 167, 167, 1)');
  lingrad.addColorStop(1.0, 'rgba(77, 77, 77, 1)');
  ctx.fillStyle = lingrad;
  roundedRect(ctx,0,0,w,h,r);
  ctx.fill();
  ctx.restore();
  delete(lingrad);

  ctx.save();
  ctx.translate(0.5, 0.5);
  lingrad = ctx.createLinearGradient( 0, 0, 0, h);
  lingrad.addColorStop(0.0, 'rgba(129, 129, 129, 1)');
  lingrad.addColorStop(1.0, 'rgba(72, 72, 72, 1)');
  ctx.strokeStyle = lingrad;
  roundedRect(ctx,0,0,w-1,h-1,r-1.0);
  ctx.stroke();
  ctx.restore();
  delete(lingrad);
}

function doBadge(badgeDiv) {
  var cue = canvasUnderElement(badgeDiv, 4, true);
  var w = cue.width, h = cue.height, r = cue.radius, ctx = cue.context, lingrad;
  cue.clear();
  cue.addShadow(0, 1, 1, "rgba(0, 0, 0, 0.5)");

  if(badgeDiv.className.search(/\bblue\b/) != -1) {
      ctx.save();
      lingrad = ctx.createLinearGradient(0,0,0,h);
      lingrad.addColorStop(0.00, 'rgba( 94, 117, 152, 1)');
      lingrad.addColorStop(1.0/h,'rgba(169, 181, 200, 1)');
      lingrad.addColorStop(2.0/h,'rgba(153, 168, 190, 1)');
      lingrad.addColorStop(4.0/h,'rgba(102, 124, 157, 1)');
      lingrad.addColorStop(5.0/h,'rgba( 91, 115, 150, 1)');
      lingrad.addColorStop(0.25,'rgba( 76, 102, 141, 1)');
      lingrad.addColorStop(0.5,'rgba( 61,  89, 131, 1)');
      lingrad.addColorStop(0.75, 'rgba( 44,  74, 120, 1)');
      lingrad.addColorStop(1.00-((1.0/h)*2), 'rgba( 34,  66, 114, 1)');
      lingrad.addColorStop(1.00, 'rgba( 34,  66, 114, 1)');
      ctx.fillStyle = lingrad;
      roundedRect(ctx,0,0,w,h,r);
      ctx.fill();
      ctx.restore();
  delete(lingrad);
  } else {
      ctx.save();
      lingrad = ctx.createLinearGradient(0,0,0,h);
      lingrad.addColorStop(0.0, 'rgba( 219,  74, 48, 1)');
      lingrad.addColorStop(1.0/h,'rgba(219, 185, 181, 1)');
      lingrad.addColorStop(3.0/h,'rgba(219, 142, 133, 1)');
      lingrad.addColorStop(4.0/h,'rgba(219, 128, 117, 1)');
      lingrad.addColorStop(5.0/h, 'rgba( 219,  41, 22, 1)');
      lingrad.addColorStop(0.5, 'rgba( 188,  19, 0, 1)');
      lingrad.addColorStop(1.00-((1.0/h)*2), 'rgba( 160,  17, 0, 1)');
      lingrad.addColorStop(1.00-((1.0/h)*2), 'rgba( 150,  16, 0, 1)');
      lingrad.addColorStop(1.00, 'rgba( 120,  13, 0, 1)');
      ctx.fillStyle = lingrad;
      roundedRect(ctx,0,0,w,h,r);
      ctx.fill();
      ctx.restore();
  delete(lingrad);
      
      ctx.save();
      ctx.beginPath();
      ctx.moveTo(0,0);
      ctx.lineTo(0,(r/2)+(r/4));
      ctx.lineTo(r,r);
      ctx.lineTo(w-r,r);
      ctx.lineTo(w,(r/2)+(r/4));
      ctx.lineTo(w,0);
      ctx.lineTo(0,0);
      ctx.moveTo(0,0);
      ctx.lineTo(w,0);
      ctx.lineTo(w,h);
      ctx.lineTo(0,h);
      ctx.lineTo(0,0);
      ctx.clip();
      innerShadow(ctx,0,0,w,h,r,'rgba(0,0,0,0.5)',0,0,3,"#fff");
      ctx.restore();
  }
}


function doAlphaFadeTopAndBottom(alphaFadeTopAndBottomDiv, r, clr) {
  var cue = canvasUnderElement(alphaFadeTopAndBottomDiv, r, true);
  var w = cue.width, h = cue.height, r = cue.radius, ctx = cue.context, lingrad;
  cue.canvas.style.zIndex = -7;
  if(clr != true) { cue.clear(); }

  ctx.save();
  roundedRect(ctx,0,0,w,h,r);
  lingrad = ctx.createLinearGradient(0,0,0,h);
  lingrad.addColorStop(0.0, 'rgba(135,145,165,0.10)');
  lingrad.addColorStop(0.33, 'rgba(135,145,165,0.0)');
  lingrad.addColorStop(0.66, 'rgba(135,145,165,0.0)');
  lingrad.addColorStop(1.0, 'rgba(135,145,165,0.08)');
  ctx.fillStyle = lingrad;
  ctx.fill();
  delete(lingrad);

  ctx.translate(0.5, 0.5);
  roundedRect(ctx,0,0,w-1,h-1,r);
  lingrad = ctx.createLinearGradient(0,0,0,h-1);
  lingrad.addColorStop(0.0, 'rgba(100,110,110,0.20)');
  lingrad.addColorStop(0.33, 'rgba(100,110,110,0.0)');
  lingrad.addColorStop(0.66, 'rgba(100,110,110,0.0)');
  lingrad.addColorStop(1.0, 'rgba(100,110,110,0.20)');
  ctx.strokeStyle = lingrad;
  ctx.stroke();
  delete(lingrad);

  ctx.restore();
}

function doAlphaFadeTop(alphaFadeTopDiv, r, clr) {
  var cue = canvasUnderElement(alphaFadeTopDiv, r, true);
  var w = cue.width, h = cue.height, r = cue.radius, ctx = cue.context, lingrad;
  cue.canvas.style.zIndex = -7;
  if(clr != true) { cue.clear(); }

  ctx.save();
  roundedRect(ctx,0,0,w,h,r);
  lingrad = ctx.createLinearGradient(0,0,0,h);
  lingrad.addColorStop(0, 'rgba(135,145,165,0.55)');
  lingrad.addColorStop(1.0, 'rgba(135,145,165,0.0)');
  ctx.fillStyle = lingrad;
  ctx.fill();
  ctx.fillStyle = lingrad;
  ctx.fillRect(0,h-r,w,r)
  ctx.restore();
  delete(lingrad);
}

function doAlphaFadeBottom(alphaFadeBottomDiv, r, clr) {
  var cue = canvasUnderElement(alphaFadeBottomDiv, r, true);
  var w = cue.width, h = cue.height, r = cue.radius, ctx = cue.context, lingrad;
  cue.canvas.style.zIndex = -8;
  if(clr != true) { cue.clear(); }

  ctx.save();
  lingrad = ctx.createLinearGradient(0,0,0,h);
  lingrad.addColorStop(0, 'rgba(0,0,0,0)');
  lingrad.addColorStop(1.0, 'rgba(0,0,0,0.10)');
  ctx.fillStyle = lingrad;
  roundedRect(ctx,0,0,w,h,r);
  ctx.fill();
  ctx.restore();
  delete(lingrad);

  ctx.save();
  ctx.translate(0.5, 0.5);
  roundedRect(ctx,0,0,w-1,h-1,r);
  lingrad = ctx.createLinearGradient(0,0,0,h-1);
  lingrad.addColorStop(0, 'rgba(0,0,0,0)');
  lingrad.addColorStop(1.0, 'rgba(0,0,0,0.1)');
  ctx.strokeStyle = lingrad;
  ctx.stroke();
  ctx.restore();
  delete(lingrad);
}

function doTopFadeIn(topFadeInDiv, h) {
  var cue = canvasUnderElement(topFadeInDiv, r, true);
  var w = cue.width, h = cue.height, r = cue.radius, ctx = cue.context, lingrad;
  cue.canvas.style.zIndex = -2;
  cue.clear();

  ctx.save();
  lingrad = ctx.createLinearGradient(0,0,0,h);
  lingrad.addColorStop(0.0, 'rgba(0,28,75,0.15)');
  lingrad.addColorStop(1.0, 'rgba(0,28,75,0.0)');
  ctx.fillStyle = lingrad;
  ctx.fillRect(0,0,w,h);
  ctx.restore();
  delete(lingrad);
}

function doBoxTitled(boxTitledDiv) {
  var box = boxTitledDiv, title, content;
  var childArray = box.childNodes;
  
  for(var x=0; x<childArray.length; x++) {
    if(childArray[x].nodeType != 1) { continue; }
    if(childArray[x].className.search(/\btitle\b/) != -1) { title = childArray[x]; continue; }
    if(childArray[x].className.search(/\bcontents\b/) != -1) { content = childArray[x]; continue; }
  }

  var titleColor = title.className.match(utils.regex.colors)[1];
  var r = Math.round(title.clientHeight * 0.25);

  if(titleColor == "steel") { if(boxTitledDiv.className.search(/\btiny\b/) != -1) { r = Math.round(title.clientHeight * (2.0/16.0)); } else { r = Math.round(title.clientHeight * (4.0/21.0)); } }
  if(boxTitledDiv.className.search(/\bbanner\b/) != -1) { r = 5; }

  var cue = canvasUnderElement(boxTitledDiv, r, true);
  cue.canvas.style.zIndex = -2;
  cue.clear();
  if(titleColor == "alum") { cue.addShadow(0, 1, 1, "rgba(0, 0, 0, 0.15)");}
  else if(titleColor == "steel") { cue.addShadow(0, 1, 2, "rgba(0, 0, 0, 0.15)");}
  else { cue.addShadow(1, 1, 2, "rgba(0, 0, 0, 0.15)"); }

  var titleCue = canvasUnderElement(title, 0, true);
  titleCue.parent = cue;
  titleCue.clear();
  drawBoxTitle(title, titleCue.canvas, titleCue);

  var contentCue = canvasUnderElement(content, 0, true);
  contentCue.parent = cue;
  contentCue.clear();
  drawBoxContent(content, contentCue.canvas, contentCue);
}

function drawBoxTitle(titleDiv, titleCanvas, titleCue) {
  var w = titleCue.width, h = titleCue.height, r = titleCue.parent.radius;
  var ctx = titleCanvas.getContext('2d');

  var titleColor = titleDiv.className.match(utils.regex.colors)[1];

  var lingrad = ctx.createLinearGradient(0,0,0,h*2);
  var shadowColor = "#000", shadowWidth = 0, borderColor = "", borderBottomColor = "";

  if(titleColor == "blueGrey") {
      lingrad.addColorStop(0.0, 'rgba(162, 170, 186, 1)');
      lingrad.addColorStop(0.5, 'rgba(114, 131, 157, 1)');
      shadowColor = "rgba(0,0,0,0.5)";
      shadowWidth = Math.ceil(h/5);
  } else if(titleColor == "metal") {
      lingrad.addColorStop(0.0, 'rgb(223, 223, 223)');
      lingrad.addColorStop(0.5, 'rgb(206, 206, 206)');
      borderBottomColor = "#afafaf";
      borderColor = ctx.createLinearGradient(0,0,0,h);
      borderColor.addColorStop(0, 'rgba(238, 238, 238, 1)');
      borderColor.addColorStop((r-0)/h, 'rgba(216, 216, 216, 1)');
      borderColor.addColorStop(1.0-(1.0/h), 'rgba(194, 194, 194,1)');
      borderColor.addColorStop(1.0, 'rgba(194, 194, 194,1)');
  } else if(titleColor == "alum") {
      lingrad.addColorStop(0.0, 'rgb(255, 255, 255)');
      lingrad.addColorStop(0.5, 'rgb(224, 224, 224)');
      borderBottomColor = "#bcbcbc";
      borderColor = ctx.createLinearGradient(0,0,0,h);
      borderColor.addColorStop(0, 'rgba(245, 245, 245, 1)');
      borderColor.addColorStop((r-0)/h, 'rgba(234, 234, 234, 1)');
      borderColor.addColorStop(1.0-(1.0/h), 'rgba(201, 201, 201,1)');
      borderColor.addColorStop(1.0, 'rgba(188, 188, 188,1)');
  } else if(titleColor == "steel") {
      lingrad.addColorStop(0.0, 'rgb(197, 197, 197)');
      lingrad.addColorStop(0.5/h, 'rgb(197, 197, 197)');
      lingrad.addColorStop(0.5-(0.5/h), 'rgb(150, 150, 150)');
      lingrad.addColorStop(0.5, 'rgb(150, 150, 150)');
      borderBottomColor = "#bcbcbc";
      borderColor = ctx.createLinearGradient(0,0,0,h);
      borderColor.addColorStop(0, 'rgba(220, 220, 220, 1)');
      borderColor.addColorStop((r+0)/h, 'rgba(200, 200, 200, 1)');
      borderColor.addColorStop((r+1)/h, 'rgba(190, 190, 190, 0)');
      borderColor.addColorStop(1.0-(1.0/h), 'rgba(152, 152, 152,0)');
      borderColor.addColorStop(1.0, 'rgba(152,152, 152,0)');
      borderBottomColor = "#888";
  } else if(titleColor == "dkRed") {
      lingrad.addColorStop(0.0, 'rgba(140, 96, 91, 1)');
      lingrad.addColorStop(0.0125, 'rgba(145, 100, 94, 1)');
      lingrad.addColorStop(0.33, 'rgba(117, 43, 35, 1)');
      lingrad.addColorStop(0.5, 'rgba(115, 42, 34, 1)');
  } else if(titleColor == "dkBlue") {
      lingrad.addColorStop(0.0, 'rgba(91, 111, 141, 1)');
      lingrad.addColorStop(0.0125, 'rgba(96, 117, 148, 1)');
      lingrad.addColorStop(0.33, 'rgba(37, 71, 122, 1)');
      lingrad.addColorStop(0.5, 'rgba(34, 66, 114, 1)');
      shadowColor = "rgba(0,0,0,0.55)";
      shadowWidth = Math.ceil(h/5);
  } else if(titleColor == "pearl") {
      lingrad.addColorStop(0.0, 'rgba(247, 247, 247, 1)');
      lingrad.addColorStop(0.425, 'rgba(231, 231, 231, 1)');
      lingrad.addColorStop(0.5, 'rgba(231, 231, 231, 1)');
      shadowColor = "rgba(0,0,0,0.2)";
      shadowWidth = Math.ceil(h/8);
  } else if(titleColor == "glass") {
      lingrad.addColorStop(0.0, 'rgba(248, 248, 249, 1)');
      lingrad.addColorStop(0.075, 'rgba(238, 239, 240, 1)');
      lingrad.addColorStop(0.15, 'rgba(227, 229, 230, 1)');
      lingrad.addColorStop(0.15, 'rgba(221, 223, 225, 1)');
      lingrad.addColorStop(0.225, 'rgba(221, 223, 225, 1)');
      lingrad.addColorStop(0.45, 'rgba(228, 230, 231, 1)');
      lingrad.addColorStop(0.5, 'rgba(225, 226, 227, 1)');
      shadowColor = "rgba(177,181,185,1.0)";
      shadowWidth = 0;
      borderColor = "rgba(177,181,185,1.0)";
  } else { // ltGrey
      lingrad.addColorStop(0.0, 'rgba(183, 194, 206, 1)');
      lingrad.addColorStop(0.5, 'rgba(215, 220, 227, 1)');
      shadowColor = "rgba(0,0,0,0.35)";
      shadowWidth = Math.ceil(h/8);
  }

  ctx.save();
  ctx.fillStyle = lingrad;
  roundedRect(ctx, 0, 0, w, h*2, r);
  ctx.fill();
  ctx.restore();

  innerShadow(ctx,0,0,w,h*2,r,shadowColor,0,0,shadowWidth,"#fff");

  if(borderColor != "") {
      ctx.save();
      ctx.translate(0.5, 0.5);
      roundedRect(ctx, 0, 0, w-1, h*2, r-1);
      ctx.strokeStyle = borderColor;
      ctx.stroke();
      ctx.restore();
  }

  if(borderBottomColor != "") {
      ctx.save();
      ctx.translate(0.5, 0.5);
      ctx.strokeStyle = borderBottomColor;
      ctx.moveTo((borderColor == "") ? 0 : 1, h-1);
      ctx.lineTo((w-1) - ((borderColor == "") ? 0 : 1), h-1);
      ctx.stroke();
      ctx.restore();
  }
}

function drawBoxContent(contentDiv, contentCanvas, contentCue) {
  var w = contentCue.width, h = contentCue.height, r = contentCue.parent.radius;
  var ctx = contentCanvas.getContext('2d');

  ctx.save();
  ctx.translate(0.0, -(r+1));

  var fillStyle = "", strokeStyle = "", borderColor = "", borderTopColor = "", shadowBlur = 0;
  var contentColor = contentDiv.className.match(utils.regex.colors)[1];

  if(contentColor == "blueGrey") {
      fillStyle = "#eee";
      strokeStyle = "#e5e5e5";
      strokeStyle = "rgba(177,181,185,1.0)";
      borderColor = "rgba(0,0,0,0.15)";
      shadowBlur = 5;
  } else if(contentColor == "metal") {
      var lingrad = ctx.createLinearGradient( 0, (r+1), 0, h+(r+1));
      lingrad.addColorStop(0.0, 'rgb(204, 204, 204)');
      lingrad.addColorStop(1.0, 'rgb(190, 190, 190)');
      fillStyle = lingrad;
      borderTopColor = "#e0e0e0";
      lingrad = ctx.createLinearGradient( 0, (r+1), 0, h+(r+1));
      lingrad.addColorStop(0, 'rgba(194, 194, 194, 1)');
      lingrad.addColorStop(1.0/h, 'rgba(194, 194, 194, 1)');
      lingrad.addColorStop(1.0, 'rgba(170, 170, 170,1)');
      strokeStyle= lingrad;
  } else if(contentColor == "alum") {
      fillStyle = "#fafafa";
      var lingrad = ctx.createLinearGradient( 0, (r+1), 0, h+(r+1));
      lingrad.addColorStop(0, 'rgba(225, 225, 225, 1)');
      lingrad.addColorStop(1.0-(r/h), 'rgba(225, 225, 225, 1)');
      lingrad.addColorStop(1.0, 'rgba(196,196,196,1)');
      strokeStyle= lingrad;
  } else if(contentColor == "glassGrey") {
      fillStyle = "#eee";
      var lingrad = ctx.createLinearGradient( 0, (r+1), 0, h+(r+1));
      lingrad.addColorStop(0.0, 'rgba(247, 247, 247, 1)');
      lingrad.addColorStop(1.0, 'rgba(231, 231, 231, 1)');
      fillStyle = lingrad;
      strokeStyle = "rgba(177,181,185,1.0)";
      borderColor = "rgba(0,0,0,0.15)";
      shadowBlur = 2;
  } else if(contentColor == "lightToWhite") {
      var lingrad = ctx.createLinearGradient( 0, (r+1), 0, h+(r+1));
      lingrad.addColorStop(0.0, 'rgba(241, 241, 241, 1)');
      lingrad.addColorStop(1.0, 'rgba(255, 255, 255, 1)');
      fillStyle = lingrad;
      strokeStyle = "#e5e5e5";
      borderColor = "rgba(0,0,0,0.1)";
      shadowBlur = 2;
  } else if(contentColor == "whiteToLight") {
      var lingrad = ctx.createLinearGradient( 0, (r+1), 0, h+(r+1));
      lingrad.addColorStop(0.0, 'rgba(255, 255, 255, 1)');
      lingrad.addColorStop(1.0, 'rgba(241, 241, 241, 1)');
      fillStyle = lingrad;
      strokeStyle = "#d4d4d4";
      borderColor = "rgba(0,0,0,0.1)";
      shadowBlur = 2;
  } else if(contentColor == "ltGreyDown") {
      var lingrad = ctx.createLinearGradient( 0, (r+1), 0, h+(r+1));
      lingrad.addColorStop(0.0, 'rgba(247, 247, 247, 1)');
      lingrad.addColorStop(1.0, 'rgba(237, 239, 242, 1)');
      fillStyle = lingrad;
      strokeStyle = "#e5e5e5";
      borderColor = "rgba(0,0,0,0.1)";
      shadowBlur = 2;
  } else if(contentColor == "ltGrey") {
      var lingrad = ctx.createLinearGradient( 0, (r+1), 0, h+(r+1));
      lingrad.addColorStop(0.0, 'rgba(237, 239, 242, 1)');
      lingrad.addColorStop(1.0, 'rgba(247, 247, 247, 1)');
      fillStyle = lingrad;
      strokeStyle = "#e5e5e5";
      borderColor = "rgba(0,0,0,0.1)";
      shadowBlur = 2;
  }
  
  ctx.save();
  roundedRect(ctx,0,0,w,h+(r+1),r);
  ctx.clip();
  ctx.fillStyle = fillStyle;
  roundedRect(ctx,0,0,w,h+(r+1),r);
  ctx.fill();
  ctx.restore();
  
  if(strokeStyle != "") {
      ctx.save();
      ctx.translate(+0.5, -0.5);
      roundedRect(ctx,0,0,w-1,h+(r+1),r-1);
      ctx.strokeStyle = strokeStyle;
      ctx.stroke();
      ctx.restore();
  }

  if(shadowBlur != 0) { innerShadow(ctx,0,0,w,h+(r+1),r,borderColor,0,0,shadowBlur,"#fff"); }

  if(borderTopColor != "") {
      ctx.save();
      ctx.translate(0.5, 0.5);
      ctx.strokeStyle = borderTopColor;
      ctx.moveTo((strokeStyle == "") ? 0 : 1, r+1);
      ctx.lineTo((w-1) - ((strokeStyle == "") ? 0 : 1), r+1);
      ctx.stroke();
      ctx.restore();
  }

  ctx.restore();
}


function draw() {
  var elementArray;

  elementArray = document.getElementsByTagName("DIV");
  for(var i = 0; i < elementArray.length; i++) { if((elementArray[i].className.search(/\brssIcon\b/) != -1) && (elementArray[i].className.search(/\buseImg\b/) != -1)) { elementArray[i].className = elementArray[i].className.replace(/\buseImg\b/, "useVector"); } }
  for(var i = 0; i < elementArray.length; i++) { drawElement(elementArray[i]); }

  elementArray = document.getElementsByTagName("SPAN");
  for(var i = 0; i < elementArray.length; i++) { if((elementArray[i].className.search(/\brssIcon\b/) != -1) && (elementArray[i].className.search(/\buseImg\b/) != -1)) { elementArray[i].className = elementArray[i].className.replace(/\buseImg\b/, "useVector"); } }
  for(var i = 0; i < elementArray.length; i++) { drawElement(elementArray[i]); }

  elementArray = document.getElementsByTagName("A");
  for(var i = 0; i < elementArray.length; i++) { drawElement(elementArray[i]); }
}

function drawElement(element) {
  if(element.className.search(/\bsky\b/) != -1) { doSky(element); }
  if(element.className.search(/\bcharcoal\b/) != -1) { doCharcoal(element); }
  if(element.className.search(/\bocean\b/) != -1) { doOcean(element); }
  if((element.className.search(/\bbutton\b/) != -1) && (element.className.search(/\bpearl\b/) != -1)) { doPearlButton(element); }

  if(element.className.search(/\brssFeedIcon\b/) != -1) { doRSSFeedIcon(element); }
  if(element.className.search(/\brssGraphic\b/) != -1) { doRSSGraphic(element); }
  if(element.className.search(/\bbadge\b/) != -1) { doBadge(element); }
  if(element.className.search(/\boldbutton\b/) != -1) { doButton(element); }
  if(element.className.search(/\balphaFadeTop\b/) != -1) { doAlphaFadeTop(element, 5); }
  if(element.className.search(/\balphaFadeBottom\b/) != -1) { doAlphaFadeBottom(element, 5); }
  if(element.className.search(/\balphaTopAndBottomFade\b/) != -1) { doAlphaFadeTopAndBottom(element, 5); }
  if(element.className.search(/\btopFadeIn\b/) != -1) { doTopFadeIn(element, 40); }
  if(element.className.search(/\bbox\b.*\btitled\b/) != -1) { doBoxTitled(element); }
  if(element.className.search(/\bbezel\b/) != -1) { doBezel(element, 5); }
  if(element.className.search(/\binset\b/) != -1) { doInsetBox(element, 3); }
  if(element.className.search(/\binsetLighten\b/) != -1) { doInsetLightenBox(element, 3); }
}

function canvasUnderElement(e, r, doPrep, refreshOnChange) {
  var i = -1;
  if(utils.browserInfo.opera == true) { for(var x = 0; x < canvasesMap.length; x++) { if(canvasesMap[x] == e) { i = x; break; } } } else { i = canvasesMap.indexOf(e); }
  if(i != -1) {
      var cue = canvases[i];
      cue.elementWidth  = e.clientWidth;
      cue.elementHeight = e.clientHeight;
      var computedStyle = document.defaultView.getComputedStyle(e, null);
      var borderH = parseInt(computedStyle.borderTopWidth.match(/(\d+)/)[1]) + parseInt(computedStyle.borderBottomWidth.match(/(\d+)/)[1]);
      var borderW = parseInt(computedStyle.borderLeftWidth.match(/(\d+)/)[1]) + parseInt(computedStyle.borderRightWidth.match(/(\d+)/)[1]);
      cue.setSize(cue.elementWidth + borderW, cue.elementHeight + borderH);
      cue.moveTo(0, 0);
      return(cue);
  }
  return(new CanvasUnderElement(e, r, doPrep, refreshOnChange));
}

function CanvasUnderElement(e, r, doPrep, refreshOnChange) {
  this.element = e;
  this.elementWidth  = this.element.clientWidth;
  this.elementHeight = this.element.clientHeight;
  this.radius = r;
  this.padWidth = 0;
  this.padHeight = 0;
  
  var computedStyle = document.defaultView.getComputedStyle(e, null);
  this.borderTop = parseInt(computedStyle.borderTopWidth.match(/(\d+)/)[1]);
  this.borderBottom = parseInt(computedStyle.borderBottomWidth.match(/(\d+)/)[1]);
  this.borderLeft = parseInt(computedStyle.borderLeftWidth.match(/(\d+)/)[1]);
  this.borderRight = parseInt(computedStyle.borderRightWidth.match(/(\d+)/)[1]);

  this.tx = 0;
  this.ty = 0;
  this.deltaX = 0;
  this.deltaY = 0;
  this.shadowDeltaX = 0;
  this.shadowDeltaY = 0;

  this.canvas = document.createElement("canvas");
  this.canvas.className = "underElement";
  this.context = this.canvas.getContext('2d');
  this.context.save();
  this.element.appendChild(this.canvas);
  this.setSizeAndPadPlusShadow(this.elementWidth, this.elementHeight, this.padWidth, this.padHeight, 0, 0, 0);

  if(this.element.className.search(/\bwithCanvasUnderElement\b/) == -1) { this.element.className += " withCanvasUnderElement"; }
  this.moveTo(0, 0);
  canvasesMap.push(e);
  canvases.push(this);
}

CanvasUnderElement.prototype.toString = function() {
    var desc = new Array();
    desc.push("x: "+this.x+" y: "+this.y);
    desc.push("tx: "+this.tx+" ty: "+this.ty);
    desc.push("element width: "+this.elementWidth+" element height: "+this.elementHeight);
    desc.push("canvas width: "+this.canvasWidth+" canvas height: "+this.canvasHeight);
    desc.push("tblr: "+this.top+", "+this.bottom+", "+this.left+", "+this.right);
    desc.push("width: "+this.width+" height: "+this.height);
    desc.push("Border lrtb: "+this.borderLeft+", "+this.borderRight+", "+this.borderTop+", "+this.borderBottom);
    desc.push("pad width: "+this.padWidth+" pad height: "+this.padHeight);
    desc.push("shadow x: "+this.shadowX+" shadow y: "+this.shadowY+" blur: "+this.shadowBlur);
    desc.push("shadow dx: "+this.shadowDeltaX+" shadow dy: "+this.shadowDeltaY);
    //desc.push("shadow pad width: "+this.shadowPadWidth+" shadow pad height: "+this.shadowPadHeight);
    desc.push("dx: "+this.deltaX+" dy: "+this.deltaY);
    desc.push("tx: "+this.tx+" ty: "+this.ty);
    desc.push("top: " + this.canvas.style.top + " left: " + this.canvas.style.left);
    desc.push("setSizeArgs: "+this.setSizeArgs);
    return(desc.join("\n"))
}

CanvasUnderElement.prototype.setSize = function(w, h) {
  this.setSizeAndPadPlusShadow(w, h, this.padWidth, this.padHeight, this.shadowX, this.shadowY, this.shadowBlur);
}

CanvasUnderElement.prototype.setPad = function(pw, ph) {
  this.setSizeAndPadPlusShadow(this.setWidth, this.setHeight, pw, ph, this.shadowX, this.shadowY, this.shadowBlur);
}

CanvasUnderElement.prototype.setShadowXYBlur = function(sx, sy, sb) {
  this.setSizeAndPadPlusShadow(this.setWidth, this.setHeight, this.padWidth, this.padHeight, sx, sy, sb);
}

CanvasUnderElement.prototype.setSizeAndPadPlusShadow = function(w, h, pw, ph, sx, sy, sb) {
  this.setSizeArgs = "w: "+w+", h: "+h+", pw: "+pw+", ph: "+ph+", sx: "+sx+", sy: "+sy+", sb: "+sb;
  this.setWidth = w; this.setHeight = h;
  this.width = w + this.borderRight + this.borderLeft; this.height = h + this.borderTop + this.borderBottom; this.padWidth = pw; this.padHeight = ph;
  this.shadowX = sx; this.shadowY = sy; this.shadowBlur = sb;
  this.top = Math.min(this.shadowY - this.shadowBlur, 0);
  this.bottom = Math.max(this.height + this.shadowY + this.shadowBlur + this.padHeight, this.height + this.padHeight);
  this.left = Math.min(this.shadowX - this.shadowBlur, 0);
  this.right = Math.max(this.width + this.shadowX + this.shadowBlur + this.padWidth, this.width + this.padWidth);
  this.canvasWidth = this.right - this.left;
  this.canvasHeight = this.bottom - this.top;
  this.canvas.setAttribute("width",  this.canvasWidth);
  this.canvas.setAttribute("height", this.canvasHeight);
}

CanvasUnderElement.prototype.setDeltaXY = function(dx, dy) {
  this.setDeltaXYAndShadowDeltaXY(dx, dy, this.shadowDeltaX, this.shadowDeltaY);
}

CanvasUnderElement.prototype.setShadowDeltaXY = function(sdx, sdy) {
  this.setDeltaXYAndShadowDeltaXY(this.deltaX, this.deltaY, sdx, sdy);
}

CanvasUnderElement.prototype.setDeltaXYAndShadowDeltaXY = function(dx, dy, sdx, sdy) {
  this.deltaX = dx;
  this.deltaY = dy;
  this.shadowDeltaX = sdx;
  this.shadowDeltaY = sdy;

  this.context.translate(-this.tx, -this.ty);
  this.tx = -this.deltaX + this.shadowDeltaX;
  this.ty = -this.deltaY + this.shadowDeltaY;
  this.context.translate(this.tx, this.ty);
  this.moveTo(this.x, this.y);
}

CanvasUnderElement.prototype.moveTo = function(x, y) {
  this.x = x; this.y = y;
  this.canvas.style.top  = (this.y - this.borderTop + this.shadowDeltaY + this.deltaY) + "px";
  this.canvas.style.left = (this.x - this.borderLeft + this.shadowDeltaX + this.deltaX) + "px";
}

CanvasUnderElement.prototype.clear = function() {
    this.clearContext();
    this.context.clearRect(0,0,this.canvasWidth, this.canvasHeight);
}

CanvasUnderElement.prototype.clearContext = function() {
    //this.context.restore();
    //this.context.save();
}

CanvasUnderElement.prototype.addShadow = function(sx, sy, sb, sc) {
  this.setShadowXYBlur(sx, sy, sb);
  this.shadowColor = sc;

  var sox = this.shadowX < this.shadowBlur ? this.shadowBlur - this.shadowX : 0;
  var soy = this.shadowY < this.shadowBlur ? this.shadowBlur - this.shadowY : 0;

  this.setShadowDeltaXY(-sox, -soy);
  //this.moveTo(this.x - sox, this.y - soy);

  var ctx = this.context;

  //this.tx += sox;
  //this.ty += soy;

  ctx.save();
  roundedRect(ctx,sox,soy,this.width-0,this.height-0,this.radius+1);
  ctx.shadowColor = this.shadowColor;
  ctx.shadowOffsetX = this.shadowX;
  ctx.shadowOffsetY = this.shadowY;
  ctx.shadowBlur = this.shadowBlur;
  ctx.fillStyle = document.defaultView.getComputedStyle(document.body, null).backgroundColor;
  ctx.fill();
  ctx.restore();

  ctx.save();
  roundedRect(ctx,sox,soy,this.width-0,this.height-0,this.radius);
  ctx.clip();
  ctx.clearRect(0,0,this.canvasWidth, this.canvasHeight);
  ctx.restore();
  
  ctx.translate(sox, soy);
}

function rectPath(ctx,x,y,width,height){
  ctx.moveTo(x,y);
  ctx.lineTo(x+width,y);
  ctx.lineTo(x+width,y+height);
  ctx.lineTo(x,y+height);
  ctx.lineTo(x,y);
}

function roundedRect(ctx,x,y,width,height,radius){
  ctx.beginPath();
  roundedRectReal(ctx,x,y,width,height,radius);
}

function roundedRectReal(ctx,x,y,width,height,radius){
  radius += 1; width -= 1; height -= 1;
  ctx.moveTo(x,y+radius+1);
  ctx.lineTo(x,y+height-radius);
  ctx.quadraticCurveTo(x,y+height+1,x+radius+1,y+height+1);
  ctx.lineTo(x+width-radius,y+height+1);
  ctx.quadraticCurveTo(x+width+1,y+height+1,x+width+1,y+height-radius);
  ctx.lineTo(x+width+1,y+radius+1);
  ctx.quadraticCurveTo(x+width+1,y,x+width-radius,y);
  ctx.lineTo(x+radius+1,y);
  ctx.quadraticCurveTo(x,y,x,y+radius+1);
}

function innerShadow(c,x,y,w,h,r,sc,sx,sy,sb,f) {
  c.save();
  roundedRect(c,x,y,w,h,r);
  c.clip();

  c.shadowColor = sc;
  c.shadowOffsetX = sx;
  c.shadowOffsetY = sy;
  c.shadowBlur = sb;

  c.translate(0.5, 0.5);
  roundedRect(c,x-1,y-1,w+1.0,h+1.0,r-2);
  c.strokeStyle = f;
  c.stroke();
  c.restore();
}

addEventListener("load", draw, false);
addEventListener("resize", draw, false);
