Subversion Repositories wimsdev

Rev

Blame | Last modification | View Log | RSS feed

  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.getReference(JXG.GeogebraReader.board, "'+ v1 +'")' : v1;
  17.       s2 = (JXG.GeogebraReader.board.ggbElements[v2]) ? 'JXG.getReference(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\.getReference\(JXG\.GeogebraReader\.board, "(.+?)"\)\./) && v1.match(/JXG\.getReference/) ) {
  43.         s1 = [v1+'.X()', v1+'.Y()'];
  44.       } else {
  45.         s1 = v1;
  46.       }
  47.  
  48.       if( JXG.isString(v2) && !v2.match(/JXG\.getReference\(JXG\.GeogebraReader\.board, "(.+?)"\)\./) && v2.match(/JXG\.getReference/) ) {
  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\.getReference\(JXG\.GeogebraReader\.board, "(.+?)"\)\./) && v1.match(/JXG\.getReference/) ) {
  84.         s1 = [v1+'.X()', v1+'.Y()'];
  85.       } else {
  86.         s1 = v1;
  87.       }
  88.  
  89.       if( JXG.isString(v2) && !v2.match(/JXG\.getReference\(JXG\.GeogebraReader\.board, "(.+?)"\)\./) && v2.match(/JXG\.getReference/) ) {
  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\.getReference\(JXG\.GeogebraReader\.board, "(.+?)"\)\./) && v1.match(/JXG\.getReference/) ) {
  140.                         s1 = [v1+'.X()', v1+'.Y()'];
  141.                       } else {
  142.                         s1 = v1;
  143.                       }
  144.  
  145.                 if( JXG.isString(v2) && !v2.match(/JXG\.getReference\(JXG\.GeogebraReader\.board, "(.+?)"\)\./) && v2.match(/JXG\.getReference/) ) {
  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\.getReference\(JXG\.GeogebraReader\.board, "(.+?)"\)\./) && v1.match(/JXG\.getReference/) ) {
  170.         s1 = [v1+'.X()', v1+'.Y()'];
  171.       } else {
  172.         s1 = v1;
  173.       }
  174.  
  175.       if( JXG.isString(v2) && !v2.match(/JXG\.getReference\(JXG\.GeogebraReader\.board, "(.+?)"\)\./) && v2.match(/JXG\.getReference/) ) {
  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.getReference(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.getReference(JXG.GeogebraReader.board, "'+ v1 +'").Value()';
  275.           } else if(typeof a.Area != 'undefined') {
  276.             return 'JXG.getReference(JXG.GeogebraReader.board, "'+ v1 +'").Area()';
  277.           } else if(typeof a.plaintextStr != 'undefined') {
  278.             return '1.0*JXG.getReference(JXG.GeogebraReader.board, "'+ v1 +'").plaintextStr';
  279.           } else if (a.type == JXG.OBJECT_TYPE_VECTOR){
  280.             return new Array(1, 'JXG.getReference(JXG.GeogebraReader.board, "'+ v1 +'").point2.X()-JXG.getReference(JXG.GeogebraReader.board, "'+ v1 +'").point1.X()','JXG.getReference(JXG.GeogebraReader.board, "'+ v1 +'").point2.Y()-JXG.getReference(JXG.GeogebraReader.board, "'+ v1 +'").point1.Y()');
  281.           }else if(a.elementClass == JXG.OBJECT_CLASS_LINE) {
  282.             return 'JXG.getReference(JXG.GeogebraReader.board, "'+ v1 +'").point1.Dist(JXG.getReference(JXG.GeogebraReader.board, "'+ v1 +'").point2)';
  283.           } else {
  284.             return 'JXG.getReference(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.getReference(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.getReference(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.getReference(board, input[1].id).type == 1330924622) {
  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.getReference(board, input[0].id).Dist(JXG.getReference(board, input[1].id)).toFixed(JXG.GeogebraReader.decimals));
  1813.                 }], attr);
  1814.           p.Value = function () {
  1815.             return (JXG.getReference(board, input[0].id).Dist(JXG.getReference(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.getReference(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.getReference(board, input[1].id).type == 1330925652) var type = 'mirrorpoint'; // Punktspiegelung
  1977.       else if(JXG.getReference(board, input[1].id).type == 1330924622) 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.         attr.straightFirst = true;
  2139.         attr.straightLast =  true;
  2140.  
  2141.         m = board.create('midpoint', input, {visible: false});
  2142.         if(JXG.getReference(board, input[0].id).type == 1330925652 && JXG.getReference(board, input[1].id).type == 1330925652) {
  2143.           t = board.create('line', input, {visible: 'false'});
  2144.           p = board.create('perpendicular', [m, t], attr);
  2145.           p.point.setProperty('visible:false');
  2146.         } else {
  2147.           p = board.create('perpendicular', [m, input[0]], attr);
  2148.           p.point.setProperty('visible:false');
  2149.         }
  2150.         return p[0];
  2151.       } catch(e) {
  2152.         JXG.debug("* <b>Err:</b> LineBiSector (Mittelsenkrechte) " + attr.name +"<br>\n");
  2153.         return false;
  2154.       }
  2155.     break;
  2156.     case 'ray':
  2157.       attr = JXG.GeogebraReader.boardProperties(gxtEl, element, attr);
  2158.       attr = JXG.GeogebraReader.colorProperties(element, attr);
  2159.       gxtEl = JXG.GeogebraReader.coordinates(gxtEl, element);
  2160.       attr = JXG.GeogebraReader.visualProperties(element, attr);
  2161.  
  2162.       try {
  2163.         JXG.debug("* <b>Ray:</b> First: " + input[0].name + "<br>\n");
  2164.         attr.straightFirst = true;
  2165.         attr.straightLast =  false;
  2166.         p = board.create('line', [input[1], input[0]], attr);
  2167.         return p;
  2168.       } catch(e) {
  2169.         JXG.debug("* <b>Err:</b> Ray " + attr.name +"<br>\n");
  2170.         return false;
  2171.       }
  2172.     break;
  2173.     case 'tangent':
  2174.       attr = JXG.GeogebraReader.boardProperties(gxtEl, element, attr);
  2175.       attr = JXG.GeogebraReader.colorProperties(element, attr);
  2176.       gxtEl = JXG.GeogebraReader.coordinates(gxtEl, element);
  2177.       attr = JXG.GeogebraReader.visualProperties(element, attr);
  2178.  
  2179.       try {
  2180.         JXG.debug("* <b>Tangent:</b> First: " + input[0].name + ", Sec.: "+ input[1].name +"("+ input[1].type +")<br>\n");
  2181.         switch(input[1].type) {
  2182.           case 1330923344: // graph
  2183.             input[0].makeGlider(input[1]);
  2184.             p = board.create('tangent', [input[0]], attr);
  2185.             return p;
  2186.           break;
  2187.           case 1330922316: // circle 0x4F54434C
  2188.           case 1330922319: // conic 0x4F54434F
  2189.             /*
  2190.             m = function(circ) {
  2191.                 return [[circ.midpoint.X()*circ.midpoint.X()+circ.midpoint.Y()*circ.midpoint.Y()-circ.Radius()*circ.Radius(),
  2192.                              -circ.midpoint.X(),-circ.midpoint.Y()],
  2193.                             [-circ.midpoint.X(),1,0],
  2194.                             [-circ.midpoint.Y(),0,1]
  2195.                            ];
  2196.                     };
  2197.  
  2198.                 t = board.create('line', [
  2199.                             function(){ return JXG.Math.matVecMult(m(input[1]), input[0].coords.usrCoords)[0]; },
  2200.                             function(){ return JXG.Math.matVecMult(m(input[1]), input[0].coords.usrCoords)[1]; },
  2201.                             function(){ return JXG.Math.matVecMult(m(input[1]), input[0].coords.usrCoords)[2]; }
  2202.                         ], {visible: false});
  2203.                      */
  2204.             // input[0]: point
  2205.             // input[1]: circle or conic
  2206.             var pol = board.create('polar',[input[1],input[0]],{visible:false});
  2207.                 var i1 = board.create('intersection', [input[1], pol, 0], {visible: false});
  2208.                 var i2 = board.create('intersection', [input[1], pol, 1], {visible: false});
  2209.                 var t1 = board.create('line', [input[0], i1], attr);
  2210.             var attr2 = {};
  2211.             attr2 = JXG.GeogebraReader.colorProperties(output[1], attr2);
  2212.             attr2 = JXG.GeogebraReader.visualProperties(output[1], attr2);
  2213.             attr2.name = output[1].getAttribute('label');
  2214.             var t2 = board.create('line', [input[0], i2], attr2);
  2215.             board.ggbElements[attr2.name] = t2;
  2216.             return [t1, t2];
  2217.           break;
  2218.         }
  2219.       } catch(e) {
  2220.         JXG.debug("* <b>Err:</b> Tangent " + attr.name +" "+ attr2.name + "<br>\n");
  2221.         return false;
  2222.       }
  2223.     break;
  2224.     case 'circumcirclearc':
  2225.       attr = JXG.GeogebraReader.boardProperties(gxtEl, element, attr);
  2226.       attr = JXG.GeogebraReader.colorProperties(element, attr);
  2227.       gxtEl = JXG.GeogebraReader.coordinates(gxtEl, element);
  2228.       attr = JXG.GeogebraReader.visualProperties(element, attr);
  2229.  
  2230.       try {
  2231.         JXG.debug("* <b>CircumcircleArc:</b> First: " + input[0].name + "<br>\n");
  2232.         p = board.create('circumcirclearc', input, attr);
  2233.         return p;
  2234.       } catch(e) {
  2235.         JXG.debug("* <b>Err:</b> CircumcircleArc " + attr.name +"<br>\n");
  2236.         return false;
  2237.       }
  2238.     break;
  2239.     case 'circumcirclesector':
  2240.       attr = JXG.GeogebraReader.boardProperties(gxtEl, element, attr);
  2241.       attr = JXG.GeogebraReader.colorProperties(element, attr);
  2242.       gxtEl = JXG.GeogebraReader.coordinates(gxtEl, element);
  2243.       attr = JXG.GeogebraReader.visualProperties(element, attr);
  2244.  
  2245.       try {
  2246.         JXG.debug("* <b>CircumcircleSector:</b> First: " + input[0].name + "<br>\n");
  2247.         p = board.create('circumcirclesector', [input[0], input[1], input[2]], attr); //{name:attr['name']});
  2248.         /*
  2249.         p.arc.setProperty(attr);
  2250.         p.lines[0].setProperty(attr);
  2251.         p.lines[1].setProperty(attr);
  2252.         p.arc.visProp.highlightstrokewidth = (1*p.arc.visProp.strokewidth.substr(0,p.arc.visProp.strokewidth.length-2)+1)+'px';
  2253.         p.lines[0].visProp.highlightstrokewidth = (1*p.lines[0].visProp.strokewidth.substr(0,p.lines[0].visProp.strokewidth.length-2)+1)+'px';
  2254.         p.lines[1].visProp.highlightstrokewidth = (1*p.lines[1].visProp.strokewidth.substr(0,p.lines[1].visProp.strokewidth.length-2)+1)+'px';
  2255.         p.arc.hasPoint = p.arc.hasPointSector;
  2256.         p.arc.highlight = (function(el){ return function() {
  2257.             this.board.renderer.highlight(this);
  2258.             this.board.renderer.highlight(el.lines[0]);
  2259.             this.board.renderer.highlight(el.lines[1]);
  2260.         };})(p);
  2261.         p.arc.noHighlight = (function(el){ return function() {
  2262.             this.board.renderer.noHighlight(this);
  2263.             this.board.renderer.noHighlight(el.lines[0]);
  2264.             this.board.renderer.noHighlight(el.lines[1]);
  2265.         };})(p);
  2266.         p.lines[0].highlight = (function(el){ return function() {
  2267.             this.board.renderer.highlight(this);
  2268.             this.board.renderer.highlight(el.arc);
  2269.             this.board.renderer.highlight(el.lines[1]);
  2270.         };})(p);
  2271.         p.lines[1].highlight = (function(el){ return function() {
  2272.             this.board.renderer.highlight(this);
  2273.             this.board.renderer.highlight(el.arc);
  2274.             this.board.renderer.highlight(el.lines[0]);
  2275.         };})(p);
  2276.         p.lines[0].noHighlight = (function(el){ return function() {
  2277.             this.board.renderer.noHighlight(this);
  2278.             this.board.renderer.noHighlight(el.arc);
  2279.             this.board.renderer.noHighlight(el.lines[1]);
  2280.         };})(p);
  2281.         p.lines[1].noHighlight = (function(el){ return function() {
  2282.             this.board.renderer.noHighlight(this);
  2283.             this.board.renderer.noHighlight(el.arc);
  2284.             this.board.renderer.noHighlight(el.lines[0]);
  2285.         };})(p);
  2286.         */
  2287.         return p;
  2288.       } catch(e) {
  2289.         JXG.debug("* <b>Err:</b> CircumcircleSector " + attr.name +"<br>\n");
  2290.         return false;
  2291.       }
  2292.     break;
  2293.     case 'semicircle':
  2294.       attr = JXG.GeogebraReader.boardProperties(gxtEl, element, attr);
  2295.       attr = JXG.GeogebraReader.colorProperties(element, attr);
  2296.       gxtEl = JXG.GeogebraReader.coordinates(gxtEl, element);
  2297.       attr = JXG.GeogebraReader.visualProperties(element, attr);
  2298.  
  2299.       try {
  2300.         JXG.debug("* <b>Semicircle:</b> First: " + input[0].name + "<br>\n");
  2301.         p = board.create('semicircle', [input[0], input[1]], attr);
  2302.         return p;
  2303.       } catch(e) {
  2304.         JXG.debug("* <b>Err:</b> Semicircle " + attr.name +"<br>\n");
  2305.         return false;
  2306.       }
  2307.     break;
  2308.     case 'angle':
  2309.       attr = JXG.GeogebraReader.boardProperties(gxtEl, element, attr);
  2310.       attr = JXG.GeogebraReader.colorProperties(element, attr);
  2311.       gxtEl = JXG.GeogebraReader.coordinates(gxtEl, element);
  2312.       attr = JXG.GeogebraReader.visualProperties(element, attr);
  2313.  
  2314.       try {
  2315.         JXG.debug("* <b>Angle:</b> First: " + input[0].name + "<br>\n");
  2316.         p = board.create('angle', input, attr);
  2317.         return p;
  2318.       } catch(e) {
  2319.         JXG.debug("* <b>Err:</b> Angle " + attr.name +"<br>\n");
  2320.         return false;
  2321.       }
  2322.     break;
  2323.     case 'angularbisector':
  2324.       attr = JXG.GeogebraReader.boardProperties(gxtEl, element, attr);
  2325.       attr = JXG.GeogebraReader.colorProperties(element, attr);
  2326.       gxtEl = JXG.GeogebraReader.coordinates(gxtEl, element);
  2327.       attr = JXG.GeogebraReader.visualProperties(element, attr);
  2328.       attr.straightFirst = true;
  2329.       attr.straightLast = true;
  2330.  
  2331.       try {
  2332.         JXG.debug("* <b>Angularbisector:</b> First: " + input[0].name + "<br>\n");
  2333.         p = board.create('bisector', input, attr);
  2334.         return p;
  2335.       } catch(e) {
  2336.         JXG.debug("* <b>Err:</b> Angularbisector " + attr.name +"<br>\n");
  2337.         return false;
  2338.       }
  2339.     break;
  2340.     case 'numeric':
  2341.     if(element.getElementsByTagName('slider').length == 0) {
  2342.       // auxiliary doesn't exist in every numeric
  2343.       //element.getElementsByTagName('auxiliary').length != 0 && element.getElementsByTagName('auxiliary')[0].attributes['val'].value == 'true') {
  2344.       exp = JXG.GeogebraReader.getElement(element.getAttribute('label'), true);
  2345.       if(exp) {
  2346.           exp = exp.getAttribute('exp');
  2347.           exp = JXG.GeogebraReader.functionParse('', exp);
  2348.           exp = JXG.GeogebraReader.ggbParse(exp);
  2349.       }
  2350.       board.ggb[attr.name] = new Function('return '+ exp +';');
  2351.       JXG.debug('value: '+ board.ggb[attr.name]());
  2352.       return board.ggb[attr.name];
  2353.         } else {
  2354.       attr = JXG.GeogebraReader.boardProperties(gxtEl, element, attr);
  2355.       attr = JXG.GeogebraReader.colorProperties(element, attr);
  2356.       // gxtEl = JXG.GeogebraReader.coordinates(gxtEl, element);
  2357.       attr = JXG.GeogebraReader.visualProperties(element, attr);
  2358.       if(element.getElementsByTagName('slider').length == 1) { // it's a slider
  2359.         sx = parseFloat(element.getElementsByTagName('slider')[0].getAttribute('x'));
  2360.         sy = parseFloat(element.getElementsByTagName('slider')[0].getAttribute('y'));
  2361.         length = parseFloat(element.getElementsByTagName('slider')[0].getAttribute('width'));
  2362.         // are coordinates absolut?
  2363.         if(element.getElementsByTagName('slider')[0].getAttribute('absoluteScreenLocation') && element.getElementsByTagName('slider')[0].getAttribute('absoluteScreenLocation') == 'true') {
  2364.           var tmp = new JXG.Coords(JXG.COORDS_BY_SCREEN, [sx, sy], board);
  2365.           sx = tmp.usrCoords[1];
  2366.           sy = tmp.usrCoords[2];
  2367.         }
  2368.  
  2369.         if(element.getElementsByTagName('slider')[0].getAttribute('horizontal') == 'true') {
  2370.           if(element.getElementsByTagName('slider')[0].getAttribute('absoluteScreenLocation') && element.getElementsByTagName('slider')[0].getAttribute('absoluteScreenLocation') == 'true')
  2371.           length /= (board.unitX); //*board.zoomX);
  2372.           ex = sx + length;
  2373.           ey = sy;
  2374.         } else {
  2375.           if(element.getElementsByTagName('slider')[0].getAttribute('absoluteScreenLocation') && element.getElementsByTagName('slider')[0].getAttribute('absoluteScreenLocation') == 'true')
  2376.           length /= (board.unitY); //*board.zoomY);
  2377.           ex = sx;
  2378.           ey = sy + length;
  2379.         }
  2380.  
  2381.         (element.getElementsByTagName('animation')[0]) ? attr.snapWidth = parseFloat(element.getElementsByTagName('animation')[0].getAttribute('step')) : false;
  2382.  
  2383.         try {
  2384.           JXG.debug("* <b>Numeric:</b> First: " + attr.name + "<br>\n");
  2385.           attr['withTicks'] = false;
  2386.           p = board.create('slider', [[sx,sy], [ex,ey], [parseFloat(element.getElementsByTagName('slider')[0].getAttribute('min')),
  2387.                                                          parseFloat(element.getElementsByTagName('value')[0].getAttribute('val')),
  2388.                                                          parseFloat(element.getElementsByTagName('slider')[0].getAttribute('max'))]], attr);
  2389.           p.setProperty({withLabel:false});
  2390.           return p;
  2391.         } catch(e) {
  2392.           JXG.debug("* <b>Err:</b> Numeric " + attr.name +"<br>\n");
  2393.           return false;
  2394.         }
  2395.       }
  2396.     }
  2397.     break;
  2398.     case 'midpoint':
  2399.       attr = JXG.GeogebraReader.boardProperties(gxtEl, element, attr);
  2400.       attr = JXG.GeogebraReader.colorProperties(element, attr);
  2401.       gxtEl = JXG.GeogebraReader.coordinates(gxtEl, element);
  2402.       attr = JXG.GeogebraReader.visualProperties(element, attr);
  2403.  
  2404.       try {
  2405.           if(!JXG.exists(attr.styleGGB)) {
  2406.              attr.face = 'circle';
  2407.              attr.fillColor = attr.strokeColor;
  2408.              attr.fillOpacity = 1;
  2409.              attr.highlightFillColor = attr.strokeColor;
  2410.              attr.highlightFillOpacity = 1;
  2411.              attr.strokeColor = 'black';
  2412.              attr.strokeWidth = '1px';
  2413.           }
  2414.           p = board.create('midpoint', input, attr);
  2415.           JXG.debug("* <b>Midpoint ("+ p.id +"):</b> "+ attr.name + "("+ gxtEl.x +", "+ gxtEl.y +")<br>\n");
  2416.           return p;
  2417.       } catch(e) {
  2418.           JXG.debug("* <b>Err:</b> Midpoint " + attr.name +"<br>\n");
  2419.           return false;
  2420.       }
  2421.     break;
  2422.     case 'center':
  2423.       attr = JXG.GeogebraReader.boardProperties(gxtEl, element, attr);
  2424.       attr = JXG.GeogebraReader.colorProperties(element, attr);
  2425.       gxtEl = JXG.GeogebraReader.coordinates(gxtEl, element);
  2426.       attr = JXG.GeogebraReader.visualProperties(element, attr);
  2427.       try {
  2428.           if(!JXG.exists(attr.styleGGB)) {
  2429.              attr.face = 'circle';
  2430.              attr.fillColor = attr.strokeColor;
  2431.              attr.fillOpacity = 1;
  2432.              attr.highlightFillColor = attr.strokeColor;
  2433.              attr.highlightFillOpacity = 1;
  2434.              attr.strokeColor = 'black';
  2435.              attr.strokeWidth = '1px';
  2436.           }
  2437.           p = board.create('point', [function() { return JXG.getReference(board, input[0].id).midpoint.X(); },
  2438.                                      function() { return JXG.getReference(board, input[0].id).midpoint.Y(); }], attr);
  2439.           JXG.debug("* <b>Center ("+ p.id +"):</b> "+ attr.name + "("+ gxtEl.x +", "+ gxtEl.y +")<br>\n");
  2440.           return p;
  2441.       } catch(e) {
  2442.           JXG.debug("* <b>Err:</b> Center " + attr.name +"<br>\n");
  2443.           return false;
  2444.       }
  2445.     break;
  2446.     case 'function':
  2447.       attr = JXG.GeogebraReader.boardProperties(gxtEl, element, attr);
  2448.       attr = JXG.GeogebraReader.colorProperties(element, attr);
  2449.       gxtEl = JXG.GeogebraReader.coordinates(gxtEl, element);
  2450.       attr = JXG.GeogebraReader.visualProperties(element, attr);
  2451.  
  2452.       if(JXG.GeogebraReader.getElement(attr.name, true)) {
  2453.         func = JXG.GeogebraReader.getElement(attr.name, true).getAttribute('exp');
  2454.         func = JXG.GeogebraReader.functionParse('c', func);
  2455.       } else {
  2456.         func = input[0];
  2457.         func = JXG.GeogebraReader.functionParse('s', func);
  2458.       }
  2459.  
  2460.       JXG.debug(func);
  2461.  
  2462.       length = func.length;
  2463.       func[func.length-1] = 'return '+ JXG.GeogebraReader.ggbParse(func[func.length-1]) +';';
  2464.  
  2465.       JXG.debug(func);
  2466.  
  2467.       range = [(input && input[1]) ? input[1] : null, (input && input[2]) ? input[2] : null];
  2468.  
  2469.       try {
  2470.         if(length == 1)
  2471.           p = board.create('functiongraph', [new Function(func[0]), range[0], range[1]], attr);
  2472.         else if(length==2)
  2473.           p = board.create('functiongraph', [new Function(func[0], func[1]), range[0], range[1]], attr);
  2474.         else if(length==3)
  2475.           p = board.create('functiongraph', [new Function(func[0], func[1], func[2]), range[0], range[1]], attr);
  2476.         else if(length==4)
  2477.           p = board.create('functiongraph', [new Function(func[0], func[1], func[2], func[3]), range[0], range[1]], attr);
  2478.         else if(length==5)
  2479.           p = board.create('functiongraph', [new Function(func[0], func[1], func[2], func[3], func[4]), range[0], range[1]], attr);
  2480.         return p;
  2481.       } catch(e) {
  2482.         JXG.debug("* <b>Err:</b> Functiongraph " + attr.name +"<br>\n");
  2483.         return false;
  2484.       }
  2485.  
  2486.      break;
  2487.      case 'polar':
  2488.       attr = JXG.GeogebraReader.boardProperties(gxtEl, element, attr);
  2489.       attr = JXG.GeogebraReader.colorProperties(element, attr);
  2490.       gxtEl = JXG.GeogebraReader.coordinates(gxtEl, element);
  2491.       attr = JXG.GeogebraReader.visualProperties(element, attr);
  2492.  
  2493.       try {
  2494.         JXG.debug("* <b>Polar:</b> First: " + input[0].name + ", Sec.: "+ input[1].name +"<br>\n");
  2495.         p = board.create('polar', input, attr);
  2496.         return p;
  2497.       } catch(e) {
  2498.         JXG.debug("* <b>Err:</b> Polar " + attr.name +"<br>\n");
  2499.         return false;
  2500.       }
  2501.     break;
  2502.     case 'slope':
  2503.      attr = JXG.GeogebraReader.boardProperties(gxtEl, element, attr);
  2504.      attr = JXG.GeogebraReader.colorProperties(element, attr);
  2505.      gxtEl = JXG.GeogebraReader.coordinates(gxtEl, element);
  2506.      attr = JXG.GeogebraReader.visualProperties(element, attr);
  2507.  
  2508.      try {
  2509.        JXG.debug("* <b>Slope ("+ attr.name +"):</b> First: " + input[0].name +"<br>\n");
  2510.        var slopeWidth = parseInt(attr.slopeWidth) || 1.0;
  2511.        var p1 = input[0].glider || input[0].point1;
  2512.        var p2 = board.create('point',[function(){return (slopeWidth+p1.X());}, function(){return p1.Y();}], {visible: false});
  2513.        var l1 = board.create('segment', [p1, p2], {visible: false}); // visible: attr.visible
  2514.        var l2 = board.create('normal', [l1, l1.point2], {visible: false}); // visible attr.visible
  2515.        var i  = board.create('intersection', [input[0], l2, 0], {visible: false});
  2516.        var m  = board.create('midpoint', [l1.point2, i], {visible: false});
  2517.  
  2518.        var t = board.create('text', [function(){return m.X();}, function(){return m.Y();},
  2519.                       function(){ return "&nbsp;&nbsp;" + (slopeWidth > 1 ? slopeWidth.toString() : "") + " " + this.name + " = " + JXG.trimNumber((slopeWidth * input[0].getSlope()).toFixed(JXG.GeogebraReader.decimals)); }], attr);
  2520.        attr.name = "";
  2521.        var t2 = board.create('text', [function(){return (p1.X() + p2.X())/2.;}, function(){return p1.Y();},
  2522.                                      function(){ return "<br/>" + slopeWidth; }], attr);
  2523.        t.Value = (function() { return function(){ return input[0].getSlope(); }; })();
  2524.        var poly = board.create('polygon',[p1,p2,i], attr);
  2525.  
  2526.        poly.borders[2].setProperty({visible: false});
  2527.        poly.borders[0].setProperty({strokeColor: attr.fillColor, strokeWidth: attr.strokeWidth, highlightStrokeColor: attr.fillColor, dash:attr.dash});
  2528.        poly.borders[1].setProperty({strokeColor: attr.fillColor, strokeWidth: attr.strokeWidth, highlightStrokeColor: attr.fillColor, dash:attr.dash});      
  2529.        return t;
  2530.      } catch(e) {
  2531.        JXG.debug("* <b>Err:</b> Slope " + attr.name +"<br>\n");
  2532.        return false;
  2533.      }
  2534.     break;
  2535.     case 'text':
  2536.      attr = JXG.GeogebraReader.boardProperties(gxtEl, element, attr);
  2537.      attr = JXG.GeogebraReader.colorProperties(element, attr);
  2538.      gxtEl = JXG.GeogebraReader.coordinates(gxtEl, element);
  2539.      attr = JXG.GeogebraReader.visualProperties(element, attr);
  2540.      var rx, res = '';
  2541.  
  2542.      try {
  2543.        if(element.getElementsByTagName('isLaTeX')[0] && element.getElementsByTagName('isLaTeX')[0].getAttribute('val') == 'true') {
  2544.          JXG.GeogebraReader.board.options.text.useASCIIMathML = true;
  2545.          t = JXG.GeogebraReader.getElement(attr.name, true).getAttribute('exp');
  2546.  
  2547.          // here we're searching for patterns like
  2548.          //    " + ... + "
  2549.          // ... will be sent to the ggbParser and a calculated text element is built from this.
  2550.          while(rx = t.match(/(.*?)" \+ (.+) \+ "(.*)/)) {
  2551.              var re2 = JXG.GeogebraReader.ggbParse(RegExp.$2);
  2552.              if (typeof re2 == 'string') {
  2553.                res = res + RegExp.$1 + re2;
  2554.              } else {
  2555.                res = res + RegExp.$1 + '" + JXG.trimNumber((' + re2 + ').toFixed(JXG.GeogebraReader.decimals)) + "';
  2556.              }
  2557.              t = RegExp.$3;
  2558.          }
  2559.          // we have to look, if the string's ending with a string-part or a formula part:
  2560.          if(rx = t.match(/(.*?)" \+ (.+)/)) {
  2561.              res = res + RegExp.$1 + '" + JXG.trimNumber((' + JXG.GeogebraReader.ggbParse(RegExp.$2) + ').toFixed(JXG.GeogebraReader.decimals))';
  2562.          } else
  2563.              res = res + t;
  2564.  
  2565.          JXG.debug("Text: "+res);
  2566.  
  2567.          p = board.create('text', [gxtEl.x, gxtEl.y, new Function('return ' + res + ';')], attr);
  2568.        } else {
  2569.          JXG.debug(JXG.GeogebraReader.getElement(attr.name, true).getAttribute('exp'));
  2570.          t = JXG.GeogebraReader.ggbParse(JXG.GeogebraReader.functionParse(false, JXG.GeogebraReader.getElement(attr.name, true).getAttribute('exp')));
  2571.          JXG.debug(t[1]);
  2572.          p = board.create('text', [gxtEl.x, gxtEl.y, new Function('return '+t[0]+' + " " + JXG.trimNumber(parseFloat(' + t[1] +').toFixed(JXG.GeogebraReader.decimals));') ], attr);
  2573.        }
  2574.        JXG.debug("* <b>Text:</b> " + t  +"<br>\n");
  2575.        return p;
  2576.      } catch(e) {
  2577.       JXG.debug("* <b>Err:</b> Text: " + t +"<br>\n");
  2578.       return false;
  2579.      }
  2580.     break;
  2581.     case 'root':
  2582.         attr = JXG.GeogebraReader.boardProperties(gxtEl, element, attr);
  2583.         attr = JXG.GeogebraReader.colorProperties(element, attr);
  2584.         gxtEl = JXG.GeogebraReader.coordinates(gxtEl, element);
  2585.         attr = JXG.GeogebraReader.visualProperties(element, attr);
  2586.         //JXG.debug(JXG.getReference(board, gxtEl.id));
  2587.  
  2588.         for(var i=0; i<output.length; i++) {
  2589.           output[i] = JXG.GeogebraReader.checkElement(output[i].getAttribute('label'));
  2590.         }
  2591.        
  2592.         var inp;
  2593.         if(JXG.isArray(input)) {
  2594.             inp = input[0];
  2595.         } else {
  2596.             inp = input;
  2597.         }
  2598.  
  2599.         // At this point, the output points already exist.
  2600.         // Bind the root function to all output elements.
  2601.         // The start values for all output elements are the x-coordinates as given
  2602.         // in the ggb file.
  2603.         for(i=0; i<output.length; i++) {
  2604.             output[i].addConstraint([
  2605.                     (function(x){ return function(){ return board.root(inp.Y,x,inp);}; })(output[i].X()),
  2606.                     function(){ return 0;}
  2607.                 ]);
  2608.         }
  2609.         //var p = board.create('point', [function(){ return board.root(output);}, function(){ return 1;}], attr);
  2610.         return output; // What to return here????
  2611.     break;
  2612.   case 'integral':
  2613.       attr = JXG.GeogebraReader.boardProperties(gxtEl, element, attr);
  2614.       attr = JXG.GeogebraReader.colorProperties(element, attr);
  2615.       gxtEl = JXG.GeogebraReader.coordinates(gxtEl, element);
  2616.       attr = JXG.GeogebraReader.visualProperties(element, attr);
  2617.  
  2618.       try {
  2619.         JXG.debug("* <b>Integral:</b> First: " + input[0].name + ", Sec.: "+ input[1].name +", Thir.: "+ input[2].name +"<br>\n");
  2620.         JXG.debug([input[1](), input[2]()]);
  2621.         var p = board.create('integral', [JXG.getRef(board, input[0]), [input[1], input[2]]], attr);
  2622.         return p;
  2623.       } catch(e) {
  2624.         JXG.debug("* <b>Err:</b> Integral " + attr.name + e + "<br>\n");
  2625.         return false;
  2626.       }
  2627.     break;
  2628.  
  2629. // case 'transform':
  2630. // break;
  2631. //    case 'radius':
  2632. //    break;
  2633. //    case 'derivative':
  2634. //    break;
  2635. //    case 'root':
  2636. //    break;
  2637. //    case 'corner':
  2638. //    break;
  2639. //    case 'unitvector':
  2640. //    break;
  2641. //    case 'extremum':
  2642. //    break;
  2643. //    case 'turningpoint':
  2644. //    break;
  2645. //    case 'arc':
  2646. //    break;
  2647. //    case 'circlepart':
  2648. //    break;
  2649. //    case 'uppersum':
  2650. //    break;
  2651. //    case 'lowersum':
  2652. //    break;
  2653. //    case 'image':
  2654. //    break;
  2655.     default:
  2656.       return false;
  2657.     break;
  2658.   }
  2659. };
  2660.  
  2661. /**
  2662.  * Reading the elements of a geogebra file
  2663.  * @param {Object} board board object
  2664.  */
  2665. this.readGeogebra = function(tree, board) {
  2666.   var el, Data, i, els = [], expr;
  2667.  
  2668.   board.ggbElements = [];
  2669.   board.ggb = {};
  2670.   JXG.GeogebraReader.tree = tree;
  2671.   JXG.GeogebraReader.board = board;
  2672.   JXG.GeogebraReader.format = parseFloat(JXG.GeogebraReader.tree.getElementsByTagName('geogebra')[0].getAttribute('format'));
  2673.   JXG.GeogebraReader.decimals = parseInt(JXG.GeogebraReader.tree.getElementsByTagName('geogebra')[0].getElementsByTagName('kernel')[0].getElementsByTagName('decimals')[0].getAttribute('val'));
  2674.   JXG.GeogebraReader.writeBoard(board);
  2675.   board = JXG.GeogebraReader.setDefaultOptions(board);
  2676.  
  2677.   // speeding up the drawing process
  2678.   //board.suspendUpdate();
  2679.  
  2680.   var constructions = JXG.GeogebraReader.tree.getElementsByTagName("construction");
  2681.   for (var t=0; t<constructions.length; t++) {
  2682.  
  2683.     var cmds = constructions[t].getElementsByTagName("command");
  2684.     for (var s=0; s<cmds.length; s++) {
  2685.       Data = cmds[s];
  2686.  
  2687.       // JXG.debug('now i\'ll parse the command:');
  2688.       // JXG.debug(Data);
  2689.  
  2690.       var input = [];
  2691.       for (i=0; i<Data.getElementsByTagName("input")[0].attributes.length; i++) {
  2692.         el = Data.getElementsByTagName("input")[0].attributes[i].value;
  2693.         if(el.match(/\u00B0/) || !el.match(/\D/) || el.match(/Circle/) || Data.getAttribute('name') == 'Function' || el == parseFloat(el) ) {
  2694.           input[i] = el;
  2695.         // } else if(el.match(/[a-zA-Z]+\[[a-zA-Z0-9]+[a-zA-Z0-9,\ ]*\]/)) {
  2696.         //   input[i] = JXG.GeogebraReader.writeElement(board, )
  2697.         } else if(el == 'xAxis' || el == 'yAxis') {
  2698.           input[i] = board.ggbElements[el];
  2699.         } else {
  2700.           input[i] = JXG.GeogebraReader.checkElement(el);
  2701.         }
  2702.       };
  2703.  
  2704.       var output = [], elname = Data.getElementsByTagName("output")[0].attributes[0].value;
  2705.       for (i=0; i<Data.getElementsByTagName("output")[0].attributes.length; i++) {
  2706.         el = Data.getElementsByTagName("output")[0].attributes[i].value;
  2707.         output[i] = JXG.GeogebraReader.getElement(el);
  2708.       };
  2709.       if(typeof board.ggbElements[elname] == 'undefined' || board.ggbElements[elname] == '') {
  2710.         board.ggbElements[elname] = JXG.GeogebraReader.writeElement(board, output, input, Data.getAttribute('name').toLowerCase());
  2711.         // JXG.debug("regged: "+board.ggbElements[elname].id+"<br/>");
  2712.  
  2713.         /* register borders to according "parent" */
  2714.         if(board.ggbElements[elname].borders)
  2715.           for(var i=0; i<board.ggbElements[elname].borders.length; i++) {
  2716.             board.ggbElements[board.ggbElements[elname].borders[i].name] = board.ggbElements[elname].borders[i];
  2717.             // JXG.debug(i+") regged: "+board.ggbElements[elname].borders[i].name+"("+ board.ggbElements[board.ggbElements[elname].borders[i].name].id +")<br/>");
  2718.           };
  2719.       }
  2720.     };
  2721.  
  2722.     JXG.debug('Restesammler: ');
  2723.     // create "single" elements which do not depend on any other
  2724.     var elements = constructions[t].getElementsByTagName("element");
  2725.     for (var s=0; s<elements.length; s++) {
  2726.       var Data = elements[s];
  2727.       var el = Data.getAttribute('label');
  2728.  
  2729.       if(typeof board.ggbElements[el] == 'undefined' || board.ggbElements[el] == '') {
  2730.         board.ggbElements[el] = JXG.GeogebraReader.writeElement(board, Data);
  2731.  
  2732.         if(expr = JXG.GeogebraReader.getElement(el, true)) {
  2733.           var type = Data.getAttribute('type');
  2734.           switch(type) {
  2735.             case 'text':
  2736.             case 'function':
  2737.               // board.ggbElements[el] = JXG.GeogebraReader.writeElement(board.ggbElements, board, expr, false, type);
  2738.             break;
  2739.             default:
  2740.               JXG.GeogebraReader.ggbParse(expr.getAttribute('exp'), el);
  2741.             break;
  2742.           }
  2743.         }
  2744.  
  2745.       }
  2746.     };
  2747.  
  2748.   }; // end: for construction
  2749.  
  2750.   // speeding up the drawing process
  2751.   board.unsuspendUpdate();
  2752.  
  2753.   board.fullUpdate();
  2754.  // delete(board.ggbElements);
  2755. };
  2756.  
  2757. /**
  2758.  * Clean the utf8-symbols in a Geogebra expression in JavaScript syntax
  2759.  * @param {String} string to clean
  2760.  * @return {String} replaced string
  2761.  */
  2762. this.utf8replace = function(exp) {
  2763.   exp = (exp.match(/\u03C0/)) ? exp.replace(/\u03C0/g, 'PI') : exp;
  2764.   exp = (exp.match(/\u00B2/)) ? exp.replace(/\u00B2/g, '^2') : exp;
  2765.   exp = (exp.match(/\u00B3/)) ? exp.replace(/\u00B3/g, '^3') : exp;
  2766.   exp = (exp.match(/\u225F/)) ? exp.replace(/\u225F/g, '==') : exp;
  2767.   exp = (exp.match(/\u2260/)) ? exp.replace(/\u2260/g, '!=') : exp;
  2768.   exp = (exp.match(/\u2264/)) ? exp.replace(/\u2264/g, '<=') : exp;
  2769.   exp = (exp.match(/\u2265/)) ? exp.replace(/\u2265/g, '>=') : exp;
  2770.   exp = (exp.match(/\u2227/)) ? exp.replace(/\u2227/g, '&&') : exp;
  2771.   exp = (exp.match(/\u2228/)) ? exp.replace(/\u2228/g, '//') : exp;
  2772.   return exp;
  2773. };
  2774.  
  2775. /**
  2776.  * Extracting the packed geogebra file in order to return the "blank" xml-tree for further parsing.
  2777.  * @param {String} archive containing geogebra.xml-file or raw input string (eg. xml-tree)
  2778.  * @return {String} content of geogebra.xml-file if archive was passed in
  2779.  */
  2780. this.prepareString = function(fileStr, isString) {
  2781.     var i, bA, len, fstr;
  2782.  
  2783.     // here we have to deal with two different base64 encoded streams
  2784.     // first one: base64 encoded xml (geogebra's web export)
  2785.     // second one: base64 encoded ggb file, this is our recommendation for an IE & Opera
  2786.     // workaround, which can't deal with binary data transferred via AJAX.
  2787.  
  2788.     // first try to decode assuming we got a base64 encoded ggb file
  2789.     if(isString) {
  2790.         fstr = JXG.Util.Base64.decode(fileStr);
  2791.         if(fstr.slice(0,2)!=="PK") {
  2792.             // ooops, that was no ggb file. try again with utf8 parameter set.
  2793.             fstr = JXG.Util.Base64.decode(fileStr, true);
  2794.         }
  2795.         fileStr = fstr;
  2796.     }
  2797.  
  2798.     if (fileStr.indexOf('<') != 0) {
  2799.         bA = [];
  2800.         len = fileStr.length;
  2801.         for (i=0;i<len;i++)
  2802.             bA[i]=JXG.Util.asciiCharCodeAt(fileStr,i);
  2803.         // Unzip
  2804.         fileStr = (new JXG.Util.Unzip(bA)).unzipFile("geogebra.xml");
  2805.     }
  2806.     fileStr = JXG.Util.utf8Decode(fileStr);
  2807.     fileStr = JXG.GeogebraReader.utf8replace(fileStr);
  2808.     return fileStr;
  2809. };
  2810.  
  2811. /**
  2812.  * Checking if a parameter is a Geogebra vector (array with length 3)
  2813.  * @param {Object} possible Geogebra vector
  2814.  * @return {boolean}
  2815.  */
  2816. this.isGGBVector = function(v){
  2817.         return JXG.isArray(v) && v.length == 3 && v[0] == 1;   
  2818. };
  2819. }; // end: GeogebraReader()
  2820.