docs: function Block(htmlElement, canvas)
  {	
  	/*
  	 * initialization
  	 */
  	 
  	this.canvas = canvas;
  	this.htmlElement = htmlElement;
  	this.id = htmlElement.id;
  	this.blocks = new Array();
  	this.moveListeners = new Array();
  	
  	if(this.id == 'description2_out1')
  		var merda = 0;
  	this.currentTop = calculateOffsetTop(this.htmlElement) - this.canvas.offsetTop;
  	this.currentLeft = calculateOffsetLeft(this.htmlElement) - this.canvas.offsetLeft;
  	
  	this.visit = function(element) {
  		if (element == this.htmlElement) {
  			// exclude itself
  			return true;
  		}
  		if (isBlock(element)) {
  			var innerBlock = new Block(element, this.canvas);
  			innerBlock.initBlock();
  			this.blocks.push(innerBlock);
  			this.moveListeners.push(innerBlock);
  			return false;
  		}
  		return true;
  	}
  	
  	this.initBlock = function() {
  		// inspect block children to identify nested blocks
  		new DocumentScanner(this, true).scan(this.htmlElement);
  	}
  	
  	this.top = function() {
  		return this.currentTop;
  	}
  	
  	this.left = function() {
  		return this.currentLeft;
  	}
  	
  	this.width = function() {
  		return this.htmlElement.offsetWidth;		
  	}
  	
  	this.height = function() {
  		return this.htmlElement.offsetHeight;
  	}
  	
  	/*
  	 * methods
  	 */	
  	this.print = function() {
  		var output = 'block: ' + this.id;
  		if (this.blocks.length > 0) {
  			output += '<ul>';
  			for(var i = 0; i < this.blocks.length; i++) {
  				output += '<li>';
  				output += this.blocks[i].print();
  				output += '</li>';
  			}
  			output += '</ul>';
  		}
  		return output;
  	}
  	
  	/*
  	 * This function searches for a nested block (or the block itself) with a given id
  	 */
  	this.findBlock = function(blockId) {
  		if(this.id == blockId)
  			return this;
  		var result;
  		for(var i = 0; i < this.blocks.length && !result; i++)
  			result = this.blocks[i].findBlock(blockId);
  		return result;
  	}
  
  	this.fit = function() {
  		function getlines(txt) {
  			return (12*txt.split ("\n").length);
  		}
  		function getcolumns(txt) {
  			var cols = 0;
  			var txts = txt.split ("\n");
  			for (var x in txts) {
  				const len = txts[x].length;
  				if (len>cols)
  					cols = len;
  			}
  			return 10+ (7*cols);
  		}
  		var text = this.htmlElement.innerHTML;
  		this.htmlElement.style.width = getcolumns (text);
  		this.htmlElement.style.height = getlines (text);
  	}
  	
  	this.move = function(left, top) {
  		this.htmlElement.style.left = left;
  		this.htmlElement.style.top = top;
  		this.onMove();
  	}
  		
  	this.onMove = function() {
  		this.currentLeft = calculateOffsetLeft(this.htmlElement) - this.canvas.offsetLeft;
  		this.currentTop = calculateOffsetTop(this.htmlElement) - this.canvas.offsetTop;
  		// notify listeners
  		for(var i = 0; i < this.moveListeners.length; i++)
  			this.moveListeners[i].onMove();
  	}
  	
  	this.toString = function() {
  		return 'block: ' + this.id;
  	}
  }