function buildcross( o ) {
 if( ( !o || !o.hor ) && crossword && crossword.run ) { o = crossword; }
 o.title =  o.title || 'Crossword';
 o.bld = o.bld || 0;
 o.cas = o.cas || 0;
 o.sef = o.sef || 0;
 o.siz = o.siz || 0;
 o.hor = o.hor || [];
 o.ver = o.ver || [];

 function setnum() {
  var q = ( dh.checked ? this.hword : this.vword ) || this.hword || this.vword;
  if( q ) { setword( q ); window.alert( 'Nr. ' + q.value + ' ' + ( q===this.hword ? 'horizontal' : 'vertical' ) + ':\n\n' + q.firstChild.nodeValue ); }
  return false;
 }
 function setword( o ) { o = o || this;
  if( ( o.parentNode===ulh ? dv : dh ).checked ) { togglebi(); } ff[o.sta[0]][o.sta[1]].focus();
 }
 function focusthis( q ) { q = q || this;
  var r, s = q.name.split( /[^\d]/ ), x = +s[0], y = +s[1]; cx = x; cy = y;
  if( this.defaultValue==='#' ) {
   focusnext( x, y );
  } else {
   r = ' ' + o.title + '  (' + ( x + 1 ) + ', ' + ( y + 1 ) + ')';
   if( window.status!==r ) {
    window.status = r; colobi( x, y );
   }
   /*q.select();*/
  }
 }
 function colobi( x, y ) {
  var i = hi.length; while( i-- ) { hi[i].style.background = 'white'; } hi.length =0; hik.style.background = ''; vik.style.background = '';
  i = x; while( ff[--i] && ff[i][y] && ff[i][y].defaultValue!=='#' ) {} ++i;
  if( nums[i] && nums[i][y] && nums[i][y].hword ) { hik=nums[i][y].hword; hik.style.background = dh.checked ? 'yellow' : '#fffacd'; }
  while( ff[i] && ff[i][y] && ff[i][y].defaultValue!=='#' ) { hi[hi.length] = ff[i][y]; ff[i++][y].style.background = dh.checked ? 'yellow' : '#fffacd'; }
  i = y; while( ff[x] && ff[x][--i] && ff[x][i].defaultValue!=='#' ) {} ++i;
  if( nums[x] && nums[x][i] && nums[x][i].vword ) { vik = nums[x][i].vword; vik.style.background = dv.checked ? 'yellow' : '#fffacd'; }
  while( ff[x] && ff[x][i] && ff[x][i].defaultValue!=='#' ) { hi[hi.length] = ff[x][i]; ff[x][i++].style.background = dv.checked ? 'yellow' : '#fffacd'; }
  ff[x][y].style.background = 'gold'; ff[x][y].focus();
 }
 function togglebi() { dh.checked = !dh.checked; dv.checked = !dv.checked; colobi(cx,cy); }
 function toggledir( o ) { o = o || this; var p = o===dh ? dv : dh; p.checked = !o.checked; colobi(cx,cy); }
 window.document.onkeydown = function( e ) {
  e = e || window.event;
  var k = e.keyCode || e.which, l = String.fromCharCode( k ).toLowerCase();
  if( e.altKey ) {
   if( l==='o' ) { e.returnValue = null; togglebi(); return false; }
   if( l==='s' ) { e.returnValue = null; if( dv.checked ) { togglebi(); } return false; }
   if( l==='w' ) { e.returnValue = null; if( dh.checked ) { togglebi(); } return false; }
  }
  focusthis( ff[cx][cy] );
 };
 function keyd( e ) {
  e = e || window.event;
  e.returnValue = null;
  var o = this || e.srcElement || e.targetElement, k = e.keyCode || e.which, l = String.fromCharCode( k ).toLowerCase();
  if( k===8 ) { o.value = ''; return false; }
  if( k===9 || k===188 || k===190 ) { togglebi(); return false; } //tab,.
  if( k===46 ) { o.value = ''; o.focus(); return false; } //del
  if( e.altKey || e.ctrlKey ) { return false; }
  var s = o.name.split( /[^\d]/ ), x = +s[0], y = +s[1]; //alert(x+' '+y);
  if( k===37 ) { //left
   while( true ) { x--; if(x<0) { x=w; y--; if(y<0) {y=h;} }
     if( ff[x] && ff[x][y] && ff[x][y].defaultValue!=='#' ) { ff[x][y].focus(); break; }
  }}else
  if( k===38 ) { //up
   while( true ) { y--; if(y<0) { y=h; x--; if(x<0) {x=w;} }
    if( ff[x] && ff[x][y] && ff[x][y].defaultValue!=='#' ) { ff[x][y].focus(); alert(document.activeElement.name);break; }
  }}else
  if( k===39 ) { //right
   while( true ) { x++; if(x>w) { x=0; y++; if(y>h) {y=0;} }
    if( ff[x] && ff[x][y] && ff[x][y].defaultValue!=='#' ) { ff[x][y].focus(); break; }
  }}else
  if( k===40 ) { //down
   while( true ) { y++; if(y>h) { y=0; x++; if(x>w) {x=0;} }
    if( ff[x] && ff[x][y] && ff[x][y].defaultValue!=='#' ) { ff[x][y].focus(); break; }
  }}else
  if( /[a-z\d ]/.test( l ) ) {
   o.value = l.replace( /\s*/g, '' ); focusnext( x, y );
  }else
  if( /[#=\+\-:;\\\/\w]/.test( l ) ) {
   focusnext( x, y );
  }
  return false;
 }
 function focusnext( x, y ) {
  var s = t; while( s-- ) {
   if( dh.checked ) {
    x++; if( x>w ) { x = 0; y++; if( y>h ) { y = 0; } }
   } else {
    y++; if( y>h ) { y = 0; x++; if( x>w ) { x = 0; } }
   }
   if( ff[x] && ff[x][y] && ff[x][y].defaultValue!=='#' ) {ff[x][y].focus();  return; }
  }
  keyd = nogrid; nogrid();
 }
 function nogrid() { /*window.alert( 'The grid is empty!' );*/ }
 function help() {
  window.alert( 'Welcome to Crossaword.\n'
   + '\nKeys\n\n'
   + 'Tab,\tToggle type direction\n'
   + 'Alt+O\tToggle type direction\n'
   + 'Alt+S\tToggle type direction across\n'
   + 'Alt+W\tToggle type direction down\n'
   + '\nButtons\n\n'
   + 'Solve\tReveal the current letter\n'
   + '\nHappy crossing!' );
  focusthis( ff[cx][cy] );
  return false;
 }
 var d = window.document, ff = [], hi = [], letters = [], nums = [], pl = 10,
  w = 0, h = 0, t = 0, nux = 0, cx=0, cy=0, hik = 0, vik = 0, i, j = 0, q,
  f = d.createElement( 'form' ),
  h1 = d.createElement( 'h1' ),
  h2 = d.createElement( 'h2' ),
  div = d.createElement( 'div' ), divb, divh, divv,
  a = d.createElement( 'a' ),
  b = d.createElement( 'input' ), b2,
  p = b.cloneNode( true ),
  dh = b.cloneNode( true ), dv,
  lh = d.createElement( 'label' ), lv,
  ulh = d.createElement( 'ol' ), ulv,
  li = d.createElement( 'li' );
 f.style.position = 'relative';
 f.style.font = '14px ' + ( o.sef ? '\'Book Antiqua\', \'Times New Roman\', Times, serif' : 'Arial, sans-serif' );
 div.style.position = 'absolute'; divb = div.cloneNode( true ); divh = div.cloneNode( true );
 h2.insertBefore( d.createTextNode( 'Horizontal' ), null );
 h2.style.margin = '0 0 0 10px';
 ulh.style.marginTop = '0';
 ulh.style.cursor = 'pointer';
 divh.style.top = 30 + 'px';
 divh.insertBefore( h2, null );
 divh.insertBefore( ulh, null );
 divv = divh.cloneNode( true );
 divv.firstChild.firstChild.nodeValue = 'Vertical'; ulv = divv.lastChild;
 div.style.top = 40 + 'px';
 div.style.left = pl + 'px';
 divb.style.left = pl + 'px';
 a.href = '#';
 a.style.position = 'absolute';
 a.style.color = 'black';
 a.style.textDecoration = 'none';
 a.style.cursor = 'default';
 a.style.font = ( o.siz<18 ? 8 : 9 ) + 'px Arial, sans-serif';
 a.insertBefore( d.createTextNode( ' ' ), null );
 b.type = 'submit'; b.style.margin = '0 2px'; b.style.font = 'menu';
 b2 = b.cloneNode( true );
 b.value = 'Solve';
 b.onclick = function() { ff[cx][cy].value = ff[cx][cy].defaultValue; focusnext( cx, cy ); return false; };
 b2.value = 'Help';
 b2.onclick = help;
 p.type = 'text'; p.value = ''; p.size = 1; p.maxLength = 1;
 p.style.position = 'absolute';
 p.style.textAlign = 'center';
 p.style.border = '1px solid black';
 p.style.width = o.siz + 4 + 'px';
 p.style.height = o.siz + 4 + 'px';
 p.style.textTransform = o.cas ? 'uppercase' : 'lowercase';
 p.style.font = ( o.bld ? 'bold ' : '' ) + o.siz + 'px ' + ( o.sef ? '\'Book Antiqua\', \'Times New Roman\', Times, serif' : 'Arial, sans-serif' );
 dh.type = 'checkbox'; dh.style.zoom = '80%';
 lh.style.font = 'menu';
 lh.insertBefore( dh, null );
 lv = lh.cloneNode( true ); dv = lv.firstChild;
 dh.name = 'dh'; dh.id = 'dh' + d.forms.length; dh.onclick = toggledir;
 dv.name = 'dv'; dv.id = 'dv' + d.forms.length; dv.onclick = toggledir;
 lh.htmlFor = dh.id; lh.insertBefore( d.createTextNode( 'Across' ), null );
 lv.htmlFor = dv.id; lv.insertBefore( d.createTextNode( 'Down' ), null );
 divb.insertBefore( lh, null );
 divb.insertBefore( lv, null );
 divb.insertBefore( d.createElement( 'br' ), null );
 divb.insertBefore( b, null );
 divb.insertBefore( b2, null );
 li.insertBefore( d.createTextNode( ' ' ), null );
 i = o.hor.length / 4; while( i-- ) {
  w = Math.max( w, o.hor[i*4+0] + o.hor[i*4+2].length );
  if( !nums[o.hor[i*4+0]] ) { nums[o.hor[i*4+0]] = []; }
  nums[o.hor[i*4+0]][o.hor[i*4+1]] = 'x';
  j = o.hor[i*4+2].length; while( j-- ) {
   if( !letters[o.hor[i*4+0] + j] ) { letters[o.hor[i*4+0] + j] = []; }
   letters[o.hor[i*4+0] + j][o.hor[i*4+1]] = o.hor[i*4+2].charAt( j );
  }
  q = li.cloneNode( true );
  q.firstChild.nodeValue = o.hor[i*4+3] + ' (' + o.hor[i*4+2].length + ')';
  q.sta = [ o.hor[i*4+0], o.hor[i*4+1] ];
  q.onclick = setword;
  ulh.insertBefore( q, ulh.firstChild );
 }
 i = o.ver.length / 4; while( i-- ) {
  h = Math.max( h, o.ver[i*4+1] + o.ver[i*4+2].length );
  if( !nums[o.ver[i*4+0]] ) { nums[o.ver[i*4+0]] = []; }
  nums[o.ver[i*4+0]][o.ver[i*4+1]] = 'x';
  if( !letters[o.ver[i*4+0]] ) { letters[o.ver[i*4+0]] = []; }
  j = o.ver[i*4+2].length; while( j-- ) {
   letters[o.ver[i*4+0]][o.ver[i*4+1] + j] = o.ver[i*4+2].charAt( j );
  }
  q = li.cloneNode( true );
  q.firstChild.nodeValue = o.ver[i*4+3] + ' (' + o.ver[i*4+2].length + ')';
  q.sta = [ o.ver[i*4+0], o.ver[i*4+1] ];
  q.onclick = setword;
  ulv.insertBefore( q, ulv.firstChild );
 }
 t = w * h;
 for( j=0; j<h; j++ ) { for( i=0; i<w; i++ ) {
  if( !ff[i] ) { ff[i] = []; }
  q = p.cloneNode( true );
  q.name = 'c' + i + 'c' + j;
  q.defaultValue = letters[i][j] || '#';
  q.style.top = j * ( o.siz + 7 ) + 'px';
  q.style.left = i * ( o.siz + 7 ) + 'px';
  q.style.background = letters[i][j] ? 'white' : 'black';
  q.onfocus = focusthis;
  q.onkeydown = keyd;
  ff[i][j] = div.insertBefore( q, div.firstChild );
  if( nums[i] && nums[i][j] ) {
   q = a.cloneNode( true );
   q.firstChild.nodeValue = ++nux;
   q.style.top = j * ( o.siz + 7 ) + 1 + 'px';
   q.style.left = i * ( o.siz + 7 ) + 2 + 'px';
   q.onclick = setnum;
   nums[i][j] = div.insertBefore( q, null );
   if( letters[i+1] && letters[i+1][j] && ( !letters[i-1] || !letters[i-1][j] ) ) { q.hword = ulh.childNodes[hik++]; q.hword.value = nux; }
   if( letters[i] && letters[i][j+1] && !letters[i][j-1] ) { q.vword = ulv.childNodes[vik++]; q.vword.value = nux; }
  }
 } } hik = ulh.lastChild; vik = ulv.lastChild; 
 h1.insertBefore( d.createTextNode( o.title ), null );
 f.insertBefore( h1, null );
 f.insertBefore( divh, null );
 f.insertBefore( divv, null );
 f.insertBefore( div, null );
 f.insertBefore( divb, null );
 d.body.insertBefore( f, null );
 dh.checked = true;
 f.style.background = 'threedface';
 f.style.border = '1px outset white';
 f.style.height = h1.scrollHeight + 40 + Math.max( h * ( o.siz + 7 ), ulh.scrollHeight, ulv.scrollHeight ) + 'px';
 divb.style.top = h * ( o.siz + 7 ) + 40 + 'px';
 h1.style.paddingLeft = pl + 'px';
 divh.style.left = w * ( o.siz + 7 ) + pl + 'px';
 divv.style.left = w * ( o.siz + 7 ) + divh.scrollWidth + pl + 'px';
 ff[0][0].focus();
 return false;
}

if( window.addEventListener ) {
 window.addEventListener( 'load', buildcross, true );
} else if( window.attachEvent ) {
 window.attachEvent( 'onload', buildcross );
}
