1 	JXG.GeogebraReader = new function() {
  2 /**
  3  * @param {String} type the type of expression
  4  * @param {String} m first input value
  5  * @param {String} n second input value
  6  * @return {String} return the object, string or calculated value
  7  */
  8 this.ggbAct = function(type, m, n) {
  9   var v1 = m, v2 = n, s1, s2, a;
 10   switch(type.toLowerCase()) {
 11     case 'end':
 12       // JXG.debug("<b>end: </b>"+ v1);
 13       return v1;
 14     break;
 15     case 'coord':
 16       s1 = (JXG.GeogebraReader.board.ggbElements[v1]) ? 'JXG.getRef(JXG.GeogebraReader.board, "'+ v1 +'")' : v1;
 17       s2 = (JXG.GeogebraReader.board.ggbElements[v2]) ? 'JXG.getRef(JXG.GeogebraReader.board, "'+ v2 +'")' : v2;
 18       return [s1, s2];
 19     break;
 20     case 'le': // smaller then
 21       return '( ('+ v1 +') <= ('+ v2 +') )';
 22     break;
 23     case 'ge': // greater then
 24       return '( ('+ v1 +') >= ('+ v2 +') )';
 25     break;
 26     case 'eq': // equal
 27       return '( ('+ v1 +') == ('+ v2 +') )';
 28     break;
 29     case 'neq': // not equal
 30       return '( ('+ v1 +') != ('+ v2 +') )';
 31     break;
 32     case 'lt': // smaller
 33       return '( ('+ v1 +') < ('+ v2 +') )';
 34     break;
 35     case 'gt': // greater
 36       return '( ('+ v1 +') > ('+ v2 +') )';
 37     break;
 38     case 'add':
 39     	if (JXG.GeogebraReader.isGGBVector(v1) && JXG.GeogebraReader.isGGBVector(v2)){ //Add: Vector + Vector
 40     		return [1, v1[1] + '+' + v2[1], v1[2] + '+' + v2[2]];
 41     	}
 42       if( JXG.isString(v1) && !v1.match(/JXG\.getRef\(JXG\.GeogebraReader\.board, "(.+?)"\)\./) && v1.match(/JXG\.getRef/) ) {
 43         s1 = [v1+'.X()', v1+'.Y()'];
 44       } else {
 45         s1 = v1;
 46       }
 47 
 48       if( JXG.isString(v2) && !v2.match(/JXG\.getRef\(JXG\.GeogebraReader\.board, "(.+?)"\)\./) && v2.match(/JXG\.getRef/) ) {
 49         s2 = [v2+'.X()', v2+'.Y()'];
 50       } else {
 51         s2 = v2;
 52       }
 53 
 54       if (JXG.GeogebraReader.isGGBVector(s1) && JXG.isArray(s2)){ //Add: Vector + Point
 55     	  return [s1[1] + '+' + s2[0], s1[2] + '+' + s2[1]];
 56   		}
 57 
 58       if (JXG.GeogebraReader.isGGBVector(s2) && JXG.isArray(s1)){ //Add: Vector + Point
 59     	  return [s2[1] + '+' + s1[0], s2[2] + '+' + s1[1]];
 60   		}
 61 
 62       if( JXG.isArray(s1) && JXG.isArray(s2) ) {
 63         return [ s1[0] +' + '+ s2[0], s1[1] +' + '+ s2[1] ];
 64       }
 65       else if( (JXG.isNumber(s1) || JXG.isString(s1)) && (JXG.isNumber(s2) || JXG.isString(s2)) ) {
 66         return s1 +' + '+ s2;
 67       }
 68       else if( (JXG.isNumber(s1) || JXG.isString(s1)) && JXG.isArray(s2) ) {
 69         return [ s1 +' + '+ s2[0], s1 +' + '+ s2[1] ];
 70       }
 71       else if( JXG.isArray(s1) && (JXG.isNumber(s2) || JXG.isString(s2)) ) {
 72         return [ s1[0] +' + '+ s2, s1[1] +' + '+ s2 ];
 73       }
 74       else {
 75         return s1 +' + '+ s2;
 76       }
 77     break;
 78     case 'sub':
 79     	if (JXG.GeogebraReader.isGGBVector(v1) && JXG.GeogebraReader.isGGBVector(v2)){ //Sub: Vector - Vector
 80     		return [1, v1[1] + '-' + v2[1], v1[2] + '-' + v2[2]];
 81     	}
 82 
 83       if( JXG.isString(v1) && !v1.match(/JXG\.getRef\(JXG\.GeogebraReader\.board, "(.+?)"\)\./) && v1.match(/JXG\.getRef/) ) {
 84         s1 = [v1+'.X()', v1+'.Y()'];
 85       } else {
 86         s1 = v1;
 87       }
 88 
 89       if( JXG.isString(v2) && !v2.match(/JXG\.getRef\(JXG\.GeogebraReader\.board, "(.+?)"\)\./) && v2.match(/JXG\.getRef/) ) {
 90         s2 = [v2+'.X()', v2+'.Y()'];
 91       } else {
 92         s2 = v2;
 93       }
 94 
 95       if (JXG.GeogebraReader.isGGBVector(s1) && JXG.isArray(s2)){ //Add: Vector - Point
 96     	  return [s1[1] + '-' + s2[0], s1[2] + '-' + s2[1]];
 97   		}
 98 
 99       if (JXG.isArray(s1) && JXG.GeogebraReader.isGGBVector(s2)){ //Add: Punkt - Vector
100     	  return [s1[0] + '-(' + s2[1] + ')', s1[1] + '-(' + s2[2] +')'];
101   		}
102 
103       if( JXG.isArray(s1) && JXG.isArray(s2) ) {
104         return [ s1[0] +' - '+ s2[0], s1[1] +' - '+ s2[1] ];
105       }
106       else if( (JXG.isNumber(s1) || JXG.isString(s1)) && (JXG.isNumber(s2) || JXG.isString(s2)) ) {
107         return s1 +' - '+ s2;
108       }
109       else if( (JXG.isNumber(s1) || JXG.isString(s1)) && JXG.isArray(s2) ) {
110         return [ s1 +' - '+ s2[0], s1 +' - '+ s2[1] ];
111       }
112       else if( JXG.isArray(s1) && (JXG.isNumber(s2) || JXG.isString(s2)) ) {
113         return [ s1[0] +' - '+ s2, s1[1] +' - '+ s2 ];
114       }
115       else {
116         return s1 +' - '+ s2;
117       }
118     break;
119     case 'neg':
120       return '!('+ v1 +')';
121     break;
122     case 'pow':
123       return 'Math.pow('+ v1 +', '+ v2 +')';
124     break;
125     case 'or':
126       return '('+ v1 +'||'+ v2 +')';
127     break;
128     case 'and':
129       return '('+ v1 +'&&'+ v2 +')';
130     break;
131     case 'mul':
132     	if (JXG.GeogebraReader.isGGBVector(v1) && !JXG.isArray(v2)){ // Mult: Vector * Skalar
133     		return [1,'(' + v1[1] + ')*'+v2,'(' + v1[2] + ')*'+v2];
134     	} else if (!JXG.isArray(v1) && JXG.GeogebraReader.isGGBVector(v2)){ // Mult: Skalar * Vector
135     		return new Array(1,'(' + v2[1] + ')*'+v1,'(' + v2[2] + ')*'+v1);
136     	} else if (JXG.GeogebraReader.isGGBVector(v1) && JXG.GeogebraReader.isGGBVector(v2)){ //Mult: Vector * Vector
137     		return '((' + v1[1] + ')*('+v2[1]+')+('+ v1[2] + ')*('+v2[2]+'))';
138     	} else { // Rest
139       if( JXG.isString(v1) && !v1.match(/JXG\.getRef\(JXG\.GeogebraReader\.board, "(.+?)"\)\./) && v1.match(/JXG\.getRef/) ) {
140 		        s1 = [v1+'.X()', v1+'.Y()'];
141 		      } else {
142 		    	s1 = v1;
143 		      }
144 
145       		if( JXG.isString(v2) && !v2.match(/JXG\.getRef\(JXG\.GeogebraReader\.board, "(.+?)"\)\./) && v2.match(/JXG\.getRef/) ) {
146 		        s2 = [v2+'.X()', v2+'.Y()'];
147 		      } else {
148 		        s2 = v2;
149 		      }
150 
151 		      if( JXG.isArray(s1) && JXG.isArray(s2) ) {
152 		        return [ s1[0] +' * '+ s2[0], s1[1] +' * '+ s2[1] ];
153 		      }
154 		      else if( (JXG.isNumber(s1) || JXG.isString(s1)) && (JXG.isNumber(s2) || JXG.isString(s2)) ) {
155 		        return s1 +' * '+ s2;
156 		      }
157 		      else if( (JXG.isNumber(s1) || JXG.isString(s1)) && JXG.isArray(s2) ) {
158 		        return [ s1 +' * '+ s2[0], s1 +' * '+ s2[1] ];
159 		      }
160 		      else if( JXG.isArray(s1) && (JXG.isNumber(s2) || JXG.isString(s2)) ) {
161 		        return [ s1[0] +' * '+ s2, s1[1] +' * '+ s2 ];
162 		      }
163 		      else {
164 		        return s1 +' * '+ s2;
165 		      }
166     	}
167     break;
168     case 'div':
169       if( JXG.isString(v1) && !v1.match(/JXG\.getRef\(JXG\.GeogebraReader\.board, "(.+?)"\)\./) && v1.match(/JXG\.getRef/) ) {
170         s1 = [v1+'.X()', v1+'.Y()'];
171       } else {
172         s1 = v1;
173       }
174 
175       if( JXG.isString(v2) && !v2.match(/JXG\.getRef\(JXG\.GeogebraReader\.board, "(.+?)"\)\./) && v2.match(/JXG\.getRef/) ) {
176         s2 = [v2+'.X()', v2+'.Y()'];
177       } else {
178         s2 = v2;
179       }
180 
181       if( JXG.isArray(s1) && JXG.isArray(s2) ) {
182         return [ s1[0] +' / '+ s2[0], s1[1] +' / '+ s2[1] ];
183       }
184       else if( (JXG.isNumber(s1) || JXG.isString(s1)) && (JXG.isNumber(s2) || JXG.isString(s2)) ) {
185         return s1 +' / '+ s2;
186       }
187       else if( (JXG.isNumber(s1) || JXG.isString(s1)) && JXG.isArray(s2) ) {
188         return [ s1 +' / '+ s2[0], s1 +' / '+ s2[1] ];
189       }
190       else if( JXG.isArray(s1) && (JXG.isNumber(s2) || JXG.isString(s2)) ) {
191         return [ s1[0] +' / '+ s2, s1[1] +' / '+ s2 ];
192       }
193       else {
194         return s1 +' / '+ s2;
195       }
196     break;
197     case 'negmult':
198     	if (JXG.GeogebraReader.isGGBVector(v1))
199     		return new Array(1, -1 + '*' + v1[1],-1 + '*' + v1[2]);
200       return -1 +'*'+ v1;
201     break;
202     case 'bra':
203     	if (JXG.GeogebraReader.isGGBVector(v1))
204     		return new Array(1,'(' + v1[1] + ')','(' + v1[2] + ')');
205       return '('+ v1 +')';
206     break;
207     case 'int':
208       return parseInt(v1);
209     break;
210     case 'float':
211       return parseFloat(v1);
212     break;
213     case 'param':
214       return v1;
215     break;
216     case 'html':
217       return v1;
218     break;
219     case 'string':
220       if(v2) return [v1, v2];
221       else   return v1;
222     break;
223     case 'command':
224       v2 = v1.split('[');
225       s1 = v2[0];
226       s2 = (v2[1].split(']'))[0];
227       switch(s1.toLowerCase()) {
228         case 'name':
229           return 'JXG.getRef(JXG.GeogebraReader.board, "'+ s2 +'").getName()'; //TODO korrigiere getName()
230         break;
231       }
232     break;
233     case 'var':
234       if(v2) {
235         switch(v1.toLowerCase()) {
236             case 'x':
237                 return v2 +'.X()';
238             break;
239             case 'y':
240                 return v2 +'.Y()';
241             break;
242             case 'abs':
243 			case 'acos':
244 			case 'asin':
245 			case 'atan':
246 			case 'ceil':
247 			case 'cos':
248 			case 'exp':
249 			case 'floor':
250 			case 'log':
251 			case 'max':
252 			case 'min':
253 			case 'pow':
254 			case 'random':
255 			case 'round':
256 			case 'sin':
257 			case 'sqrt':
258 			case 'tan':
259               return 'Math.'+v1.toLowerCase()+'('+ v2 +')';
260             break;
261             default:
262                 return v1.toLowerCase()+'*('+ v2 +')';
263             break;
264         }
265       } else {
266 
267         if(v1 == 'PI') {
268           return 'Math.PI';
269         } else {
270           a = JXG.GeogebraReader.checkElement(v1);
271           if(typeof JXG.GeogebraReader.board.ggb[v1] != 'undefined') {
272             return 'JXG.GeogebraReader.board.ggb["'+ v1 +'"]()';
273           } else if(typeof a.Value != 'undefined') {
274             return 'JXG.getRef(JXG.GeogebraReader.board, "'+ v1 +'").Value()';
275           } else if(typeof a.Area != 'undefined') {
276             return 'JXG.getRef(JXG.GeogebraReader.board, "'+ v1 +'").Area()';
277           } else if(typeof a.plaintextStr != 'undefined') {
278             return '1.0*JXG.getRef(JXG.GeogebraReader.board, "'+ v1 +'").plaintextStr';
279           } else if (a.type == JXG.OBJECT_TYPE_VECTOR){
280             return new Array(1, 'JXG.getRef(JXG.GeogebraReader.board, "'+ v1 +'").point2.X()-JXG.getRef(JXG.GeogebraReader.board, "'+ v1 +'").point1.X()','JXG.getRef(JXG.GeogebraReader.board, "'+ v1 +'").point2.Y()-JXG.getRef(JXG.GeogebraReader.board, "'+ v1 +'").point1.Y()');
281           }else if(a.elementClass == JXG.OBJECT_CLASS_LINE) {
282             return 'JXG.getRef(JXG.GeogebraReader.board, "'+ v1 +'").point1.Dist(JXG.getRef(JXG.GeogebraReader.board, "'+ v1 +'").point2)';
283           } else {
284             return 'JXG.getRef(JXG.GeogebraReader.board, "'+ v1 +'")';
285           }
286         }
287       }
288     break;
289   }
290 };
291 
292 /**
293  * JS/CC parser to convert the input expression to a working javascript function.
294  * @param {Object} board object
295  * @param {Object} element Element that needs to be updated
296  * @param {String} exp String which contains the function, expression or information
297  */
298 this.ggbParse = function(exp, element) {
299   var element = (element) ? JXG.getRef(JXG.GeogebraReader.board, JXG.GeogebraReader.board.ggbElements[element].id) : false;
300   if(element) JXG.debug("Zu aktualisierendes Element: "+ element.name + "("+ element.id +")");
301 
302 /*
303     This parser was generated with: The LALR(1) parser and lexical analyzer generator for JavaScript, written in JavaScript
304     In the version 0.30 on http://jscc.jmksf.com/
305 
306     It is based on the default template driver for JS/CC generated parsers running as
307     browser-based JavaScript/ECMAScript applications and was strongly modified.
308 
309     The parser was written 2007, 2008 by Jan Max Meyer, J.M.K S.F. Software Technologies
310     This is in the public domain.
311 */
312 
313 /***** begin replace *****/
314 	var _dbg_withtrace		= false;
315 	var _dbg_string			= new String();
316 
317 	function __dbg_print( text ) {
318 		_dbg_string += text + "\n";
319 	}
320 
321 	function __lex( info ) {
322 		var state		= 0;
323 		var match		= -1;
324 		var match_pos	= 0;
325 		var start		= 0;
326 		var pos			= info.offset + 1;
327 
328 		do
329 		{
330 			pos--;
331 			state = 0;
332 			match = -2;
333 			start = pos;
334 
335 			if( info.src.length <= start )
336 				return 28;
337 
338 			do
339 			{
340 
341 	switch( state )
342 	{
343 		case 0:
344 			if( info.src.charCodeAt( pos ) == 9 || info.src.charCodeAt( pos ) == 32 ) state = 1;
345 			else if( info.src.charCodeAt( pos ) == 33 ) state = 2;
346 			else if( info.src.charCodeAt( pos ) == 40 ) state = 3;
347 			else if( info.src.charCodeAt( pos ) == 41 ) state = 4;
348 			else if( info.src.charCodeAt( pos ) == 42 ) state = 5;
349 			else if( info.src.charCodeAt( pos ) == 43 ) state = 6;
350 			else if( info.src.charCodeAt( pos ) == 44 ) state = 7;
351 			else if( info.src.charCodeAt( pos ) == 45 ) state = 8;
352 			else if( info.src.charCodeAt( pos ) == 47 ) state = 9;
353 			else if( ( info.src.charCodeAt( pos ) >= 48 && info.src.charCodeAt( pos ) <= 57 ) ) state = 10;
354 			else if( info.src.charCodeAt( pos ) == 60 ) state = 11;
355 			else if( info.src.charCodeAt( pos ) == 62 ) state = 12;
356 			else if( ( info.src.charCodeAt( pos ) >= 65 && info.src.charCodeAt( pos ) <= 90 ) || ( info.src.charCodeAt( pos ) >= 97 && info.src.charCodeAt( pos ) <= 122 ) ) state = 13;
357 			else if( info.src.charCodeAt( pos ) == 94 ) state = 14;
358 			else if( info.src.charCodeAt( pos ) == 34 ) state = 26;
359 			else if( info.src.charCodeAt( pos ) == 38 ) state = 28;
360 			else if( info.src.charCodeAt( pos ) == 46 ) state = 29;
361 			else if( info.src.charCodeAt( pos ) == 61 ) state = 30;
362 			else if( info.src.charCodeAt( pos ) == 95 ) state = 31;
363 			else if( info.src.charCodeAt( pos ) == 124 ) state = 32;
364 			else state = -1;
365 			break;
366 
367 		case 1:
368 			state = -1;
369 			match = 1;
370 			match_pos = pos;
371 			break;
372 
373 		case 2:
374 			if( info.src.charCodeAt( pos ) == 61 ) state = 15;
375 			else state = -1;
376 			match = 23;
377 			match_pos = pos;
378 			break;
379 
380 		case 3:
381 			state = -1;
382 			match = 2;
383 			match_pos = pos;
384 			break;
385 
386 		case 4:
387 			state = -1;
388 			match = 3;
389 			match_pos = pos;
390 			break;
391 
392 		case 5:
393 			state = -1;
394 			match = 13;
395 			match_pos = pos;
396 			break;
397 
398 		case 6:
399 			state = -1;
400 			match = 11;
401 			match_pos = pos;
402 			break;
403 
404 		case 7:
405 			state = -1;
406 			match = 16;
407 			match_pos = pos;
408 			break;
409 
410 		case 8:
411 			state = -1;
412 			match = 12;
413 			match_pos = pos;
414 			break;
415 
416 		case 9:
417 			state = -1;
418 			match = 14;
419 			match_pos = pos;
420 			break;
421 
422 		case 10:
423 			if( ( info.src.charCodeAt( pos ) >= 48 && info.src.charCodeAt( pos ) <= 57 ) ) state = 10;
424 			else if( info.src.charCodeAt( pos ) == 46 ) state = 18;
425 			else state = -1;
426 			match = 4;
427 			match_pos = pos;
428 			break;
429 
430 		case 11:
431 			if( info.src.charCodeAt( pos ) == 61 ) state = 19;
432 			else state = -1;
433 			match = 21;
434 			match_pos = pos;
435 			break;
436 
437 		case 12:
438 			if( info.src.charCodeAt( pos ) == 61 ) state = 21;
439 			else state = -1;
440 			match = 22;
441 			match_pos = pos;
442 			break;
443 
444 		case 13:
445 			if( ( info.src.charCodeAt( pos ) >= 65 && info.src.charCodeAt( pos ) <= 90 ) || ( info.src.charCodeAt( pos ) >= 97 && info.src.charCodeAt( pos ) <= 122 ) ) state = 13;
446 			else if( ( info.src.charCodeAt( pos ) >= 48 && info.src.charCodeAt( pos ) <= 57 ) ) state = 27;
447 			else if( info.src.charCodeAt( pos ) == 91 ) state = 34;
448 			else if( info.src.charCodeAt( pos ) == 95 ) state = 35;
449 			else state = -1;
450 			match = 7;
451 			match_pos = pos;
452 			break;
453 
454 		case 14:
455 			state = -1;
456 			match = 15;
457 			match_pos = pos;
458 			break;
459 
460 		case 15:
461 			state = -1;
462 			match = 20;
463 			match_pos = pos;
464 			break;
465 
466 		case 16:
467 			state = -1;
468 			match = 9;
469 			match_pos = pos;
470 			break;
471 
472 		case 17:
473 			state = -1;
474 			match = 25;
475 			match_pos = pos;
476 			break;
477 
478 		case 18:
479 			if( ( info.src.charCodeAt( pos ) >= 48 && info.src.charCodeAt( pos ) <= 57 ) ) state = 18;
480 			else state = -1;
481 			match = 5;
482 			match_pos = pos;
483 			break;
484 
485 		case 19:
486 			state = -1;
487 			match = 17;
488 			match_pos = pos;
489 			break;
490 
491 		case 20:
492 			state = -1;
493 			match = 19;
494 			match_pos = pos;
495 			break;
496 
497 		case 21:
498 			state = -1;
499 			match = 18;
500 			match_pos = pos;
501 			break;
502 
503 		case 22:
504 			state = -1;
505 			match = 24;
506 			match_pos = pos;
507 			break;
508 
509 		case 23:
510 			state = -1;
511 			match = 8;
512 			match_pos = pos;
513 			break;
514 
515 		case 24:
516 			if( ( info.src.charCodeAt( pos ) >= 48 && info.src.charCodeAt( pos ) <= 57 ) || ( info.src.charCodeAt( pos ) >= 65 && info.src.charCodeAt( pos ) <= 90 ) || ( info.src.charCodeAt( pos ) >= 97 && info.src.charCodeAt( pos ) <= 122 ) ) state = 24;
517 			else state = -1;
518 			match = 6;
519 			match_pos = pos;
520 			break;
521 
522 		case 25:
523 			state = -1;
524 			match = 10;
525 			match_pos = pos;
526 			break;
527 
528 		case 26:
529 			if( info.src.charCodeAt( pos ) == 34 ) state = 16;
530 			else if( info.src.charCodeAt( pos ) == 32 || info.src.charCodeAt( pos ) == 46 || ( info.src.charCodeAt( pos ) >= 48 && info.src.charCodeAt( pos ) <= 57 ) || info.src.charCodeAt( pos ) == 61 || ( info.src.charCodeAt( pos ) >= 65 && info.src.charCodeAt( pos ) <= 90 ) || ( info.src.charCodeAt( pos ) >= 97 && info.src.charCodeAt( pos ) <= 122 ) || info.src.charCodeAt( pos ) == 223 || info.src.charCodeAt( pos ) == 228 || info.src.charCodeAt( pos ) == 246 || info.src.charCodeAt( pos ) == 252 ) state = 26;
531 			else state = -1;
532 			break;
533 
534 		case 27:
535 			if( ( info.src.charCodeAt( pos ) >= 48 && info.src.charCodeAt( pos ) <= 57 ) || ( info.src.charCodeAt( pos ) >= 65 && info.src.charCodeAt( pos ) <= 90 ) || ( info.src.charCodeAt( pos ) >= 97 && info.src.charCodeAt( pos ) <= 122 ) ) state = 27;
536 			else if( info.src.charCodeAt( pos ) == 95 ) state = 35;
537 			else state = -1;
538 			match = 7;
539 			match_pos = pos;
540 			break;
541 
542 		case 28:
543 			if( info.src.charCodeAt( pos ) == 38 ) state = 17;
544 			else if( ( info.src.charCodeAt( pos ) >= 65 && info.src.charCodeAt( pos ) <= 90 ) || ( info.src.charCodeAt( pos ) >= 97 && info.src.charCodeAt( pos ) <= 122 ) ) state = 33;
545 			else state = -1;
546 			break;
547 
548 		case 29:
549 			if( ( info.src.charCodeAt( pos ) >= 48 && info.src.charCodeAt( pos ) <= 57 ) ) state = 18;
550 			else state = -1;
551 			break;
552 
553 		case 30:
554 			if( info.src.charCodeAt( pos ) == 61 ) state = 20;
555 			else state = -1;
556 			break;
557 
558 		case 31:
559 			if( info.src.charCodeAt( pos ) == 95 ) state = 36;
560 			else state = -1;
561 			break;
562 
563 		case 32:
564 			if( info.src.charCodeAt( pos ) == 124 ) state = 22;
565 			else state = -1;
566 			break;
567 
568 		case 33:
569 			if( info.src.charCodeAt( pos ) == 59 ) state = 23;
570 			else if( ( info.src.charCodeAt( pos ) >= 65 && info.src.charCodeAt( pos ) <= 90 ) || ( info.src.charCodeAt( pos ) >= 97 && info.src.charCodeAt( pos ) <= 122 ) ) state = 33;
571 			else state = -1;
572 			break;
573 
574 		case 34:
575 			if( ( info.src.charCodeAt( pos ) >= 65 && info.src.charCodeAt( pos ) <= 90 ) || ( info.src.charCodeAt( pos ) >= 97 && info.src.charCodeAt( pos ) <= 122 ) ) state = 37;
576 			else state = -1;
577 			break;
578 
579 		case 35:
580 			if( ( info.src.charCodeAt( pos ) >= 48 && info.src.charCodeAt( pos ) <= 57 ) || ( info.src.charCodeAt( pos ) >= 65 && info.src.charCodeAt( pos ) <= 90 ) || ( info.src.charCodeAt( pos ) >= 97 && info.src.charCodeAt( pos ) <= 122 ) ) state = 27;
581 			else if( info.src.charCodeAt( pos ) == 95 ) state = 35;
582 			else state = -1;
583 			break;
584 
585 		case 36:
586 			if( ( info.src.charCodeAt( pos ) >= 48 && info.src.charCodeAt( pos ) <= 57 ) || ( info.src.charCodeAt( pos ) >= 65 && info.src.charCodeAt( pos ) <= 90 ) || ( info.src.charCodeAt( pos ) >= 97 && info.src.charCodeAt( pos ) <= 122 ) ) state = 24;
587 			else state = -1;
588 			break;
589 
590 		case 37:
591 			if( info.src.charCodeAt( pos ) == 93 ) state = 25;
592 			else if( ( info.src.charCodeAt( pos ) >= 65 && info.src.charCodeAt( pos ) <= 90 ) || ( info.src.charCodeAt( pos ) >= 97 && info.src.charCodeAt( pos ) <= 122 ) ) state = 37;
593 			else state = -1;
594 			break;
595 
596 	}
597 
598 
599 				pos++;
600 
601 			}
602 			while( state > -1 );
603 
604 		}
605 		while( 1 > -1 && match == 1 );
606 
607 		if( match > -1 )
608 		{
609 			info.att = info.src.substr( start, match_pos - start );
610 			info.offset = match_pos;
611 
612 
613 		}
614 		else
615 		{
616 			info.att = new String();
617 			match = -1;
618 		}
619 
620 		return match;
621 	}
622 
623 
624 	function __parse( src, err_off, err_la ) {
625 		var		sstack			= new Array();
626 		var		vstack			= new Array();
627 		var 	err_cnt			= 0;
628 		var		act;
629 		var		go;
630 		var		la;
631 		var		rval;
632 		var 	parseinfo		= new Function( "", "var offset; var src; var att;" );
633 		var		info			= new parseinfo();
634 
635 	/* Pop-Table */
636 	var pop_tab = new Array(
637 		new Array( 0/* p' */, 1 ),
638 		new Array( 27/* p */, 1 ),
639 		new Array( 26/* e */, 5 ),
640 		new Array( 26/* e */, 3 ),
641 		new Array( 26/* e */, 3 ),
642 		new Array( 26/* e */, 3 ),
643 		new Array( 26/* e */, 3 ),
644 		new Array( 26/* e */, 3 ),
645 		new Array( 26/* e */, 3 ),
646 		new Array( 26/* e */, 3 ),
647 		new Array( 26/* e */, 3 ),
648 		new Array( 26/* e */, 2 ),
649 		new Array( 26/* e */, 3 ),
650 		new Array( 26/* e */, 3 ),
651 		new Array( 26/* e */, 3 ),
652 		new Array( 26/* e */, 3 ),
653 		new Array( 26/* e */, 3 ),
654 		new Array( 26/* e */, 2 ),
655 		new Array( 26/* e */, 3 ),
656 		new Array( 26/* e */, 3 ),
657 		new Array( 26/* e */, 1 ),
658 		new Array( 26/* e */, 1 ),
659 		new Array( 26/* e */, 1 ),
660 		new Array( 26/* e */, 1 ),
661 		new Array( 26/* e */, 1 ),
662 		new Array( 26/* e */, 1 ),
663 		new Array( 26/* e */, 4 ),
664 		new Array( 26/* e */, 1 )
665 	);
666 
667 	/* Action-Table */
668 	var act_tab = new Array(
669 		/* State 0 */ new Array( 2/* "(" */,3 , 23/* "!" */,4 , 12/* "-" */,5 , 9/* "STRING" */,6 , 4/* "INT" */,7 , 5/* "FLOAT" */,8 , 6/* "PARAM" */,9 , 8/* "HTML" */,10 , 10/* "COMMAND" */,11 , 7/* "VAR" */,12 ),
670 		/* State 1 */ new Array( 28/* "$" */,0 ),
671 		/* State 2 */ new Array( 14/* "/" */,13 , 13/* "*" */,14 , 25/* "&&" */,15 , 24/* "||" */,16 , 15/* "^" */,17 , 12/* "-" */,18 , 11/* "+" */,19 , 22/* ">" */,20 , 21/* "<" */,21 , 20/* "!=" */,22 , 19/* "==" */,23 , 18/* ">=" */,24 , 17/* "<=" */,25 , 28/* "$" */,-1 ),
672 		/* State 3 */ new Array( 2/* "(" */,3 , 23/* "!" */,4 , 12/* "-" */,5 , 9/* "STRING" */,6 , 4/* "INT" */,7 , 5/* "FLOAT" */,8 , 6/* "PARAM" */,9 , 8/* "HTML" */,10 , 10/* "COMMAND" */,11 , 7/* "VAR" */,12 ),
673 		/* State 4 */ new Array( 2/* "(" */,3 , 23/* "!" */,4 , 12/* "-" */,5 , 9/* "STRING" */,6 , 4/* "INT" */,7 , 5/* "FLOAT" */,8 , 6/* "PARAM" */,9 , 8/* "HTML" */,10 , 10/* "COMMAND" */,11 , 7/* "VAR" */,12 ),
674 		/* State 5 */ new Array( 2/* "(" */,3 , 23/* "!" */,4 , 12/* "-" */,5 , 9/* "STRING" */,6 , 4/* "INT" */,7 , 5/* "FLOAT" */,8 , 6/* "PARAM" */,9 , 8/* "HTML" */,10 , 10/* "COMMAND" */,11 , 7/* "VAR" */,12 ),
675 		/* State 6 */ new Array( 11/* "+" */,29 , 28/* "$" */,-24 , 17/* "<=" */,-24 , 18/* ">=" */,-24 , 19/* "==" */,-24 , 20/* "!=" */,-24 , 21/* "<" */,-24 , 22/* ">" */,-24 , 12/* "-" */,-24 , 15/* "^" */,-24 , 24/* "||" */,-24 , 25/* "&&" */,-24 , 13/* "*" */,-24 , 14/* "/" */,-24 , 16/* "," */,-24 , 3/* ")" */,-24 ),
676 		/* State 7 */ new Array( 28/* "$" */,-20 , 17/* "<=" */,-20 , 18/* ">=" */,-20 , 19/* "==" */,-20 , 20/* "!=" */,-20 , 21/* "<" */,-20 , 22/* ">" */,-20 , 11/* "+" */,-20 , 12/* "-" */,-20 , 15/* "^" */,-20 , 24/* "||" */,-20 , 25/* "&&" */,-20 , 13/* "*" */,-20 , 14/* "/" */,-20 , 16/* "," */,-20 , 3/* ")" */,-20 ),
677 		/* State 8 */ new Array( 28/* "$" */,-21 , 17/* "<=" */,-21 , 18/* ">=" */,-21 , 19/* "==" */,-21 , 20/* "!=" */,-21 , 21/* "<" */,-21 , 22/* ">" */,-21 , 11/* "+" */,-21 , 12/* "-" */,-21 , 15/* "^" */,-21 , 24/* "||" */,-21 , 25/* "&&" */,-21 , 13/* "*" */,-21 , 14/* "/" */,-21 , 16/* "," */,-21 , 3/* ")" */,-21 ),
678 		/* State 9 */ new Array( 28/* "$" */,-22 , 17/* "<=" */,-22 , 18/* ">=" */,-22 , 19/* "==" */,-22 , 20/* "!=" */,-22 , 21/* "<" */,-22 , 22/* ">" */,-22 , 11/* "+" */,-22 , 12/* "-" */,-22 , 15/* "^" */,-22 , 24/* "||" */,-22 , 25/* "&&" */,-22 , 13/* "*" */,-22 , 14/* "/" */,-22 , 16/* "," */,-22 , 3/* ")" */,-22 ),
679 		/* State 10 */ new Array( 28/* "$" */,-23 , 17/* "<=" */,-23 , 18/* ">=" */,-23 , 19/* "==" */,-23 , 20/* "!=" */,-23 , 21/* "<" */,-23 , 22/* ">" */,-23 , 11/* "+" */,-23 , 12/* "-" */,-23 , 15/* "^" */,-23 , 24/* "||" */,-23 , 25/* "&&" */,-23 , 13/* "*" */,-23 , 14/* "/" */,-23 , 16/* "," */,-23 , 3/* ")" */,-23 ),
680 		/* State 11 */ new Array( 28/* "$" */,-25 , 17/* "<=" */,-25 , 18/* ">=" */,-25 , 19/* "==" */,-25 , 20/* "!=" */,-25 , 21/* "<" */,-25 , 22/* ">" */,-25 , 11/* "+" */,-25 , 12/* "-" */,-25 , 15/* "^" */,-25 , 24/* "||" */,-25 , 25/* "&&" */,-25 , 13/* "*" */,-25 , 14/* "/" */,-25 , 16/* "," */,-25 , 3/* ")" */,-25 ),
681 		/* State 12 */ new Array( 2/* "(" */,30 , 28/* "$" */,-27 , 17/* "<=" */,-27 , 18/* ">=" */,-27 , 19/* "==" */,-27 , 20/* "!=" */,-27 , 21/* "<" */,-27 , 22/* ">" */,-27 , 11/* "+" */,-27 , 12/* "-" */,-27 , 15/* "^" */,-27 , 24/* "||" */,-27 , 25/* "&&" */,-27 , 13/* "*" */,-27 , 14/* "/" */,-27 , 16/* "," */,-27 , 3/* ")" */,-27 ),
682 		/* State 13 */ new Array( 2/* "(" */,3 , 23/* "!" */,4 , 12/* "-" */,5 , 9/* "STRING" */,6 , 4/* "INT" */,7 , 5/* "FLOAT" */,8 , 6/* "PARAM" */,9 , 8/* "HTML" */,10 , 10/* "COMMAND" */,11 , 7/* "VAR" */,12 ),
683 		/* State 14 */ new Array( 2/* "(" */,3 , 23/* "!" */,4 , 12/* "-" */,5 , 9/* "STRING" */,6 , 4/* "INT" */,7 , 5/* "FLOAT" */,8 , 6/* "PARAM" */,9 , 8/* "HTML" */,10 , 10/* "COMMAND" */,11 , 7/* "VAR" */,12 ),
684 		/* State 15 */ new Array( 2/* "(" */,3 , 23/* "!" */,4 , 12/* "-" */,5 , 9/* "STRING" */,6 , 4/* "INT" */,7 , 5/* "FLOAT" */,8 , 6/* "PARAM" */,9 , 8/* "HTML" */,10 , 10/* "COMMAND" */,11 , 7/* "VAR" */,12 ),
685 		/* State 16 */ new Array( 2/* "(" */,3 , 23/* "!" */,4 , 12/* "-" */,5 , 9/* "STRING" */,6 , 4/* "INT" */,7 , 5/* "FLOAT" */,8 , 6/* "PARAM" */,9 , 8/* "HTML" */,10 , 10/* "COMMAND" */,11 , 7/* "VAR" */,12 ),
686 		/* State 17 */ new Array( 2/* "(" */,3 , 23/* "!" */,4 , 12/* "-" */,5 , 9/* "STRING" */,6 , 4/* "INT" */,7 , 5/* "FLOAT" */,8 , 6/* "PARAM" */,9 , 8/* "HTML" */,10 , 10/* "COMMAND" */,11 , 7/* "VAR" */,12 ),
687 		/* State 18 */ new Array( 2/* "(" */,3 , 23/* "!" */,4 , 12/* "-" */,5 , 9/* "STRING" */,6 , 4/* "INT" */,7 , 5/* "FLOAT" */,8 , 6/* "PARAM" */,9 , 8/* "HTML" */,10 , 10/* "COMMAND" */,11 , 7/* "VAR" */,12 ),
688 		/* State 19 */ new Array( 2/* "(" */,3 , 23/* "!" */,4 , 12/* "-" */,5 , 9/* "STRING" */,6 , 4/* "INT" */,7 , 5/* "FLOAT" */,8 , 6/* "PARAM" */,9 , 8/* "HTML" */,10 , 10/* "COMMAND" */,11 , 7/* "VAR" */,12 ),
689 		/* State 20 */ new Array( 2/* "(" */,3 , 23/* "!" */,4 , 12/* "-" */,5 , 9/* "STRING" */,6 , 4/* "INT" */,7 , 5/* "FLOAT" */,8 , 6/* "PARAM" */,9 , 8/* "HTML" */,10 , 10/* "COMMAND" */,11 , 7/* "VAR" */,12 ),
690 		/* State 21 */ new Array( 2/* "(" */,3 , 23/* "!" */,4 , 12/* "-" */,5 , 9/* "STRING" */,6 , 4/* "INT" */,7 , 5/* "FLOAT" */,8 , 6/* "PARAM" */,9 , 8/* "HTML" */,10 , 10/* "COMMAND" */,11 , 7/* "VAR" */,12 ),
691 		/* State 22 */ new Array( 2/* "(" */,3 , 23/* "!" */,4 , 12/* "-" */,5 , 9/* "STRING" */,6 , 4/* "INT" */,7 , 5/* "FLOAT" */,8 , 6/* "PARAM" */,9 , 8/* "HTML" */,10 , 10/* "COMMAND" */,11 , 7/* "VAR" */,12 ),
692 		/* State 23 */ new Array( 2/* "(" */,3 , 23/* "!" */,4 , 12/* "-" */,5 , 9/* "STRING" */,6 , 4/* "INT" */,7 , 5/* "FLOAT" */,8 , 6/* "PARAM" */,9 , 8/* "HTML" */,10 , 10/* "COMMAND" */,11 , 7/* "VAR" */,12 ),
693 		/* State 24 */ new Array( 2/* "(" */,3 , 23/* "!" */,4 , 12/* "-" */,5 , 9/* "STRING" */,6 , 4/* "INT" */,7 , 5/* "FLOAT" */,8 , 6/* "PARAM" */,9 , 8/* "HTML" */,10 , 10/* "COMMAND" */,11 , 7/* "VAR" */,12 ),
694 		/* State 25 */ new Array( 2/* "(" */,3 , 23/* "!" */,4 , 12/* "-" */,5 , 9/* "STRING" */,6 , 4/* "INT" */,7 , 5/* "FLOAT" */,8 , 6/* "PARAM" */,9 , 8/* "HTML" */,10 , 10/* "COMMAND" */,11 , 7/* "VAR" */,12 ),
695 		/* State 26 */ new Array( 14/* "/" */,13 , 13/* "*" */,14 , 25/* "&&" */,15 , 24/* "||" */,16 , 15/* "^" */,17 , 12/* "-" */,18 , 11/* "+" */,19 , 22/* ">" */,20 , 21/* "<" */,21 , 20/* "!=" */,22 , 19/* "==" */,23 , 18/* ">=" */,24 , 17/* "<=" */,25 , 16/* "," */,44 , 3/* ")" */,45 ),
696 		/* State 27 */ new Array( 14/* "/" */,-11 , 13/* "*" */,-11 , 25/* "&&" */,15 , 24/* "||" */,16 , 15/* "^" */,-11 , 12/* "-" */,-11 , 11/* "+" */,-11 , 22/* ">" */,-11 , 21/* "<" */,-11 , 20/* "!=" */,-11 , 19/* "==" */,-11 , 18/* ">=" */,-11 , 17/* "<=" */,-11 , 28/* "$" */,-11 , 16/* "," */,-11 , 3/* ")" */,-11 ),
697 		/* State 28 */ new Array( 14/* "/" */,-17 , 13/* "*" */,-17 , 25/* "&&" */,15 , 24/* "||" */,16 , 15/* "^" */,17 , 12/* "-" */,-17 , 11/* "+" */,-17 , 22/* ">" */,20 , 21/* "<" */,21 , 20/* "!=" */,22 , 19/* "==" */,23 , 18/* ">=" */,24 , 17/* "<=" */,25 , 28/* "$" */,-17 , 16/* "," */,-17 , 3/* ")" */,-17 ),
698 		/* State 29 */ new Array( 2/* "(" */,3 , 23/* "!" */,4 , 12/* "-" */,5 , 9/* "STRING" */,6 , 4/* "INT" */,7 , 5/* "FLOAT" */,8 , 6/* "PARAM" */,9 , 8/* "HTML" */,10 , 10/* "COMMAND" */,11 , 7/* "VAR" */,12 ),
699 		/* State 30 */ new Array( 2/* "(" */,3 , 23/* "!" */,4 , 12/* "-" */,5 , 9/* "STRING" */,6 , 4/* "INT" */,7 , 5/* "FLOAT" */,8 , 6/* "PARAM" */,9 , 8/* "HTML" */,10 , 10/* "COMMAND" */,11 , 7/* "VAR" */,12 ),
700 		/* State 31 */ new Array( 14/* "/" */,-16 , 13/* "*" */,-16 , 25/* "&&" */,15 , 24/* "||" */,16 , 15/* "^" */,17 , 12/* "-" */,-16 , 11/* "+" */,-16 , 22/* ">" */,20 , 21/* "<" */,21 , 20/* "!=" */,22 , 19/* "==" */,23 , 18/* ">=" */,24 , 17/* "<=" */,25 , 28/* "$" */,-16 , 16/* "," */,-16 , 3/* ")" */,-16 ),
701 		/* State 32 */ new Array( 14/* "/" */,-15 , 13/* "*" */,-15 , 25/* "&&" */,15 , 24/* "||" */,16 , 15/* "^" */,17 , 12/* "-" */,-15 , 11/* "+" */,-15 , 22/* ">" */,20 , 21/* "<" */,21 , 20/* "!=" */,22 , 19/* "==" */,23 , 18/* ">=" */,24 , 17/* "<=" */,25 , 28/* "$" */,-15 , 16/* "," */,-15 , 3/* ")" */,-15 ),
702 		/* State 33 */ new Array( 14/* "/" */,-14 , 13/* "*" */,-14 , 25/* "&&" */,-14 , 24/* "||" */,-14 , 15/* "^" */,-14 , 12/* "-" */,-14 , 11/* "+" */,-14 , 22/* ">" */,-14 , 21/* "<" */,-14 , 20/* "!=" */,-14 , 19/* "==" */,-14 , 18/* ">=" */,-14 , 17/* "<=" */,-14 , 28/* "$" */,-14 , 16/* "," */,-14 , 3/* ")" */,-14 ),
703 		/* State 34 */ new Array( 14/* "/" */,-13 , 13/* "*" */,-13 , 25/* "&&" */,-13 , 24/* "||" */,-13 , 15/* "^" */,-13 , 12/* "-" */,-13 , 11/* "+" */,-13 , 22/* ">" */,-13 , 21/* "<" */,-13 , 20/* "!=" */,-13 , 19/* "==" */,-13 , 18/* ">=" */,-13 , 17/* "<=" */,-13 , 28/* "$" */,-13 , 16/* "," */,-13 , 3/* ")" */,-13 ),
704 		/* State 35 */ new Array( 14/* "/" */,-12 , 13/* "*" */,-12 , 25/* "&&" */,15 , 24/* "||" */,16 , 15/* "^" */,-12 , 12/* "-" */,-12 , 11/* "+" */,-12 , 22/* ">" */,20 , 21/* "<" */,21 , 20/* "!=" */,22 , 19/* "==" */,23 , 18/* ">=" */,24 , 17/* "<=" */,25 , 28/* "$" */,-12 , 16/* "," */,-12 , 3/* ")" */,-12 ),
705 		/* State 36 */ new Array( 14/* "/" */,13 , 13/* "*" */,14 , 25/* "&&" */,15 , 24/* "||" */,16 , 15/* "^" */,17 , 12/* "-" */,-10 , 11/* "+" */,-10 , 22/* ">" */,20 , 21/* "<" */,21 , 20/* "!=" */,22 , 19/* "==" */,23 , 18/* ">=" */,24 , 17/* "<=" */,25 , 28/* "$" */,-10 , 16/* "," */,-10 , 3/* ")" */,-10 ),
706 		/* State 37 */ new Array( 14/* "/" */,13 , 13/* "*" */,14 , 25/* "&&" */,15 , 24/* "||" */,16 , 15/* "^" */,17 , 12/* "-" */,-9 , 11/* "+" */,-9 , 22/* ">" */,20 , 21/* "<" */,21 , 20/* "!=" */,22 , 19/* "==" */,23 , 18/* ">=" */,24 , 17/* "<=" */,25 , 28/* "$" */,-9 , 16/* "," */,-9 , 3/* ")" */,-9 ),
707 		/* State 38 */ new Array( 14/* "/" */,-8 , 13/* "*" */,-8 , 25/* "&&" */,15 , 24/* "||" */,16 , 15/* "^" */,-8 , 12/* "-" */,-8 , 11/* "+" */,-8 , 22/* ">" */,-8 , 21/* "<" */,-8 , 20/* "!=" */,-8 , 19/* "==" */,-8 , 18/* ">=" */,-8 , 17/* "<=" */,-8 , 28/* "$" */,-8 , 16/* "," */,-8 , 3/* ")" */,-8 ),
708 		/* State 39 */ new Array( 14/* "/" */,-7 , 13/* "*" */,-7 , 25/* "&&" */,15 , 24/* "||" */,16 , 15/* "^" */,-7 , 12/* "-" */,-7 , 11/* "+" */,-7 , 22/* ">" */,-7 , 21/* "<" */,-7 , 20/* "!=" */,-7 , 19/* "==" */,-7 , 18/* ">=" */,-7 , 17/* "<=" */,-7 , 28/* "$" */,-7 , 16/* "," */,-7 , 3/* ")" */,-7 ),
709 		/* State 40 */ new Array( 14/* "/" */,-6 , 13/* "*" */,-6 , 25/* "&&" */,15 , 24/* "||" */,16 , 15/* "^" */,-6 , 12/* "-" */,-6 , 11/* "+" */,-6 , 22/* ">" */,-6 , 21/* "<" */,-6 , 20/* "!=" */,-6 , 19/* "==" */,-6 , 18/* ">=" */,-6 , 17/* "<=" */,-6 , 28/* "$" */,-6 , 16/* "," */,-6 , 3/* ")" */,-6 ),
710 		/* State 41 */ new Array( 14/* "/" */,-5 , 13/* "*" */,-5 , 25/* "&&" */,15 , 24/* "||" */,16 , 15/* "^" */,-5 , 12/* "-" */,-5 , 11/* "+" */,-5 , 22/* ">" */,-5 , 21/* "<" */,-5 , 20/* "!=" */,-5 , 19/* "==" */,-5 , 18/* ">=" */,-5 , 17/* "<=" */,-5 , 28/* "$" */,-5 , 16/* "," */,-5 , 3/* ")" */,-5 ),
711 		/* State 42 */ new Array( 14/* "/" */,-4 , 13/* "*" */,-4 , 25/* "&&" */,15 , 24/* "||" */,16 , 15/* "^" */,-4 , 12/* "-" */,-4 , 11/* "+" */,-4 , 22/* ">" */,-4 , 21/* "<" */,-4 , 20/* "!=" */,-4 , 19/* "==" */,-4 , 18/* ">=" */,-4 , 17/* "<=" */,-4 , 28/* "$" */,-4 , 16/* "," */,-4 , 3/* ")" */,-4 ),
712 		/* State 43 */ new Array( 14/* "/" */,-3 , 13/* "*" */,-3 , 25/* "&&" */,15 , 24/* "||" */,16 , 15/* "^" */,-3 , 12/* "-" */,-3 , 11/* "+" */,-3 , 22/* ">" */,-3 , 21/* "<" */,-3 , 20/* "!=" */,-3 , 19/* "==" */,-3 , 18/* ">=" */,-3 , 17/* "<=" */,-3 , 28/* "$" */,-3 , 16/* "," */,-3 , 3/* ")" */,-3 ),
713 		/* State 44 */ new Array( 2/* "(" */,3 , 23/* "!" */,4 , 12/* "-" */,5 , 9/* "STRING" */,6 , 4/* "INT" */,7 , 5/* "FLOAT" */,8 , 6/* "PARAM" */,9 , 8/* "HTML" */,10 , 10/* "COMMAND" */,11 , 7/* "VAR" */,12 ),
714 		/* State 45 */ new Array( 28/* "$" */,-18 , 17/* "<=" */,-18 , 18/* ">=" */,-18 , 19/* "==" */,-18 , 20/* "!=" */,-18 , 21/* "<" */,-18 , 22/* ">" */,-18 , 11/* "+" */,-18 , 12/* "-" */,-18 , 15/* "^" */,-18 , 24/* "||" */,-18 , 25/* "&&" */,-18 , 13/* "*" */,-18 , 14/* "/" */,-18 , 16/* "," */,-18 , 3/* ")" */,-18 ),
715 		/* State 46 */ new Array( 14/* "/" */,13 , 13/* "*" */,14 , 25/* "&&" */,15 , 24/* "||" */,16 , 15/* "^" */,17 , 12/* "-" */,-19 , 11/* "+" */,-19 , 22/* ">" */,20 , 21/* "<" */,21 , 20/* "!=" */,22 , 19/* "==" */,23 , 18/* ">=" */,24 , 17/* "<=" */,25 , 28/* "$" */,-19 , 16/* "," */,-19 , 3/* ")" */,-19 ),
716 		/* State 47 */ new Array( 14/* "/" */,13 , 13/* "*" */,14 , 25/* "&&" */,15 , 24/* "||" */,16 , 15/* "^" */,17 , 12/* "-" */,18 , 11/* "+" */,19 , 22/* ">" */,20 , 21/* "<" */,21 , 20/* "!=" */,22 , 19/* "==" */,23 , 18/* ">=" */,24 , 17/* "<=" */,25 , 3/* ")" */,49 ),
717 		/* State 48 */ new Array( 14/* "/" */,13 , 13/* "*" */,14 , 25/* "&&" */,15 , 24/* "||" */,16 , 15/* "^" */,17 , 12/* "-" */,18 , 11/* "+" */,19 , 22/* ">" */,20 , 21/* "<" */,21 , 20/* "!=" */,22 , 19/* "==" */,23 , 18/* ">=" */,24 , 17/* "<=" */,25 , 3/* ")" */,50 ),
718 		/* State 49 */ new Array( 28/* "$" */,-26 , 17/* "<=" */,-26 , 18/* ">=" */,-26 , 19/* "==" */,-26 , 20/* "!=" */,-26 , 21/* "<" */,-26 , 22/* ">" */,-26 , 11/* "+" */,-26 , 12/* "-" */,-26 , 15/* "^" */,-26 , 24/* "||" */,-26 , 25/* "&&" */,-26 , 13/* "*" */,-26 , 14/* "/" */,-26 , 16/* "," */,-26 , 3/* ")" */,-26 ),
719 		/* State 50 */ new Array( 28/* "$" */,-2 , 17/* "<=" */,-2 , 18/* ">=" */,-2 , 19/* "==" */,-2 , 20/* "!=" */,-2 , 21/* "<" */,-2 , 22/* ">" */,-2 , 11/* "+" */,-2 , 12/* "-" */,-2 , 15/* "^" */,-2 , 24/* "||" */,-2 , 25/* "&&" */,-2 , 13/* "*" */,-2 , 14/* "/" */,-2 , 16/* "," */,-2 , 3/* ")" */,-2 )
720 	);
721 
722 	/* Goto-Table */
723 	var goto_tab = new Array(
724 		/* State 0 */ new Array( 27/* p */,1 , 26/* e */,2 ),
725 		/* State 1 */ new Array(  ),
726 		/* State 2 */ new Array(  ),
727 		/* State 3 */ new Array( 26/* e */,26 ),
728 		/* State 4 */ new Array( 26/* e */,27 ),
729 		/* State 5 */ new Array( 26/* e */,28 ),
730 		/* State 6 */ new Array(  ),
731 		/* State 7 */ new Array(  ),
732 		/* State 8 */ new Array(  ),
733 		/* State 9 */ new Array(  ),
734 		/* State 10 */ new Array(  ),
735 		/* State 11 */ new Array(  ),
736 		/* State 12 */ new Array(  ),
737 		/* State 13 */ new Array( 26/* e */,31 ),
738 		/* State 14 */ new Array( 26/* e */,32 ),
739 		/* State 15 */ new Array( 26/* e */,33 ),
740 		/* State 16 */ new Array( 26/* e */,34 ),
741 		/* State 17 */ new Array( 26/* e */,35 ),
742 		/* State 18 */ new Array( 26/* e */,36 ),
743 		/* State 19 */ new Array( 26/* e */,37 ),
744 		/* State 20 */ new Array( 26/* e */,38 ),
745 		/* State 21 */ new Array( 26/* e */,39 ),
746 		/* State 22 */ new Array( 26/* e */,40 ),
747 		/* State 23 */ new Array( 26/* e */,41 ),
748 		/* State 24 */ new Array( 26/* e */,42 ),
749 		/* State 25 */ new Array( 26/* e */,43 ),
750 		/* State 26 */ new Array(  ),
751 		/* State 27 */ new Array(  ),
752 		/* State 28 */ new Array(  ),
753 		/* State 29 */ new Array( 26/* e */,46 ),
754 		/* State 30 */ new Array( 26/* e */,47 ),
755 		/* State 31 */ new Array(  ),
756 		/* State 32 */ new Array(  ),
757 		/* State 33 */ new Array(  ),
758 		/* State 34 */ new Array(  ),
759 		/* State 35 */ new Array(  ),
760 		/* State 36 */ new Array(  ),
761 		/* State 37 */ new Array(  ),
762 		/* State 38 */ new Array(  ),
763 		/* State 39 */ new Array(  ),
764 		/* State 40 */ new Array(  ),
765 		/* State 41 */ new Array(  ),
766 		/* State 42 */ new Array(  ),
767 		/* State 43 */ new Array(  ),
768 		/* State 44 */ new Array( 26/* e */,48 ),
769 		/* State 45 */ new Array(  ),
770 		/* State 46 */ new Array(  ),
771 		/* State 47 */ new Array(  ),
772 		/* State 48 */ new Array(  ),
773 		/* State 49 */ new Array(  ),
774 		/* State 50 */ new Array(  )
775 	);
776 
777 
778 
779 	/* Symbol labels */
780 	var labels = new Array(
781 		"p'" /* Non-terminal symbol */,
782 		"WHITESPACE" /* Terminal symbol */,
783 		"(" /* Terminal symbol */,
784 		")" /* Terminal symbol */,
785 		"INT" /* Terminal symbol */,
786 		"FLOAT" /* Terminal symbol */,
787 		"PARAM" /* Terminal symbol */,
788 		"VAR" /* Terminal symbol */,
789 		"HTML" /* Terminal symbol */,
790 		"STRING" /* Terminal symbol */,
791 		"COMMAND" /* Terminal symbol */,
792 		"+" /* Terminal symbol */,
793 		"-" /* Terminal symbol */,
794 		"*" /* Terminal symbol */,
795 		"/" /* Terminal symbol */,
796 		"^" /* Terminal symbol */,
797 		"," /* Terminal symbol */,
798 		"<=" /* Terminal symbol */,
799 		">=" /* Terminal symbol */,
800 		"==" /* Terminal symbol */,
801 		"!=" /* Terminal symbol */,
802 		"<" /* Terminal symbol */,
803 		">" /* Terminal symbol */,
804 		"!" /* Terminal symbol */,
805 		"||" /* Terminal symbol */,
806 		"&&" /* Terminal symbol */,
807 		"e" /* Non-terminal symbol */,
808 		"p" /* Non-terminal symbol */,
809 		"$" /* Terminal symbol */
810 	);
811 
812 
813 
814 		info.offset = 0;
815 		info.src = src;
816 		info.att = new String();
817 
818 		if( !err_off )
819 			err_off	= new Array();
820 		if( !err_la )
821 		err_la = new Array();
822 
823 		sstack.push( 0 );
824 		vstack.push( 0 );
825 
826 		la = __lex( info );
827 
828 		while( true )
829 		{
830 			act = 52;
831 			for( var i = 0; i < act_tab[sstack[sstack.length-1]].length; i+=2 )
832 			{
833 				if( act_tab[sstack[sstack.length-1]][i] == la )
834 				{
835 					act = act_tab[sstack[sstack.length-1]][i+1];
836 					break;
837 				}
838 			}
839 
840 			if( _dbg_withtrace && sstack.length > 0 )
841 			{
842 				__dbg_print( "\nState " + sstack[sstack.length-1] + "\n" +
843 								"\tLookahead: " + labels[la] + " (\"" + info.att + "\")\n" +
844 								"\tAction: " + act + "\n" + 
845 								"\tSource: \"" + info.src.substr( info.offset, 30 ) + ( ( info.offset + 30 < info.src.length ) ?
846 										"..." : "" ) + "\"\n" +
847 								"\tStack: " + sstack.join() + "\n" +
848 								"\tValue stack: " + vstack.join() + "\n" );
849 			}
850 
851 
852 			//Panic-mode: Try recovery when parse-error occurs!
853 			if( act == 52 )
854 			{
855 				if( _dbg_withtrace )
856 					__dbg_print( "Error detected: There is no reduce or shift on the symbol " + labels[la] );
857 
858 				err_cnt++;
859 				err_off.push( info.offset - info.att.length );			
860 				err_la.push( new Array() );
861 				for( var i = 0; i < act_tab[sstack[sstack.length-1]].length; i+=2 )
862 					err_la[err_la.length-1].push( labels[act_tab[sstack[sstack.length-1]][i]] );
863 
864 				//Remember the original stack!
865 				var rsstack = new Array();
866 				var rvstack = new Array();
867 				for( var i = 0; i < sstack.length; i++ )
868 				{
869 					rsstack[i] = sstack[i];
870 					rvstack[i] = vstack[i];
871 				}
872 
873 				while( act == 52 && la != 28 )
874 				{
875 					if( _dbg_withtrace )
876 						__dbg_print( "\tError recovery\n" +
877 										"Current lookahead: " + labels[la] + " (" + info.att + ")\n" +
878 										"Action: " + act + "\n\n" );
879 					if( la == -1 )
880 						info.offset++;
881 
882 					while( act == 52 && sstack.length > 0 )
883 					{
884 						sstack.pop();
885 						vstack.pop();
886 
887 						if( sstack.length == 0 )
888 							break;
889 
890 						act = 52;
891 						for( var i = 0; i < act_tab[sstack[sstack.length-1]].length; i+=2 )
892 						{
893 							if( act_tab[sstack[sstack.length-1]][i] == la )
894 							{
895 								act = act_tab[sstack[sstack.length-1]][i+1];
896 								break;
897 							}
898 						}
899 					}
900 
901 					if( act != 52 )
902 						break;
903 
904 					for( var i = 0; i < rsstack.length; i++ )
905 					{
906 						sstack.push( rsstack[i] );
907 						vstack.push( rvstack[i] );
908 					}
909 
910 					la = __lex( info );
911 				}
912 
913 				if( act == 52 )
914 				{
915 					if( _dbg_withtrace )
916 						__dbg_print( "\tError recovery failed, terminating parse process..." );
917 					break;
918 				}
919 
920 
921 				if( _dbg_withtrace )
922 					__dbg_print( "\tError recovery succeeded, continuing" );
923 			}
924 
925 			/*
926 			if( act == 52 )
927 				break;
928 			*/
929 
930 
931 			//Shift
932 			if( act > 0 )
933 			{			
934 				if( _dbg_withtrace )
935 					__dbg_print( "Shifting symbol: " + labels[la] + " (" + info.att + ")" );
936 
937 				sstack.push( act );
938 				vstack.push( info.att );
939 
940 				la = __lex( info );
941 
942 				if( _dbg_withtrace )
943 					__dbg_print( "\tNew lookahead symbol: " + labels[la] + " (" + info.att + ")" );
944 			}
945 			//Reduce
946 			else
947 			{		
948 				act *= -1;
949 
950 				if( _dbg_withtrace )
951 					__dbg_print( "Reducing by producution: " + act );
952 
953 				rval = void(0);
954 
955 				if( _dbg_withtrace )
956 					__dbg_print( "\tPerforming semantic action..." );
957 
958 	switch( act )
959 	{
960 		case 0:
961 		{
962 			rval = vstack[ vstack.length - 1 ];
963 		}
964 		break;
965 		case 1:
966 		{
967 			 rval = JXG.GeogebraReader.ggbAct('end', vstack[ vstack.length - 1 ]); 
968 		}
969 		break;
970 		case 2:
971 		{
972 			 rval = JXG.GeogebraReader.ggbAct('coord', vstack[ vstack.length - 4 ], vstack[ vstack.length - 2 ], element); 
973 		}
974 		break;
975 		case 3:
976 		{
977 			 rval = JXG.GeogebraReader.ggbAct('le', vstack[ vstack.length - 3 ], vstack[ vstack.length - 1 ]); 
978 		}
979 		break;
980 		case 4:
981 		{
982 			 rval = JXG.GeogebraReader.ggbAct('ge', vstack[ vstack.length - 3 ], vstack[ vstack.length - 1 ]); 
983 		}
984 		break;
985 		case 5:
986 		{
987 			 rval = JXG.GeogebraReader.ggbAct('eq', vstack[ vstack.length - 3 ], vstack[ vstack.length - 1 ]); 
988 		}
989 		break;
990 		case 6:
991 		{
992 			 rval = JXG.GeogebraReader.ggbAct('neq', vstack[ vstack.length - 3 ], vstack[ vstack.length - 1 ]); 
993 		}
994 		break;
995 		case 7:
996 		{
997 			 rval = JXG.GeogebraReader.ggbAct('lt', vstack[ vstack.length - 3 ], vstack[ vstack.length - 1 ]); 
998 		}
999 		break;
1000 		case 8:
1001 		{
1002 			 rval = JXG.GeogebraReader.ggbAct('gt', vstack[ vstack.length - 3 ], vstack[ vstack.length - 1 ]); 
1003 		}
1004 		break;
1005 		case 9:
1006 		{
1007 			 rval = JXG.GeogebraReader.ggbAct('add', vstack[ vstack.length - 3 ], vstack[ vstack.length - 1 ]); 
1008 		}
1009 		break;
1010 		case 10:
1011 		{
1012 			 rval = JXG.GeogebraReader.ggbAct('sub', vstack[ vstack.length - 3 ], vstack[ vstack.length - 1 ]); 
1013 		}
1014 		break;
1015 		case 11:
1016 		{
1017 			 rval = JXG.GeogebraReader.ggbAct('neg', vstack[ vstack.length - 1 ]); 
1018 		}
1019 		break;
1020 		case 12:
1021 		{
1022 			 rval = JXG.GeogebraReader.ggbAct('pow', vstack[ vstack.length - 3 ], vstack[ vstack.length - 1 ]); 
1023 		}
1024 		break;
1025 		case 13:
1026 		{
1027 			 rval = JXG.GeogebraReader.ggbAct('or', vstack[ vstack.length - 3 ], vstack[ vstack.length - 1 ]); 
1028 		}
1029 		break;
1030 		case 14:
1031 		{
1032 			 rval = JXG.GeogebraReader.ggbAct('and', vstack[ vstack.length - 3 ], vstack[ vstack.length - 1 ]); 
1033 		}
1034 		break;
1035 		case 15:
1036 		{
1037 			 rval = JXG.GeogebraReader.ggbAct('mul', vstack[ vstack.length - 3 ], vstack[ vstack.length - 1 ]); 
1038 		}
1039 		break;
1040 		case 16:
1041 		{
1042 			 rval = JXG.GeogebraReader.ggbAct('div', vstack[ vstack.length - 3 ], vstack[ vstack.length - 1 ]); 
1043 		}
1044 		break;
1045 		case 17:
1046 		{
1047 			 rval = JXG.GeogebraReader.ggbAct('negmult', vstack[ vstack.length - 1 ]); 
1048 		}
1049 		break;
1050 		case 18:
1051 		{
1052 			 rval = JXG.GeogebraReader.ggbAct('bra', vstack[ vstack.length - 2 ]); 
1053 		}
1054 		break;
1055 		case 19:
1056 		{
1057 			 rval = JXG.GeogebraReader.ggbAct('string', vstack[ vstack.length - 3 ], vstack[ vstack.length - 1 ]); 
1058 		}
1059 		break;
1060 		case 20:
1061 		{
1062 			 rval = JXG.GeogebraReader.ggbAct('int', vstack[ vstack.length - 1 ]); 
1063 		}
1064 		break;
1065 		case 21:
1066 		{
1067 			 rval = JXG.GeogebraReader.ggbAct('float', vstack[ vstack.length - 1 ]); 
1068 		}
1069 		break;
1070 		case 22:
1071 		{
1072 			 rval = JXG.GeogebraReader.ggbAct('param', vstack[ vstack.length - 1 ]); 
1073 		}
1074 		break;
1075 		case 23:
1076 		{
1077 			 rval = JXG.GeogebraReader.ggbAct('html', vstack[ vstack.length - 1 ]); 
1078 		}
1079 		break;
1080 		case 24:
1081 		{
1082 			 rval = JXG.GeogebraReader.ggbAct('string', vstack[ vstack.length - 1 ]); 
1083 		}
1084 		break;
1085 		case 25:
1086 		{
1087 			 rval = JXG.GeogebraReader.ggbAct('command', vstack[ vstack.length - 1 ]); 
1088 		}
1089 		break;
1090 		case 26:
1091 		{
1092 			 rval = JXG.GeogebraReader.ggbAct('var', vstack[ vstack.length - 4 ], vstack[ vstack.length - 2 ]); 
1093 		}
1094 		break;
1095 		case 27:
1096 		{
1097 			 rval = JXG.GeogebraReader.ggbAct('var', vstack[ vstack.length - 1 ]); 
1098 		}
1099 		break;
1100 	}
1101 
1102 
1103 
1104 				if( _dbg_withtrace )
1105 					__dbg_print( "\tPopping " + pop_tab[act][1] + " off the stack..." );
1106 
1107 				for( var i = 0; i < pop_tab[act][1]; i++ )
1108 				{
1109 					sstack.pop();
1110 					str = vstack.pop();
1111 				}
1112 
1113 				go = -1;
1114 				for( var i = 0; i < goto_tab[sstack[sstack.length-1]].length; i+=2 )
1115 				{
1116 					if( goto_tab[sstack[sstack.length-1]][i] == pop_tab[act][0] )
1117 					{
1118 						go = goto_tab[sstack[sstack.length-1]][i+1];
1119 						break;
1120 					}
1121 				}
1122 
1123 				if( act == 0 )
1124 					break;
1125 
1126 				if( _dbg_withtrace )
1127 					__dbg_print( "\tPushing non-terminal " + labels[ pop_tab[act][0] ] );
1128 
1129 				sstack.push( go );
1130 				vstack.push( rval );			
1131 			}
1132 
1133 			if( _dbg_withtrace )
1134 			{		
1135 				JXG.debug( _dbg_string );
1136 				_dbg_string = new String();
1137 			}
1138 		}
1139 
1140 		if( _dbg_withtrace )
1141 		{
1142 			__dbg_print( "\nParse complete." );
1143 			JXG.debug( _dbg_string );
1144 		}
1145 
1146 		return err_cnt;
1147 	}
1148 /***** end replace *****/
1149 
1150   var error_offsets = new Array();
1151   var error_lookaheads = new Array();
1152   var error_count = 0;
1153   var str = exp;
1154   if( ( error_count = __parse( str, error_offsets, error_lookaheads ) ) > 0 ) {
1155     var errstr = new String();
1156     for( var i = 0; i < error_count; i++ )
1157       errstr += "Parse error in line " + ( str.substr( 0, error_offsets[i] ).match( /\n/g ) ?
1158                   str.substr( 0, error_offsets[i] ).match( /\n/g ).length : 1 )
1159                 + " near \"" + str.substr( error_offsets[i] ) + "\", expecting \"" + error_lookaheads[i].join() + "\"\n" ;
1160     JXG.debug( errstr );
1161   }
1162 
1163   return str;
1164 }; //end: ggbParse()
1165 
1166 
1167 /**
1168  * Override JSxGraph defaults with Geogebra settings
1169  * @param {Object} board object
1170  * @return {Object} board oject
1171  */
1172 this.setDefaultOptions = function(board){
1173   board.options.elements.strokeWidth = '1px'; // TODO: board.options.line.strokeWidth
1174   board.options.elements.withLabel = true;
1175 
1176   board.options.point.face = 'circle';
1177   board.options.point.size = 3;
1178   board.options.point.fillColor = 'blue';
1179   board.options.point.fillOpacity = 1;
1180   board.options.point.highlightFillOpacity = 1;
1181   board.options.point.strokeColor = 'black';
1182   board.options.point.highlightStrokeColor = 'black';
1183   board.options.point.strokeWidth = '2px';
1184 
1185   board.options.line.strokeWidth = '1px';
1186   board.options.line.highlightStrokeColor = '#000000';
1187   board.options.line.strokeColor = '#000000';
1188 
1189   board.options.polygon.fillColor = JXG.rgb2hex(153, 51, 0);
1190   board.options.polygon.fillOpacity = 0.1;
1191   board.options.polygon.highlightFillColor = board.options.polygon.fillColor;
1192   board.options.polygon.highlightFillOpacity = 0.1;
1193 
1194   board.options.sector.fillColor = JXG.rgb2hex(153, 51, 0);
1195   board.options.sector.fillOpacity = 0.1;
1196   board.options.sector.highlightFillColor = board.options.sector.fillColor;
1197   board.options.sector.highlightFillOpacity = 0.1;
1198 
1199   board.options.angle.fillColor = JXG.rgb2hex(0, 100, 0);
1200   board.options.angle.fillOpacity = 0.1;
1201   //board.options.angle.highlightFillColor = board.options.angle.fillColor;
1202   board.options.angle.highlightFillOpacity = 0.1;
1203 
1204   return board;
1205 };
1206 
1207 /**
1208  * Set color properties of a geogebra element.
1209  * Set stroke, fill, lighting, label and draft color attributes.
1210  * @param {Object} gxtEl element of which attributes are to set
1211  * @param {Object} attr object carrying all necessary attribute values
1212  * @return {Object} returning the updated attr-attributes object
1213  */
1214 this.colorProperties = function(Data, attr) {
1215   var a,r,g,b;
1216   a = (Data.getElementsByTagName("objColor").length > 0 && Data.getElementsByTagName("objColor")[0].getAttribute("alpha")) ? parseFloat(Data.getElementsByTagName("objColor")[0].getAttribute("alpha")) : 0;
1217   r = (Data.getElementsByTagName("objColor").length > 0 && Data.getElementsByTagName("objColor")[0].getAttribute("r")) ? parseInt(Data.getElementsByTagName("objColor")[0].getAttribute("r")).toString(16) : 0;
1218   g = (Data.getElementsByTagName("objColor").length > 0 && Data.getElementsByTagName("objColor")[0].getAttribute("g")) ? parseInt(Data.getElementsByTagName("objColor")[0].getAttribute("g")).toString(16) : 0;
1219   b = (Data.getElementsByTagName("objColor").length > 0 && Data.getElementsByTagName("objColor")[0].getAttribute("b")) ? parseInt(Data.getElementsByTagName("objColor")[0].getAttribute("b")).toString(16) : 0;
1220   if (r.length == 1) r = '0' + r;
1221   if (g.length == 1) g = '0' + g;
1222   if (b.length == 1) b = '0' + b;
1223 
1224   attr.fillColor = '#'+ r + g + b;
1225   attr.strokeColor = attr.fillColor;
1226   attr.highlightFillColor = attr.fillColor;
1227   attr.highlightStrokeColor = attr.strokeColor;
1228   attr.fillOpacity = a;
1229   attr.highlightFillOpacity = a;
1230   attr.labelColor = attr.fillColor;
1231 
1232   return attr;
1233 };
1234 
1235 /**
1236  * Set the board properties.
1237  * Set active, area, dash, draft and showinfo attributes.
1238  * @param {Object} gxtEl element of which attributes are to set
1239  * @param {Object} Data element of which attributes are to set
1240  * @param {Object} attr object containing the necessary attribute values
1241  */
1242 this.boardProperties = function(gxtEl, Data, attr) {
1243   return attr;
1244 };
1245 
1246 /**
1247  * @param {Object} gxtEl element of which attributes are to set
1248  * @param {Object} Data element of which attributes are to set
1249  * @return {Object} updated element
1250  */
1251 this.coordinates = function(gxtEl, Data) {
1252   var labelOffset = {}, tmp;
1253   labelOffset.x = 0; labelOffset.y = 0; labelOffset.z = 0;
1254 
1255   if(Data.getElementsByTagName('labelOffset')[0]) {
1256     // tmp = new JXG.Coords(JXG.COORDS_BY_SCREEN, [,
1257     //                                             parseFloat(Data.getElementsByTagName("labelOffset")[0].attributes["y"].value)], JXG.GeogebraReader.board);
1258     labelOffset.x = parseFloat(Data.getElementsByTagName("labelOffset")[0].getAttribute("x"))/JXG.GeogebraReader.board.unitX;
1259     labelOffset.y = parseFloat(Data.getElementsByTagName("labelOffset")[0].getAttribute("y"))/JXG.GeogebraReader.board.unitY;
1260   }
1261 
1262   if(Data.getElementsByTagName("coords")[0]) {
1263     gxtEl.x = parseFloat(Data.getElementsByTagName("coords")[0].getAttribute("x"));
1264     gxtEl.y = parseFloat(Data.getElementsByTagName("coords")[0].getAttribute("y"));
1265     gxtEl.z = parseFloat(Data.getElementsByTagName("coords")[0].getAttribute("z"));
1266   } else if(Data.getElementsByTagName("startPoint")[0]) {
1267     if(Data.getElementsByTagName("startPoint")[0].getAttribute('exp')) {
1268       var a = JXG.getRef(JXG.GeogebraReader.board, Data.getElementsByTagName("startPoint")[0].getAttribute('exp'));
1269       gxtEl.x = function() {return a.X()+labelOffset.x;};
1270       gxtEl.y = function() {return a.Y()-labelOffset.y;}; // minus because geogebra starts on the other side
1271       gxtEl.z = false;
1272     } else {
1273       gxtEl.x = parseFloat(Data.getElementsByTagName("startPoint")[0].getAttribute("x"));
1274       gxtEl.y = parseFloat(Data.getElementsByTagName("startPoint")[0].getAttribute("y"));
1275       gxtEl.z = parseFloat(Data.getElementsByTagName("startPoint")[0].getAttribute("z"));
1276     }
1277   } else if(Data.getElementsByTagName("absoluteScreenLocation")[0]) {
1278     var tmp = new JXG.Coords(JXG.COORDS_BY_SCREEN, [parseFloat(Data.getElementsByTagName("absoluteScreenLocation")[0].getAttribute("x")),
1279                                                     parseFloat(Data.getElementsByTagName("absoluteScreenLocation")[0].getAttribute("y"))], JXG.GeogebraReader.board);
1280     gxtEl.x = tmp.usrCoords[1]+labelOffset.x;
1281     gxtEl.y = tmp.usrCoords[2]+labelOffset.y;
1282     gxtEl.z = false;
1283   } else {
1284     return false;
1285   }
1286 
1287   return gxtEl;
1288 };
1289 
1290 /**
1291  * Writing element attributes to the given object
1292  * @param {XMLNode} Data expects the content of the current element
1293  * @return {Object} object with according attributes
1294  */
1295 this.visualProperties = function(Data, attr) {
1296   (Data.getElementsByTagName("show").length != 0 && Data.getElementsByTagName("show")[0].getAttribute("object")) ? attr.visible = Data.getElementsByTagName("show")[0].getAttribute("object") : false;
1297   (Data.getElementsByTagName("show").length != 0 && Data.getElementsByTagName("show")[0].getAttribute("label")) ? attr.withLabel = Data.getElementsByTagName("show")[0].getAttribute("label") : true;
1298   if(attr.withLabel == 'true') {
1299      attr.withLabel = true;
1300   }
1301   else if(attr.withLabel == 'false') {
1302      attr.withLabel = false;
1303   }
1304   (Data.getElementsByTagName('pointSize')[0]) ? attr.size = Data.getElementsByTagName('pointSize')[0].getAttribute("val") : false;
1305   (Data.getElementsByTagName('pointStyle')[0]) ? attr.styleGGB = Data.getElementsByTagName('pointStyle')[0].getAttribute("val") : false;
1306    if(attr.styleGGB == 0 || attr.styleGGB == 2) {
1307       attr.face = 'circle';
1308       if(attr.styleGGB == 0) {
1309         attr.fillColor = attr.strokeColor;
1310         attr.fillOpacity = 1;
1311         attr.highlightFillColor = attr.strokeColor;
1312         attr.highlightFillOpacity = 1;
1313         attr.strokeColor = 'black';
1314         attr.strokeWidth = '1px';
1315       }
1316       else if(attr.styleGGB == 2) {
1317         attr.fillColor = 'none';
1318       }
1319    }
1320    else if(attr.styleGGB == 1) {
1321       attr.face = 'x';
1322    }
1323    else if(attr.styleGGB == 3) {
1324       attr.face = '+';
1325       attr.strokeOpacity = 1;
1326    }
1327    else if(attr.styleGGB == 4 || attr.styleGGB == 5) {
1328       attr.face = 'diamond';
1329       if(attr.styleGGB == 4) {
1330          attr.fillColor = attr.strokeColor;
1331          attr.fillOpacity = 1;
1332       }
1333       else if(attr.styleGGB == 5) {
1334         attr.fillColor = 'none';
1335       }
1336    }
1337    else if(attr.styleGGB == 6) {
1338       attr.face = 'triangleUp';
1339       attr.fillColor = attr.strokeColor;
1340       attr.fillOpacity = 1;
1341    }
1342    else if(attr.styleGGB == 7) {
1343       attr.face = 'triangleDown';
1344       attr.fillColor = attr.strokeColor;
1345       attr.fillOpacity = 1;
1346    }
1347    else if(attr.styleGGB == 8) {
1348       attr.face = 'triangleRight';
1349       attr.fillColor = attr.strokeColor;
1350       attr.fillOpacity = 1;
1351    }
1352    else if(attr.styleGGB == 9) {
1353       attr.face = 'triangleLeft';
1354       attr.fillColor = attr.strokeColor;
1355       attr.fillOpacity = 1;
1356    }
1357   (Data.getElementsByTagName('slopeTriangleSize')[0]) ? attr.slopeWidth = Data.getElementsByTagName('slopeTriangleSize')[0].getAttribute("val") : false;
1358   (Data.getElementsByTagName('lineStyle')[0]) ? attr.strokeWidth = (Data.getElementsByTagName('lineStyle')[0].getAttribute("thickness")/2.0)+'px' : false;
1359   if(attr.strokeWidth) {
1360     attr.highlightStrokeWidth = (1*attr.strokeWidth.substr(0,attr.strokeWidth.length-2)+1)+'px';
1361   }
1362   (Data.getElementsByTagName('lineStyle')[0]) ? attr.dashGGB = Data.getElementsByTagName('lineStyle')[0].getAttribute("type") : false;
1363 
1364    if(attr.dashGGB == 0) {
1365       attr.dash = 0;
1366    }
1367    else if(attr.dashGGB == 10) {
1368       attr.dash = 2;
1369    }
1370    else if(attr.dashGGB == 15) {
1371       attr.dash = 3;
1372    }
1373    else if(attr.dashGGB == 20) {
1374       attr.dash = 1;
1375    }
1376    else if(attr.dashGGB == 30) {
1377       attr.dash = 6;
1378    }
1379   (Data.getElementsByTagName("labelOffset")[0]) ? attr.labelX = 1*Data.getElementsByTagName("labelOffset")[0].getAttribute("x") : false;
1380   (Data.getElementsByTagName("labelOffset")[0]) ? attr.labelY = 1*Data.getElementsByTagName("labelOffset")[0].getAttribute("y") : false;
1381   (Data.getElementsByTagName("trace")[0]) ? attr.trace = Data.getElementsByTagName("trace")[0].getAttribute("val") : false;
1382   (Data.getElementsByTagName('fix')[0]) ? attr.fixed = Data.getElementsByTagName('fix')[0].getAttribute("val") : false;
1383   return attr;
1384 };
1385 
1386 /**
1387  * Searching for an element in the geogebra tree
1388  * @param {String} the name of the element to search for
1389  * @param {Boolean} whether it is search for an expression or not
1390  * @return {Object} object with according label
1391  */
1392 this.getElement = function(name, expr) {
1393   var Data, i, j;
1394   expr = expr || false;
1395   for(i=0; i<JXG.GeogebraReader.tree.getElementsByTagName("construction").length; i++)
1396     if(expr == false) {
1397       for(j=0; j<JXG.GeogebraReader.tree.getElementsByTagName("construction")[i].getElementsByTagName("element").length; j++) {
1398         Data = JXG.GeogebraReader.tree.getElementsByTagName("construction")[i].getElementsByTagName("element")[j];
1399         if(name == Data.getAttribute("label")) {
1400           return Data;
1401         }
1402       };
1403     } else {
1404       for(j=0; j<JXG.GeogebraReader.tree.getElementsByTagName("construction")[i].getElementsByTagName("expression").length; j++) {
1405         Data = JXG.GeogebraReader.tree.getElementsByTagName("construction")[i].getElementsByTagName("expression")[j];
1406         if(name == Data.getAttribute("label")) {
1407           return Data;
1408         }
1409       };
1410     }
1411   return false;
1412 };
1413 
1414 /**
1415  * Check if an element is already registered in the temporary ggbElements register. If not, create and register the element.
1416  * @param {String} the name of the element to check
1417  * @return {Object} newly created element
1418  */
1419 this.checkElement = function(name) {
1420 // Segment[A, B] nur bis Version 2.4 ? In 2.5 schon (x(A), x(B)) und durch Parser loesbar
1421   // if(name.match(/[a-zA-Z]+\[[a-zA-Z0-9]+[a-zA-Z0-9,\ ]*\]/)) {
1422   //   var tmp, type, input, output, i;
1423   //   tmp = name.split('[');
1424   //   type = tmp[0];
1425   //   input = tmp[1].split(']');
1426   //   input = input[0].split(', ');
1427   //   for(i=0; i<input.length; i++) {
1428   //     input[i] = JXG.GeogebraReader.checkElement(input[i]);
1429   //   }
1430   //   output = {
1431   //     'attributes' : []
1432   //   };
1433   //   output.attributes['type'] = {value: type };
1434   //   output.attributes['label'] = {value: name};
1435   //
1436   //   JXG.GeogebraReader.board.ggbElements[name] = JXG.GeogebraReader.writeElement(JXG.GeogebraReader.board, name, input, type);
1437   // } else
1438   if(typeof JXG.GeogebraReader.board.ggbElements[name] == 'undefined' || JXG.GeogebraReader.board.ggbElements[name] == '') {
1439     var input = JXG.GeogebraReader.getElement(name);
1440     JXG.GeogebraReader.board.ggbElements[name] = JXG.GeogebraReader.writeElement(JXG.GeogebraReader.board, input);
1441   }
1442   return JXG.GeogebraReader.board.ggbElements[name];
1443 };
1444 
1445 /**
1446  * Prepare expression for this.ggbParse with solving multiplications and replacing mathematical functions.
1447  * @param {String} exp Expression to parse and correct
1448  * @return {String} correct expression with fixed function and multiplication
1449  */
1450 this.functionParse = function(type, exp) {
1451  var input, vars, expr, output, i, s, o;
1452  switch(type) {
1453   case 'c':
1454     // search for function params
1455     if(exp.match(/[a-zA-Z0-9\']+\([a-zA-Z0-9]+[a-zA-Z0-9,\ ]*\)[\ ]*[=][\ ]*[a-zA-Z0-9\+\-\*\/ \( \) \u005E]+/)) {
1456       input = exp.split('(')[1].split(')')[0];
1457       vars = input.split(', ');
1458 
1459       output = [];
1460       for(i=0; i<vars.length; i++)
1461         output.push("__"+vars[i]);
1462 
1463       expr = exp.split('=')[1];
1464 
1465       // separate and replace function parameters
1466       for(i=0; i<vars.length; i++) {
1467         if(vars[i] == 'x') {
1468           expr = expr.replace(/(?![e])x(?!\()(?![p])/g, '__'+vars[i]);
1469         } else if(vars[i] == 'y') {
1470           expr = expr.replace(/(?![e])y(?!\()(?![p])/g, '__'+vars[i]);
1471         } else {
1472           expr = expr.replace( eval('/'+vars[i]+'/g'), '__'+vars[i] );
1473         }
1474       }
1475 
1476       // replace -__x to -1*__x
1477       expr = expr.replace(/-__/g, '-1*__');
1478 
1479 	  if(JXG.GeogebraReader.format <= 3.01) {
1480 	    // prepare string: "solve" multiplications 'a b' to 'a*b'
1481 	    s = expr.split(' ');
1482 	    o = '';
1483 	    for(var i=0; i<s.length; i++) {
1484 	      if(s.length != i+1)
1485 	        if(s[i].search(/\)$/) > -1 || s[i].search(/[0-9]+$/) > -1 || s[i].search(/[a-zA-Z]+(\_*[a-zA-Z0-9]+)*$/) > -1)
1486 	          if(s[i+1].search(/^\(/) > -1 ||
1487                  s[i+1].search(/^[0-9]+/) > -1 ||
1488                  s[i+1].search(/^[a-zA-Z]+(\_*[a-zA-Z0-9]+)*/) > -1 ||
1489                  s[i+1].search(/\_\_[a-zA-Z0-9]+/) > -1) {
1490 	               s[i] = s[i] + "*";
1491                  }
1492 	      o += s[i];
1493 	    };
1494 	    expr = o;
1495 	  }
1496 
1497       output.push(expr);
1498       return output;
1499     } else {
1500       return exp;
1501     }
1502   break;
1503   case 's':
1504     exp = exp.replace(/(?![e])x(?!\()(?![p])/g, '__x');
1505     return ['__x', exp];
1506   break;
1507   default:
1508     if(JXG.GeogebraReader.format <= 3.01) {
1509 	  // prepare string: "solve" multiplications 'a b' to 'a*b'
1510 	  s = exp.split(' ');
1511 	  o = '';
1512       for(i=0; i<s.length; i++) {
1513         if(s.length != i+1)
1514           if(s[i].search(/\)$/) > -1 || s[i].search(/[0-9]+$/) > -1 || s[i].search(/[a-zA-Z]+(\_*[a-zA-Z0-9]+)*$/) > -1)
1515             if(s[i+1].search(/^\(/) > -1 ||
1516               s[i+1].search(/^[0-9]+/) > -1 ||
1517               s[i+1].search(/^[a-zA-Z]+(\_*[a-zA-Z0-9]+)*/) > -1 ||
1518               s[i+1].search(/\_\_[a-zA-Z0-9]+/) > -1) {
1519                 s[i] = s[i] + "*";
1520             }
1521 	    o += s[i];
1522 	  };
1523 	  exp = o;
1524 	}
1525     return exp;
1526   break;
1527  }
1528 };
1529 
1530 /**
1531  * Searching for an element in the geogebra tree
1532  * @param {Object} board object
1533  */
1534 this.writeBoard = function(board) {
1535   var boardData = JXG.GeogebraReader.tree.getElementsByTagName("euclidianView")[0];
1536 
1537   board.origin = {};
1538   board.origin.usrCoords = [1, 0, 0];
1539   board.origin.scrCoords = [1, 1*boardData.getElementsByTagName("coordSystem")[0].getAttribute("xZero"), 1*boardData.getElementsByTagName("coordSystem")[0].getAttribute("yZero")];
1540   board.unitX = (boardData.getElementsByTagName("coordSystem")[0].getAttribute("scale")) ? 1*boardData.getElementsByTagName("coordSystem")[0].getAttribute("scale") : 1;
1541   board.unitY = (boardData.getElementsByTagName("coordSystem")[0].getAttribute("yscale")) ? 1*boardData.getElementsByTagName("coordSystem")[0].getAttribute("yscale") : board.unitX;
1542 
1543   board.fontSize = (JXG.GeogebraReader.tree.getElementsByTagName("gui")[0] && JXG.GeogebraReader.tree.getElementsByTagName("gui")[0].getElementsByTagName("font")[0]) ? 1*JXG.GeogebraReader.tree.getElementsByTagName("gui")[0].getElementsByTagName("font")[0].getAttribute("size") : '12px';
1544 
1545   JXG.JSXGraph.boards[board.id] = board;
1546 
1547   // Update of properties during update() is not necessary in GEONExT files
1548   board.renderer.enhancedRendering = true;
1549 
1550   // snap to point
1551   var snapToPoint = (boardData.getElementsByTagName('evSettings')[0].getAttribute("pointCapturing") == "true");
1552 
1553   var grid = (boardData.getElementsByTagName('evSettings')[0].getAttribute("grid") == "true") ? board.create('grid') : null;
1554 
1555   if(boardData.getElementsByTagName('evSettings')[0].getAttribute("axes") && boardData.getElementsByTagName('evSettings')[0].getAttribute("axes") == "true") {
1556       board.ggbElements["xAxis"] = board.create('axis', [[0, 0], [1, 0]], {strokeColor:'black', minorTicks: 0});
1557       board.ggbElements["yAxis"] = board.create('axis', [[0, 0], [0, 1]], {strokeColor:'black', minorTicks: 0});
1558   }
1559 };
1560 
1561 /**
1562  * Searching for an element in the geogebra tree
1563  * @param {Object} board object
1564  * @param {Object} ggb element whose attributes are to parse
1565  * @param {Array} input list of all input elements
1566  * @param {String} typeName output construction method
1567  * @return {Object} return newly created element or false
1568  */
1569 this.writeElement = function(board, output, input, cmd) {
1570   var element, gxtEl, attr, p, exp, coord, type, points, border, length, m, s, e, sx, sy, ex, ey, func, range;
1571   element = (JXG.isArray(output)) ? output[0] : output;
1572 
1573   gxtEl = {}; // geometric element
1574   attr = {}; // Attributes of geometric elements
1575 
1576   JXG.debug(element);
1577 
1578   gxtEl.type = (element && element.attributes && typeof cmd === 'undefined') ? element.getAttribute('type').toLowerCase() : cmd;
1579   gxtEl.label = element.getAttribute('label');
1580   attr.name  = gxtEl.label;
1581 
1582   JXG.debug("<br><b>Konstruiere</b> "+ attr.name +"("+ gxtEl.type +"):");
1583 
1584   switch(gxtEl.type) {
1585     case 'point':
1586       attr = JXG.GeogebraReader.boardProperties(gxtEl, element, attr);
1587       attr = JXG.GeogebraReader.colorProperties(element, attr);
1588       attr = JXG.GeogebraReader.visualProperties(element, attr);
1589 
1590       if(JXG.GeogebraReader.getElement(attr.name, true)) {
1591         exp = JXG.GeogebraReader.getElement(attr.name, true).getAttribute('exp');
1592         coord = JXG.GeogebraReader.ggbParse(exp);
1593         gxtEl.x = new Function('return '+ coord[0] +';');
1594         gxtEl.y = new Function('return '+ coord[1] +';');
1595       } else {
1596         gxtEl = JXG.GeogebraReader.coordinates(gxtEl, element);
1597       }
1598       if(!JXG.exists(attr.styleGGB)) {
1599          attr.face = 'circle';
1600          attr.fillColor = attr.strokeColor;
1601          attr.fillOpacity = 1;
1602          attr.highlightFillColor = attr.strokeColor;
1603          attr.highlightFillOpacity = 1;
1604          attr.strokeColor = 'black';
1605          attr.strokeWidth = '1px';
1606       }
1607 
1608       JXG.debug(gxtEl);
1609       JXG.debug(input);
1610 
1611       try {
1612         var ma = /Circle\[\s*(\w+)\s*,\s*([\d\.]+)\s*\]/.exec(input);
1613         if(typeof input != 'undefined') {
1614           if (ma!=null && ma.length==3) {
1615             // from Circle[A, 5] take "A" and "5", stored in ma[1] and ma[2]
1616             var q = JXG.GeogebraReader.checkElement(ma[1]);
1617             var c = board.create('circle', [q, parseFloat(ma[2])], {fillColor:'none',visible:false,name:''});
1618             p = board.create('glider', [gxtEl.x, gxtEl.y, c], attr);
1619           } else if(JXG.isArray(input)) {
1620             p = board.create('glider', [gxtEl.x, gxtEl.y, input[0]], attr);
1621           } else {
1622             p = board.create('glider', [gxtEl.x, gxtEl.y, input], attr);
1623           }
1624         } else {
1625           p = board.create('point', [gxtEl.x, gxtEl.y], attr);
1626         }
1627         return p;
1628       } catch(e) {
1629           JXG.debug("* <b>Err:</b> Point " + attr.name +"<br>\n");
1630           return false;
1631       }
1632     break;
1633     case 'segment':
1634       attr = JXG.GeogebraReader.boardProperties(gxtEl, element, attr);
1635       attr = JXG.GeogebraReader.colorProperties(element, attr);
1636       gxtEl = JXG.GeogebraReader.coordinates(gxtEl, element);
1637       attr = JXG.GeogebraReader.visualProperties(element, attr);
1638 
1639       try {
1640         JXG.debug("* <b>Segment:</b> ("+ attr.name +") First: " + input[0].name + ", Last: " + input[1].name + "<br>\n");
1641         attr.straightFirst = false;
1642         attr.straightLast =  false;
1643         p = board.create('line', input, attr);
1644         return p;
1645       } catch(e) {
1646         JXG.debug("* <b>Err:</b> Segment " + attr.name +" First: " + input[0].name + ", Last: " + input[1].name + "<br>\n");
1647         return false;
1648       }
1649     break;
1650     case 'line':
1651       attr = JXG.GeogebraReader.boardProperties(gxtEl, element, attr);
1652       attr = JXG.GeogebraReader.colorProperties(element, attr);
1653       gxtEl = JXG.GeogebraReader.coordinates(gxtEl, element);
1654       attr = JXG.GeogebraReader.visualProperties(element, attr);
1655 
1656       type = 'line';
1657       if(!input) {
1658         input = [ parseFloat(element.getElementsByTagName('coords')[0].getAttribute('z')),
1659                       parseFloat(element.getElementsByTagName('coords')[0].getAttribute('x')),
1660                       parseFloat(element.getElementsByTagName('coords')[0].getAttribute('y'))
1661                     ];
1662       } else if (JXG.getRef(board, input[1].id).elementClass == JXG.OBJECT_CLASS_LINE) {
1663          type = 'parallel'; // Parallele durch Punkt
1664       }
1665 
1666       try {
1667         p = board.create(type, input, attr);
1668         return p;
1669       } catch(e) {
1670         JXG.debug("* <b>Err:</b> Line " + attr.label +"<br>\n");
1671         return false;
1672       }
1673     break;
1674     case "orthogonalline":
1675       attr = JXG.GeogebraReader.boardProperties(gxtEl, element, attr);
1676       attr = JXG.GeogebraReader.colorProperties(element, attr);
1677       gxtEl = JXG.GeogebraReader.coordinates(gxtEl, element);
1678       attr = JXG.GeogebraReader.visualProperties(element, attr);
1679 
1680       try {
1681         JXG.debug("* <b>Orthogonalline:</b> First: " + input[0].id + ", Last: " + input[1].id + "<br>\n");
1682         p = board.create('normal', input, attr);
1683         return p;
1684       } catch(e) {
1685         JXG.debug("* <b>Err:</b> Orthogonalline " + attr.label +"<br>\n");
1686         return false;
1687       }
1688     break;
1689     case "polygon":
1690       attr = JXG.GeogebraReader.boardProperties(gxtEl, element, attr);
1691       attr = JXG.GeogebraReader.colorProperties(element, attr);
1692       gxtEl = JXG.GeogebraReader.coordinates(gxtEl, element);
1693       attr = JXG.GeogebraReader.visualProperties(element, attr);
1694 
1695       // test if polygon is regular
1696       if(input.length == 3 && output.length != 4) {
1697         input[2] = parseInt(input[2]);
1698         type = 'regular';
1699       }
1700 
1701       try {
1702         JXG.debug("* <b>Polygon:</b> First: " + input[0].name + ", Second: " + input[1].name + ", Third: " + input[2] + "<br>\n");
1703 
1704         var borders = [];
1705         var borderatts = [];
1706         length = (type == 'regular') ? output.length-input[2]+2 : output.length;
1707 
1708         for(var i=1; i<length; i++) {
1709           borders[i-1] = {};
1710           borderatts[i-1] = {};
1711           borders[i-1].id = '';
1712           borders[i-1].name = output[i].getAttribute('label');
1713           borderatts[i-1] = JXG.GeogebraReader.colorProperties(output[i], borderatts[i-1]);
1714           borderatts[i-1] = JXG.GeogebraReader.visualProperties(output[i], borderatts[i-1]);
1715           // JXG.debug("border["+ typeof borders[i-1] +"]: "+ borders[i-1].name);
1716         }
1717         attr.borders = borders;
1718 
1719         points = [];
1720         if(type == 'regular') {
1721           points.push(input[0]);
1722           points.push(input[1]);
1723 
1724           for(i=input[2]+1; i<output.length; i++){
1725             if(output[i].attributes)
1726               points.push(JXG.GeogebraReader.checkElement(output[i].getAttribute('label')));
1727             else
1728               points.push(output[i]);
1729           }
1730         } else {
1731           for(i=0; i<input.length; i++) {
1732             if(typeof input[i] === 'object') {
1733               points.push(input[i]);
1734               // JXG.debug("input-queue: added "+ input[i].name);
1735             }
1736           }
1737         }
1738 
1739         if(type == 'regular') {
1740           p = board.create('regularpolygon', points, attr);
1741         }
1742         else {
1743           p = board.create('polygon', points, attr);
1744         }
1745         for(i=0; i<p.borders.length; i++) {
1746             if(borderatts[i].withLabel) {
1747                 p.borders[i].createLabel();
1748             }
1749             p.borders[i].setProperty(borderatts[i]);
1750         }
1751         return p;
1752       } catch(e) {
1753         JXG.debug("* <b>Err:</b> Polygon " + attr.name +"<br>\n");
1754         return false;
1755       }
1756     break;
1757     case 'intersect':
1758       attr = JXG.GeogebraReader.boardProperties(gxtEl, element, attr);
1759       attr = JXG.GeogebraReader.colorProperties(element, attr);
1760       gxtEl = JXG.GeogebraReader.coordinates(gxtEl, element);
1761       attr = JXG.GeogebraReader.visualProperties(element, attr);
1762 
1763       try {
1764         JXG.debug("* <b>Intersection:</b> First: " + input[0].name + ", Second: " + input[1].name + "<br>\n");
1765         if(!JXG.exists(attr.styleGGB)) {
1766            attr.face = 'circle';
1767            attr.fillColor = attr.strokeColor;
1768            attr.fillOpacity = 1;
1769            attr.highlightFillColor = attr.strokeColor;
1770            attr.highlightFillOpacity = 1;
1771            attr.strokeColor = 'black';
1772            attr.strokeWidth = '1px';
1773         }
1774         if(output.length == 1) {
1775            p = board.create('intersection', [input[0], input[1], 0], attr);
1776         }
1777         else {
1778            p = board.create('intersection', [input[0], input[1], 1], attr);
1779            var attr2 = {};
1780            attr2 = JXG.GeogebraReader.colorProperties(output[1], attr2);
1781            attr2 = JXG.GeogebraReader.visualProperties(output[1], attr2);
1782            attr2.name = output[1].getAttribute('label');
1783            var p2 = board.create('otherintersection', [input[0], input[1], p], attr2);
1784            board.ggbElements[attr2.name] = p2;
1785         }
1786 
1787         return p;
1788       } catch(e) {
1789         JXG.debug("* <b>Err:</b> Intersection " + attr.name +"<br>\n");
1790         return false;
1791       }
1792     break;
1793     case 'distance':
1794       attr = JXG.GeogebraReader.boardProperties(gxtEl, element, attr);
1795       attr = JXG.GeogebraReader.colorProperties(element, attr);
1796       gxtEl = JXG.GeogebraReader.coordinates(gxtEl, element);
1797       attr = JXG.GeogebraReader.visualProperties(element, attr);
1798 
1799 
1800       try {
1801         JXG.debug("* <b>Distance:</b> First: " + input[0].name + ", Second: " + input[1].name + "<br>\n");
1802 
1803         if(false && output[0].getAtribute('type') && output[0].getAttribute('type') == 'numeric') {
1804           input[1].Value = function(){ return this.X(); };
1805           p = input[1];
1806           board.elementsByName[attr.name] = p;
1807         } else {
1808           m = board.create('midpoint', input, {visible: 'false'});
1809           attr.visible = 'true';
1810           p = board.create('text', [function(){return m.X();}, function(){return m.Y();}, function(){
1811               return "<span style='text-decoration: overline'>"+ input[0].name + input[1].name +"</span> = "
1812                      + JXG.trimNumber(JXG.getRef(board, input[0].id).Dist(JXG.getRef(board, input[1].id)).toFixed(JXG.GeogebraReader.decimals));
1813                 }], attr);
1814           p.Value = function () {
1815             return (JXG.getRef(board, input[0].id).Dist(JXG.getRef(board, input[1].id)));
1816           }
1817         }
1818         return p;
1819       } catch(e) {
1820         JXG.debug("* <b>Err:</b> Distance " + attr.name +"<br>\n");
1821         return false;
1822       }
1823     break;
1824     case 'vector':
1825       attr = JXG.GeogebraReader.boardProperties(gxtEl, element, attr);
1826       attr = JXG.GeogebraReader.colorProperties(element, attr);
1827       gxtEl = JXG.GeogebraReader.coordinates(gxtEl, element);
1828       attr = JXG.GeogebraReader.visualProperties(element, attr);
1829 
1830       if(element.getElementsByTagName("startPoint")[0]) {
1831 
1832         if(input && input.length == 2) {
1833             e = JXG.GeogebraReader.checkElement(input[1].name);
1834         } else {
1835             e = [parseFloat(element.getElementsByTagName("coords")[0].getAttribute("x")), parseFloat(element.getElementsByTagName("coords")[0].getAttribute("y"))];
1836         }
1837         if(element.getElementsByTagName("startPoint")[0].getAttribute("x") && element.getElementsByTagName("startPoint")[0].getAttribute("y")) {
1838             s = [parseFloat(element.getElementsByTagName("startPoint")[0].getAttribute("x")), parseFloat(element.getElementsByTagName("startPoint")[0].getAttribute("y"))];
1839         } else if(element.getElementsByTagName("startPoint")[0].getAttribute("exp")) {
1840             var startpoint = element.getElementsByTagName("startPoint")[0].getAttribute("exp");
1841             s = JXG.GeogebraReader.checkElement(startpoint);
1842         }
1843       } else if(input && input.length != 0) {
1844         s = input[0];
1845         e = input[1];
1846       } else {
1847         exp = JXG.GeogebraReader.getElement(element.getAttribute('label'), true);
1848         if(exp) {// experimental
1849             exp = exp.getAttribute('exp');
1850             // exp = JXG.GeogebraReader.functionParse('', exp);
1851             exp = JXG.GeogebraReader.ggbParse(exp);
1852             if (JXG.isArray(exp))
1853             	exp = new Array(new Function('return '+ exp[1] +';'), new Function('return '+ exp[2] +';'));
1854             else
1855             	exp = new Function('return '+ exp +';');
1856             JXG.debug('exp: '+ exp);
1857             p = board.create('arrow', [[0,0], [exp[0], exp[1]]], attr);
1858             return p;
1859             //t = JXG.getRef(board, 'a');
1860             //s = t.point1;
1861             // var e = [-1*vector.point2.X(), -1*vector.point2.Y()];
1862             // attr.type = 'rotate';
1863             // var angle;
1864             // if(exp < 0) {
1865             //   angle = Math.PI;
1866             // } else if(exp == 0) {
1867             //   angle = 0;
1868             // } else {
1869             //   angle = Math.PI/exp;
1870             // }
1871             // needed: a clean rotating based on factor 'exp'
1872 
1873             // priorization of expression like 't*a' --> a := startPoint
1874         }
1875       }
1876 
1877       try {
1878         JXG.debug("* <b>Vector:</b> First: " + attr.name);
1879         p = board.create('arrow', [s, e], attr);
1880         return p;
1881       } catch(e) {
1882         JXG.debug("* <b>Err:</b> Vector " + attr.name + e +"<br>\n");
1883         return false;
1884       }
1885     break;
1886     case 'rotate':
1887       attr = JXG.GeogebraReader.boardProperties(gxtEl, element, attr);
1888       attr = JXG.GeogebraReader.colorProperties(element, attr);
1889       gxtEl = JXG.GeogebraReader.coordinates(gxtEl, element);
1890       attr = JXG.GeogebraReader.visualProperties(element, attr);
1891 
1892       try {
1893         JXG.debug("* <b>Rotate:</b> First: " + input[0].name + ", Second: " + input[1] + "<br>\n");
1894         attr.type = 'rotate';
1895 
1896         if(!JXG.exists(attr.styleGGB)) {
1897            attr.face = 'circle';
1898            attr.fillColor = attr.strokeColor;
1899            attr.fillOpacity = 1;
1900            attr.highlightFillColor = attr.strokeColor;
1901            attr.highlightFillOpacity = 1;
1902            attr.strokeColor = 'black';
1903            attr.strokeWidth = '1px';
1904         }
1905 
1906         t = board.create('transform', [parseInt(input[1])*Math.PI/180, input[2]], {type:'rotate'});
1907         p = board.create('point', [input[0], t], attr);
1908         return p;
1909       } catch(e) {
1910         JXG.debug("* <b>Err:</b> Rotate " + attr.name +"<br>\n");
1911         return false;
1912       }
1913     break;
1914     case 'dilate':
1915       attr = JXG.GeogebraReader.boardProperties(gxtEl, element, attr);
1916       attr = JXG.GeogebraReader.colorProperties(element, attr);
1917       gxtEl = JXG.GeogebraReader.coordinates(gxtEl, element);
1918       attr = JXG.GeogebraReader.visualProperties(element, attr);
1919 
1920       try {
1921         JXG.debug("* <b>Dilate:</b> First: " + input[0].name + ", Second: " + input[1] + "<br>\n");
1922         attr.type = 'rotate';
1923         var d = parseInt(input[1]);
1924         var d1 = board.create('transform', [d, d], {type:'scale'});
1925         var d2 = board.create('transform', [function() { return (1-d) * input[2].X(); },
1926                                                function() { return (1-d) * input[2].Y(); }], {type:'translate'});
1927 
1928         if(!JXG.exists(attr.styleGGB)) {
1929            attr.face = 'circle';
1930            attr.fillColor = attr.strokeColor;
1931            attr.fillOpacity = 1;
1932            attr.highlightFillColor = attr.strokeColor;
1933            attr.highlightFillOpacity = 1;
1934            attr.strokeColor = 'black';
1935            attr.strokeWidth = '1px';
1936         }
1937         p = board.create('point', [input[0], [d1, d2]], attr);
1938 
1939         return p;
1940       } catch(e) {
1941         JXG.debug("* <b>Err:</b> Dilate " + attr.name +"<br>\n");
1942         return false;
1943       }
1944     break;
1945     case 'translate':
1946       attr = JXG.GeogebraReader.boardProperties(gxtEl, element, attr);
1947       attr = JXG.GeogebraReader.colorProperties(element, attr);
1948       gxtEl = JXG.GeogebraReader.coordinates(gxtEl, element);
1949       attr = JXG.GeogebraReader.visualProperties(element, attr);
1950 
1951       try {
1952           t = board.create('transform', [function() { return input[1].point2.X()-input[1].point1.X(); },
1953                                          function() { return input[1].point2.Y()-input[1].point1.Y(); }], {type:'translate'});
1954           if(!JXG.exists(attr.styleGGB)) {
1955              attr.face = 'circle';
1956              attr.fillColor = attr.strokeColor;
1957              attr.fillOpacity = 1;
1958              attr.highlightFillColor = attr.strokeColor;
1959              attr.highlightFillOpacity = 1;
1960              attr.strokeColor = 'black';
1961              attr.strokeWidth = '1px';
1962           }
1963           p = board.create('point', [input[0], t], attr);
1964           return p;
1965       } catch(e) {
1966         JXG.debug("* <b>Err:</b> Translate " + attr.name +"<br>\n");
1967         return false;
1968       }
1969     break;
1970     case 'mirror':
1971       attr = JXG.GeogebraReader.boardProperties(gxtEl, element, attr);
1972       attr = JXG.GeogebraReader.colorProperties(element, attr);
1973       gxtEl = JXG.GeogebraReader.coordinates(gxtEl, element);
1974       attr = JXG.GeogebraReader.visualProperties(element, attr);
1975 
1976       if (JXG.isPoint(JXG.getRef(board, input[1].id))) var type = 'mirrorpoint'; // Punktspiegelung
1977       else if(JXG.getRef(board, input[1].id).elementClass == JXG.OBJECT_CLASS_LINE) var type = 'reflection'; // Geradenspiegelung
1978 
1979       try {
1980         JXG.debug("* <b>Mirror:</b> First: " + input[0].name + ", Second: " + input[1].name + "<br>\n");
1981         p = board.create(type, [input[1], input[0]], attr);
1982         return p;
1983       } catch(e) {
1984         JXG.debug("* <b>Err:</b> Mirror " + attr.name +"<br>\n");
1985         return false;
1986       }
1987     break;
1988     case 'circle':
1989       attr = JXG.GeogebraReader.boardProperties(gxtEl, element, attr);
1990       attr = JXG.GeogebraReader.colorProperties(element, attr);
1991       gxtEl = JXG.GeogebraReader.coordinates(gxtEl, element);
1992       attr = JXG.GeogebraReader.visualProperties(element, attr);
1993 
1994       try {
1995         JXG.debug("* <b>Circle:</b> First: " + input[0].name + ", Second: " + input[1] + "<br>\n");
1996         p = board.create('circle', input, attr);
1997         return p;
1998       } catch(e) {
1999         JXG.debug("* <b>Err:</b> Circle " + attr.name +"<br>\n");
2000         return false;
2001       }
2002     break;
2003     case 'circlearc':
2004       attr = JXG.GeogebraReader.boardProperties(gxtEl, element, attr);
2005       attr = JXG.GeogebraReader.colorProperties(element, attr);
2006       gxtEl = JXG.GeogebraReader.coordinates(gxtEl, element);
2007       attr = JXG.GeogebraReader.visualProperties(element, attr);
2008 
2009       try {
2010         JXG.debug("* <b>CircleArc:</b> First: " + input[0].name + ", Second: " + input[1].name + "<br>\n");
2011         p = board.create('arc', input, attr);
2012         return p;
2013       } catch(e) {
2014         JXG.debug("* <b>Err:</b> CircleArc " + attr.name +"<br>\n");
2015         return false;
2016       }
2017     break;
2018     case 'ellipse':
2019       attr = JXG.GeogebraReader.boardProperties(gxtEl, element, attr);
2020       attr = JXG.GeogebraReader.colorProperties(element, attr);
2021       gxtEl = JXG.GeogebraReader.coordinates(gxtEl, element);
2022       attr = JXG.GeogebraReader.visualProperties(element, attr);
2023 
2024       try {
2025         JXG.debug("* <b>Ellipse:</b> First: " + input[0].name + ", Second: " + input[1].name + ", Third: "+ input[2] +"<br>\n");
2026         // if third parameters is the major axis, else the third parameter is a point
2027         if(parseInt(input[2]) == input[2])
2028           input[2] = parseInt(input[2]*2); // Geogebra delivers the half major axis
2029 
2030         p = board.create('ellipse', input, attr);
2031         return p;
2032       } catch(e) {
2033         JXG.debug("* <b>Err:</b> Ellipse " + attr.name +"<br>\n");
2034         return false;
2035       }
2036     break;
2037     case 'conic':
2038       attr = JXG.GeogebraReader.boardProperties(gxtEl, element, attr);
2039       attr = JXG.GeogebraReader.colorProperties(element, attr);
2040       gxtEl = JXG.GeogebraReader.coordinates(gxtEl, element);
2041       attr = JXG.GeogebraReader.visualProperties(element, attr);
2042 
2043 //      try {
2044 	/*
2045         // is there an expression named like the conic?
2046         var exp = JXG.GeogebraReader.getElement(attr.name, true);
2047 
2048         // then get the function parameteres
2049         if(exp.attributes['exp']){
2050           // exp = JXG.GeogebraReader.functionParse(exp.attributes['exp'].value);
2051           // exp = JXG.GeogebraReader.ggbParse(exp.attributes['exp'].value);
2052 
2053 
2054 
2055           // (exp.getElementsByTagName('value')) ? exp = parseFloat(exp.getElementsByTagName('value')[0].attributes['val'].value) : false;
2056 
2057         } else */ if(input && input.length == 5) {
2058           p = board.create('conic', input, attr);
2059         } else if(element.getElementsByTagName('matrix')) {
2060           m = [];
2061           for(var i=0; i<element.getElementsByTagName('matrix')[0].attributes.length; i++) {
2062             m[i] = parseFloat(element.getElementsByTagName('matrix')[0].attributes[i].value);
2063           }
2064           p = board.create('conic', m, attr);
2065         }
2066 
2067         return p;
2068 //      } catch(e) {
2069 //        JXG.debug("* <b>Err:</b> Conic " + attr.name +"<br>\n");
2070 //        return false;
2071 //      }
2072     break;
2073     case 'circlesector':
2074       attr = JXG.GeogebraReader.boardProperties(gxtEl, element, attr);
2075       attr = JXG.GeogebraReader.colorProperties(element, attr);
2076       gxtEl = JXG.GeogebraReader.coordinates(gxtEl, element);
2077       attr = JXG.GeogebraReader.visualProperties(element, attr);
2078       //attr.names = [attr.name,'','',''];
2079       //attr2 = {};
2080       //attr2.names = attr.names;
2081       try {
2082         JXG.debug("* <b>CircleSector:</b> First: " + input[0].name + ", Second: " + input[1].name + ", Third: " + input[2].name + "<br>\n");
2083         p = board.create('sector', [input[0],input[1],input[2]], attr);
2084         /*
2085         p.point4.hideElement();
2086         p.arc.setProperty(attr);
2087         p.arc.visProp.highlightstrokewidth = (1*p.arc.visProp.strokewidth.substr(0,p.arc.visProp.strokewidth.length-2)+1)+'px';
2088         p.lines[0].setProperty(attr);
2089         p.lines[1].setProperty(attr);
2090         p.lines[0].visProp.highlightstrokewidth = (1*p.lines[0].visProp.strokerwWidth.substr(0,p.lines[0].visProp.strokewidth.length-2)+1)+'px';
2091         p.lines[1].visProp.highlightstrokewidth = (1*p.lines[1].visProp.strokerwWidth.substr(0,p.lines[1].visProp.strokewidth.length-2)+1)+'px';
2092         p.arc.hasPoint = p.arc.hasPointSector;
2093         p.arc.highlight = (function(el){ return function() {
2094             this.board.renderer.highlight(this);
2095             this.board.renderer.highlight(el.lines[0]);
2096             this.board.renderer.highlight(el.lines[1]);
2097         };})(p);
2098         p.arc.noHighlight = (function(el){ return function() {
2099             this.board.renderer.noHighlight(this);
2100             this.board.renderer.noHighlight(el.lines[0]);
2101             this.board.renderer.noHighlight(el.lines[1]);
2102         };})(p);
2103         p.lines[0].highlight = (function(el){ return function() {
2104             this.board.renderer.highlight(this);
2105             this.board.renderer.highlight(el.arc);
2106             this.board.renderer.highlight(el.lines[1]);
2107         };})(p);
2108         p.lines[1].highlight = (function(el){ return function() {
2109             this.board.renderer.highlight(this);
2110             this.board.renderer.highlight(el.arc);
2111             this.board.renderer.highlight(el.lines[0]);
2112         };})(p);
2113         p.lines[0].noHighlight = (function(el){ return function() {
2114             this.board.renderer.noHighlight(this);
2115             this.board.renderer.noHighlight(el.arc);
2116             this.board.renderer.noHighlight(el.lines[1]);
2117         };})(p);
2118         p.lines[1].noHighlight = (function(el){ return function() {
2119             this.board.renderer.noHighlight(this);
2120             this.board.renderer.noHighlight(el.arc);
2121             this.board.renderer.noHighlight(el.lines[0]);
2122         };})(p);
2123         */
2124         return p;
2125       } catch(e) {
2126         JXG.debug("* <b>Err:</b> CircleSector " + attr.name +"<br>\n");
2127         return false;
2128       }
2129     break;
2130     case 'linebisector':
2131       attr = JXG.GeogebraReader.boardProperties(gxtEl, element, attr);
2132       attr = JXG.GeogebraReader.colorProperties(element, attr);
2133       gxtEl = JXG.GeogebraReader.coordinates(gxtEl, element);
2134       attr = JXG.GeogebraReader.visualProperties(element, attr);
2135 
2136       try {
2137         JXG.debug("* <b>LineBiSector (Mittelsenkrechte):</b> First: " + input[0].name + "<br>\n");
2138         m = board.create('midpoint', input, {visible: false});
2139         if(JXG.isPoint(JXG.getRef(board, input[0].id)) && 
2140            JXG.isPoint(JXG.getRef(board, input[1].id))) {
2141           t = board.create('line', input, {visible: 'false'});
2142           p = board.create('perpendicular', [m, t], attr);
2143           // p.point.setProperty('visible:false');
2144         } else {
2145           p = board.create('perpendicular', [m, input[0]], attr);
2146           // p.point.setProperty('visible:false');
2147         }
2148         return p;
2149       } catch(e) {
2150         JXG.debug("* <b>Err:</b> LineBiSector (Mittelsenkrechte) " + attr.name +"<br>\n");
2151         return false;
2152       }
2153     break;
2154     case 'ray':
2155       attr = JXG.GeogebraReader.boardProperties(gxtEl, element, attr);
2156       attr = JXG.GeogebraReader.colorProperties(element, attr);
2157       gxtEl = JXG.GeogebraReader.coordinates(gxtEl, element);
2158       attr = JXG.GeogebraReader.visualProperties(element, attr);
2159 
2160       try {
2161         JXG.debug("* <b>Ray:</b> First: " + input[0].name + "<br>\n");
2162         attr.straightFirst = true;
2163         attr.straightLast =  false;
2164         p = board.create('line', [input[1], input[0]], attr);
2165         return p;
2166       } catch(e) {
2167         JXG.debug("* <b>Err:</b> Ray " + attr.name +"<br>\n");
2168         return false;
2169       }
2170     break;
2171     case 'tangent':
2172       attr = JXG.GeogebraReader.boardProperties(gxtEl, element, attr);
2173       attr = JXG.GeogebraReader.colorProperties(element, attr);
2174       gxtEl = JXG.GeogebraReader.coordinates(gxtEl, element);
2175       attr = JXG.GeogebraReader.visualProperties(element, attr);
2176 
2177       try {
2178         JXG.debug("* <b>Tangent:</b> First: " + input[0].name + ", Sec.: "+ input[1].name +"("+ input[1].type +")<br>\n");
2179         switch(input[1].type) {
2180           case 1330923344: // graph
2181             input[0].makeGlider(input[1]);
2182             p = board.create('tangent', [input[0]], attr);
2183             return p;
2184           break;
2185           case 1330922316: // circle 0x4F54434C
2186           case 1330922319: // conic 0x4F54434F
2187             var pol = board.create('polar',[input[1],input[0]],{visible:false});
2188 	        var i1 = board.create('intersection', [input[1], pol, 0], {visible: false});
2189 	        var i2 = board.create('intersection', [input[1], pol, 1], {visible: false});
2190 	        var t1 = board.create('line', [input[0], i1], attr);
2191             var attr2 = {};
2192             attr2 = JXG.GeogebraReader.colorProperties(output[1], attr2);
2193             attr2 = JXG.GeogebraReader.visualProperties(output[1], attr2);
2194             attr2.name = output[1].getAttribute('label');
2195             var t2 = board.create('line', [input[0], i2], attr2);
2196             board.ggbElements[attr2.name] = t2;
2197             return [t1, t2];
2198           break;
2199         }
2200       } catch(e) {
2201         JXG.debug("* <b>Err:</b> Tangent " + attr.name +" "+ attr2.name + "<br>\n");
2202         return false;
2203       }
2204     break;
2205     case 'circumcirclearc':
2206       attr = JXG.GeogebraReader.boardProperties(gxtEl, element, attr);
2207       attr = JXG.GeogebraReader.colorProperties(element, attr);
2208       gxtEl = JXG.GeogebraReader.coordinates(gxtEl, element);
2209       attr = JXG.GeogebraReader.visualProperties(element, attr);
2210 
2211       try {
2212         JXG.debug("* <b>CircumcircleArc:</b> First: " + input[0].name + "<br>\n");
2213         p = board.create('circumcirclearc', input, attr);
2214         return p;
2215       } catch(e) {
2216         JXG.debug("* <b>Err:</b> CircumcircleArc " + attr.name +"<br>\n");
2217         return false;
2218       }
2219     break;
2220     case 'circumcirclesector':
2221       attr = JXG.GeogebraReader.boardProperties(gxtEl, element, attr);
2222       attr = JXG.GeogebraReader.colorProperties(element, attr);
2223       gxtEl = JXG.GeogebraReader.coordinates(gxtEl, element);
2224       attr = JXG.GeogebraReader.visualProperties(element, attr);
2225 
2226       try {
2227         JXG.debug("* <b>CircumcircleSector:</b> First: " + input[0].name + "<br>\n");
2228         p = board.create('circumcirclesector', [input[0], input[1], input[2]], attr); //{name:attr['name']});
2229         /*
2230         p.arc.setProperty(attr);
2231         p.lines[0].setProperty(attr);
2232         p.lines[1].setProperty(attr);
2233         p.arc.visProp.highlightstrokewidth = (1*p.arc.visProp.strokewidth.substr(0,p.arc.visProp.strokewidth.length-2)+1)+'px';
2234         p.lines[0].visProp.highlightstrokewidth = (1*p.lines[0].visProp.strokewidth.substr(0,p.lines[0].visProp.strokewidth.length-2)+1)+'px';
2235         p.lines[1].visProp.highlightstrokewidth = (1*p.lines[1].visProp.strokewidth.substr(0,p.lines[1].visProp.strokewidth.length-2)+1)+'px';
2236         p.arc.hasPoint = p.arc.hasPointSector;
2237         p.arc.highlight = (function(el){ return function() {
2238             this.board.renderer.highlight(this);
2239             this.board.renderer.highlight(el.lines[0]);
2240             this.board.renderer.highlight(el.lines[1]);
2241         };})(p);
2242         p.arc.noHighlight = (function(el){ return function() {
2243             this.board.renderer.noHighlight(this);
2244             this.board.renderer.noHighlight(el.lines[0]);
2245             this.board.renderer.noHighlight(el.lines[1]);
2246         };})(p);
2247         p.lines[0].highlight = (function(el){ return function() {
2248             this.board.renderer.highlight(this);
2249             this.board.renderer.highlight(el.arc);
2250             this.board.renderer.highlight(el.lines[1]);
2251         };})(p);
2252         p.lines[1].highlight = (function(el){ return function() {
2253             this.board.renderer.highlight(this);
2254             this.board.renderer.highlight(el.arc);
2255             this.board.renderer.highlight(el.lines[0]);
2256         };})(p);
2257         p.lines[0].noHighlight = (function(el){ return function() {
2258             this.board.renderer.noHighlight(this);
2259             this.board.renderer.noHighlight(el.arc);
2260             this.board.renderer.noHighlight(el.lines[1]);
2261         };})(p);
2262         p.lines[1].noHighlight = (function(el){ return function() {
2263             this.board.renderer.noHighlight(this);
2264             this.board.renderer.noHighlight(el.arc);
2265             this.board.renderer.noHighlight(el.lines[0]);
2266         };})(p);
2267         */
2268         return p;
2269       } catch(e) {
2270         JXG.debug("* <b>Err:</b> CircumcircleSector " + attr.name +"<br>\n");
2271         return false;
2272       }
2273     break;
2274     case 'semicircle':
2275       attr = JXG.GeogebraReader.boardProperties(gxtEl, element, attr);
2276       attr = JXG.GeogebraReader.colorProperties(element, attr);
2277       gxtEl = JXG.GeogebraReader.coordinates(gxtEl, element);
2278       attr = JXG.GeogebraReader.visualProperties(element, attr);
2279 
2280       try {
2281         JXG.debug("* <b>Semicircle:</b> First: " + input[0].name + "<br>\n");
2282         p = board.create('semicircle', [input[0], input[1]], attr);
2283         return p;
2284       } catch(e) {
2285         JXG.debug("* <b>Err:</b> Semicircle " + attr.name +"<br>\n");
2286         return false;
2287       }
2288     break;
2289     case 'angle':
2290       attr = JXG.GeogebraReader.boardProperties(gxtEl, element, attr);
2291       attr = JXG.GeogebraReader.colorProperties(element, attr);
2292       gxtEl = JXG.GeogebraReader.coordinates(gxtEl, element);
2293       attr = JXG.GeogebraReader.visualProperties(element, attr);
2294 
2295       try {
2296         JXG.debug("* <b>Angle:</b> First: " + input[0].name + "<br>\n");
2297         p = board.create('angle', input, attr);
2298         return p;
2299       } catch(e) {
2300         JXG.debug("* <b>Err:</b> Angle " + attr.name +"<br>\n");
2301         return false;
2302       }
2303     break;
2304     case 'angularbisector':
2305       attr = JXG.GeogebraReader.boardProperties(gxtEl, element, attr);
2306       attr = JXG.GeogebraReader.colorProperties(element, attr);
2307       gxtEl = JXG.GeogebraReader.coordinates(gxtEl, element);
2308       attr = JXG.GeogebraReader.visualProperties(element, attr);
2309       attr.straightFirst = true;
2310       attr.straightLast = true;
2311 
2312       try {
2313         JXG.debug("* <b>Angularbisector:</b> First: " + input[0].name + "<br>\n");
2314         p = board.create('bisector', input, attr);
2315         return p;
2316       } catch(e) {
2317         JXG.debug("* <b>Err:</b> Angularbisector " + attr.name +"<br>\n");
2318         return false;
2319       }
2320     break;
2321     case 'numeric':
2322     if(element.getElementsByTagName('slider').length == 0) {
2323       // auxiliary doesn't exist in every numeric
2324       //element.getElementsByTagName('auxiliary').length != 0 && element.getElementsByTagName('auxiliary')[0].attributes['val'].value == 'true') {
2325       exp = JXG.GeogebraReader.getElement(element.getAttribute('label'), true);
2326       if(exp) {
2327     	  exp = exp.getAttribute('exp');
2328     	  exp = JXG.GeogebraReader.functionParse('', exp);
2329     	  exp = JXG.GeogebraReader.ggbParse(exp);
2330       }
2331       board.ggb[attr.name] = new Function('return '+ exp +';');
2332       JXG.debug('value: '+ board.ggb[attr.name]());
2333       return board.ggb[attr.name];
2334 	} else {
2335       attr = JXG.GeogebraReader.boardProperties(gxtEl, element, attr);
2336       attr = JXG.GeogebraReader.colorProperties(element, attr);
2337       // gxtEl = JXG.GeogebraReader.coordinates(gxtEl, element);
2338       attr = JXG.GeogebraReader.visualProperties(element, attr);
2339       if(element.getElementsByTagName('slider').length == 1) { // it's a slider
2340         sx = parseFloat(element.getElementsByTagName('slider')[0].getAttribute('x'));
2341         sy = parseFloat(element.getElementsByTagName('slider')[0].getAttribute('y'));
2342         length = parseFloat(element.getElementsByTagName('slider')[0].getAttribute('width'));
2343         // are coordinates absolut?
2344         if(element.getElementsByTagName('slider')[0].getAttribute('absoluteScreenLocation') && element.getElementsByTagName('slider')[0].getAttribute('absoluteScreenLocation') == 'true') {
2345           var tmp = new JXG.Coords(JXG.COORDS_BY_SCREEN, [sx, sy], board);
2346           sx = tmp.usrCoords[1];
2347           sy = tmp.usrCoords[2];
2348         }
2349 
2350         if(element.getElementsByTagName('slider')[0].getAttribute('horizontal') == 'true') {
2351           if(element.getElementsByTagName('slider')[0].getAttribute('absoluteScreenLocation') && element.getElementsByTagName('slider')[0].getAttribute('absoluteScreenLocation') == 'true')
2352           length /= (board.unitX); //*board.zoomX);
2353           ex = sx + length;
2354           ey = sy;
2355         } else {
2356           if(element.getElementsByTagName('slider')[0].getAttribute('absoluteScreenLocation') && element.getElementsByTagName('slider')[0].getAttribute('absoluteScreenLocation') == 'true')
2357           length /= (board.unitY); //*board.zoomY);
2358           ex = sx;
2359           ey = sy + length;
2360         }
2361 
2362         (element.getElementsByTagName('animation')[0]) ? attr.snapWidth = parseFloat(element.getElementsByTagName('animation')[0].getAttribute('step')) : false;
2363 
2364         try {
2365           JXG.debug("* <b>Numeric:</b> First: " + attr.name + "<br>\n");
2366           attr['withTicks'] = false;
2367           p = board.create('slider', [[sx,sy], [ex,ey], [parseFloat(element.getElementsByTagName('slider')[0].getAttribute('min')),
2368                                                          parseFloat(element.getElementsByTagName('value')[0].getAttribute('val')),
2369                                                          parseFloat(element.getElementsByTagName('slider')[0].getAttribute('max'))]], attr);
2370           p.setProperty({withLabel:false});
2371           return p;
2372         } catch(e) {
2373           JXG.debug("* <b>Err:</b> Numeric " + attr.name +"<br>\n");
2374           return false;
2375         }
2376       }
2377     }
2378     break;
2379     case 'midpoint':
2380       attr = JXG.GeogebraReader.boardProperties(gxtEl, element, attr);
2381       attr = JXG.GeogebraReader.colorProperties(element, attr);
2382       gxtEl = JXG.GeogebraReader.coordinates(gxtEl, element);
2383       attr = JXG.GeogebraReader.visualProperties(element, attr);
2384 
2385       try {
2386           if(!JXG.exists(attr.styleGGB)) {
2387              attr.face = 'circle';
2388              attr.fillColor = attr.strokeColor;
2389              attr.fillOpacity = 1;
2390              attr.highlightFillColor = attr.strokeColor;
2391              attr.highlightFillOpacity = 1;
2392              attr.strokeColor = 'black';
2393              attr.strokeWidth = '1px';
2394           }
2395           p = board.create('midpoint', input, attr);
2396           JXG.debug("* <b>Midpoint ("+ p.id +"):</b> "+ attr.name + "("+ gxtEl.x +", "+ gxtEl.y +")<br>\n");
2397           return p;
2398       } catch(e) {
2399           JXG.debug("* <b>Err:</b> Midpoint " + attr.name +"<br>\n");
2400           return false;
2401       }
2402     break;
2403     case 'center':
2404       attr = JXG.GeogebraReader.boardProperties(gxtEl, element, attr);
2405       attr = JXG.GeogebraReader.colorProperties(element, attr);
2406       gxtEl = JXG.GeogebraReader.coordinates(gxtEl, element);
2407       attr = JXG.GeogebraReader.visualProperties(element, attr);
2408       try {
2409           if(!JXG.exists(attr.styleGGB)) {
2410              attr.face = 'circle';
2411              attr.fillColor = attr.strokeColor;
2412              attr.fillOpacity = 1;
2413              attr.highlightFillColor = attr.strokeColor;
2414              attr.highlightFillOpacity = 1;
2415              attr.strokeColor = 'black';
2416              attr.strokeWidth = '1px';
2417           }
2418           p = board.create('point', [function() { return JXG.getRef(board, input[0].id).center.X(); },
2419                                      function() { return JXG.getRef(board, input[0].id).center.Y(); }], attr);
2420           JXG.debug("* <b>Center ("+ p.id +"):</b> "+ attr.name + "("+ gxtEl.x +", "+ gxtEl.y +")<br>\n");
2421           return p;
2422       } catch(e) {
2423           JXG.debug("* <b>Err:</b> Center " + attr.name +"<br>\n");
2424           return false;
2425       }
2426     break;
2427     case 'function':
2428       attr = JXG.GeogebraReader.boardProperties(gxtEl, element, attr);
2429       attr = JXG.GeogebraReader.colorProperties(element, attr);
2430       gxtEl = JXG.GeogebraReader.coordinates(gxtEl, element);
2431       attr = JXG.GeogebraReader.visualProperties(element, attr);
2432 
2433       if(JXG.GeogebraReader.getElement(attr.name, true)) {
2434         func = JXG.GeogebraReader.getElement(attr.name, true).getAttribute('exp');
2435         func = JXG.GeogebraReader.functionParse('c', func);
2436       } else {
2437         func = input[0];
2438         func = JXG.GeogebraReader.functionParse('s', func);
2439       }
2440 
2441       JXG.debug(func);
2442 
2443       length = func.length;
2444       func[func.length-1] = 'return '+ JXG.GeogebraReader.ggbParse(func[func.length-1]) +';';
2445 
2446       JXG.debug(func);
2447 
2448       range = [(input && input[1]) ? input[1] : null, (input && input[2]) ? input[2] : null];
2449 
2450       try {
2451         if(length == 1)
2452           p = board.create('functiongraph', [new Function(func[0]), range[0], range[1]], attr);
2453         else if(length==2)
2454           p = board.create('functiongraph', [new Function(func[0], func[1]), range[0], range[1]], attr);
2455         else if(length==3)
2456           p = board.create('functiongraph', [new Function(func[0], func[1], func[2]), range[0], range[1]], attr);
2457         else if(length==4)
2458           p = board.create('functiongraph', [new Function(func[0], func[1], func[2], func[3]), range[0], range[1]], attr);
2459         else if(length==5)
2460           p = board.create('functiongraph', [new Function(func[0], func[1], func[2], func[3], func[4]), range[0], range[1]], attr);
2461         return p;
2462       } catch(e) {
2463         JXG.debug("* <b>Err:</b> Functiongraph " + attr.name +"<br>\n");
2464         return false;
2465       }
2466 
2467      break;
2468      case 'polar':
2469       attr = JXG.GeogebraReader.boardProperties(gxtEl, element, attr);
2470       attr = JXG.GeogebraReader.colorProperties(element, attr);
2471       gxtEl = JXG.GeogebraReader.coordinates(gxtEl, element);
2472       attr = JXG.GeogebraReader.visualProperties(element, attr);
2473 
2474       try {
2475         JXG.debug("* <b>Polar:</b> First: " + input[0].name + ", Sec.: "+ input[1].name +"<br>\n");
2476         p = board.create('polar', input, attr);
2477         return p;
2478       } catch(e) {
2479         JXG.debug("* <b>Err:</b> Polar " + attr.name +"<br>\n");
2480         return false;
2481       }
2482     break;
2483     case 'slope':
2484      attr = JXG.GeogebraReader.boardProperties(gxtEl, element, attr);
2485      attr = JXG.GeogebraReader.colorProperties(element, attr);
2486      gxtEl = JXG.GeogebraReader.coordinates(gxtEl, element);
2487      attr = JXG.GeogebraReader.visualProperties(element, attr);
2488 
2489      try {
2490        JXG.debug("* <b>Slope ("+ attr.name +"):</b> First: " + input[0].name +"<br>\n");
2491        var slopeWidth = parseInt(attr.slopeWidth) || 1.0;
2492        var p1 = input[0].glider || input[0].point1;
2493        var p2 = board.create('point',[function(){return (slopeWidth+p1.X());}, function(){return p1.Y();}], {visible: false});
2494        var l1 = board.create('segment', [p1, p2], {visible: false}); // visible: attr.visible
2495        var l2 = board.create('normal', [l1, l1.point2], {visible: false}); // visible attr.visible
2496        var i  = board.create('intersection', [input[0], l2, 0], {visible: false});
2497        var m  = board.create('midpoint', [l1.point2, i], {visible: false});
2498 
2499        var t = board.create('text', [function(){return m.X();}, function(){return m.Y();},
2500                       function(){ return "  " + (slopeWidth > 1 ? slopeWidth.toString() : "") + " " + this.name + " = " + JXG.trimNumber((slopeWidth * input[0].getSlope()).toFixed(JXG.GeogebraReader.decimals)); }], attr);
2501        attr.name = "";
2502        var t2 = board.create('text', [function(){return (p1.X() + p2.X())/2.;}, function(){return p1.Y();},
2503                                      function(){ return "<br/>" + slopeWidth; }], attr);
2504        t.Value = (function() { return function(){ return input[0].getSlope(); }; })();
2505        var poly = board.create('polygon',[p1,p2,i], attr);
2506 
2507        poly.borders[2].setProperty({visible: false});
2508        poly.borders[0].setProperty({strokeColor: attr.fillColor, strokeWidth: attr.strokeWidth, highlightStrokeColor: attr.fillColor, dash:attr.dash});
2509        poly.borders[1].setProperty({strokeColor: attr.fillColor, strokeWidth: attr.strokeWidth, highlightStrokeColor: attr.fillColor, dash:attr.dash});       
2510        return t;
2511      } catch(e) {
2512        JXG.debug("* <b>Err:</b> Slope " + attr.name +"<br>\n");
2513        return false;
2514      }
2515     break;
2516     case 'text':
2517      attr = JXG.GeogebraReader.boardProperties(gxtEl, element, attr);
2518      attr = JXG.GeogebraReader.colorProperties(element, attr);
2519      gxtEl = JXG.GeogebraReader.coordinates(gxtEl, element);
2520      attr = JXG.GeogebraReader.visualProperties(element, attr);
2521      var rx, res = '';
2522 
2523      try {
2524        if(element.getElementsByTagName('isLaTeX')[0] && element.getElementsByTagName('isLaTeX')[0].getAttribute('val') == 'true') {
2525          JXG.GeogebraReader.board.options.text.useASCIIMathML = true;
2526          t = JXG.GeogebraReader.getElement(attr.name, true).getAttribute('exp');
2527 
2528          // here we're searching for patterns like
2529          //    " + ... + "
2530          // ... will be sent to the ggbParser and a calculated text element is built from this.
2531          while(rx = t.match(/(.*?)" \+ (.+) \+ "(.*)/)) {
2532              var re2 = JXG.GeogebraReader.ggbParse(RegExp.$2);
2533              if (typeof re2 == 'string') {
2534                res = res + RegExp.$1 + re2;
2535              } else {
2536                res = res + RegExp.$1 + '" + JXG.trimNumber((' + re2 + ').toFixed(JXG.GeogebraReader.decimals)) + "';
2537              }
2538              t = RegExp.$3;
2539          }
2540          // we have to look, if the string's ending with a string-part or a formula part:
2541          if(rx = t.match(/(.*?)" \+ (.+)/)) {
2542              res = res + RegExp.$1 + '" + JXG.trimNumber((' + JXG.GeogebraReader.ggbParse(RegExp.$2) + ').toFixed(JXG.GeogebraReader.decimals))';
2543          } else
2544              res = res + t;
2545 
2546          JXG.debug("Text: "+res);
2547 
2548          p = board.create('text', [gxtEl.x, gxtEl.y, new Function('return ' + res + ';')], attr);
2549        } else {
2550          JXG.debug(JXG.GeogebraReader.getElement(attr.name, true).getAttribute('exp'));
2551          t = JXG.GeogebraReader.ggbParse(JXG.GeogebraReader.functionParse(false, JXG.GeogebraReader.getElement(attr.name, true).getAttribute('exp')));
2552          JXG.debug(t[1]);
2553          p = board.create('text', [gxtEl.x, gxtEl.y, new Function('return '+t[0]+' + " " + JXG.trimNumber(parseFloat(' + t[1] +').toFixed(JXG.GeogebraReader.decimals));') ], attr);
2554        }
2555        JXG.debug("* <b>Text:</b> " + t  +"<br>\n");
2556        return p;
2557      } catch(e) {
2558       JXG.debug("* <b>Err:</b> Text: " + t +"<br>\n");
2559       return false;
2560      }
2561     break;
2562     case 'root':
2563         attr = JXG.GeogebraReader.boardProperties(gxtEl, element, attr);
2564         attr = JXG.GeogebraReader.colorProperties(element, attr);
2565         gxtEl = JXG.GeogebraReader.coordinates(gxtEl, element);
2566         attr = JXG.GeogebraReader.visualProperties(element, attr);
2567         //JXG.debug(JXG.getRef(board, gxtEl.id));
2568 
2569         for(var i=0; i<output.length; i++) {
2570           output[i] = JXG.GeogebraReader.checkElement(output[i].getAttribute('label'));
2571         }
2572         
2573         var inp;
2574         if(JXG.isArray(input)) {
2575             inp = input[0];
2576         } else {
2577             inp = input;
2578         }
2579 
2580         // At this point, the output points already exist. 
2581         // Bind the root function to all output elements.
2582         // The start values for all output elements are the x-coordinates as given
2583         // in the ggb file.
2584         for(i=0; i<output.length; i++) {
2585             output[i].addConstraint([
2586                     (function(x){ return function(){ return board.root(inp.Y,x,inp);}; })(output[i].X()), 
2587                     function(){ return 0;}
2588                 ]);
2589         }
2590         //var p = board.create('point', [function(){ return board.root(output);}, function(){ return 1;}], attr);
2591         return output; // What to return here????
2592     break;
2593   case 'integral':
2594       attr = JXG.GeogebraReader.boardProperties(gxtEl, element, attr);
2595       attr = JXG.GeogebraReader.colorProperties(element, attr);
2596       gxtEl = JXG.GeogebraReader.coordinates(gxtEl, element);
2597       attr = JXG.GeogebraReader.visualProperties(element, attr);
2598 
2599       try {
2600         JXG.debug("* <b>Integral:</b> First: " + input[0].name + ", Sec.: "+ input[1].name +", Thir.: "+ input[2].name +"<br>\n");
2601         JXG.debug([input[1](), input[2]()]);
2602         var p = board.create('integral', [JXG.getRef(board, input[0]), [input[1], input[2]]], attr);
2603         return p;
2604       } catch(e) {
2605         JXG.debug("* <b>Err:</b> Integral " + attr.name + e + "<br>\n");
2606         return false;
2607       }
2608     break;
2609 
2610 // case 'transform':
2611 // break;
2612 //    case 'radius':
2613 //    break;
2614 //    case 'derivative':
2615 //    break;
2616 //    case 'root':
2617 //    break;
2618 //    case 'corner':
2619 //    break;
2620 //    case 'unitvector':
2621 //    break;
2622 //    case 'extremum':
2623 //    break;
2624 //    case 'turningpoint':
2625 //    break;
2626 //    case 'arc':
2627 //    break;
2628 //    case 'circlepart':
2629 //    break;
2630 //    case 'uppersum':
2631 //    break;
2632 //    case 'lowersum':
2633 //    break;
2634 //    case 'image':
2635 //    break;
2636     default:
2637       return false;
2638     break;
2639   }
2640 };
2641 
2642 /**
2643  * Reading the elements of a geogebra file
2644  * @param {Object} board board object
2645  */
2646 this.readGeogebra = function(tree, board) {
2647   var el, Data, i, els = [], expr;
2648 
2649   board.ggbElements = [];
2650   board.ggb = {};
2651   JXG.GeogebraReader.tree = tree;
2652   JXG.GeogebraReader.board = board;
2653   JXG.GeogebraReader.format = parseFloat(JXG.GeogebraReader.tree.getElementsByTagName('geogebra')[0].getAttribute('format'));
2654   JXG.GeogebraReader.decimals = parseInt(JXG.GeogebraReader.tree.getElementsByTagName('geogebra')[0].getElementsByTagName('kernel')[0].getElementsByTagName('decimals')[0].getAttribute('val'));
2655   JXG.GeogebraReader.writeBoard(board);
2656   board = JXG.GeogebraReader.setDefaultOptions(board);
2657 
2658   // speeding up the drawing process
2659   //board.suspendUpdate();
2660 
2661   var constructions = JXG.GeogebraReader.tree.getElementsByTagName("construction");
2662   for (var t=0; t<constructions.length; t++) {
2663 
2664     var cmds = constructions[t].getElementsByTagName("command");
2665     for (var s=0; s<cmds.length; s++) {
2666       Data = cmds[s];
2667 
2668       // JXG.debug('now i\'ll parse the command:');
2669       // JXG.debug(Data);
2670 
2671       var input = [];
2672       for (i=0; i<Data.getElementsByTagName("input")[0].attributes.length; i++) {
2673         el = Data.getElementsByTagName("input")[0].attributes[i].value;
2674         if(el.match(/\u00B0/) || !el.match(/\D/) || el.match(/Circle/) || Data.getAttribute('name') == 'Function' || el == parseFloat(el) ) {
2675           input[i] = el;
2676         // } else if(el.match(/[a-zA-Z]+\[[a-zA-Z0-9]+[a-zA-Z0-9,\ ]*\]/)) {
2677         //   input[i] = JXG.GeogebraReader.writeElement(board, )
2678         } else if(el == 'xAxis' || el == 'yAxis') {
2679           input[i] = board.ggbElements[el];
2680         } else {
2681           input[i] = JXG.GeogebraReader.checkElement(el);
2682         }
2683       };
2684 
2685       var output = [], elname = Data.getElementsByTagName("output")[0].attributes[0].value;
2686       for (i=0; i<Data.getElementsByTagName("output")[0].attributes.length; i++) {
2687         el = Data.getElementsByTagName("output")[0].attributes[i].value;
2688         output[i] = JXG.GeogebraReader.getElement(el);
2689       };
2690       if(typeof board.ggbElements[elname] == 'undefined' || board.ggbElements[elname] == '') {
2691         board.ggbElements[elname] = JXG.GeogebraReader.writeElement(board, output, input, Data.getAttribute('name').toLowerCase());
2692         // JXG.debug("regged: "+board.ggbElements[elname].id+"<br/>");
2693 
2694         /* register borders to according "parent" */
2695         if(board.ggbElements[elname].borders)
2696           for(var i=0; i<board.ggbElements[elname].borders.length; i++) {
2697             board.ggbElements[board.ggbElements[elname].borders[i].name] = board.ggbElements[elname].borders[i];
2698             // JXG.debug(i+") regged: "+board.ggbElements[elname].borders[i].name+"("+ board.ggbElements[board.ggbElements[elname].borders[i].name].id +")<br/>");
2699           };
2700       }
2701     };
2702 
2703     JXG.debug('Restesammler: ');
2704     // create "single" elements which do not depend on any other
2705     var elements = constructions[t].getElementsByTagName("element");
2706     for (var s=0; s<elements.length; s++) {
2707       var Data = elements[s];
2708       var el = Data.getAttribute('label');
2709 
2710       if(typeof board.ggbElements[el] == 'undefined' || board.ggbElements[el] == '') {
2711         board.ggbElements[el] = JXG.GeogebraReader.writeElement(board, Data);
2712 
2713         if(expr = JXG.GeogebraReader.getElement(el, true)) {
2714           var type = Data.getAttribute('type');
2715           switch(type) {
2716             case 'text':
2717             case 'function':
2718               // board.ggbElements[el] = JXG.GeogebraReader.writeElement(board.ggbElements, board, expr, false, type);
2719             break;
2720             default:
2721               JXG.GeogebraReader.ggbParse(expr.getAttribute('exp'), el);
2722             break;
2723           }
2724         }
2725 
2726       }
2727     };
2728 
2729   }; // end: for construction
2730 
2731   // speeding up the drawing process
2732   board.unsuspendUpdate();
2733 
2734   board.fullUpdate();
2735  // delete(board.ggbElements);
2736 };
2737 
2738 /**
2739  * Clean the utf8-symbols in a Geogebra expression in JavaScript syntax
2740  * @param {String} string to clean
2741  * @return {String} replaced string
2742  */
2743 this.utf8replace = function(exp) {
2744   exp = (exp.match(/\u03C0/)) ? exp.replace(/\u03C0/g, 'PI') : exp;
2745   exp = (exp.match(/\u00B2/)) ? exp.replace(/\u00B2/g, '^2') : exp;
2746   exp = (exp.match(/\u00B3/)) ? exp.replace(/\u00B3/g, '^3') : exp;
2747   exp = (exp.match(/\u225F/)) ? exp.replace(/\u225F/g, '==') : exp;
2748   exp = (exp.match(/\u2260/)) ? exp.replace(/\u2260/g, '!=') : exp;
2749   exp = (exp.match(/\u2264/)) ? exp.replace(/\u2264/g, '<=') : exp;
2750   exp = (exp.match(/\u2265/)) ? exp.replace(/\u2265/g, '>=') : exp;
2751   exp = (exp.match(/\u2227/)) ? exp.replace(/\u2227/g, '&&') : exp;
2752   exp = (exp.match(/\u2228/)) ? exp.replace(/\u2228/g, '//') : exp;
2753   return exp;
2754 };
2755 
2756 /**
2757  * Extracting the packed geogebra file in order to return the "blank" xml-tree for further parsing.
2758  * @param {String} archive containing geogebra.xml-file or raw input string (eg. xml-tree)
2759  * @return {String} content of geogebra.xml-file if archive was passed in
2760  */
2761 this.prepareString = function(fileStr, isString) {
2762     var i, bA, len, fstr;
2763 
2764     // here we have to deal with two different base64 encoded streams
2765     // first one: base64 encoded xml (geogebra's web export)
2766     // second one: base64 encoded ggb file, this is our recommendation for an IE & Opera
2767     // workaround, which can't deal with binary data transferred via AJAX.
2768 
2769     // first try to decode assuming we got a base64 encoded ggb file
2770     if(isString) {
2771         fstr = JXG.Util.Base64.decode(fileStr);
2772         if(fstr.slice(0,2)!=="PK") {
2773             // ooops, that was no ggb file. try again with utf8 parameter set.
2774             fstr = JXG.Util.Base64.decode(fileStr, true);
2775         }
2776         fileStr = fstr;
2777     }
2778 
2779     if (fileStr.indexOf('<') != 0) {
2780         bA = [];
2781         len = fileStr.length;
2782         for (i=0;i<len;i++)
2783             bA[i]=JXG.Util.asciiCharCodeAt(fileStr,i);
2784         // Unzip
2785         fileStr = (new JXG.Util.Unzip(bA)).unzipFile("geogebra.xml");
2786     }
2787     fileStr = JXG.Util.utf8Decode(fileStr);
2788     fileStr = JXG.GeogebraReader.utf8replace(fileStr);
2789     return fileStr;
2790 };
2791 
2792 /**
2793  * Checking if a parameter is a Geogebra vector (array with length 3)
2794  * @param {Object} possible Geogebra vector
2795  * @return {boolean}
2796  */
2797 this.isGGBVector = function(v){
2798 	return JXG.isArray(v) && v.length == 3 && v[0] == 1;	
2799 };
2800 }; // end: GeogebraReader()
2801