Index: TXM/trunk/org.txm.conllu.core/build.properties
===================================================================
--- TXM/trunk/org.txm.conllu.core/build.properties	(revision 0)
+++ TXM/trunk/org.txm.conllu.core/build.properties	(revision 3567)
@@ -0,0 +1,9 @@
+source.. = src/
+output.. = bin/
+bin.includes = META-INF/,\
+               .,\
+               groovy/,\
+               plugin.xml,\
+               icons/,\
+               template/
+#qualifier=svn

Property changes on: TXM/trunk/org.txm.conllu.core/build.properties
___________________________________________________________________
Added: svn:mime-type
   + text/plain

Index: TXM/trunk/org.txm.conllu.core/icons/functions/UD.png
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: TXM/trunk/org.txm.conllu.core/icons/functions/UD.png
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: TXM/trunk/org.txm.conllu.core/icons/functions/UDplus.png
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: TXM/trunk/org.txm.conllu.core/icons/functions/UDplus.png
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: TXM/trunk/org.txm.conllu.core/template/lib/brat/url_monitor.js
===================================================================
--- TXM/trunk/org.txm.conllu.core/template/lib/brat/url_monitor.js	(revision 0)
+++ TXM/trunk/org.txm.conllu.core/template/lib/brat/url_monitor.js	(revision 3567)
@@ -0,0 +1,233 @@
+// -*- Mode: JavaScript; tab-width: 2; indent-tabs-mode: nil; -*-
+// vim:set ft=javascript ts=2 sw=2 sts=2 cindent:
+var URLMonitor = (function($, window, undefined) {
+    var URLMonitor = function(dispatcher) {
+      var that = this;
+
+      var reloadData = true;
+      var changed = false;
+      var newIntArgs = {};
+
+      that.url_hash = new URLHash();
+
+      // Thanks to:
+      // http://kilianvalkhof.com/2010/javascript/the-case-of-the-disappearing-favicon/
+      var setFavicon = function() {
+        var link = $('link[type="image/x-icon"]').remove().attr("href");
+        $('<link href="'+ link +'" rel="shortcut icon" type="image/x-icon" />').appendTo('head');
+      }
+
+      var updateURL = function() {
+        var new_hash = that.url_hash.getHash();
+        changed = false;
+        window.location.hash = new_hash;
+        setFavicon();
+        dispatcher.post('hideForm');
+      };
+
+      var setArguments = function(args, force) {
+        var oldArgs = that.url_hash.arguments;
+        var argSplit = URLHash.splitArgs(args);
+
+        if (!Util.isEqual(that.url_hash.extArguments, argSplit[1])) {
+          changed = true;
+          that.url_hash.setArguments(args);
+          dispatcher.post('argsChanged', [args, oldArgs]);
+        }
+        if (changed) {
+          // hashchange event will trigger
+          newIntArgs = argSplit[0];
+          updateURL();
+        } else if (force || !Util.isEqual(that.url_hash.intArguments, argSplit[0])) {
+          // hash is same, but internal arguments differ
+          that.url_hash.setArguments(args);
+          // hashchange event won't trigger, but internal args have
+          // changed, so we have to do updateState's job
+          dispatcher.post('hideForm');
+          dispatcher.post('argsChanged', [args, oldArgs]);
+          dispatcher.post('current', [that.url_hash.collection,
+              that.url_hash.document, that.url_hash.arguments, reloadData]);
+          reloadData = true;
+        }
+      };
+
+      var setDocument = function(doc, args) {
+        var oldDoc = that.url_hash.document;
+        if (oldDoc !== doc) {
+          changed = true;
+          that.url_hash.setDocument(doc);
+          dispatcher.post('docChanged', [doc, oldDoc]);
+        }
+        setArguments(args || null);
+      };
+
+      var setCollection = function(coll, doc, args) {
+        var oldColl = that.url_hash.collection;
+        if (oldColl !== coll) {
+          changed = true;
+          that.url_hash.setCollection(coll);
+
+          // keep "blind" down while loading new collection
+          $('#waiter').dialog('open');
+
+          dispatcher.post('ajax', [{
+              action: 'getCollectionInformation',
+              collection: coll
+            }, 'collectionLoaded', {
+              collection: coll,
+              keep: true
+            }]);
+          dispatcher.post('collectionChanged', [coll, oldColl]);
+        }
+        setDocument(doc || '', args);
+      }
+
+      var updateState = function() {
+        dispatcher.post('makeAjaxObsolete');
+        if (!changed) {
+          var new_url_hash = URLHash.parse(window.location.hash);
+          setCollection(new_url_hash.collection, new_url_hash.document,
+              $.extend(new_url_hash.arguments, newIntArgs));
+          that.url_hash = new_url_hash;
+          newIntArgs = {};
+        }
+       
+        dispatcher.post('current', [that.url_hash.collection,
+            that.url_hash.document, that.url_hash.arguments, reloadData]);
+        reloadData = true;
+      };
+
+      var forceUpdate = function() {
+        $(window).trigger('hashchange');
+      };
+
+      var preventReloadByURL = function() {
+        reloadData = false;
+      }
+      var allowReloadByURL = function() {
+        reloadData = true;
+      }
+
+      var init = function() {
+        $(window).bind('hashchange', updateState);
+        forceUpdate();
+      }
+
+      dispatcher.
+          on('forceUpdate', forceUpdate).
+          on('setArguments', setArguments).
+          on('setDocument', setDocument).
+          on('setCollection', setCollection).
+          on('preventReloadByURL', preventReloadByURL).
+          on('allowReloadByURL', allowReloadByURL).
+          on('init', init);
+    };
+
+    return URLMonitor;
+})(jQuery, window);
+
+var URLHash = (function($, window, undefined) {
+    var URLHash = function(collection, _document, _arguments) {
+      var that = this;
+      that.collection = collection;
+      that.document = _document || '';
+      that.arguments = _arguments || {};
+      that.calcArgs();
+    }
+
+    URLHash.prototype = {
+      calcArgs: function() {
+        var args = URLHash.splitArgs(this.arguments);
+        this.intArguments = args[0];
+        this.extArguments = args[1];
+      },
+
+      setArgument: function(argument, value) {
+        if (!this.arguments) {
+          this.arguments = {};
+        }
+        this.arguments[argument] = value;
+        this.calcArgs();
+        return this;
+      },
+
+      setArguments: function(_arguments) {
+        // the $.extend here basically takes a copy; raw assignment
+        // would allow changes of the args to alter original, which
+        // could be e.g. the "args" of search results
+        this.arguments = $.extend({}, _arguments || {});
+        this.calcArgs();
+        return this;
+      },
+
+      setDocument: function(_document) {
+        this.document = _document;
+        return this;
+      },
+
+      setCollection: function(collection) {
+        this.collection = collection;
+        return this;
+      },
+
+      getHash: function() {
+        var url_hash = this.collection + this.document;
+
+        var url_args = Util.param(this.extArguments);
+
+        if (url_args.length) {
+          url_hash += '?' + url_args;
+        }
+
+        if (url_hash.length) {
+          url_hash = '#' + url_hash;
+        }
+
+        return url_hash;
+      },
+    };
+
+    // arguments that do not appear in the URL
+    var INT_ARGS = ['match', 'matchfocus', 'edited'];
+
+    URLHash.splitArgs = function(args) {
+      var intArgs = {};
+      var extArgs = $.extend({}, args);
+      var intArgNameLen = INT_ARGS.length;
+      for (var i = 0; i < intArgNameLen; i++) {
+        intArgs[INT_ARGS[i]] = extArgs[INT_ARGS[i]];
+        delete extArgs[INT_ARGS[i]];
+      }
+      return [intArgs, extArgs];
+    };
+
+    // TODO: Document and conform variables to the rest of the object
+    URLHash.parse = function(hash) {
+      if (hash.length) {
+        // Remove the leading hash (#)
+        hash = hash.substr(1);
+      }
+
+      var pathAndArgs = hash.split('?');
+      var path = pathAndArgs[0] || '';
+      var argsStr = pathAndArgs[1] || '';
+      var coll;
+      var slashPos = path.lastIndexOf('/');
+      if (slashPos === -1) {
+        coll = '/';
+      } else {
+        coll = path.substr(0, slashPos + 1);
+        if (coll[coll.length - 1] !== '/') {
+          coll += '/';
+        }
+        if (coll[0] !== '/') {
+          coll = '/' + coll;
+        }
+      }
+      var doc = path.substr(slashPos + 1);
+      var args = Util.deparam(argsStr);
+      return new URLHash(coll, doc, args);
+    };
+
+    return URLHash;
+})(jQuery, window)

Property changes on: TXM/trunk/org.txm.conllu.core/template/lib/brat/url_monitor.js
___________________________________________________________________
Added: svn:mime-type
   + text/plain

Index: TXM/trunk/org.txm.conllu.core/template/lib/brat/annotation_log.js
===================================================================
--- TXM/trunk/org.txm.conllu.core/template/lib/brat/annotation_log.js	(revision 0)
+++ TXM/trunk/org.txm.conllu.core/template/lib/brat/annotation_log.js	(revision 3567)
@@ -0,0 +1,42 @@
+// -*- Mode: JavaScript; tab-width: 2; indent-tabs-mode: nil; -*-
+// vim:set ft=javascript ts=2 sw=2 sts=2 cindent:
+
+var AnnotationLog = (function(window, undefined) {
+    var AnnotationLog = function(dispatcher) {
+      var annotationLoggingOn = false;
+      var currentCollection = null;
+      var currentDocument = null;
+      var currentArguments = null;
+
+      var rememberLoggingState = function(response) {
+        annotationLoggingOn = response.annotation_logging;
+      };
+
+      var rememberCurrent = function(_collection, _document, _arguments) {
+        currentCollection = _collection;
+        currentDocument = _document;
+        currentArguments = _arguments;
+      };
+
+      var logAction = function(_action) {
+        if (!annotationLoggingOn) {
+          // logging not requested for current collection
+          return false;
+        } else {
+          dispatcher.post('ajax', [ {
+            action: 'logAnnotatorAction',
+            collection: currentCollection,
+            'document': currentDocument,
+            log: _action,
+          }, null]);
+        }
+      }
+
+      dispatcher.
+          on('collectionLoaded', rememberLoggingState).
+          on('current', rememberCurrent).
+          on('logAction', logAction);
+    }
+
+    return AnnotationLog;
+})(window);

Property changes on: TXM/trunk/org.txm.conllu.core/template/lib/brat/annotation_log.js
___________________________________________________________________
Added: svn:mime-type
   + text/plain

Index: TXM/trunk/org.txm.conllu.core/template/lib/brat/util.js
===================================================================
--- TXM/trunk/org.txm.conllu.core/template/lib/brat/util.js	(revision 0)
+++ TXM/trunk/org.txm.conllu.core/template/lib/brat/util.js	(revision 3567)
@@ -0,0 +1,699 @@
+// -*- Mode: JavaScript; tab-width: 2; indent-tabs-mode: nil; -*-
+// vim:set ft=javascript ts=2 sw=2 sts=2 cindent:
+var Util = (function(window, undefined) {
+
+    var fontLoadTimeout = 5000; // 5 seconds
+
+    var monthNames = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'];
+
+    var isMac = navigator.platform == 'MacIntel'; // XXX should we go broader?
+
+    var cmp = function(a,b) {
+      return a < b ? -1 : a > b ? 1 : 0;
+    }
+
+    var cmpArrayOnFirstElement = function(a,b) {
+      a = a[0];
+      b = b[0];
+      return a < b ? -1 : a > b ? 1 : 0;
+    }
+
+    var unitAgo = function(n, unit) {
+      if (n == 1) return "" + n + " " + unit + " ago";
+      return "" + n + " " + unit + "s ago";
+    };
+
+    var formatTimeAgo = function(time) {
+      if (time == -1000) {
+        return "never"; // FIXME make the server return the server time!
+      }
+
+      var nowDate = new Date();
+      var now = nowDate.getTime();
+      var diff = Math.floor((now - time) / 1000);
+      if (!diff) return "just now";
+      if (diff < 60) return unitAgo(diff, "second");
+      diff = Math.floor(diff / 60);
+      if (diff < 60) return unitAgo(diff, "minute");
+      diff = Math.floor(diff / 60);
+      if (diff < 24) return unitAgo(diff, "hour");
+      diff = Math.floor(diff / 24);
+      if (diff < 7) return unitAgo(diff, "day");
+      if (diff < 28) return unitAgo(Math.floor(diff / 7), "week");
+      var thenDate = new Date(time);
+      var result = thenDate.getDate() + ' ' + monthNames[thenDate.getMonth()];
+      if (thenDate.getYear() != nowDate.getYear()) {
+        result += ' ' + thenDate.getFullYear();
+      }
+      return result;
+    }
+
+    var realBBox = function(span) {
+      var box = span.rect.getBBox();
+      var chunkTranslation = span.chunk.translation;
+      var rowTranslation = span.chunk.row.translation;
+      box.x += chunkTranslation.x + rowTranslation.x;
+      box.y += chunkTranslation.y + rowTranslation.y;
+      return box;
+    }
+
+    var escapeHTML = function(str) {
+      return str.replace(/&/g,'&amp;').replace(/</g,'&lt;').replace(/>/g,'&gt;');
+    }
+
+    var escapeHTMLandQuotes = function(str) {
+      return str.replace(/&/g,'&amp;').replace(/</g,'&lt;').replace(/>/g,'&gt;').replace(/\"/g,'&quot;');
+    }
+
+    var escapeHTMLwithNewlines = function(str) {
+      return str.replace(/&/g,'&amp;').replace(/</g,'&lt;').replace(/>/g,'&gt;').replace(/\n/g,'<br/>');
+    }
+
+    var escapeQuotes = function(str) {
+      // we only use double quotes for HTML attributes
+      return str.replace(/\"/g,'&quot;');
+    }
+
+    var getSpanLabels = function(spanTypes, spanType) {
+      var type = spanTypes[spanType];
+      return type && type.labels || [];
+    }
+
+    var spanDisplayForm = function(spanTypes, spanType) {
+      var labels = getSpanLabels(spanTypes, spanType);
+      return labels[0] || spanType;
+    }
+
+    var getArcLabels = function(spanTypes, spanType, arcType, relationTypesHash) {
+      var type = spanTypes[spanType];
+      var arcTypes = type && type.arcs || [];
+      var arcDesc = null;
+      // also consider matches without suffix number, if any
+      var noNumArcType;
+      if (arcType) {
+          var splitType = arcType.match(/^(.*?)(\d*)$/);
+          noNumArcType = splitType[1];
+      }
+      $.each(arcTypes, function(arcno, arcDescI) {
+        if (arcDescI.type == arcType || arcDescI.type == noNumArcType) {
+          arcDesc = arcDescI;
+          return false;
+        }
+      });
+      // fall back to relation types for unconfigured or missing def
+      if (!arcDesc) {
+        arcDesc = $.extend({}, relationTypesHash[arcType] || relationTypesHash[noNumArcType]);
+      }
+      return arcDesc && arcDesc.labels || [];
+    }
+
+    var arcDisplayForm = function(spanTypes, spanType, arcType, relationTypesHash) {
+      var labels = getArcLabels(spanTypes, spanType, arcType, relationTypesHash);
+      return labels[0] || arcType;
+    }
+
+    // TODO: switching to use of $.param(), this function should
+    // be deprecated and removed.
+    var objectToUrlStr = function(o) {
+      a = [];
+      $.each(o, function(key,value) {
+        a.push(key+"="+encodeURIComponent(value));
+      });
+      return a.join("&");
+    }
+
+    // color name RGB list, converted from
+    // http://www.w3schools.com/html/html_colornames.asp
+    // with perl as
+    //     perl -e 'print "var colors = {\n"; while(<>) { /(\S+)\s+\#([0-9a-z]{2})([0-9a-z]{2})([0-9a-z]{2})\s*/i or die "Failed to parse $_"; ($r,$g,$b)=(hex($2),hex($3),hex($4)); print "    '\''",lc($1),"'\'':\[$r,$g,$b\],\n" } print "};\n" '
+    var colors = {
+        'aliceblue':[240,248,255],
+        'antiquewhite':[250,235,215],
+        'aqua':[0,255,255],
+        'aquamarine':[127,255,212],
+        'azure':[240,255,255],
+        'beige':[245,245,220],
+        'bisque':[255,228,196],
+        'black':[0,0,0],
+        'blanchedalmond':[255,235,205],
+        'blue':[0,0,255],
+        'blueviolet':[138,43,226],
+        'brown':[165,42,42],
+        'burlywood':[222,184,135],
+        'cadetblue':[95,158,160],
+        'chartreuse':[127,255,0],
+        'chocolate':[210,105,30],
+        'coral':[255,127,80],
+        'cornflowerblue':[100,149,237],
+        'cornsilk':[255,248,220],
+        'crimson':[220,20,60],
+        'cyan':[0,255,255],
+        'darkblue':[0,0,139],
+        'darkcyan':[0,139,139],
+        'darkgoldenrod':[184,134,11],
+        'darkgray':[169,169,169],
+        'darkgrey':[169,169,169],
+        'darkgreen':[0,100,0],
+        'darkkhaki':[189,183,107],
+        'darkmagenta':[139,0,139],
+        'darkolivegreen':[85,107,47],
+        'darkorange':[255,140,0],
+        'darkorchid':[153,50,204],
+        'darkred':[139,0,0],
+        'darksalmon':[233,150,122],
+        'darkseagreen':[143,188,143],
+        'darkslateblue':[72,61,139],
+        'darkslategray':[47,79,79],
+        'darkslategrey':[47,79,79],
+        'darkturquoise':[0,206,209],
+        'darkviolet':[148,0,211],
+        'deeppink':[255,20,147],
+        'deepskyblue':[0,191,255],
+        'dimgray':[105,105,105],
+        'dimgrey':[105,105,105],
+        'dodgerblue':[30,144,255],
+        'firebrick':[178,34,34],
+        'floralwhite':[255,250,240],
+        'forestgreen':[34,139,34],
+        'fuchsia':[255,0,255],
+        'gainsboro':[220,220,220],
+        'ghostwhite':[248,248,255],
+        'gold':[255,215,0],
+        'goldenrod':[218,165,32],
+        'gray':[128,128,128],
+        'grey':[128,128,128],
+        'green':[0,128,0],
+        'greenyellow':[173,255,47],
+        'honeydew':[240,255,240],
+        'hotpink':[255,105,180],
+        'indianred':[205,92,92],
+        'indigo':[75,0,130],
+        'ivory':[255,255,240],
+        'khaki':[240,230,140],
+        'lavender':[230,230,250],
+        'lavenderblush':[255,240,245],
+        'lawngreen':[124,252,0],
+        'lemonchiffon':[255,250,205],
+        'lightblue':[173,216,230],
+        'lightcoral':[240,128,128],
+        'lightcyan':[224,255,255],
+        'lightgoldenrodyellow':[250,250,210],
+        'lightgray':[211,211,211],
+        'lightgrey':[211,211,211],
+        'lightgreen':[144,238,144],
+        'lightpink':[255,182,193],
+        'lightsalmon':[255,160,122],
+        'lightseagreen':[32,178,170],
+        'lightskyblue':[135,206,250],
+        'lightslategray':[119,136,153],
+        'lightslategrey':[119,136,153],
+        'lightsteelblue':[176,196,222],
+        'lightyellow':[255,255,224],
+        'lime':[0,255,0],
+        'limegreen':[50,205,50],
+        'linen':[250,240,230],
+        'magenta':[255,0,255],
+        'maroon':[128,0,0],
+        'mediumaquamarine':[102,205,170],
+        'mediumblue':[0,0,205],
+        'mediumorchid':[186,85,211],
+        'mediumpurple':[147,112,216],
+        'mediumseagreen':[60,179,113],
+        'mediumslateblue':[123,104,238],
+        'mediumspringgreen':[0,250,154],
+        'mediumturquoise':[72,209,204],
+        'mediumvioletred':[199,21,133],
+        'midnightblue':[25,25,112],
+        'mintcream':[245,255,250],
+        'mistyrose':[255,228,225],
+        'moccasin':[255,228,181],
+        'navajowhite':[255,222,173],
+        'navy':[0,0,128],
+        'oldlace':[253,245,230],
+        'olive':[128,128,0],
+        'olivedrab':[107,142,35],
+        'orange':[255,165,0],
+        'orangered':[255,69,0],
+        'orchid':[218,112,214],
+        'palegoldenrod':[238,232,170],
+        'palegreen':[152,251,152],
+        'paleturquoise':[175,238,238],
+        'palevioletred':[216,112,147],
+        'papayawhip':[255,239,213],
+        'peachpuff':[255,218,185],
+        'peru':[205,133,63],
+        'pink':[255,192,203],
+        'plum':[221,160,221],
+        'powderblue':[176,224,230],
+        'purple':[128,0,128],
+        'red':[255,0,0],
+        'rosybrown':[188,143,143],
+        'royalblue':[65,105,225],
+        'saddlebrown':[139,69,19],
+        'salmon':[250,128,114],
+        'sandybrown':[244,164,96],
+        'seagreen':[46,139,87],
+        'seashell':[255,245,238],
+        'sienna':[160,82,45],
+        'silver':[192,192,192],
+        'skyblue':[135,206,235],
+        'slateblue':[106,90,205],
+        'slategray':[112,128,144],
+        'slategrey':[112,128,144],
+        'snow':[255,250,250],
+        'springgreen':[0,255,127],
+        'steelblue':[70,130,180],
+        'tan':[210,180,140],
+        'teal':[0,128,128],
+        'thistle':[216,191,216],
+        'tomato':[255,99,71],
+        'turquoise':[64,224,208],
+        'violet':[238,130,238],
+        'wheat':[245,222,179],
+        'white':[255,255,255],
+        'whitesmoke':[245,245,245],
+        'yellow':[255,255,0],
+        'yellowgreen':[154,205,50],
+    };
+
+    // color parsing function originally from
+    // http://plugins.jquery.com/files/jquery.color.js.txt
+    // (with slight modifications)
+
+    // Parse strings looking for color tuples [255,255,255]
+    var rgbNumRE = /rgb\(\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*\)/;
+    var rgbPercRE = /rgb\(\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*\)/;
+    var rgbHash6RE = /#([a-fA-F0-9]{2})([a-fA-F0-9]{2})([a-fA-F0-9]{2})/;
+    var rgbHash3RE = /#([a-fA-F0-9])([a-fA-F0-9])([a-fA-F0-9])/;
+
+    var strToRgb = function(color) {
+      var result;
+
+      // Check if we're already dealing with an array of colors
+//         if ( color && color.constructor == Array && color.length == 3 )
+//             return color;
+      
+      // Look for rgb(num,num,num)
+      if (result = rgbNumRE.exec(color))
+        return [parseInt(result[1]), parseInt(result[2]), parseInt(result[3])];
+      
+      // Look for rgb(num%,num%,num%)
+      if (result = rgbPercRE.exec(color))
+        return [parseFloat(result[1])*2.55, parseFloat(result[2])*2.55, parseFloat(result[3])*2.55];
+      
+      // Look for #a0b1c2
+      if (result = rgbHash6RE.exec(color))
+        return [parseInt(result[1],16), parseInt(result[2],16), parseInt(result[3],16)];
+      
+      // Look for #fff
+      if (result = rgbHash3RE.exec(color))
+        return [parseInt(result[1]+result[1],16), parseInt(result[2]+result[2],16), parseInt(result[3]+result[3],16)];
+      
+      // Otherwise, we're most likely dealing with a named color
+      return colors[$.trim(color).toLowerCase()];
+    }
+
+    var rgbToStr = function(rgb) {
+      // TODO: there has to be a better way, even in JS
+      var r = Math.floor(rgb[0]).toString(16);
+      var g = Math.floor(rgb[1]).toString(16);
+      var b = Math.floor(rgb[2]).toString(16);
+      // pad
+      r = r.length < 2 ? '0' + r : r;
+      g = g.length < 2 ? '0' + g : g;
+      b = b.length < 2 ? '0' + b : b;        
+      return ('#'+r+g+b);
+    }
+    
+    // Functions rgbToHsl and hslToRgb originally from 
+    // http://mjijackson.com/2008/02/rgb-to-hsl-and-rgb-to-hsv-color-model-conversion-algorithms-in-javascript
+    // implementation of functions in Wikipedia
+    // (with slight modifications)
+
+    // RGB to HSL color conversion
+    var rgbToHsl = function(rgb) {
+      var r = rgb[0]/255, g = rgb[1]/255, b = rgb[2]/255;
+      var max = Math.max(r, g, b), min = Math.min(r, g, b);
+      var h, s, l = (max + min) / 2;
+
+      if (max == min) {
+        h = s = 0; // achromatic
+      } else {
+        var d = max - min;
+        s = l > 0.5 ? d / (2 - max - min) : d / (max + min);
+        switch (max) {
+          case r: h = (g - b) / d + (g < b ? 6 : 0); break;
+          case g: h = (b - r) / d + 2; break;
+          case b: h = (r - g) / d + 4; break;
+        }
+        h /= 6;
+      }
+      
+      return [h, s, l];
+    }
+
+    var hue2rgb = function(p, q, t) {
+      if (t < 0) t += 1;
+      if (t > 1) t -= 1;
+      if (t < 1/6) return p + (q - p) * 6 * t;
+      if (t < 1/2) return q;
+      if (t < 2/3) return p + (q - p) * (2/3 - t) * 6;
+      return p;
+    }
+
+    var hslToRgb = function(hsl) {
+      var h = hsl[0], s = hsl[1], l = hsl[2];
+
+      var r, g, b;
+
+      if (s == 0) {
+        r = g = b = l; // achromatic
+      } else {
+        var q = l < 0.5 ? l * (1 + s) : l + s - l * s;
+        var p = 2 * l - q;
+        r = hue2rgb(p, q, h + 1/3);
+        g = hue2rgb(p, q, h);
+        b = hue2rgb(p, q, h - 1/3);
+      }
+      
+      return [r * 255, g * 255, b * 255];
+    }
+
+    var adjustLightnessCache = {};
+
+    // given color string and -1<=adjust<=1, returns color string
+    // where lightness (in the HSL sense) is adjusted by the given
+    // amount, the larger the lighter: -1 gives black, 1 white, and 0
+    // the given color.
+    var adjustColorLightness = function(colorstr, adjust) {
+      if (!(colorstr in adjustLightnessCache)) {
+        adjustLightnessCache[colorstr] = {}
+      }
+      if (!(adjust in adjustLightnessCache[colorstr])) {
+        var rgb = strToRgb(colorstr);
+        if (rgb === undefined) {
+          // failed color string conversion; just return the input
+          adjustLightnessCache[colorstr][adjust] = colorstr;
+        } else {
+          var hsl = rgbToHsl(rgb);
+          if (adjust > 0.0) {
+            hsl[2] = 1.0 - ((1.0-hsl[2])*(1.0-adjust));
+          } else {
+            hsl[2] = (1.0+adjust)*hsl[2];
+          }
+          var lightRgb = hslToRgb(hsl);
+          adjustLightnessCache[colorstr][adjust] = rgbToStr(lightRgb);
+        }
+      }
+      return adjustLightnessCache[colorstr][adjust];
+    }
+
+    // Partially stolen from: http://documentcloud.github.com/underscore/
+    // MIT-License
+    // TODO: Mention in LICENSE.md
+    var isEqual = function(a, b) {
+      // Check object identity.
+      if (a === b) return true;
+      // Different types?
+      var atype = typeof(a), btype = typeof(b);
+      if (atype != btype) return false;
+      // Basic equality test (watch out for coercions).
+      if (a == b) return true;
+      // One is falsy and the other truthy.
+      if ((!a && b) || (a && !b)) return false;
+      // If a is not an object by this point, we can't handle it.
+      if (atype !== 'object') return false;
+      // Check for different array lengths before comparing contents.
+      if (a.length && (a.length !== b.length)) return false;
+      // Nothing else worked, deep compare the contents.
+      for (var key in b) if (!(key in a)) return false;
+      // Recursive comparison of contents.
+      for (var key in a) if (!(key in b) || !isEqual(a[key], b[key])) return false;
+      return true;
+    };
+
+    var keyValRE = /^([^=]+)=(.*)$/; // key=value
+    var isDigitsRE = /^[0-9]+$/;
+
+    var deparam = function(str) {
+      var args = str.split('&');
+      var len = args.length;
+      if (!len) return null;
+      var result = {};
+      for (var i = 0; i < len; i++) {
+        var parts = args[i].match(keyValRE);
+        if (!parts || parts.length != 3) break;
+        var val = [];
+        var arr = parts[2].split(',');
+        var sublen = arr.length;
+        for (var j = 0; j < sublen; j++) {
+          var innermost = [];
+          // map empty arguments ("" in URL) to empty arrays
+          // (innermost remains [])
+          if (arr[j].length) {
+            var arrsplit = arr[j].split('~');
+            var subsublen = arrsplit.length;
+            for (var k = 0; k < subsublen; k++) {
+              if(arrsplit[k].match(isDigitsRE)) {
+                // convert digits into ints ...
+                innermost.push(parseInt(arrsplit[k], 10));
+              }
+              else {
+                // ... anything else remains a string.
+                innermost.push(arrsplit[k]);
+              }
+            }
+          }
+          val.push(innermost);
+        }
+        result[parts[1]] = val;
+      }
+      return result;
+    };
+
+    var paramArray = function(val) {
+      val = val || [];
+      var len = val.length;
+      var arr = [];
+      for (var i = 0; i < len; i++) {
+        if ($.isArray(val[i])) {
+          arr.push(val[i].join('~'));
+        } else {
+          // non-array argument; this is an error from the caller
+          console.error('param: Error: received non-array-in-array argument [', i, ']', ':', val[i], '(fix caller)');
+        }
+      }
+      return arr;
+    };
+
+    var param = function(args) {
+      if (!args) return '';
+      var vals = [];
+      for (var key in args) {
+        if (args.hasOwnProperty(key)) {
+          var val = args[key];
+          if (val == undefined) {
+            console.error('Error: received argument', key, 'with value', val);
+            continue;
+          }
+          // values normally expected to be arrays, but some callers screw
+          // up, so check
+          if ($.isArray(val)) {
+            var arr = paramArray(val);
+            vals.push(key + '=' + arr.join(','));
+          } else {
+            // non-array argument; this is an error from the caller
+            console.error('param: Error: received non-array argument', key, ':', val, '(fix caller)');
+          }
+        }
+      }
+      return vals.join('&');
+    };
+
+    var profiles = {};
+    var profileStarts = {};
+    var profileOn = false;
+    var profileEnable = function(on) {
+      if (on === undefined) on = true;
+      profileOn = on;
+    }; // profileEnable
+    var profileClear = function() {
+      if (!profileOn) return;
+      profiles = {};
+      profileStarts = {};
+    }; // profileClear
+    var profileStart = function(label) {
+      if (!profileOn) return;
+      profileStarts[label] = new Date();
+    }; // profileStart
+    var profileEnd = function(label) {
+      if (!profileOn) return;
+      var profileElapsed = new Date() - profileStarts[label]
+      if (!profiles[label]) profiles[label] = 0;
+      profiles[label] += profileElapsed;
+    }; // profileEnd
+    var profileReport = function() {
+      if (!profileOn) return;
+      if (window.console) {
+        $.each(profiles, function(label, time) {
+          console.log("profile " + label, time);
+        });
+        console.log("-------");
+      }
+    }; // profileReport
+    
+    // container: ID or jQuery element
+    // collData: the collection data (in the format of the result of
+    //   http://.../brat/ajax.cgi?action=getCollectionInformation&collection=...
+    // docData: the document data (in the format of the result of
+    //   http://.../brat/ajax.cgi?action=getDocument&collection=...&document=...
+    // returns the embedded visualizer's dispatcher object
+    var embed = function(container, collData, docData, webFontURLs,
+                         dispatcher, options) {
+      if (dispatcher === undefined) {
+          dispatcher = new Dispatcher();
+      }
+      if (options === undefined) {
+          options = {};
+      }
+
+      var visualizer = new Visualizer(dispatcher, container, webFontURLs,
+                                      options);
+
+      docData.collection = null;
+
+      dispatcher.post('collectionLoaded', [collData]);
+      dispatcher.post('requestRenderData', [docData]);
+
+      return dispatcher;
+    };
+
+    // container: ID or jQuery element
+    // collDataURL: the URL of the collection data, or collection data
+    //   object (if pre-fetched)
+    // docDataURL: the url of the document data (if pre-fetched, use
+    //   simple `embed` instead)
+    // callback: optional; the callback to call afterwards; it will be
+    //   passed the embedded visualizer's dispatcher object
+    var embedByURL = function(container, collDataURL, docDataURL, webFontURLs, callback) {
+      var collData, docData;
+      var handler = function() {
+        if (collData && docData) {
+          var dispatcher = embed(container, collData, docData, webFontURLs);
+          if (callback) callback(dispatcher);
+        }
+      };
+      if (typeof(container) == 'string') {
+        $.getJSON(collDataURL, function(data) { collData = data; handler(); });
+      } else {
+        collData = collDataURL;
+      }
+      $.getJSON(docDataURL, function(data) { docData = data; handler(); });
+    };
+
+    var fontsLoaded = false;
+    var fontNotifyList = false;
+
+    var proceedWithFonts = function() {
+      if (fontsLoaded) return;
+
+      fontsLoaded = true;
+      $.each(fontNotifyList, function(dispatcherNo, dispatcher) {
+        dispatcher.post('triggerRender');
+      });
+      fontNotifyList = null;
+    };
+
+    var loadFonts = function(webFontURLs, dispatcher) {
+      if (fontsLoaded) {
+        dispatcher.post('triggerRender');
+        return;
+      }
+
+      if (fontNotifyList) {
+        fontNotifyList.push(dispatcher);
+        return;
+      }
+
+      fontNotifyList = [dispatcher];
+
+      webFontURLs = webFontURLs || [
+        'static/fonts/Astloch-Bold.ttf',
+        'static/fonts/PT_Sans-Caption-Web-Regular.ttf',
+        'static/fonts/Liberation_Sans-Regular.ttf'
+      ];
+
+      var families = [];
+      $.each(webFontURLs, function(urlNo, url) {
+        if (/Astloch/i.test(url)) families.push('Astloch');
+        else if (/PT.*Sans.*Caption/i.test(url)) families.push('PT Sans Caption');
+        else if (/Liberation.*Sans/i.test(url)) families.push('Liberation Sans');
+      });
+
+      webFontURLs = {
+        families: families,
+        urls: webFontURLs
+      }
+
+      var webFontConfig = {
+        custom: webFontURLs,
+        active: proceedWithFonts,
+        inactive: proceedWithFonts,
+        fontactive: function(fontFamily, fontDescription) {
+          // Note: Enable for font debugging
+          // console.log("font active: ", fontFamily, fontDescription);
+        },
+        fontloading: function(fontFamily, fontDescription) {
+          // Note: Enable for font debugging
+          // console.log("font loading:", fontFamily, fontDescription);
+        },
+      };
+
+      WebFont.load(webFontConfig);
+
+      setTimeout(function() {
+        if (!fontsLoaded) {
+          console.error('Timeout in loading fonts');
+          proceedWithFonts();
+        }
+      }, fontLoadTimeout);
+    };
+
+    var areFontsLoaded = function() {
+      return fontsLoaded;
+    };
+
+
+    return {
+      profileEnable: profileEnable,
+      profileClear: profileClear,
+      profileStart: profileStart,
+      profileEnd: profileEnd,
+      profileReport: profileReport,
+      formatTimeAgo: formatTimeAgo,
+      realBBox: realBBox,
+      getSpanLabels: getSpanLabels,
+      spanDisplayForm: spanDisplayForm,
+      getArcLabels: getArcLabels,
+      arcDisplayForm: arcDisplayForm,
+      escapeQuotes: escapeQuotes,
+      escapeHTML: escapeHTML,
+      escapeHTMLandQuotes: escapeHTMLandQuotes,
+      escapeHTMLwithNewlines: escapeHTMLwithNewlines,
+      cmp: cmp,
+      rgbToHsl: rgbToHsl,
+      hslToRgb: hslToRgb,
+      adjustColorLightness: adjustColorLightness,
+      objectToUrlStr: objectToUrlStr,
+      isEqual: isEqual,
+      paramArray: paramArray,
+      param: param,
+      deparam: deparam,
+      embed: embed,
+      embedByURL: embedByURL,
+      isMac: isMac,
+      loadFonts: loadFonts,
+      areFontsLoaded: areFontsLoaded,
+    };
+
+})(window);

Property changes on: TXM/trunk/org.txm.conllu.core/template/lib/brat/util.js
___________________________________________________________________
Added: svn:mime-type
   + text/plain

Index: TXM/trunk/org.txm.conllu.core/template/lib/brat/visualizer.js
===================================================================
--- TXM/trunk/org.txm.conllu.core/template/lib/brat/visualizer.js	(revision 0)
+++ TXM/trunk/org.txm.conllu.core/template/lib/brat/visualizer.js	(revision 3567)
@@ -0,0 +1,3381 @@
+// -*- Mode: JavaScript; tab-width: 2; indent-tabs-mode: nil; -*-
+// vim:set ft=javascript ts=2 sw=2 sts=2 cindent:
+
+var Visualizer = (function($, window, undefined) {
+    var DocumentData = function(text) {
+      this.text = text;
+      this.chunks = [];
+      this.spans = {};
+      this.eventDescs = {};
+      this.sentComment = {};
+      this.arcs = [];
+      this.arcById = {};
+      this.markedSent = {};
+      this.spanAnnTexts = {};
+      this.towers = {};
+      // this.sizes = {};
+    };
+
+    var Fragment = function(id, span, from, to) {
+      this.id = id;
+      this.span = span;
+      this.from = from;
+      this.to = to;
+      // this.towerId = undefined;
+      // this.drawOrder = undefined;
+    };
+
+    var Span = function(id, type, offsets, generalType) {
+      this.id = id;
+      this.type = type;
+      this.totalDist = 0;
+      this.numArcs = 0;
+      this.generalType = generalType;
+      this.headFragment = null;
+      this.unsegmentedOffsets = offsets;
+      this.offsets = [];
+      this.segmentedOffsetsMap = {};
+      // this.unsegmentedOffsets = undefined;
+      // this.from = undefined;
+      // this.to = undefined;
+      // this.wholeFrom = undefined;
+      // this.wholeTo = undefined;
+      // this.headFragment = undefined;
+      // this.chunk = undefined;
+      // this.marked = undefined;
+      // this.avgDist = undefined;
+      // this.curly = undefined;
+      // this.comment = undefined; // { type: undefined, text: undefined };
+      // this.annotatorNotes = undefined;
+      // this.drawCurly = undefined;
+      // this.glyphedLabelText = undefined;
+      // this.group = undefined;
+      // this.height = undefined;
+      // this.highlightPos = undefined;
+      // this.indexNumber = undefined;
+      // this.labelText = undefined;
+      // this.nestingDepth = undefined;
+      // this.nestingDepthLR = undefined;
+      // this.nestingDepthRL = undefined;
+      // this.nestingHeight = undefined;
+      // this.nestingHeightLR = undefined;
+      // this.nestingHeightRL = undefined;
+      // this.rect = undefined;
+      // this.rectBox = undefined;
+      // this.refedIndexSum = undefined;
+      // this.right = undefined;
+      // this.totaldist = undefined;
+      // this.width = undefined;
+      this.initContainers();
+    };
+
+    Span.prototype.initContainers = function(offsets) {
+      this.incoming = [];
+      this.outgoing = [];
+      this.attributes = {};
+      this.attributeText = [];
+      this.attributeCues = {};
+      this.attributeCueFor = {};
+      this.attributeMerge = {}; // for box, cross, etc. that are span-global
+      this.fragments = [];
+      this.normalizations = [];
+    };
+
+    Span.prototype.splitMultilineOffsets = function(text) {
+      this.segmentedOffsetsMap = {};
+
+      for (var fi = 0, nfi = 0; fi < this.unsegmentedOffsets.length; fi++) {
+        var begin = this.unsegmentedOffsets[fi][0];
+        var end = this.unsegmentedOffsets[fi][1];
+      
+        for (var ti = begin; ti < end; ti++) {
+          var c = text.charAt(ti);
+          if (c == '\n' || c == '\r') {
+            if (begin !== null) {
+              this.offsets.push([begin, ti])
+              this.segmentedOffsetsMap[nfi++] = fi;
+              begin = null;
+            }
+          }
+          else if (begin === null) {
+            begin = ti;
+          }
+        }
+      
+        if (begin !== null) {
+          this.offsets.push([begin, end]);
+          this.segmentedOffsetsMap[nfi++] = fi;
+        }
+      }
+    };
+
+    Span.prototype.copy = function(id) {
+      var span = $.extend(new Span(), this); // clone
+      span.id = id;
+      // protect from shallow copy
+      span.initContainers();
+      span.unsegmentedOffsets = this.unsegmentedOffsets.slice();
+      // read-only; shallow copy is fine
+      span.offsets = this.offsets;
+      span.segmentedOffsetsMap = this.segmentedOffsetsMap;
+      return span;
+    };
+
+    var EventDesc = function(id, triggerId, roles, klass) {
+      this.id = id;
+      this.triggerId = triggerId;
+      var roleList = this.roles = [];
+      $.each(roles, function(roleNo, role) {
+        roleList.push({ type: role[0], targetId: role[1] });
+      });
+      if (klass == "equiv") {
+        this.equiv = true;
+      } else if (klass == "relation") {
+        this.relation = true;
+      }
+      // this.leftSpans = undefined;
+      // this.rightSpans = undefined;
+      // this.annotatorNotes = undefined;
+    };
+
+    var Chunk = function(index, text, from, to, space, spans) {
+      this.index = index;
+      this.text = text;
+      this.from = from;
+      this.to = to;
+      this.space = space;
+      this.fragments = [];
+      // this.sentence = undefined;
+      // this.group = undefined;
+      // this.highlightGroup = undefined;
+      // this.markedTextStart = undefined;
+      // this.markedTextEnd = undefined;
+      // this.nextSpace = undefined;
+      // this.right = undefined;
+      // this.row = undefined;
+      // this.textX = undefined;
+      // this.translation = undefined;
+    }
+
+    var Arc = function(eventDesc, role, dist, eventNo) {
+      this.origin = eventDesc.id;
+      this.target = role.targetId;
+      this.dist = dist;
+      this.type = role.type;
+      this.shadowClass = eventDesc.shadowClass;
+      this.jumpHeight = 0;
+      if (eventDesc.equiv) {
+        this.equiv = true;
+        this.eventDescId = eventNo;
+        eventDesc.equivArc = this;
+      } else if (eventDesc.relation) {
+        this.relation = true;
+        this.eventDescId = eventNo;
+      }
+      // this.marked = undefined;
+    };
+
+    var Row = function(svg) {
+      this.group = svg.group();
+      this.background = svg.group(this.group);
+      this.chunks = [];
+      this.hasAnnotations = false;
+      this.maxArcHeight = 0;
+      this.maxSpanHeight = 0;
+    };
+
+    var Measurements = function(widths, height, y) {
+      this.widths = widths;
+      this.height = height;
+      this.y = y;
+    };
+
+    // A naive whitespace tokeniser
+    var tokenise = function(text) {
+      var tokenOffsets = [];
+      var tokenStart = null;
+      var lastCharPos = null;
+
+      for (var i = 0; i < text.length; i++) {
+        var c = text[i];
+        // Have we found the start of a token?
+        if (tokenStart == null && !/\s/.test(c)) {
+          tokenStart = i;
+          lastCharPos = i;
+        // Have we found the end of a token?
+        } else if (/\s/.test(c) && tokenStart != null) {
+          tokenOffsets.push([tokenStart, i]);
+          tokenStart = null;
+        // Is it a non-whitespace character?
+        } else if (!/\s/.test(c)) {
+          lastCharPos = i;
+        }
+      }
+      // Do we have a trailing token?
+      if (tokenStart != null) {
+        tokenOffsets.push([tokenStart, lastCharPos + 1]);
+      }
+
+      return tokenOffsets;
+    };
+
+    // A naive newline sentence splitter
+    var sentenceSplit = function(text) {
+      var sentenceOffsets = [];
+      var sentStart = null;
+      var lastCharPos = null;
+
+      for (var i = 0; i < text.length; i++) {
+        var c = text[i];
+        // Have we found the start of a sentence?
+        if (sentStart == null && !/\s/.test(c)) {
+          sentStart = i;
+          lastCharPos = i;
+        // Have we found the end of a sentence?
+        } else if (c == '\n' && sentStart != null) {
+          sentenceOffsets.push([sentStart, i]);
+          sentStart = null;
+        // Is it a non-whitespace character?
+        } else if (!/\s/.test(c)) {
+          lastCharPos = i;
+        }
+      }
+      // Do we have a trailing sentence without a closing newline?
+      if (sentStart != null) {
+        sentenceOffsets.push([sentStart, lastCharPos + 1]);
+      }
+
+      return sentenceOffsets;
+    };
+
+    // Sets default values for a wide range of optional attributes
+    var setSourceDataDefaults = function(sourceData) {
+      // The following are empty lists if not set
+      $.each([
+          'attributes',
+          'comments',
+          'entities',
+          'equivs',
+          'events',
+          'modifications',
+          'normalizations',
+          'relations',
+          'triggers',
+          ], function(attrNo, attr) {
+        if (sourceData[attr] === undefined) {
+          sourceData[attr] = [];
+        }
+      });
+
+      // If we lack sentence offsets we fall back on naive sentence splitting
+      if (sourceData.sentence_offsets === undefined) {
+        sourceData.sentence_offsets = sentenceSplit(sourceData.text);
+      }
+      // Similarily we fall back on whitespace tokenisation
+      if (sourceData.token_offsets === undefined) {
+        sourceData.token_offsets = tokenise(sourceData.text);
+      }
+    };
+
+    // Set default values for a variety of collection attributes
+    var setCollectionDefaults = function(collectionData) {
+      // The following are empty lists if not set
+      $.each([
+          'entity_attribute_types',
+          'entity_types',
+          'event_attribute_types',
+          'event_types',
+          'relation_attribute_types',
+          'relation_types',
+          'unconfigured_types',
+          ], function(attrNo, attr) {
+        if (collectionData[attr] === undefined) {
+          collectionData[attr] = [];
+        }
+      });
+    };
+
+    var Visualizer = function(dispatcher, svgId, webFontURLs,
+                              visualizerOptions) {
+      if (visualizerOptions === undefined) {
+        visualizerOptions = {};
+      }
+      var $svgDiv = $('#' + svgId);
+      if (!$svgDiv.length) {
+        throw Error('Could not find container with id="' + svgId + '"');
+      }
+      var that = this;
+
+      // OPTIONS
+      var roundCoordinates = true; // try to have exact pixel offsets
+      var boxTextMargin = { x: 0, y: 1.5 }; // effect is inverse of "margin" for some reason
+      var highlightRounding = { x: 3, y:3 }; // rx, ry for highlight boxes
+      var spaceWidths = {
+        ' ': 4,
+        '\u00a0': 4,
+        '\u200b': 0,
+        '\u3000': 8,
+        '\t': 12,
+        '\n': 4
+      };
+      var coloredCurlies = true; // color curlies by box BG
+      var arcSlant = 15; //10;
+      var minArcSlant = 8;
+      var arcHorizontalSpacing = 10; // min space boxes with connecting arc
+      var rowSpacing = -5;          // for some funny reason approx. -10 gives "tight" packing.
+      var sentNumMargin = 20;
+      var smoothArcCurves = true;   // whether to use curves (vs lines) in arcs
+      var smoothArcSteepness = 0.5; // steepness of smooth curves (control point)
+      var reverseArcControlx = 5;   // control point distance for "UFO catchers"
+
+      // "shadow" effect settings (note, error, incompelete)
+      var rectShadowSize = 3;
+      var rectShadowRounding = 2.5;
+      var arcLabelShadowSize = 1;
+      var arcLabelShadowRounding = 5;
+      var shadowStroke = 2.5; // TODO XXX: this doesn't affect anything..?
+
+      // "marked" effect settings (edited, focus, match)
+      var markedSpanSize = 6;
+      var markedArcSize = 2;
+      var markedArcStroke = 7; // TODO XXX: this doesn't seem to do anything..?
+
+      var rowPadding = 2;
+      var nestingAdjustYStepSize = 2; // size of height adjust for nested/nesting spans
+      var nestingAdjustXStepSize = 1; // size of height adjust for nested/nesting spans
+
+      var highlightSequence = '#FF9632;#FFCC00;#FF9632'; // yellow - deep orange
+      //var highlightSequence = '#FFFC69;#FFCC00;#FFFC69'; // a bit toned town
+      var highlightSpanSequence = highlightSequence;
+      var highlightArcSequence =  highlightSequence;
+      var highlightTextSequence = highlightSequence;
+      var highlightDuration = '2s';
+      // different sequence for "mere" matches (as opposed to "focus" and
+      // "edited" highlights)
+      var highlightMatchSequence = '#FFFF00'; // plain yellow
+
+      var fragmentConnectorDashArray = '1,3,3,3';
+      var fragmentConnectorColor = '#000000';
+
+      // set caller options
+      if (visualizerOptions.sentNumMargin !== undefined) {
+          sentNumMargin = visualizerOptions.sentNumMargin;
+          // TODO: more, ideally allow any option above to be set
+      }
+
+      // END OPTIONS
+
+
+      var svg;
+      var $svg;
+      var data = null;
+      var sourceData = null;
+      var requestedData = null;
+      var coll, doc, args;
+      var relationTypesHash;
+      var isRenderRequested;
+      var isCollectionLoaded = false;
+      var entityAttributeTypes = null;
+      var eventAttributeTypes = null;
+      var spanTypes = null;
+      var highlightGroup;
+      var collapseArcs = false;
+      var collapseArcSpace = false;
+
+      // var commentPrioLevels = ['Unconfirmed', 'Incomplete', 'Warning', 'Error', 'AnnotatorNotes'];
+      // XXX Might need to be tweaked - inserted diff levels
+      var commentPrioLevels = [
+        'Unconfirmed', 'Incomplete', 'Warning', 'Error', 'AnnotatorNotes',
+        'AddedAnnotation', 'MissingAnnotation', 'ChangedAnnotation'];
+
+      this.arcDragOrigin = null; // TODO
+
+      // due to silly Chrome bug, I have to make it pay attention
+      var forceRedraw = function() {
+        if (!$.browser.chrome) return; // not needed
+        $svg.css('margin-bottom', 1);
+        setTimeout(function() { $svg.css('margin-bottom', 0); }, 0);
+      }
+
+      var rowBBox = function(span) {
+        var box = $.extend({}, span.rectBox); // clone
+        var chunkTranslation = span.chunk.translation;
+        box.x += chunkTranslation.x;
+        box.y += chunkTranslation.y;
+        return box;
+      };
+
+      var commentPriority = function(commentClass) {
+        if (commentClass === undefined) return -1;
+        var len = commentPrioLevels.length;
+        for (var i = 0; i < len; i++) {
+          if (commentClass.indexOf(commentPrioLevels[i]) != -1) return i;
+        }
+        return 0;
+      };
+
+      var clearSVG = function() {
+        data = null;
+        sourceData = null;
+        svg.clear();
+        $svgDiv.hide();
+      };
+
+      var setMarked = function(markedType) {
+        $.each(args[markedType] || [], function(markedNo, marked) {
+          if (marked[0] == 'sent') {
+            data.markedSent[marked[1]] = true;
+          } else if (marked[0] == 'equiv') { // [equiv, Equiv, T1]
+            $.each(sourceData.equivs, function(equivNo, equiv) {
+              if (equiv[1] == marked[1]) {
+                var len = equiv.length;
+                for (var i = 2; i < len; i++) {
+                  if (equiv[i] == marked[2]) {
+                    // found it
+                    len -= 3;
+                    for (var i = 1; i <= len; i++) {
+                      var arc = data.eventDescs[equiv[0] + "*" + i].equivArc;
+                      arc.marked = markedType;
+                    }
+                    return; // next equiv
+                  }
+                }
+              }
+            });
+          } else if (marked.length == 2) {
+            markedText.push([parseInt(marked[0], 10), parseInt(marked[1], 10), markedType]);
+          } else {
+            var span = data.spans[marked[0]];
+            if (span) {
+              if (marked.length == 3) { // arc
+                $.each(span.outgoing, function(arcNo, arc) {
+                  if (arc.target == marked[2] && arc.type == marked[1]) {
+                    arc.marked = markedType;
+                  }
+                });
+              } else { // span
+                span.marked = markedType;
+              }
+            } else {
+              var eventDesc = data.eventDescs[marked[0]];
+              if (eventDesc) { // relation
+                var relArc = eventDesc.roles[0];
+                $.each(data.spans[eventDesc.triggerId].outgoing, function(arcNo, arc) {
+                  if (arc.target == relArc.targetId && arc.type == relArc.type) {
+                    arc.marked = markedType;
+                  }
+                });
+              } else { // try for trigger
+                $.each(data.eventDescs, function(eventDescNo, eventDesc) {
+                  if (eventDesc.triggerId == marked[0]) {
+                    data.spans[eventDesc.id].marked = markedType;
+                  }
+                });
+              }
+            }
+          }
+        });
+      };
+
+      var findArcHeight = function(fromIndex, toIndex, fragmentHeights) {
+        var height = 0;
+        for (var i = fromIndex; i <= toIndex; i++) {
+          if (fragmentHeights[i] > height) height = fragmentHeights[i];
+        }
+        height += Configuration.visual.arcSpacing;
+        return height;
+      }
+
+      var adjustFragmentHeights = function(fromIndex, toIndex, fragmentHeights, height) {
+        for (var i = fromIndex; i <= toIndex; i++) {
+          if (fragmentHeights[i] < height) fragmentHeights[i] = height;
+        }
+      }
+
+      var fragmentComparator = function(a, b) {
+        var tmp;
+        var aSpan = a.span;
+        var bSpan = b.span;
+
+        // spans with more fragments go first
+        tmp = aSpan.fragments.length - bSpan.fragments.length;
+        if (tmp) {
+          return tmp < 0 ? 1 : -1;
+        }
+
+        // longer arc distances go last
+        tmp = aSpan.avgDist - bSpan.avgDist;
+        if (tmp) {
+          return tmp < 0 ? -1 : 1;
+        }
+        // spans with more arcs go last
+        tmp = aSpan.numArcs - bSpan.numArcs;
+        if (tmp) {
+          return tmp < 0 ? -1 : 1;
+        }
+        // compare the span widths,
+        // put wider on bottom so they don't mess with arcs, or shorter
+        // on bottom if there are no arcs.
+        var ad = a.to - a.from;
+        var bd = b.to - b.from;
+        tmp = ad - bd;
+        if (aSpan.numArcs == 0 && bSpan.numArcs == 0) {
+          tmp = -tmp;
+        }
+        if (tmp) {
+          return tmp < 0 ? 1 : -1;
+        }
+        tmp = aSpan.refedIndexSum - bSpan.refedIndexSum;
+        if (tmp) {
+          return tmp < 0 ? -1 : 1;
+        }
+        // if no other criterion is found, sort by type to maintain
+        // consistency
+        // TODO: isn't there a cmp() in JS?
+        if (aSpan.type < bSpan.type) {
+          return -1;
+        } else if (aSpan.type > bSpan.type) {
+          return 1;
+        }
+
+        return 0;
+      };
+
+
+      var setData = function(_sourceData) {
+        if (!args) args = {};
+        sourceData = _sourceData;
+        dispatcher.post('newSourceData', [sourceData]);
+        data = new DocumentData(sourceData.text);
+
+        // collect annotation data
+        $.each(sourceData.entities, function(entityNo, entity) {
+          // offsets given as array of (start, end) pairs
+          var span =
+              //      (id,        type,      offsets,   generalType)
+              new Span(entity[0], entity[1], entity[2], 'entity');
+          span.splitMultilineOffsets(data.text);
+          data.spans[entity[0]] = span;
+        });
+        var triggerHash = {};
+        $.each(sourceData.triggers, function(triggerNo, trigger) {
+                       //       (id,         type,       offsets,    generalType)
+          var triggerSpan = new Span(trigger[0], trigger[1], trigger[2], 'trigger');
+          triggerSpan.splitMultilineOffsets(data.text);
+          triggerHash[trigger[0]] = [triggerSpan, []]; // triggerSpan, eventlist
+        });
+        $.each(sourceData.events, function(eventNo, eventRow) {
+          var eventDesc = data.eventDescs[eventRow[0]] =
+              //           (id,          triggerId,   roles,        klass)
+              new EventDesc(eventRow[0], eventRow[1], eventRow[2]);
+          var trigger = triggerHash[eventDesc.triggerId];
+          var span = trigger[0].copy(eventDesc.id);
+          trigger[1].push(span);
+          data.spans[eventDesc.id] = span;
+        });
+
+        // XXX modifications: delete later
+        $.each(sourceData.modifications, function(modNo, mod) {
+          // mod: [id, spanId, modification]
+          if (!data.spans[mod[2]]) {
+            dispatcher.post('messages', [[['<strong>ERROR</strong><br/>Event ' + mod[2] + ' (referenced from modification ' + mod[0] + ') does not occur in document ' + data.document + '<br/>(please correct the source data)', 'error', 5]]]);
+            return;
+          }
+          data.spans[mod[2]][mod[1]] = true;
+        });
+
+        var midpointComparator = function(a, b) {
+          var tmp = a.from + a.to - b.from - b.to;
+          if (!tmp) return 0;
+          return tmp < 0 ? -1 : 1;
+        };
+        // split spans into span fragments (for discontinuous spans)
+        $.each(data.spans, function(spanNo, span) {
+          $.each(span.offsets, function(offsetsNo, offsets) {
+            var from = parseInt(offsets[0], 10);
+            var to = parseInt(offsets[1], 10);
+            var fragment = new Fragment(offsetsNo, span, from, to);
+            span.fragments.push(fragment);
+          });
+          // ensure ascending order
+          span.fragments.sort(midpointComparator);
+          span.wholeFrom = span.fragments[0].from;
+          span.wholeTo = span.fragments[span.fragments.length - 1].to;
+          span.headFragment = span.fragments[(true) ? span.fragments.length - 1 : 0]; // TODO configurable!
+        });
+
+        var spanComparator = function(a, b) {
+          var aSpan = data.spans[a];
+          var bSpan = data.spans[b];
+          var tmp = aSpan.headFragment.from + aSpan.headFragment.to - bSpan.headFragment.from - bSpan.headFragment.to;
+          if (tmp) {
+            return tmp < 0 ? -1 : 1;
+          }
+          return 0;
+        };
+        $.each(sourceData.equivs, function(equivNo, equiv) {
+          // equiv: ['*', 'Equiv', spanId...]
+          equiv[0] = "*" + equivNo;
+          var equivSpans = equiv.slice(2);
+          var okEquivSpans = [];
+          // collect the equiv spans in an array
+          $.each(equivSpans, function(equivSpanNo, equivSpan) {
+            if (data.spans[equivSpan]) okEquivSpans.push(equivSpan);
+            // TODO: #404, inform the user with a message?
+          });
+          // sort spans in the equiv by their midpoint
+          okEquivSpans.sort(spanComparator);
+          // generate the arcs
+          var len = okEquivSpans.length;
+          for (var i = 1; i < len; i++) {
+            var eventDesc = data.eventDescs[equiv[0] + '*' + i] =
+                //           (id,                  triggerId,           roles,                         klass)
+                new EventDesc(okEquivSpans[i - 1], okEquivSpans[i - 1], [[equiv[1], okEquivSpans[i]]], 'equiv');
+            eventDesc.leftSpans = okEquivSpans.slice(0, i);
+            eventDesc.rightSpans = okEquivSpans.slice(i);
+          }
+        });
+        $.each(sourceData.relations, function(relNo, rel) {
+          // rel[2] is args, rel[2][a][0] is role and rel[2][a][1] is value for a in (0,1)
+          var argsDesc = relationTypesHash[rel[1]];
+          argsDesc = argsDesc && argsDesc.args;
+          var t1, t2;
+          if (argsDesc) {
+            // sort the arguments according to the config
+            var args = {}
+            args[rel[2][0][0]] = rel[2][0][1];
+            args[rel[2][1][0]] = rel[2][1][1];
+            t1 = args[argsDesc[0].role];
+            t2 = args[argsDesc[1].role];
+          } else {
+            // (or leave as-is in its absence)
+            t1 = rel[2][0][1];
+            t2 = rel[2][1][1];
+          }
+          data.eventDescs[rel[0]] =
+              //           (id, triggerId, roles,          klass)
+              new EventDesc(t1, t1,        [[rel[1], t2]], 'relation');
+        });
+
+        // attributes
+        $.each(sourceData.attributes, function(attrNo, attr) {
+          // attr: [id, name, spanId, value, cueSpanId
+
+          // TODO: might wish to check what's appropriate for the type
+          // instead of using the first attribute def found
+          var attrType = (eventAttributeTypes[attr[1]] ||
+                          entityAttributeTypes[attr[1]]);
+          var attrValue = attrType && attrType.values[attrType.bool || attr[3]];
+          var span = data.spans[attr[2]];
+          if (!span) {
+            dispatcher.post('messages', [[['Annotation ' + attr[2] + ', referenced from attribute ' + attr[0] + ', does not exist.', 'error']]]);
+            return;
+          }
+          var valText = (attrValue && attrValue.name) || attr[3];
+          var attrText = attrType
+            ? (attrType.bool ? attrType.name : (attrType.name + ': ' + valText))
+            : (attr[3] === true ? attr[1] : attr[1] + ': ' + attr[3]);
+          span.attributeText.push(attrText);
+          span.attributes[attr[1]] = attr[3];
+          if (attr[4]) { // cue
+            span.attributeCues[attr[1]] = attr[4];
+            var cueSpan = data.spans[attr[4]];
+            cueSpan.attributeCueFor[data.spans[1]] = attr[2];
+            cueSpan.cue = 'CUE'; // special css type
+          }
+          $.extend(span.attributeMerge, attrValue);
+        });
+
+        // comments
+        $.each(sourceData.comments, function(commentNo, comment) {
+          // comment: [entityId, type, text]
+
+          // TODO error handling
+
+          // sentence id: ['sent', sentId]
+          if (comment[0] instanceof Array && comment[0][0] == 'sent') {
+            // sentence comment
+            var sent = comment[0][1];
+            var text = comment[2];
+            if (data.sentComment[sent]) {
+              text = data.sentComment[sent].text + '<br/>' + text;
+            }
+            data.sentComment[sent] = { type: comment[1], text: text };
+          } else {
+            var id = comment[0];
+            var trigger = triggerHash[id];
+            var eventDesc = data.eventDescs[id];
+            var commentEntities =
+                trigger
+                ? trigger[1] // trigger: [span, ...]
+                : id in data.spans
+                  ? [data.spans[id]] // span: [span]
+                  : id in data.eventDescs
+                    ? [data.eventDescs[id]] // arc: [eventDesc]
+                    : [];
+            $.each(commentEntities, function(entityId, entity) {
+              // if duplicate comment for entity:
+              // overwrite type, concatenate comment with a newline
+              if (!entity.comment) {
+                entity.comment = { type: comment[1], text: comment[2] };
+              } else {
+                entity.comment.type = comment[1];
+                entity.comment.text += "\n" + comment[2];
+              }
+              // partially duplicate marking of annotator note comments
+              if (comment[1] == "AnnotatorNotes") {
+                entity.annotatorNotes = comment[2];
+              }
+              // prioritize type setting when multiple comments are present
+              if (commentPriority(comment[1]) > commentPriority(entity.shadowClass)) {
+                entity.shadowClass = comment[1];
+              }
+            });
+          }
+        });
+
+        // normalizations
+        $.each(sourceData.normalizations, function(normNo, norm) {
+          var id = norm[0];
+          var normType = norm[1];
+          var target = norm[2];
+          var refdb = norm[3];
+          var refid = norm[4];
+          var reftext = norm[5];
+
+          // grab entity / event the normalization applies to
+          var span = data.spans[target];
+          if (!span) {
+            dispatcher.post('messages', [[['Annotation ' + target + ', referenced from normalization ' + id + ', does not exist.', 'error']]]);
+            return;
+          }
+
+          // TODO: do we have any possible use for the normType?
+          span.normalizations.push([refdb, refid, reftext]);
+
+          // quick hack for span box visual style
+          span.normalized = 'Normalized';
+        });
+
+        // prepare span boundaries for token containment testing
+        var sortedFragments = [];
+        $.each(data.spans, function(spanNo, span) {
+          $.each(span.fragments, function(fragmentNo, fragment) {
+            sortedFragments.push(fragment);
+          });
+        });
+        // sort fragments by beginning, then by end
+        sortedFragments.sort(function(a, b) {
+          var x = a.from;
+          var y = b.from;
+          if (x == y) {
+            x = a.to;
+            y = b.to;
+          }
+          return ((x < y) ? -1 : ((x > y) ? 1 : 0));
+        });
+        var currentFragmentId = 0;
+        var startFragmentId = 0;
+        var numFragments = sortedFragments.length;
+        var lastTo = 0;
+        var firstFrom = null;
+        var chunkNo = 0;
+        var space;
+        var chunk = null;
+        // token containment testing (chunk recognition)
+        $.each(sourceData.token_offsets, function() {
+          var from = this[0];
+          var to = this[1];
+          if (firstFrom === null) firstFrom = from;
+
+          // Replaced for speedup; TODO check correctness
+          // inSpan = false;
+          // $.each(data.spans, function(spanNo, span) {
+          //   if (span.from < to && to < span.to) {
+          //     // it does; no word break
+          //     inSpan = true;
+          //     return false;
+          //   }
+          // });
+
+          // Is the token end inside a span?
+          if (startFragmentId && to > sortedFragments[startFragmentId - 1].to) {
+            while (startFragmentId < numFragments && to > sortedFragments[startFragmentId].from) {
+              startFragmentId++;
+            }
+          }
+          currentFragmentId = startFragmentId;
+          while (currentFragmentId < numFragments && to >= sortedFragments[currentFragmentId].to) {
+            currentFragmentId++;
+          }
+          // if yes, the next token is in the same chunk
+          if (currentFragmentId < numFragments && to > sortedFragments[currentFragmentId].from) {
+            return;
+          }
+
+          // otherwise, create the chunk found so far
+          space = data.text.substring(lastTo, firstFrom);
+          var text = data.text.substring(firstFrom, to);
+          if (chunk) chunk.nextSpace = space;
+          //               (index,     text, from,      to, space) {
+          chunk = new Chunk(chunkNo++, text, firstFrom, to, space);
+          chunk.lastSpace = space;
+          data.chunks.push(chunk);
+          lastTo = to;
+          firstFrom = null;
+        });
+        var numChunks = chunkNo;
+
+        // find sentence boundaries in relation to chunks
+        chunkNo = 0;
+        var sentenceNo = 0;
+        var pastFirst = false;
+        $.each(sourceData.sentence_offsets, function() {
+          var from = this[0];
+          if (chunkNo >= numChunks) return false;
+          if (data.chunks[chunkNo].from > from) return;
+          var chunk;
+          while (chunkNo < numChunks && (chunk = data.chunks[chunkNo]).from < from) {
+            chunkNo++;
+          }
+          chunkNo++;
+          if (pastFirst && from <= chunk.from) {
+            var numNL = chunk.space.split("\n").length - 1;
+            if (!numNL) numNL = 1;
+            sentenceNo += numNL;
+            chunk.sentence = sentenceNo;
+          } else {
+            pastFirst = true;
+          }
+        });
+
+        // assign fragments to appropriate chunks
+        var currentChunkId = 0;
+        var chunk;
+        $.each(sortedFragments, function(fragmentId, fragment) {
+          while (fragment.to > (chunk = data.chunks[currentChunkId]).to) currentChunkId++;
+          chunk.fragments.push(fragment);
+          fragment.text = chunk.text.substring(fragment.from - chunk.from, fragment.to - chunk.from);
+          fragment.chunk = chunk;
+        });
+
+        // assign arcs to spans; calculate arc distances
+        $.each(data.eventDescs, function(eventNo, eventDesc) {
+          var dist = 0;
+          var origin = data.spans[eventDesc.id];
+          if (!origin) {
+            // TODO: include missing trigger ID in error message
+            dispatcher.post('messages', [[['<strong>ERROR</strong><br/>Trigger for event "' + eventDesc.id + '" not found in ' + data.document + '<br/>(please correct the source data)', 'error', 5]]]);
+            return;
+          }
+          var here = origin.headFragment.from + origin.headFragment.to;
+          $.each(eventDesc.roles, function(roleNo, role) {
+            var target = data.spans[role.targetId];
+            if (!target) {
+              dispatcher.post('messages', [[['<strong>ERROR</strong><br/>"' + role.targetId + '" (referenced from "' + eventDesc.id + '") not found in ' + data.document + '<br/>(please correct the source data)', 'error', 5]]]);
+              return;
+            }
+            var there = target.headFragment.from + target.headFragment.to;
+            var dist = Math.abs(here - there);
+            var arc = new Arc(eventDesc, role, dist, eventNo);
+            origin.totalDist += dist;
+            origin.numArcs++;
+            target.totalDist += dist;
+            target.numArcs++;
+            data.arcs.push(arc);
+            target.incoming.push(arc);
+            origin.outgoing.push(arc);
+            // ID dict for easy access. TODO: have a function defining the
+            // (origin,type,target)->id mapping (see also annotator_ui.js)
+            var arcId = origin.id + '--' + role.type + '--' + target.id;
+            data.arcById[arcId] = arc;
+          }); // roles
+        }); // eventDescs
+
+        // highlighting
+        markedText = [];
+        setMarked('edited'); // set by editing process
+        setMarked('focus'); // set by URL
+        setMarked('matchfocus'); // set by search process, focused match
+        setMarked('match'); // set by search process, other (non-focused) match
+
+        $.each(data.spans, function(spanId, span) {
+          // calculate average arc distances
+          // average distance of arcs (0 for no arcs)
+          span.avgDist = span.numArcs ? span.totalDist / span.numArcs : 0;
+          lastSpan = span;
+
+          // collect fragment texts into span texts
+          var fragmentTexts = [];
+          $.each(span.fragments, function(fragmentNo, fragment) {
+            // TODO heuristics
+            fragmentTexts.push(fragment.text);
+          });
+          span.text = fragmentTexts.join('');
+        }); // data.spans
+
+        for (var i = 0; i < 2; i++) {
+          // preliminary sort to assign heights for basic cases
+          // (first round) and cases resolved in the previous
+          // round(s).
+          $.each(data.chunks, function(chunkNo, chunk) {
+            // sort
+            chunk.fragments.sort(fragmentComparator);
+            // renumber
+            $.each(chunk.fragments, function(fragmentNo, fragment) {
+              fragment.indexNumber = fragmentNo;
+            });
+          });
+          // nix the sums, so we can sum again
+          $.each(data.spans, function(spanNo, span) {
+            span.refedIndexSum = 0;
+          });
+          // resolved cases will now have indexNumber set
+          // to indicate their relative order. Sum those for referencing cases
+          // for use in iterative resorting
+          $.each(data.arcs, function(arcNo, arc) {
+            data.spans[arc.origin].refedIndexSum += data.spans[arc.target].headFragment.indexNumber;
+          });
+        }
+
+        // Final sort of fragments in chunks for drawing purposes
+        // Also identify the marked text boundaries regarding chunks
+        $.each(data.chunks, function(chunkNo, chunk) {
+          // and make the next sort take this into account. Note that this will
+          // now resolve first-order dependencies between sort orders but not
+          // second-order or higher.
+          chunk.fragments.sort(fragmentComparator);
+          $.each(chunk.fragments, function(fragmentNo, fragment) {
+            fragment.drawOrder = fragmentNo;
+          });
+        });
+
+        data.spanDrawOrderPermutation = Object.keys(data.spans);
+        data.spanDrawOrderPermutation.sort(function(a, b) {
+          var spanA = data.spans[a];
+          var spanB = data.spans[b];
+
+          // We're jumping all over the chunks, but it's enough that
+          // we're doing everything inside each chunk in the right
+          // order. should it become necessary to actually do these in
+          // linear order, put in a similar condition for
+          // spanX.headFragment.chunk.index; but it should not be
+          // needed.
+
+          var tmp = spanA.headFragment.drawOrder - spanB.headFragment.drawOrder;
+          if (tmp) return tmp < 0 ? -1 : 1;
+
+          return 0;
+        });
+
+        // resort the spans for linear order by center
+        sortedFragments.sort(midpointComparator);
+
+        // sort fragments into towers, calculate average arc distances
+        var lastFragment = null;
+        var towerId = -1;
+        $.each(sortedFragments, function(i, fragment) {
+          if (!lastFragment || (lastFragment.from != fragment.from || lastFragment.to != fragment.to)) {
+            towerId++;
+          }
+          fragment.towerId = towerId;
+          lastFragment = fragment;
+        }); // sortedFragments
+
+        // find curlies (only the first fragment drawn in a tower)
+        $.each(data.spanDrawOrderPermutation, function(spanIdNo, spanId) {
+          var span = data.spans[spanId];
+
+          $.each(span.fragments, function(fragmentNo, fragment) {
+            if (!data.towers[fragment.towerId]) {
+              data.towers[fragment.towerId] = [];
+              fragment.drawCurly = true;
+              fragment.span.drawCurly = true;
+            }
+            data.towers[fragment.towerId].push(fragment);
+          });
+        });
+
+        var spanAnnTexts = {};
+        $.each(data.chunks, function(chunkNo, chunk) {
+          chunk.markedTextStart = [];
+          chunk.markedTextEnd = [];
+
+          $.each(chunk.fragments, function(fragmentNo, fragment) {
+            if (chunk.firstFragmentIndex == undefined) {
+              chunk.firstFragmentIndex = fragment.towerId;
+            }
+            chunk.lastFragmentIndex = fragment.towerId;
+
+            var spanLabels = Util.getSpanLabels(spanTypes, fragment.span.type);
+            fragment.labelText = Util.spanDisplayForm(spanTypes, fragment.span.type);
+            // Find the most appropriate label according to text width
+            if (Configuration.abbrevsOn && spanLabels) {
+              var labelIdx = 1; // first abbrev
+              var maxLength = (fragment.to - fragment.from) / 0.8;
+              while (fragment.labelText.length > maxLength &&
+                  spanLabels[labelIdx]) {
+                fragment.labelText = spanLabels[labelIdx];
+                labelIdx++;
+              }
+            }
+
+            var svgtext = svg.createText(); // one "text" element per row
+            var postfixArray = [];
+            var prefix = '';
+            var postfix = '';
+            var warning = false;
+            $.each(fragment.span.attributes, function(attrType, valType) {
+              // TODO: might wish to check what's appropriate for the type
+              // instead of using the first attribute def found
+              var attr = (eventAttributeTypes[attrType] ||
+                          entityAttributeTypes[attrType]);
+              if (!attr) {
+                // non-existent type
+                warning = true;
+                return;
+              }
+              var val = attr.values[attr.bool || valType];
+              if (!val) {
+                // non-existent value
+                warning = true;
+                return;
+              }
+              if ($.isEmptyObject(val)) {
+                // defined, but lacks any visual presentation
+                warning = true;
+                return;
+              }
+              if (val.glyph) {
+                if (val.position == "left") {
+                  prefix = val.glyph + prefix;
+                  var tspan_attrs = { 'class' : 'glyph' };
+                  if (val.glyphColor) {
+                    tspan_attrs.fill = val.glyphColor;
+                  }
+                  svgtext.span(val.glyph, tspan_attrs);
+                } else { // XXX right is implied - maybe change
+                  postfixArray.push([attr, val]);
+                  postfix += val.glyph;
+                }
+              }
+            });
+            var text = fragment.labelText;
+            if (prefix !== '') {
+              text = prefix + ' ' + text;
+              svgtext.string(' ');
+            }
+            svgtext.string(fragment.labelText);
+            if (postfixArray.length) {
+              text += ' ' + postfix;
+              svgtext.string(' ');
+              $.each(postfixArray, function(elNo, el) {
+                var tspan_attrs = { 'class' : 'glyph' };
+                if (el[1].glyphColor) {
+                  tspan_attrs.fill = el[1].glyphColor;
+                }
+                svgtext.span(el[1].glyph, tspan_attrs);
+              });
+            }
+            if (warning) {
+              svgtext.span("#", { 'class': 'glyph attribute_warning' });
+              text += ' #';
+            }
+            fragment.glyphedLabelText = text;
+
+            if (!spanAnnTexts[text]) {
+              spanAnnTexts[text] = true;
+              data.spanAnnTexts[text] = svgtext;
+            }
+          }); // chunk.fragments
+        }); // chunks
+
+        var numChunks = data.chunks.length;
+        // note the location of marked text with respect to chunks
+        var startChunk = 0;
+        var currentChunk;
+        // sort by "from"; we don't need to sort by "to" as well,
+        // because unlike spans, chunks are disjunct
+        markedText.sort(function(a, b) {
+          return Util.cmp(a[0], b[0]);
+        });
+        $.each(markedText, function(textNo, textPos) {
+          var from = textPos[0];
+          var to = textPos[1];
+          var markedType = textPos[2];
+          if (from < 0) from = 0;
+          if (to < 0) to = 0;
+          if (to >= data.text.length) to = data.text.length - 1;
+          if (from > to) from = to;
+          while (startChunk < numChunks) {
+            var chunk = data.chunks[startChunk];
+            if (from <= chunk.to) {
+              chunk.markedTextStart.push([textNo, true, from - chunk.from, null, markedType]);
+              break;
+            }
+            startChunk++;
+          }
+          if (startChunk == numChunks) {
+            dispatcher.post('messages', [[['Wrong text offset', 'error']]]);
+            return;
+          }
+          currentChunk = startChunk;
+          while (currentChunk < numChunks) {
+            var chunk = data.chunks[currentChunk];
+            if (to <= chunk.to) {
+              chunk.markedTextEnd.push([textNo, false, to - chunk.from]);
+              break
+            }
+            currentChunk++;
+          }
+          if (currentChunk == numChunks) {
+            dispatcher.post('messages', [[['Wrong text offset', 'error']]]);
+            var chunk = data.chunks[data.chunks.length - 1];
+            chunk.markedTextEnd.push([textNo, false, chunk.text.length]);
+            return;
+          }
+        }); // markedText
+
+        dispatcher.post('dataReady', [data]);
+      };
+
+      var resetData = function() {
+        setData(sourceData);
+        renderData();
+      }
+
+      var translate = function(element, x, y) {
+        $(element.group).attr('transform', 'translate(' + x + ', ' + y + ')');
+        element.translation = { x: x, y: y };
+      };
+
+      var showMtime = function() {
+        if (data.mtime) {
+            // we're getting seconds and need milliseconds
+            //$('#document_ctime').text("Created: " + Annotator.formatTime(1000 * data.ctime)).css("display", "inline");
+            $('#document_mtime').text("Last modified: " + Util.formatTimeAgo(1000 * data.mtime)).css("display", "inline");
+        } else {
+            //$('#document_ctime').css("display", "none");
+            $('#document_mtime').css("display", "none");
+        }
+      };
+
+      var addHeaderAndDefs = function() {
+        var commentName = (coll + '/' + doc).replace('--', '-\\-');
+        $svg.append('<!-- document: ' + commentName + ' -->');
+        var defs = svg.defs();
+        var $blurFilter = $('<filter id="Gaussian_Blur"><feGaussianBlur in="SourceGraphic" stdDeviation="2" /></filter>');
+        svg.add(defs, $blurFilter);
+        return defs;
+      }
+
+      var getTextMeasurements = function(textsHash, options, callback) {
+        // make some text elements, find out the dimensions
+        var textMeasureGroup = svg.group(options);
+
+        // changed from $.each because of #264 ('length' can appear)
+        for (var text in textsHash) {
+          if (textsHash.hasOwnProperty(text)) {
+            svg.text(textMeasureGroup, 0, 0, text);
+          }
+        }
+
+        // measuring goes on here
+        var widths = {};
+        $(textMeasureGroup).find('text').each(function(svgTextNo, svgText) {
+          var text = $(svgText).text();
+          widths[text] = this.getComputedTextLength();
+
+          if (callback) {
+            $.each(textsHash[text], function(text, object) {
+              callback(object, svgText);
+            });
+          }
+        });
+        var bbox = textMeasureGroup.getBBox();
+        svg.remove(textMeasureGroup);
+
+        return new Measurements(widths, bbox.height, bbox.y);
+      };
+
+      var getTextAndSpanTextMeasurements = function() {
+        // get the span text sizes
+        var chunkTexts = {}; // set of span texts
+        $.each(data.chunks, function(chunkNo, chunk) {
+          chunk.row = undefined; // reset
+          if (!chunkTexts.hasOwnProperty(chunk.text)) chunkTexts[chunk.text] = []
+          var chunkText = chunkTexts[chunk.text];
+
+          // here we also need all the spans that are contained in
+          // chunks with this text, because we need to know the position
+          // of the span text within the respective chunk text
+          chunkText.push.apply(chunkText, chunk.fragments);
+          // and also the markedText boundaries
+          chunkText.push.apply(chunkText, chunk.markedTextStart);
+          chunkText.push.apply(chunkText, chunk.markedTextEnd);
+        });
+        var textSizes = getTextMeasurements(
+          chunkTexts,
+          undefined,
+          function(fragment, text) {
+            if (fragment instanceof Fragment) { // it's a fragment!
+              // measure the fragment text position in pixels
+              var firstChar = fragment.from - fragment.chunk.from;
+              if (firstChar < 0) {
+                firstChar = 0;
+                dispatcher.post('messages', [[['<strong>WARNING</strong>' +
+                  '<br/> ' +
+                  'The fragment [' + fragment.from + ', ' + fragment.to + '] (' + fragment.text + ') is not ' +
+                  'contained in its designated chunk [' +
+                  fragment.chunk.from + ', ' + fragment.chunk.to + '] most likely ' +
+                  'due to the fragment starting or ending with a space, please ' +
+                  'verify the sanity of your data since we are unable to ' +
+                  'visualise this fragment correctly and will drop leading ' +
+                  'space characters'
+                  , 'warning', 15]]]);
+              }
+              var lastChar = fragment.to - fragment.chunk.from - 1;
+
+              // Adjust for XML whitespace (#832, #1009)
+              var textUpToFirstChar = fragment.chunk.text.substring(0, firstChar);
+              var textUpToLastChar = fragment.chunk.text.substring(0, lastChar);
+              var textUpToFirstCharUnspaced = textUpToFirstChar.replace(/\s\s+/g, ' ');
+              var textUpToLastCharUnspaced = textUpToLastChar.replace(/\s\s+/g, ' ');
+              firstChar -= textUpToFirstChar.length - textUpToFirstCharUnspaced.length;
+              lastChar -= textUpToLastChar.length - textUpToLastCharUnspaced.length;
+
+              var startPos, endPos;
+              if (firstChar < fragment.chunk.text.length) {
+                startPos = text.getStartPositionOfChar(firstChar).x;
+              } else {
+                startPos = text.getComputedTextLength();
+              }
+              endPos = (lastChar < firstChar)
+                ? startPos
+                : text.getEndPositionOfChar(lastChar).x;
+              fragment.curly = {
+                from: startPos,
+                to: endPos
+              };
+            } else { // it's markedText [id, start?, char#, offset]
+              if (fragment[2] < 0) fragment[2] = 0;
+              if (!fragment[2]) { // start
+                fragment[3] = text.getStartPositionOfChar(fragment[2]).x;
+              } else {
+                fragment[3] = text.getEndPositionOfChar(fragment[2] - 1).x + 1;
+              }
+            }
+          });
+
+        // get the fragment annotation text sizes
+        var fragmentTexts = {};
+        var noSpans = true;
+        $.each(data.spans, function(spanNo, span) {
+          $.each(span.fragments, function(fragmentNo, fragment) {
+            fragmentTexts[fragment.glyphedLabelText] = true;
+            noSpans = false;
+          });
+        });
+        if (noSpans) fragmentTexts.$ = true; // dummy so we can at least get the height
+        var fragmentSizes = getTextMeasurements(fragmentTexts, {'class': 'span'});
+
+        return {
+          texts: textSizes,
+          fragments: fragmentSizes
+        };
+      };
+
+      var addArcTextMeasurements = function(sizes) {
+        // get the arc annotation text sizes (for all labels)
+        var arcTexts = {};
+        $.each(data.arcs, function(arcNo, arc) {
+          var labels = Util.getArcLabels(spanTypes, data.spans[arc.origin].type, arc.type, relationTypesHash);
+          if (!labels.length) labels = [arc.type];
+          $.each(labels, function(labelNo, label) {
+            arcTexts[label] = true;
+          });
+        });
+        var arcSizes = getTextMeasurements(arcTexts, {'class': 'arcs'});
+        sizes.arcs = arcSizes;
+      };
+
+      var adjustTowerAnnotationSizes = function() {
+        // find biggest annotation in each tower
+        $.each(data.towers, function(towerNo, tower) {
+          var maxWidth = 0;
+          $.each(tower, function(fragmentNo, fragment) {
+            var width = data.sizes.fragments.widths[fragment.glyphedLabelText];
+            if (width > maxWidth) maxWidth = width;
+          }); // tower
+          $.each(tower, function(fragmentNo, fragment) {
+            fragment.width = maxWidth;
+          }); // tower
+        }); // data.towers
+      };
+
+      var makeArrow = function(defs, spec) {
+        var parsedSpec = spec.split(',');
+        var type = parsedSpec[0];
+        if (type == 'none') return;
+
+        var width = 5;
+        var height = 5;
+        var color = "black";
+        if ($.isNumeric(parsedSpec[1]) && parsedSpec[2]) {
+          if ($.isNumeric(parsedSpec[2]) && parsedSpec[3]) {
+            // 3 args, 2 numeric: assume width, height, color
+            width = parsedSpec[1];
+            height = parsedSpec[2];
+            color = parsedSpec[3] || 'black';
+          } else {
+            // 2 args, 1 numeric: assume width/height, color
+            width = height = parsedSpec[1];
+            color = parsedSpec[2] || 'black';
+          }
+        } else {
+          // other: assume color only
+          width = height = 5;
+          color = parsedSpec[1] || 'black';
+        }
+        // hash needs to be replaced as IDs don't permit it.
+        var arrowId = 'arrow_' + spec.replace(/#/g, '').replace(/,/g, '_');
+
+        var arrow;
+        if (type == 'triangle') {
+          arrow = svg.marker(defs, arrowId,
+            width, height / 2, width, height, 'auto',
+            {
+              markerUnits: 'strokeWidth',
+              'fill': color,
+            });
+          svg.polyline(arrow, [[0, 0], [width, height / 2], [0, height], [width / 12, height / 2]]);
+        }
+        return arrowId;
+      }
+
+      var createStyleMap = function(styles) {
+          var styleMap = {};
+          
+          if (!styles) {
+              return styleMap;
+          }
+          for (var i=0; i<styles.length; i++) {
+              var style = styles[i];
+
+              if (!style || style.length !== 3) {
+                  console.log('warning: invalid style spec:', style);
+                  continue;
+              }
+
+              var targetRef = style[0],
+                  attribute = style[1],
+                  value = style[2];
+
+              // map multipart IDs to reference string by joining w/space
+              if (targetRef instanceof Array) {
+                  targetRef = targetRef.join(' ');
+              }
+
+              if (styleMap[targetRef] === undefined) {
+                  styleMap[targetRef] = {};
+              }
+              if (styleMap[targetRef][attribute] !== undefined) {
+                  console.log('warning: multiple style definitions for',
+                              targetRef, attribute);
+              }
+              styleMap[targetRef][attribute] = value;
+          }
+          return styleMap;
+      };
+
+      var drawing = false;
+      var redraw = false;
+
+      var renderDataReal = function(sourceData) {
+Util.profileEnd('before render');
+Util.profileStart('render');
+Util.profileStart('init');
+
+        if (!sourceData && !data) {
+          dispatcher.post('doneRendering', [coll, doc, args]);
+          return;
+        }
+        $svgDiv.show();
+        if ((sourceData && sourceData.collection && (sourceData.document !== doc || sourceData.collection !== coll)) || drawing) {
+          redraw = true;
+          dispatcher.post('doneRendering', [coll, doc, args]);
+          return;
+        }
+        redraw = false;
+        drawing = true;
+
+        if (sourceData) setData(sourceData);
+        showMtime();
+
+        // clear the SVG
+        svg.clear(true);
+        if (!data || data.length == 0) return;
+
+        // establish the width according to the enclosing element
+        canvasWidth = that.forceWidth || $svgDiv.width();
+
+        var defs = addHeaderAndDefs();
+
+        var backgroundGroup = svg.group({ 'class': 'background' });
+        var glowGroup = svg.group({ 'class': 'glow' });
+        highlightGroup = svg.group({ 'class': 'highlight' });
+        var textGroup = svg.group({ 'class': 'text' });
+
+Util.profileEnd('init');
+Util.profileStart('measures');
+
+        var sizes = getTextAndSpanTextMeasurements();
+        data.sizes = sizes;
+
+        var styleMap = createStyleMap(sourceData['styles']);
+
+        adjustTowerAnnotationSizes();
+        var maxTextWidth = 0;
+        for (var text in sizes.texts.widths) {
+          if (sizes.texts.widths.hasOwnProperty(text)) {
+            var width = sizes.texts.widths[text]
+            if (width > maxTextWidth) maxTextWidth = width;
+          }
+        }
+
+Util.profileEnd('measures');
+Util.profileStart('chunks');
+
+        var currentX = Configuration.visual.margin.x + sentNumMargin + rowPadding;
+        var rows = [];
+        var fragmentHeights = [];
+        var sentenceToggle = 0;
+        var sentenceNumber = 0;
+        var row = new Row(svg);
+        row.sentence = ++sentenceNumber;
+        row.backgroundIndex = sentenceToggle;
+        row.index = 0;
+        var rowIndex = 0;
+        var twoBarWidths; // HACK to avoid measuring space's width
+        var openTextHighlights = {};
+        var textMarkedRows = [];
+
+        addArcTextMeasurements(sizes);
+
+        // reserve places for spans
+        var floors = [];
+        var reservations = []; // reservations[chunk][floor] = [[from, to, headroom]...]
+        for (var i = 0; i <= data.lastFragmentIndex; i++) {
+          reservation[i] = {};
+        }
+        var inf = 1.0/0.0;
+
+        $.each(data.spanDrawOrderPermutation, function(spanIdNo, spanId) {
+          var span = data.spans[spanId];
+          var spanDesc = spanTypes[span.type];
+          var bgColor = ((spanDesc && spanDesc.bgColor) ||
+                          (spanTypes.SPAN_DEFAULT &&
+                          spanTypes.SPAN_DEFAULT.bgColor) || '#ffffff');
+          if (bgColor == "hidden") {
+            span.hidden = true;
+            return;
+          }
+
+          var f1 = span.fragments[0];
+          var f2 = span.fragments[span.fragments.length - 1];
+
+          var x1 = (f1.curly.from + f1.curly.to - f1.width) / 2 -
+              Configuration.visual.margin.x;
+          var i1 = f1.chunk.index;
+
+          var x2 = (f2.curly.from + f2.curly.to + f2.width) / 2 +
+              Configuration.visual.margin.x;
+          var i2 = f2.chunk.index;
+
+          // Start from the ground level, going up floor by floor.
+          // If no more floors, make a new available one.
+          // If a floor is available and there is no carpet, mark it as carpet.
+          // If a floor is available and there is carpet and height
+          //   difference is at least fragment height + curly, OK.
+          // If a floor is not available, forget about carpet.
+          // --
+          // When OK, calculate exact ceiling.
+          // If there isn't one, make a new floor, copy reservations
+          //   from floor below (with decreased ceiling)
+          // Make the reservation from the carpet to just below the
+          //   current floor.
+          //
+          // TODO drawCurly and height could be prettified to only check
+          // actual positions of curlies
+          var carpet = 0;
+          var outside = true;
+          var thisCurlyHeight = span.drawCurly ? Configuration.visual.curlyHeight : 0;
+          var height = sizes.fragments.height + thisCurlyHeight + Configuration.visual.boxSpacing +
+              2 * Configuration.visual.margin.y - 3;
+          $.each(floors, function(floorNo, floor) {
+            var floorAvailable = true;
+            for (var i = i1; i <= i2; i++) {
+              if (!(reservations[i] && reservations[i][floor])) continue;
+              var from = (i == i1) ? x1 : -inf;
+              var to = (i == i2) ? x2 : inf;
+              $.each(reservations[i][floor], function(resNo, res) {
+                if (res[0] < to && from < res[1]) {
+                  floorAvailable = false;
+                  return false;
+                }
+              });
+            }
+            if (floorAvailable) {
+              if (carpet === null) {
+                carpet = floor;
+              } else if (height + carpet <= floor) {
+                // found our floor!
+                outside = false;
+                return false;
+              }
+            } else {
+              carpet = null;
+            }
+          });
+          var reslen = reservations.length;
+          var makeNewFloorIfNeeded = function(floor) {
+            var floorNo = $.inArray(floor, floors);
+            if (floorNo == -1) {
+              floors.push(floor);
+              floors.sort(Util.cmp);
+              floorNo = $.inArray(floor, floors);
+              if (floorNo != 0) {
+                // copy reservations from the floor below
+                var parquet = floors[floorNo - 1];
+                for (var i = 0; i <= reslen; i++) {
+                  if (reservations[i]) {
+                    if (!reservations[i][parquet]) {
+                      reservations[i][parquet] = [];
+                    }
+                    var footroom = floor - parquet;
+                    $.each(reservations[i][parquet], function(resNo, res) {
+                      if (res[2] > footroom) {
+                        if (!reservations[i][floor]) {
+                          reservations[i][floor] = [];
+                        }
+                        reservations[i][floor].push([res[0], res[1], res[2] - footroom]);
+                      }
+                    });
+                  }
+                }
+              }
+            }
+            return floorNo;
+          }
+          var ceiling = carpet + height;
+          var ceilingNo = makeNewFloorIfNeeded(ceiling);
+          var carpetNo = makeNewFloorIfNeeded(carpet);
+          // make the reservation
+          var floor, floorNo;
+          for (floorNo = carpetNo;
+              (floor = floors[floorNo]) !== undefined && floor < ceiling;
+              floorNo++) {
+            var headroom = ceiling - floor;
+            for (var i = i1; i <= i2; i++) {
+              var from = (i == i1) ? x1 : 0;
+              var to = (i == i2) ? x2 : inf;
+              if (!reservations[i]) reservations[i] = {};
+              if (!reservations[i][floor]) reservations[i][floor] = [];
+              reservations[i][floor].push([from, to, headroom]); // XXX maybe add fragment; probably unnecessary
+            }
+          }
+          span.floor = carpet + thisCurlyHeight;
+        });
+
+        $.each(data.chunks, function(chunkNo, chunk) {
+          var spaceWidth = 0;
+          if (chunk.lastSpace) {
+            var spaceLen = chunk.lastSpace.length || 0;
+            var spacePos = chunk.lastSpace.lastIndexOf("\n") + 1;
+            if (spacePos || !chunkNo || !chunk.sentence) {
+              // indent if
+              // * non-first paragraph first word
+              // * first paragraph first word
+              // * non-first word in a line
+              // don't indent if
+              // * the first word in a non-paragraph line
+              for (var i = spacePos; i < spaceLen; i++) spaceWidth += spaceWidths[chunk.lastSpace[i]] || 0;
+              currentX += spaceWidth;
+            }
+          }
+
+          chunk.group = svg.group(row.group);
+          chunk.highlightGroup = svg.group(chunk.group);
+
+          var y = 0;
+          var minArcDist;
+          var hasLeftArcs, hasRightArcs, hasInternalArcs;
+          var hasAnnotations;
+          var chunkFrom = Infinity;
+          var chunkTo = 0;
+          var chunkHeight = 0;
+          var spacing = 0;
+          var spacingChunkId = null;
+          var spacingRowBreak = 0;
+
+          $.each(chunk.fragments, function(fragmentNo, fragment) {
+            var span = fragment.span;
+            var spanDesc = spanTypes[span.type];
+            var bgColor = ((spanDesc && spanDesc.bgColor) ||
+                           (spanTypes.SPAN_DEFAULT &&
+                            spanTypes.SPAN_DEFAULT.bgColor) || '#ffffff');
+            if (span.hidden) return;
+            var fgColor = ((spanDesc && spanDesc.fgColor) ||
+                           (spanTypes.SPAN_DEFAULT &&
+                            spanTypes.SPAN_DEFAULT.fgColor) || '#000000');
+            var borderColor = ((spanDesc && spanDesc.borderColor) ||
+                               (spanTypes.SPAN_DEFAULT &&
+                                spanTypes.SPAN_DEFAULT.borderColor) || '#000000');
+
+            // set span-specific styles
+            if (styleMap[span.id]) {
+                if (styleMap[span.id]['fgColor'] !== undefined) {
+                    fgColor = styleMap[span.id]['fgColor'];
+                }
+                if (styleMap[span.id]['bgColor'] !== undefined) {
+                    bgColor = styleMap[span.id]['bgColor'];
+                }
+                if (styleMap[span.id]['borderColor'] !== undefined) {
+                    borderColor = styleMap[span.id]['borderColor'];
+                }
+            }
+
+            // special case: if the border 'color' value is 'darken',
+            // then just darken the BG color a bit for the border.
+            if (borderColor == 'darken') {
+                borderColor = Util.adjustColorLightness(bgColor, -0.6);
+            }
+
+            fragment.group = svg.group(chunk.group, {
+              'class': 'span',
+            });
+
+            var fragmentHeight = 0;
+
+            if (!y) y = -sizes.texts.height;
+            var x = (fragment.curly.from + fragment.curly.to) / 2;
+
+            // XXX is it maybe sizes.texts?
+            var yy = y + sizes.fragments.y;
+            var hh = sizes.fragments.height;
+            var ww = fragment.width;
+            var xx = x - ww / 2;
+
+            // text margin fine-tuning
+            yy += boxTextMargin.y;
+            hh -= 2*boxTextMargin.y;
+            xx += boxTextMargin.x;
+            ww -= 2*boxTextMargin.x;
+            var rectClass = 'span_' + (span.cue || span.type) + ' span_default'; // TODO XXX first part unneeded I think; remove
+
+            // attach e.g. "False_positive" into the type
+            if (span.comment && span.comment.type) { rectClass += ' '+span.comment.type; }
+            var bx = xx - Configuration.visual.margin.x - boxTextMargin.x;
+            var by = yy - Configuration.visual.margin.y;
+            var bw = ww + 2 * Configuration.visual.margin.x;
+            var bh = hh + 2 * Configuration.visual.margin.y;
+
+            if (roundCoordinates) {
+              x  = (x|0)+0.5;
+              bx = (bx|0)+0.5;
+            }
+
+            var shadowRect;
+            var markedRect;
+            if (span.marked) {
+              markedRect = svg.rect(chunk.highlightGroup,
+                  bx - markedSpanSize, by - markedSpanSize,
+                  bw + 2 * markedSpanSize, bh + 2 * markedSpanSize, {
+
+                  // filter: 'url(#Gaussian_Blur)',
+                  'class': "shadow_EditHighlight",
+                  rx: markedSpanSize,
+                  ry: markedSpanSize,
+              });
+              svg.other(markedRect, 'animate', {
+                'data-type': span.marked,
+                attributeName: 'fill',
+                values: (span.marked == 'match'? highlightMatchSequence
+                         : highlightSpanSequence),
+                dur: highlightDuration,
+                repeatCount: 'indefinite',
+                begin: 'indefinite'
+              });
+              chunkFrom = Math.min(bx - markedSpanSize, chunkFrom);
+              chunkTo = Math.max(bx + bw + markedSpanSize, chunkTo);
+              fragmentHeight = Math.max(bh + 2 * markedSpanSize, fragmentHeight);
+            }
+            // .match() removes unconfigured shadows, which were
+            // always showing up as black.
+            // TODO: don't hard-code configured shadowclasses.
+            if (span.shadowClass &&
+                span.shadowClass.match('True_positive|False_positive|False_negative|AnnotationError|AnnotationWarning|AnnotatorNotes|Normalized|AnnotationIncomplete|AnnotationUnconfirmed|rectEditHighlight|EditHighlight_arc|MissingAnnotation|ChangedAnnotation ')) {
+              shadowRect = svg.rect(fragment.group,
+                  bx - rectShadowSize, by - rectShadowSize,
+                  bw + 2 * rectShadowSize, bh + 2 * rectShadowSize, {
+                  'class': 'shadow_' + span.shadowClass,
+                  filter: 'url(#Gaussian_Blur)',
+                  rx: rectShadowRounding,
+                  ry: rectShadowRounding,
+              });
+              chunkFrom = Math.min(bx - rectShadowSize, chunkFrom);
+              chunkTo = Math.max(bx + bw + rectShadowSize, chunkTo);
+              fragmentHeight = Math.max(bh + 2 * rectShadowSize, fragmentHeight);
+            }
+            fragment.rect = svg.rect(fragment.group,
+                bx, by, bw, bh, {
+
+                'class': rectClass,
+                fill: bgColor,
+                stroke: borderColor,
+                rx: Configuration.visual.margin.x,
+                ry: Configuration.visual.margin.y,
+                'data-span-id': span.id,
+                'data-fragment-id': span.segmentedOffsetsMap[fragment.id],
+                'strokeDashArray': span.attributeMerge.dashArray,
+              });
+
+            // TODO XXX: quick nasty hack to allow normalizations
+            // to be marked visually; do something cleaner!
+            if (span.normalized) {
+              $(fragment.rect).addClass(span.normalized);
+            }
+
+            fragment.right = bx + bw; // TODO put it somewhere nicer?
+            if (!(span.shadowClass || span.marked)) {
+              chunkFrom = Math.min(bx, chunkFrom);
+              chunkTo = Math.max(bx + bw, chunkTo);
+              fragmentHeight = Math.max(bh, fragmentHeight);
+            }
+
+            fragment.rectBox = { x: bx, y: by - span.floor, width: bw, height: bh };
+            fragment.height = span.floor + hh + 3 * Configuration.visual.margin.y + Configuration.visual.curlyHeight + Configuration.visual.arcSpacing;
+            var spacedTowerId = fragment.towerId * 2;
+            if (!fragmentHeights[spacedTowerId] || fragmentHeights[spacedTowerId] < fragment.height) {
+              fragmentHeights[spacedTowerId] = fragment.height;
+            }
+            $(fragment.rect).attr('y', yy - Configuration.visual.margin.y - span.floor);
+            if (shadowRect) {
+              $(shadowRect).attr('y', yy - rectShadowSize - Configuration.visual.margin.y - span.floor);
+            }
+            if (markedRect) {
+              $(markedRect).attr('y', yy - markedSpanSize - Configuration.visual.margin.y - span.floor);
+            }
+            if (span.attributeMerge.box === "crossed") {
+              svg.path(fragment.group, svg.createPath().
+                  move(xx, yy - Configuration.visual.margin.y - span.floor).
+                  line(xx + fragment.width,
+                    yy + hh + Configuration.visual.margin.y - span.floor),
+                  { 'class': 'boxcross' });
+              svg.path(fragment.group, svg.createPath().
+                  move(xx + fragment.width, yy - Configuration.visual.margin.y - span.floor).
+                  line(xx, yy + hh + Configuration.visual.margin.y - span.floor),
+                  { 'class': 'boxcross' });
+            }
+            svg.text(fragment.group, x, y - span.floor, data.spanAnnTexts[fragment.glyphedLabelText], { fill: fgColor });
+
+            // Make curlies to show the fragment
+            if (fragment.drawCurly) {
+              var curlyColor = 'grey';
+              if (coloredCurlies) {
+                var spanDesc = spanTypes[span.type];
+                var bgColor = ((spanDesc && spanDesc.bgColor) ||
+                               (spanTypes.SPAN_DEFAULT &&
+                                spanTypes.SPAN_DEFAULT.fgColor) ||
+                               '#000000');
+                curlyColor = Util.adjustColorLightness(bgColor, -0.6);
+              }
+
+              var bottom = yy + hh + Configuration.visual.margin.y - span.floor + 1;
+              svg.path(fragment.group, svg.createPath()
+                  .move(fragment.curly.from, bottom + Configuration.visual.curlyHeight)
+                  .curveC(fragment.curly.from, bottom,
+                    x, bottom + Configuration.visual.curlyHeight,
+                    x, bottom)
+                  .curveC(x, bottom + Configuration.visual.curlyHeight,
+                    fragment.curly.to, bottom,
+                    fragment.curly.to, bottom + Configuration.visual.curlyHeight),
+                {
+                  'class': 'curly',
+                  'stroke': curlyColor,
+                });
+              chunkFrom = Math.min(fragment.curly.from, chunkFrom);
+              chunkTo = Math.max(fragment.curly.to, chunkTo);
+              fragmentHeight = Math.max(Configuration.visual.curlyHeight, fragmentHeight);
+            }
+
+            if (fragment == span.headFragment) {
+              // find the gap to fit the backwards arcs, but only on
+              // head fragment - other fragments don't have arcs
+              $.each(span.incoming, function(arcId, arc) {
+                var leftSpan = data.spans[arc.origin];
+                var origin = leftSpan.headFragment.chunk;
+                var border;
+                if (chunk.index == origin.index) {
+                  hasInternalArcs = true;
+                }
+                if (origin.row) {
+                  var labels = Util.getArcLabels(spanTypes, leftSpan.type, arc.type, relationTypesHash);
+                  if (!labels.length) labels = [arc.type];
+                  if (origin.row.index == rowIndex) {
+                    // same row, but before this
+                    border = origin.translation.x + leftSpan.fragments[leftSpan.fragments.length - 1].right;
+                  } else {
+                    border = Configuration.visual.margin.x + sentNumMargin + rowPadding;
+                  }
+                  var labelNo = Configuration.abbrevsOn ? labels.length - 1 : 0;
+                  var smallestLabelWidth = sizes.arcs.widths[labels[labelNo]] + 2 * minArcSlant;
+                  var gap = currentX + bx - border;
+                  var arcSpacing = smallestLabelWidth - gap;
+                  if (!hasLeftArcs || spacing < arcSpacing) {
+                    spacing = arcSpacing;
+                    spacingChunkId = origin.index + 1;
+                  }
+                  arcSpacing = smallestLabelWidth - bx;
+                  if (!hasLeftArcs || spacingRowBreak < arcSpacing) {
+                    spacingRowBreak = arcSpacing;
+                  }
+                  hasLeftArcs = true;
+                } else {
+                  hasRightArcs = true;
+                }
+              });
+              $.each(span.outgoing, function(arcId, arc) {
+                var leftSpan = data.spans[arc.target];
+                var target = leftSpan.headFragment.chunk;
+                var border;
+                if (target.row) {
+                  var labels = Util.getArcLabels(spanTypes, span.type, arc.type, relationTypesHash);
+                  if (!labels.length) labels = [arc.type];
+                  if (target.row.index == rowIndex) {
+                    // same row, but before this
+                    border = target.translation.x + leftSpan.fragments[leftSpan.fragments.length - 1].right;
+                  } else {
+                    border = Configuration.visual.margin.x + sentNumMargin + rowPadding;
+                  }
+                  var labelNo = Configuration.abbrevsOn ? labels.length - 1 : 0;
+                  var smallestLabelWidth = sizes.arcs.widths[labels[labelNo]] + 2 * minArcSlant;
+                  var gap = currentX + bx - border;
+                  var arcSpacing = smallestLabelWidth - gap;
+                  if (!hasLeftArcs || spacing < arcSpacing) {
+                    spacing = arcSpacing;
+                    spacingChunkId = target.index + 1;
+                  }
+                  arcSpacing = smallestLabelWidth - bx;
+                  if (!hasLeftArcs || spacingRowBreak < arcSpacing) {
+                    spacingRowBreak = arcSpacing;
+                  }
+                  hasLeftArcs = true;
+                } else {
+                  hasRightArcs = true;
+                }
+              });
+            }
+            fragmentHeight += span.floor || Configuration.visual.curlyHeight;
+            if (fragmentHeight > chunkHeight) chunkHeight = fragmentHeight;
+            hasAnnotations = true;
+          }); // fragments
+
+          // positioning of the chunk
+          chunk.right = chunkTo;
+          var textWidth = sizes.texts.widths[chunk.text];
+          chunkHeight += sizes.texts.height;
+          var boxX = -Math.min(chunkFrom, 0);
+          var boxWidth =
+              Math.max(textWidth, chunkTo) -
+              Math.min(0, chunkFrom);
+          // if (hasLeftArcs) {
+            // TODO change this with smallestLeftArc
+            // var spacing = arcHorizontalSpacing - (currentX - lastArcBorder);
+            // arc too small?
+          if (spacing > 0) currentX += spacing;
+          // }
+          var rightBorderForArcs = hasRightArcs ? arcHorizontalSpacing : (hasInternalArcs ? arcSlant : 0);
+
+          var lastX = currentX;
+          var lastRow = row;
+
+          if (chunk.sentence) {
+            while (sentenceNumber < chunk.sentence) {
+              sentenceNumber++;
+              row.arcs = svg.group(row.group, { 'class': 'arcs' });
+              rows.push(row);
+              row = new Row(svg);
+              sentenceToggle = 1 - sentenceToggle;
+              row.backgroundIndex = sentenceToggle;
+              row.index = ++rowIndex;
+            }
+            sentenceToggle = 1 - sentenceToggle;
+          }
+
+          if (chunk.sentence ||
+              currentX + boxWidth + rightBorderForArcs >= canvasWidth - 2 * Configuration.visual.margin.x) {
+            // the chunk does not fit
+            row.arcs = svg.group(row.group, { 'class': 'arcs' });
+            // TODO: related to issue #571
+            // replace arcHorizontalSpacing with a calculated value
+            currentX = Configuration.visual.margin.x + sentNumMargin + rowPadding +
+                (hasLeftArcs ? arcHorizontalSpacing : (hasInternalArcs ? arcSlant : 0)) +
+                spaceWidth;
+            if (hasLeftArcs) {
+              var adjustedCurTextWidth = sizes.texts.widths[chunk.text] + arcHorizontalSpacing;
+              if (adjustedCurTextWidth > maxTextWidth) {
+                maxTextWidth = adjustedCurTextWidth;
+              }
+            }
+            if (spacingRowBreak > 0) {
+              currentX += spacingRowBreak;
+              spacing = 0; // do not center intervening elements
+            }
+
+            // new row
+            rows.push(row);
+
+            svg.remove(chunk.group);
+            row = new Row(svg);
+            row.backgroundIndex = sentenceToggle;
+            row.index = ++rowIndex;
+            svg.add(row.group, chunk.group);
+            chunk.group = row.group.lastElementChild;
+            $(chunk.group).children("g[class='span']").
+              each(function(index, element) {
+                  chunk.fragments[index].group = element;
+              });
+            $(chunk.group).find("rect[data-span-id]").
+              each(function(index, element) {
+                  chunk.fragments[index].rect = element;
+              });
+          }
+
+          // break the text highlights when the row breaks
+          if (row.index !== lastRow.index) {
+            $.each(openTextHighlights, function(textId, textDesc) {
+              if (textDesc[3] != lastX) {
+                var newDesc = [lastRow, textDesc[3], lastX + boxX, textDesc[4]];
+                textMarkedRows.push(newDesc);
+              }
+              textDesc[3] = currentX;
+            });
+          }
+
+          // open text highlights
+          $.each(chunk.markedTextStart, function(textNo, textDesc) {
+            textDesc[3] += currentX + boxX;
+            openTextHighlights[textDesc[0]] = textDesc;
+          });
+
+          // close text highlights
+          $.each(chunk.markedTextEnd, function(textNo, textDesc) {
+            textDesc[3] += currentX + boxX;
+            var startDesc = openTextHighlights[textDesc[0]];
+            delete openTextHighlights[textDesc[0]];
+            markedRow = [row, startDesc[3], textDesc[3], startDesc[4]];
+            textMarkedRows.push(markedRow);
+          });
+
+          // XXX check this - is it used? should it be lastRow?
+          if (hasAnnotations) row.hasAnnotations = true;
+
+          if (chunk.sentence) {
+            row.sentence = ++sentenceNumber;
+          }
+
+          if (spacing > 0) {
+            // if we added a gap, center the intervening elements
+            spacing /= 2;
+            var firstChunkInRow = row.chunks[row.chunks.length - 1];
+            if (firstChunkInRow === undefined) {
+              console.log('warning: firstChunkInRow undefined, chunk:', chunk);
+            } else { // valid firstChunkInRow
+              if (spacingChunkId < firstChunkInRow.index) {
+                spacingChunkId = firstChunkInRow.index + 1;
+              }
+              for (var chunkIndex = spacingChunkId; chunkIndex < chunk.index; chunkIndex++) {
+                var movedChunk = data.chunks[chunkIndex];
+                translate(movedChunk, movedChunk.translation.x + spacing, 0);
+                movedChunk.textX += spacing;
+              }
+            }
+          }
+
+          row.chunks.push(chunk);
+          chunk.row = row;
+
+          translate(chunk, currentX + boxX, 0);
+          chunk.textX = currentX + boxX;
+
+          currentX += boxWidth;
+        }); // chunks
+
+        // finish the last row
+        row.arcs = svg.group(row.group, { 'class': 'arcs' });
+        rows.push(row);
+
+Util.profileEnd('chunks');
+Util.profileStart('arcsPrep');
+
+        var arrows = {};
+        var arrow = makeArrow(defs, 'none');
+        if (arrow) arrows['none'] = arrow;
+
+        var len = fragmentHeights.length;
+        for (var i = 0; i < len; i++) {
+          if (!fragmentHeights[i] || fragmentHeights[i] < Configuration.visual.arcStartHeight) {
+            fragmentHeights[i] = Configuration.visual.arcStartHeight;
+          }
+        }
+
+        // find out how high the arcs have to go
+        $.each(data.arcs, function(arcNo, arc) {
+          arc.jumpHeight = 0;
+          var fromFragment = data.spans[arc.origin].headFragment;
+          var toFragment = data.spans[arc.target].headFragment;
+          if (fromFragment.span.hidden || toFragment.span.hidden) {
+            arc.hidden = true;
+            return;
+          }
+          if (fromFragment.towerId > toFragment.towerId) {
+            var tmp = fromFragment; fromFragment = toFragment; toFragment = tmp;
+          }
+          var from, to;
+          if (fromFragment.chunk.index == toFragment.chunk.index) {
+            from = fromFragment.towerId;
+            to = toFragment.towerId;
+          } else {
+            from = fromFragment.towerId + 1;
+            to = toFragment.towerId - 1;
+          }
+          for (var i = from; i <= to; i++) {
+            if (arc.jumpHeight < fragmentHeights[i * 2]) arc.jumpHeight = fragmentHeights[i * 2];
+          }
+        });
+
+        // sort the arcs
+        data.arcs.sort(function(a, b) {
+          // first write those that have less to jump over
+          var tmp = a.jumpHeight - b.jumpHeight;
+          if (tmp) return tmp < 0 ? -1 : 1;
+          // if equal, then those that span less distance
+          tmp = a.dist - b.dist;
+          if (tmp) return tmp < 0 ? -1 : 1;
+          // if equal, then those where heights of the targets are smaller
+          tmp = data.spans[a.origin].headFragment.height + data.spans[a.target].headFragment.height -
+            data.spans[b.origin].headFragment.height - data.spans[b.target].headFragment.height;
+          if (tmp) return tmp < 0 ? -1 : 1;
+          // if equal, then those with the lower origin
+          tmp = data.spans[a.origin].headFragment.height - data.spans[b.origin].headFragment.height;
+          if (tmp) return tmp < 0 ? -1 : 1;
+          // if equal, they're just equal.
+          return 0;
+        });
+
+        // see which fragments are in each row
+        var heightsStart = 0;
+        var heightsRowsAdded = 0;
+        $.each(rows, function(rowId, row) {
+          var seenFragment = false;
+          row.heightsStart = row.heightsEnd = heightsStart;
+          $.each(row.chunks, function(chunkId, chunk) {
+            if (chunk.lastFragmentIndex !== undefined) {
+              // fragmentful chunk
+              seenFragment = true;
+              var heightsIndex = chunk.lastFragmentIndex * 2 + heightsRowsAdded;
+              if (row.heightsEnd < heightsIndex) {
+                row.heightsEnd = heightsIndex;
+              }
+              var heightsIndex = chunk.firstFragmentIndex * 2 + heightsRowsAdded;
+              if (row.heightsStart > heightsIndex) {
+                row.heightsStart = heightsIndex;
+              }
+            }
+          });
+          fragmentHeights.splice(row.heightsStart, 0, Configuration.visual.arcStartHeight);
+          heightsRowsAdded++;
+
+          row.heightsAdjust = heightsRowsAdded;
+          if (seenFragment) {
+            row.heightsEnd += 2;
+          }
+          heightsStart = row.heightsEnd + 1;
+        });
+
+        // draw the drag arc marker
+        var arrowhead = svg.marker(defs, 'drag_arrow',
+          5, 2.5, 5, 5, 'auto',
+          {
+            markerUnits: 'strokeWidth',
+            'class': 'drag_fill',
+          });
+        svg.polyline(arrowhead, [[0, 0], [5, 2.5], [0, 5], [0.2, 2.5]]);
+        var arcDragArc = svg.path(svg.createPath(), {
+          markerEnd: 'url(#drag_arrow)',
+          'class': 'drag_stroke',
+          fill: 'none',
+          visibility: 'hidden',
+        });
+        dispatcher.post('arcDragArcDrawn', [arcDragArc]);
+
+Util.profileEnd('arcsPrep');
+Util.profileStart('arcs');
+
+        var arcCache = {};
+        // add the arcs
+        $.each(data.arcs, function(arcNo, arc) {
+          if (arc.hidden) return;
+          // separate out possible numeric suffix from type
+          var noNumArcType;
+          var splitArcType;
+          if (arc.type) {
+            splitArcType = arc.type.match(/^(.*?)(\d*)$/);
+            noNumArcType = splitArcType[1];
+          }
+
+          var originSpan = data.spans[arc.origin];
+          var targetSpan = data.spans[arc.target];
+
+          var leftToRight = originSpan.headFragment.towerId < targetSpan.headFragment.towerId;
+          var left, right;
+          if (leftToRight) {
+            left = originSpan.headFragment;
+            right = targetSpan.headFragment;
+          } else {
+            left = targetSpan.headFragment;
+            right = originSpan.headFragment;
+          }
+
+          // fall back on relation types in case we still don't have
+          // an arc description, with final fallback to unnumbered relation
+          var arcDesc = relationTypesHash[arc.type] || relationTypesHash[noNumArcType];
+
+          // if it's not a relationship, see if we can find it in span
+          // descriptions
+          // TODO: might make more sense to reformat this as dict instead
+          // of searching through the list every type
+          var spanDesc = spanTypes[originSpan.type];
+          if (!arcDesc && spanDesc && spanDesc.arcs) {
+            $.each(spanDesc.arcs, function(arcDescNo, arcDescIter) {
+                if (arcDescIter.type == arc.type) {
+                  arcDesc = arcDescIter;
+                }
+              });
+          }
+          // last fall back on unnumbered type if not found in full
+          if (!arcDesc && noNumArcType && noNumArcType != arc.type &&
+            spanDesc && spanDesc.arcs) {
+            $.each(spanDesc.arcs, function(arcDescNo, arcDescIter) {
+                if (arcDescIter.type == noNumArcType) {
+                  arcDesc = arcDescIter;
+                }
+              });
+          }
+          // empty default
+          if (!arcDesc) arcDesc = {};
+
+          var color = ((arcDesc && arcDesc.color) ||
+                       (spanTypes.ARC_DEFAULT && spanTypes.ARC_DEFAULT.color) ||
+                       '#000000');
+          if (color == 'hidden') return;
+          var symmetric = arcDesc && arcDesc.properties && arcDesc.properties.symmetric;
+          var dashArray = arcDesc && arcDesc.dashArray;
+          var arrowHead = ((arcDesc && arcDesc.arrowHead) ||
+                           (spanTypes.ARC_DEFAULT && spanTypes.ARC_DEFAULT.arrowHead) ||
+                           'triangle,5');
+          var labelArrowHead = ((arcDesc && arcDesc.labelArrow) ||
+                                (spanTypes.ARC_DEFAULT && spanTypes.ARC_DEFAULT.labelArrow) ||
+                                'triangle,5');
+
+          // set arc-specific styles
+          var arcRef = [arc.origin, arc.target, arc.type].join(' ');
+          if (styleMap[arcRef]) {
+              if (styleMap[arcRef]['color'] !== undefined) {
+                  color = styleMap[arcRef]['color'];
+              }
+              if (styleMap[arcRef]['symmetric'] !== undefined) {
+                  symmetric = styleMap[arcRef]['symmetric'];
+              }
+              if (styleMap[arcRef]['dashArray'] !== undefined) {
+                  dashArray = styleMap[arcRef]['dashArray'];
+              }
+              if (styleMap[arcRef]['arrowHead'] !== undefined) {
+                  arrowHead = styleMap[arcRef]['arrowHead'];
+              }
+              if (styleMap[arcRef]['labelArrow'] !== undefined) {
+                  labelArrowHead = styleMap[arcRef]['labelArrow'];
+              }
+          }
+
+          arrowHead +=  ',' + color;
+          labelArrowHead += ',' + color;
+
+          var leftBox = rowBBox(left);
+          var rightBox = rowBBox(right);
+          var leftRow = left.chunk.row.index;
+          var rightRow = right.chunk.row.index;
+
+          if (!arrows[arrowHead]) {
+            var arrow = makeArrow(defs, arrowHead);
+            if (arrow) arrows[arrowHead] = arrow;
+          }
+          if (!arrows[labelArrowHead]) {
+            var arrow = makeArrow(defs, labelArrowHead);
+            if (arrow) arrows[labelArrowHead] = arrow;
+          }
+
+          // find the next height
+          var height;
+
+          var fromIndex2, toIndex2;
+          if (left.chunk.index == right.chunk.index) {
+            fromIndex2 = left.towerId * 2 + left.chunk.row.heightsAdjust;
+            toIndex2 = right.towerId * 2 + right.chunk.row.heightsAdjust;
+          } else {
+            fromIndex2 = left.towerId * 2 + 1 + left.chunk.row.heightsAdjust;
+            toIndex2 = right.towerId * 2 - 1 + right.chunk.row.heightsAdjust;
+          }
+          if (!collapseArcSpace) {
+            height = findArcHeight(fromIndex2, toIndex2, fragmentHeights);
+            adjustFragmentHeights(fromIndex2, toIndex2, fragmentHeights, height);
+
+            // Adjust the height to align with pixels when rendered
+
+            // TODO: on at least Chrome, this doesn't make a difference:
+            // the lines come out pixel-width even without it. Check.
+            height += 0.5;
+          }
+          var leftSlantBound, rightSlantBound;
+
+          var chunkReverse = false;
+          var ufoCatcher = originSpan.headFragment.chunk.index == targetSpan.headFragment.chunk.index;
+          if (ufoCatcher) {
+            chunkReverse =
+              leftBox.x + leftBox.width / 2 < rightBox.x + rightBox.width / 2;
+          }
+          var ufoCatcherMod = ufoCatcher ? chunkReverse ? -0.5 : 0.5 : 1;
+
+          for (var rowIndex = leftRow; rowIndex <= rightRow; rowIndex++) {
+            var row = rows[rowIndex];
+            if (row.chunks.length) {
+              row.hasAnnotations = true;
+
+              if (collapseArcSpace) {
+                var fromIndex2R = rowIndex == leftRow ? fromIndex2 : row.heightsStart;
+                var toIndex2R = rowIndex == rightRow ? toIndex2 : row.heightsEnd;
+                height = findArcHeight(fromIndex2R, toIndex2R, fragmentHeights);
+              }
+
+              var arcGroup = svg.group(row.arcs, {
+                  'data-from': arc.origin,
+                  'data-to': arc.target
+              });
+              var from, to;
+
+              if (rowIndex == leftRow) {
+                from = leftBox.x + (chunkReverse ? 0 : leftBox.width);
+              } else {
+                from = sentNumMargin;
+              }
+
+              if (rowIndex == rightRow) {
+                to = rightBox.x + (chunkReverse ? rightBox.width : 0);
+              } else {
+                to = canvasWidth - 2 * Configuration.visual.margin.y;
+              }
+
+              var adjustHeight = true;
+              if (collapseArcs) {
+                var arcCacheKey = arc.type + ' ' + rowIndex + ' ' + from + ' ' + to;
+                if (rowIndex == leftRow) arcCacheKey = left.span.id + ' ' + arcCacheKey;
+                if (rowIndex == rightRow) arcCacheKey += ' ' + right.span.id;
+                var rowHeight = arcCache[arcCacheKey];
+                if (rowHeight !== undefined) {
+                  height = rowHeight;
+                  adjustHeight = false;
+                } else {
+                  arcCache[arcCacheKey] = height;
+                }
+              }
+
+              if (collapseArcSpace && adjustHeight) {
+                adjustFragmentHeights(fromIndex2R, toIndex2R, fragmentHeights, height);
+
+                // Adjust the height to align with pixels when rendered
+
+                // TODO: on at least Chrome, this doesn't make a difference:
+                // the lines come out pixel-width even without it. Check.
+                height += 0.5;
+              }
+
+              var originType = data.spans[arc.origin].type;
+              var arcLabels = Util.getArcLabels(spanTypes, originType, arc.type, relationTypesHash);
+              var labelText = Util.arcDisplayForm(spanTypes, originType, arc.type, relationTypesHash);
+              // if (Configuration.abbrevsOn && !ufoCatcher && arcLabels) {
+              if (Configuration.abbrevsOn && arcLabels) {
+                var labelIdx = 1; // first abbreviation
+                // strictly speaking 2*arcSlant would be needed to allow for
+                // the full-width arcs to fit, but judged unabbreviated text
+                // to be more important than the space for arcs.
+                var maxLength = (to - from) - (arcSlant);
+                while (sizes.arcs.widths[labelText] > maxLength &&
+                       arcLabels[labelIdx]) {
+                  labelText = arcLabels[labelIdx];
+                  labelIdx++;
+                }
+              }
+
+              var shadowGroup;
+              if (arc.shadowClass || arc.marked) {
+                shadowGroup = svg.group(arcGroup);
+              }
+              var options = {
+                'fill': color,
+                'data-arc-role': arc.type,
+                'data-arc-origin': arc.origin,
+                'data-arc-target': arc.target,
+                // TODO: confirm this is unused and remove.
+                //'data-arc-id': arc.id,
+                'data-arc-ed': arc.eventDescId,
+              };
+
+              // construct SVG text, showing possible trailing index
+              // numbers (as in e.g. "Theme2") as subscripts
+              var svgText;
+              if (!splitArcType[2]) {
+                  // no subscript, simple string suffices
+                  svgText = labelText;
+              } else {
+                  // Need to parse out possible numeric suffixes to avoid
+                  // duplicating number in label and its subscript
+                  var splitLabelText = labelText.match(/^(.*?)(\d*)$/);
+                  var noNumLabelText = splitLabelText[1];
+
+                  svgText = svg.createText();
+                  // TODO: to address issue #453, attaching options also
+                  // to spans, not only primary text. Make sure there
+                  // are no problems with this.
+                  svgText.span(noNumLabelText, options);
+                  var subscriptSettings = {
+                    'dy': '0.3em',
+                    'font-size': '80%'
+                  };
+                  // alternate possibility
+  //                 var subscriptSettings = {
+  //                   'baseline-shift': 'sub',
+  //                   'font-size': '80%'
+  //                 };
+                  $.extend(subscriptSettings, options);
+                  svgText.span(splitArcType[2], subscriptSettings);
+              }
+
+              // guess at the correct baseline shift to get vertical centering.
+              // (CSS dominant-baseline can't be used as not all SVG rendereds support it.)
+              var baseline_shift = sizes.arcs.height / 4;
+              var text = svg.text(arcGroup, (from + to) / 2, -height + baseline_shift,
+                                  svgText, options);
+
+              var width = sizes.arcs.widths[labelText];
+              var textBox = {
+                x: (from + to - width) / 2,
+                width: width,
+                y: -height - sizes.arcs.height / 2,
+                height: sizes.arcs.height,
+              }
+              if (arc.marked) {
+                var markedRect = svg.rect(shadowGroup,
+                    textBox.x - markedArcSize, textBox.y - markedArcSize,
+                    textBox.width + 2 * markedArcSize, textBox.height + 2 * markedArcSize, {
+                      // filter: 'url(#Gaussian_Blur)',
+                      'class': "shadow_EditHighlight",
+                      rx: markedArcSize,
+                      ry: markedArcSize,
+                });
+                svg.other(markedRect, 'animate', {
+                  'data-type': arc.marked,
+                  attributeName: 'fill',
+                  values: (arc.marked == 'match' ? highlightMatchSequence
+                           : highlightArcSequence),
+                  dur: highlightDuration,
+                  repeatCount: 'indefinite',
+                  begin: 'indefinite'
+                });
+              }
+              if (arc.shadowClass) {
+                svg.rect(shadowGroup,
+                    textBox.x - arcLabelShadowSize,
+                    textBox.y - arcLabelShadowSize,
+                    textBox.width  + 2 * arcLabelShadowSize,
+                    textBox.height + 2 * arcLabelShadowSize, {
+                      'class': 'shadow_' + arc.shadowClass,
+                      filter: 'url(#Gaussian_Blur)',
+                      rx: arcLabelShadowRounding,
+                      ry: arcLabelShadowRounding,
+                });
+              }
+              var textStart = textBox.x;
+              var textEnd = textBox.x + textBox.width;
+
+              // adjust by margin for arc drawing
+              textStart -= Configuration.visual.arcTextMargin;
+              textEnd += Configuration.visual.arcTextMargin;
+
+              if (from > to) {
+                var tmp = textStart; textStart = textEnd; textEnd = tmp;
+              }
+
+              var path;
+
+              if (roundCoordinates) {
+                // don't ask
+                height = (height|0)+0.5;
+              }
+              if (height > row.maxArcHeight) row.maxArcHeight = height;
+
+              var myArrowHead   = ((styleMap[arcRef] && styleMap[arcRef]['arrowHead']) ||
+                                   (arcDesc && arcDesc.arrowHead) ||
+                                   (spanTypes.ARC_DEFAULT && spanTypes.ARC_DEFAULT.arrowHead));
+              var arrowName = (symmetric ? myArrowHead || 'none' :
+                    (leftToRight ? 'none' : myArrowHead || 'triangle,5')
+                  ) + ',' + color;
+              var arrowType = arrows[arrowName];
+              var arrowDecl = arrowType && ('url(#' + arrowType + ')');
+
+              var arrowAtLabelAdjust = 0;
+              var labelArrowDecl = null;
+              var myLabelArrowHead = ((styleMap[arcRef] && styleMap[arcRef]['labelArrow']) ||
+                                      (arcDesc && arcDesc.labelArrow) ||
+                                      (spanTypes.ARC_DEFAULT && spanTypes.ARC_DEFAULT.labelArrow));
+              if (myLabelArrowHead) {
+                var labelArrowName = (leftToRight ?
+                    symmetric && myLabelArrowHead || 'none' :
+                    myLabelArrowHead || 'triangle,5') + ',' + color;
+                var labelArrowSplit = labelArrowName.split(',');
+                arrowAtLabelAdjust = labelArrowSplit[0] != 'none' && parseInt(labelArrowSplit[1], 10) || 0;
+                var labelArrowType = arrows[labelArrowName];
+                var labelArrowDecl = labelArrowType && ('url(#' + labelArrowType + ')');
+                if (ufoCatcher) arrowAtLabelAdjust = -arrowAtLabelAdjust;
+              }
+              var arrowStart = textStart - arrowAtLabelAdjust;
+              path = svg.createPath().move(arrowStart, -height);
+              if (rowIndex == leftRow) {
+                var cornerx = from + ufoCatcherMod * arcSlant;
+                // for normal cases, should not be past textStart even if narrow
+                if (!ufoCatcher && cornerx > arrowStart - 1) { cornerx = arrowStart - 1; }
+                if (smoothArcCurves) {
+                  var controlx = ufoCatcher ? cornerx + 2*ufoCatcherMod*reverseArcControlx : smoothArcSteepness*from+(1-smoothArcSteepness)*cornerx;
+                  var endy = leftBox.y + (leftToRight || arc.equiv ? leftBox.height / 2 : Configuration.visual.margin.y);
+                  // no curving for short lines covering short vertical
+                  // distances, the arrowheads can go off (#925)
+                  if (Math.abs(-height-endy) < 2 &&
+                      Math.abs(cornerx-from) < 5) {
+                    endy = -height;
+                  }
+                  line = path.line(cornerx, -height).
+                      curveQ(controlx, -height, from, endy);
+                } else {
+                  path.line(cornerx, -height).
+                      line(from, leftBox.y + (leftToRight || arc.equiv ? leftBox.height / 2 : Configuration.visual.margin.y));
+                }
+              } else {
+                path.line(from, -height);
+              }
+              svg.path(arcGroup, path, {
+                  markerEnd: arrowDecl,
+                  markerStart: labelArrowDecl,
+                  style: 'stroke: ' + color,
+                  'strokeDashArray': dashArray,
+              });
+              if (arc.marked) {
+                svg.path(shadowGroup, path, {
+                    'class': 'shadow_EditHighlight_arc',
+                    strokeWidth: markedArcStroke,
+                    'strokeDashArray': dashArray,
+                });
+                svg.other(markedRect, 'animate', {
+                  'data-type': arc.marked,
+                  attributeName: 'fill',
+                  values: (arc.marked == 'match' ? highlightMatchSequence
+                           : highlightArcSequence),
+                  dur: highlightDuration,
+                  repeatCount: 'indefinite',
+                  begin: 'indefinite'
+                });
+              }
+              if (arc.shadowClass) {
+                svg.path(shadowGroup, path, {
+                    'class': 'shadow_' + arc.shadowClass,
+                    strokeWidth: shadowStroke,
+                    'strokeDashArray': dashArray,
+                });
+              }
+              if (!symmetric) {
+                myArrowHead = ((arcDesc && arcDesc.arrowHead) ||
+                               (spanTypes.ARC_DEFAULT && spanTypes.ARC_DEFAULT.arrowHead));
+                arrowName = (leftToRight ?
+                    myArrowHead || 'triangle,5' :
+                    'none') + ',' + color;
+              }
+              var arrowType = arrows[arrowName];
+              var arrowDecl = arrowType && ('url(#' + arrowType + ')');
+
+              var arrowAtLabelAdjust = 0;
+              var labelArrowDecl = null;
+              var myLabelArrowHead = ((arcDesc && arcDesc.labelArrow) ||
+                                      (spanTypes.ARC_DEFAULT && spanTypes.ARC_DEFAULT.labelArrow));
+              if (myLabelArrowHead) {
+                var labelArrowName = (leftToRight ?
+                    myLabelArrowHead || 'triangle,5' :
+                    symmetric && myLabelArrowHead || 'none') + ',' + color;
+                var labelArrowSplit = labelArrowName.split(',');
+                arrowAtLabelAdjust = labelArrowSplit[0] != 'none' && parseInt(labelArrowSplit[1], 10) || 0;
+                var labelArrowType = arrows[labelArrowName];
+                var labelArrowDecl = labelArrowType && ('url(#' + labelArrowType + ')');
+                if (ufoCatcher) arrowAtLabelAdjust = -arrowAtLabelAdjust;
+              }
+              var arrowEnd = textEnd + arrowAtLabelAdjust;
+              path = svg.createPath().move(arrowEnd, -height);
+              if (rowIndex == rightRow) {
+                var cornerx  = to - ufoCatcherMod * arcSlant;
+                // TODO: duplicates above in part, make funcs
+                // for normal cases, should not be past textEnd even if narrow
+                if (!ufoCatcher && cornerx < arrowEnd + 1) { cornerx = arrowEnd + 1; }
+                if (smoothArcCurves) {
+                  var controlx = ufoCatcher ? cornerx - 2*ufoCatcherMod*reverseArcControlx : smoothArcSteepness*to+(1-smoothArcSteepness)*cornerx;
+                  var endy = rightBox.y + (leftToRight && !arc.equiv ? Configuration.visual.margin.y : rightBox.height / 2);
+                  // no curving for short lines covering short vertical
+                  // distances, the arrowheads can go off (#925)
+                  if (Math.abs(-height-endy) < 2 &&
+                      Math.abs(cornerx-to) < 5) {
+                    endy = -height;
+                  }
+                  path.line(cornerx, -height).
+                      curveQ(controlx, -height, to, endy);
+                } else {
+                  path.line(cornerx, -height).
+                      line(to, rightBox.y + (leftToRight && !arc.equiv ? Configuration.visual.margin.y : rightBox.height / 2));
+                }
+              } else {
+                path.line(to, -height);
+              }
+              svg.path(arcGroup, path, {
+                  markerEnd: arrowDecl,
+                  markerStart: labelArrowDecl,
+                  style: 'stroke: ' + color,
+                  'strokeDashArray': dashArray,
+              });
+              if (arc.marked) {
+                svg.path(shadowGroup, path, {
+                    'class': 'shadow_EditHighlight_arc',
+                    strokeWidth: markedArcStroke,
+                    'strokeDashArray': dashArray,
+                });
+              }
+              if (shadowGroup) {
+                svg.path(shadowGroup, path, {
+                    'class': 'shadow_' + arc.shadowClass,
+                    strokeWidth: shadowStroke,
+                    'strokeDashArray': dashArray,
+                });
+              }
+            }
+          } // arc rows
+        }); // arcs
+
+Util.profileEnd('arcs');
+Util.profileStart('fragmentConnectors');
+
+        $.each(data.spans, function(spanNo, span) {
+          var numConnectors = span.fragments.length - 1;
+          for (var connectorNo = 0; connectorNo < numConnectors; connectorNo++) {
+            var left = span.fragments[connectorNo];
+            var right = span.fragments[connectorNo + 1];
+
+            var leftBox = rowBBox(left);
+            var rightBox = rowBBox(right);
+            var leftRow = left.chunk.row.index;
+            var rightRow = right.chunk.row.index;
+
+            for (var rowIndex = leftRow; rowIndex <= rightRow; rowIndex++) {
+              var row = rows[rowIndex];
+              if (row.chunks.length) {
+                row.hasAnnotations = true;
+
+                if (rowIndex == leftRow) {
+                  from = leftBox.x + leftBox.width;
+                } else {
+                  from = sentNumMargin;
+                }
+
+                if (rowIndex == rightRow) {
+                  to = rightBox.x;
+                } else {
+                  to = canvasWidth - 2 * Configuration.visual.margin.y;
+                }
+
+                var height = leftBox.y + leftBox.height - Configuration.visual.margin.y;
+                if (roundCoordinates) {
+                  // don't ask
+                  height = (height|0)+0.5;
+                }
+
+                var path = svg.createPath().move(from, height).line(to, height);
+                svg.path(row.arcs, path, {
+                  style: 'stroke: ' + fragmentConnectorColor,
+                  'strokeDashArray': fragmentConnectorDashArray
+                });
+              }
+            } // rowIndex
+          } // connectorNo
+        }); // spans
+
+Util.profileEnd('fragmentConnectors');
+Util.profileStart('rows');
+
+        // position the rows
+        var y = Configuration.visual.margin.y;
+        var sentNumGroup = svg.group({'class': 'sentnum'});
+        var currentSent;
+        $.each(rows, function(rowId, row) {
+          // find the maximum fragment height
+          $.each(row.chunks, function(chunkId, chunk) {
+            $.each(chunk.fragments, function(fragmentId, fragment) {
+              if (row.maxSpanHeight < fragment.height) row.maxSpanHeight = fragment.height;
+            });
+          });
+          if (row.sentence) {
+            currentSent = row.sentence;
+          }
+          // SLOW (#724) and replaced with calculations:
+          //
+          // var rowBox = row.group.getBBox();
+          // // Make it work on IE
+          // rowBox = { x: rowBox.x, y: rowBox.y, height: rowBox.height, width: rowBox.width };
+          // // Make it work on Firefox and Opera
+          // if (rowBox.height == -Infinity) {
+          //   rowBox = { x: 0, y: 0, height: 0, width: 0 };
+          // }
+
+          // XXX TODO HACK: find out where 5 and 1.5 come from!
+          // This is the fix for #724, but the numbers are guessed.
+          var rowBoxHeight = Math.max(row.maxArcHeight + 5, row.maxSpanHeight + 1.5); // XXX TODO HACK: why 5, 1.5?
+          if (row.hasAnnotations) {
+            // rowBox.height = -rowBox.y + rowSpacing;
+            rowBoxHeight += rowSpacing + 1.5; // XXX TODO HACK: why 1.5?
+          } else {
+            rowBoxHeight -= 5; // XXX TODO HACK: why -5?
+          }
+
+          rowBoxHeight += rowPadding;
+          var bgClass;
+          if (data.markedSent[currentSent]) {
+            // specifically highlighted
+            bgClass = 'backgroundHighlight';
+          } else if (Configuration.textBackgrounds == "striped") {
+            // give every other sentence a different bg class
+            bgClass = 'background'+ row.backgroundIndex;
+          } else {
+            // plain "standard" bg
+            bgClass = 'background0';
+          }
+          svg.rect(backgroundGroup,
+            0, y + sizes.texts.y + sizes.texts.height,
+            canvasWidth, rowBoxHeight + sizes.texts.height + 1, {
+            'class': bgClass,
+          });
+          y += rowBoxHeight;
+          y += sizes.texts.height;
+          row.textY = y - rowPadding;
+          if (row.sentence) {
+            var sentence_hash = new URLHash(coll, doc, { focus: [[ 'sent', row.sentence ]] } );
+            var link = svg.link(sentNumGroup, sentence_hash.getHash());
+            var text = svg.text(link, sentNumMargin - Configuration.visual.margin.x, y - rowPadding,
+                '' + row.sentence, { 'data-sent': row.sentence });
+            var sentComment = data.sentComment[row.sentence];
+            if (sentComment) {
+              var box = text.getBBox();
+              svg.remove(text);
+              // TODO: using rectShadowSize, but this shadow should
+              // probably have its own setting for shadow size
+              shadowRect = svg.rect(sentNumGroup,
+                  box.x - rectShadowSize, box.y - rectShadowSize,
+                  box.width + 2 * rectShadowSize, box.height + 2 * rectShadowSize, {
+
+                  'class': 'shadow_' + sentComment.type,
+                  filter: 'url(#Gaussian_Blur)',
+                  rx: rectShadowRounding,
+                  ry: rectShadowRounding,
+                  'data-sent': row.sentence,
+              });
+              var text = svg.text(sentNumGroup, sentNumMargin - Configuration.visual.margin.x, y - rowPadding,
+                  '' + row.sentence, { 'data-sent': row.sentence });
+            }
+          }
+
+          var rowY = y - rowPadding;
+          if (roundCoordinates) {
+            rowY = rowY|0;
+          }
+          translate(row, 0, rowY);
+          y += Configuration.visual.margin.y;
+        });
+        y += Configuration.visual.margin.y;
+
+Util.profileEnd('rows');
+Util.profileStart('chunkFinish');
+
+        // chunk index sort functions for overlapping fragment drawing
+        // algorithm; first for left-to-right pass, sorting primarily
+        // by start offset, second for right-to-left pass by end
+        // offset. Secondary sort by fragment length in both cases.
+        var currentChunk;
+        var lrChunkComp = function(a,b) {
+          var ac = currentChunk.fragments[a];
+          var bc = currentChunk.fragments[b]
+          var startDiff = Util.cmp(ac.from, bc.from);
+          return startDiff != 0 ? startDiff : Util.cmp(bc.to-bc.from, ac.to-ac.from);
+        }
+        var rlChunkComp = function(a,b) {
+          var ac = currentChunk.fragments[a];
+          var bc = currentChunk.fragments[b]
+          var endDiff = Util.cmp(bc.to, ac.to);
+          return endDiff != 0 ? endDiff : Util.cmp(bc.to-bc.from, ac.to-ac.from);
+        }
+
+        var sentenceText = null;
+        $.each(data.chunks, function(chunkNo, chunk) {
+          // context for sort
+          currentChunk = chunk;
+
+          // text rendering
+          if (chunk.sentence) {
+            if (sentenceText) {
+              // svg.text(textGroup, sentenceText); // avoids jQuerySVG bug
+              svg.text(textGroup, 0, 0, sentenceText);
+            }
+            sentenceText = null;
+          }
+          if (!sentenceText) {
+            sentenceText = svg.createText();
+          }
+          var nextChunk = data.chunks[chunkNo + 1];
+          var nextSpace = nextChunk ? nextChunk.space : '';
+          sentenceText.span(chunk.text + nextSpace, {
+            x: chunk.textX,
+            y: chunk.row.textY,
+            'data-chunk-id': chunk.index
+          });
+
+          // chunk backgrounds
+          if (chunk.fragments.length) {
+            var orderedIdx = [];
+            for (var i=chunk.fragments.length-1; i>=0; i--) {
+              orderedIdx.push(i);
+            }
+
+            // Mark entity nesting height/depth (number of
+            // nested/nesting entities). To account for crossing
+            // brackets in a (mostly) reasonable way, determine
+            // depth/height separately in a left-to-right traversal
+            // and a right-to-left traversal.
+            orderedIdx.sort(lrChunkComp);
+
+            var openFragments = [];
+            for(var i=0; i<orderedIdx.length; i++) {
+              var current = chunk.fragments[orderedIdx[i]];
+              current.nestingHeightLR = 0;
+              current.nestingDepthLR = 0;
+              var stillOpen = [];
+              for(var o=0; o<openFragments.length; o++) {
+                if(openFragments[o].to > current.from) {
+                  stillOpen.push(openFragments[o]);
+                  openFragments[o].nestingHeightLR++;
+                }
+              }
+              openFragments = stillOpen;
+              current.nestingDepthLR=openFragments.length;
+              openFragments.push(current);
+            }
+
+            // re-sort for right-to-left traversal by end position
+            orderedIdx.sort(rlChunkComp);
+
+            openFragments = [];
+            for(var i=0; i<orderedIdx.length; i++) {
+              var current = chunk.fragments[orderedIdx[i]];
+              current.nestingHeightRL = 0;
+              current.nestingDepthRL = 0;
+              var stillOpen = [];
+              for(var o=0; o<openFragments.length; o++) {
+                if(openFragments[o].from < current.to) {
+                  stillOpen.push(openFragments[o]);
+                  openFragments[o].nestingHeightRL++;
+                }
+              }
+              openFragments = stillOpen;
+              current.nestingDepthRL=openFragments.length;
+              openFragments.push(current);
+            }
+
+            // the effective depth and height are the max of those
+            // for the left-to-right and right-to-left traversals.
+            for(var i=0; i<orderedIdx.length; i++) {
+              var c = chunk.fragments[orderedIdx[i]];
+              c.nestingHeight = c.nestingHeightLR > c.nestingHeightRL ? c.nestingHeightLR : c.nestingHeightRL;
+              c.nestingDepth = c.nestingDepthLR > c.nestingDepthRL ? c.nestingDepthLR : c.nestingDepthRL;
+            }
+
+            // Re-order by nesting height and draw in order
+            orderedIdx.sort(function(a,b) { return Util.cmp(chunk.fragments[b].nestingHeight, chunk.fragments[a].nestingHeight) });
+
+            for(var i=0; i<chunk.fragments.length; i++) {
+              var fragment = chunk.fragments[orderedIdx[i]];
+              var spanDesc = spanTypes[fragment.span.type];
+              var bgColor = ((spanDesc && spanDesc.bgColor) ||
+                             (spanTypes.SPAN_DEFAULT && spanTypes.SPAN_DEFAULT.bgColor) ||
+                             '#ffffff');
+              if (fragment.span.hidden) continue;
+
+              // Tweak for nesting depth/height. Recognize just three
+              // levels for now: normal, nested, and nesting, where
+              // nested+nesting yields normal. (Currently testing
+              // minor tweak: don't shrink for depth 1 as the nesting
+              // highlight will grow anyway [check nestingDepth > 1])
+              var shrink = 0;
+              if(fragment.nestingDepth > 1 && fragment.nestingHeight == 0) {
+                  shrink = 1;
+              } else if(fragment.nestingDepth == 0 && fragment.nestingHeight > 0) {
+                  shrink = -1;
+              }
+              var yShrink = shrink * nestingAdjustYStepSize;
+              var xShrink = shrink * nestingAdjustXStepSize;
+              // bit lighter
+              var lightBgColor = Util.adjustColorLightness(bgColor, 0.8);
+              // tweak for Y start offset (and corresponding height
+              // reduction): text rarely hits font max height, so this
+              // tends to look better
+              var yStartTweak = 1;
+              // store to have same mouseover highlight without recalc
+              fragment.highlightPos = {
+                  x: chunk.textX + fragment.curly.from + xShrink,
+                  y: chunk.row.textY + sizes.texts.y + yShrink + yStartTweak,
+                  w: fragment.curly.to - fragment.curly.from - 2*xShrink,
+                  h: sizes.texts.height - 2*yShrink - yStartTweak,
+              };
+              svg.rect(highlightGroup,
+                  fragment.highlightPos.x, fragment.highlightPos.y,
+                  fragment.highlightPos.w, fragment.highlightPos.h,
+                  { fill: lightBgColor, //opacity:1,
+                    rx: highlightRounding.x,
+                    ry: highlightRounding.y,
+                  });
+            }
+          }
+        });
+        if (sentenceText) {
+          // svg.text(textGroup, sentenceText); // avoids jQuerySVG bug
+          svg.text(textGroup, 0, 0, sentenceText);
+        }
+
+        // draw the markedText
+        $.each(textMarkedRows, function(textRowNo, textRowDesc) { // row, from, to
+          var textHighlight = svg.rect(highlightGroup,
+              textRowDesc[1] - 2, textRowDesc[0].textY - sizes.fragments.height,
+              textRowDesc[2] - textRowDesc[1] + 4, sizes.fragments.height + 4,
+              { fill: 'yellow' } // TODO: put into css file, as default - turn into class
+          );
+          // NOTE: changing highlightTextSequence here will give
+          // different-colored highlights
+          // TODO: entirely different settings for non-animations?
+          var markedType = textRowDesc[3];
+          svg.other(textHighlight, 'animate', {
+            'data-type': markedType,
+            attributeName: 'fill',
+            values: (markedType == 'match' ? highlightMatchSequence
+                     : highlightTextSequence),
+            dur: highlightDuration,
+            repeatCount: 'indefinite',
+            begin: 'indefinite'
+          });
+        });
+
+
+Util.profileEnd('chunkFinish');
+Util.profileStart('finish');
+
+        svg.path(sentNumGroup, svg.createPath().
+          move(sentNumMargin, 0).
+          line(sentNumMargin, y));
+
+        // resize the SVG
+        var width = maxTextWidth + sentNumMargin + 2 * Configuration.visual.margin.x + 1;
+        if (width > canvasWidth) canvasWidth = width;
+
+        $svg.width(canvasWidth);
+        $svg.height(y);
+        $svgDiv.height(y);
+
+Util.profileEnd('finish');
+Util.profileEnd('render');
+Util.profileReport();
+
+
+        drawing = false;
+        if (redraw) {
+          redraw = false;
+          renderDataReal();
+        }
+        $svg.find('animate').each(function() {
+          if (this.beginElement) { // protect against non-SMIL browsers
+            this.beginElement();
+          }
+        });
+        dispatcher.post('doneRendering', [coll, doc, args]);
+      };
+
+      var renderErrors = {
+        unableToReadTextFile: true,
+        annotationFileNotFound: true,
+        isDirectoryError: true
+      };
+      var renderData = function(sourceData) {
+        Util.profileEnd('invoke getDocument');
+        if (sourceData && sourceData.exception) {
+          if (renderErrors[sourceData.exception]) {
+            dispatcher.post('renderError:' + sourceData.exception, [sourceData]);
+          } else {
+            dispatcher.post('unknownError', [sourceData.exception]);
+          }
+        } else {
+          // Fill in default values that don't necessarily go over the protocol
+          if (sourceData) {
+            setSourceDataDefaults(sourceData);
+          }
+
+          dispatcher.post('startedRendering', [coll, doc, args]);
+          dispatcher.post('spin');
+          setTimeout(function() {
+              try {
+                renderDataReal(sourceData);
+              } catch (e) {
+                // We are sure not to be drawing anymore, reset the state
+                drawing = false;
+                // TODO: Hook printout into dispatch elsewhere?
+                console.warn('Rendering terminated due to: ' + e, e.stack);
+                dispatcher.post('renderError: Fatal', [sourceData, e]);
+              }
+              dispatcher.post('unspin');
+          }, 0);
+        }
+      };
+
+      var renderDocument = function() {
+        Util.profileStart('invoke getDocument');
+        dispatcher.post('ajax', [{
+            action: 'getDocument',
+            collection: coll,
+            'document': doc,
+          }, 'renderData', {
+            collection: coll,
+            'document': doc
+          }]);
+      };
+
+      var triggerRender = function() {
+        if (svg && ((isRenderRequested && isCollectionLoaded) || requestedData) && Util.areFontsLoaded()) {
+          isRenderRequested = false;
+          if (requestedData) {
+
+Util.profileClear();
+Util.profileStart('before render');
+
+            renderData(requestedData);
+          } else if (doc.length) {
+
+Util.profileClear();
+Util.profileStart('before render');
+
+            renderDocument();
+          } else {
+            dispatcher.post(0, 'renderError:noFileSpecified');
+          }
+        }
+      };
+
+      var requestRenderData = function(sourceData) {
+        requestedData = sourceData;
+        triggerRender();
+      };
+
+      var collectionChanged = function() {
+        isCollectionLoaded = false;
+      };
+
+      var gotCurrent = function(_coll, _doc, _args, reloadData) {
+        coll = _coll;
+        doc  = _doc;
+        args = _args;
+        if (reloadData) {
+          isRenderRequested = true;
+          triggerRender();
+        }
+      };
+
+
+      // event handlers
+
+      var highlight, highlightArcs, highlightSpans, commentId;
+
+      var onMouseOver = function(evt) {
+        var target = $(evt.target);
+        var id;
+        if (id = target.attr('data-span-id')) {
+          commentId = id;
+          var span = data.spans[id];
+          dispatcher.post('displaySpanComment', [
+              evt, target, id, span.type, span.attributeText,
+              span.text,
+              span.comment && span.comment.text,
+              span.comment && span.comment.type,
+              span.normalizations]);
+
+          var spanDesc = spanTypes[span.type];
+          var bgColor = ((spanDesc && spanDesc.bgColor) ||
+                         (spanTypes.SPAN_DEFAULT && spanTypes.SPAN_DEFAULT.bgColor) ||
+                         '#ffffff');
+          if (span.hidden) return;
+          highlight = [];
+          $.each(span.fragments, function(fragmentNo, fragment) {
+            highlight.push(svg.rect(highlightGroup,
+                                 fragment.highlightPos.x, fragment.highlightPos.y,
+                                 fragment.highlightPos.w, fragment.highlightPos.h,
+                                 { 'fill': bgColor, opacity:0.75,
+                                   rx: highlightRounding.x,
+                                   ry: highlightRounding.y,
+                                 }));
+          });
+
+          if (that.arcDragOrigin) {
+            target.parent().addClass('highlight');
+          } else {
+            var equivs = {};
+            var spans = {};
+            spans[id] = true;
+            var spanIds = [];
+            // find all arcs, normal and equiv. Equivs need to go far (#1023)
+            var addArcAndSpan = function(arc, span) {
+              if (arc.equiv) {
+                equivs[arc.eventDescId.substr(0, arc.eventDescId.indexOf('*', 2) + 1)] = true;
+                var eventDesc = data.eventDescs[arc.eventDescId];
+                $.each(eventDesc.leftSpans.concat(eventDesc.rightSpans), function(ospanId, ospan) {
+                  spans[ospan] = true;
+                });
+              } else {
+                spans[arc.origin] = true;
+              }
+            }
+            $.each(span.incoming, function(arcNo, arc) {
+                addArcAndSpan(arc, arc.origin);
+            });
+            $.each(span.outgoing, function(arcNo, arc) {
+                addArcAndSpan(arc, arc.target);
+            });
+            var equivSelector = [];
+            $.each(equivs, function(equiv, dummy) {
+              equivSelector.push('[data-arc-ed^="' + equiv + '"]');
+            });
+
+            highlightArcs = $svg.
+                find(equivSelector.join(', ')).
+                parent().
+                add('g[data-from="' + id + '"], g[data-to="' + id + '"]' + equivSelector).
+                addClass('highlight');
+
+            $.each(spans, function(spanId, dummy) {
+                spanIds.push('rect[data-span-id="' + spanId + '"]');
+            });
+            highlightSpans = $svg.
+                find(spanIds.join(', ')).
+                parent().
+                addClass('highlight');
+          }
+          forceRedraw();
+        } else if (!that.arcDragOrigin && (id = target.attr('data-arc-role'))) {
+          var originSpanId = target.attr('data-arc-origin');
+          var targetSpanId = target.attr('data-arc-target');
+          var role = target.attr('data-arc-role');
+          var symmetric = (relationTypesHash &&
+                           relationTypesHash[role] &&
+                           relationTypesHash[role].properties &&
+                           relationTypesHash[role].properties.symmetric);
+          // NOTE: no commentText, commentType for now
+          var arcEventDescId = target.attr('data-arc-ed');
+          var commentText = '';
+          var commentType = '';
+          var arcId;
+          if (arcEventDescId) {
+            var eventDesc = data.eventDescs[arcEventDescId];
+            var comment = eventDesc.comment;
+            if (comment) {
+              commentText = comment.text;
+              commentType = comment.type;
+              if (commentText == '' && commentType) {
+                  // default to type if missing text
+                  commentText = commentType;
+              }
+            }
+            if (eventDesc.relation) {
+              // among arcs, only ones corresponding to relations have
+              // "independent" IDs
+              arcId = arcEventDescId;
+            }
+          }
+          var originSpanType = data.spans[originSpanId].type || '';
+          var targetSpanType = data.spans[targetSpanId].type || '';
+          dispatcher.post('displayArcComment', [
+              evt, target, symmetric, arcId,
+              originSpanId, originSpanType, role,
+              targetSpanId, targetSpanType,
+              commentText, commentType]);
+          highlightArcs = $svg.
+              find('g[data-from="' + originSpanId + '"][data-to="' + targetSpanId + '"]').
+              addClass('highlight');
+          highlightSpans = $($svg).
+              find('rect[data-span-id="' + originSpanId + '"], rect[data-span-id="' + targetSpanId + '"]').
+              parent().
+              addClass('highlight');
+        } else if (id = target.attr('data-sent')) {
+          var comment = data.sentComment[id];
+          if (comment) {
+            dispatcher.post('displaySentComment', [evt, target, comment.text, comment.type]);
+          }
+        }
+      };
+
+      var onMouseOut = function(evt) {
+        var target = $(evt.target);
+        target.removeClass('badTarget');
+        dispatcher.post('hideComment');
+        if (highlight) {
+          $.each(highlight, function() {
+            svg.remove(this);
+          });
+          highlight = undefined;
+        }
+        if (highlightSpans) {
+          highlightArcs.removeClass('highlight');
+          highlightSpans.removeClass('highlight');
+          highlightSpans = undefined;
+        }
+        forceRedraw();
+      };
+
+      var setAbbrevs = function(_abbrevsOn) {
+        // TODO: this is a slightly weird place to tweak the configuration
+        Configuration.abbrevsOn = _abbrevsOn;
+        dispatcher.post('configurationChanged');
+      }
+
+      var setTextBackgrounds = function(_textBackgrounds) {
+        Configuration.textBackgrounds = _textBackgrounds;
+        dispatcher.post('configurationChanged');
+      }
+
+      var setLayoutDensity = function(_density) {
+        //dispatcher.post('messages', [[['Setting layout density ' + _density, 'comment']]]);
+        // TODO: store standard settings instead of hard-coding
+        // them here (again)
+        if (_density < 2) {
+          // dense
+          Configuration.visual.margin = { x: 1, y: 0 };
+          Configuration.visual.boxSpacing = 1;
+          Configuration.visual.curlyHeight = 1;
+          Configuration.visual.arcSpacing = 7;
+          Configuration.visual.arcStartHeight = 18
+        } else if(_density > 2) {
+          // spacious
+          Configuration.visual.margin = { x: 2, y: 1 };
+          Configuration.visual.boxSpacing = 3;
+          Configuration.visual.curlyHeight = 6;
+          Configuration.visual.arcSpacing = 12;
+          Configuration.visual.arcStartHeight = 23;
+        } else {
+          // standard
+          Configuration.visual.margin = { x: 2, y: 1 };
+          Configuration.visual.boxSpacing = 1;
+          Configuration.visual.curlyHeight = 4;
+          Configuration.visual.arcSpacing = 9;
+          Configuration.visual.arcStartHeight = 19;
+        }
+        dispatcher.post('configurationChanged');
+      }
+
+      var setSvgWidth = function(_width) {
+        $svgDiv.width(_width);
+        if (Configuration.svgWidth != _width) {
+          Configuration.svgWidth = _width;
+          dispatcher.post('configurationChanged');
+        }
+      }
+
+      $svgDiv = $($svgDiv).hide();
+
+      // register event listeners
+      var registerHandlers = function(element, events) {
+        $.each(events, function(eventNo, eventName) {
+            element.bind(eventName,
+              function(evt) {
+                dispatcher.post(eventName, [evt], 'all');
+              }
+            );
+        });
+      };
+      registerHandlers($svgDiv, [
+          'mouseover', 'mouseout', 'mousemove',
+          'mouseup', 'mousedown',
+          'dragstart',
+          'dblclick', 'click'
+      ]);
+      registerHandlers($(document), [
+          'keydown', 'keypress',
+          'touchstart', 'touchend'
+      ]);
+      registerHandlers($(window), [
+          'resize'
+      ]);
+
+      // create the svg wrapper
+      $svgDiv.svg({
+          onLoad: function(_svg) {
+              that.svg = svg = _svg;
+              $svg = $(svg._svg);
+
+              /* XXX HACK REMOVED - not efficient?
+
+              // XXX HACK to allow off-DOM SVG element creation
+              // we need to replace the jQuery SVG's _makeNode function
+              // with a modified one.
+              // Be aware of potential breakage upon jQuery SVG upgrade.
+              svg._makeNode = function(parent, name, settings) {
+                  // COMMENTED OUT: parent = parent || this._svg;
+                  var node = this._svg.ownerDocument.createElementNS($.svg.svgNS, name);
+                  for (var name in settings) {
+                    var value = settings[name];
+                    if (value != null && value != null &&
+                        (typeof value != 'string' || value != '')) {
+                      node.setAttribute($.svg._attrNames[name] || name, value);
+                    }
+                  }
+                  // ADDED IN:
+                  if (parent)
+                    parent.appendChild(node);
+                  return node;
+                };
+              */
+
+              triggerRender();
+          }
+      });
+
+      var loadSpanTypes = function(types) {
+        $.each(types, function(typeNo, type) {
+          if (type) {
+            spanTypes[type.type] = type;
+            var children = type.children;
+            if (children && children.length) {
+              loadSpanTypes(children);
+            }
+          }
+        });
+      }
+
+      var loadAttributeTypes = function(response_types) {
+        var processed = {};
+        $.each(response_types, function(aTypeNo, aType) {
+          processed[aType.type] = aType;
+          // count the values; if only one, it's a boolean attribute
+          var values = [];
+          for (var i in aType.values) {
+            if (aType.values.hasOwnProperty(i)) {
+              values.push(i);
+            }
+          }
+          if (values.length == 1) {
+            aType.bool = values[0];
+          }
+        });
+        return processed;
+      }
+
+      var loadRelationTypes = function(relation_types) {
+        $.each(relation_types, function(relTypeNo, relType) {
+          if (relType) {
+            relationTypesHash[relType.type] = relType;
+            var children = relType.children;
+            if (children && children.length) {
+              loadRelationTypes(children);
+            }
+          }
+        });
+      }
+
+      var collectionLoaded = function(response) {
+        if (!response.exception) {
+          setCollectionDefaults(response);
+          eventAttributeTypes = loadAttributeTypes(response.event_attribute_types);
+          entityAttributeTypes = loadAttributeTypes(response.entity_attribute_types);
+          spanTypes = {};
+          loadSpanTypes(response.entity_types);
+          loadSpanTypes(response.event_types);
+          loadSpanTypes(response.unconfigured_types);
+          relationTypesHash = {};
+          loadRelationTypes(response.relation_types);
+          loadRelationTypes(response.unconfigured_types);
+          // TODO XXX: isn't the following completely redundant with
+          // loadRelationTypes?
+          $.each(response.relation_types, function(relTypeNo, relType) {
+            relationTypesHash[relType.type] = relType;
+          });
+          var arcBundle = (response.visual_options || {}).arc_bundle || 'none';
+          collapseArcs = arcBundle == "all";
+          collapseArcSpace = arcBundle != "none";
+
+          dispatcher.post('spanAndAttributeTypesLoaded', [spanTypes, entityAttributeTypes, eventAttributeTypes, relationTypesHash]);
+
+          isCollectionLoaded = true;
+          triggerRender();
+        } else {
+          // exception on collection load; allow visualizer_ui
+          // collectionLoaded to handle this
+        }
+      };
+
+      var isReloadOkay = function() {
+        // do not reload while the user is in the dialog
+        return !drawing;
+      };
+
+      Util.loadFonts(webFontURLs, dispatcher);
+
+      dispatcher.
+          on('collectionChanged', collectionChanged).
+          on('collectionLoaded', collectionLoaded).
+          on('renderData', renderData).
+          on('triggerRender', triggerRender).
+          on('requestRenderData', requestRenderData).
+          on('isReloadOkay', isReloadOkay).
+          on('resetData', resetData).
+          on('abbrevs', setAbbrevs).
+          on('textBackgrounds', setTextBackgrounds).
+          on('layoutDensity', setLayoutDensity).
+          on('svgWidth', setSvgWidth).
+          on('current', gotCurrent).
+          on('clearSVG', clearSVG).
+          on('mouseover', onMouseOver).
+          on('mouseout', onMouseOut);
+    };
+
+    return Visualizer;
+})(jQuery, window);

Property changes on: TXM/trunk/org.txm.conllu.core/template/lib/brat/visualizer.js
___________________________________________________________________
Added: svn:mime-type
   + text/plain

Index: TXM/trunk/org.txm.conllu.core/template/lib/brat/dispatcher.js
===================================================================
--- TXM/trunk/org.txm.conllu.core/template/lib/brat/dispatcher.js	(revision 0)
+++ TXM/trunk/org.txm.conllu.core/template/lib/brat/dispatcher.js	(revision 3567)
@@ -0,0 +1,129 @@
+// -*- Mode: JavaScript; tab-width: 2; indent-tabs-mode: nil; -*-
+// vim:set ft=javascript ts=2 sw=2 sts=2 cindent:
+
+var Dispatcher = (function($, window, undefined) {
+    var Dispatcher = function() {
+      var that = this;
+
+      var table = {};
+
+      var on = function on(message, host, handler) {
+        if (handler === undefined) {
+          handler = host;
+          host = on.caller;
+        }
+        if (table[message] === undefined) {
+          table[message] = [];
+        }
+        table[message].push([host, handler]);
+        return this;
+      };
+
+      // Notify listeners that we encountered an error in an asynch call
+      var inAsynchError = false; // To avoid error avalanches
+      var handleAsynchError = function(e) {
+        if (!inAsynchError) {
+          inAsynchError = true;
+          // TODO: Hook printout into dispatch elsewhere?
+          console.warn('Handled async error:', e);
+          that.post('dispatchAsynchError', [e]);
+          inAsynchError = false;
+        } else {
+          console.warn('Dropped asynch error:', e);
+        }
+      };
+
+      var post = function post(asynch, message, args, returnType) {
+        if (typeof(asynch) !== 'number') {
+          // no asynch parameter
+          returnType = args;
+          args = message;
+          message = asynch;
+          asynch = null;
+        }
+        if (args === undefined) {
+          args = [];
+        }
+        var results = [];
+        // DEBUG: if (typeof(message) != "string" || !(message.match(/mouse/) || message == "hideComment")) console.log(message, args);
+
+        if (typeof(message) === 'function') {
+          // someone was lazy and sent a simple function
+          var host = post.caller;
+          if (asynch !== null) {
+            result = setTimeout(function() {
+              try {
+                message.apply(host, args);
+              } catch(e) {
+                handleAsynchError(e);
+              }
+            }, asynch);
+          } else {
+            result = message.apply(host, args);
+          }
+          results.push(result);
+        } else {
+          // a proper message, propagate to all interested parties
+          var todo = table[message];
+          if (todo !== undefined) {
+            $.each(todo, function(itemNo, item) {
+              var result;
+              if (asynch !== null) {
+                result = setTimeout(function() {
+                  try {
+                    item[1].apply(item[0], args);
+                  } catch (e) {
+                    handleAsynchError(e);
+                  }
+                }, asynch);
+              } else {
+                result = item[1].apply(item[0], args);
+              }
+              results.push(result);
+            });
+/* DEBUG
+          } else {
+            console.warn('Message ' + message + ' has no subscribers.'); // DEBUG
+*/
+          }
+        }
+        if (returnType == 'any') {
+          var i = results.length;
+          while (i--) {
+            if (results[i] !== false) return results[i];
+          }
+          return false;
+        }
+        if (returnType == 'all') {
+          var i = results.length;
+          while (i--) {
+            if (results[i] === false) return results[i];
+          }
+        }
+        return results;
+      };
+
+      var proxy = function(destination, message) {
+        this.on(message, function() {
+          destination.post(message, Array.prototype.slice.call(arguments));
+        });
+      };
+
+      var dispatcher = {
+        on: on,
+        post: post,
+        proxy: proxy,
+      };
+      Dispatcher.dispatchers.push(dispatcher);
+      return dispatcher;
+    };
+
+    Dispatcher.dispatchers = [];
+    Dispatcher.post = function(asynch, message, args, returnType) {
+      $.each(Dispatcher.dispatchers, function(dispatcherNo, dispatcher) {
+        dispatcher.post(asynch, message, args, returnType);
+      });
+    };
+
+    return Dispatcher;
+})(jQuery, window);

Property changes on: TXM/trunk/org.txm.conllu.core/template/lib/brat/dispatcher.js
___________________________________________________________________
Added: svn:mime-type
   + text/plain

Index: TXM/trunk/org.txm.conllu.core/template/lib/brat/configuration.js
===================================================================
--- TXM/trunk/org.txm.conllu.core/template/lib/brat/configuration.js	(revision 0)
+++ TXM/trunk/org.txm.conllu.core/template/lib/brat/configuration.js	(revision 3567)
@@ -0,0 +1,31 @@
+// -*- Mode: JavaScript; tab-width: 2; indent-tabs-mode: nil; -*-
+// vim:set ft=javascript ts=2 sw=2 sts=2 cindent:
+var Configuration = (function(window, undefined) {
+    var abbrevsOn = true;
+    var textBackgrounds = "striped";
+    var svgWidth = '100%';
+    var rapidModeOn = false;
+    var confirmModeOn = true;
+    var autorefreshOn = false;
+    var typeCollapseLimit = 30;
+    
+    var visual = {
+      margin: { x: 2, y: 1 },
+      arcTextMargin: 1,
+      boxSpacing: 1,
+      curlyHeight: 4,
+      arcSpacing: 9, //10;
+      arcStartHeight: 19, //23; //25;
+    }
+
+    return {
+      abbrevsOn: abbrevsOn,
+      textBackgrounds: textBackgrounds,
+      visual: visual,
+      svgWidth: svgWidth,
+      rapidModeOn: rapidModeOn,
+      confirmModeOn: confirmModeOn,
+      autorefreshOn: autorefreshOn,
+      typeCollapseLimit: typeCollapseLimit,
+    };
+})(window);

Property changes on: TXM/trunk/org.txm.conllu.core/template/lib/brat/configuration.js
___________________________________________________________________
Added: svn:mime-type
   + text/plain

Index: TXM/trunk/org.txm.conllu.core/template/lib/local/config.js
===================================================================
--- TXM/trunk/org.txm.conllu.core/template/lib/local/config.js	(revision 0)
+++ TXM/trunk/org.txm.conllu.core/template/lib/local/config.js	(revision 3567)
@@ -0,0 +1,63 @@
+// -*- Mode: JavaScript; tab-width: 4; indent-tabs-mode: nil; -*-
+// vim:set ft=javascript ts=4 sw=4 sts=4 cindent:
+
+var Config = (function(window, undefined) {
+
+    var bratCollData = {
+	'entity_types': [
+// this is optional
+        {
+            'type': 'SPAN_DEFAULT',
+            'bgColor': '#7fa2ff',
+            'borderColor': 'darken'
+        },
+        {
+            'type': 'ARC_DEFAULT',
+            'color': 'black',
+            'arrowHead': 'triangle,5',
+            'labelArrow': 'triangle,3,5',
+        },
+        {
+            'type': 'token',
+            'labels': [ '\u00A0\u00A0' ], // non-breaking space for empty
+        },
+        {
+            'type': '-',
+            'labels': [ '\u00A0\u00A0' ], // non-breaking space for empty
+        }
+	],
+  'event_attribute_types': [],
+  'entity_attribute_types': [
+        {
+            'type':   'Name',
+            'values': { 
+                'Name' : { 'glyph': '(N)' },
+             },
+         },
+         ],
+	'relation_types': [
+// this is optional
+//         {
+//             'type': 'subj',
+//             'labels': [ 'subj' ],
+//             'dashArray': '3,3',
+//             'color': 'green',
+//             'args': [
+//                 {
+//                     'role': 'arg1',
+//                     'targets': [ 'token' ]
+//                 },
+//                 {
+//                     'role': 'arg2',
+//                     'targets': [ 'token' ]
+//                 }
+//             ]
+//         }
+        ],
+	'event_types': [],
+    };
+
+    return {
+        bratCollData: bratCollData,
+    };
+})(window);

Property changes on: TXM/trunk/org.txm.conllu.core/template/lib/local/config.js
___________________________________________________________________
Added: svn:mime-type
   + text/plain

Index: TXM/trunk/org.txm.conllu.core/template/lib/ext/jquery-ui.min.js
===================================================================
--- TXM/trunk/org.txm.conllu.core/template/lib/ext/jquery-ui.min.js	(revision 0)
+++ TXM/trunk/org.txm.conllu.core/template/lib/ext/jquery-ui.min.js	(revision 3567)
@@ -0,0 +1,791 @@
+/*!
+ * jQuery UI 1.8.16
+ *
+ * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
+ * Dual licensed under the MIT or GPL Version 2 licenses.
+ * http://jquery.org/license
+ *
+ * http://docs.jquery.com/UI
+ */
+(function(c,j){function k(a,b){var d=a.nodeName.toLowerCase();if("area"===d){b=a.parentNode;d=b.name;if(!a.href||!d||b.nodeName.toLowerCase()!=="map")return false;a=c("img[usemap=#"+d+"]")[0];return!!a&&l(a)}return(/input|select|textarea|button|object/.test(d)?!a.disabled:"a"==d?a.href||b:b)&&l(a)}function l(a){return!c(a).parents().andSelf().filter(function(){return c.curCSS(this,"visibility")==="hidden"||c.expr.filters.hidden(this)}).length}c.ui=c.ui||{};if(!c.ui.version){c.extend(c.ui,{version:"1.8.16",
+keyCode:{ALT:18,BACKSPACE:8,CAPS_LOCK:20,COMMA:188,COMMAND:91,COMMAND_LEFT:91,COMMAND_RIGHT:93,CONTROL:17,DELETE:46,DOWN:40,END:35,ENTER:13,ESCAPE:27,HOME:36,INSERT:45,LEFT:37,MENU:93,NUMPAD_ADD:107,NUMPAD_DECIMAL:110,NUMPAD_DIVIDE:111,NUMPAD_ENTER:108,NUMPAD_MULTIPLY:106,NUMPAD_SUBTRACT:109,PAGE_DOWN:34,PAGE_UP:33,PERIOD:190,RIGHT:39,SHIFT:16,SPACE:32,TAB:9,UP:38,WINDOWS:91}});c.fn.extend({propAttr:c.fn.prop||c.fn.attr,_focus:c.fn.focus,focus:function(a,b){return typeof a==="number"?this.each(function(){var d=
+this;setTimeout(function(){c(d).focus();b&&b.call(d)},a)}):this._focus.apply(this,arguments)},scrollParent:function(){var a;a=c.browser.msie&&/(static|relative)/.test(this.css("position"))||/absolute/.test(this.css("position"))?this.parents().filter(function(){return/(relative|absolute|fixed)/.test(c.curCSS(this,"position",1))&&/(auto|scroll)/.test(c.curCSS(this,"overflow",1)+c.curCSS(this,"overflow-y",1)+c.curCSS(this,"overflow-x",1))}).eq(0):this.parents().filter(function(){return/(auto|scroll)/.test(c.curCSS(this,
+"overflow",1)+c.curCSS(this,"overflow-y",1)+c.curCSS(this,"overflow-x",1))}).eq(0);return/fixed/.test(this.css("position"))||!a.length?c(document):a},zIndex:function(a){if(a!==j)return this.css("zIndex",a);if(this.length){a=c(this[0]);for(var b;a.length&&a[0]!==document;){b=a.css("position");if(b==="absolute"||b==="relative"||b==="fixed"){b=parseInt(a.css("zIndex"),10);if(!isNaN(b)&&b!==0)return b}a=a.parent()}}return 0},disableSelection:function(){return this.bind((c.support.selectstart?"selectstart":
+"mousedown")+".ui-disableSelection",function(a){a.preventDefault()})},enableSelection:function(){return this.unbind(".ui-disableSelection")}});c.each(["Width","Height"],function(a,b){function d(f,g,m,n){c.each(e,function(){g-=parseFloat(c.curCSS(f,"padding"+this,true))||0;if(m)g-=parseFloat(c.curCSS(f,"border"+this+"Width",true))||0;if(n)g-=parseFloat(c.curCSS(f,"margin"+this,true))||0});return g}var e=b==="Width"?["Left","Right"]:["Top","Bottom"],h=b.toLowerCase(),i={innerWidth:c.fn.innerWidth,innerHeight:c.fn.innerHeight,
+outerWidth:c.fn.outerWidth,outerHeight:c.fn.outerHeight};c.fn["inner"+b]=function(f){if(f===j)return i["inner"+b].call(this);return this.each(function(){c(this).css(h,d(this,f)+"px")})};c.fn["outer"+b]=function(f,g){if(typeof f!=="number")return i["outer"+b].call(this,f);return this.each(function(){c(this).css(h,d(this,f,true,g)+"px")})}});c.extend(c.expr[":"],{data:function(a,b,d){return!!c.data(a,d[3])},focusable:function(a){return k(a,!isNaN(c.attr(a,"tabindex")))},tabbable:function(a){var b=c.attr(a,
+"tabindex"),d=isNaN(b);return(d||b>=0)&&k(a,!d)}});c(function(){var a=document.body,b=a.appendChild(b=document.createElement("div"));c.extend(b.style,{minHeight:"100px",height:"auto",padding:0,borderWidth:0});c.support.minHeight=b.offsetHeight===100;c.support.selectstart="onselectstart"in b;a.removeChild(b).style.display="none"});c.extend(c.ui,{plugin:{add:function(a,b,d){a=c.ui[a].prototype;for(var e in d){a.plugins[e]=a.plugins[e]||[];a.plugins[e].push([b,d[e]])}},call:function(a,b,d){if((b=a.plugins[b])&&
+a.element[0].parentNode)for(var e=0;e<b.length;e++)a.options[b[e][0]]&&b[e][1].apply(a.element,d)}},contains:function(a,b){return document.compareDocumentPosition?a.compareDocumentPosition(b)&16:a!==b&&a.contains(b)},hasScroll:function(a,b){if(c(a).css("overflow")==="hidden")return false;b=b&&b==="left"?"scrollLeft":"scrollTop";var d=false;if(a[b]>0)return true;a[b]=1;d=a[b]>0;a[b]=0;return d},isOverAxis:function(a,b,d){return a>b&&a<b+d},isOver:function(a,b,d,e,h,i){return c.ui.isOverAxis(a,d,h)&&
+c.ui.isOverAxis(b,e,i)}})}})(jQuery);
+;/*!
+ * jQuery UI Widget 1.8.16
+ *
+ * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
+ * Dual licensed under the MIT or GPL Version 2 licenses.
+ * http://jquery.org/license
+ *
+ * http://docs.jquery.com/UI/Widget
+ */
+(function(b,j){if(b.cleanData){var k=b.cleanData;b.cleanData=function(a){for(var c=0,d;(d=a[c])!=null;c++)try{b(d).triggerHandler("remove")}catch(e){}k(a)}}else{var l=b.fn.remove;b.fn.remove=function(a,c){return this.each(function(){if(!c)if(!a||b.filter(a,[this]).length)b("*",this).add([this]).each(function(){try{b(this).triggerHandler("remove")}catch(d){}});return l.call(b(this),a,c)})}}b.widget=function(a,c,d){var e=a.split(".")[0],f;a=a.split(".")[1];f=e+"-"+a;if(!d){d=c;c=b.Widget}b.expr[":"][f]=
+function(h){return!!b.data(h,a)};b[e]=b[e]||{};b[e][a]=function(h,g){arguments.length&&this._createWidget(h,g)};c=new c;c.options=b.extend(true,{},c.options);b[e][a].prototype=b.extend(true,c,{namespace:e,widgetName:a,widgetEventPrefix:b[e][a].prototype.widgetEventPrefix||a,widgetBaseClass:f},d);b.widget.bridge(a,b[e][a])};b.widget.bridge=function(a,c){b.fn[a]=function(d){var e=typeof d==="string",f=Array.prototype.slice.call(arguments,1),h=this;d=!e&&f.length?b.extend.apply(null,[true,d].concat(f)):
+d;if(e&&d.charAt(0)==="_")return h;e?this.each(function(){var g=b.data(this,a),i=g&&b.isFunction(g[d])?g[d].apply(g,f):g;if(i!==g&&i!==j){h=i;return false}}):this.each(function(){var g=b.data(this,a);g?g.option(d||{})._init():b.data(this,a,new c(d,this))});return h}};b.Widget=function(a,c){arguments.length&&this._createWidget(a,c)};b.Widget.prototype={widgetName:"widget",widgetEventPrefix:"",options:{disabled:false},_createWidget:function(a,c){b.data(c,this.widgetName,this);this.element=b(c);this.options=
+b.extend(true,{},this.options,this._getCreateOptions(),a);var d=this;this.element.bind("remove."+this.widgetName,function(){d.destroy()});this._create();this._trigger("create");this._init()},_getCreateOptions:function(){return b.metadata&&b.metadata.get(this.element[0])[this.widgetName]},_create:function(){},_init:function(){},destroy:function(){this.element.unbind("."+this.widgetName).removeData(this.widgetName);this.widget().unbind("."+this.widgetName).removeAttr("aria-disabled").removeClass(this.widgetBaseClass+
+"-disabled ui-state-disabled")},widget:function(){return this.element},option:function(a,c){var d=a;if(arguments.length===0)return b.extend({},this.options);if(typeof a==="string"){if(c===j)return this.options[a];d={};d[a]=c}this._setOptions(d);return this},_setOptions:function(a){var c=this;b.each(a,function(d,e){c._setOption(d,e)});return this},_setOption:function(a,c){this.options[a]=c;if(a==="disabled")this.widget()[c?"addClass":"removeClass"](this.widgetBaseClass+"-disabled ui-state-disabled").attr("aria-disabled",
+c);return this},enable:function(){return this._setOption("disabled",false)},disable:function(){return this._setOption("disabled",true)},_trigger:function(a,c,d){var e=this.options[a];c=b.Event(c);c.type=(a===this.widgetEventPrefix?a:this.widgetEventPrefix+a).toLowerCase();d=d||{};if(c.originalEvent){a=b.event.props.length;for(var f;a;){f=b.event.props[--a];c[f]=c.originalEvent[f]}}this.element.trigger(c,d);return!(b.isFunction(e)&&e.call(this.element[0],c,d)===false||c.isDefaultPrevented())}}})(jQuery);
+;/*!
+ * jQuery UI Mouse 1.8.16
+ *
+ * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
+ * Dual licensed under the MIT or GPL Version 2 licenses.
+ * http://jquery.org/license
+ *
+ * http://docs.jquery.com/UI/Mouse
+ *
+ * Depends:
+ *	jquery.ui.widget.js
+ */
+(function(b){var d=false;b(document).mouseup(function(){d=false});b.widget("ui.mouse",{options:{cancel:":input,option",distance:1,delay:0},_mouseInit:function(){var a=this;this.element.bind("mousedown."+this.widgetName,function(c){return a._mouseDown(c)}).bind("click."+this.widgetName,function(c){if(true===b.data(c.target,a.widgetName+".preventClickEvent")){b.removeData(c.target,a.widgetName+".preventClickEvent");c.stopImmediatePropagation();return false}});this.started=false},_mouseDestroy:function(){this.element.unbind("."+
+this.widgetName)},_mouseDown:function(a){if(!d){this._mouseStarted&&this._mouseUp(a);this._mouseDownEvent=a;var c=this,f=a.which==1,g=typeof this.options.cancel=="string"&&a.target.nodeName?b(a.target).closest(this.options.cancel).length:false;if(!f||g||!this._mouseCapture(a))return true;this.mouseDelayMet=!this.options.delay;if(!this.mouseDelayMet)this._mouseDelayTimer=setTimeout(function(){c.mouseDelayMet=true},this.options.delay);if(this._mouseDistanceMet(a)&&this._mouseDelayMet(a)){this._mouseStarted=
+this._mouseStart(a)!==false;if(!this._mouseStarted){a.preventDefault();return true}}true===b.data(a.target,this.widgetName+".preventClickEvent")&&b.removeData(a.target,this.widgetName+".preventClickEvent");this._mouseMoveDelegate=function(e){return c._mouseMove(e)};this._mouseUpDelegate=function(e){return c._mouseUp(e)};b(document).bind("mousemove."+this.widgetName,this._mouseMoveDelegate).bind("mouseup."+this.widgetName,this._mouseUpDelegate);a.preventDefault();return d=true}},_mouseMove:function(a){if(b.browser.msie&&
+!(document.documentMode>=9)&&!a.button)return this._mouseUp(a);if(this._mouseStarted){this._mouseDrag(a);return a.preventDefault()}if(this._mouseDistanceMet(a)&&this._mouseDelayMet(a))(this._mouseStarted=this._mouseStart(this._mouseDownEvent,a)!==false)?this._mouseDrag(a):this._mouseUp(a);return!this._mouseStarted},_mouseUp:function(a){b(document).unbind("mousemove."+this.widgetName,this._mouseMoveDelegate).unbind("mouseup."+this.widgetName,this._mouseUpDelegate);if(this._mouseStarted){this._mouseStarted=
+false;a.target==this._mouseDownEvent.target&&b.data(a.target,this.widgetName+".preventClickEvent",true);this._mouseStop(a)}return false},_mouseDistanceMet:function(a){return Math.max(Math.abs(this._mouseDownEvent.pageX-a.pageX),Math.abs(this._mouseDownEvent.pageY-a.pageY))>=this.options.distance},_mouseDelayMet:function(){return this.mouseDelayMet},_mouseStart:function(){},_mouseDrag:function(){},_mouseStop:function(){},_mouseCapture:function(){return true}})})(jQuery);
+;/*
+ * jQuery UI Position 1.8.16
+ *
+ * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
+ * Dual licensed under the MIT or GPL Version 2 licenses.
+ * http://jquery.org/license
+ *
+ * http://docs.jquery.com/UI/Position
+ */
+(function(c){c.ui=c.ui||{};var n=/left|center|right/,o=/top|center|bottom/,t=c.fn.position,u=c.fn.offset;c.fn.position=function(b){if(!b||!b.of)return t.apply(this,arguments);b=c.extend({},b);var a=c(b.of),d=a[0],g=(b.collision||"flip").split(" "),e=b.offset?b.offset.split(" "):[0,0],h,k,j;if(d.nodeType===9){h=a.width();k=a.height();j={top:0,left:0}}else if(d.setTimeout){h=a.width();k=a.height();j={top:a.scrollTop(),left:a.scrollLeft()}}else if(d.preventDefault){b.at="left top";h=k=0;j={top:b.of.pageY,
+left:b.of.pageX}}else{h=a.outerWidth();k=a.outerHeight();j=a.offset()}c.each(["my","at"],function(){var f=(b[this]||"").split(" ");if(f.length===1)f=n.test(f[0])?f.concat(["center"]):o.test(f[0])?["center"].concat(f):["center","center"];f[0]=n.test(f[0])?f[0]:"center";f[1]=o.test(f[1])?f[1]:"center";b[this]=f});if(g.length===1)g[1]=g[0];e[0]=parseInt(e[0],10)||0;if(e.length===1)e[1]=e[0];e[1]=parseInt(e[1],10)||0;if(b.at[0]==="right")j.left+=h;else if(b.at[0]==="center")j.left+=h/2;if(b.at[1]==="bottom")j.top+=
+k;else if(b.at[1]==="center")j.top+=k/2;j.left+=e[0];j.top+=e[1];return this.each(function(){var f=c(this),l=f.outerWidth(),m=f.outerHeight(),p=parseInt(c.curCSS(this,"marginLeft",true))||0,q=parseInt(c.curCSS(this,"marginTop",true))||0,v=l+p+(parseInt(c.curCSS(this,"marginRight",true))||0),w=m+q+(parseInt(c.curCSS(this,"marginBottom",true))||0),i=c.extend({},j),r;if(b.my[0]==="right")i.left-=l;else if(b.my[0]==="center")i.left-=l/2;if(b.my[1]==="bottom")i.top-=m;else if(b.my[1]==="center")i.top-=
+m/2;i.left=Math.round(i.left);i.top=Math.round(i.top);r={left:i.left-p,top:i.top-q};c.each(["left","top"],function(s,x){c.ui.position[g[s]]&&c.ui.position[g[s]][x](i,{targetWidth:h,targetHeight:k,elemWidth:l,elemHeight:m,collisionPosition:r,collisionWidth:v,collisionHeight:w,offset:e,my:b.my,at:b.at})});c.fn.bgiframe&&f.bgiframe();f.offset(c.extend(i,{using:b.using}))})};c.ui.position={fit:{left:function(b,a){var d=c(window);d=a.collisionPosition.left+a.collisionWidth-d.width()-d.scrollLeft();b.left=
+d>0?b.left-d:Math.max(b.left-a.collisionPosition.left,b.left)},top:function(b,a){var d=c(window);d=a.collisionPosition.top+a.collisionHeight-d.height()-d.scrollTop();b.top=d>0?b.top-d:Math.max(b.top-a.collisionPosition.top,b.top)}},flip:{left:function(b,a){if(a.at[0]!=="center"){var d=c(window);d=a.collisionPosition.left+a.collisionWidth-d.width()-d.scrollLeft();var g=a.my[0]==="left"?-a.elemWidth:a.my[0]==="right"?a.elemWidth:0,e=a.at[0]==="left"?a.targetWidth:-a.targetWidth,h=-2*a.offset[0];b.left+=
+a.collisionPosition.left<0?g+e+h:d>0?g+e+h:0}},top:function(b,a){if(a.at[1]!=="center"){var d=c(window);d=a.collisionPosition.top+a.collisionHeight-d.height()-d.scrollTop();var g=a.my[1]==="top"?-a.elemHeight:a.my[1]==="bottom"?a.elemHeight:0,e=a.at[1]==="top"?a.targetHeight:-a.targetHeight,h=-2*a.offset[1];b.top+=a.collisionPosition.top<0?g+e+h:d>0?g+e+h:0}}}};if(!c.offset.setOffset){c.offset.setOffset=function(b,a){if(/static/.test(c.curCSS(b,"position")))b.style.position="relative";var d=c(b),
+g=d.offset(),e=parseInt(c.curCSS(b,"top",true),10)||0,h=parseInt(c.curCSS(b,"left",true),10)||0;g={top:a.top-g.top+e,left:a.left-g.left+h};"using"in a?a.using.call(b,g):d.css(g)};c.fn.offset=function(b){var a=this[0];if(!a||!a.ownerDocument)return null;if(b)return this.each(function(){c.offset.setOffset(this,b)});return u.call(this)}}})(jQuery);
+;/*
+ * jQuery UI Draggable 1.8.16
+ *
+ * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
+ * Dual licensed under the MIT or GPL Version 2 licenses.
+ * http://jquery.org/license
+ *
+ * http://docs.jquery.com/UI/Draggables
+ *
+ * Depends:
+ *	jquery.ui.core.js
+ *	jquery.ui.mouse.js
+ *	jquery.ui.widget.js
+ */
+(function(d){d.widget("ui.draggable",d.ui.mouse,{widgetEventPrefix:"drag",options:{addClasses:true,appendTo:"parent",axis:false,connectToSortable:false,containment:false,cursor:"auto",cursorAt:false,grid:false,handle:false,helper:"original",iframeFix:false,opacity:false,refreshPositions:false,revert:false,revertDuration:500,scope:"default",scroll:true,scrollSensitivity:20,scrollSpeed:20,snap:false,snapMode:"both",snapTolerance:20,stack:false,zIndex:false},_create:function(){if(this.options.helper==
+"original"&&!/^(?:r|a|f)/.test(this.element.css("position")))this.element[0].style.position="relative";this.options.addClasses&&this.element.addClass("ui-draggable");this.options.disabled&&this.element.addClass("ui-draggable-disabled");this._mouseInit()},destroy:function(){if(this.element.data("draggable")){this.element.removeData("draggable").unbind(".draggable").removeClass("ui-draggable ui-draggable-dragging ui-draggable-disabled");this._mouseDestroy();return this}},_mouseCapture:function(a){var b=
+this.options;if(this.helper||b.disabled||d(a.target).is(".ui-resizable-handle"))return false;this.handle=this._getHandle(a);if(!this.handle)return false;if(b.iframeFix)d(b.iframeFix===true?"iframe":b.iframeFix).each(function(){d('<div class="ui-draggable-iframeFix" style="background: #fff;"></div>').css({width:this.offsetWidth+"px",height:this.offsetHeight+"px",position:"absolute",opacity:"0.001",zIndex:1E3}).css(d(this).offset()).appendTo("body")});return true},_mouseStart:function(a){var b=this.options;
+this.helper=this._createHelper(a);this._cacheHelperProportions();if(d.ui.ddmanager)d.ui.ddmanager.current=this;this._cacheMargins();this.cssPosition=this.helper.css("position");this.scrollParent=this.helper.scrollParent();this.offset=this.positionAbs=this.element.offset();this.offset={top:this.offset.top-this.margins.top,left:this.offset.left-this.margins.left};d.extend(this.offset,{click:{left:a.pageX-this.offset.left,top:a.pageY-this.offset.top},parent:this._getParentOffset(),relative:this._getRelativeOffset()});
+this.originalPosition=this.position=this._generatePosition(a);this.originalPageX=a.pageX;this.originalPageY=a.pageY;b.cursorAt&&this._adjustOffsetFromHelper(b.cursorAt);b.containment&&this._setContainment();if(this._trigger("start",a)===false){this._clear();return false}this._cacheHelperProportions();d.ui.ddmanager&&!b.dropBehaviour&&d.ui.ddmanager.prepareOffsets(this,a);this.helper.addClass("ui-draggable-dragging");this._mouseDrag(a,true);d.ui.ddmanager&&d.ui.ddmanager.dragStart(this,a);return true},
+_mouseDrag:function(a,b){this.position=this._generatePosition(a);this.positionAbs=this._convertPositionTo("absolute");if(!b){b=this._uiHash();if(this._trigger("drag",a,b)===false){this._mouseUp({});return false}this.position=b.position}if(!this.options.axis||this.options.axis!="y")this.helper[0].style.left=this.position.left+"px";if(!this.options.axis||this.options.axis!="x")this.helper[0].style.top=this.position.top+"px";d.ui.ddmanager&&d.ui.ddmanager.drag(this,a);return false},_mouseStop:function(a){var b=
+false;if(d.ui.ddmanager&&!this.options.dropBehaviour)b=d.ui.ddmanager.drop(this,a);if(this.dropped){b=this.dropped;this.dropped=false}if((!this.element[0]||!this.element[0].parentNode)&&this.options.helper=="original")return false;if(this.options.revert=="invalid"&&!b||this.options.revert=="valid"&&b||this.options.revert===true||d.isFunction(this.options.revert)&&this.options.revert.call(this.element,b)){var c=this;d(this.helper).animate(this.originalPosition,parseInt(this.options.revertDuration,
+10),function(){c._trigger("stop",a)!==false&&c._clear()})}else this._trigger("stop",a)!==false&&this._clear();return false},_mouseUp:function(a){this.options.iframeFix===true&&d("div.ui-draggable-iframeFix").each(function(){this.parentNode.removeChild(this)});d.ui.ddmanager&&d.ui.ddmanager.dragStop(this,a);return d.ui.mouse.prototype._mouseUp.call(this,a)},cancel:function(){this.helper.is(".ui-draggable-dragging")?this._mouseUp({}):this._clear();return this},_getHandle:function(a){var b=!this.options.handle||
+!d(this.options.handle,this.element).length?true:false;d(this.options.handle,this.element).find("*").andSelf().each(function(){if(this==a.target)b=true});return b},_createHelper:function(a){var b=this.options;a=d.isFunction(b.helper)?d(b.helper.apply(this.element[0],[a])):b.helper=="clone"?this.element.clone().removeAttr("id"):this.element;a.parents("body").length||a.appendTo(b.appendTo=="parent"?this.element[0].parentNode:b.appendTo);a[0]!=this.element[0]&&!/(fixed|absolute)/.test(a.css("position"))&&
+a.css("position","absolute");return a},_adjustOffsetFromHelper:function(a){if(typeof a=="string")a=a.split(" ");if(d.isArray(a))a={left:+a[0],top:+a[1]||0};if("left"in a)this.offset.click.left=a.left+this.margins.left;if("right"in a)this.offset.click.left=this.helperProportions.width-a.right+this.margins.left;if("top"in a)this.offset.click.top=a.top+this.margins.top;if("bottom"in a)this.offset.click.top=this.helperProportions.height-a.bottom+this.margins.top},_getParentOffset:function(){this.offsetParent=
+this.helper.offsetParent();var a=this.offsetParent.offset();if(this.cssPosition=="absolute"&&this.scrollParent[0]!=document&&d.ui.contains(this.scrollParent[0],this.offsetParent[0])){a.left+=this.scrollParent.scrollLeft();a.top+=this.scrollParent.scrollTop()}if(this.offsetParent[0]==document.body||this.offsetParent[0].tagName&&this.offsetParent[0].tagName.toLowerCase()=="html"&&d.browser.msie)a={top:0,left:0};return{top:a.top+(parseInt(this.offsetParent.css("borderTopWidth"),10)||0),left:a.left+(parseInt(this.offsetParent.css("borderLeftWidth"),
+10)||0)}},_getRelativeOffset:function(){if(this.cssPosition=="relative"){var a=this.element.position();return{top:a.top-(parseInt(this.helper.css("top"),10)||0)+this.scrollParent.scrollTop(),left:a.left-(parseInt(this.helper.css("left"),10)||0)+this.scrollParent.scrollLeft()}}else return{top:0,left:0}},_cacheMargins:function(){this.margins={left:parseInt(this.element.css("marginLeft"),10)||0,top:parseInt(this.element.css("marginTop"),10)||0,right:parseInt(this.element.css("marginRight"),10)||0,bottom:parseInt(this.element.css("marginBottom"),
+10)||0}},_cacheHelperProportions:function(){this.helperProportions={width:this.helper.outerWidth(),height:this.helper.outerHeight()}},_setContainment:function(){var a=this.options;if(a.containment=="parent")a.containment=this.helper[0].parentNode;if(a.containment=="document"||a.containment=="window")this.containment=[a.containment=="document"?0:d(window).scrollLeft()-this.offset.relative.left-this.offset.parent.left,a.containment=="document"?0:d(window).scrollTop()-this.offset.relative.top-this.offset.parent.top,
+(a.containment=="document"?0:d(window).scrollLeft())+d(a.containment=="document"?document:window).width()-this.helperProportions.width-this.margins.left,(a.containment=="document"?0:d(window).scrollTop())+(d(a.containment=="document"?document:window).height()||document.body.parentNode.scrollHeight)-this.helperProportions.height-this.margins.top];if(!/^(document|window|parent)$/.test(a.containment)&&a.containment.constructor!=Array){a=d(a.containment);var b=a[0];if(b){a.offset();var c=d(b).css("overflow")!=
+"hidden";this.containment=[(parseInt(d(b).css("borderLeftWidth"),10)||0)+(parseInt(d(b).css("paddingLeft"),10)||0),(parseInt(d(b).css("borderTopWidth"),10)||0)+(parseInt(d(b).css("paddingTop"),10)||0),(c?Math.max(b.scrollWidth,b.offsetWidth):b.offsetWidth)-(parseInt(d(b).css("borderLeftWidth"),10)||0)-(parseInt(d(b).css("paddingRight"),10)||0)-this.helperProportions.width-this.margins.left-this.margins.right,(c?Math.max(b.scrollHeight,b.offsetHeight):b.offsetHeight)-(parseInt(d(b).css("borderTopWidth"),
+10)||0)-(parseInt(d(b).css("paddingBottom"),10)||0)-this.helperProportions.height-this.margins.top-this.margins.bottom];this.relative_container=a}}else if(a.containment.constructor==Array)this.containment=a.containment},_convertPositionTo:function(a,b){if(!b)b=this.position;a=a=="absolute"?1:-1;var c=this.cssPosition=="absolute"&&!(this.scrollParent[0]!=document&&d.ui.contains(this.scrollParent[0],this.offsetParent[0]))?this.offsetParent:this.scrollParent,f=/(html|body)/i.test(c[0].tagName);return{top:b.top+
+this.offset.relative.top*a+this.offset.parent.top*a-(d.browser.safari&&d.browser.version<526&&this.cssPosition=="fixed"?0:(this.cssPosition=="fixed"?-this.scrollParent.scrollTop():f?0:c.scrollTop())*a),left:b.left+this.offset.relative.left*a+this.offset.parent.left*a-(d.browser.safari&&d.browser.version<526&&this.cssPosition=="fixed"?0:(this.cssPosition=="fixed"?-this.scrollParent.scrollLeft():f?0:c.scrollLeft())*a)}},_generatePosition:function(a){var b=this.options,c=this.cssPosition=="absolute"&&
+!(this.scrollParent[0]!=document&&d.ui.contains(this.scrollParent[0],this.offsetParent[0]))?this.offsetParent:this.scrollParent,f=/(html|body)/i.test(c[0].tagName),e=a.pageX,h=a.pageY;if(this.originalPosition){var g;if(this.containment){if(this.relative_container){g=this.relative_container.offset();g=[this.containment[0]+g.left,this.containment[1]+g.top,this.containment[2]+g.left,this.containment[3]+g.top]}else g=this.containment;if(a.pageX-this.offset.click.left<g[0])e=g[0]+this.offset.click.left;
+if(a.pageY-this.offset.click.top<g[1])h=g[1]+this.offset.click.top;if(a.pageX-this.offset.click.left>g[2])e=g[2]+this.offset.click.left;if(a.pageY-this.offset.click.top>g[3])h=g[3]+this.offset.click.top}if(b.grid){h=b.grid[1]?this.originalPageY+Math.round((h-this.originalPageY)/b.grid[1])*b.grid[1]:this.originalPageY;h=g?!(h-this.offset.click.top<g[1]||h-this.offset.click.top>g[3])?h:!(h-this.offset.click.top<g[1])?h-b.grid[1]:h+b.grid[1]:h;e=b.grid[0]?this.originalPageX+Math.round((e-this.originalPageX)/
+b.grid[0])*b.grid[0]:this.originalPageX;e=g?!(e-this.offset.click.left<g[0]||e-this.offset.click.left>g[2])?e:!(e-this.offset.click.left<g[0])?e-b.grid[0]:e+b.grid[0]:e}}return{top:h-this.offset.click.top-this.offset.relative.top-this.offset.parent.top+(d.browser.safari&&d.browser.version<526&&this.cssPosition=="fixed"?0:this.cssPosition=="fixed"?-this.scrollParent.scrollTop():f?0:c.scrollTop()),left:e-this.offset.click.left-this.offset.relative.left-this.offset.parent.left+(d.browser.safari&&d.browser.version<
+526&&this.cssPosition=="fixed"?0:this.cssPosition=="fixed"?-this.scrollParent.scrollLeft():f?0:c.scrollLeft())}},_clear:function(){this.helper.removeClass("ui-draggable-dragging");this.helper[0]!=this.element[0]&&!this.cancelHelperRemoval&&this.helper.remove();this.helper=null;this.cancelHelperRemoval=false},_trigger:function(a,b,c){c=c||this._uiHash();d.ui.plugin.call(this,a,[b,c]);if(a=="drag")this.positionAbs=this._convertPositionTo("absolute");return d.Widget.prototype._trigger.call(this,a,b,
+c)},plugins:{},_uiHash:function(){return{helper:this.helper,position:this.position,originalPosition:this.originalPosition,offset:this.positionAbs}}});d.extend(d.ui.draggable,{version:"1.8.16"});d.ui.plugin.add("draggable","connectToSortable",{start:function(a,b){var c=d(this).data("draggable"),f=c.options,e=d.extend({},b,{item:c.element});c.sortables=[];d(f.connectToSortable).each(function(){var h=d.data(this,"sortable");if(h&&!h.options.disabled){c.sortables.push({instance:h,shouldRevert:h.options.revert});
+h.refreshPositions();h._trigger("activate",a,e)}})},stop:function(a,b){var c=d(this).data("draggable"),f=d.extend({},b,{item:c.element});d.each(c.sortables,function(){if(this.instance.isOver){this.instance.isOver=0;c.cancelHelperRemoval=true;this.instance.cancelHelperRemoval=false;if(this.shouldRevert)this.instance.options.revert=true;this.instance._mouseStop(a);this.instance.options.helper=this.instance.options._helper;c.options.helper=="original"&&this.instance.currentItem.css({top:"auto",left:"auto"})}else{this.instance.cancelHelperRemoval=
+false;this.instance._trigger("deactivate",a,f)}})},drag:function(a,b){var c=d(this).data("draggable"),f=this;d.each(c.sortables,function(){this.instance.positionAbs=c.positionAbs;this.instance.helperProportions=c.helperProportions;this.instance.offset.click=c.offset.click;if(this.instance._intersectsWith(this.instance.containerCache)){if(!this.instance.isOver){this.instance.isOver=1;this.instance.currentItem=d(f).clone().removeAttr("id").appendTo(this.instance.element).data("sortable-item",true);
+this.instance.options._helper=this.instance.options.helper;this.instance.options.helper=function(){return b.helper[0]};a.target=this.instance.currentItem[0];this.instance._mouseCapture(a,true);this.instance._mouseStart(a,true,true);this.instance.offset.click.top=c.offset.click.top;this.instance.offset.click.left=c.offset.click.left;this.instance.offset.parent.left-=c.offset.parent.left-this.instance.offset.parent.left;this.instance.offset.parent.top-=c.offset.parent.top-this.instance.offset.parent.top;
+c._trigger("toSortable",a);c.dropped=this.instance.element;c.currentItem=c.element;this.instance.fromOutside=c}this.instance.currentItem&&this.instance._mouseDrag(a)}else if(this.instance.isOver){this.instance.isOver=0;this.instance.cancelHelperRemoval=true;this.instance.options.revert=false;this.instance._trigger("out",a,this.instance._uiHash(this.instance));this.instance._mouseStop(a,true);this.instance.options.helper=this.instance.options._helper;this.instance.currentItem.remove();this.instance.placeholder&&
+this.instance.placeholder.remove();c._trigger("fromSortable",a);c.dropped=false}})}});d.ui.plugin.add("draggable","cursor",{start:function(){var a=d("body"),b=d(this).data("draggable").options;if(a.css("cursor"))b._cursor=a.css("cursor");a.css("cursor",b.cursor)},stop:function(){var a=d(this).data("draggable").options;a._cursor&&d("body").css("cursor",a._cursor)}});d.ui.plugin.add("draggable","opacity",{start:function(a,b){a=d(b.helper);b=d(this).data("draggable").options;if(a.css("opacity"))b._opacity=
+a.css("opacity");a.css("opacity",b.opacity)},stop:function(a,b){a=d(this).data("draggable").options;a._opacity&&d(b.helper).css("opacity",a._opacity)}});d.ui.plugin.add("draggable","scroll",{start:function(){var a=d(this).data("draggable");if(a.scrollParent[0]!=document&&a.scrollParent[0].tagName!="HTML")a.overflowOffset=a.scrollParent.offset()},drag:function(a){var b=d(this).data("draggable"),c=b.options,f=false;if(b.scrollParent[0]!=document&&b.scrollParent[0].tagName!="HTML"){if(!c.axis||c.axis!=
+"x")if(b.overflowOffset.top+b.scrollParent[0].offsetHeight-a.pageY<c.scrollSensitivity)b.scrollParent[0].scrollTop=f=b.scrollParent[0].scrollTop+c.scrollSpeed;else if(a.pageY-b.overflowOffset.top<c.scrollSensitivity)b.scrollParent[0].scrollTop=f=b.scrollParent[0].scrollTop-c.scrollSpeed;if(!c.axis||c.axis!="y")if(b.overflowOffset.left+b.scrollParent[0].offsetWidth-a.pageX<c.scrollSensitivity)b.scrollParent[0].scrollLeft=f=b.scrollParent[0].scrollLeft+c.scrollSpeed;else if(a.pageX-b.overflowOffset.left<
+c.scrollSensitivity)b.scrollParent[0].scrollLeft=f=b.scrollParent[0].scrollLeft-c.scrollSpeed}else{if(!c.axis||c.axis!="x")if(a.pageY-d(document).scrollTop()<c.scrollSensitivity)f=d(document).scrollTop(d(document).scrollTop()-c.scrollSpeed);else if(d(window).height()-(a.pageY-d(document).scrollTop())<c.scrollSensitivity)f=d(document).scrollTop(d(document).scrollTop()+c.scrollSpeed);if(!c.axis||c.axis!="y")if(a.pageX-d(document).scrollLeft()<c.scrollSensitivity)f=d(document).scrollLeft(d(document).scrollLeft()-
+c.scrollSpeed);else if(d(window).width()-(a.pageX-d(document).scrollLeft())<c.scrollSensitivity)f=d(document).scrollLeft(d(document).scrollLeft()+c.scrollSpeed)}f!==false&&d.ui.ddmanager&&!c.dropBehaviour&&d.ui.ddmanager.prepareOffsets(b,a)}});d.ui.plugin.add("draggable","snap",{start:function(){var a=d(this).data("draggable"),b=a.options;a.snapElements=[];d(b.snap.constructor!=String?b.snap.items||":data(draggable)":b.snap).each(function(){var c=d(this),f=c.offset();this!=a.element[0]&&a.snapElements.push({item:this,
+width:c.outerWidth(),height:c.outerHeight(),top:f.top,left:f.left})})},drag:function(a,b){for(var c=d(this).data("draggable"),f=c.options,e=f.snapTolerance,h=b.offset.left,g=h+c.helperProportions.width,n=b.offset.top,o=n+c.helperProportions.height,i=c.snapElements.length-1;i>=0;i--){var j=c.snapElements[i].left,l=j+c.snapElements[i].width,k=c.snapElements[i].top,m=k+c.snapElements[i].height;if(j-e<h&&h<l+e&&k-e<n&&n<m+e||j-e<h&&h<l+e&&k-e<o&&o<m+e||j-e<g&&g<l+e&&k-e<n&&n<m+e||j-e<g&&g<l+e&&k-e<o&&
+o<m+e){if(f.snapMode!="inner"){var p=Math.abs(k-o)<=e,q=Math.abs(m-n)<=e,r=Math.abs(j-g)<=e,s=Math.abs(l-h)<=e;if(p)b.position.top=c._convertPositionTo("relative",{top:k-c.helperProportions.height,left:0}).top-c.margins.top;if(q)b.position.top=c._convertPositionTo("relative",{top:m,left:0}).top-c.margins.top;if(r)b.position.left=c._convertPositionTo("relative",{top:0,left:j-c.helperProportions.width}).left-c.margins.left;if(s)b.position.left=c._convertPositionTo("relative",{top:0,left:l}).left-c.margins.left}var t=
+p||q||r||s;if(f.snapMode!="outer"){p=Math.abs(k-n)<=e;q=Math.abs(m-o)<=e;r=Math.abs(j-h)<=e;s=Math.abs(l-g)<=e;if(p)b.position.top=c._convertPositionTo("relative",{top:k,left:0}).top-c.margins.top;if(q)b.position.top=c._convertPositionTo("relative",{top:m-c.helperProportions.height,left:0}).top-c.margins.top;if(r)b.position.left=c._convertPositionTo("relative",{top:0,left:j}).left-c.margins.left;if(s)b.position.left=c._convertPositionTo("relative",{top:0,left:l-c.helperProportions.width}).left-c.margins.left}if(!c.snapElements[i].snapping&&
+(p||q||r||s||t))c.options.snap.snap&&c.options.snap.snap.call(c.element,a,d.extend(c._uiHash(),{snapItem:c.snapElements[i].item}));c.snapElements[i].snapping=p||q||r||s||t}else{c.snapElements[i].snapping&&c.options.snap.release&&c.options.snap.release.call(c.element,a,d.extend(c._uiHash(),{snapItem:c.snapElements[i].item}));c.snapElements[i].snapping=false}}}});d.ui.plugin.add("draggable","stack",{start:function(){var a=d(this).data("draggable").options;a=d.makeArray(d(a.stack)).sort(function(c,f){return(parseInt(d(c).css("zIndex"),
+10)||0)-(parseInt(d(f).css("zIndex"),10)||0)});if(a.length){var b=parseInt(a[0].style.zIndex)||0;d(a).each(function(c){this.style.zIndex=b+c});this[0].style.zIndex=b+a.length}}});d.ui.plugin.add("draggable","zIndex",{start:function(a,b){a=d(b.helper);b=d(this).data("draggable").options;if(a.css("zIndex"))b._zIndex=a.css("zIndex");a.css("zIndex",b.zIndex)},stop:function(a,b){a=d(this).data("draggable").options;a._zIndex&&d(b.helper).css("zIndex",a._zIndex)}})})(jQuery);
+;/*
+ * jQuery UI Droppable 1.8.16
+ *
+ * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
+ * Dual licensed under the MIT or GPL Version 2 licenses.
+ * http://jquery.org/license
+ *
+ * http://docs.jquery.com/UI/Droppables
+ *
+ * Depends:
+ *	jquery.ui.core.js
+ *	jquery.ui.widget.js
+ *	jquery.ui.mouse.js
+ *	jquery.ui.draggable.js
+ */
+(function(d){d.widget("ui.droppable",{widgetEventPrefix:"drop",options:{accept:"*",activeClass:false,addClasses:true,greedy:false,hoverClass:false,scope:"default",tolerance:"intersect"},_create:function(){var a=this.options,b=a.accept;this.isover=0;this.isout=1;this.accept=d.isFunction(b)?b:function(c){return c.is(b)};this.proportions={width:this.element[0].offsetWidth,height:this.element[0].offsetHeight};d.ui.ddmanager.droppables[a.scope]=d.ui.ddmanager.droppables[a.scope]||[];d.ui.ddmanager.droppables[a.scope].push(this);
+a.addClasses&&this.element.addClass("ui-droppable")},destroy:function(){for(var a=d.ui.ddmanager.droppables[this.options.scope],b=0;b<a.length;b++)a[b]==this&&a.splice(b,1);this.element.removeClass("ui-droppable ui-droppable-disabled").removeData("droppable").unbind(".droppable");return this},_setOption:function(a,b){if(a=="accept")this.accept=d.isFunction(b)?b:function(c){return c.is(b)};d.Widget.prototype._setOption.apply(this,arguments)},_activate:function(a){var b=d.ui.ddmanager.current;this.options.activeClass&&
+this.element.addClass(this.options.activeClass);b&&this._trigger("activate",a,this.ui(b))},_deactivate:function(a){var b=d.ui.ddmanager.current;this.options.activeClass&&this.element.removeClass(this.options.activeClass);b&&this._trigger("deactivate",a,this.ui(b))},_over:function(a){var b=d.ui.ddmanager.current;if(!(!b||(b.currentItem||b.element)[0]==this.element[0]))if(this.accept.call(this.element[0],b.currentItem||b.element)){this.options.hoverClass&&this.element.addClass(this.options.hoverClass);
+this._trigger("over",a,this.ui(b))}},_out:function(a){var b=d.ui.ddmanager.current;if(!(!b||(b.currentItem||b.element)[0]==this.element[0]))if(this.accept.call(this.element[0],b.currentItem||b.element)){this.options.hoverClass&&this.element.removeClass(this.options.hoverClass);this._trigger("out",a,this.ui(b))}},_drop:function(a,b){var c=b||d.ui.ddmanager.current;if(!c||(c.currentItem||c.element)[0]==this.element[0])return false;var e=false;this.element.find(":data(droppable)").not(".ui-draggable-dragging").each(function(){var g=
+d.data(this,"droppable");if(g.options.greedy&&!g.options.disabled&&g.options.scope==c.options.scope&&g.accept.call(g.element[0],c.currentItem||c.element)&&d.ui.intersect(c,d.extend(g,{offset:g.element.offset()}),g.options.tolerance)){e=true;return false}});if(e)return false;if(this.accept.call(this.element[0],c.currentItem||c.element)){this.options.activeClass&&this.element.removeClass(this.options.activeClass);this.options.hoverClass&&this.element.removeClass(this.options.hoverClass);this._trigger("drop",
+a,this.ui(c));return this.element}return false},ui:function(a){return{draggable:a.currentItem||a.element,helper:a.helper,position:a.position,offset:a.positionAbs}}});d.extend(d.ui.droppable,{version:"1.8.16"});d.ui.intersect=function(a,b,c){if(!b.offset)return false;var e=(a.positionAbs||a.position.absolute).left,g=e+a.helperProportions.width,f=(a.positionAbs||a.position.absolute).top,h=f+a.helperProportions.height,i=b.offset.left,k=i+b.proportions.width,j=b.offset.top,l=j+b.proportions.height;
+switch(c){case "fit":return i<=e&&g<=k&&j<=f&&h<=l;case "intersect":return i<e+a.helperProportions.width/2&&g-a.helperProportions.width/2<k&&j<f+a.helperProportions.height/2&&h-a.helperProportions.height/2<l;case "pointer":return d.ui.isOver((a.positionAbs||a.position.absolute).top+(a.clickOffset||a.offset.click).top,(a.positionAbs||a.position.absolute).left+(a.clickOffset||a.offset.click).left,j,i,b.proportions.height,b.proportions.width);case "touch":return(f>=j&&f<=l||h>=j&&h<=l||f<j&&h>l)&&(e>=
+i&&e<=k||g>=i&&g<=k||e<i&&g>k);default:return false}};d.ui.ddmanager={current:null,droppables:{"default":[]},prepareOffsets:function(a,b){var c=d.ui.ddmanager.droppables[a.options.scope]||[],e=b?b.type:null,g=(a.currentItem||a.element).find(":data(droppable)").andSelf(),f=0;a:for(;f<c.length;f++)if(!(c[f].options.disabled||a&&!c[f].accept.call(c[f].element[0],a.currentItem||a.element))){for(var h=0;h<g.length;h++)if(g[h]==c[f].element[0]){c[f].proportions.height=0;continue a}c[f].visible=c[f].element.css("display")!=
+"none";if(c[f].visible){e=="mousedown"&&c[f]._activate.call(c[f],b);c[f].offset=c[f].element.offset();c[f].proportions={width:c[f].element[0].offsetWidth,height:c[f].element[0].offsetHeight}}}},drop:function(a,b){var c=false;d.each(d.ui.ddmanager.droppables[a.options.scope]||[],function(){if(this.options){if(!this.options.disabled&&this.visible&&d.ui.intersect(a,this,this.options.tolerance))c=c||this._drop.call(this,b);if(!this.options.disabled&&this.visible&&this.accept.call(this.element[0],a.currentItem||
+a.element)){this.isout=1;this.isover=0;this._deactivate.call(this,b)}}});return c},dragStart:function(a,b){a.element.parents(":not(body,html)").bind("scroll.droppable",function(){a.options.refreshPositions||d.ui.ddmanager.prepareOffsets(a,b)})},drag:function(a,b){a.options.refreshPositions&&d.ui.ddmanager.prepareOffsets(a,b);d.each(d.ui.ddmanager.droppables[a.options.scope]||[],function(){if(!(this.options.disabled||this.greedyChild||!this.visible)){var c=d.ui.intersect(a,this,this.options.tolerance);
+if(c=!c&&this.isover==1?"isout":c&&this.isover==0?"isover":null){var e;if(this.options.greedy){var g=this.element.parents(":data(droppable):eq(0)");if(g.length){e=d.data(g[0],"droppable");e.greedyChild=c=="isover"?1:0}}if(e&&c=="isover"){e.isover=0;e.isout=1;e._out.call(e,b)}this[c]=1;this[c=="isout"?"isover":"isout"]=0;this[c=="isover"?"_over":"_out"].call(this,b);if(e&&c=="isout"){e.isout=0;e.isover=1;e._over.call(e,b)}}}})},dragStop:function(a,b){a.element.parents(":not(body,html)").unbind("scroll.droppable");
+a.options.refreshPositions||d.ui.ddmanager.prepareOffsets(a,b)}}})(jQuery);
+;/*
+ * jQuery UI Resizable 1.8.16
+ *
+ * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
+ * Dual licensed under the MIT or GPL Version 2 licenses.
+ * http://jquery.org/license
+ *
+ * http://docs.jquery.com/UI/Resizables
+ *
+ * Depends:
+ *	jquery.ui.core.js
+ *	jquery.ui.mouse.js
+ *	jquery.ui.widget.js
+ */
+(function(e){e.widget("ui.resizable",e.ui.mouse,{widgetEventPrefix:"resize",options:{alsoResize:false,animate:false,animateDuration:"slow",animateEasing:"swing",aspectRatio:false,autoHide:false,containment:false,ghost:false,grid:false,handles:"e,s,se",helper:false,maxHeight:null,maxWidth:null,minHeight:10,minWidth:10,zIndex:1E3},_create:function(){var b=this,a=this.options;this.element.addClass("ui-resizable");e.extend(this,{_aspectRatio:!!a.aspectRatio,aspectRatio:a.aspectRatio,originalElement:this.element,
+_proportionallyResizeElements:[],_helper:a.helper||a.ghost||a.animate?a.helper||"ui-resizable-helper":null});if(this.element[0].nodeName.match(/canvas|textarea|input|select|button|img/i)){/relative/.test(this.element.css("position"))&&e.browser.opera&&this.element.css({position:"relative",top:"auto",left:"auto"});this.element.wrap(e('<div class="ui-wrapper" style="overflow: hidden;"></div>').css({position:this.element.css("position"),width:this.element.outerWidth(),height:this.element.outerHeight(),
+top:this.element.css("top"),left:this.element.css("left")}));this.element=this.element.parent().data("resizable",this.element.data("resizable"));this.elementIsWrapper=true;this.element.css({marginLeft:this.originalElement.css("marginLeft"),marginTop:this.originalElement.css("marginTop"),marginRight:this.originalElement.css("marginRight"),marginBottom:this.originalElement.css("marginBottom")});this.originalElement.css({marginLeft:0,marginTop:0,marginRight:0,marginBottom:0});this.originalResizeStyle=
+this.originalElement.css("resize");this.originalElement.css("resize","none");this._proportionallyResizeElements.push(this.originalElement.css({position:"static",zoom:1,display:"block"}));this.originalElement.css({margin:this.originalElement.css("margin")});this._proportionallyResize()}this.handles=a.handles||(!e(".ui-resizable-handle",this.element).length?"e,s,se":{n:".ui-resizable-n",e:".ui-resizable-e",s:".ui-resizable-s",w:".ui-resizable-w",se:".ui-resizable-se",sw:".ui-resizable-sw",ne:".ui-resizable-ne",
+nw:".ui-resizable-nw"});if(this.handles.constructor==String){if(this.handles=="all")this.handles="n,e,s,w,se,sw,ne,nw";var c=this.handles.split(",");this.handles={};for(var d=0;d<c.length;d++){var f=e.trim(c[d]),g=e('<div class="ui-resizable-handle '+("ui-resizable-"+f)+'"></div>');/sw|se|ne|nw/.test(f)&&g.css({zIndex:++a.zIndex});"se"==f&&g.addClass("ui-icon ui-icon-gripsmall-diagonal-se");this.handles[f]=".ui-resizable-"+f;this.element.append(g)}}this._renderAxis=function(h){h=h||this.element;for(var i in this.handles){if(this.handles[i].constructor==
+String)this.handles[i]=e(this.handles[i],this.element).show();if(this.elementIsWrapper&&this.originalElement[0].nodeName.match(/textarea|input|select|button/i)){var j=e(this.handles[i],this.element),l=0;l=/sw|ne|nw|se|n|s/.test(i)?j.outerHeight():j.outerWidth();j=["padding",/ne|nw|n/.test(i)?"Top":/se|sw|s/.test(i)?"Bottom":/^e$/.test(i)?"Right":"Left"].join("");h.css(j,l);this._proportionallyResize()}e(this.handles[i])}};this._renderAxis(this.element);this._handles=e(".ui-resizable-handle",this.element).disableSelection();
+this._handles.mouseover(function(){if(!b.resizing){if(this.className)var h=this.className.match(/ui-resizable-(se|sw|ne|nw|n|e|s|w)/i);b.axis=h&&h[1]?h[1]:"se"}});if(a.autoHide){this._handles.hide();e(this.element).addClass("ui-resizable-autohide").hover(function(){if(!a.disabled){e(this).removeClass("ui-resizable-autohide");b._handles.show()}},function(){if(!a.disabled)if(!b.resizing){e(this).addClass("ui-resizable-autohide");b._handles.hide()}})}this._mouseInit()},destroy:function(){this._mouseDestroy();
+var b=function(c){e(c).removeClass("ui-resizable ui-resizable-disabled ui-resizable-resizing").removeData("resizable").unbind(".resizable").find(".ui-resizable-handle").remove()};if(this.elementIsWrapper){b(this.element);var a=this.element;a.after(this.originalElement.css({position:a.css("position"),width:a.outerWidth(),height:a.outerHeight(),top:a.css("top"),left:a.css("left")})).remove()}this.originalElement.css("resize",this.originalResizeStyle);b(this.originalElement);return this},_mouseCapture:function(b){var a=
+false;for(var c in this.handles)if(e(this.handles[c])[0]==b.target)a=true;return!this.options.disabled&&a},_mouseStart:function(b){var a=this.options,c=this.element.position(),d=this.element;this.resizing=true;this.documentScroll={top:e(document).scrollTop(),left:e(document).scrollLeft()};if(d.is(".ui-draggable")||/absolute/.test(d.css("position")))d.css({position:"absolute",top:c.top,left:c.left});e.browser.opera&&/relative/.test(d.css("position"))&&d.css({position:"relative",top:"auto",left:"auto"});
+this._renderProxy();c=m(this.helper.css("left"));var f=m(this.helper.css("top"));if(a.containment){c+=e(a.containment).scrollLeft()||0;f+=e(a.containment).scrollTop()||0}this.offset=this.helper.offset();this.position={left:c,top:f};this.size=this._helper?{width:d.outerWidth(),height:d.outerHeight()}:{width:d.width(),height:d.height()};this.originalSize=this._helper?{width:d.outerWidth(),height:d.outerHeight()}:{width:d.width(),height:d.height()};this.originalPosition={left:c,top:f};this.sizeDiff=
+{width:d.outerWidth()-d.width(),height:d.outerHeight()-d.height()};this.originalMousePosition={left:b.pageX,top:b.pageY};this.aspectRatio=typeof a.aspectRatio=="number"?a.aspectRatio:this.originalSize.width/this.originalSize.height||1;a=e(".ui-resizable-"+this.axis).css("cursor");e("body").css("cursor",a=="auto"?this.axis+"-resize":a);d.addClass("ui-resizable-resizing");this._propagate("start",b);return true},_mouseDrag:function(b){var a=this.helper,c=this.originalMousePosition,d=this._change[this.axis];
+if(!d)return false;c=d.apply(this,[b,b.pageX-c.left||0,b.pageY-c.top||0]);this._updateVirtualBoundaries(b.shiftKey);if(this._aspectRatio||b.shiftKey)c=this._updateRatio(c,b);c=this._respectSize(c,b);this._propagate("resize",b);a.css({top:this.position.top+"px",left:this.position.left+"px",width:this.size.width+"px",height:this.size.height+"px"});!this._helper&&this._proportionallyResizeElements.length&&this._proportionallyResize();this._updateCache(c);this._trigger("resize",b,this.ui());return false},
+_mouseStop:function(b){this.resizing=false;var a=this.options,c=this;if(this._helper){var d=this._proportionallyResizeElements,f=d.length&&/textarea/i.test(d[0].nodeName);d=f&&e.ui.hasScroll(d[0],"left")?0:c.sizeDiff.height;f=f?0:c.sizeDiff.width;f={width:c.helper.width()-f,height:c.helper.height()-d};d=parseInt(c.element.css("left"),10)+(c.position.left-c.originalPosition.left)||null;var g=parseInt(c.element.css("top"),10)+(c.position.top-c.originalPosition.top)||null;a.animate||this.element.css(e.extend(f,
+{top:g,left:d}));c.helper.height(c.size.height);c.helper.width(c.size.width);this._helper&&!a.animate&&this._proportionallyResize()}e("body").css("cursor","auto");this.element.removeClass("ui-resizable-resizing");this._propagate("stop",b);this._helper&&this.helper.remove();return false},_updateVirtualBoundaries:function(b){var a=this.options,c,d,f;a={minWidth:k(a.minWidth)?a.minWidth:0,maxWidth:k(a.maxWidth)?a.maxWidth:Infinity,minHeight:k(a.minHeight)?a.minHeight:0,maxHeight:k(a.maxHeight)?a.maxHeight:
+Infinity};if(this._aspectRatio||b){b=a.minHeight*this.aspectRatio;d=a.minWidth/this.aspectRatio;c=a.maxHeight*this.aspectRatio;f=a.maxWidth/this.aspectRatio;if(b>a.minWidth)a.minWidth=b;if(d>a.minHeight)a.minHeight=d;if(c<a.maxWidth)a.maxWidth=c;if(f<a.maxHeight)a.maxHeight=f}this._vBoundaries=a},_updateCache:function(b){this.offset=this.helper.offset();if(k(b.left))this.position.left=b.left;if(k(b.top))this.position.top=b.top;if(k(b.height))this.size.height=b.height;if(k(b.width))this.size.width=
+b.width},_updateRatio:function(b){var a=this.position,c=this.size,d=this.axis;if(k(b.height))b.width=b.height*this.aspectRatio;else if(k(b.width))b.height=b.width/this.aspectRatio;if(d=="sw"){b.left=a.left+(c.width-b.width);b.top=null}if(d=="nw"){b.top=a.top+(c.height-b.height);b.left=a.left+(c.width-b.width)}return b},_respectSize:function(b){var a=this._vBoundaries,c=this.axis,d=k(b.width)&&a.maxWidth&&a.maxWidth<b.width,f=k(b.height)&&a.maxHeight&&a.maxHeight<b.height,g=k(b.width)&&a.minWidth&&
+a.minWidth>b.width,h=k(b.height)&&a.minHeight&&a.minHeight>b.height;if(g)b.width=a.minWidth;if(h)b.height=a.minHeight;if(d)b.width=a.maxWidth;if(f)b.height=a.maxHeight;var i=this.originalPosition.left+this.originalSize.width,j=this.position.top+this.size.height,l=/sw|nw|w/.test(c);c=/nw|ne|n/.test(c);if(g&&l)b.left=i-a.minWidth;if(d&&l)b.left=i-a.maxWidth;if(h&&c)b.top=j-a.minHeight;if(f&&c)b.top=j-a.maxHeight;if((a=!b.width&&!b.height)&&!b.left&&b.top)b.top=null;else if(a&&!b.top&&b.left)b.left=
+null;return b},_proportionallyResize:function(){if(this._proportionallyResizeElements.length)for(var b=this.helper||this.element,a=0;a<this._proportionallyResizeElements.length;a++){var c=this._proportionallyResizeElements[a];if(!this.borderDif){var d=[c.css("borderTopWidth"),c.css("borderRightWidth"),c.css("borderBottomWidth"),c.css("borderLeftWidth")],f=[c.css("paddingTop"),c.css("paddingRight"),c.css("paddingBottom"),c.css("paddingLeft")];this.borderDif=e.map(d,function(g,h){g=parseInt(g,10)||
+0;h=parseInt(f[h],10)||0;return g+h})}e.browser.msie&&(e(b).is(":hidden")||e(b).parents(":hidden").length)||c.css({height:b.height()-this.borderDif[0]-this.borderDif[2]||0,width:b.width()-this.borderDif[1]-this.borderDif[3]||0})}},_renderProxy:function(){var b=this.options;this.elementOffset=this.element.offset();if(this._helper){this.helper=this.helper||e('<div style="overflow:hidden;"></div>');var a=e.browser.msie&&e.browser.version<7,c=a?1:0;a=a?2:-1;this.helper.addClass(this._helper).css({width:this.element.outerWidth()+
+a,height:this.element.outerHeight()+a,position:"absolute",left:this.elementOffset.left-c+"px",top:this.elementOffset.top-c+"px",zIndex:++b.zIndex});this.helper.appendTo("body").disableSelection()}else this.helper=this.element},_change:{e:function(b,a){return{width:this.originalSize.width+a}},w:function(b,a){return{left:this.originalPosition.left+a,width:this.originalSize.width-a}},n:function(b,a,c){return{top:this.originalPosition.top+c,height:this.originalSize.height-c}},s:function(b,a,c){return{height:this.originalSize.height+
+c}},se:function(b,a,c){return e.extend(this._change.s.apply(this,arguments),this._change.e.apply(this,[b,a,c]))},sw:function(b,a,c){return e.extend(this._change.s.apply(this,arguments),this._change.w.apply(this,[b,a,c]))},ne:function(b,a,c){return e.extend(this._change.n.apply(this,arguments),this._change.e.apply(this,[b,a,c]))},nw:function(b,a,c){return e.extend(this._change.n.apply(this,arguments),this._change.w.apply(this,[b,a,c]))}},_propagate:function(b,a){e.ui.plugin.call(this,b,[a,this.ui()]);
+b!="resize"&&this._trigger(b,a,this.ui())},plugins:{},ui:function(){return{originalElement:this.originalElement,element:this.element,helper:this.helper,position:this.position,size:this.size,originalSize:this.originalSize,originalPosition:this.originalPosition}}});e.extend(e.ui.resizable,{version:"1.8.16"});e.ui.plugin.add("resizable","alsoResize",{start:function(){var b=e(this).data("resizable").options,a=function(c){e(c).each(function(){var d=e(this);d.data("resizable-alsoresize",{width:parseInt(d.width(),
+10),height:parseInt(d.height(),10),left:parseInt(d.css("left"),10),top:parseInt(d.css("top"),10),position:d.css("position")})})};if(typeof b.alsoResize=="object"&&!b.alsoResize.parentNode)if(b.alsoResize.length){b.alsoResize=b.alsoResize[0];a(b.alsoResize)}else e.each(b.alsoResize,function(c){a(c)});else a(b.alsoResize)},resize:function(b,a){var c=e(this).data("resizable");b=c.options;var d=c.originalSize,f=c.originalPosition,g={height:c.size.height-d.height||0,width:c.size.width-d.width||0,top:c.position.top-
+f.top||0,left:c.position.left-f.left||0},h=function(i,j){e(i).each(function(){var l=e(this),q=e(this).data("resizable-alsoresize"),p={},r=j&&j.length?j:l.parents(a.originalElement[0]).length?["width","height"]:["width","height","top","left"];e.each(r,function(n,o){if((n=(q[o]||0)+(g[o]||0))&&n>=0)p[o]=n||null});if(e.browser.opera&&/relative/.test(l.css("position"))){c._revertToRelativePosition=true;l.css({position:"absolute",top:"auto",left:"auto"})}l.css(p)})};typeof b.alsoResize=="object"&&!b.alsoResize.nodeType?
+e.each(b.alsoResize,function(i,j){h(i,j)}):h(b.alsoResize)},stop:function(){var b=e(this).data("resizable"),a=b.options,c=function(d){e(d).each(function(){var f=e(this);f.css({position:f.data("resizable-alsoresize").position})})};if(b._revertToRelativePosition){b._revertToRelativePosition=false;typeof a.alsoResize=="object"&&!a.alsoResize.nodeType?e.each(a.alsoResize,function(d){c(d)}):c(a.alsoResize)}e(this).removeData("resizable-alsoresize")}});e.ui.plugin.add("resizable","animate",{stop:function(b){var a=
+e(this).data("resizable"),c=a.options,d=a._proportionallyResizeElements,f=d.length&&/textarea/i.test(d[0].nodeName),g=f&&e.ui.hasScroll(d[0],"left")?0:a.sizeDiff.height;f={width:a.size.width-(f?0:a.sizeDiff.width),height:a.size.height-g};g=parseInt(a.element.css("left"),10)+(a.position.left-a.originalPosition.left)||null;var h=parseInt(a.element.css("top"),10)+(a.position.top-a.originalPosition.top)||null;a.element.animate(e.extend(f,h&&g?{top:h,left:g}:{}),{duration:c.animateDuration,easing:c.animateEasing,
+step:function(){var i={width:parseInt(a.element.css("width"),10),height:parseInt(a.element.css("height"),10),top:parseInt(a.element.css("top"),10),left:parseInt(a.element.css("left"),10)};d&&d.length&&e(d[0]).css({width:i.width,height:i.height});a._updateCache(i);a._propagate("resize",b)}})}});e.ui.plugin.add("resizable","containment",{start:function(){var b=e(this).data("resizable"),a=b.element,c=b.options.containment;if(a=c instanceof e?c.get(0):/parent/.test(c)?a.parent().get(0):c){b.containerElement=
+e(a);if(/document/.test(c)||c==document){b.containerOffset={left:0,top:0};b.containerPosition={left:0,top:0};b.parentData={element:e(document),left:0,top:0,width:e(document).width(),height:e(document).height()||document.body.parentNode.scrollHeight}}else{var d=e(a),f=[];e(["Top","Right","Left","Bottom"]).each(function(i,j){f[i]=m(d.css("padding"+j))});b.containerOffset=d.offset();b.containerPosition=d.position();b.containerSize={height:d.innerHeight()-f[3],width:d.innerWidth()-f[1]};c=b.containerOffset;
+var g=b.containerSize.height,h=b.containerSize.width;h=e.ui.hasScroll(a,"left")?a.scrollWidth:h;g=e.ui.hasScroll(a)?a.scrollHeight:g;b.parentData={element:a,left:c.left,top:c.top,width:h,height:g}}}},resize:function(b){var a=e(this).data("resizable"),c=a.options,d=a.containerOffset,f=a.position;b=a._aspectRatio||b.shiftKey;var g={top:0,left:0},h=a.containerElement;if(h[0]!=document&&/static/.test(h.css("position")))g=d;if(f.left<(a._helper?d.left:0)){a.size.width+=a._helper?a.position.left-d.left:
+a.position.left-g.left;if(b)a.size.height=a.size.width/c.aspectRatio;a.position.left=c.helper?d.left:0}if(f.top<(a._helper?d.top:0)){a.size.height+=a._helper?a.position.top-d.top:a.position.top;if(b)a.size.width=a.size.height*c.aspectRatio;a.position.top=a._helper?d.top:0}a.offset.left=a.parentData.left+a.position.left;a.offset.top=a.parentData.top+a.position.top;c=Math.abs((a._helper?a.offset.left-g.left:a.offset.left-g.left)+a.sizeDiff.width);d=Math.abs((a._helper?a.offset.top-g.top:a.offset.top-
+d.top)+a.sizeDiff.height);f=a.containerElement.get(0)==a.element.parent().get(0);g=/relative|absolute/.test(a.containerElement.css("position"));if(f&&g)c-=a.parentData.left;if(c+a.size.width>=a.parentData.width){a.size.width=a.parentData.width-c;if(b)a.size.height=a.size.width/a.aspectRatio}if(d+a.size.height>=a.parentData.height){a.size.height=a.parentData.height-d;if(b)a.size.width=a.size.height*a.aspectRatio}},stop:function(){var b=e(this).data("resizable"),a=b.options,c=b.containerOffset,d=b.containerPosition,
+f=b.containerElement,g=e(b.helper),h=g.offset(),i=g.outerWidth()-b.sizeDiff.width;g=g.outerHeight()-b.sizeDiff.height;b._helper&&!a.animate&&/relative/.test(f.css("position"))&&e(this).css({left:h.left-d.left-c.left,width:i,height:g});b._helper&&!a.animate&&/static/.test(f.css("position"))&&e(this).css({left:h.left-d.left-c.left,width:i,height:g})}});e.ui.plugin.add("resizable","ghost",{start:function(){var b=e(this).data("resizable"),a=b.options,c=b.size;b.ghost=b.originalElement.clone();b.ghost.css({opacity:0.25,
+display:"block",position:"relative",height:c.height,width:c.width,margin:0,left:0,top:0}).addClass("ui-resizable-ghost").addClass(typeof a.ghost=="string"?a.ghost:"");b.ghost.appendTo(b.helper)},resize:function(){var b=e(this).data("resizable");b.ghost&&b.ghost.css({position:"relative",height:b.size.height,width:b.size.width})},stop:function(){var b=e(this).data("resizable");b.ghost&&b.helper&&b.helper.get(0).removeChild(b.ghost.get(0))}});e.ui.plugin.add("resizable","grid",{resize:function(){var b=
+e(this).data("resizable"),a=b.options,c=b.size,d=b.originalSize,f=b.originalPosition,g=b.axis;a.grid=typeof a.grid=="number"?[a.grid,a.grid]:a.grid;var h=Math.round((c.width-d.width)/(a.grid[0]||1))*(a.grid[0]||1);a=Math.round((c.height-d.height)/(a.grid[1]||1))*(a.grid[1]||1);if(/^(se|s|e)$/.test(g)){b.size.width=d.width+h;b.size.height=d.height+a}else if(/^(ne)$/.test(g)){b.size.width=d.width+h;b.size.height=d.height+a;b.position.top=f.top-a}else{if(/^(sw)$/.test(g)){b.size.width=d.width+h;b.size.height=
+d.height+a}else{b.size.width=d.width+h;b.size.height=d.height+a;b.position.top=f.top-a}b.position.left=f.left-h}}});var m=function(b){return parseInt(b,10)||0},k=function(b){return!isNaN(parseInt(b,10))}})(jQuery);
+;/*
+ * jQuery UI Selectable 1.8.16
+ *
+ * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
+ * Dual licensed under the MIT or GPL Version 2 licenses.
+ * http://jquery.org/license
+ *
+ * http://docs.jquery.com/UI/Selectables
+ *
+ * Depends:
+ *	jquery.ui.core.js
+ *	jquery.ui.mouse.js
+ *	jquery.ui.widget.js
+ */
+(function(e){e.widget("ui.selectable",e.ui.mouse,{options:{appendTo:"body",autoRefresh:true,distance:0,filter:"*",tolerance:"touch"},_create:function(){var c=this;this.element.addClass("ui-selectable");this.dragged=false;var f;this.refresh=function(){f=e(c.options.filter,c.element[0]);f.each(function(){var d=e(this),b=d.offset();e.data(this,"selectable-item",{element:this,$element:d,left:b.left,top:b.top,right:b.left+d.outerWidth(),bottom:b.top+d.outerHeight(),startselected:false,selected:d.hasClass("ui-selected"),
+selecting:d.hasClass("ui-selecting"),unselecting:d.hasClass("ui-unselecting")})})};this.refresh();this.selectees=f.addClass("ui-selectee");this._mouseInit();this.helper=e("<div class='ui-selectable-helper'></div>")},destroy:function(){this.selectees.removeClass("ui-selectee").removeData("selectable-item");this.element.removeClass("ui-selectable ui-selectable-disabled").removeData("selectable").unbind(".selectable");this._mouseDestroy();return this},_mouseStart:function(c){var f=this;this.opos=[c.pageX,
+c.pageY];if(!this.options.disabled){var d=this.options;this.selectees=e(d.filter,this.element[0]);this._trigger("start",c);e(d.appendTo).append(this.helper);this.helper.css({left:c.clientX,top:c.clientY,width:0,height:0});d.autoRefresh&&this.refresh();this.selectees.filter(".ui-selected").each(function(){var b=e.data(this,"selectable-item");b.startselected=true;if(!c.metaKey){b.$element.removeClass("ui-selected");b.selected=false;b.$element.addClass("ui-unselecting");b.unselecting=true;f._trigger("unselecting",
+c,{unselecting:b.element})}});e(c.target).parents().andSelf().each(function(){var b=e.data(this,"selectable-item");if(b){var g=!c.metaKey||!b.$element.hasClass("ui-selected");b.$element.removeClass(g?"ui-unselecting":"ui-selected").addClass(g?"ui-selecting":"ui-unselecting");b.unselecting=!g;b.selecting=g;(b.selected=g)?f._trigger("selecting",c,{selecting:b.element}):f._trigger("unselecting",c,{unselecting:b.element});return false}})}},_mouseDrag:function(c){var f=this;this.dragged=true;if(!this.options.disabled){var d=
+this.options,b=this.opos[0],g=this.opos[1],h=c.pageX,i=c.pageY;if(b>h){var j=h;h=b;b=j}if(g>i){j=i;i=g;g=j}this.helper.css({left:b,top:g,width:h-b,height:i-g});this.selectees.each(function(){var a=e.data(this,"selectable-item");if(!(!a||a.element==f.element[0])){var k=false;if(d.tolerance=="touch")k=!(a.left>h||a.right<b||a.top>i||a.bottom<g);else if(d.tolerance=="fit")k=a.left>b&&a.right<h&&a.top>g&&a.bottom<i;if(k){if(a.selected){a.$element.removeClass("ui-selected");a.selected=false}if(a.unselecting){a.$element.removeClass("ui-unselecting");
+a.unselecting=false}if(!a.selecting){a.$element.addClass("ui-selecting");a.selecting=true;f._trigger("selecting",c,{selecting:a.element})}}else{if(a.selecting)if(c.metaKey&&a.startselected){a.$element.removeClass("ui-selecting");a.selecting=false;a.$element.addClass("ui-selected");a.selected=true}else{a.$element.removeClass("ui-selecting");a.selecting=false;if(a.startselected){a.$element.addClass("ui-unselecting");a.unselecting=true}f._trigger("unselecting",c,{unselecting:a.element})}if(a.selected)if(!c.metaKey&&
+!a.startselected){a.$element.removeClass("ui-selected");a.selected=false;a.$element.addClass("ui-unselecting");a.unselecting=true;f._trigger("unselecting",c,{unselecting:a.element})}}}});return false}},_mouseStop:function(c){var f=this;this.dragged=false;e(".ui-unselecting",this.element[0]).each(function(){var d=e.data(this,"selectable-item");d.$element.removeClass("ui-unselecting");d.unselecting=false;d.startselected=false;f._trigger("unselected",c,{unselected:d.element})});e(".ui-selecting",this.element[0]).each(function(){var d=
+e.data(this,"selectable-item");d.$element.removeClass("ui-selecting").addClass("ui-selected");d.selecting=false;d.selected=true;d.startselected=true;f._trigger("selected",c,{selected:d.element})});this._trigger("stop",c);this.helper.remove();return false}});e.extend(e.ui.selectable,{version:"1.8.16"})})(jQuery);
+;/*
+ * jQuery UI Sortable 1.8.16
+ *
+ * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
+ * Dual licensed under the MIT or GPL Version 2 licenses.
+ * http://jquery.org/license
+ *
+ * http://docs.jquery.com/UI/Sortables
+ *
+ * Depends:
+ *	jquery.ui.core.js
+ *	jquery.ui.mouse.js
+ *	jquery.ui.widget.js
+ */
+(function(d){d.widget("ui.sortable",d.ui.mouse,{widgetEventPrefix:"sort",options:{appendTo:"parent",axis:false,connectWith:false,containment:false,cursor:"auto",cursorAt:false,dropOnEmpty:true,forcePlaceholderSize:false,forceHelperSize:false,grid:false,handle:false,helper:"original",items:"> *",opacity:false,placeholder:false,revert:false,scroll:true,scrollSensitivity:20,scrollSpeed:20,scope:"default",tolerance:"intersect",zIndex:1E3},_create:function(){var a=this.options;this.containerCache={};this.element.addClass("ui-sortable");
+this.refresh();this.floating=this.items.length?a.axis==="x"||/left|right/.test(this.items[0].item.css("float"))||/inline|table-cell/.test(this.items[0].item.css("display")):false;this.offset=this.element.offset();this._mouseInit()},destroy:function(){this.element.removeClass("ui-sortable ui-sortable-disabled").removeData("sortable").unbind(".sortable");this._mouseDestroy();for(var a=this.items.length-1;a>=0;a--)this.items[a].item.removeData("sortable-item");return this},_setOption:function(a,b){if(a===
+"disabled"){this.options[a]=b;this.widget()[b?"addClass":"removeClass"]("ui-sortable-disabled")}else d.Widget.prototype._setOption.apply(this,arguments)},_mouseCapture:function(a,b){if(this.reverting)return false;if(this.options.disabled||this.options.type=="static")return false;this._refreshItems(a);var c=null,e=this;d(a.target).parents().each(function(){if(d.data(this,"sortable-item")==e){c=d(this);return false}});if(d.data(a.target,"sortable-item")==e)c=d(a.target);if(!c)return false;if(this.options.handle&&
+!b){var f=false;d(this.options.handle,c).find("*").andSelf().each(function(){if(this==a.target)f=true});if(!f)return false}this.currentItem=c;this._removeCurrentsFromItems();return true},_mouseStart:function(a,b,c){b=this.options;var e=this;this.currentContainer=this;this.refreshPositions();this.helper=this._createHelper(a);this._cacheHelperProportions();this._cacheMargins();this.scrollParent=this.helper.scrollParent();this.offset=this.currentItem.offset();this.offset={top:this.offset.top-this.margins.top,
+left:this.offset.left-this.margins.left};this.helper.css("position","absolute");this.cssPosition=this.helper.css("position");d.extend(this.offset,{click:{left:a.pageX-this.offset.left,top:a.pageY-this.offset.top},parent:this._getParentOffset(),relative:this._getRelativeOffset()});this.originalPosition=this._generatePosition(a);this.originalPageX=a.pageX;this.originalPageY=a.pageY;b.cursorAt&&this._adjustOffsetFromHelper(b.cursorAt);this.domPosition={prev:this.currentItem.prev()[0],parent:this.currentItem.parent()[0]};
+this.helper[0]!=this.currentItem[0]&&this.currentItem.hide();this._createPlaceholder();b.containment&&this._setContainment();if(b.cursor){if(d("body").css("cursor"))this._storedCursor=d("body").css("cursor");d("body").css("cursor",b.cursor)}if(b.opacity){if(this.helper.css("opacity"))this._storedOpacity=this.helper.css("opacity");this.helper.css("opacity",b.opacity)}if(b.zIndex){if(this.helper.css("zIndex"))this._storedZIndex=this.helper.css("zIndex");this.helper.css("zIndex",b.zIndex)}if(this.scrollParent[0]!=
+document&&this.scrollParent[0].tagName!="HTML")this.overflowOffset=this.scrollParent.offset();this._trigger("start",a,this._uiHash());this._preserveHelperProportions||this._cacheHelperProportions();if(!c)for(c=this.containers.length-1;c>=0;c--)this.containers[c]._trigger("activate",a,e._uiHash(this));if(d.ui.ddmanager)d.ui.ddmanager.current=this;d.ui.ddmanager&&!b.dropBehaviour&&d.ui.ddmanager.prepareOffsets(this,a);this.dragging=true;this.helper.addClass("ui-sortable-helper");this._mouseDrag(a);
+return true},_mouseDrag:function(a){this.position=this._generatePosition(a);this.positionAbs=this._convertPositionTo("absolute");if(!this.lastPositionAbs)this.lastPositionAbs=this.positionAbs;if(this.options.scroll){var b=this.options,c=false;if(this.scrollParent[0]!=document&&this.scrollParent[0].tagName!="HTML"){if(this.overflowOffset.top+this.scrollParent[0].offsetHeight-a.pageY<b.scrollSensitivity)this.scrollParent[0].scrollTop=c=this.scrollParent[0].scrollTop+b.scrollSpeed;else if(a.pageY-this.overflowOffset.top<
+b.scrollSensitivity)this.scrollParent[0].scrollTop=c=this.scrollParent[0].scrollTop-b.scrollSpeed;if(this.overflowOffset.left+this.scrollParent[0].offsetWidth-a.pageX<b.scrollSensitivity)this.scrollParent[0].scrollLeft=c=this.scrollParent[0].scrollLeft+b.scrollSpeed;else if(a.pageX-this.overflowOffset.left<b.scrollSensitivity)this.scrollParent[0].scrollLeft=c=this.scrollParent[0].scrollLeft-b.scrollSpeed}else{if(a.pageY-d(document).scrollTop()<b.scrollSensitivity)c=d(document).scrollTop(d(document).scrollTop()-
+b.scrollSpeed);else if(d(window).height()-(a.pageY-d(document).scrollTop())<b.scrollSensitivity)c=d(document).scrollTop(d(document).scrollTop()+b.scrollSpeed);if(a.pageX-d(document).scrollLeft()<b.scrollSensitivity)c=d(document).scrollLeft(d(document).scrollLeft()-b.scrollSpeed);else if(d(window).width()-(a.pageX-d(document).scrollLeft())<b.scrollSensitivity)c=d(document).scrollLeft(d(document).scrollLeft()+b.scrollSpeed)}c!==false&&d.ui.ddmanager&&!b.dropBehaviour&&d.ui.ddmanager.prepareOffsets(this,
+a)}this.positionAbs=this._convertPositionTo("absolute");if(!this.options.axis||this.options.axis!="y")this.helper[0].style.left=this.position.left+"px";if(!this.options.axis||this.options.axis!="x")this.helper[0].style.top=this.position.top+"px";for(b=this.items.length-1;b>=0;b--){c=this.items[b];var e=c.item[0],f=this._intersectsWithPointer(c);if(f)if(e!=this.currentItem[0]&&this.placeholder[f==1?"next":"prev"]()[0]!=e&&!d.ui.contains(this.placeholder[0],e)&&(this.options.type=="semi-dynamic"?!d.ui.contains(this.element[0],
+e):true)){this.direction=f==1?"down":"up";if(this.options.tolerance=="pointer"||this._intersectsWithSides(c))this._rearrange(a,c);else break;this._trigger("change",a,this._uiHash());break}}this._contactContainers(a);d.ui.ddmanager&&d.ui.ddmanager.drag(this,a);this._trigger("sort",a,this._uiHash());this.lastPositionAbs=this.positionAbs;return false},_mouseStop:function(a,b){if(a){d.ui.ddmanager&&!this.options.dropBehaviour&&d.ui.ddmanager.drop(this,a);if(this.options.revert){var c=this;b=c.placeholder.offset();
+c.reverting=true;d(this.helper).animate({left:b.left-this.offset.parent.left-c.margins.left+(this.offsetParent[0]==document.body?0:this.offsetParent[0].scrollLeft),top:b.top-this.offset.parent.top-c.margins.top+(this.offsetParent[0]==document.body?0:this.offsetParent[0].scrollTop)},parseInt(this.options.revert,10)||500,function(){c._clear(a)})}else this._clear(a,b);return false}},cancel:function(){var a=this;if(this.dragging){this._mouseUp({target:null});this.options.helper=="original"?this.currentItem.css(this._storedCSS).removeClass("ui-sortable-helper"):
+this.currentItem.show();for(var b=this.containers.length-1;b>=0;b--){this.containers[b]._trigger("deactivate",null,a._uiHash(this));if(this.containers[b].containerCache.over){this.containers[b]._trigger("out",null,a._uiHash(this));this.containers[b].containerCache.over=0}}}if(this.placeholder){this.placeholder[0].parentNode&&this.placeholder[0].parentNode.removeChild(this.placeholder[0]);this.options.helper!="original"&&this.helper&&this.helper[0].parentNode&&this.helper.remove();d.extend(this,{helper:null,
+dragging:false,reverting:false,_noFinalSort:null});this.domPosition.prev?d(this.domPosition.prev).after(this.currentItem):d(this.domPosition.parent).prepend(this.currentItem)}return this},serialize:function(a){var b=this._getItemsAsjQuery(a&&a.connected),c=[];a=a||{};d(b).each(function(){var e=(d(a.item||this).attr(a.attribute||"id")||"").match(a.expression||/(.+)[-=_](.+)/);if(e)c.push((a.key||e[1]+"[]")+"="+(a.key&&a.expression?e[1]:e[2]))});!c.length&&a.key&&c.push(a.key+"=");return c.join("&")},
+toArray:function(a){var b=this._getItemsAsjQuery(a&&a.connected),c=[];a=a||{};b.each(function(){c.push(d(a.item||this).attr(a.attribute||"id")||"")});return c},_intersectsWith:function(a){var b=this.positionAbs.left,c=b+this.helperProportions.width,e=this.positionAbs.top,f=e+this.helperProportions.height,g=a.left,h=g+a.width,i=a.top,k=i+a.height,j=this.offset.click.top,l=this.offset.click.left;j=e+j>i&&e+j<k&&b+l>g&&b+l<h;return this.options.tolerance=="pointer"||this.options.forcePointerForContainers||
+this.options.tolerance!="pointer"&&this.helperProportions[this.floating?"width":"height"]>a[this.floating?"width":"height"]?j:g<b+this.helperProportions.width/2&&c-this.helperProportions.width/2<h&&i<e+this.helperProportions.height/2&&f-this.helperProportions.height/2<k},_intersectsWithPointer:function(a){var b=d.ui.isOverAxis(this.positionAbs.top+this.offset.click.top,a.top,a.height);a=d.ui.isOverAxis(this.positionAbs.left+this.offset.click.left,a.left,a.width);b=b&&a;a=this._getDragVerticalDirection();
+var c=this._getDragHorizontalDirection();if(!b)return false;return this.floating?c&&c=="right"||a=="down"?2:1:a&&(a=="down"?2:1)},_intersectsWithSides:function(a){var b=d.ui.isOverAxis(this.positionAbs.top+this.offset.click.top,a.top+a.height/2,a.height);a=d.ui.isOverAxis(this.positionAbs.left+this.offset.click.left,a.left+a.width/2,a.width);var c=this._getDragVerticalDirection(),e=this._getDragHorizontalDirection();return this.floating&&e?e=="right"&&a||e=="left"&&!a:c&&(c=="down"&&b||c=="up"&&!b)},
+_getDragVerticalDirection:function(){var a=this.positionAbs.top-this.lastPositionAbs.top;return a!=0&&(a>0?"down":"up")},_getDragHorizontalDirection:function(){var a=this.positionAbs.left-this.lastPositionAbs.left;return a!=0&&(a>0?"right":"left")},refresh:function(a){this._refreshItems(a);this.refreshPositions();return this},_connectWith:function(){var a=this.options;return a.connectWith.constructor==String?[a.connectWith]:a.connectWith},_getItemsAsjQuery:function(a){var b=[],c=[],e=this._connectWith();
+if(e&&a)for(a=e.length-1;a>=0;a--)for(var f=d(e[a]),g=f.length-1;g>=0;g--){var h=d.data(f[g],"sortable");if(h&&h!=this&&!h.options.disabled)c.push([d.isFunction(h.options.items)?h.options.items.call(h.element):d(h.options.items,h.element).not(".ui-sortable-helper").not(".ui-sortable-placeholder"),h])}c.push([d.isFunction(this.options.items)?this.options.items.call(this.element,null,{options:this.options,item:this.currentItem}):d(this.options.items,this.element).not(".ui-sortable-helper").not(".ui-sortable-placeholder"),
+this]);for(a=c.length-1;a>=0;a--)c[a][0].each(function(){b.push(this)});return d(b)},_removeCurrentsFromItems:function(){for(var a=this.currentItem.find(":data(sortable-item)"),b=0;b<this.items.length;b++)for(var c=0;c<a.length;c++)a[c]==this.items[b].item[0]&&this.items.splice(b,1)},_refreshItems:function(a){this.items=[];this.containers=[this];var b=this.items,c=[[d.isFunction(this.options.items)?this.options.items.call(this.element[0],a,{item:this.currentItem}):d(this.options.items,this.element),
+this]],e=this._connectWith();if(e)for(var f=e.length-1;f>=0;f--)for(var g=d(e[f]),h=g.length-1;h>=0;h--){var i=d.data(g[h],"sortable");if(i&&i!=this&&!i.options.disabled){c.push([d.isFunction(i.options.items)?i.options.items.call(i.element[0],a,{item:this.currentItem}):d(i.options.items,i.element),i]);this.containers.push(i)}}for(f=c.length-1;f>=0;f--){a=c[f][1];e=c[f][0];h=0;for(g=e.length;h<g;h++){i=d(e[h]);i.data("sortable-item",a);b.push({item:i,instance:a,width:0,height:0,left:0,top:0})}}},refreshPositions:function(a){if(this.offsetParent&&
+this.helper)this.offset.parent=this._getParentOffset();for(var b=this.items.length-1;b>=0;b--){var c=this.items[b];if(!(c.instance!=this.currentContainer&&this.currentContainer&&c.item[0]!=this.currentItem[0])){var e=this.options.toleranceElement?d(this.options.toleranceElement,c.item):c.item;if(!a){c.width=e.outerWidth();c.height=e.outerHeight()}e=e.offset();c.left=e.left;c.top=e.top}}if(this.options.custom&&this.options.custom.refreshContainers)this.options.custom.refreshContainers.call(this);else for(b=
+this.containers.length-1;b>=0;b--){e=this.containers[b].element.offset();this.containers[b].containerCache.left=e.left;this.containers[b].containerCache.top=e.top;this.containers[b].containerCache.width=this.containers[b].element.outerWidth();this.containers[b].containerCache.height=this.containers[b].element.outerHeight()}return this},_createPlaceholder:function(a){var b=a||this,c=b.options;if(!c.placeholder||c.placeholder.constructor==String){var e=c.placeholder;c.placeholder={element:function(){var f=
+d(document.createElement(b.currentItem[0].nodeName)).addClass(e||b.currentItem[0].className+" ui-sortable-placeholder").removeClass("ui-sortable-helper")[0];if(!e)f.style.visibility="hidden";return f},update:function(f,g){if(!(e&&!c.forcePlaceholderSize)){g.height()||g.height(b.currentItem.innerHeight()-parseInt(b.currentItem.css("paddingTop")||0,10)-parseInt(b.currentItem.css("paddingBottom")||0,10));g.width()||g.width(b.currentItem.innerWidth()-parseInt(b.currentItem.css("paddingLeft")||0,10)-parseInt(b.currentItem.css("paddingRight")||
+0,10))}}}}b.placeholder=d(c.placeholder.element.call(b.element,b.currentItem));b.currentItem.after(b.placeholder);c.placeholder.update(b,b.placeholder)},_contactContainers:function(a){for(var b=null,c=null,e=this.containers.length-1;e>=0;e--)if(!d.ui.contains(this.currentItem[0],this.containers[e].element[0]))if(this._intersectsWith(this.containers[e].containerCache)){if(!(b&&d.ui.contains(this.containers[e].element[0],b.element[0]))){b=this.containers[e];c=e}}else if(this.containers[e].containerCache.over){this.containers[e]._trigger("out",
+a,this._uiHash(this));this.containers[e].containerCache.over=0}if(b)if(this.containers.length===1){this.containers[c]._trigger("over",a,this._uiHash(this));this.containers[c].containerCache.over=1}else if(this.currentContainer!=this.containers[c]){b=1E4;e=null;for(var f=this.positionAbs[this.containers[c].floating?"left":"top"],g=this.items.length-1;g>=0;g--)if(d.ui.contains(this.containers[c].element[0],this.items[g].item[0])){var h=this.items[g][this.containers[c].floating?"left":"top"];if(Math.abs(h-
+f)<b){b=Math.abs(h-f);e=this.items[g]}}if(e||this.options.dropOnEmpty){this.currentContainer=this.containers[c];e?this._rearrange(a,e,null,true):this._rearrange(a,null,this.containers[c].element,true);this._trigger("change",a,this._uiHash());this.containers[c]._trigger("change",a,this._uiHash(this));this.options.placeholder.update(this.currentContainer,this.placeholder);this.containers[c]._trigger("over",a,this._uiHash(this));this.containers[c].containerCache.over=1}}},_createHelper:function(a){var b=
+this.options;a=d.isFunction(b.helper)?d(b.helper.apply(this.element[0],[a,this.currentItem])):b.helper=="clone"?this.currentItem.clone():this.currentItem;a.parents("body").length||d(b.appendTo!="parent"?b.appendTo:this.currentItem[0].parentNode)[0].appendChild(a[0]);if(a[0]==this.currentItem[0])this._storedCSS={width:this.currentItem[0].style.width,height:this.currentItem[0].style.height,position:this.currentItem.css("position"),top:this.currentItem.css("top"),left:this.currentItem.css("left")};if(a[0].style.width==
+""||b.forceHelperSize)a.width(this.currentItem.width());if(a[0].style.height==""||b.forceHelperSize)a.height(this.currentItem.height());return a},_adjustOffsetFromHelper:function(a){if(typeof a=="string")a=a.split(" ");if(d.isArray(a))a={left:+a[0],top:+a[1]||0};if("left"in a)this.offset.click.left=a.left+this.margins.left;if("right"in a)this.offset.click.left=this.helperProportions.width-a.right+this.margins.left;if("top"in a)this.offset.click.top=a.top+this.margins.top;if("bottom"in a)this.offset.click.top=
+this.helperProportions.height-a.bottom+this.margins.top},_getParentOffset:function(){this.offsetParent=this.helper.offsetParent();var a=this.offsetParent.offset();if(this.cssPosition=="absolute"&&this.scrollParent[0]!=document&&d.ui.contains(this.scrollParent[0],this.offsetParent[0])){a.left+=this.scrollParent.scrollLeft();a.top+=this.scrollParent.scrollTop()}if(this.offsetParent[0]==document.body||this.offsetParent[0].tagName&&this.offsetParent[0].tagName.toLowerCase()=="html"&&d.browser.msie)a=
+{top:0,left:0};return{top:a.top+(parseInt(this.offsetParent.css("borderTopWidth"),10)||0),left:a.left+(parseInt(this.offsetParent.css("borderLeftWidth"),10)||0)}},_getRelativeOffset:function(){if(this.cssPosition=="relative"){var a=this.currentItem.position();return{top:a.top-(parseInt(this.helper.css("top"),10)||0)+this.scrollParent.scrollTop(),left:a.left-(parseInt(this.helper.css("left"),10)||0)+this.scrollParent.scrollLeft()}}else return{top:0,left:0}},_cacheMargins:function(){this.margins={left:parseInt(this.currentItem.css("marginLeft"),
+10)||0,top:parseInt(this.currentItem.css("marginTop"),10)||0}},_cacheHelperProportions:function(){this.helperProportions={width:this.helper.outerWidth(),height:this.helper.outerHeight()}},_setContainment:function(){var a=this.options;if(a.containment=="parent")a.containment=this.helper[0].parentNode;if(a.containment=="document"||a.containment=="window")this.containment=[0-this.offset.relative.left-this.offset.parent.left,0-this.offset.relative.top-this.offset.parent.top,d(a.containment=="document"?
+document:window).width()-this.helperProportions.width-this.margins.left,(d(a.containment=="document"?document:window).height()||document.body.parentNode.scrollHeight)-this.helperProportions.height-this.margins.top];if(!/^(document|window|parent)$/.test(a.containment)){var b=d(a.containment)[0];a=d(a.containment).offset();var c=d(b).css("overflow")!="hidden";this.containment=[a.left+(parseInt(d(b).css("borderLeftWidth"),10)||0)+(parseInt(d(b).css("paddingLeft"),10)||0)-this.margins.left,a.top+(parseInt(d(b).css("borderTopWidth"),
+10)||0)+(parseInt(d(b).css("paddingTop"),10)||0)-this.margins.top,a.left+(c?Math.max(b.scrollWidth,b.offsetWidth):b.offsetWidth)-(parseInt(d(b).css("borderLeftWidth"),10)||0)-(parseInt(d(b).css("paddingRight"),10)||0)-this.helperProportions.width-this.margins.left,a.top+(c?Math.max(b.scrollHeight,b.offsetHeight):b.offsetHeight)-(parseInt(d(b).css("borderTopWidth"),10)||0)-(parseInt(d(b).css("paddingBottom"),10)||0)-this.helperProportions.height-this.margins.top]}},_convertPositionTo:function(a,b){if(!b)b=
+this.position;a=a=="absolute"?1:-1;var c=this.cssPosition=="absolute"&&!(this.scrollParent[0]!=document&&d.ui.contains(this.scrollParent[0],this.offsetParent[0]))?this.offsetParent:this.scrollParent,e=/(html|body)/i.test(c[0].tagName);return{top:b.top+this.offset.relative.top*a+this.offset.parent.top*a-(d.browser.safari&&this.cssPosition=="fixed"?0:(this.cssPosition=="fixed"?-this.scrollParent.scrollTop():e?0:c.scrollTop())*a),left:b.left+this.offset.relative.left*a+this.offset.parent.left*a-(d.browser.safari&&
+this.cssPosition=="fixed"?0:(this.cssPosition=="fixed"?-this.scrollParent.scrollLeft():e?0:c.scrollLeft())*a)}},_generatePosition:function(a){var b=this.options,c=this.cssPosition=="absolute"&&!(this.scrollParent[0]!=document&&d.ui.contains(this.scrollParent[0],this.offsetParent[0]))?this.offsetParent:this.scrollParent,e=/(html|body)/i.test(c[0].tagName);if(this.cssPosition=="relative"&&!(this.scrollParent[0]!=document&&this.scrollParent[0]!=this.offsetParent[0]))this.offset.relative=this._getRelativeOffset();
+var f=a.pageX,g=a.pageY;if(this.originalPosition){if(this.containment){if(a.pageX-this.offset.click.left<this.containment[0])f=this.containment[0]+this.offset.click.left;if(a.pageY-this.offset.click.top<this.containment[1])g=this.containment[1]+this.offset.click.top;if(a.pageX-this.offset.click.left>this.containment[2])f=this.containment[2]+this.offset.click.left;if(a.pageY-this.offset.click.top>this.containment[3])g=this.containment[3]+this.offset.click.top}if(b.grid){g=this.originalPageY+Math.round((g-
+this.originalPageY)/b.grid[1])*b.grid[1];g=this.containment?!(g-this.offset.click.top<this.containment[1]||g-this.offset.click.top>this.containment[3])?g:!(g-this.offset.click.top<this.containment[1])?g-b.grid[1]:g+b.grid[1]:g;f=this.originalPageX+Math.round((f-this.originalPageX)/b.grid[0])*b.grid[0];f=this.containment?!(f-this.offset.click.left<this.containment[0]||f-this.offset.click.left>this.containment[2])?f:!(f-this.offset.click.left<this.containment[0])?f-b.grid[0]:f+b.grid[0]:f}}return{top:g-
+this.offset.click.top-this.offset.relative.top-this.offset.parent.top+(d.browser.safari&&this.cssPosition=="fixed"?0:this.cssPosition=="fixed"?-this.scrollParent.scrollTop():e?0:c.scrollTop()),left:f-this.offset.click.left-this.offset.relative.left-this.offset.parent.left+(d.browser.safari&&this.cssPosition=="fixed"?0:this.cssPosition=="fixed"?-this.scrollParent.scrollLeft():e?0:c.scrollLeft())}},_rearrange:function(a,b,c,e){c?c[0].appendChild(this.placeholder[0]):b.item[0].parentNode.insertBefore(this.placeholder[0],
+this.direction=="down"?b.item[0]:b.item[0].nextSibling);this.counter=this.counter?++this.counter:1;var f=this,g=this.counter;window.setTimeout(function(){g==f.counter&&f.refreshPositions(!e)},0)},_clear:function(a,b){this.reverting=false;var c=[];!this._noFinalSort&&this.currentItem.parent().length&&this.placeholder.before(this.currentItem);this._noFinalSort=null;if(this.helper[0]==this.currentItem[0]){for(var e in this._storedCSS)if(this._storedCSS[e]=="auto"||this._storedCSS[e]=="static")this._storedCSS[e]=
+"";this.currentItem.css(this._storedCSS).removeClass("ui-sortable-helper")}else this.currentItem.show();this.fromOutside&&!b&&c.push(function(f){this._trigger("receive",f,this._uiHash(this.fromOutside))});if((this.fromOutside||this.domPosition.prev!=this.currentItem.prev().not(".ui-sortable-helper")[0]||this.domPosition.parent!=this.currentItem.parent()[0])&&!b)c.push(function(f){this._trigger("update",f,this._uiHash())});if(!d.ui.contains(this.element[0],this.currentItem[0])){b||c.push(function(f){this._trigger("remove",
+f,this._uiHash())});for(e=this.containers.length-1;e>=0;e--)if(d.ui.contains(this.containers[e].element[0],this.currentItem[0])&&!b){c.push(function(f){return function(g){f._trigger("receive",g,this._uiHash(this))}}.call(this,this.containers[e]));c.push(function(f){return function(g){f._trigger("update",g,this._uiHash(this))}}.call(this,this.containers[e]))}}for(e=this.containers.length-1;e>=0;e--){b||c.push(function(f){return function(g){f._trigger("deactivate",g,this._uiHash(this))}}.call(this,
+this.containers[e]));if(this.containers[e].containerCache.over){c.push(function(f){return function(g){f._trigger("out",g,this._uiHash(this))}}.call(this,this.containers[e]));this.containers[e].containerCache.over=0}}this._storedCursor&&d("body").css("cursor",this._storedCursor);this._storedOpacity&&this.helper.css("opacity",this._storedOpacity);if(this._storedZIndex)this.helper.css("zIndex",this._storedZIndex=="auto"?"":this._storedZIndex);this.dragging=false;if(this.cancelHelperRemoval){if(!b){this._trigger("beforeStop",
+a,this._uiHash());for(e=0;e<c.length;e++)c[e].call(this,a);this._trigger("stop",a,this._uiHash())}return false}b||this._trigger("beforeStop",a,this._uiHash());this.placeholder[0].parentNode.removeChild(this.placeholder[0]);this.helper[0]!=this.currentItem[0]&&this.helper.remove();this.helper=null;if(!b){for(e=0;e<c.length;e++)c[e].call(this,a);this._trigger("stop",a,this._uiHash())}this.fromOutside=false;return true},_trigger:function(){d.Widget.prototype._trigger.apply(this,arguments)===false&&this.cancel()},
+_uiHash:function(a){var b=a||this;return{helper:b.helper,placeholder:b.placeholder||d([]),position:b.position,originalPosition:b.originalPosition,offset:b.positionAbs,item:b.currentItem,sender:a?a.element:null}}});d.extend(d.ui.sortable,{version:"1.8.16"})})(jQuery);
+;/*
+ * jQuery UI Accordion 1.8.16
+ *
+ * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
+ * Dual licensed under the MIT or GPL Version 2 licenses.
+ * http://jquery.org/license
+ *
+ * http://docs.jquery.com/UI/Accordion
+ *
+ * Depends:
+ *	jquery.ui.core.js
+ *	jquery.ui.widget.js
+ */
+(function(c){c.widget("ui.accordion",{options:{active:0,animated:"slide",autoHeight:true,clearStyle:false,collapsible:false,event:"click",fillSpace:false,header:"> li > :first-child,> :not(li):even",icons:{header:"ui-icon-triangle-1-e",headerSelected:"ui-icon-triangle-1-s"},navigation:false,navigationFilter:function(){return this.href.toLowerCase()===location.href.toLowerCase()}},_create:function(){var a=this,b=a.options;a.running=0;a.element.addClass("ui-accordion ui-widget ui-helper-reset").children("li").addClass("ui-accordion-li-fix");
+a.headers=a.element.find(b.header).addClass("ui-accordion-header ui-helper-reset ui-state-default ui-corner-all").bind("mouseenter.accordion",function(){b.disabled||c(this).addClass("ui-state-hover")}).bind("mouseleave.accordion",function(){b.disabled||c(this).removeClass("ui-state-hover")}).bind("focus.accordion",function(){b.disabled||c(this).addClass("ui-state-focus")}).bind("blur.accordion",function(){b.disabled||c(this).removeClass("ui-state-focus")});a.headers.next().addClass("ui-accordion-content ui-helper-reset ui-widget-content ui-corner-bottom");
+if(b.navigation){var d=a.element.find("a").filter(b.navigationFilter).eq(0);if(d.length){var h=d.closest(".ui-accordion-header");a.active=h.length?h:d.closest(".ui-accordion-content").prev()}}a.active=a._findActive(a.active||b.active).addClass("ui-state-default ui-state-active").toggleClass("ui-corner-all").toggleClass("ui-corner-top");a.active.next().addClass("ui-accordion-content-active");a._createIcons();a.resize();a.element.attr("role","tablist");a.headers.attr("role","tab").bind("keydown.accordion",
+function(f){return a._keydown(f)}).next().attr("role","tabpanel");a.headers.not(a.active||"").attr({"aria-expanded":"false","aria-selected":"false",tabIndex:-1}).next().hide();a.active.length?a.active.attr({"aria-expanded":"true","aria-selected":"true",tabIndex:0}):a.headers.eq(0).attr("tabIndex",0);c.browser.safari||a.headers.find("a").attr("tabIndex",-1);b.event&&a.headers.bind(b.event.split(" ").join(".accordion ")+".accordion",function(f){a._clickHandler.call(a,f,this);f.preventDefault()})},_createIcons:function(){var a=
+this.options;if(a.icons){c("<span></span>").addClass("ui-icon "+a.icons.header).prependTo(this.headers);this.active.children(".ui-icon").toggleClass(a.icons.header).toggleClass(a.icons.headerSelected);this.element.addClass("ui-accordion-icons")}},_destroyIcons:function(){this.headers.children(".ui-icon").remove();this.element.removeClass("ui-accordion-icons")},destroy:function(){var a=this.options;this.element.removeClass("ui-accordion ui-widget ui-helper-reset").removeAttr("role");this.headers.unbind(".accordion").removeClass("ui-accordion-header ui-accordion-disabled ui-helper-reset ui-state-default ui-corner-all ui-state-active ui-state-disabled ui-corner-top").removeAttr("role").removeAttr("aria-expanded").removeAttr("aria-selected").removeAttr("tabIndex");
+this.headers.find("a").removeAttr("tabIndex");this._destroyIcons();var b=this.headers.next().css("display","").removeAttr("role").removeClass("ui-helper-reset ui-widget-content ui-corner-bottom ui-accordion-content ui-accordion-content-active ui-accordion-disabled ui-state-disabled");if(a.autoHeight||a.fillHeight)b.css("height","");return c.Widget.prototype.destroy.call(this)},_setOption:function(a,b){c.Widget.prototype._setOption.apply(this,arguments);a=="active"&&this.activate(b);if(a=="icons"){this._destroyIcons();
+b&&this._createIcons()}if(a=="disabled")this.headers.add(this.headers.next())[b?"addClass":"removeClass"]("ui-accordion-disabled ui-state-disabled")},_keydown:function(a){if(!(this.options.disabled||a.altKey||a.ctrlKey)){var b=c.ui.keyCode,d=this.headers.length,h=this.headers.index(a.target),f=false;switch(a.keyCode){case b.RIGHT:case b.DOWN:f=this.headers[(h+1)%d];break;case b.LEFT:case b.UP:f=this.headers[(h-1+d)%d];break;case b.SPACE:case b.ENTER:this._clickHandler({target:a.target},a.target);
+a.preventDefault()}if(f){c(a.target).attr("tabIndex",-1);c(f).attr("tabIndex",0);f.focus();return false}return true}},resize:function(){var a=this.options,b;if(a.fillSpace){if(c.browser.msie){var d=this.element.parent().css("overflow");this.element.parent().css("overflow","hidden")}b=this.element.parent().height();c.browser.msie&&this.element.parent().css("overflow",d);this.headers.each(function(){b-=c(this).outerHeight(true)});this.headers.next().each(function(){c(this).height(Math.max(0,b-c(this).innerHeight()+
+c(this).height()))}).css("overflow","auto")}else if(a.autoHeight){b=0;this.headers.next().each(function(){b=Math.max(b,c(this).height("").height())}).height(b)}return this},activate:function(a){this.options.active=a;a=this._findActive(a)[0];this._clickHandler({target:a},a);return this},_findActive:function(a){return a?typeof a==="number"?this.headers.filter(":eq("+a+")"):this.headers.not(this.headers.not(a)):a===false?c([]):this.headers.filter(":eq(0)")},_clickHandler:function(a,b){var d=this.options;
+if(!d.disabled)if(a.target){a=c(a.currentTarget||b);b=a[0]===this.active[0];d.active=d.collapsible&&b?false:this.headers.index(a);if(!(this.running||!d.collapsible&&b)){var h=this.active;j=a.next();g=this.active.next();e={options:d,newHeader:b&&d.collapsible?c([]):a,oldHeader:this.active,newContent:b&&d.collapsible?c([]):j,oldContent:g};var f=this.headers.index(this.active[0])>this.headers.index(a[0]);this.active=b?c([]):a;this._toggle(j,g,e,b,f);h.removeClass("ui-state-active ui-corner-top").addClass("ui-state-default ui-corner-all").children(".ui-icon").removeClass(d.icons.headerSelected).addClass(d.icons.header);
+if(!b){a.removeClass("ui-state-default ui-corner-all").addClass("ui-state-active ui-corner-top").children(".ui-icon").removeClass(d.icons.header).addClass(d.icons.headerSelected);a.next().addClass("ui-accordion-content-active")}}}else if(d.collapsible){this.active.removeClass("ui-state-active ui-corner-top").addClass("ui-state-default ui-corner-all").children(".ui-icon").removeClass(d.icons.headerSelected).addClass(d.icons.header);this.active.next().addClass("ui-accordion-content-active");var g=this.active.next(),
+e={options:d,newHeader:c([]),oldHeader:d.active,newContent:c([]),oldContent:g},j=this.active=c([]);this._toggle(j,g,e)}},_toggle:function(a,b,d,h,f){var g=this,e=g.options;g.toShow=a;g.toHide=b;g.data=d;var j=function(){if(g)return g._completed.apply(g,arguments)};g._trigger("changestart",null,g.data);g.running=b.size()===0?a.size():b.size();if(e.animated){d={};d=e.collapsible&&h?{toShow:c([]),toHide:b,complete:j,down:f,autoHeight:e.autoHeight||e.fillSpace}:{toShow:a,toHide:b,complete:j,down:f,autoHeight:e.autoHeight||
+e.fillSpace};if(!e.proxied)e.proxied=e.animated;if(!e.proxiedDuration)e.proxiedDuration=e.duration;e.animated=c.isFunction(e.proxied)?e.proxied(d):e.proxied;e.duration=c.isFunction(e.proxiedDuration)?e.proxiedDuration(d):e.proxiedDuration;h=c.ui.accordion.animations;var i=e.duration,k=e.animated;if(k&&!h[k]&&!c.easing[k])k="slide";h[k]||(h[k]=function(l){this.slide(l,{easing:k,duration:i||700})});h[k](d)}else{if(e.collapsible&&h)a.toggle();else{b.hide();a.show()}j(true)}b.prev().attr({"aria-expanded":"false",
+"aria-selected":"false",tabIndex:-1}).blur();a.prev().attr({"aria-expanded":"true","aria-selected":"true",tabIndex:0}).focus()},_completed:function(a){this.running=a?0:--this.running;if(!this.running){this.options.clearStyle&&this.toShow.add(this.toHide).css({height:"",overflow:""});this.toHide.removeClass("ui-accordion-content-active");if(this.toHide.length)this.toHide.parent()[0].className=this.toHide.parent()[0].className;this._trigger("change",null,this.data)}}});c.extend(c.ui.accordion,{version:"1.8.16",
+animations:{slide:function(a,b){a=c.extend({easing:"swing",duration:300},a,b);if(a.toHide.size())if(a.toShow.size()){var d=a.toShow.css("overflow"),h=0,f={},g={},e;b=a.toShow;e=b[0].style.width;b.width(parseInt(b.parent().width(),10)-parseInt(b.css("paddingLeft"),10)-parseInt(b.css("paddingRight"),10)-(parseInt(b.css("borderLeftWidth"),10)||0)-(parseInt(b.css("borderRightWidth"),10)||0));c.each(["height","paddingTop","paddingBottom"],function(j,i){g[i]="hide";j=(""+c.css(a.toShow[0],i)).match(/^([\d+-.]+)(.*)$/);
+f[i]={value:j[1],unit:j[2]||"px"}});a.toShow.css({height:0,overflow:"hidden"}).show();a.toHide.filter(":hidden").each(a.complete).end().filter(":visible").animate(g,{step:function(j,i){if(i.prop=="height")h=i.end-i.start===0?0:(i.now-i.start)/(i.end-i.start);a.toShow[0].style[i.prop]=h*f[i.prop].value+f[i.prop].unit},duration:a.duration,easing:a.easing,complete:function(){a.autoHeight||a.toShow.css("height","");a.toShow.css({width:e,overflow:d});a.complete()}})}else a.toHide.animate({height:"hide",
+paddingTop:"hide",paddingBottom:"hide"},a);else a.toShow.animate({height:"show",paddingTop:"show",paddingBottom:"show"},a)},bounceslide:function(a){this.slide(a,{easing:a.down?"easeOutBounce":"swing",duration:a.down?1E3:200})}}})})(jQuery);
+;/*
+ * jQuery UI Autocomplete 1.8.16
+ *
+ * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
+ * Dual licensed under the MIT or GPL Version 2 licenses.
+ * http://jquery.org/license
+ *
+ * http://docs.jquery.com/UI/Autocomplete
+ *
+ * Depends:
+ *	jquery.ui.core.js
+ *	jquery.ui.widget.js
+ *	jquery.ui.position.js
+ */
+(function(d){var e=0;d.widget("ui.autocomplete",{options:{appendTo:"body",autoFocus:false,delay:300,minLength:1,position:{my:"left top",at:"left bottom",collision:"none"},source:null},pending:0,_create:function(){var a=this,b=this.element[0].ownerDocument,g;this.element.addClass("ui-autocomplete-input").attr("autocomplete","off").attr({role:"textbox","aria-autocomplete":"list","aria-haspopup":"true"}).bind("keydown.autocomplete",function(c){if(!(a.options.disabled||a.element.propAttr("readOnly"))){g=
+false;var f=d.ui.keyCode;switch(c.keyCode){case f.PAGE_UP:a._move("previousPage",c);break;case f.PAGE_DOWN:a._move("nextPage",c);break;case f.UP:a._move("previous",c);c.preventDefault();break;case f.DOWN:a._move("next",c);c.preventDefault();break;case f.ENTER:case f.NUMPAD_ENTER:if(a.menu.active){g=true;c.preventDefault()}case f.TAB:if(!a.menu.active)return;a.menu.select(c);break;case f.ESCAPE:a.element.val(a.term);a.close(c);break;default:clearTimeout(a.searching);a.searching=setTimeout(function(){if(a.term!=
+a.element.val()){a.selectedItem=null;a.search(null,c)}},a.options.delay);break}}}).bind("keypress.autocomplete",function(c){if(g){g=false;c.preventDefault()}}).bind("focus.autocomplete",function(){if(!a.options.disabled){a.selectedItem=null;a.previous=a.element.val()}}).bind("blur.autocomplete",function(c){if(!a.options.disabled){clearTimeout(a.searching);a.closing=setTimeout(function(){a.close(c);a._change(c)},150)}});this._initSource();this.response=function(){return a._response.apply(a,arguments)};
+this.menu=d("<ul></ul>").addClass("ui-autocomplete").appendTo(d(this.options.appendTo||"body",b)[0]).mousedown(function(c){var f=a.menu.element[0];d(c.target).closest(".ui-menu-item").length||setTimeout(function(){d(document).one("mousedown",function(h){h.target!==a.element[0]&&h.target!==f&&!d.ui.contains(f,h.target)&&a.close()})},1);setTimeout(function(){clearTimeout(a.closing)},13)}).menu({focus:function(c,f){f=f.item.data("item.autocomplete");false!==a._trigger("focus",c,{item:f})&&/^key/.test(c.originalEvent.type)&&
+a.element.val(f.value)},selected:function(c,f){var h=f.item.data("item.autocomplete"),i=a.previous;if(a.element[0]!==b.activeElement){a.element.focus();a.previous=i;setTimeout(function(){a.previous=i;a.selectedItem=h},1)}false!==a._trigger("select",c,{item:h})&&a.element.val(h.value);a.term=a.element.val();a.close(c);a.selectedItem=h},blur:function(){a.menu.element.is(":visible")&&a.element.val()!==a.term&&a.element.val(a.term)}}).zIndex(this.element.zIndex()+1).css({top:0,left:0}).hide().data("menu");
+d.fn.bgiframe&&this.menu.element.bgiframe()},destroy:function(){this.element.removeClass("ui-autocomplete-input").removeAttr("autocomplete").removeAttr("role").removeAttr("aria-autocomplete").removeAttr("aria-haspopup");this.menu.element.remove();d.Widget.prototype.destroy.call(this)},_setOption:function(a,b){d.Widget.prototype._setOption.apply(this,arguments);a==="source"&&this._initSource();if(a==="appendTo")this.menu.element.appendTo(d(b||"body",this.element[0].ownerDocument)[0]);a==="disabled"&&
+b&&this.xhr&&this.xhr.abort()},_initSource:function(){var a=this,b,g;if(d.isArray(this.options.source)){b=this.options.source;this.source=function(c,f){f(d.ui.autocomplete.filter(b,c.term))}}else if(typeof this.options.source==="string"){g=this.options.source;this.source=function(c,f){a.xhr&&a.xhr.abort();a.xhr=d.ajax({url:g,data:c,dataType:"json",autocompleteRequest:++e,success:function(h){this.autocompleteRequest===e&&f(h)},error:function(){this.autocompleteRequest===e&&f([])}})}}else this.source=
+this.options.source},search:function(a,b){a=a!=null?a:this.element.val();this.term=this.element.val();if(a.length<this.options.minLength)return this.close(b);clearTimeout(this.closing);if(this._trigger("search",b)!==false)return this._search(a)},_search:function(a){this.pending++;this.element.addClass("ui-autocomplete-loading");this.source({term:a},this.response)},_response:function(a){if(!this.options.disabled&&a&&a.length){a=this._normalize(a);this._suggest(a);this._trigger("open")}else this.close();
+this.pending--;this.pending||this.element.removeClass("ui-autocomplete-loading")},close:function(a){clearTimeout(this.closing);if(this.menu.element.is(":visible")){this.menu.element.hide();this.menu.deactivate();this._trigger("close",a)}},_change:function(a){this.previous!==this.element.val()&&this._trigger("change",a,{item:this.selectedItem})},_normalize:function(a){if(a.length&&a[0].label&&a[0].value)return a;return d.map(a,function(b){if(typeof b==="string")return{label:b,value:b};return d.extend({label:b.label||
+b.value,value:b.value||b.label},b)})},_suggest:function(a){var b=this.menu.element.empty().zIndex(this.element.zIndex()+1);this._renderMenu(b,a);this.menu.deactivate();this.menu.refresh();b.show();this._resizeMenu();b.position(d.extend({of:this.element},this.options.position));this.options.autoFocus&&this.menu.next(new d.Event("mouseover"))},_resizeMenu:function(){var a=this.menu.element;a.outerWidth(Math.max(a.width("").outerWidth(),this.element.outerWidth()))},_renderMenu:function(a,b){var g=this;
+d.each(b,function(c,f){g._renderItem(a,f)})},_renderItem:function(a,b){return d("<li></li>").data("item.autocomplete",b).append(d("<a></a>").text(b.label)).appendTo(a)},_move:function(a,b){if(this.menu.element.is(":visible"))if(this.menu.first()&&/^previous/.test(a)||this.menu.last()&&/^next/.test(a)){this.element.val(this.term);this.menu.deactivate()}else this.menu[a](b);else this.search(null,b)},widget:function(){return this.menu.element}});d.extend(d.ui.autocomplete,{escapeRegex:function(a){return a.replace(/[-[\]{}()*+?.,\\^$|#\s]/g,
+"\\$&")},filter:function(a,b){var g=new RegExp(d.ui.autocomplete.escapeRegex(b),"i");return d.grep(a,function(c){return g.test(c.label||c.value||c)})}})})(jQuery);
+(function(d){d.widget("ui.menu",{_create:function(){var e=this;this.element.addClass("ui-menu ui-widget ui-widget-content ui-corner-all").attr({role:"listbox","aria-activedescendant":"ui-active-menuitem"}).click(function(a){if(d(a.target).closest(".ui-menu-item a").length){a.preventDefault();e.select(a)}});this.refresh()},refresh:function(){var e=this;this.element.children("li:not(.ui-menu-item):has(a)").addClass("ui-menu-item").attr("role","menuitem").children("a").addClass("ui-corner-all").attr("tabindex",
+-1).mouseenter(function(a){e.activate(a,d(this).parent())}).mouseleave(function(){e.deactivate()})},activate:function(e,a){this.deactivate();if(this.hasScroll()){var b=a.offset().top-this.element.offset().top,g=this.element.scrollTop(),c=this.element.height();if(b<0)this.element.scrollTop(g+b);else b>=c&&this.element.scrollTop(g+b-c+a.height())}this.active=a.eq(0).children("a").addClass("ui-state-hover").attr("id","ui-active-menuitem").end();this._trigger("focus",e,{item:a})},deactivate:function(){if(this.active){this.active.children("a").removeClass("ui-state-hover").removeAttr("id");
+this._trigger("blur");this.active=null}},next:function(e){this.move("next",".ui-menu-item:first",e)},previous:function(e){this.move("prev",".ui-menu-item:last",e)},first:function(){return this.active&&!this.active.prevAll(".ui-menu-item").length},last:function(){return this.active&&!this.active.nextAll(".ui-menu-item").length},move:function(e,a,b){if(this.active){e=this.active[e+"All"](".ui-menu-item").eq(0);e.length?this.activate(b,e):this.activate(b,this.element.children(a))}else this.activate(b,
+this.element.children(a))},nextPage:function(e){if(this.hasScroll())if(!this.active||this.last())this.activate(e,this.element.children(".ui-menu-item:first"));else{var a=this.active.offset().top,b=this.element.height(),g=this.element.children(".ui-menu-item").filter(function(){var c=d(this).offset().top-a-b+d(this).height();return c<10&&c>-10});g.length||(g=this.element.children(".ui-menu-item:last"));this.activate(e,g)}else this.activate(e,this.element.children(".ui-menu-item").filter(!this.active||
+this.last()?":first":":last"))},previousPage:function(e){if(this.hasScroll())if(!this.active||this.first())this.activate(e,this.element.children(".ui-menu-item:last"));else{var a=this.active.offset().top,b=this.element.height();result=this.element.children(".ui-menu-item").filter(function(){var g=d(this).offset().top-a+b-d(this).height();return g<10&&g>-10});result.length||(result=this.element.children(".ui-menu-item:first"));this.activate(e,result)}else this.activate(e,this.element.children(".ui-menu-item").filter(!this.active||
+this.first()?":last":":first"))},hasScroll:function(){return this.element.height()<this.element[d.fn.prop?"prop":"attr"]("scrollHeight")},select:function(e){this._trigger("selected",e,{item:this.active})}})})(jQuery);
+;/*
+ * jQuery UI Button 1.8.16
+ *
+ * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
+ * Dual licensed under the MIT or GPL Version 2 licenses.
+ * http://jquery.org/license
+ *
+ * http://docs.jquery.com/UI/Button
+ *
+ * Depends:
+ *	jquery.ui.core.js
+ *	jquery.ui.widget.js
+ */
+(function(b){var h,i,j,g,l=function(){var a=b(this).find(":ui-button");setTimeout(function(){a.button("refresh")},1)},k=function(a){var c=a.name,e=a.form,f=b([]);if(c)f=e?b(e).find("[name='"+c+"']"):b("[name='"+c+"']",a.ownerDocument).filter(function(){return!this.form});return f};b.widget("ui.button",{options:{disabled:null,text:true,label:null,icons:{primary:null,secondary:null}},_create:function(){this.element.closest("form").unbind("reset.button").bind("reset.button",l);if(typeof this.options.disabled!==
+"boolean")this.options.disabled=this.element.propAttr("disabled");this._determineButtonType();this.hasTitle=!!this.buttonElement.attr("title");var a=this,c=this.options,e=this.type==="checkbox"||this.type==="radio",f="ui-state-hover"+(!e?" ui-state-active":"");if(c.label===null)c.label=this.buttonElement.html();if(this.element.is(":disabled"))c.disabled=true;this.buttonElement.addClass("ui-button ui-widget ui-state-default ui-corner-all").attr("role","button").bind("mouseenter.button",function(){if(!c.disabled){b(this).addClass("ui-state-hover");
+this===h&&b(this).addClass("ui-state-active")}}).bind("mouseleave.button",function(){c.disabled||b(this).removeClass(f)}).bind("click.button",function(d){if(c.disabled){d.preventDefault();d.stopImmediatePropagation()}});this.element.bind("focus.button",function(){a.buttonElement.addClass("ui-state-focus")}).bind("blur.button",function(){a.buttonElement.removeClass("ui-state-focus")});if(e){this.element.bind("change.button",function(){g||a.refresh()});this.buttonElement.bind("mousedown.button",function(d){if(!c.disabled){g=
+false;i=d.pageX;j=d.pageY}}).bind("mouseup.button",function(d){if(!c.disabled)if(i!==d.pageX||j!==d.pageY)g=true})}if(this.type==="checkbox")this.buttonElement.bind("click.button",function(){if(c.disabled||g)return false;b(this).toggleClass("ui-state-active");a.buttonElement.attr("aria-pressed",a.element[0].checked)});else if(this.type==="radio")this.buttonElement.bind("click.button",function(){if(c.disabled||g)return false;b(this).addClass("ui-state-active");a.buttonElement.attr("aria-pressed","true");
+var d=a.element[0];k(d).not(d).map(function(){return b(this).button("widget")[0]}).removeClass("ui-state-active").attr("aria-pressed","false")});else{this.buttonElement.bind("mousedown.button",function(){if(c.disabled)return false;b(this).addClass("ui-state-active");h=this;b(document).one("mouseup",function(){h=null})}).bind("mouseup.button",function(){if(c.disabled)return false;b(this).removeClass("ui-state-active")}).bind("keydown.button",function(d){if(c.disabled)return false;if(d.keyCode==b.ui.keyCode.SPACE||
+d.keyCode==b.ui.keyCode.ENTER)b(this).addClass("ui-state-active")}).bind("keyup.button",function(){b(this).removeClass("ui-state-active")});this.buttonElement.is("a")&&this.buttonElement.keyup(function(d){d.keyCode===b.ui.keyCode.SPACE&&b(this).click()})}this._setOption("disabled",c.disabled);this._resetButton()},_determineButtonType:function(){this.type=this.element.is(":checkbox")?"checkbox":this.element.is(":radio")?"radio":this.element.is("input")?"input":"button";if(this.type==="checkbox"||this.type===
+"radio"){var a=this.element.parents().filter(":last"),c="label[for='"+this.element.attr("id")+"']";this.buttonElement=a.find(c);if(!this.buttonElement.length){a=a.length?a.siblings():this.element.siblings();this.buttonElement=a.filter(c);if(!this.buttonElement.length)this.buttonElement=a.find(c)}this.element.addClass("ui-helper-hidden-accessible");(a=this.element.is(":checked"))&&this.buttonElement.addClass("ui-state-active");this.buttonElement.attr("aria-pressed",a)}else this.buttonElement=this.element},
+widget:function(){return this.buttonElement},destroy:function(){this.element.removeClass("ui-helper-hidden-accessible");this.buttonElement.removeClass("ui-button ui-widget ui-state-default ui-corner-all ui-state-hover ui-state-active  ui-button-icons-only ui-button-icon-only ui-button-text-icons ui-button-text-icon-primary ui-button-text-icon-secondary ui-button-text-only").removeAttr("role").removeAttr("aria-pressed").html(this.buttonElement.find(".ui-button-text").html());this.hasTitle||this.buttonElement.removeAttr("title");
+b.Widget.prototype.destroy.call(this)},_setOption:function(a,c){b.Widget.prototype._setOption.apply(this,arguments);if(a==="disabled")c?this.element.propAttr("disabled",true):this.element.propAttr("disabled",false);else this._resetButton()},refresh:function(){var a=this.element.is(":disabled");a!==this.options.disabled&&this._setOption("disabled",a);if(this.type==="radio")k(this.element[0]).each(function(){b(this).is(":checked")?b(this).button("widget").addClass("ui-state-active").attr("aria-pressed",
+"true"):b(this).button("widget").removeClass("ui-state-active").attr("aria-pressed","false")});else if(this.type==="checkbox")this.element.is(":checked")?this.buttonElement.addClass("ui-state-active").attr("aria-pressed","true"):this.buttonElement.removeClass("ui-state-active").attr("aria-pressed","false")},_resetButton:function(){if(this.type==="input")this.options.label&&this.element.val(this.options.label);else{var a=this.buttonElement.removeClass("ui-button-icons-only ui-button-icon-only ui-button-text-icons ui-button-text-icon-primary ui-button-text-icon-secondary ui-button-text-only"),
+c=b("<span></span>").addClass("ui-button-text").html(this.options.label).appendTo(a.empty()).text(),e=this.options.icons,f=e.primary&&e.secondary,d=[];if(e.primary||e.secondary){if(this.options.text)d.push("ui-button-text-icon"+(f?"s":e.primary?"-primary":"-secondary"));e.primary&&a.prepend("<span class='ui-button-icon-primary ui-icon "+e.primary+"'></span>");e.secondary&&a.append("<span class='ui-button-icon-secondary ui-icon "+e.secondary+"'></span>");if(!this.options.text){d.push(f?"ui-button-icons-only":
+"ui-button-icon-only");this.hasTitle||a.attr("title",c)}}else d.push("ui-button-text-only");a.addClass(d.join(" "))}}});b.widget("ui.buttonset",{options:{items:":button, :submit, :reset, :checkbox, :radio, a, :data(button)"},_create:function(){this.element.addClass("ui-buttonset")},_init:function(){this.refresh()},_setOption:function(a,c){a==="disabled"&&this.buttons.button("option",a,c);b.Widget.prototype._setOption.apply(this,arguments)},refresh:function(){var a=this.element.css("direction")===
+"ltr";this.buttons=this.element.find(this.options.items).filter(":ui-button").button("refresh").end().not(":ui-button").button().end().map(function(){return b(this).button("widget")[0]}).removeClass("ui-corner-all ui-corner-left ui-corner-right").filter(":first").addClass(a?"ui-corner-left":"ui-corner-right").end().filter(":last").addClass(a?"ui-corner-right":"ui-corner-left").end().end()},destroy:function(){this.element.removeClass("ui-buttonset");this.buttons.map(function(){return b(this).button("widget")[0]}).removeClass("ui-corner-left ui-corner-right").end().button("destroy");
+b.Widget.prototype.destroy.call(this)}})})(jQuery);
+;/*
+ * jQuery UI Dialog 1.8.16
+ *
+ * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
+ * Dual licensed under the MIT or GPL Version 2 licenses.
+ * http://jquery.org/license
+ *
+ * http://docs.jquery.com/UI/Dialog
+ *
+ * Depends:
+ *	jquery.ui.core.js
+ *	jquery.ui.widget.js
+ *  jquery.ui.button.js
+ *	jquery.ui.draggable.js
+ *	jquery.ui.mouse.js
+ *	jquery.ui.position.js
+ *	jquery.ui.resizable.js
+ */
+(function(c,l){var m={buttons:true,height:true,maxHeight:true,maxWidth:true,minHeight:true,minWidth:true,width:true},n={maxHeight:true,maxWidth:true,minHeight:true,minWidth:true},o=c.attrFn||{val:true,css:true,html:true,text:true,data:true,width:true,height:true,offset:true,click:true};c.widget("ui.dialog",{options:{autoOpen:true,buttons:{},closeOnEscape:true,closeText:"close",dialogClass:"",draggable:true,hide:null,height:"auto",maxHeight:false,maxWidth:false,minHeight:150,minWidth:150,modal:false,
+position:{my:"center",at:"center",collision:"fit",using:function(a){var b=c(this).css(a).offset().top;b<0&&c(this).css("top",a.top-b)}},resizable:true,show:null,stack:true,title:"",width:300,zIndex:1E3},_create:function(){this.originalTitle=this.element.attr("title");if(typeof this.originalTitle!=="string")this.originalTitle="";this.options.title=this.options.title||this.originalTitle;var a=this,b=a.options,d=b.title||"&#160;",e=c.ui.dialog.getTitleId(a.element),g=(a.uiDialog=c("<div></div>")).appendTo(document.body).hide().addClass("ui-dialog ui-widget ui-widget-content ui-corner-all "+
+b.dialogClass).css({zIndex:b.zIndex}).attr("tabIndex",-1).css("outline",0).keydown(function(i){if(b.closeOnEscape&&!i.isDefaultPrevented()&&i.keyCode&&i.keyCode===c.ui.keyCode.ESCAPE){a.close(i);i.preventDefault()}}).attr({role:"dialog","aria-labelledby":e}).mousedown(function(i){a.moveToTop(false,i)});a.element.show().removeAttr("title").addClass("ui-dialog-content ui-widget-content").appendTo(g);var f=(a.uiDialogTitlebar=c("<div></div>")).addClass("ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix").prependTo(g),
+h=c('<a href="#"></a>').addClass("ui-dialog-titlebar-close ui-corner-all").attr("role","button").hover(function(){h.addClass("ui-state-hover")},function(){h.removeClass("ui-state-hover")}).focus(function(){h.addClass("ui-state-focus")}).blur(function(){h.removeClass("ui-state-focus")}).click(function(i){a.close(i);return false}).appendTo(f);(a.uiDialogTitlebarCloseText=c("<span></span>")).addClass("ui-icon ui-icon-closethick").text(b.closeText).appendTo(h);c("<span></span>").addClass("ui-dialog-title").attr("id",
+e).html(d).prependTo(f);if(c.isFunction(b.beforeclose)&&!c.isFunction(b.beforeClose))b.beforeClose=b.beforeclose;f.find("*").add(f).disableSelection();b.draggable&&c.fn.draggable&&a._makeDraggable();b.resizable&&c.fn.resizable&&a._makeResizable();a._createButtons(b.buttons);a._isOpen=false;c.fn.bgiframe&&g.bgiframe()},_init:function(){this.options.autoOpen&&this.open()},destroy:function(){var a=this;a.overlay&&a.overlay.destroy();a.uiDialog.hide();a.element.unbind(".dialog").removeData("dialog").removeClass("ui-dialog-content ui-widget-content").hide().appendTo("body");
+a.uiDialog.remove();a.originalTitle&&a.element.attr("title",a.originalTitle);return a},widget:function(){return this.uiDialog},close:function(a){var b=this,d,e;if(false!==b._trigger("beforeClose",a)){b.overlay&&b.overlay.destroy();b.uiDialog.unbind("keypress.ui-dialog");b._isOpen=false;if(b.options.hide)b.uiDialog.hide(b.options.hide,function(){b._trigger("close",a)});else{b.uiDialog.hide();b._trigger("close",a)}c.ui.dialog.overlay.resize();if(b.options.modal){d=0;c(".ui-dialog").each(function(){if(this!==
+b.uiDialog[0]){e=c(this).css("z-index");isNaN(e)||(d=Math.max(d,e))}});c.ui.dialog.maxZ=d}return b}},isOpen:function(){return this._isOpen},moveToTop:function(a,b){var d=this,e=d.options;if(e.modal&&!a||!e.stack&&!e.modal)return d._trigger("focus",b);if(e.zIndex>c.ui.dialog.maxZ)c.ui.dialog.maxZ=e.zIndex;if(d.overlay){c.ui.dialog.maxZ+=1;d.overlay.$el.css("z-index",c.ui.dialog.overlay.maxZ=c.ui.dialog.maxZ)}a={scrollTop:d.element.scrollTop(),scrollLeft:d.element.scrollLeft()};c.ui.dialog.maxZ+=1;
+d.uiDialog.css("z-index",c.ui.dialog.maxZ);d.element.attr(a);d._trigger("focus",b);return d},open:function(){if(!this._isOpen){var a=this,b=a.options,d=a.uiDialog;a.overlay=b.modal?new c.ui.dialog.overlay(a):null;a._size();a._position(b.position);d.show(b.show);a.moveToTop(true);b.modal&&d.bind("keypress.ui-dialog",function(e){if(e.keyCode===c.ui.keyCode.TAB){var g=c(":tabbable",this),f=g.filter(":first");g=g.filter(":last");if(e.target===g[0]&&!e.shiftKey){f.focus(1);return false}else if(e.target===
+f[0]&&e.shiftKey){g.focus(1);return false}}});c(a.element.find(":tabbable").get().concat(d.find(".ui-dialog-buttonpane :tabbable").get().concat(d.get()))).eq(0).focus();a._isOpen=true;a._trigger("open");return a}},_createButtons:function(a){var b=this,d=false,e=c("<div></div>").addClass("ui-dialog-buttonpane ui-widget-content ui-helper-clearfix"),g=c("<div></div>").addClass("ui-dialog-buttonset").appendTo(e);b.uiDialog.find(".ui-dialog-buttonpane").remove();typeof a==="object"&&a!==null&&c.each(a,
+function(){return!(d=true)});if(d){c.each(a,function(f,h){h=c.isFunction(h)?{click:h,text:f}:h;var i=c('<button type="button"></button>').click(function(){h.click.apply(b.element[0],arguments)}).appendTo(g);c.each(h,function(j,k){if(j!=="click")j in o?i[j](k):i.attr(j,k)});c.fn.button&&i.button()});e.appendTo(b.uiDialog)}},_makeDraggable:function(){function a(f){return{position:f.position,offset:f.offset}}var b=this,d=b.options,e=c(document),g;b.uiDialog.draggable({cancel:".ui-dialog-content, .ui-dialog-titlebar-close",
+handle:".ui-dialog-titlebar",containment:"document",start:function(f,h){g=d.height==="auto"?"auto":c(this).height();c(this).height(c(this).height()).addClass("ui-dialog-dragging");b._trigger("dragStart",f,a(h))},drag:function(f,h){b._trigger("drag",f,a(h))},stop:function(f,h){d.position=[h.position.left-e.scrollLeft(),h.position.top-e.scrollTop()];c(this).removeClass("ui-dialog-dragging").height(g);b._trigger("dragStop",f,a(h));c.ui.dialog.overlay.resize()}})},_makeResizable:function(a){function b(f){return{originalPosition:f.originalPosition,
+originalSize:f.originalSize,position:f.position,size:f.size}}a=a===l?this.options.resizable:a;var d=this,e=d.options,g=d.uiDialog.css("position");a=typeof a==="string"?a:"n,e,s,w,se,sw,ne,nw";d.uiDialog.resizable({cancel:".ui-dialog-content",containment:"document",alsoResize:d.element,maxWidth:e.maxWidth,maxHeight:e.maxHeight,minWidth:e.minWidth,minHeight:d._minHeight(),handles:a,start:function(f,h){c(this).addClass("ui-dialog-resizing");d._trigger("resizeStart",f,b(h))},resize:function(f,h){d._trigger("resize",
+f,b(h))},stop:function(f,h){c(this).removeClass("ui-dialog-resizing");e.height=c(this).height();e.width=c(this).width();d._trigger("resizeStop",f,b(h));c.ui.dialog.overlay.resize()}}).css("position",g).find(".ui-resizable-se").addClass("ui-icon ui-icon-grip-diagonal-se")},_minHeight:function(){var a=this.options;return a.height==="auto"?a.minHeight:Math.min(a.minHeight,a.height)},_position:function(a){var b=[],d=[0,0],e;if(a){if(typeof a==="string"||typeof a==="object"&&"0"in a){b=a.split?a.split(" "):
+[a[0],a[1]];if(b.length===1)b[1]=b[0];c.each(["left","top"],function(g,f){if(+b[g]===b[g]){d[g]=b[g];b[g]=f}});a={my:b.join(" "),at:b.join(" "),offset:d.join(" ")}}a=c.extend({},c.ui.dialog.prototype.options.position,a)}else a=c.ui.dialog.prototype.options.position;(e=this.uiDialog.is(":visible"))||this.uiDialog.show();this.uiDialog.css({top:0,left:0}).position(c.extend({of:window},a));e||this.uiDialog.hide()},_setOptions:function(a){var b=this,d={},e=false;c.each(a,function(g,f){b._setOption(g,f);
+if(g in m)e=true;if(g in n)d[g]=f});e&&this._size();this.uiDialog.is(":data(resizable)")&&this.uiDialog.resizable("option",d)},_setOption:function(a,b){var d=this,e=d.uiDialog;switch(a){case "beforeclose":a="beforeClose";break;case "buttons":d._createButtons(b);break;case "closeText":d.uiDialogTitlebarCloseText.text(""+b);break;case "dialogClass":e.removeClass(d.options.dialogClass).addClass("ui-dialog ui-widget ui-widget-content ui-corner-all "+b);break;case "disabled":b?e.addClass("ui-dialog-disabled"):
+e.removeClass("ui-dialog-disabled");break;case "draggable":var g=e.is(":data(draggable)");g&&!b&&e.draggable("destroy");!g&&b&&d._makeDraggable();break;case "position":d._position(b);break;case "resizable":(g=e.is(":data(resizable)"))&&!b&&e.resizable("destroy");g&&typeof b==="string"&&e.resizable("option","handles",b);!g&&b!==false&&d._makeResizable(b);break;case "title":c(".ui-dialog-title",d.uiDialogTitlebar).html(""+(b||"&#160;"));break}c.Widget.prototype._setOption.apply(d,arguments)},_size:function(){var a=
+this.options,b,d,e=this.uiDialog.is(":visible");this.element.show().css({width:"auto",minHeight:0,height:0});if(a.minWidth>a.width)a.width=a.minWidth;b=this.uiDialog.css({height:"auto",width:a.width}).height();d=Math.max(0,a.minHeight-b);if(a.height==="auto")if(c.support.minHeight)this.element.css({minHeight:d,height:"auto"});else{this.uiDialog.show();a=this.element.css("height","auto").height();e||this.uiDialog.hide();this.element.height(Math.max(a,d))}else this.element.height(Math.max(a.height-
+b,0));this.uiDialog.is(":data(resizable)")&&this.uiDialog.resizable("option","minHeight",this._minHeight())}});c.extend(c.ui.dialog,{version:"1.8.16",uuid:0,maxZ:0,getTitleId:function(a){a=a.attr("id");if(!a){this.uuid+=1;a=this.uuid}return"ui-dialog-title-"+a},overlay:function(a){this.$el=c.ui.dialog.overlay.create(a)}});c.extend(c.ui.dialog.overlay,{instances:[],oldInstances:[],maxZ:0,events:c.map("focus,mousedown,mouseup,keydown,keypress,click".split(","),function(a){return a+".dialog-overlay"}).join(" "),
+create:function(a){if(this.instances.length===0){setTimeout(function(){c.ui.dialog.overlay.instances.length&&c(document).bind(c.ui.dialog.overlay.events,function(d){if(c(d.target).zIndex()<c.ui.dialog.overlay.maxZ)return false})},1);c(document).bind("keydown.dialog-overlay",function(d){if(a.options.closeOnEscape&&!d.isDefaultPrevented()&&d.keyCode&&d.keyCode===c.ui.keyCode.ESCAPE){a.close(d);d.preventDefault()}});c(window).bind("resize.dialog-overlay",c.ui.dialog.overlay.resize)}var b=(this.oldInstances.pop()||
+c("<div></div>").addClass("ui-widget-overlay")).appendTo(document.body).css({width:this.width(),height:this.height()});c.fn.bgiframe&&b.bgiframe();this.instances.push(b);return b},destroy:function(a){var b=c.inArray(a,this.instances);b!=-1&&this.oldInstances.push(this.instances.splice(b,1)[0]);this.instances.length===0&&c([document,window]).unbind(".dialog-overlay");a.remove();var d=0;c.each(this.instances,function(){d=Math.max(d,this.css("z-index"))});this.maxZ=d},height:function(){var a,b;if(c.browser.msie&&
+c.browser.version<7){a=Math.max(document.documentElement.scrollHeight,document.body.scrollHeight);b=Math.max(document.documentElement.offsetHeight,document.body.offsetHeight);return a<b?c(window).height()+"px":a+"px"}else return c(document).height()+"px"},width:function(){var a,b;if(c.browser.msie){a=Math.max(document.documentElement.scrollWidth,document.body.scrollWidth);b=Math.max(document.documentElement.offsetWidth,document.body.offsetWidth);return a<b?c(window).width()+"px":a+"px"}else return c(document).width()+
+"px"},resize:function(){var a=c([]);c.each(c.ui.dialog.overlay.instances,function(){a=a.add(this)});a.css({width:0,height:0}).css({width:c.ui.dialog.overlay.width(),height:c.ui.dialog.overlay.height()})}});c.extend(c.ui.dialog.overlay.prototype,{destroy:function(){c.ui.dialog.overlay.destroy(this.$el)}})})(jQuery);
+;/*
+ * jQuery UI Slider 1.8.16
+ *
+ * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
+ * Dual licensed under the MIT or GPL Version 2 licenses.
+ * http://jquery.org/license
+ *
+ * http://docs.jquery.com/UI/Slider
+ *
+ * Depends:
+ *	jquery.ui.core.js
+ *	jquery.ui.mouse.js
+ *	jquery.ui.widget.js
+ */
+(function(d){d.widget("ui.slider",d.ui.mouse,{widgetEventPrefix:"slide",options:{animate:false,distance:0,max:100,min:0,orientation:"horizontal",range:false,step:1,value:0,values:null},_create:function(){var a=this,b=this.options,c=this.element.find(".ui-slider-handle").addClass("ui-state-default ui-corner-all"),f=b.values&&b.values.length||1,e=[];this._mouseSliding=this._keySliding=false;this._animateOff=true;this._handleIndex=null;this._detectOrientation();this._mouseInit();this.element.addClass("ui-slider ui-slider-"+
+this.orientation+" ui-widget ui-widget-content ui-corner-all"+(b.disabled?" ui-slider-disabled ui-disabled":""));this.range=d([]);if(b.range){if(b.range===true){if(!b.values)b.values=[this._valueMin(),this._valueMin()];if(b.values.length&&b.values.length!==2)b.values=[b.values[0],b.values[0]]}this.range=d("<div></div>").appendTo(this.element).addClass("ui-slider-range ui-widget-header"+(b.range==="min"||b.range==="max"?" ui-slider-range-"+b.range:""))}for(var j=c.length;j<f;j+=1)e.push("<a class='ui-slider-handle ui-state-default ui-corner-all' href='#'></a>");
+this.handles=c.add(d(e.join("")).appendTo(a.element));this.handle=this.handles.eq(0);this.handles.add(this.range).filter("a").click(function(g){g.preventDefault()}).hover(function(){b.disabled||d(this).addClass("ui-state-hover")},function(){d(this).removeClass("ui-state-hover")}).focus(function(){if(b.disabled)d(this).blur();else{d(".ui-slider .ui-state-focus").removeClass("ui-state-focus");d(this).addClass("ui-state-focus")}}).blur(function(){d(this).removeClass("ui-state-focus")});this.handles.each(function(g){d(this).data("index.ui-slider-handle",
+g)});this.handles.keydown(function(g){var k=true,l=d(this).data("index.ui-slider-handle"),i,h,m;if(!a.options.disabled){switch(g.keyCode){case d.ui.keyCode.HOME:case d.ui.keyCode.END:case d.ui.keyCode.PAGE_UP:case d.ui.keyCode.PAGE_DOWN:case d.ui.keyCode.UP:case d.ui.keyCode.RIGHT:case d.ui.keyCode.DOWN:case d.ui.keyCode.LEFT:k=false;if(!a._keySliding){a._keySliding=true;d(this).addClass("ui-state-active");i=a._start(g,l);if(i===false)return}break}m=a.options.step;i=a.options.values&&a.options.values.length?
+(h=a.values(l)):(h=a.value());switch(g.keyCode){case d.ui.keyCode.HOME:h=a._valueMin();break;case d.ui.keyCode.END:h=a._valueMax();break;case d.ui.keyCode.PAGE_UP:h=a._trimAlignValue(i+(a._valueMax()-a._valueMin())/5);break;case d.ui.keyCode.PAGE_DOWN:h=a._trimAlignValue(i-(a._valueMax()-a._valueMin())/5);break;case d.ui.keyCode.UP:case d.ui.keyCode.RIGHT:if(i===a._valueMax())return;h=a._trimAlignValue(i+m);break;case d.ui.keyCode.DOWN:case d.ui.keyCode.LEFT:if(i===a._valueMin())return;h=a._trimAlignValue(i-
+m);break}a._slide(g,l,h);return k}}).keyup(function(g){var k=d(this).data("index.ui-slider-handle");if(a._keySliding){a._keySliding=false;a._stop(g,k);a._change(g,k);d(this).removeClass("ui-state-active")}});this._refreshValue();this._animateOff=false},destroy:function(){this.handles.remove();this.range.remove();this.element.removeClass("ui-slider ui-slider-horizontal ui-slider-vertical ui-slider-disabled ui-widget ui-widget-content ui-corner-all").removeData("slider").unbind(".slider");this._mouseDestroy();
+return this},_mouseCapture:function(a){var b=this.options,c,f,e,j,g;if(b.disabled)return false;this.elementSize={width:this.element.outerWidth(),height:this.element.outerHeight()};this.elementOffset=this.element.offset();c=this._normValueFromMouse({x:a.pageX,y:a.pageY});f=this._valueMax()-this._valueMin()+1;j=this;this.handles.each(function(k){var l=Math.abs(c-j.values(k));if(f>l){f=l;e=d(this);g=k}});if(b.range===true&&this.values(1)===b.min){g+=1;e=d(this.handles[g])}if(this._start(a,g)===false)return false;
+this._mouseSliding=true;j._handleIndex=g;e.addClass("ui-state-active").focus();b=e.offset();this._clickOffset=!d(a.target).parents().andSelf().is(".ui-slider-handle")?{left:0,top:0}:{left:a.pageX-b.left-e.width()/2,top:a.pageY-b.top-e.height()/2-(parseInt(e.css("borderTopWidth"),10)||0)-(parseInt(e.css("borderBottomWidth"),10)||0)+(parseInt(e.css("marginTop"),10)||0)};this.handles.hasClass("ui-state-hover")||this._slide(a,g,c);return this._animateOff=true},_mouseStart:function(){return true},_mouseDrag:function(a){var b=
+this._normValueFromMouse({x:a.pageX,y:a.pageY});this._slide(a,this._handleIndex,b);return false},_mouseStop:function(a){this.handles.removeClass("ui-state-active");this._mouseSliding=false;this._stop(a,this._handleIndex);this._change(a,this._handleIndex);this._clickOffset=this._handleIndex=null;return this._animateOff=false},_detectOrientation:function(){this.orientation=this.options.orientation==="vertical"?"vertical":"horizontal"},_normValueFromMouse:function(a){var b;if(this.orientation==="horizontal"){b=
+this.elementSize.width;a=a.x-this.elementOffset.left-(this._clickOffset?this._clickOffset.left:0)}else{b=this.elementSize.height;a=a.y-this.elementOffset.top-(this._clickOffset?this._clickOffset.top:0)}b=a/b;if(b>1)b=1;if(b<0)b=0;if(this.orientation==="vertical")b=1-b;a=this._valueMax()-this._valueMin();return this._trimAlignValue(this._valueMin()+b*a)},_start:function(a,b){var c={handle:this.handles[b],value:this.value()};if(this.options.values&&this.options.values.length){c.value=this.values(b);
+c.values=this.values()}return this._trigger("start",a,c)},_slide:function(a,b,c){var f;if(this.options.values&&this.options.values.length){f=this.values(b?0:1);if(this.options.values.length===2&&this.options.range===true&&(b===0&&c>f||b===1&&c<f))c=f;if(c!==this.values(b)){f=this.values();f[b]=c;a=this._trigger("slide",a,{handle:this.handles[b],value:c,values:f});this.values(b?0:1);a!==false&&this.values(b,c,true)}}else if(c!==this.value()){a=this._trigger("slide",a,{handle:this.handles[b],value:c});
+a!==false&&this.value(c)}},_stop:function(a,b){var c={handle:this.handles[b],value:this.value()};if(this.options.values&&this.options.values.length){c.value=this.values(b);c.values=this.values()}this._trigger("stop",a,c)},_change:function(a,b){if(!this._keySliding&&!this._mouseSliding){var c={handle:this.handles[b],value:this.value()};if(this.options.values&&this.options.values.length){c.value=this.values(b);c.values=this.values()}this._trigger("change",a,c)}},value:function(a){if(arguments.length){this.options.value=
+this._trimAlignValue(a);this._refreshValue();this._change(null,0)}else return this._value()},values:function(a,b){var c,f,e;if(arguments.length>1){this.options.values[a]=this._trimAlignValue(b);this._refreshValue();this._change(null,a)}else if(arguments.length)if(d.isArray(arguments[0])){c=this.options.values;f=arguments[0];for(e=0;e<c.length;e+=1){c[e]=this._trimAlignValue(f[e]);this._change(null,e)}this._refreshValue()}else return this.options.values&&this.options.values.length?this._values(a):
+this.value();else return this._values()},_setOption:function(a,b){var c,f=0;if(d.isArray(this.options.values))f=this.options.values.length;d.Widget.prototype._setOption.apply(this,arguments);switch(a){case "disabled":if(b){this.handles.filter(".ui-state-focus").blur();this.handles.removeClass("ui-state-hover");this.handles.propAttr("disabled",true);this.element.addClass("ui-disabled")}else{this.handles.propAttr("disabled",false);this.element.removeClass("ui-disabled")}break;case "orientation":this._detectOrientation();
+this.element.removeClass("ui-slider-horizontal ui-slider-vertical").addClass("ui-slider-"+this.orientation);this._refreshValue();break;case "value":this._animateOff=true;this._refreshValue();this._change(null,0);this._animateOff=false;break;case "values":this._animateOff=true;this._refreshValue();for(c=0;c<f;c+=1)this._change(null,c);this._animateOff=false;break}},_value:function(){var a=this.options.value;return a=this._trimAlignValue(a)},_values:function(a){var b,c;if(arguments.length){b=this.options.values[a];
+return b=this._trimAlignValue(b)}else{b=this.options.values.slice();for(c=0;c<b.length;c+=1)b[c]=this._trimAlignValue(b[c]);return b}},_trimAlignValue:function(a){if(a<=this._valueMin())return this._valueMin();if(a>=this._valueMax())return this._valueMax();var b=this.options.step>0?this.options.step:1,c=(a-this._valueMin())%b;a=a-c;if(Math.abs(c)*2>=b)a+=c>0?b:-b;return parseFloat(a.toFixed(5))},_valueMin:function(){return this.options.min},_valueMax:function(){return this.options.max},_refreshValue:function(){var a=
+this.options.range,b=this.options,c=this,f=!this._animateOff?b.animate:false,e,j={},g,k,l,i;if(this.options.values&&this.options.values.length)this.handles.each(function(h){e=(c.values(h)-c._valueMin())/(c._valueMax()-c._valueMin())*100;j[c.orientation==="horizontal"?"left":"bottom"]=e+"%";d(this).stop(1,1)[f?"animate":"css"](j,b.animate);if(c.options.range===true)if(c.orientation==="horizontal"){if(h===0)c.range.stop(1,1)[f?"animate":"css"]({left:e+"%"},b.animate);if(h===1)c.range[f?"animate":"css"]({width:e-
+g+"%"},{queue:false,duration:b.animate})}else{if(h===0)c.range.stop(1,1)[f?"animate":"css"]({bottom:e+"%"},b.animate);if(h===1)c.range[f?"animate":"css"]({height:e-g+"%"},{queue:false,duration:b.animate})}g=e});else{k=this.value();l=this._valueMin();i=this._valueMax();e=i!==l?(k-l)/(i-l)*100:0;j[c.orientation==="horizontal"?"left":"bottom"]=e+"%";this.handle.stop(1,1)[f?"animate":"css"](j,b.animate);if(a==="min"&&this.orientation==="horizontal")this.range.stop(1,1)[f?"animate":"css"]({width:e+"%"},
+b.animate);if(a==="max"&&this.orientation==="horizontal")this.range[f?"animate":"css"]({width:100-e+"%"},{queue:false,duration:b.animate});if(a==="min"&&this.orientation==="vertical")this.range.stop(1,1)[f?"animate":"css"]({height:e+"%"},b.animate);if(a==="max"&&this.orientation==="vertical")this.range[f?"animate":"css"]({height:100-e+"%"},{queue:false,duration:b.animate})}}});d.extend(d.ui.slider,{version:"1.8.16"})})(jQuery);
+;/*
+ * jQuery UI Tabs 1.8.16
+ *
+ * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
+ * Dual licensed under the MIT or GPL Version 2 licenses.
+ * http://jquery.org/license
+ *
+ * http://docs.jquery.com/UI/Tabs
+ *
+ * Depends:
+ *	jquery.ui.core.js
+ *	jquery.ui.widget.js
+ */
+(function(d,p){function u(){return++v}function w(){return++x}var v=0,x=0;d.widget("ui.tabs",{options:{add:null,ajaxOptions:null,cache:false,cookie:null,collapsible:false,disable:null,disabled:[],enable:null,event:"click",fx:null,idPrefix:"ui-tabs-",load:null,panelTemplate:"<div></div>",remove:null,select:null,show:null,spinner:"<em>Loading&#8230;</em>",tabTemplate:"<li><a href='#{href}'><span>#{label}</span></a></li>"},_create:function(){this._tabify(true)},_setOption:function(b,e){if(b=="selected")this.options.collapsible&&
+e==this.options.selected||this.select(e);else{this.options[b]=e;this._tabify()}},_tabId:function(b){return b.title&&b.title.replace(/\s/g,"_").replace(/[^\w\u00c0-\uFFFF-]/g,"")||this.options.idPrefix+u()},_sanitizeSelector:function(b){return b.replace(/:/g,"\\:")},_cookie:function(){var b=this.cookie||(this.cookie=this.options.cookie.name||"ui-tabs-"+w());return d.cookie.apply(null,[b].concat(d.makeArray(arguments)))},_ui:function(b,e){return{tab:b,panel:e,index:this.anchors.index(b)}},_cleanup:function(){this.lis.filter(".ui-state-processing").removeClass("ui-state-processing").find("span:data(label.tabs)").each(function(){var b=
+d(this);b.html(b.data("label.tabs")).removeData("label.tabs")})},_tabify:function(b){function e(g,f){g.css("display","");!d.support.opacity&&f.opacity&&g[0].style.removeAttribute("filter")}var a=this,c=this.options,h=/^#.+/;this.list=this.element.find("ol,ul").eq(0);this.lis=d(" > li:has(a[href])",this.list);this.anchors=this.lis.map(function(){return d("a",this)[0]});this.panels=d([]);this.anchors.each(function(g,f){var i=d(f).attr("href"),l=i.split("#")[0],q;if(l&&(l===location.toString().split("#")[0]||
+(q=d("base")[0])&&l===q.href)){i=f.hash;f.href=i}if(h.test(i))a.panels=a.panels.add(a.element.find(a._sanitizeSelector(i)));else if(i&&i!=="#"){d.data(f,"href.tabs",i);d.data(f,"load.tabs",i.replace(/#.*$/,""));i=a._tabId(f);f.href="#"+i;f=a.element.find("#"+i);if(!f.length){f=d(c.panelTemplate).attr("id",i).addClass("ui-tabs-panel ui-widget-content ui-corner-bottom").insertAfter(a.panels[g-1]||a.list);f.data("destroy.tabs",true)}a.panels=a.panels.add(f)}else c.disabled.push(g)});if(b){this.element.addClass("ui-tabs ui-widget ui-widget-content ui-corner-all");
+this.list.addClass("ui-tabs-nav ui-helper-reset ui-helper-clearfix ui-widget-header ui-corner-all");this.lis.addClass("ui-state-default ui-corner-top");this.panels.addClass("ui-tabs-panel ui-widget-content ui-corner-bottom");if(c.selected===p){location.hash&&this.anchors.each(function(g,f){if(f.hash==location.hash){c.selected=g;return false}});if(typeof c.selected!=="number"&&c.cookie)c.selected=parseInt(a._cookie(),10);if(typeof c.selected!=="number"&&this.lis.filter(".ui-tabs-selected").length)c.selected=
+this.lis.index(this.lis.filter(".ui-tabs-selected"));c.selected=c.selected||(this.lis.length?0:-1)}else if(c.selected===null)c.selected=-1;c.selected=c.selected>=0&&this.anchors[c.selected]||c.selected<0?c.selected:0;c.disabled=d.unique(c.disabled.concat(d.map(this.lis.filter(".ui-state-disabled"),function(g){return a.lis.index(g)}))).sort();d.inArray(c.selected,c.disabled)!=-1&&c.disabled.splice(d.inArray(c.selected,c.disabled),1);this.panels.addClass("ui-tabs-hide");this.lis.removeClass("ui-tabs-selected ui-state-active");
+if(c.selected>=0&&this.anchors.length){a.element.find(a._sanitizeSelector(a.anchors[c.selected].hash)).removeClass("ui-tabs-hide");this.lis.eq(c.selected).addClass("ui-tabs-selected ui-state-active");a.element.queue("tabs",function(){a._trigger("show",null,a._ui(a.anchors[c.selected],a.element.find(a._sanitizeSelector(a.anchors[c.selected].hash))[0]))});this.load(c.selected)}d(window).bind("unload",function(){a.lis.add(a.anchors).unbind(".tabs");a.lis=a.anchors=a.panels=null})}else c.selected=this.lis.index(this.lis.filter(".ui-tabs-selected"));
+this.element[c.collapsible?"addClass":"removeClass"]("ui-tabs-collapsible");c.cookie&&this._cookie(c.selected,c.cookie);b=0;for(var j;j=this.lis[b];b++)d(j)[d.inArray(b,c.disabled)!=-1&&!d(j).hasClass("ui-tabs-selected")?"addClass":"removeClass"]("ui-state-disabled");c.cache===false&&this.anchors.removeData("cache.tabs");this.lis.add(this.anchors).unbind(".tabs");if(c.event!=="mouseover"){var k=function(g,f){f.is(":not(.ui-state-disabled)")&&f.addClass("ui-state-"+g)},n=function(g,f){f.removeClass("ui-state-"+
+g)};this.lis.bind("mouseover.tabs",function(){k("hover",d(this))});this.lis.bind("mouseout.tabs",function(){n("hover",d(this))});this.anchors.bind("focus.tabs",function(){k("focus",d(this).closest("li"))});this.anchors.bind("blur.tabs",function(){n("focus",d(this).closest("li"))})}var m,o;if(c.fx)if(d.isArray(c.fx)){m=c.fx[0];o=c.fx[1]}else m=o=c.fx;var r=o?function(g,f){d(g).closest("li").addClass("ui-tabs-selected ui-state-active");f.hide().removeClass("ui-tabs-hide").animate(o,o.duration||"normal",
+function(){e(f,o);a._trigger("show",null,a._ui(g,f[0]))})}:function(g,f){d(g).closest("li").addClass("ui-tabs-selected ui-state-active");f.removeClass("ui-tabs-hide");a._trigger("show",null,a._ui(g,f[0]))},s=m?function(g,f){f.animate(m,m.duration||"normal",function(){a.lis.removeClass("ui-tabs-selected ui-state-active");f.addClass("ui-tabs-hide");e(f,m);a.element.dequeue("tabs")})}:function(g,f){a.lis.removeClass("ui-tabs-selected ui-state-active");f.addClass("ui-tabs-hide");a.element.dequeue("tabs")};
+this.anchors.bind(c.event+".tabs",function(){var g=this,f=d(g).closest("li"),i=a.panels.filter(":not(.ui-tabs-hide)"),l=a.element.find(a._sanitizeSelector(g.hash));if(f.hasClass("ui-tabs-selected")&&!c.collapsible||f.hasClass("ui-state-disabled")||f.hasClass("ui-state-processing")||a.panels.filter(":animated").length||a._trigger("select",null,a._ui(this,l[0]))===false){this.blur();return false}c.selected=a.anchors.index(this);a.abort();if(c.collapsible)if(f.hasClass("ui-tabs-selected")){c.selected=
+-1;c.cookie&&a._cookie(c.selected,c.cookie);a.element.queue("tabs",function(){s(g,i)}).dequeue("tabs");this.blur();return false}else if(!i.length){c.cookie&&a._cookie(c.selected,c.cookie);a.element.queue("tabs",function(){r(g,l)});a.load(a.anchors.index(this));this.blur();return false}c.cookie&&a._cookie(c.selected,c.cookie);if(l.length){i.length&&a.element.queue("tabs",function(){s(g,i)});a.element.queue("tabs",function(){r(g,l)});a.load(a.anchors.index(this))}else throw"jQuery UI Tabs: Mismatching fragment identifier.";
+d.browser.msie&&this.blur()});this.anchors.bind("click.tabs",function(){return false})},_getIndex:function(b){if(typeof b=="string")b=this.anchors.index(this.anchors.filter("[href$="+b+"]"));return b},destroy:function(){var b=this.options;this.abort();this.element.unbind(".tabs").removeClass("ui-tabs ui-widget ui-widget-content ui-corner-all ui-tabs-collapsible").removeData("tabs");this.list.removeClass("ui-tabs-nav ui-helper-reset ui-helper-clearfix ui-widget-header ui-corner-all");this.anchors.each(function(){var e=
+d.data(this,"href.tabs");if(e)this.href=e;var a=d(this).unbind(".tabs");d.each(["href","load","cache"],function(c,h){a.removeData(h+".tabs")})});this.lis.unbind(".tabs").add(this.panels).each(function(){d.data(this,"destroy.tabs")?d(this).remove():d(this).removeClass("ui-state-default ui-corner-top ui-tabs-selected ui-state-active ui-state-hover ui-state-focus ui-state-disabled ui-tabs-panel ui-widget-content ui-corner-bottom ui-tabs-hide")});b.cookie&&this._cookie(null,b.cookie);return this},add:function(b,
+e,a){if(a===p)a=this.anchors.length;var c=this,h=this.options;e=d(h.tabTemplate.replace(/#\{href\}/g,b).replace(/#\{label\}/g,e));b=!b.indexOf("#")?b.replace("#",""):this._tabId(d("a",e)[0]);e.addClass("ui-state-default ui-corner-top").data("destroy.tabs",true);var j=c.element.find("#"+b);j.length||(j=d(h.panelTemplate).attr("id",b).data("destroy.tabs",true));j.addClass("ui-tabs-panel ui-widget-content ui-corner-bottom ui-tabs-hide");if(a>=this.lis.length){e.appendTo(this.list);j.appendTo(this.list[0].parentNode)}else{e.insertBefore(this.lis[a]);
+j.insertBefore(this.panels[a])}h.disabled=d.map(h.disabled,function(k){return k>=a?++k:k});this._tabify();if(this.anchors.length==1){h.selected=0;e.addClass("ui-tabs-selected ui-state-active");j.removeClass("ui-tabs-hide");this.element.queue("tabs",function(){c._trigger("show",null,c._ui(c.anchors[0],c.panels[0]))});this.load(0)}this._trigger("add",null,this._ui(this.anchors[a],this.panels[a]));return this},remove:function(b){b=this._getIndex(b);var e=this.options,a=this.lis.eq(b).remove(),c=this.panels.eq(b).remove();
+if(a.hasClass("ui-tabs-selected")&&this.anchors.length>1)this.select(b+(b+1<this.anchors.length?1:-1));e.disabled=d.map(d.grep(e.disabled,function(h){return h!=b}),function(h){return h>=b?--h:h});this._tabify();this._trigger("remove",null,this._ui(a.find("a")[0],c[0]));return this},enable:function(b){b=this._getIndex(b);var e=this.options;if(d.inArray(b,e.disabled)!=-1){this.lis.eq(b).removeClass("ui-state-disabled");e.disabled=d.grep(e.disabled,function(a){return a!=b});this._trigger("enable",null,
+this._ui(this.anchors[b],this.panels[b]));return this}},disable:function(b){b=this._getIndex(b);var e=this.options;if(b!=e.selected){this.lis.eq(b).addClass("ui-state-disabled");e.disabled.push(b);e.disabled.sort();this._trigger("disable",null,this._ui(this.anchors[b],this.panels[b]))}return this},select:function(b){b=this._getIndex(b);if(b==-1)if(this.options.collapsible&&this.options.selected!=-1)b=this.options.selected;else return this;this.anchors.eq(b).trigger(this.options.event+".tabs");return this},
+load:function(b){b=this._getIndex(b);var e=this,a=this.options,c=this.anchors.eq(b)[0],h=d.data(c,"load.tabs");this.abort();if(!h||this.element.queue("tabs").length!==0&&d.data(c,"cache.tabs"))this.element.dequeue("tabs");else{this.lis.eq(b).addClass("ui-state-processing");if(a.spinner){var j=d("span",c);j.data("label.tabs",j.html()).html(a.spinner)}this.xhr=d.ajax(d.extend({},a.ajaxOptions,{url:h,success:function(k,n){e.element.find(e._sanitizeSelector(c.hash)).html(k);e._cleanup();a.cache&&d.data(c,
+"cache.tabs",true);e._trigger("load",null,e._ui(e.anchors[b],e.panels[b]));try{a.ajaxOptions.success(k,n)}catch(m){}},error:function(k,n){e._cleanup();e._trigger("load",null,e._ui(e.anchors[b],e.panels[b]));try{a.ajaxOptions.error(k,n,b,c)}catch(m){}}}));e.element.dequeue("tabs");return this}},abort:function(){this.element.queue([]);this.panels.stop(false,true);this.element.queue("tabs",this.element.queue("tabs").splice(-2,2));if(this.xhr){this.xhr.abort();delete this.xhr}this._cleanup();return this},
+url:function(b,e){this.anchors.eq(b).removeData("cache.tabs").data("load.tabs",e);return this},length:function(){return this.anchors.length}});d.extend(d.ui.tabs,{version:"1.8.16"});d.extend(d.ui.tabs.prototype,{rotation:null,rotate:function(b,e){var a=this,c=this.options,h=a._rotate||(a._rotate=function(j){clearTimeout(a.rotation);a.rotation=setTimeout(function(){var k=c.selected;a.select(++k<a.anchors.length?k:0)},b);j&&j.stopPropagation()});e=a._unrotate||(a._unrotate=!e?function(j){j.clientX&&
+a.rotate(null)}:function(){t=c.selected;h()});if(b){this.element.bind("tabsshow",h);this.anchors.bind(c.event+".tabs",e);h()}else{clearTimeout(a.rotation);this.element.unbind("tabsshow",h);this.anchors.unbind(c.event+".tabs",e);delete this._rotate;delete this._unrotate}return this}})})(jQuery);
+;/*
+ * jQuery UI Datepicker 1.8.16
+ *
+ * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
+ * Dual licensed under the MIT or GPL Version 2 licenses.
+ * http://jquery.org/license
+ *
+ * http://docs.jquery.com/UI/Datepicker
+ *
+ * Depends:
+ *	jquery.ui.core.js
+ */
+(function(d,C){function M(){this.debug=false;this._curInst=null;this._keyEvent=false;this._disabledInputs=[];this._inDialog=this._datepickerShowing=false;this._mainDivId="ui-datepicker-div";this._inlineClass="ui-datepicker-inline";this._appendClass="ui-datepicker-append";this._triggerClass="ui-datepicker-trigger";this._dialogClass="ui-datepicker-dialog";this._disableClass="ui-datepicker-disabled";this._unselectableClass="ui-datepicker-unselectable";this._currentClass="ui-datepicker-current-day";this._dayOverClass=
+"ui-datepicker-days-cell-over";this.regional=[];this.regional[""]={closeText:"Done",prevText:"Prev",nextText:"Next",currentText:"Today",monthNames:["January","February","March","April","May","June","July","August","September","October","November","December"],monthNamesShort:["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"],dayNames:["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"],dayNamesShort:["Sun","Mon","Tue","Wed","Thu","Fri","Sat"],dayNamesMin:["Su",
+"Mo","Tu","We","Th","Fr","Sa"],weekHeader:"Wk",dateFormat:"mm/dd/yy",firstDay:0,isRTL:false,showMonthAfterYear:false,yearSuffix:""};this._defaults={showOn:"focus",showAnim:"fadeIn",showOptions:{},defaultDate:null,appendText:"",buttonText:"...",buttonImage:"",buttonImageOnly:false,hideIfNoPrevNext:false,navigationAsDateFormat:false,gotoCurrent:false,changeMonth:false,changeYear:false,yearRange:"c-10:c+10",showOtherMonths:false,selectOtherMonths:false,showWeek:false,calculateWeek:this.iso8601Week,shortYearCutoff:"+10",
+minDate:null,maxDate:null,duration:"fast",beforeShowDay:null,beforeShow:null,onSelect:null,onChangeMonthYear:null,onClose:null,numberOfMonths:1,showCurrentAtPos:0,stepMonths:1,stepBigMonths:12,altField:"",altFormat:"",constrainInput:true,showButtonPanel:false,autoSize:false,disabled:false};d.extend(this._defaults,this.regional[""]);this.dpDiv=N(d('<div id="'+this._mainDivId+'" class="ui-datepicker ui-widget ui-widget-content ui-helper-clearfix ui-corner-all"></div>'))}function N(a){return a.bind("mouseout",
+function(b){b=d(b.target).closest("button, .ui-datepicker-prev, .ui-datepicker-next, .ui-datepicker-calendar td a");b.length&&b.removeClass("ui-state-hover ui-datepicker-prev-hover ui-datepicker-next-hover")}).bind("mouseover",function(b){b=d(b.target).closest("button, .ui-datepicker-prev, .ui-datepicker-next, .ui-datepicker-calendar td a");if(!(d.datepicker._isDisabledDatepicker(J.inline?a.parent()[0]:J.input[0])||!b.length)){b.parents(".ui-datepicker-calendar").find("a").removeClass("ui-state-hover");
+b.addClass("ui-state-hover");b.hasClass("ui-datepicker-prev")&&b.addClass("ui-datepicker-prev-hover");b.hasClass("ui-datepicker-next")&&b.addClass("ui-datepicker-next-hover")}})}function H(a,b){d.extend(a,b);for(var c in b)if(b[c]==null||b[c]==C)a[c]=b[c];return a}d.extend(d.ui,{datepicker:{version:"1.8.16"}});var B=(new Date).getTime(),J;d.extend(M.prototype,{markerClassName:"hasDatepicker",maxRows:4,log:function(){this.debug&&console.log.apply("",arguments)},_widgetDatepicker:function(){return this.dpDiv},
+setDefaults:function(a){H(this._defaults,a||{});return this},_attachDatepicker:function(a,b){var c=null;for(var e in this._defaults){var f=a.getAttribute("date:"+e);if(f){c=c||{};try{c[e]=eval(f)}catch(h){c[e]=f}}}e=a.nodeName.toLowerCase();f=e=="div"||e=="span";if(!a.id){this.uuid+=1;a.id="dp"+this.uuid}var i=this._newInst(d(a),f);i.settings=d.extend({},b||{},c||{});if(e=="input")this._connectDatepicker(a,i);else f&&this._inlineDatepicker(a,i)},_newInst:function(a,b){return{id:a[0].id.replace(/([^A-Za-z0-9_-])/g,
+"\\\\$1"),input:a,selectedDay:0,selectedMonth:0,selectedYear:0,drawMonth:0,drawYear:0,inline:b,dpDiv:!b?this.dpDiv:N(d('<div class="'+this._inlineClass+' ui-datepicker ui-widget ui-widget-content ui-helper-clearfix ui-corner-all"></div>'))}},_connectDatepicker:function(a,b){var c=d(a);b.append=d([]);b.trigger=d([]);if(!c.hasClass(this.markerClassName)){this._attachments(c,b);c.addClass(this.markerClassName).keydown(this._doKeyDown).keypress(this._doKeyPress).keyup(this._doKeyUp).bind("setData.datepicker",
+function(e,f,h){b.settings[f]=h}).bind("getData.datepicker",function(e,f){return this._get(b,f)});this._autoSize(b);d.data(a,"datepicker",b);b.settings.disabled&&this._disableDatepicker(a)}},_attachments:function(a,b){var c=this._get(b,"appendText"),e=this._get(b,"isRTL");b.append&&b.append.remove();if(c){b.append=d('<span class="'+this._appendClass+'">'+c+"</span>");a[e?"before":"after"](b.append)}a.unbind("focus",this._showDatepicker);b.trigger&&b.trigger.remove();c=this._get(b,"showOn");if(c==
+"focus"||c=="both")a.focus(this._showDatepicker);if(c=="button"||c=="both"){c=this._get(b,"buttonText");var f=this._get(b,"buttonImage");b.trigger=d(this._get(b,"buttonImageOnly")?d("<img/>").addClass(this._triggerClass).attr({src:f,alt:c,title:c}):d('<button type="button"></button>').addClass(this._triggerClass).html(f==""?c:d("<img/>").attr({src:f,alt:c,title:c})));a[e?"before":"after"](b.trigger);b.trigger.click(function(){d.datepicker._datepickerShowing&&d.datepicker._lastInput==a[0]?d.datepicker._hideDatepicker():
+d.datepicker._showDatepicker(a[0]);return false})}},_autoSize:function(a){if(this._get(a,"autoSize")&&!a.inline){var b=new Date(2009,11,20),c=this._get(a,"dateFormat");if(c.match(/[DM]/)){var e=function(f){for(var h=0,i=0,g=0;g<f.length;g++)if(f[g].length>h){h=f[g].length;i=g}return i};b.setMonth(e(this._get(a,c.match(/MM/)?"monthNames":"monthNamesShort")));b.setDate(e(this._get(a,c.match(/DD/)?"dayNames":"dayNamesShort"))+20-b.getDay())}a.input.attr("size",this._formatDate(a,b).length)}},_inlineDatepicker:function(a,
+b){var c=d(a);if(!c.hasClass(this.markerClassName)){c.addClass(this.markerClassName).append(b.dpDiv).bind("setData.datepicker",function(e,f,h){b.settings[f]=h}).bind("getData.datepicker",function(e,f){return this._get(b,f)});d.data(a,"datepicker",b);this._setDate(b,this._getDefaultDate(b),true);this._updateDatepicker(b);this._updateAlternate(b);b.settings.disabled&&this._disableDatepicker(a);b.dpDiv.css("display","block")}},_dialogDatepicker:function(a,b,c,e,f){a=this._dialogInst;if(!a){this.uuid+=
+1;this._dialogInput=d('<input type="text" id="'+("dp"+this.uuid)+'" style="position: absolute; top: -100px; width: 0px; z-index: -10;"/>');this._dialogInput.keydown(this._doKeyDown);d("body").append(this._dialogInput);a=this._dialogInst=this._newInst(this._dialogInput,false);a.settings={};d.data(this._dialogInput[0],"datepicker",a)}H(a.settings,e||{});b=b&&b.constructor==Date?this._formatDate(a,b):b;this._dialogInput.val(b);this._pos=f?f.length?f:[f.pageX,f.pageY]:null;if(!this._pos)this._pos=[document.documentElement.clientWidth/
+2-100+(document.documentElement.scrollLeft||document.body.scrollLeft),document.documentElement.clientHeight/2-150+(document.documentElement.scrollTop||document.body.scrollTop)];this._dialogInput.css("left",this._pos[0]+20+"px").css("top",this._pos[1]+"px");a.settings.onSelect=c;this._inDialog=true;this.dpDiv.addClass(this._dialogClass);this._showDatepicker(this._dialogInput[0]);d.blockUI&&d.blockUI(this.dpDiv);d.data(this._dialogInput[0],"datepicker",a);return this},_destroyDatepicker:function(a){var b=
+d(a),c=d.data(a,"datepicker");if(b.hasClass(this.markerClassName)){var e=a.nodeName.toLowerCase();d.removeData(a,"datepicker");if(e=="input"){c.append.remove();c.trigger.remove();b.removeClass(this.markerClassName).unbind("focus",this._showDatepicker).unbind("keydown",this._doKeyDown).unbind("keypress",this._doKeyPress).unbind("keyup",this._doKeyUp)}else if(e=="div"||e=="span")b.removeClass(this.markerClassName).empty()}},_enableDatepicker:function(a){var b=d(a),c=d.data(a,"datepicker");if(b.hasClass(this.markerClassName)){var e=
+a.nodeName.toLowerCase();if(e=="input"){a.disabled=false;c.trigger.filter("button").each(function(){this.disabled=false}).end().filter("img").css({opacity:"1.0",cursor:""})}else if(e=="div"||e=="span"){b=b.children("."+this._inlineClass);b.children().removeClass("ui-state-disabled");b.find("select.ui-datepicker-month, select.ui-datepicker-year").removeAttr("disabled")}this._disabledInputs=d.map(this._disabledInputs,function(f){return f==a?null:f})}},_disableDatepicker:function(a){var b=d(a),c=d.data(a,
+"datepicker");if(b.hasClass(this.markerClassName)){var e=a.nodeName.toLowerCase();if(e=="input"){a.disabled=true;c.trigger.filter("button").each(function(){this.disabled=true}).end().filter("img").css({opacity:"0.5",cursor:"default"})}else if(e=="div"||e=="span"){b=b.children("."+this._inlineClass);b.children().addClass("ui-state-disabled");b.find("select.ui-datepicker-month, select.ui-datepicker-year").attr("disabled","disabled")}this._disabledInputs=d.map(this._disabledInputs,function(f){return f==
+a?null:f});this._disabledInputs[this._disabledInputs.length]=a}},_isDisabledDatepicker:function(a){if(!a)return false;for(var b=0;b<this._disabledInputs.length;b++)if(this._disabledInputs[b]==a)return true;return false},_getInst:function(a){try{return d.data(a,"datepicker")}catch(b){throw"Missing instance data for this datepicker";}},_optionDatepicker:function(a,b,c){var e=this._getInst(a);if(arguments.length==2&&typeof b=="string")return b=="defaults"?d.extend({},d.datepicker._defaults):e?b=="all"?
+d.extend({},e.settings):this._get(e,b):null;var f=b||{};if(typeof b=="string"){f={};f[b]=c}if(e){this._curInst==e&&this._hideDatepicker();var h=this._getDateDatepicker(a,true),i=this._getMinMaxDate(e,"min"),g=this._getMinMaxDate(e,"max");H(e.settings,f);if(i!==null&&f.dateFormat!==C&&f.minDate===C)e.settings.minDate=this._formatDate(e,i);if(g!==null&&f.dateFormat!==C&&f.maxDate===C)e.settings.maxDate=this._formatDate(e,g);this._attachments(d(a),e);this._autoSize(e);this._setDate(e,h);this._updateAlternate(e);
+this._updateDatepicker(e)}},_changeDatepicker:function(a,b,c){this._optionDatepicker(a,b,c)},_refreshDatepicker:function(a){(a=this._getInst(a))&&this._updateDatepicker(a)},_setDateDatepicker:function(a,b){if(a=this._getInst(a)){this._setDate(a,b);this._updateDatepicker(a);this._updateAlternate(a)}},_getDateDatepicker:function(a,b){(a=this._getInst(a))&&!a.inline&&this._setDateFromField(a,b);return a?this._getDate(a):null},_doKeyDown:function(a){var b=d.datepicker._getInst(a.target),c=true,e=b.dpDiv.is(".ui-datepicker-rtl");
+b._keyEvent=true;if(d.datepicker._datepickerShowing)switch(a.keyCode){case 9:d.datepicker._hideDatepicker();c=false;break;case 13:c=d("td."+d.datepicker._dayOverClass+":not(."+d.datepicker._currentClass+")",b.dpDiv);c[0]&&d.datepicker._selectDay(a.target,b.selectedMonth,b.selectedYear,c[0]);if(a=d.datepicker._get(b,"onSelect")){c=d.datepicker._formatDate(b);a.apply(b.input?b.input[0]:null,[c,b])}else d.datepicker._hideDatepicker();return false;case 27:d.datepicker._hideDatepicker();break;case 33:d.datepicker._adjustDate(a.target,
+a.ctrlKey?-d.datepicker._get(b,"stepBigMonths"):-d.datepicker._get(b,"stepMonths"),"M");break;case 34:d.datepicker._adjustDate(a.target,a.ctrlKey?+d.datepicker._get(b,"stepBigMonths"):+d.datepicker._get(b,"stepMonths"),"M");break;case 35:if(a.ctrlKey||a.metaKey)d.datepicker._clearDate(a.target);c=a.ctrlKey||a.metaKey;break;case 36:if(a.ctrlKey||a.metaKey)d.datepicker._gotoToday(a.target);c=a.ctrlKey||a.metaKey;break;case 37:if(a.ctrlKey||a.metaKey)d.datepicker._adjustDate(a.target,e?+1:-1,"D");c=
+a.ctrlKey||a.metaKey;if(a.originalEvent.altKey)d.datepicker._adjustDate(a.target,a.ctrlKey?-d.datepicker._get(b,"stepBigMonths"):-d.datepicker._get(b,"stepMonths"),"M");break;case 38:if(a.ctrlKey||a.metaKey)d.datepicker._adjustDate(a.target,-7,"D");c=a.ctrlKey||a.metaKey;break;case 39:if(a.ctrlKey||a.metaKey)d.datepicker._adjustDate(a.target,e?-1:+1,"D");c=a.ctrlKey||a.metaKey;if(a.originalEvent.altKey)d.datepicker._adjustDate(a.target,a.ctrlKey?+d.datepicker._get(b,"stepBigMonths"):+d.datepicker._get(b,
+"stepMonths"),"M");break;case 40:if(a.ctrlKey||a.metaKey)d.datepicker._adjustDate(a.target,+7,"D");c=a.ctrlKey||a.metaKey;break;default:c=false}else if(a.keyCode==36&&a.ctrlKey)d.datepicker._showDatepicker(this);else c=false;if(c){a.preventDefault();a.stopPropagation()}},_doKeyPress:function(a){var b=d.datepicker._getInst(a.target);if(d.datepicker._get(b,"constrainInput")){b=d.datepicker._possibleChars(d.datepicker._get(b,"dateFormat"));var c=String.fromCharCode(a.charCode==C?a.keyCode:a.charCode);
+return a.ctrlKey||a.metaKey||c<" "||!b||b.indexOf(c)>-1}},_doKeyUp:function(a){a=d.datepicker._getInst(a.target);if(a.input.val()!=a.lastVal)try{if(d.datepicker.parseDate(d.datepicker._get(a,"dateFormat"),a.input?a.input.val():null,d.datepicker._getFormatConfig(a))){d.datepicker._setDateFromField(a);d.datepicker._updateAlternate(a);d.datepicker._updateDatepicker(a)}}catch(b){d.datepicker.log(b)}return true},_showDatepicker:function(a){a=a.target||a;if(a.nodeName.toLowerCase()!="input")a=d("input",
+a.parentNode)[0];if(!(d.datepicker._isDisabledDatepicker(a)||d.datepicker._lastInput==a)){var b=d.datepicker._getInst(a);if(d.datepicker._curInst&&d.datepicker._curInst!=b){d.datepicker._datepickerShowing&&d.datepicker._triggerOnClose(d.datepicker._curInst);d.datepicker._curInst.dpDiv.stop(true,true)}var c=d.datepicker._get(b,"beforeShow");c=c?c.apply(a,[a,b]):{};if(c!==false){H(b.settings,c);b.lastVal=null;d.datepicker._lastInput=a;d.datepicker._setDateFromField(b);if(d.datepicker._inDialog)a.value=
+"";if(!d.datepicker._pos){d.datepicker._pos=d.datepicker._findPos(a);d.datepicker._pos[1]+=a.offsetHeight}var e=false;d(a).parents().each(function(){e|=d(this).css("position")=="fixed";return!e});if(e&&d.browser.opera){d.datepicker._pos[0]-=document.documentElement.scrollLeft;d.datepicker._pos[1]-=document.documentElement.scrollTop}c={left:d.datepicker._pos[0],top:d.datepicker._pos[1]};d.datepicker._pos=null;b.dpDiv.empty();b.dpDiv.css({position:"absolute",display:"block",top:"-1000px"});d.datepicker._updateDatepicker(b);
+c=d.datepicker._checkOffset(b,c,e);b.dpDiv.css({position:d.datepicker._inDialog&&d.blockUI?"static":e?"fixed":"absolute",display:"none",left:c.left+"px",top:c.top+"px"});if(!b.inline){c=d.datepicker._get(b,"showAnim");var f=d.datepicker._get(b,"duration"),h=function(){var i=b.dpDiv.find("iframe.ui-datepicker-cover");if(i.length){var g=d.datepicker._getBorders(b.dpDiv);i.css({left:-g[0],top:-g[1],width:b.dpDiv.outerWidth(),height:b.dpDiv.outerHeight()})}};b.dpDiv.zIndex(d(a).zIndex()+1);d.datepicker._datepickerShowing=
+true;d.effects&&d.effects[c]?b.dpDiv.show(c,d.datepicker._get(b,"showOptions"),f,h):b.dpDiv[c||"show"](c?f:null,h);if(!c||!f)h();b.input.is(":visible")&&!b.input.is(":disabled")&&b.input.focus();d.datepicker._curInst=b}}}},_updateDatepicker:function(a){this.maxRows=4;var b=d.datepicker._getBorders(a.dpDiv);J=a;a.dpDiv.empty().append(this._generateHTML(a));var c=a.dpDiv.find("iframe.ui-datepicker-cover");c.length&&c.css({left:-b[0],top:-b[1],width:a.dpDiv.outerWidth(),height:a.dpDiv.outerHeight()});
+a.dpDiv.find("."+this._dayOverClass+" a").mouseover();b=this._getNumberOfMonths(a);c=b[1];a.dpDiv.removeClass("ui-datepicker-multi-2 ui-datepicker-multi-3 ui-datepicker-multi-4").width("");c>1&&a.dpDiv.addClass("ui-datepicker-multi-"+c).css("width",17*c+"em");a.dpDiv[(b[0]!=1||b[1]!=1?"add":"remove")+"Class"]("ui-datepicker-multi");a.dpDiv[(this._get(a,"isRTL")?"add":"remove")+"Class"]("ui-datepicker-rtl");a==d.datepicker._curInst&&d.datepicker._datepickerShowing&&a.input&&a.input.is(":visible")&&
+!a.input.is(":disabled")&&a.input[0]!=document.activeElement&&a.input.focus();if(a.yearshtml){var e=a.yearshtml;setTimeout(function(){e===a.yearshtml&&a.yearshtml&&a.dpDiv.find("select.ui-datepicker-year:first").replaceWith(a.yearshtml);e=a.yearshtml=null},0)}},_getBorders:function(a){var b=function(c){return{thin:1,medium:2,thick:3}[c]||c};return[parseFloat(b(a.css("border-left-width"))),parseFloat(b(a.css("border-top-width")))]},_checkOffset:function(a,b,c){var e=a.dpDiv.outerWidth(),f=a.dpDiv.outerHeight(),
+h=a.input?a.input.outerWidth():0,i=a.input?a.input.outerHeight():0,g=document.documentElement.clientWidth+d(document).scrollLeft(),j=document.documentElement.clientHeight+d(document).scrollTop();b.left-=this._get(a,"isRTL")?e-h:0;b.left-=c&&b.left==a.input.offset().left?d(document).scrollLeft():0;b.top-=c&&b.top==a.input.offset().top+i?d(document).scrollTop():0;b.left-=Math.min(b.left,b.left+e>g&&g>e?Math.abs(b.left+e-g):0);b.top-=Math.min(b.top,b.top+f>j&&j>f?Math.abs(f+i):0);return b},_findPos:function(a){for(var b=
+this._get(this._getInst(a),"isRTL");a&&(a.type=="hidden"||a.nodeType!=1||d.expr.filters.hidden(a));)a=a[b?"previousSibling":"nextSibling"];a=d(a).offset();return[a.left,a.top]},_triggerOnClose:function(a){var b=this._get(a,"onClose");if(b)b.apply(a.input?a.input[0]:null,[a.input?a.input.val():"",a])},_hideDatepicker:function(a){var b=this._curInst;if(!(!b||a&&b!=d.data(a,"datepicker")))if(this._datepickerShowing){a=this._get(b,"showAnim");var c=this._get(b,"duration"),e=function(){d.datepicker._tidyDialog(b);
+this._curInst=null};d.effects&&d.effects[a]?b.dpDiv.hide(a,d.datepicker._get(b,"showOptions"),c,e):b.dpDiv[a=="slideDown"?"slideUp":a=="fadeIn"?"fadeOut":"hide"](a?c:null,e);a||e();d.datepicker._triggerOnClose(b);this._datepickerShowing=false;this._lastInput=null;if(this._inDialog){this._dialogInput.css({position:"absolute",left:"0",top:"-100px"});if(d.blockUI){d.unblockUI();d("body").append(this.dpDiv)}}this._inDialog=false}},_tidyDialog:function(a){a.dpDiv.removeClass(this._dialogClass).unbind(".ui-datepicker-calendar")},
+_checkExternalClick:function(a){if(d.datepicker._curInst){a=d(a.target);a[0].id!=d.datepicker._mainDivId&&a.parents("#"+d.datepicker._mainDivId).length==0&&!a.hasClass(d.datepicker.markerClassName)&&!a.hasClass(d.datepicker._triggerClass)&&d.datepicker._datepickerShowing&&!(d.datepicker._inDialog&&d.blockUI)&&d.datepicker._hideDatepicker()}},_adjustDate:function(a,b,c){a=d(a);var e=this._getInst(a[0]);if(!this._isDisabledDatepicker(a[0])){this._adjustInstDate(e,b+(c=="M"?this._get(e,"showCurrentAtPos"):
+0),c);this._updateDatepicker(e)}},_gotoToday:function(a){a=d(a);var b=this._getInst(a[0]);if(this._get(b,"gotoCurrent")&&b.currentDay){b.selectedDay=b.currentDay;b.drawMonth=b.selectedMonth=b.currentMonth;b.drawYear=b.selectedYear=b.currentYear}else{var c=new Date;b.selectedDay=c.getDate();b.drawMonth=b.selectedMonth=c.getMonth();b.drawYear=b.selectedYear=c.getFullYear()}this._notifyChange(b);this._adjustDate(a)},_selectMonthYear:function(a,b,c){a=d(a);var e=this._getInst(a[0]);e["selected"+(c=="M"?
+"Month":"Year")]=e["draw"+(c=="M"?"Month":"Year")]=parseInt(b.options[b.selectedIndex].value,10);this._notifyChange(e);this._adjustDate(a)},_selectDay:function(a,b,c,e){var f=d(a);if(!(d(e).hasClass(this._unselectableClass)||this._isDisabledDatepicker(f[0]))){f=this._getInst(f[0]);f.selectedDay=f.currentDay=d("a",e).html();f.selectedMonth=f.currentMonth=b;f.selectedYear=f.currentYear=c;this._selectDate(a,this._formatDate(f,f.currentDay,f.currentMonth,f.currentYear))}},_clearDate:function(a){a=d(a);
+this._getInst(a[0]);this._selectDate(a,"")},_selectDate:function(a,b){a=this._getInst(d(a)[0]);b=b!=null?b:this._formatDate(a);a.input&&a.input.val(b);this._updateAlternate(a);var c=this._get(a,"onSelect");if(c)c.apply(a.input?a.input[0]:null,[b,a]);else a.input&&a.input.trigger("change");if(a.inline)this._updateDatepicker(a);else{this._hideDatepicker();this._lastInput=a.input[0];typeof a.input[0]!="object"&&a.input.focus();this._lastInput=null}},_updateAlternate:function(a){var b=this._get(a,"altField");
+if(b){var c=this._get(a,"altFormat")||this._get(a,"dateFormat"),e=this._getDate(a),f=this.formatDate(c,e,this._getFormatConfig(a));d(b).each(function(){d(this).val(f)})}},noWeekends:function(a){a=a.getDay();return[a>0&&a<6,""]},iso8601Week:function(a){a=new Date(a.getTime());a.setDate(a.getDate()+4-(a.getDay()||7));var b=a.getTime();a.setMonth(0);a.setDate(1);return Math.floor(Math.round((b-a)/864E5)/7)+1},parseDate:function(a,b,c){if(a==null||b==null)throw"Invalid arguments";b=typeof b=="object"?
+b.toString():b+"";if(b=="")return null;var e=(c?c.shortYearCutoff:null)||this._defaults.shortYearCutoff;e=typeof e!="string"?e:(new Date).getFullYear()%100+parseInt(e,10);for(var f=(c?c.dayNamesShort:null)||this._defaults.dayNamesShort,h=(c?c.dayNames:null)||this._defaults.dayNames,i=(c?c.monthNamesShort:null)||this._defaults.monthNamesShort,g=(c?c.monthNames:null)||this._defaults.monthNames,j=c=-1,l=-1,u=-1,k=false,o=function(p){(p=A+1<a.length&&a.charAt(A+1)==p)&&A++;return p},m=function(p){var D=
+o(p);p=new RegExp("^\\d{1,"+(p=="@"?14:p=="!"?20:p=="y"&&D?4:p=="o"?3:2)+"}");p=b.substring(q).match(p);if(!p)throw"Missing number at position "+q;q+=p[0].length;return parseInt(p[0],10)},n=function(p,D,K){p=d.map(o(p)?K:D,function(w,x){return[[x,w]]}).sort(function(w,x){return-(w[1].length-x[1].length)});var E=-1;d.each(p,function(w,x){w=x[1];if(b.substr(q,w.length).toLowerCase()==w.toLowerCase()){E=x[0];q+=w.length;return false}});if(E!=-1)return E+1;else throw"Unknown name at position "+q;},s=
+function(){if(b.charAt(q)!=a.charAt(A))throw"Unexpected literal at position "+q;q++},q=0,A=0;A<a.length;A++)if(k)if(a.charAt(A)=="'"&&!o("'"))k=false;else s();else switch(a.charAt(A)){case "d":l=m("d");break;case "D":n("D",f,h);break;case "o":u=m("o");break;case "m":j=m("m");break;case "M":j=n("M",i,g);break;case "y":c=m("y");break;case "@":var v=new Date(m("@"));c=v.getFullYear();j=v.getMonth()+1;l=v.getDate();break;case "!":v=new Date((m("!")-this._ticksTo1970)/1E4);c=v.getFullYear();j=v.getMonth()+
+1;l=v.getDate();break;case "'":if(o("'"))s();else k=true;break;default:s()}if(q<b.length)throw"Extra/unparsed characters found in date: "+b.substring(q);if(c==-1)c=(new Date).getFullYear();else if(c<100)c+=(new Date).getFullYear()-(new Date).getFullYear()%100+(c<=e?0:-100);if(u>-1){j=1;l=u;do{e=this._getDaysInMonth(c,j-1);if(l<=e)break;j++;l-=e}while(1)}v=this._daylightSavingAdjust(new Date(c,j-1,l));if(v.getFullYear()!=c||v.getMonth()+1!=j||v.getDate()!=l)throw"Invalid date";return v},ATOM:"yy-mm-dd",
+COOKIE:"D, dd M yy",ISO_8601:"yy-mm-dd",RFC_822:"D, d M y",RFC_850:"DD, dd-M-y",RFC_1036:"D, d M y",RFC_1123:"D, d M yy",RFC_2822:"D, d M yy",RSS:"D, d M y",TICKS:"!",TIMESTAMP:"@",W3C:"yy-mm-dd",_ticksTo1970:(718685+Math.floor(492.5)-Math.floor(19.7)+Math.floor(4.925))*24*60*60*1E7,formatDate:function(a,b,c){if(!b)return"";var e=(c?c.dayNamesShort:null)||this._defaults.dayNamesShort,f=(c?c.dayNames:null)||this._defaults.dayNames,h=(c?c.monthNamesShort:null)||this._defaults.monthNamesShort;c=(c?c.monthNames:
+null)||this._defaults.monthNames;var i=function(o){(o=k+1<a.length&&a.charAt(k+1)==o)&&k++;return o},g=function(o,m,n){m=""+m;if(i(o))for(;m.length<n;)m="0"+m;return m},j=function(o,m,n,s){return i(o)?s[m]:n[m]},l="",u=false;if(b)for(var k=0;k<a.length;k++)if(u)if(a.charAt(k)=="'"&&!i("'"))u=false;else l+=a.charAt(k);else switch(a.charAt(k)){case "d":l+=g("d",b.getDate(),2);break;case "D":l+=j("D",b.getDay(),e,f);break;case "o":l+=g("o",Math.round(((new Date(b.getFullYear(),b.getMonth(),b.getDate())).getTime()-
+(new Date(b.getFullYear(),0,0)).getTime())/864E5),3);break;case "m":l+=g("m",b.getMonth()+1,2);break;case "M":l+=j("M",b.getMonth(),h,c);break;case "y":l+=i("y")?b.getFullYear():(b.getYear()%100<10?"0":"")+b.getYear()%100;break;case "@":l+=b.getTime();break;case "!":l+=b.getTime()*1E4+this._ticksTo1970;break;case "'":if(i("'"))l+="'";else u=true;break;default:l+=a.charAt(k)}return l},_possibleChars:function(a){for(var b="",c=false,e=function(h){(h=f+1<a.length&&a.charAt(f+1)==h)&&f++;return h},f=
+0;f<a.length;f++)if(c)if(a.charAt(f)=="'"&&!e("'"))c=false;else b+=a.charAt(f);else switch(a.charAt(f)){case "d":case "m":case "y":case "@":b+="0123456789";break;case "D":case "M":return null;case "'":if(e("'"))b+="'";else c=true;break;default:b+=a.charAt(f)}return b},_get:function(a,b){return a.settings[b]!==C?a.settings[b]:this._defaults[b]},_setDateFromField:function(a,b){if(a.input.val()!=a.lastVal){var c=this._get(a,"dateFormat"),e=a.lastVal=a.input?a.input.val():null,f,h;f=h=this._getDefaultDate(a);
+var i=this._getFormatConfig(a);try{f=this.parseDate(c,e,i)||h}catch(g){this.log(g);e=b?"":e}a.selectedDay=f.getDate();a.drawMonth=a.selectedMonth=f.getMonth();a.drawYear=a.selectedYear=f.getFullYear();a.currentDay=e?f.getDate():0;a.currentMonth=e?f.getMonth():0;a.currentYear=e?f.getFullYear():0;this._adjustInstDate(a)}},_getDefaultDate:function(a){return this._restrictMinMax(a,this._determineDate(a,this._get(a,"defaultDate"),new Date))},_determineDate:function(a,b,c){var e=function(h){var i=new Date;
+i.setDate(i.getDate()+h);return i},f=function(h){try{return d.datepicker.parseDate(d.datepicker._get(a,"dateFormat"),h,d.datepicker._getFormatConfig(a))}catch(i){}var g=(h.toLowerCase().match(/^c/)?d.datepicker._getDate(a):null)||new Date,j=g.getFullYear(),l=g.getMonth();g=g.getDate();for(var u=/([+-]?[0-9]+)\s*(d|D|w|W|m|M|y|Y)?/g,k=u.exec(h);k;){switch(k[2]||"d"){case "d":case "D":g+=parseInt(k[1],10);break;case "w":case "W":g+=parseInt(k[1],10)*7;break;case "m":case "M":l+=parseInt(k[1],10);g=
+Math.min(g,d.datepicker._getDaysInMonth(j,l));break;case "y":case "Y":j+=parseInt(k[1],10);g=Math.min(g,d.datepicker._getDaysInMonth(j,l));break}k=u.exec(h)}return new Date(j,l,g)};if(b=(b=b==null||b===""?c:typeof b=="string"?f(b):typeof b=="number"?isNaN(b)?c:e(b):new Date(b.getTime()))&&b.toString()=="Invalid Date"?c:b){b.setHours(0);b.setMinutes(0);b.setSeconds(0);b.setMilliseconds(0)}return this._daylightSavingAdjust(b)},_daylightSavingAdjust:function(a){if(!a)return null;a.setHours(a.getHours()>
+12?a.getHours()+2:0);return a},_setDate:function(a,b,c){var e=!b,f=a.selectedMonth,h=a.selectedYear;b=this._restrictMinMax(a,this._determineDate(a,b,new Date));a.selectedDay=a.currentDay=b.getDate();a.drawMonth=a.selectedMonth=a.currentMonth=b.getMonth();a.drawYear=a.selectedYear=a.currentYear=b.getFullYear();if((f!=a.selectedMonth||h!=a.selectedYear)&&!c)this._notifyChange(a);this._adjustInstDate(a);if(a.input)a.input.val(e?"":this._formatDate(a))},_getDate:function(a){return!a.currentYear||a.input&&
+a.input.val()==""?null:this._daylightSavingAdjust(new Date(a.currentYear,a.currentMonth,a.currentDay))},_generateHTML:function(a){var b=new Date;b=this._daylightSavingAdjust(new Date(b.getFullYear(),b.getMonth(),b.getDate()));var c=this._get(a,"isRTL"),e=this._get(a,"showButtonPanel"),f=this._get(a,"hideIfNoPrevNext"),h=this._get(a,"navigationAsDateFormat"),i=this._getNumberOfMonths(a),g=this._get(a,"showCurrentAtPos"),j=this._get(a,"stepMonths"),l=i[0]!=1||i[1]!=1,u=this._daylightSavingAdjust(!a.currentDay?
+new Date(9999,9,9):new Date(a.currentYear,a.currentMonth,a.currentDay)),k=this._getMinMaxDate(a,"min"),o=this._getMinMaxDate(a,"max");g=a.drawMonth-g;var m=a.drawYear;if(g<0){g+=12;m--}if(o){var n=this._daylightSavingAdjust(new Date(o.getFullYear(),o.getMonth()-i[0]*i[1]+1,o.getDate()));for(n=k&&n<k?k:n;this._daylightSavingAdjust(new Date(m,g,1))>n;){g--;if(g<0){g=11;m--}}}a.drawMonth=g;a.drawYear=m;n=this._get(a,"prevText");n=!h?n:this.formatDate(n,this._daylightSavingAdjust(new Date(m,g-j,1)),this._getFormatConfig(a));
+n=this._canAdjustMonth(a,-1,m,g)?'<a class="ui-datepicker-prev ui-corner-all" onclick="DP_jQuery_'+B+".datepicker._adjustDate('#"+a.id+"', -"+j+", 'M');\" title=\""+n+'"><span class="ui-icon ui-icon-circle-triangle-'+(c?"e":"w")+'">'+n+"</span></a>":f?"":'<a class="ui-datepicker-prev ui-corner-all ui-state-disabled" title="'+n+'"><span class="ui-icon ui-icon-circle-triangle-'+(c?"e":"w")+'">'+n+"</span></a>";var s=this._get(a,"nextText");s=!h?s:this.formatDate(s,this._daylightSavingAdjust(new Date(m,
+g+j,1)),this._getFormatConfig(a));f=this._canAdjustMonth(a,+1,m,g)?'<a class="ui-datepicker-next ui-corner-all" onclick="DP_jQuery_'+B+".datepicker._adjustDate('#"+a.id+"', +"+j+", 'M');\" title=\""+s+'"><span class="ui-icon ui-icon-circle-triangle-'+(c?"w":"e")+'">'+s+"</span></a>":f?"":'<a class="ui-datepicker-next ui-corner-all ui-state-disabled" title="'+s+'"><span class="ui-icon ui-icon-circle-triangle-'+(c?"w":"e")+'">'+s+"</span></a>";j=this._get(a,"currentText");s=this._get(a,"gotoCurrent")&&
+a.currentDay?u:b;j=!h?j:this.formatDate(j,s,this._getFormatConfig(a));h=!a.inline?'<button type="button" class="ui-datepicker-close ui-state-default ui-priority-primary ui-corner-all" onclick="DP_jQuery_'+B+'.datepicker._hideDatepicker();">'+this._get(a,"closeText")+"</button>":"";e=e?'<div class="ui-datepicker-buttonpane ui-widget-content">'+(c?h:"")+(this._isInRange(a,s)?'<button type="button" class="ui-datepicker-current ui-state-default ui-priority-secondary ui-corner-all" onclick="DP_jQuery_'+
+B+".datepicker._gotoToday('#"+a.id+"');\">"+j+"</button>":"")+(c?"":h)+"</div>":"";h=parseInt(this._get(a,"firstDay"),10);h=isNaN(h)?0:h;j=this._get(a,"showWeek");s=this._get(a,"dayNames");this._get(a,"dayNamesShort");var q=this._get(a,"dayNamesMin"),A=this._get(a,"monthNames"),v=this._get(a,"monthNamesShort"),p=this._get(a,"beforeShowDay"),D=this._get(a,"showOtherMonths"),K=this._get(a,"selectOtherMonths");this._get(a,"calculateWeek");for(var E=this._getDefaultDate(a),w="",x=0;x<i[0];x++){var O=
+"";this.maxRows=4;for(var G=0;G<i[1];G++){var P=this._daylightSavingAdjust(new Date(m,g,a.selectedDay)),t=" ui-corner-all",y="";if(l){y+='<div class="ui-datepicker-group';if(i[1]>1)switch(G){case 0:y+=" ui-datepicker-group-first";t=" ui-corner-"+(c?"right":"left");break;case i[1]-1:y+=" ui-datepicker-group-last";t=" ui-corner-"+(c?"left":"right");break;default:y+=" ui-datepicker-group-middle";t="";break}y+='">'}y+='<div class="ui-datepicker-header ui-widget-header ui-helper-clearfix'+t+'">'+(/all|left/.test(t)&&
+x==0?c?f:n:"")+(/all|right/.test(t)&&x==0?c?n:f:"")+this._generateMonthYearHeader(a,g,m,k,o,x>0||G>0,A,v)+'</div><table class="ui-datepicker-calendar"><thead><tr>';var z=j?'<th class="ui-datepicker-week-col">'+this._get(a,"weekHeader")+"</th>":"";for(t=0;t<7;t++){var r=(t+h)%7;z+="<th"+((t+h+6)%7>=5?' class="ui-datepicker-week-end"':"")+'><span title="'+s[r]+'">'+q[r]+"</span></th>"}y+=z+"</tr></thead><tbody>";z=this._getDaysInMonth(m,g);if(m==a.selectedYear&&g==a.selectedMonth)a.selectedDay=Math.min(a.selectedDay,
+z);t=(this._getFirstDayOfMonth(m,g)-h+7)%7;z=Math.ceil((t+z)/7);this.maxRows=z=l?this.maxRows>z?this.maxRows:z:z;r=this._daylightSavingAdjust(new Date(m,g,1-t));for(var Q=0;Q<z;Q++){y+="<tr>";var R=!j?"":'<td class="ui-datepicker-week-col">'+this._get(a,"calculateWeek")(r)+"</td>";for(t=0;t<7;t++){var I=p?p.apply(a.input?a.input[0]:null,[r]):[true,""],F=r.getMonth()!=g,L=F&&!K||!I[0]||k&&r<k||o&&r>o;R+='<td class="'+((t+h+6)%7>=5?" ui-datepicker-week-end":"")+(F?" ui-datepicker-other-month":"")+(r.getTime()==
+P.getTime()&&g==a.selectedMonth&&a._keyEvent||E.getTime()==r.getTime()&&E.getTime()==P.getTime()?" "+this._dayOverClass:"")+(L?" "+this._unselectableClass+" ui-state-disabled":"")+(F&&!D?"":" "+I[1]+(r.getTime()==u.getTime()?" "+this._currentClass:"")+(r.getTime()==b.getTime()?" ui-datepicker-today":""))+'"'+((!F||D)&&I[2]?' title="'+I[2]+'"':"")+(L?"":' onclick="DP_jQuery_'+B+".datepicker._selectDay('#"+a.id+"',"+r.getMonth()+","+r.getFullYear()+', this);return false;"')+">"+(F&&!D?"&#xa0;":L?'<span class="ui-state-default">'+
+r.getDate()+"</span>":'<a class="ui-state-default'+(r.getTime()==b.getTime()?" ui-state-highlight":"")+(r.getTime()==u.getTime()?" ui-state-active":"")+(F?" ui-priority-secondary":"")+'" href="#">'+r.getDate()+"</a>")+"</td>";r.setDate(r.getDate()+1);r=this._daylightSavingAdjust(r)}y+=R+"</tr>"}g++;if(g>11){g=0;m++}y+="</tbody></table>"+(l?"</div>"+(i[0]>0&&G==i[1]-1?'<div class="ui-datepicker-row-break"></div>':""):"");O+=y}w+=O}w+=e+(d.browser.msie&&parseInt(d.browser.version,10)<7&&!a.inline?'<iframe src="javascript:false;" class="ui-datepicker-cover" frameborder="0"></iframe>':
+"");a._keyEvent=false;return w},_generateMonthYearHeader:function(a,b,c,e,f,h,i,g){var j=this._get(a,"changeMonth"),l=this._get(a,"changeYear"),u=this._get(a,"showMonthAfterYear"),k='<div class="ui-datepicker-title">',o="";if(h||!j)o+='<span class="ui-datepicker-month">'+i[b]+"</span>";else{i=e&&e.getFullYear()==c;var m=f&&f.getFullYear()==c;o+='<select class="ui-datepicker-month" onchange="DP_jQuery_'+B+".datepicker._selectMonthYear('#"+a.id+"', this, 'M');\" >";for(var n=0;n<12;n++)if((!i||n>=e.getMonth())&&
+(!m||n<=f.getMonth()))o+='<option value="'+n+'"'+(n==b?' selected="selected"':"")+">"+g[n]+"</option>";o+="</select>"}u||(k+=o+(h||!(j&&l)?"&#xa0;":""));if(!a.yearshtml){a.yearshtml="";if(h||!l)k+='<span class="ui-datepicker-year">'+c+"</span>";else{g=this._get(a,"yearRange").split(":");var s=(new Date).getFullYear();i=function(q){q=q.match(/c[+-].*/)?c+parseInt(q.substring(1),10):q.match(/[+-].*/)?s+parseInt(q,10):parseInt(q,10);return isNaN(q)?s:q};b=i(g[0]);g=Math.max(b,i(g[1]||""));b=e?Math.max(b,
+e.getFullYear()):b;g=f?Math.min(g,f.getFullYear()):g;for(a.yearshtml+='<select class="ui-datepicker-year" onchange="DP_jQuery_'+B+".datepicker._selectMonthYear('#"+a.id+"', this, 'Y');\" >";b<=g;b++)a.yearshtml+='<option value="'+b+'"'+(b==c?' selected="selected"':"")+">"+b+"</option>";a.yearshtml+="</select>";k+=a.yearshtml;a.yearshtml=null}}k+=this._get(a,"yearSuffix");if(u)k+=(h||!(j&&l)?"&#xa0;":"")+o;k+="</div>";return k},_adjustInstDate:function(a,b,c){var e=a.drawYear+(c=="Y"?b:0),f=a.drawMonth+
+(c=="M"?b:0);b=Math.min(a.selectedDay,this._getDaysInMonth(e,f))+(c=="D"?b:0);e=this._restrictMinMax(a,this._daylightSavingAdjust(new Date(e,f,b)));a.selectedDay=e.getDate();a.drawMonth=a.selectedMonth=e.getMonth();a.drawYear=a.selectedYear=e.getFullYear();if(c=="M"||c=="Y")this._notifyChange(a)},_restrictMinMax:function(a,b){var c=this._getMinMaxDate(a,"min");a=this._getMinMaxDate(a,"max");b=c&&b<c?c:b;return b=a&&b>a?a:b},_notifyChange:function(a){var b=this._get(a,"onChangeMonthYear");if(b)b.apply(a.input?
+a.input[0]:null,[a.selectedYear,a.selectedMonth+1,a])},_getNumberOfMonths:function(a){a=this._get(a,"numberOfMonths");return a==null?[1,1]:typeof a=="number"?[1,a]:a},_getMinMaxDate:function(a,b){return this._determineDate(a,this._get(a,b+"Date"),null)},_getDaysInMonth:function(a,b){return 32-this._daylightSavingAdjust(new Date(a,b,32)).getDate()},_getFirstDayOfMonth:function(a,b){return(new Date(a,b,1)).getDay()},_canAdjustMonth:function(a,b,c,e){var f=this._getNumberOfMonths(a);c=this._daylightSavingAdjust(new Date(c,
+e+(b<0?b:f[0]*f[1]),1));b<0&&c.setDate(this._getDaysInMonth(c.getFullYear(),c.getMonth()));return this._isInRange(a,c)},_isInRange:function(a,b){var c=this._getMinMaxDate(a,"min");a=this._getMinMaxDate(a,"max");return(!c||b.getTime()>=c.getTime())&&(!a||b.getTime()<=a.getTime())},_getFormatConfig:function(a){var b=this._get(a,"shortYearCutoff");b=typeof b!="string"?b:(new Date).getFullYear()%100+parseInt(b,10);return{shortYearCutoff:b,dayNamesShort:this._get(a,"dayNamesShort"),dayNames:this._get(a,
+"dayNames"),monthNamesShort:this._get(a,"monthNamesShort"),monthNames:this._get(a,"monthNames")}},_formatDate:function(a,b,c,e){if(!b){a.currentDay=a.selectedDay;a.currentMonth=a.selectedMonth;a.currentYear=a.selectedYear}b=b?typeof b=="object"?b:this._daylightSavingAdjust(new Date(e,c,b)):this._daylightSavingAdjust(new Date(a.currentYear,a.currentMonth,a.currentDay));return this.formatDate(this._get(a,"dateFormat"),b,this._getFormatConfig(a))}});d.fn.datepicker=function(a){if(!this.length)return this;
+if(!d.datepicker.initialized){d(document).mousedown(d.datepicker._checkExternalClick).find("body").append(d.datepicker.dpDiv);d.datepicker.initialized=true}var b=Array.prototype.slice.call(arguments,1);if(typeof a=="string"&&(a=="isDisabled"||a=="getDate"||a=="widget"))return d.datepicker["_"+a+"Datepicker"].apply(d.datepicker,[this[0]].concat(b));if(a=="option"&&arguments.length==2&&typeof arguments[1]=="string")return d.datepicker["_"+a+"Datepicker"].apply(d.datepicker,[this[0]].concat(b));return this.each(function(){typeof a==
+"string"?d.datepicker["_"+a+"Datepicker"].apply(d.datepicker,[this].concat(b)):d.datepicker._attachDatepicker(this,a)})};d.datepicker=new M;d.datepicker.initialized=false;d.datepicker.uuid=(new Date).getTime();d.datepicker.version="1.8.16";window["DP_jQuery_"+B]=d})(jQuery);
+;/*
+ * jQuery UI Progressbar 1.8.16
+ *
+ * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
+ * Dual licensed under the MIT or GPL Version 2 licenses.
+ * http://jquery.org/license
+ *
+ * http://docs.jquery.com/UI/Progressbar
+ *
+ * Depends:
+ *   jquery.ui.core.js
+ *   jquery.ui.widget.js
+ */
+(function(b,d){b.widget("ui.progressbar",{options:{value:0,max:100},min:0,_create:function(){this.element.addClass("ui-progressbar ui-widget ui-widget-content ui-corner-all").attr({role:"progressbar","aria-valuemin":this.min,"aria-valuemax":this.options.max,"aria-valuenow":this._value()});this.valueDiv=b("<div class='ui-progressbar-value ui-widget-header ui-corner-left'></div>").appendTo(this.element);this.oldValue=this._value();this._refreshValue()},destroy:function(){this.element.removeClass("ui-progressbar ui-widget ui-widget-content ui-corner-all").removeAttr("role").removeAttr("aria-valuemin").removeAttr("aria-valuemax").removeAttr("aria-valuenow");
+this.valueDiv.remove();b.Widget.prototype.destroy.apply(this,arguments)},value:function(a){if(a===d)return this._value();this._setOption("value",a);return this},_setOption:function(a,c){if(a==="value"){this.options.value=c;this._refreshValue();this._value()===this.options.max&&this._trigger("complete")}b.Widget.prototype._setOption.apply(this,arguments)},_value:function(){var a=this.options.value;if(typeof a!=="number")a=0;return Math.min(this.options.max,Math.max(this.min,a))},_percentage:function(){return 100*
+this._value()/this.options.max},_refreshValue:function(){var a=this.value(),c=this._percentage();if(this.oldValue!==a){this.oldValue=a;this._trigger("change")}this.valueDiv.toggle(a>this.min).toggleClass("ui-corner-right",a===this.options.max).width(c.toFixed(0)+"%");this.element.attr("aria-valuenow",a)}});b.extend(b.ui.progressbar,{version:"1.8.16"})})(jQuery);
+;/*
+ * jQuery UI Effects 1.8.16
+ *
+ * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
+ * Dual licensed under the MIT or GPL Version 2 licenses.
+ * http://jquery.org/license
+ *
+ * http://docs.jquery.com/UI/Effects/
+ */
+jQuery.effects||function(f,j){function m(c){var a;if(c&&c.constructor==Array&&c.length==3)return c;if(a=/rgb\(\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*\)/.exec(c))return[parseInt(a[1],10),parseInt(a[2],10),parseInt(a[3],10)];if(a=/rgb\(\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*\)/.exec(c))return[parseFloat(a[1])*2.55,parseFloat(a[2])*2.55,parseFloat(a[3])*2.55];if(a=/#([a-fA-F0-9]{2})([a-fA-F0-9]{2})([a-fA-F0-9]{2})/.exec(c))return[parseInt(a[1],
+16),parseInt(a[2],16),parseInt(a[3],16)];if(a=/#([a-fA-F0-9])([a-fA-F0-9])([a-fA-F0-9])/.exec(c))return[parseInt(a[1]+a[1],16),parseInt(a[2]+a[2],16),parseInt(a[3]+a[3],16)];if(/rgba\(0, 0, 0, 0\)/.exec(c))return n.transparent;return n[f.trim(c).toLowerCase()]}function s(c,a){var b;do{b=f.curCSS(c,a);if(b!=""&&b!="transparent"||f.nodeName(c,"body"))break;a="backgroundColor"}while(c=c.parentNode);return m(b)}function o(){var c=document.defaultView?document.defaultView.getComputedStyle(this,null):this.currentStyle,
+a={},b,d;if(c&&c.length&&c[0]&&c[c[0]])for(var e=c.length;e--;){b=c[e];if(typeof c[b]=="string"){d=b.replace(/\-(\w)/g,function(g,h){return h.toUpperCase()});a[d]=c[b]}}else for(b in c)if(typeof c[b]==="string")a[b]=c[b];return a}function p(c){var a,b;for(a in c){b=c[a];if(b==null||f.isFunction(b)||a in t||/scrollbar/.test(a)||!/color/i.test(a)&&isNaN(parseFloat(b)))delete c[a]}return c}function u(c,a){var b={_:0},d;for(d in a)if(c[d]!=a[d])b[d]=a[d];return b}function k(c,a,b,d){if(typeof c=="object"){d=
+a;b=null;a=c;c=a.effect}if(f.isFunction(a)){d=a;b=null;a={}}if(typeof a=="number"||f.fx.speeds[a]){d=b;b=a;a={}}if(f.isFunction(b)){d=b;b=null}a=a||{};b=b||a.duration;b=f.fx.off?0:typeof b=="number"?b:b in f.fx.speeds?f.fx.speeds[b]:f.fx.speeds._default;d=d||a.complete;return[c,a,b,d]}function l(c){if(!c||typeof c==="number"||f.fx.speeds[c])return true;if(typeof c==="string"&&!f.effects[c])return true;return false}f.effects={};f.each(["backgroundColor","borderBottomColor","borderLeftColor","borderRightColor",
+"borderTopColor","borderColor","color","outlineColor"],function(c,a){f.fx.step[a]=function(b){if(!b.colorInit){b.start=s(b.elem,a);b.end=m(b.end);b.colorInit=true}b.elem.style[a]="rgb("+Math.max(Math.min(parseInt(b.pos*(b.end[0]-b.start[0])+b.start[0],10),255),0)+","+Math.max(Math.min(parseInt(b.pos*(b.end[1]-b.start[1])+b.start[1],10),255),0)+","+Math.max(Math.min(parseInt(b.pos*(b.end[2]-b.start[2])+b.start[2],10),255),0)+")"}});var n={aqua:[0,255,255],azure:[240,255,255],beige:[245,245,220],black:[0,
+0,0],blue:[0,0,255],brown:[165,42,42],cyan:[0,255,255],darkblue:[0,0,139],darkcyan:[0,139,139],darkgrey:[169,169,169],darkgreen:[0,100,0],darkkhaki:[189,183,107],darkmagenta:[139,0,139],darkolivegreen:[85,107,47],darkorange:[255,140,0],darkorchid:[153,50,204],darkred:[139,0,0],darksalmon:[233,150,122],darkviolet:[148,0,211],fuchsia:[255,0,255],gold:[255,215,0],green:[0,128,0],indigo:[75,0,130],khaki:[240,230,140],lightblue:[173,216,230],lightcyan:[224,255,255],lightgreen:[144,238,144],lightgrey:[211,
+211,211],lightpink:[255,182,193],lightyellow:[255,255,224],lime:[0,255,0],magenta:[255,0,255],maroon:[128,0,0],navy:[0,0,128],olive:[128,128,0],orange:[255,165,0],pink:[255,192,203],purple:[128,0,128],violet:[128,0,128],red:[255,0,0],silver:[192,192,192],white:[255,255,255],yellow:[255,255,0],transparent:[255,255,255]},q=["add","remove","toggle"],t={border:1,borderBottom:1,borderColor:1,borderLeft:1,borderRight:1,borderTop:1,borderWidth:1,margin:1,padding:1};f.effects.animateClass=function(c,a,b,
+d){if(f.isFunction(b)){d=b;b=null}return this.queue(function(){var e=f(this),g=e.attr("style")||" ",h=p(o.call(this)),r,v=e.attr("class");f.each(q,function(w,i){c[i]&&e[i+"Class"](c[i])});r=p(o.call(this));e.attr("class",v);e.animate(u(h,r),{queue:false,duration:a,easing:b,complete:function(){f.each(q,function(w,i){c[i]&&e[i+"Class"](c[i])});if(typeof e.attr("style")=="object"){e.attr("style").cssText="";e.attr("style").cssText=g}else e.attr("style",g);d&&d.apply(this,arguments);f.dequeue(this)}})})};
+f.fn.extend({_addClass:f.fn.addClass,addClass:function(c,a,b,d){return a?f.effects.animateClass.apply(this,[{add:c},a,b,d]):this._addClass(c)},_removeClass:f.fn.removeClass,removeClass:function(c,a,b,d){return a?f.effects.animateClass.apply(this,[{remove:c},a,b,d]):this._removeClass(c)},_toggleClass:f.fn.toggleClass,toggleClass:function(c,a,b,d,e){return typeof a=="boolean"||a===j?b?f.effects.animateClass.apply(this,[a?{add:c}:{remove:c},b,d,e]):this._toggleClass(c,a):f.effects.animateClass.apply(this,
+[{toggle:c},a,b,d])},switchClass:function(c,a,b,d,e){return f.effects.animateClass.apply(this,[{add:a,remove:c},b,d,e])}});f.extend(f.effects,{version:"1.8.16",save:function(c,a){for(var b=0;b<a.length;b++)a[b]!==null&&c.data("ec.storage."+a[b],c[0].style[a[b]])},restore:function(c,a){for(var b=0;b<a.length;b++)a[b]!==null&&c.css(a[b],c.data("ec.storage."+a[b]))},setMode:function(c,a){if(a=="toggle")a=c.is(":hidden")?"show":"hide";return a},getBaseline:function(c,a){var b;switch(c[0]){case "top":b=
+0;break;case "middle":b=0.5;break;case "bottom":b=1;break;default:b=c[0]/a.height}switch(c[1]){case "left":c=0;break;case "center":c=0.5;break;case "right":c=1;break;default:c=c[1]/a.width}return{x:c,y:b}},createWrapper:function(c){if(c.parent().is(".ui-effects-wrapper"))return c.parent();var a={width:c.outerWidth(true),height:c.outerHeight(true),"float":c.css("float")},b=f("<div></div>").addClass("ui-effects-wrapper").css({fontSize:"100%",background:"transparent",border:"none",margin:0,padding:0}),
+d=document.activeElement;c.wrap(b);if(c[0]===d||f.contains(c[0],d))f(d).focus();b=c.parent();if(c.css("position")=="static"){b.css({position:"relative"});c.css({position:"relative"})}else{f.extend(a,{position:c.css("position"),zIndex:c.css("z-index")});f.each(["top","left","bottom","right"],function(e,g){a[g]=c.css(g);if(isNaN(parseInt(a[g],10)))a[g]="auto"});c.css({position:"relative",top:0,left:0,right:"auto",bottom:"auto"})}return b.css(a).show()},removeWrapper:function(c){var a,b=document.activeElement;
+if(c.parent().is(".ui-effects-wrapper")){a=c.parent().replaceWith(c);if(c[0]===b||f.contains(c[0],b))f(b).focus();return a}return c},setTransition:function(c,a,b,d){d=d||{};f.each(a,function(e,g){unit=c.cssUnit(g);if(unit[0]>0)d[g]=unit[0]*b+unit[1]});return d}});f.fn.extend({effect:function(c){var a=k.apply(this,arguments),b={options:a[1],duration:a[2],callback:a[3]};a=b.options.mode;var d=f.effects[c];if(f.fx.off||!d)return a?this[a](b.duration,b.callback):this.each(function(){b.callback&&b.callback.call(this)});
+return d.call(this,b)},_show:f.fn.show,show:function(c){if(l(c))return this._show.apply(this,arguments);else{var a=k.apply(this,arguments);a[1].mode="show";return this.effect.apply(this,a)}},_hide:f.fn.hide,hide:function(c){if(l(c))return this._hide.apply(this,arguments);else{var a=k.apply(this,arguments);a[1].mode="hide";return this.effect.apply(this,a)}},__toggle:f.fn.toggle,toggle:function(c){if(l(c)||typeof c==="boolean"||f.isFunction(c))return this.__toggle.apply(this,arguments);else{var a=k.apply(this,
+arguments);a[1].mode="toggle";return this.effect.apply(this,a)}},cssUnit:function(c){var a=this.css(c),b=[];f.each(["em","px","%","pt"],function(d,e){if(a.indexOf(e)>0)b=[parseFloat(a),e]});return b}});f.easing.jswing=f.easing.swing;f.extend(f.easing,{def:"easeOutQuad",swing:function(c,a,b,d,e){return f.easing[f.easing.def](c,a,b,d,e)},easeInQuad:function(c,a,b,d,e){return d*(a/=e)*a+b},easeOutQuad:function(c,a,b,d,e){return-d*(a/=e)*(a-2)+b},easeInOutQuad:function(c,a,b,d,e){if((a/=e/2)<1)return d/
+2*a*a+b;return-d/2*(--a*(a-2)-1)+b},easeInCubic:function(c,a,b,d,e){return d*(a/=e)*a*a+b},easeOutCubic:function(c,a,b,d,e){return d*((a=a/e-1)*a*a+1)+b},easeInOutCubic:function(c,a,b,d,e){if((a/=e/2)<1)return d/2*a*a*a+b;return d/2*((a-=2)*a*a+2)+b},easeInQuart:function(c,a,b,d,e){return d*(a/=e)*a*a*a+b},easeOutQuart:function(c,a,b,d,e){return-d*((a=a/e-1)*a*a*a-1)+b},easeInOutQuart:function(c,a,b,d,e){if((a/=e/2)<1)return d/2*a*a*a*a+b;return-d/2*((a-=2)*a*a*a-2)+b},easeInQuint:function(c,a,b,
+d,e){return d*(a/=e)*a*a*a*a+b},easeOutQuint:function(c,a,b,d,e){return d*((a=a/e-1)*a*a*a*a+1)+b},easeInOutQuint:function(c,a,b,d,e){if((a/=e/2)<1)return d/2*a*a*a*a*a+b;return d/2*((a-=2)*a*a*a*a+2)+b},easeInSine:function(c,a,b,d,e){return-d*Math.cos(a/e*(Math.PI/2))+d+b},easeOutSine:function(c,a,b,d,e){return d*Math.sin(a/e*(Math.PI/2))+b},easeInOutSine:function(c,a,b,d,e){return-d/2*(Math.cos(Math.PI*a/e)-1)+b},easeInExpo:function(c,a,b,d,e){return a==0?b:d*Math.pow(2,10*(a/e-1))+b},easeOutExpo:function(c,
+a,b,d,e){return a==e?b+d:d*(-Math.pow(2,-10*a/e)+1)+b},easeInOutExpo:function(c,a,b,d,e){if(a==0)return b;if(a==e)return b+d;if((a/=e/2)<1)return d/2*Math.pow(2,10*(a-1))+b;return d/2*(-Math.pow(2,-10*--a)+2)+b},easeInCirc:function(c,a,b,d,e){return-d*(Math.sqrt(1-(a/=e)*a)-1)+b},easeOutCirc:function(c,a,b,d,e){return d*Math.sqrt(1-(a=a/e-1)*a)+b},easeInOutCirc:function(c,a,b,d,e){if((a/=e/2)<1)return-d/2*(Math.sqrt(1-a*a)-1)+b;return d/2*(Math.sqrt(1-(a-=2)*a)+1)+b},easeInElastic:function(c,a,b,
+d,e){c=1.70158;var g=0,h=d;if(a==0)return b;if((a/=e)==1)return b+d;g||(g=e*0.3);if(h<Math.abs(d)){h=d;c=g/4}else c=g/(2*Math.PI)*Math.asin(d/h);return-(h*Math.pow(2,10*(a-=1))*Math.sin((a*e-c)*2*Math.PI/g))+b},easeOutElastic:function(c,a,b,d,e){c=1.70158;var g=0,h=d;if(a==0)return b;if((a/=e)==1)return b+d;g||(g=e*0.3);if(h<Math.abs(d)){h=d;c=g/4}else c=g/(2*Math.PI)*Math.asin(d/h);return h*Math.pow(2,-10*a)*Math.sin((a*e-c)*2*Math.PI/g)+d+b},easeInOutElastic:function(c,a,b,d,e){c=1.70158;var g=
+0,h=d;if(a==0)return b;if((a/=e/2)==2)return b+d;g||(g=e*0.3*1.5);if(h<Math.abs(d)){h=d;c=g/4}else c=g/(2*Math.PI)*Math.asin(d/h);if(a<1)return-0.5*h*Math.pow(2,10*(a-=1))*Math.sin((a*e-c)*2*Math.PI/g)+b;return h*Math.pow(2,-10*(a-=1))*Math.sin((a*e-c)*2*Math.PI/g)*0.5+d+b},easeInBack:function(c,a,b,d,e,g){if(g==j)g=1.70158;return d*(a/=e)*a*((g+1)*a-g)+b},easeOutBack:function(c,a,b,d,e,g){if(g==j)g=1.70158;return d*((a=a/e-1)*a*((g+1)*a+g)+1)+b},easeInOutBack:function(c,a,b,d,e,g){if(g==j)g=1.70158;
+if((a/=e/2)<1)return d/2*a*a*(((g*=1.525)+1)*a-g)+b;return d/2*((a-=2)*a*(((g*=1.525)+1)*a+g)+2)+b},easeInBounce:function(c,a,b,d,e){return d-f.easing.easeOutBounce(c,e-a,0,d,e)+b},easeOutBounce:function(c,a,b,d,e){return(a/=e)<1/2.75?d*7.5625*a*a+b:a<2/2.75?d*(7.5625*(a-=1.5/2.75)*a+0.75)+b:a<2.5/2.75?d*(7.5625*(a-=2.25/2.75)*a+0.9375)+b:d*(7.5625*(a-=2.625/2.75)*a+0.984375)+b},easeInOutBounce:function(c,a,b,d,e){if(a<e/2)return f.easing.easeInBounce(c,a*2,0,d,e)*0.5+b;return f.easing.easeOutBounce(c,
+a*2-e,0,d,e)*0.5+d*0.5+b}})}(jQuery);
+;/*
+ * jQuery UI Effects Blind 1.8.16
+ *
+ * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
+ * Dual licensed under the MIT or GPL Version 2 licenses.
+ * http://jquery.org/license
+ *
+ * http://docs.jquery.com/UI/Effects/Blind
+ *
+ * Depends:
+ *	jquery.effects.core.js
+ */
+(function(b){b.effects.blind=function(c){return this.queue(function(){var a=b(this),g=["position","top","bottom","left","right"],f=b.effects.setMode(a,c.options.mode||"hide"),d=c.options.direction||"vertical";b.effects.save(a,g);a.show();var e=b.effects.createWrapper(a).css({overflow:"hidden"}),h=d=="vertical"?"height":"width";d=d=="vertical"?e.height():e.width();f=="show"&&e.css(h,0);var i={};i[h]=f=="show"?d:0;e.animate(i,c.duration,c.options.easing,function(){f=="hide"&&a.hide();b.effects.restore(a,
+g);b.effects.removeWrapper(a);c.callback&&c.callback.apply(a[0],arguments);a.dequeue()})})}})(jQuery);
+;/*
+ * jQuery UI Effects Bounce 1.8.16
+ *
+ * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
+ * Dual licensed under the MIT or GPL Version 2 licenses.
+ * http://jquery.org/license
+ *
+ * http://docs.jquery.com/UI/Effects/Bounce
+ *
+ * Depends:
+ *	jquery.effects.core.js
+ */
+(function(e){e.effects.bounce=function(b){return this.queue(function(){var a=e(this),l=["position","top","bottom","left","right"],h=e.effects.setMode(a,b.options.mode||"effect"),d=b.options.direction||"up",c=b.options.distance||20,m=b.options.times||5,i=b.duration||250;/show|hide/.test(h)&&l.push("opacity");e.effects.save(a,l);a.show();e.effects.createWrapper(a);var f=d=="up"||d=="down"?"top":"left";d=d=="up"||d=="left"?"pos":"neg";c=b.options.distance||(f=="top"?a.outerHeight({margin:true})/3:a.outerWidth({margin:true})/
+3);if(h=="show")a.css("opacity",0).css(f,d=="pos"?-c:c);if(h=="hide")c/=m*2;h!="hide"&&m--;if(h=="show"){var g={opacity:1};g[f]=(d=="pos"?"+=":"-=")+c;a.animate(g,i/2,b.options.easing);c/=2;m--}for(g=0;g<m;g++){var j={},k={};j[f]=(d=="pos"?"-=":"+=")+c;k[f]=(d=="pos"?"+=":"-=")+c;a.animate(j,i/2,b.options.easing).animate(k,i/2,b.options.easing);c=h=="hide"?c*2:c/2}if(h=="hide"){g={opacity:0};g[f]=(d=="pos"?"-=":"+=")+c;a.animate(g,i/2,b.options.easing,function(){a.hide();e.effects.restore(a,l);e.effects.removeWrapper(a);
+b.callback&&b.callback.apply(this,arguments)})}else{j={};k={};j[f]=(d=="pos"?"-=":"+=")+c;k[f]=(d=="pos"?"+=":"-=")+c;a.animate(j,i/2,b.options.easing).animate(k,i/2,b.options.easing,function(){e.effects.restore(a,l);e.effects.removeWrapper(a);b.callback&&b.callback.apply(this,arguments)})}a.queue("fx",function(){a.dequeue()});a.dequeue()})}})(jQuery);
+;/*
+ * jQuery UI Effects Clip 1.8.16
+ *
+ * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
+ * Dual licensed under the MIT or GPL Version 2 licenses.
+ * http://jquery.org/license
+ *
+ * http://docs.jquery.com/UI/Effects/Clip
+ *
+ * Depends:
+ *	jquery.effects.core.js
+ */
+(function(b){b.effects.clip=function(e){return this.queue(function(){var a=b(this),i=["position","top","bottom","left","right","height","width"],f=b.effects.setMode(a,e.options.mode||"hide"),c=e.options.direction||"vertical";b.effects.save(a,i);a.show();var d=b.effects.createWrapper(a).css({overflow:"hidden"});d=a[0].tagName=="IMG"?d:a;var g={size:c=="vertical"?"height":"width",position:c=="vertical"?"top":"left"};c=c=="vertical"?d.height():d.width();if(f=="show"){d.css(g.size,0);d.css(g.position,
+c/2)}var h={};h[g.size]=f=="show"?c:0;h[g.position]=f=="show"?0:c/2;d.animate(h,{queue:false,duration:e.duration,easing:e.options.easing,complete:function(){f=="hide"&&a.hide();b.effects.restore(a,i);b.effects.removeWrapper(a);e.callback&&e.callback.apply(a[0],arguments);a.dequeue()}})})}})(jQuery);
+;/*
+ * jQuery UI Effects Drop 1.8.16
+ *
+ * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
+ * Dual licensed under the MIT or GPL Version 2 licenses.
+ * http://jquery.org/license
+ *
+ * http://docs.jquery.com/UI/Effects/Drop
+ *
+ * Depends:
+ *	jquery.effects.core.js
+ */
+(function(c){c.effects.drop=function(d){return this.queue(function(){var a=c(this),h=["position","top","bottom","left","right","opacity"],e=c.effects.setMode(a,d.options.mode||"hide"),b=d.options.direction||"left";c.effects.save(a,h);a.show();c.effects.createWrapper(a);var f=b=="up"||b=="down"?"top":"left";b=b=="up"||b=="left"?"pos":"neg";var g=d.options.distance||(f=="top"?a.outerHeight({margin:true})/2:a.outerWidth({margin:true})/2);if(e=="show")a.css("opacity",0).css(f,b=="pos"?-g:g);var i={opacity:e==
+"show"?1:0};i[f]=(e=="show"?b=="pos"?"+=":"-=":b=="pos"?"-=":"+=")+g;a.animate(i,{queue:false,duration:d.duration,easing:d.options.easing,complete:function(){e=="hide"&&a.hide();c.effects.restore(a,h);c.effects.removeWrapper(a);d.callback&&d.callback.apply(this,arguments);a.dequeue()}})})}})(jQuery);
+;/*
+ * jQuery UI Effects Explode 1.8.16
+ *
+ * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
+ * Dual licensed under the MIT or GPL Version 2 licenses.
+ * http://jquery.org/license
+ *
+ * http://docs.jquery.com/UI/Effects/Explode
+ *
+ * Depends:
+ *	jquery.effects.core.js
+ */
+(function(j){j.effects.explode=function(a){return this.queue(function(){var c=a.options.pieces?Math.round(Math.sqrt(a.options.pieces)):3,d=a.options.pieces?Math.round(Math.sqrt(a.options.pieces)):3;a.options.mode=a.options.mode=="toggle"?j(this).is(":visible")?"hide":"show":a.options.mode;var b=j(this).show().css("visibility","hidden"),g=b.offset();g.top-=parseInt(b.css("marginTop"),10)||0;g.left-=parseInt(b.css("marginLeft"),10)||0;for(var h=b.outerWidth(true),i=b.outerHeight(true),e=0;e<c;e++)for(var f=
+0;f<d;f++)b.clone().appendTo("body").wrap("<div></div>").css({position:"absolute",visibility:"visible",left:-f*(h/d),top:-e*(i/c)}).parent().addClass("ui-effects-explode").css({position:"absolute",overflow:"hidden",width:h/d,height:i/c,left:g.left+f*(h/d)+(a.options.mode=="show"?(f-Math.floor(d/2))*(h/d):0),top:g.top+e*(i/c)+(a.options.mode=="show"?(e-Math.floor(c/2))*(i/c):0),opacity:a.options.mode=="show"?0:1}).animate({left:g.left+f*(h/d)+(a.options.mode=="show"?0:(f-Math.floor(d/2))*(h/d)),top:g.top+
+e*(i/c)+(a.options.mode=="show"?0:(e-Math.floor(c/2))*(i/c)),opacity:a.options.mode=="show"?1:0},a.duration||500);setTimeout(function(){a.options.mode=="show"?b.css({visibility:"visible"}):b.css({visibility:"visible"}).hide();a.callback&&a.callback.apply(b[0]);b.dequeue();j("div.ui-effects-explode").remove()},a.duration||500)})}})(jQuery);
+;/*
+ * jQuery UI Effects Fade 1.8.16
+ *
+ * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
+ * Dual licensed under the MIT or GPL Version 2 licenses.
+ * http://jquery.org/license
+ *
+ * http://docs.jquery.com/UI/Effects/Fade
+ *
+ * Depends:
+ *	jquery.effects.core.js
+ */
+(function(b){b.effects.fade=function(a){return this.queue(function(){var c=b(this),d=b.effects.setMode(c,a.options.mode||"hide");c.animate({opacity:d},{queue:false,duration:a.duration,easing:a.options.easing,complete:function(){a.callback&&a.callback.apply(this,arguments);c.dequeue()}})})}})(jQuery);
+;/*
+ * jQuery UI Effects Fold 1.8.16
+ *
+ * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
+ * Dual licensed under the MIT or GPL Version 2 licenses.
+ * http://jquery.org/license
+ *
+ * http://docs.jquery.com/UI/Effects/Fold
+ *
+ * Depends:
+ *	jquery.effects.core.js
+ */
+(function(c){c.effects.fold=function(a){return this.queue(function(){var b=c(this),j=["position","top","bottom","left","right"],d=c.effects.setMode(b,a.options.mode||"hide"),g=a.options.size||15,h=!!a.options.horizFirst,k=a.duration?a.duration/2:c.fx.speeds._default/2;c.effects.save(b,j);b.show();var e=c.effects.createWrapper(b).css({overflow:"hidden"}),f=d=="show"!=h,l=f?["width","height"]:["height","width"];f=f?[e.width(),e.height()]:[e.height(),e.width()];var i=/([0-9]+)%/.exec(g);if(i)g=parseInt(i[1],
+10)/100*f[d=="hide"?0:1];if(d=="show")e.css(h?{height:0,width:g}:{height:g,width:0});h={};i={};h[l[0]]=d=="show"?f[0]:g;i[l[1]]=d=="show"?f[1]:0;e.animate(h,k,a.options.easing).animate(i,k,a.options.easing,function(){d=="hide"&&b.hide();c.effects.restore(b,j);c.effects.removeWrapper(b);a.callback&&a.callback.apply(b[0],arguments);b.dequeue()})})}})(jQuery);
+;/*
+ * jQuery UI Effects Highlight 1.8.16
+ *
+ * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
+ * Dual licensed under the MIT or GPL Version 2 licenses.
+ * http://jquery.org/license
+ *
+ * http://docs.jquery.com/UI/Effects/Highlight
+ *
+ * Depends:
+ *	jquery.effects.core.js
+ */
+(function(b){b.effects.highlight=function(c){return this.queue(function(){var a=b(this),e=["backgroundImage","backgroundColor","opacity"],d=b.effects.setMode(a,c.options.mode||"show"),f={backgroundColor:a.css("backgroundColor")};if(d=="hide")f.opacity=0;b.effects.save(a,e);a.show().css({backgroundImage:"none",backgroundColor:c.options.color||"#ffff99"}).animate(f,{queue:false,duration:c.duration,easing:c.options.easing,complete:function(){d=="hide"&&a.hide();b.effects.restore(a,e);d=="show"&&!b.support.opacity&&
+this.style.removeAttribute("filter");c.callback&&c.callback.apply(this,arguments);a.dequeue()}})})}})(jQuery);
+;/*
+ * jQuery UI Effects Pulsate 1.8.16
+ *
+ * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
+ * Dual licensed under the MIT or GPL Version 2 licenses.
+ * http://jquery.org/license
+ *
+ * http://docs.jquery.com/UI/Effects/Pulsate
+ *
+ * Depends:
+ *	jquery.effects.core.js
+ */
+(function(d){d.effects.pulsate=function(a){return this.queue(function(){var b=d(this),c=d.effects.setMode(b,a.options.mode||"show");times=(a.options.times||5)*2-1;duration=a.duration?a.duration/2:d.fx.speeds._default/2;isVisible=b.is(":visible");animateTo=0;if(!isVisible){b.css("opacity",0).show();animateTo=1}if(c=="hide"&&isVisible||c=="show"&&!isVisible)times--;for(c=0;c<times;c++){b.animate({opacity:animateTo},duration,a.options.easing);animateTo=(animateTo+1)%2}b.animate({opacity:animateTo},duration,
+a.options.easing,function(){animateTo==0&&b.hide();a.callback&&a.callback.apply(this,arguments)});b.queue("fx",function(){b.dequeue()}).dequeue()})}})(jQuery);
+;/*
+ * jQuery UI Effects Scale 1.8.16
+ *
+ * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
+ * Dual licensed under the MIT or GPL Version 2 licenses.
+ * http://jquery.org/license
+ *
+ * http://docs.jquery.com/UI/Effects/Scale
+ *
+ * Depends:
+ *	jquery.effects.core.js
+ */
+(function(c){c.effects.puff=function(b){return this.queue(function(){var a=c(this),e=c.effects.setMode(a,b.options.mode||"hide"),g=parseInt(b.options.percent,10)||150,h=g/100,i={height:a.height(),width:a.width()};c.extend(b.options,{fade:true,mode:e,percent:e=="hide"?g:100,from:e=="hide"?i:{height:i.height*h,width:i.width*h}});a.effect("scale",b.options,b.duration,b.callback);a.dequeue()})};c.effects.scale=function(b){return this.queue(function(){var a=c(this),e=c.extend(true,{},b.options),g=c.effects.setMode(a,
+b.options.mode||"effect"),h=parseInt(b.options.percent,10)||(parseInt(b.options.percent,10)==0?0:g=="hide"?0:100),i=b.options.direction||"both",f=b.options.origin;if(g!="effect"){e.origin=f||["middle","center"];e.restore=true}f={height:a.height(),width:a.width()};a.from=b.options.from||(g=="show"?{height:0,width:0}:f);h={y:i!="horizontal"?h/100:1,x:i!="vertical"?h/100:1};a.to={height:f.height*h.y,width:f.width*h.x};if(b.options.fade){if(g=="show"){a.from.opacity=0;a.to.opacity=1}if(g=="hide"){a.from.opacity=
+1;a.to.opacity=0}}e.from=a.from;e.to=a.to;e.mode=g;a.effect("size",e,b.duration,b.callback);a.dequeue()})};c.effects.size=function(b){return this.queue(function(){var a=c(this),e=["position","top","bottom","left","right","width","height","overflow","opacity"],g=["position","top","bottom","left","right","overflow","opacity"],h=["width","height","overflow"],i=["fontSize"],f=["borderTopWidth","borderBottomWidth","paddingTop","paddingBottom"],k=["borderLeftWidth","borderRightWidth","paddingLeft","paddingRight"],
+p=c.effects.setMode(a,b.options.mode||"effect"),n=b.options.restore||false,m=b.options.scale||"both",l=b.options.origin,j={height:a.height(),width:a.width()};a.from=b.options.from||j;a.to=b.options.to||j;if(l){l=c.effects.getBaseline(l,j);a.from.top=(j.height-a.from.height)*l.y;a.from.left=(j.width-a.from.width)*l.x;a.to.top=(j.height-a.to.height)*l.y;a.to.left=(j.width-a.to.width)*l.x}var d={from:{y:a.from.height/j.height,x:a.from.width/j.width},to:{y:a.to.height/j.height,x:a.to.width/j.width}};
+if(m=="box"||m=="both"){if(d.from.y!=d.to.y){e=e.concat(f);a.from=c.effects.setTransition(a,f,d.from.y,a.from);a.to=c.effects.setTransition(a,f,d.to.y,a.to)}if(d.from.x!=d.to.x){e=e.concat(k);a.from=c.effects.setTransition(a,k,d.from.x,a.from);a.to=c.effects.setTransition(a,k,d.to.x,a.to)}}if(m=="content"||m=="both")if(d.from.y!=d.to.y){e=e.concat(i);a.from=c.effects.setTransition(a,i,d.from.y,a.from);a.to=c.effects.setTransition(a,i,d.to.y,a.to)}c.effects.save(a,n?e:g);a.show();c.effects.createWrapper(a);
+a.css("overflow","hidden").css(a.from);if(m=="content"||m=="both"){f=f.concat(["marginTop","marginBottom"]).concat(i);k=k.concat(["marginLeft","marginRight"]);h=e.concat(f).concat(k);a.find("*[width]").each(function(){child=c(this);n&&c.effects.save(child,h);var o={height:child.height(),width:child.width()};child.from={height:o.height*d.from.y,width:o.width*d.from.x};child.to={height:o.height*d.to.y,width:o.width*d.to.x};if(d.from.y!=d.to.y){child.from=c.effects.setTransition(child,f,d.from.y,child.from);
+child.to=c.effects.setTransition(child,f,d.to.y,child.to)}if(d.from.x!=d.to.x){child.from=c.effects.setTransition(child,k,d.from.x,child.from);child.to=c.effects.setTransition(child,k,d.to.x,child.to)}child.css(child.from);child.animate(child.to,b.duration,b.options.easing,function(){n&&c.effects.restore(child,h)})})}a.animate(a.to,{queue:false,duration:b.duration,easing:b.options.easing,complete:function(){a.to.opacity===0&&a.css("opacity",a.from.opacity);p=="hide"&&a.hide();c.effects.restore(a,
+n?e:g);c.effects.removeWrapper(a);b.callback&&b.callback.apply(this,arguments);a.dequeue()}})})}})(jQuery);
+;/*
+ * jQuery UI Effects Shake 1.8.16
+ *
+ * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
+ * Dual licensed under the MIT or GPL Version 2 licenses.
+ * http://jquery.org/license
+ *
+ * http://docs.jquery.com/UI/Effects/Shake
+ *
+ * Depends:
+ *	jquery.effects.core.js
+ */
+(function(d){d.effects.shake=function(a){return this.queue(function(){var b=d(this),j=["position","top","bottom","left","right"];d.effects.setMode(b,a.options.mode||"effect");var c=a.options.direction||"left",e=a.options.distance||20,l=a.options.times||3,f=a.duration||a.options.duration||140;d.effects.save(b,j);b.show();d.effects.createWrapper(b);var g=c=="up"||c=="down"?"top":"left",h=c=="up"||c=="left"?"pos":"neg";c={};var i={},k={};c[g]=(h=="pos"?"-=":"+=")+e;i[g]=(h=="pos"?"+=":"-=")+e*2;k[g]=
+(h=="pos"?"-=":"+=")+e*2;b.animate(c,f,a.options.easing);for(e=1;e<l;e++)b.animate(i,f,a.options.easing).animate(k,f,a.options.easing);b.animate(i,f,a.options.easing).animate(c,f/2,a.options.easing,function(){d.effects.restore(b,j);d.effects.removeWrapper(b);a.callback&&a.callback.apply(this,arguments)});b.queue("fx",function(){b.dequeue()});b.dequeue()})}})(jQuery);
+;/*
+ * jQuery UI Effects Slide 1.8.16
+ *
+ * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
+ * Dual licensed under the MIT or GPL Version 2 licenses.
+ * http://jquery.org/license
+ *
+ * http://docs.jquery.com/UI/Effects/Slide
+ *
+ * Depends:
+ *	jquery.effects.core.js
+ */
+(function(c){c.effects.slide=function(d){return this.queue(function(){var a=c(this),h=["position","top","bottom","left","right"],f=c.effects.setMode(a,d.options.mode||"show"),b=d.options.direction||"left";c.effects.save(a,h);a.show();c.effects.createWrapper(a).css({overflow:"hidden"});var g=b=="up"||b=="down"?"top":"left";b=b=="up"||b=="left"?"pos":"neg";var e=d.options.distance||(g=="top"?a.outerHeight({margin:true}):a.outerWidth({margin:true}));if(f=="show")a.css(g,b=="pos"?isNaN(e)?"-"+e:-e:e);
+var i={};i[g]=(f=="show"?b=="pos"?"+=":"-=":b=="pos"?"-=":"+=")+e;a.animate(i,{queue:false,duration:d.duration,easing:d.options.easing,complete:function(){f=="hide"&&a.hide();c.effects.restore(a,h);c.effects.removeWrapper(a);d.callback&&d.callback.apply(this,arguments);a.dequeue()}})})}})(jQuery);
+;/*
+ * jQuery UI Effects Transfer 1.8.16
+ *
+ * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
+ * Dual licensed under the MIT or GPL Version 2 licenses.
+ * http://jquery.org/license
+ *
+ * http://docs.jquery.com/UI/Effects/Transfer
+ *
+ * Depends:
+ *	jquery.effects.core.js
+ */
+(function(e){e.effects.transfer=function(a){return this.queue(function(){var b=e(this),c=e(a.options.to),d=c.offset();c={top:d.top,left:d.left,height:c.innerHeight(),width:c.innerWidth()};d=b.offset();var f=e('<div class="ui-effects-transfer"></div>').appendTo(document.body).addClass(a.options.className).css({top:d.top,left:d.left,height:b.innerHeight(),width:b.innerWidth(),position:"absolute"}).animate(c,a.duration,a.options.easing,function(){f.remove();a.callback&&a.callback.apply(b[0],arguments);
+b.dequeue()})})}})(jQuery);
+;
\ No newline at end of file

Property changes on: TXM/trunk/org.txm.conllu.core/template/lib/ext/jquery-ui.min.js
___________________________________________________________________
Added: svn:mime-type
   + text/plain

Index: TXM/trunk/org.txm.conllu.core/template/lib/ext/jquery.svg.min.js
===================================================================
--- TXM/trunk/org.txm.conllu.core/template/lib/ext/jquery.svg.min.js	(revision 0)
+++ TXM/trunk/org.txm.conllu.core/template/lib/ext/jquery.svg.min.js	(revision 3567)
@@ -0,0 +1,7 @@
+/* http://keith-wood.name/svg.html
+   SVG for jQuery v1.4.3.
+   Written by Keith Wood (kbwood{at}iinet.com.au) August 2007.
+   Dual licensed under the GPL (http://dev.jquery.com/browser/trunk/jquery/GPL-LICENSE.txt) and 
+   MIT (http://dev.jquery.com/browser/trunk/jquery/MIT-LICENSE.txt) licenses. 
+   Please attribute the author if you use it. */
+(function($){function SVGManager(){this._settings=[];this._extensions=[];this.regional=[];this.regional['']={errorLoadingText:'Error loading',notSupportedText:'This browser does not support SVG'};this.local=this.regional[''];this._uuid=new Date().getTime();this._renesis=detectActiveX('RenesisX.RenesisCtrl')}function detectActiveX(a){try{return!!(window.ActiveXObject&&new ActiveXObject(a))}catch(e){return false}}var p='svgwrapper';$.extend(SVGManager.prototype,{markerClassName:'hasSVG',svgNS:'http://www.w3.org/2000/svg',xlinkNS:'http://www.w3.org/1999/xlink',_wrapperClass:SVGWrapper,_attrNames:{class_:'class',in_:'in',alignmentBaseline:'alignment-baseline',baselineShift:'baseline-shift',clipPath:'clip-path',clipRule:'clip-rule',colorInterpolation:'color-interpolation',colorInterpolationFilters:'color-interpolation-filters',colorRendering:'color-rendering',dominantBaseline:'dominant-baseline',enableBackground:'enable-background',fillOpacity:'fill-opacity',fillRule:'fill-rule',floodColor:'flood-color',floodOpacity:'flood-opacity',fontFamily:'font-family',fontSize:'font-size',fontSizeAdjust:'font-size-adjust',fontStretch:'font-stretch',fontStyle:'font-style',fontVariant:'font-variant',fontWeight:'font-weight',glyphOrientationHorizontal:'glyph-orientation-horizontal',glyphOrientationVertical:'glyph-orientation-vertical',horizAdvX:'horiz-adv-x',horizOriginX:'horiz-origin-x',imageRendering:'image-rendering',letterSpacing:'letter-spacing',lightingColor:'lighting-color',markerEnd:'marker-end',markerMid:'marker-mid',markerStart:'marker-start',stopColor:'stop-color',stopOpacity:'stop-opacity',strikethroughPosition:'strikethrough-position',strikethroughThickness:'strikethrough-thickness',strokeDashArray:'stroke-dasharray',strokeDashOffset:'stroke-dashoffset',strokeLineCap:'stroke-linecap',strokeLineJoin:'stroke-linejoin',strokeMiterLimit:'stroke-miterlimit',strokeOpacity:'stroke-opacity',strokeWidth:'stroke-width',textAnchor:'text-anchor',textDecoration:'text-decoration',textRendering:'text-rendering',underlinePosition:'underline-position',underlineThickness:'underline-thickness',vertAdvY:'vert-adv-y',vertOriginY:'vert-origin-y',wordSpacing:'word-spacing',writingMode:'writing-mode'},_attachSVG:function(a,b){var c=(a.namespaceURI==this.svgNS?a:null);var a=(c?null:a);if($(a||c).hasClass(this.markerClassName)){return}if(typeof b=='string'){b={loadURL:b}}else if(typeof b=='function'){b={onLoad:b}}$(a||c).addClass(this.markerClassName);try{if(!c){c=document.createElementNS(this.svgNS,'svg');c.setAttribute('version','1.1');c.setAttribute('width',a.clientWidth);c.setAttribute('height',a.clientHeight);a.appendChild(c)}this._afterLoad(a,c,b||{})}catch(e){if($.browser.msie){if(!a.id){a.id='svg'+(this._uuid++)}this._settings[a.id]=b;a.innerHTML='<embed type="image/svg+xml" width="100%" '+'height="100%" src="'+(b.initPath||'')+'blank.svg"/>'}else{a.innerHTML='<p class="svg_error">'+this.local.notSupportedText+'</p>'}}},_registerSVG:function(){for(var i=0;i<document.embeds.length;i++){var a=document.embeds[i].parentNode;if(!$(a).hasClass($.svg.markerClassName)||$.data(a,p)){continue}var b=null;try{b=document.embeds[i].getSVGDocument()}catch(e){setTimeout($.svg._registerSVG,250);return}b=(b?b.documentElement:null);if(b){$.svg._afterLoad(a,b)}}},_afterLoad:function(a,b,c){var c=c||this._settings[a.id];this._settings[a?a.id:'']=null;var d=new this._wrapperClass(b,a);$.data(a||b,p,d);try{if(c.loadURL){d.load(c.loadURL,c)}if(c.settings){d.configure(c.settings)}if(c.onLoad&&!c.loadURL){c.onLoad.apply(a||b,[d])}}catch(e){alert(e)}},_getSVG:function(a){a=(typeof a=='string'?$(a)[0]:(a.jquery?a[0]:a));return $.data(a,p)},_destroySVG:function(a){var b=$(a);if(!b.hasClass(this.markerClassName)){return}b.removeClass(this.markerClassName);if(a.namespaceURI!=this.svgNS){b.empty()}$.removeData(a,p)},addExtension:function(a,b){this._extensions.push([a,b])}});function SVGWrapper(a,b){this._svg=a;this._container=b;for(var i=0;i<$.svg._extensions.length;i++){var c=$.svg._extensions[i];this[c[0]]=new c[1](this)}}$.extend(SVGWrapper.prototype,{_width:function(){return(this._container?this._container.clientWidth:this._svg.width)},_height:function(){return(this._container?this._container.clientHeight:this._svg.height)},root:function(){return this._svg},configure:function(a,b){if(b){for(var i=this._svg.attributes.length-1;i>=0;i--){var c=this._svg.attributes.item(i);if(!(c.nodeName=='onload'||c.nodeName=='version'||c.nodeName.substring(0,5)=='xmlns')){this._svg.attributes.removeNamedItem(c.nodeName)}}}for(var d in a){this._svg.setAttribute(d,a[d])}return this},getElementById:function(a){return this._svg.ownerDocument.getElementById(a)},change:function(a,b){if(a){for(var c in b){if(b[c]==null){a.removeAttribute(c)}else{a.setAttribute(c,b[c])}}}return this},_args:function(b,c,d){c.splice(0,0,'parent');c.splice(c.length,0,'settings');var e={};var f=0;if(b[0]!=null&&b[0].jquery){b[0]=b[0][0]}if(b[0]!=null&&!(typeof b[0]=='object'&&b[0].nodeName)){e['parent']=null;f=1}for(var i=0;i<b.length;i++){e[c[i+f]]=b[i]}if(d){$.each(d,function(i,a){if(typeof e[a]=='object'){e.settings=e[a];e[a]=null}})}return e},title:function(a,b,c){var d=this._args(arguments,['text']);var e=this._makeNode(d.parent,'title',d.settings||{});e.appendChild(this._svg.ownerDocument.createTextNode(d.text));return e},describe:function(a,b,c){var d=this._args(arguments,['text']);var e=this._makeNode(d.parent,'desc',d.settings||{});e.appendChild(this._svg.ownerDocument.createTextNode(d.text));return e},defs:function(a,b,c){var d=this._args(arguments,['id'],['id']);return this._makeNode(d.parent,'defs',$.extend((d.id?{id:d.id}:{}),d.settings||{}))},symbol:function(a,b,c,d,e,f,g){var h=this._args(arguments,['id','x1','y1','width','height']);return this._makeNode(h.parent,'symbol',$.extend({id:h.id,viewBox:h.x1+' '+h.y1+' '+h.width+' '+h.height},h.settings||{}))},marker:function(a,b,c,d,e,f,g,h){var i=this._args(arguments,['id','refX','refY','mWidth','mHeight','orient'],['orient']);return this._makeNode(i.parent,'marker',$.extend({id:i.id,refX:i.refX,refY:i.refY,markerWidth:i.mWidth,markerHeight:i.mHeight,orient:i.orient||'auto'},i.settings||{}))},style:function(a,b,c){var d=this._args(arguments,['styles']);var e=this._makeNode(d.parent,'style',$.extend({type:'text/css'},d.settings||{}));e.appendChild(this._svg.ownerDocument.createTextNode(d.styles));if($.browser.opera){$('head').append('<style type="text/css">'+d.styles+'</style>')}return e},script:function(a,b,c,d){var e=this._args(arguments,['script','type'],['type']);var f=this._makeNode(e.parent,'script',$.extend({type:e.type||'text/javascript'},e.settings||{}));f.appendChild(this._svg.ownerDocument.createTextNode(this._escapeXML(e.script)));if(!$.browser.mozilla){$.globalEval(e.script)}return f},linearGradient:function(a,b,c,d,e,f,g,h){var i=this._args(arguments,['id','stops','x1','y1','x2','y2'],['x1']);var j=$.extend({id:i.id},(i.x1!=null?{x1:i.x1,y1:i.y1,x2:i.x2,y2:i.y2}:{}));return this._gradient(i.parent,'linearGradient',$.extend(j,i.settings||{}),i.stops)},radialGradient:function(a,b,c,d,e,r,f,g,h){var i=this._args(arguments,['id','stops','cx','cy','r','fx','fy'],['cx']);var j=$.extend({id:i.id},(i.cx!=null?{cx:i.cx,cy:i.cy,r:i.r,fx:i.fx,fy:i.fy}:{}));return this._gradient(i.parent,'radialGradient',$.extend(j,i.settings||{}),i.stops)},_gradient:function(a,b,c,d){var e=this._makeNode(a,b,c);for(var i=0;i<d.length;i++){var f=d[i];this._makeNode(e,'stop',$.extend({offset:f[0],stopColor:f[1]},(f[2]!=null?{stopOpacity:f[2]}:{})))}return e},pattern:function(a,b,x,y,c,d,e,f,g,h,i){var j=this._args(arguments,['id','x','y','width','height','vx','vy','vwidth','vheight'],['vx']);var k=$.extend({id:j.id,x:j.x,y:j.y,width:j.width,height:j.height},(j.vx!=null?{viewBox:j.vx+' '+j.vy+' '+j.vwidth+' '+j.vheight}:{}));return this._makeNode(j.parent,'pattern',$.extend(k,j.settings||{}))},mask:function(a,b,x,y,c,d,e){var f=this._args(arguments,['id','x','y','width','height']);return this._makeNode(f.parent,'mask',$.extend({id:f.id,x:f.x,y:f.y,width:f.width,height:f.height},f.settings||{}))},createPath:function(){return new SVGPath()},createText:function(){return new SVGText()},svg:function(a,x,y,b,c,d,e,f,g,h){var i=this._args(arguments,['x','y','width','height','vx','vy','vwidth','vheight'],['vx']);var j=$.extend({x:i.x,y:i.y,width:i.width,height:i.height},(i.vx!=null?{viewBox:i.vx+' '+i.vy+' '+i.vwidth+' '+i.vheight}:{}));return this._makeNode(i.parent,'svg',$.extend(j,i.settings||{}))},group:function(a,b,c){var d=this._args(arguments,['id'],['id']);return this._makeNode(d.parent,'g',$.extend({id:d.id},d.settings||{}))},use:function(a,x,y,b,c,d,e){var f=this._args(arguments,['x','y','width','height','ref']);if(typeof f.x=='string'){f.ref=f.x;f.settings=f.y;f.x=f.y=f.width=f.height=null}var g=this._makeNode(f.parent,'use',$.extend({x:f.x,y:f.y,width:f.width,height:f.height},f.settings||{}));g.setAttributeNS($.svg.xlinkNS,'href',f.ref);return g},link:function(a,b,c){var d=this._args(arguments,['ref']);var e=this._makeNode(d.parent,'a',d.settings);e.setAttributeNS($.svg.xlinkNS,'href',d.ref);return e},image:function(a,x,y,b,c,d,e){var f=this._args(arguments,['x','y','width','height','ref']);var g=this._makeNode(f.parent,'image',$.extend({x:f.x,y:f.y,width:f.width,height:f.height},f.settings||{}));g.setAttributeNS($.svg.xlinkNS,'href',f.ref);return g},path:function(a,b,c){var d=this._args(arguments,['path']);return this._makeNode(d.parent,'path',$.extend({d:(d.path.path?d.path.path():d.path)},d.settings||{}))},rect:function(a,x,y,b,c,d,e,f){var g=this._args(arguments,['x','y','width','height','rx','ry'],['rx']);return this._makeNode(g.parent,'rect',$.extend({x:g.x,y:g.y,width:g.width,height:g.height},(g.rx?{rx:g.rx,ry:g.ry}:{}),g.settings||{}))},circle:function(a,b,c,r,d){var e=this._args(arguments,['cx','cy','r']);return this._makeNode(e.parent,'circle',$.extend({cx:e.cx,cy:e.cy,r:e.r},e.settings||{}))},ellipse:function(a,b,c,d,e,f){var g=this._args(arguments,['cx','cy','rx','ry']);return this._makeNode(g.parent,'ellipse',$.extend({cx:g.cx,cy:g.cy,rx:g.rx,ry:g.ry},g.settings||{}))},line:function(a,b,c,d,e,f){var g=this._args(arguments,['x1','y1','x2','y2']);return this._makeNode(g.parent,'line',$.extend({x1:g.x1,y1:g.y1,x2:g.x2,y2:g.y2},g.settings||{}))},polyline:function(a,b,c){var d=this._args(arguments,['points']);return this._poly(d.parent,'polyline',d.points,d.settings)},polygon:function(a,b,c){var d=this._args(arguments,['points']);return this._poly(d.parent,'polygon',d.points,d.settings)},_poly:function(a,b,c,d){var e='';for(var i=0;i<c.length;i++){e+=c[i].join()+' '}return this._makeNode(a,b,$.extend({points:$.trim(e)},d||{}))},text:function(a,x,y,b,c){var d=this._args(arguments,['x','y','value']);if(typeof d.x=='string'&&arguments.length<4){d.value=d.x;d.settings=d.y;d.x=d.y=null}return this._text(d.parent,'text',d.value,$.extend({x:(d.x&&isArray(d.x)?d.x.join(' '):d.x),y:(d.y&&isArray(d.y)?d.y.join(' '):d.y)},d.settings||{}))},textpath:function(a,b,c,d){var e=this._args(arguments,['path','value']);var f=this._text(e.parent,'textPath',e.value,e.settings||{});f.setAttributeNS($.svg.xlinkNS,'href',e.path);return f},_text:function(a,b,c,d){var e=this._makeNode(a,b,d);if(typeof c=='string'){e.appendChild(e.ownerDocument.createTextNode(c))}else{for(var i=0;i<c._parts.length;i++){var f=c._parts[i];if(f[0]=='tspan'){var g=this._makeNode(e,f[0],f[2]);g.appendChild(e.ownerDocument.createTextNode(f[1]));e.appendChild(g)}else if(f[0]=='tref'){var g=this._makeNode(e,f[0],f[2]);g.setAttributeNS($.svg.xlinkNS,'href',f[1]);e.appendChild(g)}else if(f[0]=='textpath'){var h=$.extend({},f[2]);h.href=null;var g=this._makeNode(e,f[0],h);g.setAttributeNS($.svg.xlinkNS,'href',f[2].href);g.appendChild(e.ownerDocument.createTextNode(f[1]));e.appendChild(g)}else{e.appendChild(e.ownerDocument.createTextNode(f[1]))}}}return e},other:function(a,b,c){var d=this._args(arguments,['name']);return this._makeNode(d.parent,d.name,d.settings||{})},_makeNode:function(a,b,c){a=a||this._svg;var d=this._svg.ownerDocument.createElementNS($.svg.svgNS,b);for(var b in c){var e=c[b];if(e!=null&&e!=null&&(typeof e!='string'||e!='')){d.setAttribute($.svg._attrNames[b]||b,e)}}a.appendChild(d);return d},add:function(b,c){var d=this._args((arguments.length==1?[null,b]:arguments),['node']);var f=this;d.parent=d.parent||this._svg;try{if($.svg._renesis){throw'Force traversal';}d.parent.appendChild(d.node.cloneNode(true))}catch(e){d.node=(d.node.jquery?d.node:$(d.node));d.node.each(function(){var a=f._cloneAsSVG(this);if(a){d.parent.appendChild(a)}})}return this},_cloneAsSVG:function(a){var b=null;if(a.nodeType==1){b=this._svg.ownerDocument.createElementNS($.svg.svgNS,this._checkName(a.nodeName));for(var i=0;i<a.attributes.length;i++){var c=a.attributes.item(i);if(c.nodeName!='xmlns'&&c.nodeValue){if(c.prefix=='xlink'){b.setAttributeNS($.svg.xlinkNS,c.localName,c.nodeValue)}else{b.setAttribute(this._checkName(c.nodeName),c.nodeValue)}}}for(var i=0;i<a.childNodes.length;i++){var d=this._cloneAsSVG(a.childNodes[i]);if(d){b.appendChild(d)}}}else if(a.nodeType==3){if($.trim(a.nodeValue)){b=this._svg.ownerDocument.createTextNode(a.nodeValue)}}else if(a.nodeType==4){if($.trim(a.nodeValue)){try{b=this._svg.ownerDocument.createCDATASection(a.nodeValue)}catch(e){b=this._svg.ownerDocument.createTextNode(a.nodeValue.replace(/&/g,'&amp;').replace(/</g,'&lt;').replace(/>/g,'&gt;'))}}}return b},_checkName:function(a){a=(a.substring(0,1)>='A'&&a.substring(0,1)<='Z'?a.toLowerCase():a);return(a.substring(0,4)=='svg:'?a.substring(4):a)},load:function(h,j){j=(typeof j=='boolean'?{addTo:j}:(typeof j=='function'?{onLoad:j}:j||{}));if(!j.addTo){this.clear(false)}var k=[this._svg.getAttribute('width'),this._svg.getAttribute('height')];var l=this;var m=function(a){a=$.svg.local.errorLoadingText+': '+a;if(j.onLoad){j.onLoad.apply(l._container||l._svg,[l,a])}else{l.text(null,10,20,a)}};var n=function(a){var b=new ActiveXObject('Microsoft.XMLDOM');b.validateOnParse=false;b.resolveExternals=false;b.async=false;b.loadXML(a);if(b.parseError.errorCode!=0){m(b.parseError.reason);return null}return b};var o=function(a){if(!a){return}if(a.documentElement.nodeName!='svg'){var b=a.getElementsByTagName('parsererror');var c=(b.length?b[0].getElementsByTagName('div'):[]);m(!b.length?'???':(c.length?c[0]:b[0]).firstChild.nodeValue);return}var d={};for(var i=0;i<a.documentElement.attributes.length;i++){var f=a.documentElement.attributes.item(i);if(!(f.nodeName=='version'||f.nodeName.substring(0,5)=='xmlns')){d[f.nodeName]=f.nodeValue}}l.configure(d,true);var g=a.documentElement.childNodes;for(var i=0;i<g.length;i++){try{if($.svg._renesis){throw'Force traversal';}l._svg.appendChild(g[i].cloneNode(true));if(g[i].nodeName=='script'){$.globalEval(g[i].textContent)}}catch(e){l.add(null,g[i])}}if(!j.changeSize){l.configure({width:k[0],height:k[1]})}if(j.onLoad){j.onLoad.apply(l._container||l._svg,[l])}};if(h.match('<svg')){o($.browser.msie?n(h):new DOMParser().parseFromString(h,'text/xml'))}else{$.ajax({url:h,dataType:($.browser.msie?'text':'xml'),success:function(a){o($.browser.msie?n(a):a)},error:function(a,b,c){m(b+(c?' '+c.message:''))}})}return this},remove:function(a){a=(a.jquery?a[0]:a);a.parentNode.removeChild(a);return this},clear:function(a){if(a){this.configure({},true)}while(this._svg.firstChild){this._svg.removeChild(this._svg.firstChild)}return this},toSVG:function(a){a=a||this._svg;return(typeof XMLSerializer=='undefined'?this._toSVG(a):new XMLSerializer().serializeToString(a))},_toSVG:function(a){var b='';if(!a){return b}if(a.nodeType==3){b=a.nodeValue}else if(a.nodeType==4){b='<![CDATA['+a.nodeValue+']]>'}else{b='<'+a.nodeName;if(a.attributes){for(var i=0;i<a.attributes.length;i++){var c=a.attributes.item(i);if(!($.trim(c.nodeValue)==''||c.nodeValue.match(/^\[object/)||c.nodeValue.match(/^function/))){b+=' '+(c.namespaceURI==$.svg.xlinkNS?'xlink:':'')+c.nodeName+'="'+c.nodeValue+'"'}}}if(a.firstChild){b+='>';var d=a.firstChild;while(d){b+=this._toSVG(d);d=d.nextSibling}b+='</'+a.nodeName+'>'}else{b+='/>'}}return b},_escapeXML:function(a){a=a.replace(/&/g,'&amp;');a=a.replace(/</g,'&lt;');a=a.replace(/>/g,'&gt;');return a}});function SVGPath(){this._path=''}$.extend(SVGPath.prototype,{reset:function(){this._path='';return this},move:function(x,y,a){a=(isArray(x)?y:a);return this._coords((a?'m':'M'),x,y)},line:function(x,y,a){a=(isArray(x)?y:a);return this._coords((a?'l':'L'),x,y)},horiz:function(x,a){this._path+=(a?'h':'H')+(isArray(x)?x.join(' '):x);return this},vert:function(y,a){this._path+=(a?'v':'V')+(isArray(y)?y.join(' '):y);return this},curveC:function(a,b,c,d,x,y,e){e=(isArray(a)?b:e);return this._coords((e?'c':'C'),a,b,c,d,x,y)},smoothC:function(a,b,x,y,c){c=(isArray(a)?b:c);return this._coords((c?'s':'S'),a,b,x,y)},curveQ:function(a,b,x,y,c){c=(isArray(a)?b:c);return this._coords((c?'q':'Q'),a,b,x,y)},smoothQ:function(x,y,a){a=(isArray(x)?y:a);return this._coords((a?'t':'T'),x,y)},_coords:function(a,b,c,d,e,f,g){if(isArray(b)){for(var i=0;i<b.length;i++){var h=b[i];this._path+=(i==0?a:' ')+h[0]+','+h[1]+(h.length<4?'':' '+h[2]+','+h[3]+(h.length<6?'':' '+h[4]+','+h[5]))}}else{this._path+=a+b+','+c+(d==null?'':' '+d+','+e+(f==null?'':' '+f+','+g))}return this},arc:function(a,b,c,d,e,x,y,f){f=(isArray(a)?b:f);this._path+=(f?'a':'A');if(isArray(a)){for(var i=0;i<a.length;i++){var g=a[i];this._path+=(i==0?'':' ')+g[0]+','+g[1]+' '+g[2]+' '+(g[3]?'1':'0')+','+(g[4]?'1':'0')+' '+g[5]+','+g[6]}}else{this._path+=a+','+b+' '+c+' '+(d?'1':'0')+','+(e?'1':'0')+' '+x+','+y}return this},close:function(){this._path+='z';return this},path:function(){return this._path}});SVGPath.prototype.moveTo=SVGPath.prototype.move;SVGPath.prototype.lineTo=SVGPath.prototype.line;SVGPath.prototype.horizTo=SVGPath.prototype.horiz;SVGPath.prototype.vertTo=SVGPath.prototype.vert;SVGPath.prototype.curveCTo=SVGPath.prototype.curveC;SVGPath.prototype.smoothCTo=SVGPath.prototype.smoothC;SVGPath.prototype.curveQTo=SVGPath.prototype.curveQ;SVGPath.prototype.smoothQTo=SVGPath.prototype.smoothQ;SVGPath.prototype.arcTo=SVGPath.prototype.arc;function SVGText(){this._parts=[]}$.extend(SVGText.prototype,{reset:function(){this._parts=[];return this},string:function(a){this._parts[this._parts.length]=['text',a];return this},span:function(a,b){this._parts[this._parts.length]=['tspan',a,b];return this},ref:function(a,b){this._parts[this._parts.length]=['tref',a,b];return this},path:function(a,b,c){this._parts[this._parts.length]=['textpath',b,$.extend({href:a},c||{})];return this}});$.fn.svg=function(a){var b=Array.prototype.slice.call(arguments,1);if(typeof a=='string'&&a=='get'){return $.svg['_'+a+'SVG'].apply($.svg,[this[0]].concat(b))}return this.each(function(){if(typeof a=='string'){$.svg['_'+a+'SVG'].apply($.svg,[this].concat(b))}else{$.svg._attachSVG(this,a||{})}})};function isArray(a){return(a&&a.constructor==Array)}$.svg=new SVGManager()})(jQuery);
\ No newline at end of file

Property changes on: TXM/trunk/org.txm.conllu.core/template/lib/ext/jquery.svg.min.js
___________________________________________________________________
Added: svn:mime-type
   + text/plain

Index: TXM/trunk/org.txm.conllu.core/template/lib/ext/jquery.svgdom.min.js
===================================================================
--- TXM/trunk/org.txm.conllu.core/template/lib/ext/jquery.svgdom.min.js	(revision 0)
+++ TXM/trunk/org.txm.conllu.core/template/lib/ext/jquery.svgdom.min.js	(revision 3567)
@@ -0,0 +1,7 @@
+/* http://keith-wood.name/svg.html
+   SVG/jQuery DOM compatibility for jQuery v1.4.3.
+   Written by Keith Wood (kbwood{at}iinet.com.au) April 2009.
+   Dual licensed under the GPL (http://dev.jquery.com/browser/trunk/jquery/GPL-LICENSE.txt) and 
+   MIT (http://dev.jquery.com/browser/trunk/jquery/MIT-LICENSE.txt) licenses. 
+   Please attribute the author if you use it. */
+(function($){$.fn.addClass=function(e){return function(d){d=d||'';return this.each(function(){if(isSVGElem(this)){var c=this;$.each(d.split(/\s+/),function(i,a){var b=(c.className?c.className.baseVal:c.getAttribute('class'));if($.inArray(a,b.split(/\s+/))==-1){b+=(b?' ':'')+a;(c.className?c.className.baseVal=b:c.setAttribute('class',b))}})}else{e.apply($(this),[d])}})}}($.fn.addClass);$.fn.removeClass=function(e){return function(d){d=d||'';return this.each(function(){if(isSVGElem(this)){var c=this;$.each(d.split(/\s+/),function(i,a){var b=(c.className?c.className.baseVal:c.getAttribute('class'));b=$.grep(b.split(/\s+/),function(n,i){return n!=a}).join(' ');(c.className?c.className.baseVal=b:c.setAttribute('class',b))})}else{e.apply($(this),[d])}})}}($.fn.removeClass);$.fn.toggleClass=function(c){return function(a,b){return this.each(function(){if(isSVGElem(this)){if(typeof b!=='boolean'){b=!$(this).hasClass(a)}$(this)[(b?'add':'remove')+'Class'](a)}else{c.apply($(this),[a,b])}})}}($.fn.toggleClass);$.fn.hasClass=function(d){return function(b){b=b||'';var c=false;this.each(function(){if(isSVGElem(this)){var a=(this.className?this.className.baseVal:this.getAttribute('class')).split(/\s+/);c=($.inArray(b,a)>-1)}else{c=(d.apply($(this),[b]))}return!c});return c}}($.fn.hasClass);$.fn.attr=function(h){return function(b,c,d){if(typeof b==='string'&&c===undefined){var e=h.apply(this,[b,c,d]);if(e&&e.baseVal&&e.baseVal.numberOfItems!=null){c='';e=e.baseVal;for(var i=0;i<e.numberOfItems;i++){var f=e.getItem(i);switch(f.type){case 1:c+=' matrix('+f.matrix.a+','+f.matrix.b+','+f.matrix.c+','+f.matrix.d+','+f.matrix.e+','+f.matrix.f+')';break;case 2:c+=' translate('+f.matrix.e+','+f.matrix.f+')';break;case 3:c+=' scale('+f.matrix.a+','+f.matrix.d+')';break;case 4:c+=' rotate('+f.angle+')';break;case 5:c+=' skewX('+f.angle+')';break;case 6:c+=' skewY('+f.angle+')';break}}e=c.substring(1)}return(e&&e.baseVal?e.baseVal.valueAsString:e)}var g=b;if(typeof b==='string'){g={};g[b]=c}return this.each(function(){if(isSVGElem(this)){for(var n in g){var a=($.isFunction(g[n])?g[n]():g[n]);(d?this.style[n]=a:this.setAttribute(n,a))}}else{h.apply($(this),[b,c,d])}})}}($.fn.attr);$.fn.removeAttr=function(b){return function(a){return this.each(function(){if(isSVGElem(this)){(this[a]&&this[a].baseVal?this[a].baseVal.value='':this.setAttribute(a,''))}else{b.apply($(this),[a])}})}}($.fn.removeAttr);function anySVG(a){for(var i=0;i<a.length;i++){if(a[i].nodeType==1&&a[i].namespaceURI==$.svg.svgNS){return true}}return false}$.expr.relative['+']=function(d){return function(a,b,c){d(a,b,c||anySVG(a))}}($.expr.relative['+']);$.expr.relative['>']=function(d){return function(a,b,c){d(a,b,c||anySVG(a))}}($.expr.relative['>']);$.expr.relative['']=function(d){return function(a,b,c){d(a,b,c||anySVG(a))}}($.expr.relative['']);$.expr.relative['~']=function(d){return function(a,b,c){d(a,b,c||anySVG(a))}}($.expr.relative['~']);$.expr.find.ID=function(d){return function(a,b,c){return(isSVGElem(b)?[b.ownerDocument.getElementById(a[1])]:d(a,b,c))}}($.expr.find.ID);var j=document.createElement('div');j.appendChild(document.createComment(''));if(j.getElementsByTagName('*').length>0){$.expr.find.TAG=function(a,b){var c=b.getElementsByTagName(a[1]);if(a[1]==='*'){var d=[];for(var i=0;c[i]||c.item(i);i++){if((c[i]||c.item(i)).nodeType===1){d.push(c[i]||c.item(i))}}c=d}return c}}$.expr.preFilter.CLASS=function(a,b,c,d,f,g){a=' '+a[1].replace(/\\/g,'')+' ';if(g){return a}for(var i=0,elem={};elem!=null;i++){elem=b[i];if(!elem){try{elem=b.item(i)}catch(e){}}if(elem){var h=(!isSVGElem(elem)?elem.className:(elem.className?elem.className.baseVal:'')||elem.getAttribute('class'));if(f^(h&&(' '+h+' ').indexOf(a)>-1)){if(!c)d.push(elem)}else if(c){b[i]=false}}}return false};$.expr.filter.CLASS=function(a,b){var c=(!isSVGElem(a)?a.className:(a.className?a.className.baseVal:a.getAttribute('class')));return(' '+c+' ').indexOf(b)>-1};$.expr.filter.ATTR=function(g){return function(c,d){var e=null;if(isSVGElem(c)){e=d[1];$.expr.attrHandle[e]=function(a){var b=a.getAttribute(e);return b&&b.baseVal||b}}var f=g(c,d);if(e){$.expr.attrHandle[e]=null}return f}}($.expr.filter.ATTR);function isSVGElem(a){return(a.nodeType==1&&a.namespaceURI==$.svg.svgNS)}})(jQuery);
\ No newline at end of file

Property changes on: TXM/trunk/org.txm.conllu.core/template/lib/ext/jquery.svgdom.min.js
___________________________________________________________________
Added: svn:mime-type
   + text/plain

Index: TXM/trunk/org.txm.conllu.core/template/lib/ext/waypoints.min.js
===================================================================
--- TXM/trunk/org.txm.conllu.core/template/lib/ext/waypoints.min.js	(revision 0)
+++ TXM/trunk/org.txm.conllu.core/template/lib/ext/waypoints.min.js	(revision 3567)
@@ -0,0 +1,8 @@
+// Generated by CoffeeScript 1.6.2
+/*!
+jQuery Waypoints - v2.0.5
+Copyright (c) 2011-2014 Caleb Troughton
+Licensed under the MIT license.
+https://github.com/imakewebthings/jquery-waypoints/blob/master/licenses.txt
+*/
+(function(){var t=[].indexOf||function(t){for(var e=0,n=this.length;e<n;e++){if(e in this&&this[e]===t)return e}return-1},e=[].slice;(function(t,e){if(typeof define==="function"&&define.amd){return define("waypoints",["jquery"],function(n){return e(n,t)})}else{return e(t.jQuery,t)}})(window,function(n,r){var i,o,l,s,f,u,c,a,h,d,p,y,v,w,g,m;i=n(r);a=t.call(r,"ontouchstart")>=0;s={horizontal:{},vertical:{}};f=1;c={};u="waypoints-context-id";p="resize.waypoints";y="scroll.waypoints";v=1;w="waypoints-waypoint-ids";g="waypoint";m="waypoints";o=function(){function t(t){var e=this;this.$element=t;this.element=t[0];this.didResize=false;this.didScroll=false;this.id="context"+f++;this.oldScroll={x:t.scrollLeft(),y:t.scrollTop()};this.waypoints={horizontal:{},vertical:{}};this.element[u]=this.id;c[this.id]=this;t.bind(y,function(){var t;if(!(e.didScroll||a)){e.didScroll=true;t=function(){e.doScroll();return e.didScroll=false};return r.setTimeout(t,n[m].settings.scrollThrottle)}});t.bind(p,function(){var t;if(!e.didResize){e.didResize=true;t=function(){n[m]("refresh");return e.didResize=false};return r.setTimeout(t,n[m].settings.resizeThrottle)}})}t.prototype.doScroll=function(){var t,e=this;t={horizontal:{newScroll:this.$element.scrollLeft(),oldScroll:this.oldScroll.x,forward:"right",backward:"left"},vertical:{newScroll:this.$element.scrollTop(),oldScroll:this.oldScroll.y,forward:"down",backward:"up"}};if(a&&(!t.vertical.oldScroll||!t.vertical.newScroll)){n[m]("refresh")}n.each(t,function(t,r){var i,o,l;l=[];o=r.newScroll>r.oldScroll;i=o?r.forward:r.backward;n.each(e.waypoints[t],function(t,e){var n,i;if(r.oldScroll<(n=e.offset)&&n<=r.newScroll){return l.push(e)}else if(r.newScroll<(i=e.offset)&&i<=r.oldScroll){return l.push(e)}});l.sort(function(t,e){return t.offset-e.offset});if(!o){l.reverse()}return n.each(l,function(t,e){if(e.options.continuous||t===l.length-1){return e.trigger([i])}})});return this.oldScroll={x:t.horizontal.newScroll,y:t.vertical.newScroll}};t.prototype.refresh=function(){var t,e,r,i=this;r=n.isWindow(this.element);e=this.$element.offset();this.doScroll();t={horizontal:{contextOffset:r?0:e.left,contextScroll:r?0:this.oldScroll.x,contextDimension:this.$element.width(),oldScroll:this.oldScroll.x,forward:"right",backward:"left",offsetProp:"left"},vertical:{contextOffset:r?0:e.top,contextScroll:r?0:this.oldScroll.y,contextDimension:r?n[m]("viewportHeight"):this.$element.height(),oldScroll:this.oldScroll.y,forward:"down",backward:"up",offsetProp:"top"}};return n.each(t,function(t,e){return n.each(i.waypoints[t],function(t,r){var i,o,l,s,f;i=r.options.offset;l=r.offset;o=n.isWindow(r.element)?0:r.$element.offset()[e.offsetProp];if(n.isFunction(i)){i=i.apply(r.element)}else if(typeof i==="string"){i=parseFloat(i);if(r.options.offset.indexOf("%")>-1){i=Math.ceil(e.contextDimension*i/100)}}r.offset=o-e.contextOffset+e.contextScroll-i;if(r.options.onlyOnScroll&&l!=null||!r.enabled){return}if(l!==null&&l<(s=e.oldScroll)&&s<=r.offset){return r.trigger([e.backward])}else if(l!==null&&l>(f=e.oldScroll)&&f>=r.offset){return r.trigger([e.forward])}else if(l===null&&e.oldScroll>=r.offset){return r.trigger([e.forward])}})})};t.prototype.checkEmpty=function(){if(n.isEmptyObject(this.waypoints.horizontal)&&n.isEmptyObject(this.waypoints.vertical)){this.$element.unbind([p,y].join(" "));return delete c[this.id]}};return t}();l=function(){function t(t,e,r){var i,o;if(r.offset==="bottom-in-view"){r.offset=function(){var t;t=n[m]("viewportHeight");if(!n.isWindow(e.element)){t=e.$element.height()}return t-n(this).outerHeight()}}this.$element=t;this.element=t[0];this.axis=r.horizontal?"horizontal":"vertical";this.callback=r.handler;this.context=e;this.enabled=r.enabled;this.id="waypoints"+v++;this.offset=null;this.options=r;e.waypoints[this.axis][this.id]=this;s[this.axis][this.id]=this;i=(o=this.element[w])!=null?o:[];i.push(this.id);this.element[w]=i}t.prototype.trigger=function(t){if(!this.enabled){return}if(this.callback!=null){this.callback.apply(this.element,t)}if(this.options.triggerOnce){return this.destroy()}};t.prototype.disable=function(){return this.enabled=false};t.prototype.enable=function(){this.context.refresh();return this.enabled=true};t.prototype.destroy=function(){delete s[this.axis][this.id];delete this.context.waypoints[this.axis][this.id];return this.context.checkEmpty()};t.getWaypointsByElement=function(t){var e,r;r=t[w];if(!r){return[]}e=n.extend({},s.horizontal,s.vertical);return n.map(r,function(t){return e[t]})};return t}();d={init:function(t,e){var r;e=n.extend({},n.fn[g].defaults,e);if((r=e.handler)==null){e.handler=t}this.each(function(){var t,r,i,s;t=n(this);i=(s=e.context)!=null?s:n.fn[g].defaults.context;if(!n.isWindow(i)){i=t.closest(i)}i=n(i);r=c[i[0][u]];if(!r){r=new o(i)}return new l(t,r,e)});n[m]("refresh");return this},disable:function(){return d._invoke.call(this,"disable")},enable:function(){return d._invoke.call(this,"enable")},destroy:function(){return d._invoke.call(this,"destroy")},prev:function(t,e){return d._traverse.call(this,t,e,function(t,e,n){if(e>0){return t.push(n[e-1])}})},next:function(t,e){return d._traverse.call(this,t,e,function(t,e,n){if(e<n.length-1){return t.push(n[e+1])}})},_traverse:function(t,e,i){var o,l;if(t==null){t="vertical"}if(e==null){e=r}l=h.aggregate(e);o=[];this.each(function(){var e;e=n.inArray(this,l[t]);return i(o,e,l[t])});return this.pushStack(o)},_invoke:function(t){this.each(function(){var e;e=l.getWaypointsByElement(this);return n.each(e,function(e,n){n[t]();return true})});return this}};n.fn[g]=function(){var t,r;r=arguments[0],t=2<=arguments.length?e.call(arguments,1):[];if(d[r]){return d[r].apply(this,t)}else if(n.isFunction(r)){return d.init.apply(this,arguments)}else if(n.isPlainObject(r)){return d.init.apply(this,[null,r])}else if(!r){return n.error("jQuery Waypoints needs a callback function or handler option.")}else{return n.error("The "+r+" method does not exist in jQuery Waypoints.")}};n.fn[g].defaults={context:r,continuous:true,enabled:true,horizontal:false,offset:0,triggerOnce:false};h={refresh:function(){return n.each(c,function(t,e){return e.refresh()})},viewportHeight:function(){var t;return(t=r.innerHeight)!=null?t:i.height()},aggregate:function(t){var e,r,i;e=s;if(t){e=(i=c[n(t)[0][u]])!=null?i.waypoints:void 0}if(!e){return[]}r={horizontal:[],vertical:[]};n.each(r,function(t,i){n.each(e[t],function(t,e){return i.push(e)});i.sort(function(t,e){return t.offset-e.offset});r[t]=n.map(i,function(t){return t.element});return r[t]=n.unique(r[t])});return r},above:function(t){if(t==null){t=r}return h._filter(t,"vertical",function(t,e){return e.offset<=t.oldScroll.y})},below:function(t){if(t==null){t=r}return h._filter(t,"vertical",function(t,e){return e.offset>t.oldScroll.y})},left:function(t){if(t==null){t=r}return h._filter(t,"horizontal",function(t,e){return e.offset<=t.oldScroll.x})},right:function(t){if(t==null){t=r}return h._filter(t,"horizontal",function(t,e){return e.offset>t.oldScroll.x})},enable:function(){return h._invoke("enable")},disable:function(){return h._invoke("disable")},destroy:function(){return h._invoke("destroy")},extendFn:function(t,e){return d[t]=e},_invoke:function(t){var e;e=n.extend({},s.vertical,s.horizontal);return n.each(e,function(e,n){n[t]();return true})},_filter:function(t,e,r){var i,o;i=c[n(t)[0][u]];if(!i){return[]}o=[];n.each(i.waypoints[e],function(t,e){if(r(i,e)){return o.push(e)}});o.sort(function(t,e){return t.offset-e.offset});return n.map(o,function(t){return t.element})}};n[m]=function(){var t,n;n=arguments[0],t=2<=arguments.length?e.call(arguments,1):[];if(h[n]){return h[n].apply(null,t)}else{return h.aggregate.call(null,n)}};n[m].settings={resizeThrottle:100,scrollThrottle:30};return i.on("load.waypoints",function(){return n[m]("refresh")})})}).call(this);
\ No newline at end of file

Property changes on: TXM/trunk/org.txm.conllu.core/template/lib/ext/waypoints.min.js
___________________________________________________________________
Added: svn:mime-type
   + text/plain

Index: TXM/trunk/org.txm.conllu.core/template/lib/ext/head.load.min.js
===================================================================
--- TXM/trunk/org.txm.conllu.core/template/lib/ext/head.load.min.js	(revision 0)
+++ TXM/trunk/org.txm.conllu.core/template/lib/ext/head.load.min.js	(revision 3567)
@@ -0,0 +1,8 @@
+/**
+	Head JS		The only script in your <HEAD>
+	Copyright	Tero Piirainen (tipiirai)
+	License		MIT / http://bit.ly/mit-license
+	Version		0.9
+	
+	http://headjs.com
+*/(function(a){var b=a.documentElement,c,d,e=[],f=[],g={},h={},i=a.createElement("script").async===true||"MozAppearance"in a.documentElement.style||window.opera;var j=window.head_conf&&head_conf.head||"head",k=window[j]=window[j]||function(){k.ready.apply(null,arguments)};var l=0,m=1,n=2,o=3;i?k.js=function(){var a=arguments,b=a[a.length-1],c=[];t(b)||(b=null),s(a,function(d,e){d!=b&&(d=r(d),c.push(d),x(d,b&&e==a.length-2?function(){u(c)&&p(b)}:null))});return k}:k.js=function(){var a=arguments,b=[].slice.call(a,1),d=b[0];if(!c){f.push(function(){k.js.apply(null,a)});return k}d?(s(b,function(a){t(a)||w(r(a))}),x(r(a[0]),t(d)?d:function(){k.js.apply(null,b)})):x(r(a[0]));return k},k.ready=function(a,b){if(a=="dom"){d?p(b):e.push(b);return k}t(a)&&(b=a,a="ALL");var c=h[a];if(c&&c.state==o||a=="ALL"&&u()&&d){p(b);return k}var f=g[a];f?f.push(b):f=g[a]=[b];return k},k.ready("dom",function(){c&&u()&&s(g.ALL,function(a){p(a)}),k.feature&&k.feature("domloaded",true)});function p(a){a._done||(a(),a._done=1)}function q(a){var b=a.split("/"),c=b[b.length-1],d=c.indexOf("?");return d!=-1?c.substring(0,d):c}function r(a){var b;if(typeof a=="object")for(var c in a)a[c]&&(b={name:c,url:a[c]});else b={name:q(a),url:a};var d=h[b.name];if(d&&d.url===b.url)return d;h[b.name]=b;return b}function s(a,b){if(a){typeof a=="object"&&(a=[].slice.call(a));for(var c=0;c<a.length;c++)b.call(a,a[c],c)}}function t(a){return Object.prototype.toString.call(a)=="[object Function]"}function u(a){a=a||h;var b=false,c=0;for(var d in a){if(a[d].state!=o)return false;b=true,c++}return b||c===0}function v(a){a.state=l,s(a.onpreload,function(a){a.call()})}function w(a,b){a.state||(a.state=m,a.onpreload=[],y({src:a.url,type:"cache"},function(){v(a)}))}function x(a,b){if(a.state==o&&b)return b();if(a.state==n)return k.ready(a.name,b);if(a.state==m)return a.onpreload.push(function(){x(a,b)});a.state=n,y(a.url,function(){a.state=o,b&&b(),s(g[a.name],function(a){p(a)}),d&&u()&&s(g.ALL,function(a){p(a)})})}function y(c,d){var e=a.createElement("script");e.type="text/"+(c.type||"javascript"),e.src=c.src||c,e.async=false,e.onreadystatechange=e.onload=function(){var a=e.readyState;!d.done&&(!a||/loaded|complete/.test(a))&&(d(),d.done=true)},b.appendChild(e)}setTimeout(function(){c=true,s(f,function(a){a()})},0);function z(){d||(d=true,s(e,function(a){p(a)}))}window.addEventListener?(a.addEventListener("DOMContentLoaded",z,false),window.addEventListener("onload",z,false)):window.attachEvent&&(a.attachEvent("onreadystatechange",function(){a.readyState==="complete"&&z()}),window.frameElement==null&&b.doScroll&&function(){try{b.doScroll("left"),z()}catch(a){setTimeout(arguments.callee,1);return}}(),window.attachEvent("onload",z)),!a.readyState&&a.addEventListener&&(a.readyState="loading",a.addEventListener("DOMContentLoaded",handler=function(){a.removeEventListener("DOMContentLoaded",handler,false),a.readyState="complete"},false))})(document)
\ No newline at end of file

Property changes on: TXM/trunk/org.txm.conllu.core/template/lib/ext/head.load.min.js
___________________________________________________________________
Added: svn:mime-type
   + text/plain

Index: TXM/trunk/org.txm.conllu.core/template/lib/ext/jquery.min.js
===================================================================
--- TXM/trunk/org.txm.conllu.core/template/lib/ext/jquery.min.js	(revision 0)
+++ TXM/trunk/org.txm.conllu.core/template/lib/ext/jquery.min.js	(revision 3567)
@@ -0,0 +1,4 @@
+/*! jQuery v1.7.1 jquery.com | jquery.org/license */
+(function(a,b){function cy(a){return f.isWindow(a)?a:a.nodeType===9?a.defaultView||a.parentWindow:!1}function cv(a){if(!ck[a]){var b=c.body,d=f("<"+a+">").appendTo(b),e=d.css("display");d.remove();if(e==="none"||e===""){cl||(cl=c.createElement("iframe"),cl.frameBorder=cl.width=cl.height=0),b.appendChild(cl);if(!cm||!cl.createElement)cm=(cl.contentWindow||cl.contentDocument).document,cm.write((c.compatMode==="CSS1Compat"?"<!doctype html>":"")+"<html><body>"),cm.close();d=cm.createElement(a),cm.body.appendChild(d),e=f.css(d,"display"),b.removeChild(cl)}ck[a]=e}return ck[a]}function cu(a,b){var c={};f.each(cq.concat.apply([],cq.slice(0,b)),function(){c[this]=a});return c}function ct(){cr=b}function cs(){setTimeout(ct,0);return cr=f.now()}function cj(){try{return new a.ActiveXObject("Microsoft.XMLHTTP")}catch(b){}}function ci(){try{return new a.XMLHttpRequest}catch(b){}}function cc(a,c){a.dataFilter&&(c=a.dataFilter(c,a.dataType));var d=a.dataTypes,e={},g,h,i=d.length,j,k=d[0],l,m,n,o,p;for(g=1;g<i;g++){if(g===1)for(h in a.converters)typeof h=="string"&&(e[h.toLowerCase()]=a.converters[h]);l=k,k=d[g];if(k==="*")k=l;else if(l!=="*"&&l!==k){m=l+" "+k,n=e[m]||e["* "+k];if(!n){p=b;for(o in e){j=o.split(" ");if(j[0]===l||j[0]==="*"){p=e[j[1]+" "+k];if(p){o=e[o],o===!0?n=p:p===!0&&(n=o);break}}}}!n&&!p&&f.error("No conversion from "+m.replace(" "," to ")),n!==!0&&(c=n?n(c):p(o(c)))}}return c}function cb(a,c,d){var e=a.contents,f=a.dataTypes,g=a.responseFields,h,i,j,k;for(i in g)i in d&&(c[g[i]]=d[i]);while(f[0]==="*")f.shift(),h===b&&(h=a.mimeType||c.getResponseHeader("content-type"));if(h)for(i in e)if(e[i]&&e[i].test(h)){f.unshift(i);break}if(f[0]in d)j=f[0];else{for(i in d){if(!f[0]||a.converters[i+" "+f[0]]){j=i;break}k||(k=i)}j=j||k}if(j){j!==f[0]&&f.unshift(j);return d[j]}}function ca(a,b,c,d){if(f.isArray(b))f.each(b,function(b,e){c||bE.test(a)?d(a,e):ca(a+"["+(typeof e=="object"||f.isArray(e)?b:"")+"]",e,c,d)});else if(!c&&b!=null&&typeof b=="object")for(var e in b)ca(a+"["+e+"]",b[e],c,d);else d(a,b)}function b_(a,c){var d,e,g=f.ajaxSettings.flatOptions||{};for(d in c)c[d]!==b&&((g[d]?a:e||(e={}))[d]=c[d]);e&&f.extend(!0,a,e)}function b$(a,c,d,e,f,g){f=f||c.dataTypes[0],g=g||{},g[f]=!0;var h=a[f],i=0,j=h?h.length:0,k=a===bT,l;for(;i<j&&(k||!l);i++)l=h[i](c,d,e),typeof l=="string"&&(!k||g[l]?l=b:(c.dataTypes.unshift(l),l=b$(a,c,d,e,l,g)));(k||!l)&&!g["*"]&&(l=b$(a,c,d,e,"*",g));return l}function bZ(a){return function(b,c){typeof b!="string"&&(c=b,b="*");if(f.isFunction(c)){var d=b.toLowerCase().split(bP),e=0,g=d.length,h,i,j;for(;e<g;e++)h=d[e],j=/^\+/.test(h),j&&(h=h.substr(1)||"*"),i=a[h]=a[h]||[],i[j?"unshift":"push"](c)}}}function bC(a,b,c){var d=b==="width"?a.offsetWidth:a.offsetHeight,e=b==="width"?bx:by,g=0,h=e.length;if(d>0){if(c!=="border")for(;g<h;g++)c||(d-=parseFloat(f.css(a,"padding"+e[g]))||0),c==="margin"?d+=parseFloat(f.css(a,c+e[g]))||0:d-=parseFloat(f.css(a,"border"+e[g]+"Width"))||0;return d+"px"}d=bz(a,b,b);if(d<0||d==null)d=a.style[b]||0;d=parseFloat(d)||0;if(c)for(;g<h;g++)d+=parseFloat(f.css(a,"padding"+e[g]))||0,c!=="padding"&&(d+=parseFloat(f.css(a,"border"+e[g]+"Width"))||0),c==="margin"&&(d+=parseFloat(f.css(a,c+e[g]))||0);return d+"px"}function bp(a,b){b.src?f.ajax({url:b.src,async:!1,dataType:"script"}):f.globalEval((b.text||b.textContent||b.innerHTML||"").replace(bf,"/*$0*/")),b.parentNode&&b.parentNode.removeChild(b)}function bo(a){var b=c.createElement("div");bh.appendChild(b),b.innerHTML=a.outerHTML;return b.firstChild}function bn(a){var b=(a.nodeName||"").toLowerCase();b==="input"?bm(a):b!=="script"&&typeof a.getElementsByTagName!="undefined"&&f.grep(a.getElementsByTagName("input"),bm)}function bm(a){if(a.type==="checkbox"||a.type==="radio")a.defaultChecked=a.checked}function bl(a){return typeof a.getElementsByTagName!="undefined"?a.getElementsByTagName("*"):typeof a.querySelectorAll!="undefined"?a.querySelectorAll("*"):[]}function bk(a,b){var c;if(b.nodeType===1){b.clearAttributes&&b.clearAttributes(),b.mergeAttributes&&b.mergeAttributes(a),c=b.nodeName.toLowerCase();if(c==="object")b.outerHTML=a.outerHTML;else if(c!=="input"||a.type!=="checkbox"&&a.type!=="radio"){if(c==="option")b.selected=a.defaultSelected;else if(c==="input"||c==="textarea")b.defaultValue=a.defaultValue}else a.checked&&(b.defaultChecked=b.checked=a.checked),b.value!==a.value&&(b.value=a.value);b.removeAttribute(f.expando)}}function bj(a,b){if(b.nodeType===1&&!!f.hasData(a)){var c,d,e,g=f._data(a),h=f._data(b,g),i=g.events;if(i){delete h.handle,h.events={};for(c in i)for(d=0,e=i[c].length;d<e;d++)f.event.add(b,c+(i[c][d].namespace?".":"")+i[c][d].namespace,i[c][d],i[c][d].data)}h.data&&(h.data=f.extend({},h.data))}}function bi(a,b){return f.nodeName(a,"table")?a.getElementsByTagName("tbody")[0]||a.appendChild(a.ownerDocument.createElement("tbody")):a}function U(a){var b=V.split("|"),c=a.createDocumentFragment();if(c.createElement)while(b.length)c.createElement(b.pop());return c}function T(a,b,c){b=b||0;if(f.isFunction(b))return f.grep(a,function(a,d){var e=!!b.call(a,d,a);return e===c});if(b.nodeType)return f.grep(a,function(a,d){return a===b===c});if(typeof b=="string"){var d=f.grep(a,function(a){return a.nodeType===1});if(O.test(b))return f.filter(b,d,!c);b=f.filter(b,d)}return f.grep(a,function(a,d){return f.inArray(a,b)>=0===c})}function S(a){return!a||!a.parentNode||a.parentNode.nodeType===11}function K(){return!0}function J(){return!1}function n(a,b,c){var d=b+"defer",e=b+"queue",g=b+"mark",h=f._data(a,d);h&&(c==="queue"||!f._data(a,e))&&(c==="mark"||!f._data(a,g))&&setTimeout(function(){!f._data(a,e)&&!f._data(a,g)&&(f.removeData(a,d,!0),h.fire())},0)}function m(a){for(var b in a){if(b==="data"&&f.isEmptyObject(a[b]))continue;if(b!=="toJSON")return!1}return!0}function l(a,c,d){if(d===b&&a.nodeType===1){var e="data-"+c.replace(k,"-$1").toLowerCase();d=a.getAttribute(e);if(typeof d=="string"){try{d=d==="true"?!0:d==="false"?!1:d==="null"?null:f.isNumeric(d)?parseFloat(d):j.test(d)?f.parseJSON(d):d}catch(g){}f.data(a,c,d)}else d=b}return d}function h(a){var b=g[a]={},c,d;a=a.split(/\s+/);for(c=0,d=a.length;c<d;c++)b[a[c]]=!0;return b}var c=a.document,d=a.navigator,e=a.location,f=function(){function J(){if(!e.isReady){try{c.documentElement.doScroll("left")}catch(a){setTimeout(J,1);return}e.ready()}}var e=function(a,b){return new e.fn.init(a,b,h)},f=a.jQuery,g=a.$,h,i=/^(?:[^#<]*(<[\w\W]+>)[^>]*$|#([\w\-]*)$)/,j=/\S/,k=/^\s+/,l=/\s+$/,m=/^<(\w+)\s*\/?>(?:<\/\1>)?$/,n=/^[\],:{}\s]*$/,o=/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g,p=/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g,q=/(?:^|:|,)(?:\s*\[)+/g,r=/(webkit)[ \/]([\w.]+)/,s=/(opera)(?:.*version)?[ \/]([\w.]+)/,t=/(msie) ([\w.]+)/,u=/(mozilla)(?:.*? rv:([\w.]+))?/,v=/-([a-z]|[0-9])/ig,w=/^-ms-/,x=function(a,b){return(b+"").toUpperCase()},y=d.userAgent,z,A,B,C=Object.prototype.toString,D=Object.prototype.hasOwnProperty,E=Array.prototype.push,F=Array.prototype.slice,G=String.prototype.trim,H=Array.prototype.indexOf,I={};e.fn=e.prototype={constructor:e,init:function(a,d,f){var g,h,j,k;if(!a)return this;if(a.nodeType){this.context=this[0]=a,this.length=1;return this}if(a==="body"&&!d&&c.body){this.context=c,this[0]=c.body,this.selector=a,this.length=1;return this}if(typeof a=="string"){a.charAt(0)!=="<"||a.charAt(a.length-1)!==">"||a.length<3?g=i.exec(a):g=[null,a,null];if(g&&(g[1]||!d)){if(g[1]){d=d instanceof e?d[0]:d,k=d?d.ownerDocument||d:c,j=m.exec(a),j?e.isPlainObject(d)?(a=[c.createElement(j[1])],e.fn.attr.call(a,d,!0)):a=[k.createElement(j[1])]:(j=e.buildFragment([g[1]],[k]),a=(j.cacheable?e.clone(j.fragment):j.fragment).childNodes);return e.merge(this,a)}h=c.getElementById(g[2]);if(h&&h.parentNode){if(h.id!==g[2])return f.find(a);this.length=1,this[0]=h}this.context=c,this.selector=a;return this}return!d||d.jquery?(d||f).find(a):this.constructor(d).find(a)}if(e.isFunction(a))return f.ready(a);a.selector!==b&&(this.selector=a.selector,this.context=a.context);return e.makeArray(a,this)},selector:"",jquery:"1.7.1",length:0,size:function(){return this.length},toArray:function(){return F.call(this,0)},get:function(a){return a==null?this.toArray():a<0?this[this.length+a]:this[a]},pushStack:function(a,b,c){var d=this.constructor();e.isArray(a)?E.apply(d,a):e.merge(d,a),d.prevObject=this,d.context=this.context,b==="find"?d.selector=this.selector+(this.selector?" ":"")+c:b&&(d.selector=this.selector+"."+b+"("+c+")");return d},each:function(a,b){return e.each(this,a,b)},ready:function(a){e.bindReady(),A.add(a);return this},eq:function(a){a=+a;return a===-1?this.slice(a):this.slice(a,a+1)},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},slice:function(){return this.pushStack(F.apply(this,arguments),"slice",F.call(arguments).join(","))},map:function(a){return this.pushStack(e.map(this,function(b,c){return a.call(b,c,b)}))},end:function(){return this.prevObject||this.constructor(null)},push:E,sort:[].sort,splice:[].splice},e.fn.init.prototype=e.fn,e.extend=e.fn.extend=function(){var a,c,d,f,g,h,i=arguments[0]||{},j=1,k=arguments.length,l=!1;typeof i=="boolean"&&(l=i,i=arguments[1]||{},j=2),typeof i!="object"&&!e.isFunction(i)&&(i={}),k===j&&(i=this,--j);for(;j<k;j++)if((a=arguments[j])!=null)for(c in a){d=i[c],f=a[c];if(i===f)continue;l&&f&&(e.isPlainObject(f)||(g=e.isArray(f)))?(g?(g=!1,h=d&&e.isArray(d)?d:[]):h=d&&e.isPlainObject(d)?d:{},i[c]=e.extend(l,h,f)):f!==b&&(i[c]=f)}return i},e.extend({noConflict:function(b){a.$===e&&(a.$=g),b&&a.jQuery===e&&(a.jQuery=f);return e},isReady:!1,readyWait:1,holdReady:function(a){a?e.readyWait++:e.ready(!0)},ready:function(a){if(a===!0&&!--e.readyWait||a!==!0&&!e.isReady){if(!c.body)return setTimeout(e.ready,1);e.isReady=!0;if(a!==!0&&--e.readyWait>0)return;A.fireWith(c,[e]),e.fn.trigger&&e(c).trigger("ready").off("ready")}},bindReady:function(){if(!A){A=e.Callbacks("once memory");if(c.readyState==="complete")return setTimeout(e.ready,1);if(c.addEventListener)c.addEventListener("DOMContentLoaded",B,!1),a.addEventListener("load",e.ready,!1);else if(c.attachEvent){c.attachEvent("onreadystatechange",B),a.attachEvent("onload",e.ready);var b=!1;try{b=a.frameElement==null}catch(d){}c.documentElement.doScroll&&b&&J()}}},isFunction:function(a){return e.type(a)==="function"},isArray:Array.isArray||function(a){return e.type(a)==="array"},isWindow:function(a){return a&&typeof a=="object"&&"setInterval"in a},isNumeric:function(a){return!isNaN(parseFloat(a))&&isFinite(a)},type:function(a){return a==null?String(a):I[C.call(a)]||"object"},isPlainObject:function(a){if(!a||e.type(a)!=="object"||a.nodeType||e.isWindow(a))return!1;try{if(a.constructor&&!D.call(a,"constructor")&&!D.call(a.constructor.prototype,"isPrototypeOf"))return!1}catch(c){return!1}var d;for(d in a);return d===b||D.call(a,d)},isEmptyObject:function(a){for(var b in a)return!1;return!0},error:function(a){throw new Error(a)},parseJSON:function(b){if(typeof b!="string"||!b)return null;b=e.trim(b);if(a.JSON&&a.JSON.parse)return a.JSON.parse(b);if(n.test(b.replace(o,"@").replace(p,"]").replace(q,"")))return(new Function("return "+b))();e.error("Invalid JSON: "+b)},parseXML:function(c){var d,f;try{a.DOMParser?(f=new DOMParser,d=f.parseFromString(c,"text/xml")):(d=new ActiveXObject("Microsoft.XMLDOM"),d.async="false",d.loadXML(c))}catch(g){d=b}(!d||!d.documentElement||d.getElementsByTagName("parsererror").length)&&e.error("Invalid XML: "+c);return d},noop:function(){},globalEval:function(b){b&&j.test(b)&&(a.execScript||function(b){a.eval.call(a,b)})(b)},camelCase:function(a){return a.replace(w,"ms-").replace(v,x)},nodeName:function(a,b){return a.nodeName&&a.nodeName.toUpperCase()===b.toUpperCase()},each:function(a,c,d){var f,g=0,h=a.length,i=h===b||e.isFunction(a);if(d){if(i){for(f in a)if(c.apply(a[f],d)===!1)break}else for(;g<h;)if(c.apply(a[g++],d)===!1)break}else if(i){for(f in a)if(c.call(a[f],f,a[f])===!1)break}else for(;g<h;)if(c.call(a[g],g,a[g++])===!1)break;return a},trim:G?function(a){return a==null?"":G.call(a)}:function(a){return a==null?"":(a+"").replace(k,"").replace(l,"")},makeArray:function(a,b){var c=b||[];if(a!=null){var d=e.type(a);a.length==null||d==="string"||d==="function"||d==="regexp"||e.isWindow(a)?E.call(c,a):e.merge(c,a)}return c},inArray:function(a,b,c){var d;if(b){if(H)return H.call(b,a,c);d=b.length,c=c?c<0?Math.max(0,d+c):c:0;for(;c<d;c++)if(c in b&&b[c]===a)return c}return-1},merge:function(a,c){var d=a.length,e=0;if(typeof c.length=="number")for(var f=c.length;e<f;e++)a[d++]=c[e];else while(c[e]!==b)a[d++]=c[e++];a.length=d;return a},grep:function(a,b,c){var d=[],e;c=!!c;for(var f=0,g=a.length;f<g;f++)e=!!b(a[f],f),c!==e&&d.push(a[f]);return d},map:function(a,c,d){var f,g,h=[],i=0,j=a.length,k=a instanceof e||j!==b&&typeof j=="number"&&(j>0&&a[0]&&a[j-1]||j===0||e.isArray(a));if(k)for(;i<j;i++)f=c(a[i],i,d),f!=null&&(h[h.length]=f);else for(g in a)f=c(a[g],g,d),f!=null&&(h[h.length]=f);return h.concat.apply([],h)},guid:1,proxy:function(a,c){if(typeof c=="string"){var d=a[c];c=a,a=d}if(!e.isFunction(a))return b;var f=F.call(arguments,2),g=function(){return a.apply(c,f.concat(F.call(arguments)))};g.guid=a.guid=a.guid||g.guid||e.guid++;return g},access:function(a,c,d,f,g,h){var i=a.length;if(typeof c=="object"){for(var j in c)e.access(a,j,c[j],f,g,d);return a}if(d!==b){f=!h&&f&&e.isFunction(d);for(var k=0;k<i;k++)g(a[k],c,f?d.call(a[k],k,g(a[k],c)):d,h);return a}return i?g(a[0],c):b},now:function(){return(new Date).getTime()},uaMatch:function(a){a=a.toLowerCase();var b=r.exec(a)||s.exec(a)||t.exec(a)||a.indexOf("compatible")<0&&u.exec(a)||[];return{browser:b[1]||"",version:b[2]||"0"}},sub:function(){function a(b,c){return new a.fn.init(b,c)}e.extend(!0,a,this),a.superclass=this,a.fn=a.prototype=this(),a.fn.constructor=a,a.sub=this.sub,a.fn.init=function(d,f){f&&f instanceof e&&!(f instanceof a)&&(f=a(f));return e.fn.init.call(this,d,f,b)},a.fn.init.prototype=a.fn;var b=a(c);return a},browser:{}}),e.each("Boolean Number String Function Array Date RegExp Object".split(" "),function(a,b){I["[object "+b+"]"]=b.toLowerCase()}),z=e.uaMatch(y),z.browser&&(e.browser[z.browser]=!0,e.browser.version=z.version),e.browser.webkit&&(e.browser.safari=!0),j.test(" ")&&(k=/^[\s\xA0]+/,l=/[\s\xA0]+$/),h=e(c),c.addEventListener?B=function(){c.removeEventListener("DOMContentLoaded",B,!1),e.ready()}:c.attachEvent&&(B=function(){c.readyState==="complete"&&(c.detachEvent("onreadystatechange",B),e.ready())});return e}(),g={};f.Callbacks=function(a){a=a?g[a]||h(a):{};var c=[],d=[],e,i,j,k,l,m=function(b){var d,e,g,h,i;for(d=0,e=b.length;d<e;d++)g=b[d],h=f.type(g),h==="array"?m(g):h==="function"&&(!a.unique||!o.has(g))&&c.push(g)},n=function(b,f){f=f||[],e=!a.memory||[b,f],i=!0,l=j||0,j=0,k=c.length;for(;c&&l<k;l++)if(c[l].apply(b,f)===!1&&a.stopOnFalse){e=!0;break}i=!1,c&&(a.once?e===!0?o.disable():c=[]:d&&d.length&&(e=d.shift(),o.fireWith(e[0],e[1])))},o={add:function(){if(c){var a=c.length;m(arguments),i?k=c.length:e&&e!==!0&&(j=a,n(e[0],e[1]))}return this},remove:function(){if(c){var b=arguments,d=0,e=b.length;for(;d<e;d++)for(var f=0;f<c.length;f++)if(b[d]===c[f]){i&&f<=k&&(k--,f<=l&&l--),c.splice(f--,1);if(a.unique)break}}return this},has:function(a){if(c){var b=0,d=c.length;for(;b<d;b++)if(a===c[b])return!0}return!1},empty:function(){c=[];return this},disable:function(){c=d=e=b;return this},disabled:function(){return!c},lock:function(){d=b,(!e||e===!0)&&o.disable();return this},locked:function(){return!d},fireWith:function(b,c){d&&(i?a.once||d.push([b,c]):(!a.once||!e)&&n(b,c));return this},fire:function(){o.fireWith(this,arguments);return this},fired:function(){return!!e}};return o};var i=[].slice;f.extend({Deferred:function(a){var b=f.Callbacks("once memory"),c=f.Callbacks("once memory"),d=f.Callbacks("memory"),e="pending",g={resolve:b,reject:c,notify:d},h={done:b.add,fail:c.add,progress:d.add,state:function(){return e},isResolved:b.fired,isRejected:c.fired,then:function(a,b,c){i.done(a).fail(b).progress(c);return this},always:function(){i.done.apply(i,arguments).fail.apply(i,arguments);return this},pipe:function(a,b,c){return f.Deferred(function(d){f.each({done:[a,"resolve"],fail:[b,"reject"],progress:[c,"notify"]},function(a,b){var c=b[0],e=b[1],g;f.isFunction(c)?i[a](function(){g=c.apply(this,arguments),g&&f.isFunction(g.promise)?g.promise().then(d.resolve,d.reject,d.notify):d[e+"With"](this===i?d:this,[g])}):i[a](d[e])})}).promise()},promise:function(a){if(a==null)a=h;else for(var b in h)a[b]=h[b];return a}},i=h.promise({}),j;for(j in g)i[j]=g[j].fire,i[j+"With"]=g[j].fireWith;i.done(function(){e="resolved"},c.disable,d.lock).fail(function(){e="rejected"},b.disable,d.lock),a&&a.call(i,i);return i},when:function(a){function m(a){return function(b){e[a]=arguments.length>1?i.call(arguments,0):b,j.notifyWith(k,e)}}function l(a){return function(c){b[a]=arguments.length>1?i.call(arguments,0):c,--g||j.resolveWith(j,b)}}var b=i.call(arguments,0),c=0,d=b.length,e=Array(d),g=d,h=d,j=d<=1&&a&&f.isFunction(a.promise)?a:f.Deferred(),k=j.promise();if(d>1){for(;c<d;c++)b[c]&&b[c].promise&&f.isFunction(b[c].promise)?b[c].promise().then(l(c),j.reject,m(c)):--g;g||j.resolveWith(j,b)}else j!==a&&j.resolveWith(j,d?[a]:[]);return k}}),f.support=function(){var b,d,e,g,h,i,j,k,l,m,n,o,p,q=c.createElement("div"),r=c.documentElement;q.setAttribute("className","t"),q.innerHTML="   <link/><table></table><a href='/a' style='top:1px;float:left;opacity:.55;'>a</a><input type='checkbox'/>",d=q.getElementsByTagName("*"),e=q.getElementsByTagName("a")[0];if(!d||!d.length||!e)return{};g=c.createElement("select"),h=g.appendChild(c.createElement("option")),i=q.getElementsByTagName("input")[0],b={leadingWhitespace:q.firstChild.nodeType===3,tbody:!q.getElementsByTagName("tbody").length,htmlSerialize:!!q.getElementsByTagName("link").length,style:/top/.test(e.getAttribute("style")),hrefNormalized:e.getAttribute("href")==="/a",opacity:/^0.55/.test(e.style.opacity),cssFloat:!!e.style.cssFloat,checkOn:i.value==="on",optSelected:h.selected,getSetAttribute:q.className!=="t",enctype:!!c.createElement("form").enctype,html5Clone:c.createElement("nav").cloneNode(!0).outerHTML!=="<:nav></:nav>",submitBubbles:!0,changeBubbles:!0,focusinBubbles:!1,deleteExpando:!0,noCloneEvent:!0,inlineBlockNeedsLayout:!1,shrinkWrapBlocks:!1,reliableMarginRight:!0},i.checked=!0,b.noCloneChecked=i.cloneNode(!0).checked,g.disabled=!0,b.optDisabled=!h.disabled;try{delete q.test}catch(s){b.deleteExpando=!1}!q.addEventListener&&q.attachEvent&&q.fireEvent&&(q.attachEvent("onclick",function(){b.noCloneEvent=!1}),q.cloneNode(!0).fireEvent("onclick")),i=c.createElement("input"),i.value="t",i.setAttribute("type","radio"),b.radioValue=i.value==="t",i.setAttribute("checked","checked"),q.appendChild(i),k=c.createDocumentFragment(),k.appendChild(q.lastChild),b.checkClone=k.cloneNode(!0).cloneNode(!0).lastChild.checked,b.appendChecked=i.checked,k.removeChild(i),k.appendChild(q),q.innerHTML="",a.getComputedStyle&&(j=c.createElement("div"),j.style.width="0",j.style.marginRight="0",q.style.width="2px",q.appendChild(j),b.reliableMarginRight=(parseInt((a.getComputedStyle(j,null)||{marginRight:0}).marginRight,10)||0)===0);if(q.attachEvent)for(o in{submit:1,change:1,focusin:1})n="on"+o,p=n in q,p||(q.setAttribute(n,"return;"),p=typeof q[n]=="function"),b[o+"Bubbles"]=p;k.removeChild(q),k=g=h=j=q=i=null,f(function(){var a,d,e,g,h,i,j,k,m,n,o,r=c.getElementsByTagName("body")[0];!r||(j=1,k="position:absolute;top:0;left:0;width:1px;height:1px;margin:0;",m="visibility:hidden;border:0;",n="style='"+k+"border:5px solid #000;padding:0;'",o="<div "+n+"><div></div></div>"+"<table "+n+" cellpadding='0' cellspacing='0'>"+"<tr><td></td></tr></table>",a=c.createElement("div"),a.style.cssText=m+"width:0;height:0;position:static;top:0;margin-top:"+j+"px",r.insertBefore(a,r.firstChild),q=c.createElement("div"),a.appendChild(q),q.innerHTML="<table><tr><td style='padding:0;border:0;display:none'></td><td>t</td></tr></table>",l=q.getElementsByTagName("td"),p=l[0].offsetHeight===0,l[0].style.display="",l[1].style.display="none",b.reliableHiddenOffsets=p&&l[0].offsetHeight===0,q.innerHTML="",q.style.width=q.style.paddingLeft="1px",f.boxModel=b.boxModel=q.offsetWidth===2,typeof q.style.zoom!="undefined"&&(q.style.display="inline",q.style.zoom=1,b.inlineBlockNeedsLayout=q.offsetWidth===2,q.style.display="",q.innerHTML="<div style='width:4px;'></div>",b.shrinkWrapBlocks=q.offsetWidth!==2),q.style.cssText=k+m,q.innerHTML=o,d=q.firstChild,e=d.firstChild,h=d.nextSibling.firstChild.firstChild,i={doesNotAddBorder:e.offsetTop!==5,doesAddBorderForTableAndCells:h.offsetTop===5},e.style.position="fixed",e.style.top="20px",i.fixedPosition=e.offsetTop===20||e.offsetTop===15,e.style.position=e.style.top="",d.style.overflow="hidden",d.style.position="relative",i.subtractsBorderForOverflowNotVisible=e.offsetTop===-5,i.doesNotIncludeMarginInBodyOffset=r.offsetTop!==j,r.removeChild(a),q=a=null,f.extend(b,i))});return b}();var j=/^(?:\{.*\}|\[.*\])$/,k=/([A-Z])/g;f.extend({cache:{},uuid:0,expando:"jQuery"+(f.fn.jquery+Math.random()).replace(/\D/g,""),noData:{embed:!0,object:"clsid:D27CDB6E-AE6D-11cf-96B8-444553540000",applet:!0},hasData:function(a){a=a.nodeType?f.cache[a[f.expando]]:a[f.expando];return!!a&&!m(a)},data:function(a,c,d,e){if(!!f.acceptData(a)){var g,h,i,j=f.expando,k=typeof c=="string",l=a.nodeType,m=l?f.cache:a,n=l?a[j]:a[j]&&j,o=c==="events";if((!n||!m[n]||!o&&!e&&!m[n].data)&&k&&d===b)return;n||(l?a[j]=n=++f.uuid:n=j),m[n]||(m[n]={},l||(m[n].toJSON=f.noop));if(typeof c=="object"||typeof c=="function")e?m[n]=f.extend(m[n],c):m[n].data=f.extend(m[n].data,c);g=h=m[n],e||(h.data||(h.data={}),h=h.data),d!==b&&(h[f.camelCase(c)]=d);if(o&&!h[c])return g.events;k?(i=h[c],i==null&&(i=h[f.camelCase(c)])):i=h;return i}},removeData:function(a,b,c){if(!!f.acceptData(a)){var d,e,g,h=f.expando,i=a.nodeType,j=i?f.cache:a,k=i?a[h]:h;if(!j[k])return;if(b){d=c?j[k]:j[k].data;if(d){f.isArray(b)||(b in d?b=[b]:(b=f.camelCase(b),b in d?b=[b]:b=b.split(" ")));for(e=0,g=b.length;e<g;e++)delete d[b[e]];if(!(c?m:f.isEmptyObject)(d))return}}if(!c){delete j[k].data;if(!m(j[k]))return}f.support.deleteExpando||!j.setInterval?delete j[k]:j[k]=null,i&&(f.support.deleteExpando?delete a[h]:a.removeAttribute?a.removeAttribute(h):a[h]=null)}},_data:function(a,b,c){return f.data(a,b,c,!0)},acceptData:function(a){if(a.nodeName){var b=f.noData[a.nodeName.toLowerCase()];if(b)return b!==!0&&a.getAttribute("classid")===b}return!0}}),f.fn.extend({data:function(a,c){var d,e,g,h=null;if(typeof a=="undefined"){if(this.length){h=f.data(this[0]);if(this[0].nodeType===1&&!f._data(this[0],"parsedAttrs")){e=this[0].attributes;for(var i=0,j=e.length;i<j;i++)g=e[i].name,g.indexOf("data-")===0&&(g=f.camelCase(g.substring(5)),l(this[0],g,h[g]));f._data(this[0],"parsedAttrs",!0)}}return h}if(typeof a=="object")return this.each(function(){f.data(this,a)});d=a.split("."),d[1]=d[1]?"."+d[1]:"";if(c===b){h=this.triggerHandler("getData"+d[1]+"!",[d[0]]),h===b&&this.length&&(h=f.data(this[0],a),h=l(this[0],a,h));return h===b&&d[1]?this.data(d[0]):h}return this.each(function(){var b=f(this),e=[d[0],c];b.triggerHandler("setData"+d[1]+"!",e),f.data(this,a,c),b.triggerHandler("changeData"+d[1]+"!",e)})},removeData:function(a){return this.each(function(){f.removeData(this,a)})}}),f.extend({_mark:function(a,b){a&&(b=(b||"fx")+"mark",f._data(a,b,(f._data(a,b)||0)+1))},_unmark:function(a,b,c){a!==!0&&(c=b,b=a,a=!1);if(b){c=c||"fx";var d=c+"mark",e=a?0:(f._data(b,d)||1)-1;e?f._data(b,d,e):(f.removeData(b,d,!0),n(b,c,"mark"))}},queue:function(a,b,c){var d;if(a){b=(b||"fx")+"queue",d=f._data(a,b),c&&(!d||f.isArray(c)?d=f._data(a,b,f.makeArray(c)):d.push(c));return d||[]}},dequeue:function(a,b){b=b||"fx";var c=f.queue(a,b),d=c.shift(),e={};d==="inprogress"&&(d=c.shift()),d&&(b==="fx"&&c.unshift("inprogress"),f._data(a,b+".run",e),d.call(a,function(){f.dequeue(a,b)},e)),c.length||(f.removeData(a,b+"queue "+b+".run",!0),n(a,b,"queue"))}}),f.fn.extend({queue:function(a,c){typeof a!="string"&&(c=a,a="fx");if(c===b)return f.queue(this[0],a);return this.each(function(){var b=f.queue(this,a,c);a==="fx"&&b[0]!=="inprogress"&&f.dequeue(this,a)})},dequeue:function(a){return this.each(function(){f.dequeue(this,a)})},delay:function(a,b){a=f.fx?f.fx.speeds[a]||a:a,b=b||"fx";return this.queue(b,function(b,c){var d=setTimeout(b,a);c.stop=function(){clearTimeout(d)}})},clearQueue:function(a){return this.queue(a||"fx",[])},promise:function(a,c){function m(){--h||d.resolveWith(e,[e])}typeof a!="string"&&(c=a,a=b),a=a||"fx";var d=f.Deferred(),e=this,g=e.length,h=1,i=a+"defer",j=a+"queue",k=a+"mark",l;while(g--)if(l=f.data(e[g],i,b,!0)||(f.data(e[g],j,b,!0)||f.data(e[g],k,b,!0))&&f.data(e[g],i,f.Callbacks("once memory"),!0))h++,l.add(m);m();return d.promise()}});var o=/[\n\t\r]/g,p=/\s+/,q=/\r/g,r=/^(?:button|input)$/i,s=/^(?:button|input|object|select|textarea)$/i,t=/^a(?:rea)?$/i,u=/^(?:autofocus|autoplay|async|checked|controls|defer|disabled|hidden|loop|multiple|open|readonly|required|scoped|selected)$/i,v=f.support.getSetAttribute,w,x,y;f.fn.extend({attr:function(a,b){return f.access(this,a,b,!0,f.attr)},removeAttr:function(a){return this.each(function(){f.removeAttr(this,a)})},prop:function(a,b){return f.access(this,a,b,!0,f.prop)},removeProp:function(a){a=f.propFix[a]||a;return this.each(function(){try{this[a]=b,delete this[a]}catch(c){}})},addClass:function(a){var b,c,d,e,g,h,i;if(f.isFunction(a))return this.each(function(b){f(this).addClass(a.call(this,b,this.className))});if(a&&typeof a=="string"){b=a.split(p);for(c=0,d=this.length;c<d;c++){e=this[c];if(e.nodeType===1)if(!e.className&&b.length===1)e.className=a;else{g=" "+e.className+" ";for(h=0,i=b.length;h<i;h++)~g.indexOf(" "+b[h]+" ")||(g+=b[h]+" ");e.className=f.trim(g)}}}return this},removeClass:function(a){var c,d,e,g,h,i,j;if(f.isFunction(a))return this.each(function(b){f(this).removeClass(a.call(this,b,this.className))});if(a&&typeof a=="string"||a===b){c=(a||"").split(p);for(d=0,e=this.length;d<e;d++){g=this[d];if(g.nodeType===1&&g.className)if(a){h=(" "+g.className+" ").replace(o," ");for(i=0,j=c.length;i<j;i++)h=h.replace(" "+c[i]+" "," ");g.className=f.trim(h)}else g.className=""}}return this},toggleClass:function(a,b){var c=typeof a,d=typeof b=="boolean";if(f.isFunction(a))return this.each(function(c){f(this).toggleClass(a.call(this,c,this.className,b),b)});return this.each(function(){if(c==="string"){var e,g=0,h=f(this),i=b,j=a.split(p);while(e=j[g++])i=d?i:!h.hasClass(e),h[i?"addClass":"removeClass"](e)}else if(c==="undefined"||c==="boolean")this.className&&f._data(this,"__className__",this.className),this.className=this.className||a===!1?"":f._data(this,"__className__")||""})},hasClass:function(a){var b=" "+a+" ",c=0,d=this.length;for(;c<d;c++)if(this[c].nodeType===1&&(" "+this[c].className+" ").replace(o," ").indexOf(b)>-1)return!0;return!1},val:function(a){var c,d,e,g=this[0];{if(!!arguments.length){e=f.isFunction(a);return this.each(function(d){var g=f(this),h;if(this.nodeType===1){e?h=a.call(this,d,g.val()):h=a,h==null?h="":typeof h=="number"?h+="":f.isArray(h)&&(h=f.map(h,function(a){return a==null?"":a+""})),c=f.valHooks[this.nodeName.toLowerCase()]||f.valHooks[this.type];if(!c||!("set"in c)||c.set(this,h,"value")===b)this.value=h}})}if(g){c=f.valHooks[g.nodeName.toLowerCase()]||f.valHooks[g.type];if(c&&"get"in c&&(d=c.get(g,"value"))!==b)return d;d=g.value;return typeof d=="string"?d.replace(q,""):d==null?"":d}}}}),f.extend({valHooks:{option:{get:function(a){var b=a.attributes.value;return!b||b.specified?a.value:a.text}},select:{get:function(a){var b,c,d,e,g=a.selectedIndex,h=[],i=a.options,j=a.type==="select-one";if(g<0)return null;c=j?g:0,d=j?g+1:i.length;for(;c<d;c++){e=i[c];if(e.selected&&(f.support.optDisabled?!e.disabled:e.getAttribute("disabled")===null)&&(!e.parentNode.disabled||!f.nodeName(e.parentNode,"optgroup"))){b=f(e).val();if(j)return b;h.push(b)}}if(j&&!h.length&&i.length)return f(i[g]).val();return h},set:function(a,b){var c=f.makeArray(b);f(a).find("option").each(function(){this.selected=f.inArray(f(this).val(),c)>=0}),c.length||(a.selectedIndex=-1);return c}}},attrFn:{val:!0,css:!0,html:!0,text:!0,data:!0,width:!0,height:!0,offset:!0},attr:function(a,c,d,e){var g,h,i,j=a.nodeType;if(!!a&&j!==3&&j!==8&&j!==2){if(e&&c in f.attrFn)return f(a)[c](d);if(typeof a.getAttribute=="undefined")return f.prop(a,c,d);i=j!==1||!f.isXMLDoc(a),i&&(c=c.toLowerCase(),h=f.attrHooks[c]||(u.test(c)?x:w));if(d!==b){if(d===null){f.removeAttr(a,c);return}if(h&&"set"in h&&i&&(g=h.set(a,d,c))!==b)return g;a.setAttribute(c,""+d);return d}if(h&&"get"in h&&i&&(g=h.get(a,c))!==null)return g;g=a.getAttribute(c);return g===null?b:g}},removeAttr:function(a,b){var c,d,e,g,h=0;if(b&&a.nodeType===1){d=b.toLowerCase().split(p),g=d.length;for(;h<g;h++)e=d[h],e&&(c=f.propFix[e]||e,f.attr(a,e,""),a.removeAttribute(v?e:c),u.test(e)&&c in a&&(a[c]=!1))}},attrHooks:{type:{set:function(a,b){if(r.test(a.nodeName)&&a.parentNode)f.error("type property can't be changed");else if(!f.support.radioValue&&b==="radio"&&f.nodeName(a,"input")){var c=a.value;a.setAttribute("type",b),c&&(a.value=c);return b}}},value:{get:function(a,b){if(w&&f.nodeName(a,"button"))return w.get(a,b);return b in a?a.value:null},set:function(a,b,c){if(w&&f.nodeName(a,"button"))return w.set(a,b,c);a.value=b}}},propFix:{tabindex:"tabIndex",readonly:"readOnly","for":"htmlFor","class":"className",maxlength:"maxLength",cellspacing:"cellSpacing",cellpadding:"cellPadding",rowspan:"rowSpan",colspan:"colSpan",usemap:"useMap",frameborder:"frameBorder",contenteditable:"contentEditable"},prop:function(a,c,d){var e,g,h,i=a.nodeType;if(!!a&&i!==3&&i!==8&&i!==2){h=i!==1||!f.isXMLDoc(a),h&&(c=f.propFix[c]||c,g=f.propHooks[c]);return d!==b?g&&"set"in g&&(e=g.set(a,d,c))!==b?e:a[c]=d:g&&"get"in g&&(e=g.get(a,c))!==null?e:a[c]}},propHooks:{tabIndex:{get:function(a){var c=a.getAttributeNode("tabindex");return c&&c.specified?parseInt(c.value,10):s.test(a.nodeName)||t.test(a.nodeName)&&a.href?0:b}}}}),f.attrHooks.tabindex=f.propHooks.tabIndex,x={get:function(a,c){var d,e=f.prop(a,c);return e===!0||typeof e!="boolean"&&(d=a.getAttributeNode(c))&&d.nodeValue!==!1?c.toLowerCase():b},set:function(a,b,c){var d;b===!1?f.removeAttr(a,c):(d=f.propFix[c]||c,d in a&&(a[d]=!0),a.setAttribute(c,c.toLowerCase()));return c}},v||(y={name:!0,id:!0},w=f.valHooks.button={get:function(a,c){var d;d=a.getAttributeNode(c);return d&&(y[c]?d.nodeValue!=="":d.specified)?d.nodeValue:b},set:function(a,b,d){var e=a.getAttributeNode(d);e||(e=c.createAttribute(d),a.setAttributeNode(e));return e.nodeValue=b+""}},f.attrHooks.tabindex.set=w.set,f.each(["width","height"],function(a,b){f.attrHooks[b]=f.extend(f.attrHooks[b],{set:function(a,c){if(c===""){a.setAttribute(b,"auto");return c}}})}),f.attrHooks.contenteditable={get:w.get,set:function(a,b,c){b===""&&(b="false"),w.set(a,b,c)}}),f.support.hrefNormalized||f.each(["href","src","width","height"],function(a,c){f.attrHooks[c]=f.extend(f.attrHooks[c],{get:function(a){var d=a.getAttribute(c,2);return d===null?b:d}})}),f.support.style||(f.attrHooks.style={get:function(a){return a.style.cssText.toLowerCase()||b},set:function(a,b){return a.style.cssText=""+b}}),f.support.optSelected||(f.propHooks.selected=f.extend(f.propHooks.selected,{get:function(a){var b=a.parentNode;b&&(b.selectedIndex,b.parentNode&&b.parentNode.selectedIndex);return null}})),f.support.enctype||(f.propFix.enctype="encoding"),f.support.checkOn||f.each(["radio","checkbox"],function(){f.valHooks[this]={get:function(a){return a.getAttribute("value")===null?"on":a.value}}}),f.each(["radio","checkbox"],function(){f.valHooks[this]=f.extend(f.valHooks[this],{set:function(a,b){if(f.isArray(b))return a.checked=f.inArray(f(a).val(),b)>=0}})});var z=/^(?:textarea|input|select)$/i,A=/^([^\.]*)?(?:\.(.+))?$/,B=/\bhover(\.\S+)?\b/,C=/^key/,D=/^(?:mouse|contextmenu)|click/,E=/^(?:focusinfocus|focusoutblur)$/,F=/^(\w*)(?:#([\w\-]+))?(?:\.([\w\-]+))?$/,G=function(a){var b=F.exec(a);b&&(b[1]=(b[1]||"").toLowerCase(),b[3]=b[3]&&new RegExp("(?:^|\\s)"+b[3]+"(?:\\s|$)"));return b},H=function(a,b){var c=a.attributes||{};return(!b[1]||a.nodeName.toLowerCase()===b[1])&&(!b[2]||(c.id||{}).value===b[2])&&(!b[3]||b[3].test((c["class"]||{}).value))},I=function(a){return f.event.special.hover?a:a.replace(B,"mouseenter$1 mouseleave$1")};
+f.event={add:function(a,c,d,e,g){var h,i,j,k,l,m,n,o,p,q,r,s;if(!(a.nodeType===3||a.nodeType===8||!c||!d||!(h=f._data(a)))){d.handler&&(p=d,d=p.handler),d.guid||(d.guid=f.guid++),j=h.events,j||(h.events=j={}),i=h.handle,i||(h.handle=i=function(a){return typeof f!="undefined"&&(!a||f.event.triggered!==a.type)?f.event.dispatch.apply(i.elem,arguments):b},i.elem=a),c=f.trim(I(c)).split(" ");for(k=0;k<c.length;k++){l=A.exec(c[k])||[],m=l[1],n=(l[2]||"").split(".").sort(),s=f.event.special[m]||{},m=(g?s.delegateType:s.bindType)||m,s=f.event.special[m]||{},o=f.extend({type:m,origType:l[1],data:e,handler:d,guid:d.guid,selector:g,quick:G(g),namespace:n.join(".")},p),r=j[m];if(!r){r=j[m]=[],r.delegateCount=0;if(!s.setup||s.setup.call(a,e,n,i)===!1)a.addEventListener?a.addEventListener(m,i,!1):a.attachEvent&&a.attachEvent("on"+m,i)}s.add&&(s.add.call(a,o),o.handler.guid||(o.handler.guid=d.guid)),g?r.splice(r.delegateCount++,0,o):r.push(o),f.event.global[m]=!0}a=null}},global:{},remove:function(a,b,c,d,e){var g=f.hasData(a)&&f._data(a),h,i,j,k,l,m,n,o,p,q,r,s;if(!!g&&!!(o=g.events)){b=f.trim(I(b||"")).split(" ");for(h=0;h<b.length;h++){i=A.exec(b[h])||[],j=k=i[1],l=i[2];if(!j){for(j in o)f.event.remove(a,j+b[h],c,d,!0);continue}p=f.event.special[j]||{},j=(d?p.delegateType:p.bindType)||j,r=o[j]||[],m=r.length,l=l?new RegExp("(^|\\.)"+l.split(".").sort().join("\\.(?:.*\\.)?")+"(\\.|$)"):null;for(n=0;n<r.length;n++)s=r[n],(e||k===s.origType)&&(!c||c.guid===s.guid)&&(!l||l.test(s.namespace))&&(!d||d===s.selector||d==="**"&&s.selector)&&(r.splice(n--,1),s.selector&&r.delegateCount--,p.remove&&p.remove.call(a,s));r.length===0&&m!==r.length&&((!p.teardown||p.teardown.call(a,l)===!1)&&f.removeEvent(a,j,g.handle),delete o[j])}f.isEmptyObject(o)&&(q=g.handle,q&&(q.elem=null),f.removeData(a,["events","handle"],!0))}},customEvent:{getData:!0,setData:!0,changeData:!0},trigger:function(c,d,e,g){if(!e||e.nodeType!==3&&e.nodeType!==8){var h=c.type||c,i=[],j,k,l,m,n,o,p,q,r,s;if(E.test(h+f.event.triggered))return;h.indexOf("!")>=0&&(h=h.slice(0,-1),k=!0),h.indexOf(".")>=0&&(i=h.split("."),h=i.shift(),i.sort());if((!e||f.event.customEvent[h])&&!f.event.global[h])return;c=typeof c=="object"?c[f.expando]?c:new f.Event(h,c):new f.Event(h),c.type=h,c.isTrigger=!0,c.exclusive=k,c.namespace=i.join("."),c.namespace_re=c.namespace?new RegExp("(^|\\.)"+i.join("\\.(?:.*\\.)?")+"(\\.|$)"):null,o=h.indexOf(":")<0?"on"+h:"";if(!e){j=f.cache;for(l in j)j[l].events&&j[l].events[h]&&f.event.trigger(c,d,j[l].handle.elem,!0);return}c.result=b,c.target||(c.target=e),d=d!=null?f.makeArray(d):[],d.unshift(c),p=f.event.special[h]||{};if(p.trigger&&p.trigger.apply(e,d)===!1)return;r=[[e,p.bindType||h]];if(!g&&!p.noBubble&&!f.isWindow(e)){s=p.delegateType||h,m=E.test(s+h)?e:e.parentNode,n=null;for(;m;m=m.parentNode)r.push([m,s]),n=m;n&&n===e.ownerDocument&&r.push([n.defaultView||n.parentWindow||a,s])}for(l=0;l<r.length&&!c.isPropagationStopped();l++)m=r[l][0],c.type=r[l][1],q=(f._data(m,"events")||{})[c.type]&&f._data(m,"handle"),q&&q.apply(m,d),q=o&&m[o],q&&f.acceptData(m)&&q.apply(m,d)===!1&&c.preventDefault();c.type=h,!g&&!c.isDefaultPrevented()&&(!p._default||p._default.apply(e.ownerDocument,d)===!1)&&(h!=="click"||!f.nodeName(e,"a"))&&f.acceptData(e)&&o&&e[h]&&(h!=="focus"&&h!=="blur"||c.target.offsetWidth!==0)&&!f.isWindow(e)&&(n=e[o],n&&(e[o]=null),f.event.triggered=h,e[h](),f.event.triggered=b,n&&(e[o]=n));return c.result}},dispatch:function(c){c=f.event.fix(c||a.event);var d=(f._data(this,"events")||{})[c.type]||[],e=d.delegateCount,g=[].slice.call(arguments,0),h=!c.exclusive&&!c.namespace,i=[],j,k,l,m,n,o,p,q,r,s,t;g[0]=c,c.delegateTarget=this;if(e&&!c.target.disabled&&(!c.button||c.type!=="click")){m=f(this),m.context=this.ownerDocument||this;for(l=c.target;l!=this;l=l.parentNode||this){o={},q=[],m[0]=l;for(j=0;j<e;j++)r=d[j],s=r.selector,o[s]===b&&(o[s]=r.quick?H(l,r.quick):m.is(s)),o[s]&&q.push(r);q.length&&i.push({elem:l,matches:q})}}d.length>e&&i.push({elem:this,matches:d.slice(e)});for(j=0;j<i.length&&!c.isPropagationStopped();j++){p=i[j],c.currentTarget=p.elem;for(k=0;k<p.matches.length&&!c.isImmediatePropagationStopped();k++){r=p.matches[k];if(h||!c.namespace&&!r.namespace||c.namespace_re&&c.namespace_re.test(r.namespace))c.data=r.data,c.handleObj=r,n=((f.event.special[r.origType]||{}).handle||r.handler).apply(p.elem,g),n!==b&&(c.result=n,n===!1&&(c.preventDefault(),c.stopPropagation()))}}return c.result},props:"attrChange attrName relatedNode srcElement altKey bubbles cancelable ctrlKey currentTarget eventPhase metaKey relatedTarget shiftKey target timeStamp view which".split(" "),fixHooks:{},keyHooks:{props:"char charCode key keyCode".split(" "),filter:function(a,b){a.which==null&&(a.which=b.charCode!=null?b.charCode:b.keyCode);return a}},mouseHooks:{props:"button buttons clientX clientY fromElement offsetX offsetY pageX pageY screenX screenY toElement".split(" "),filter:function(a,d){var e,f,g,h=d.button,i=d.fromElement;a.pageX==null&&d.clientX!=null&&(e=a.target.ownerDocument||c,f=e.documentElement,g=e.body,a.pageX=d.clientX+(f&&f.scrollLeft||g&&g.scrollLeft||0)-(f&&f.clientLeft||g&&g.clientLeft||0),a.pageY=d.clientY+(f&&f.scrollTop||g&&g.scrollTop||0)-(f&&f.clientTop||g&&g.clientTop||0)),!a.relatedTarget&&i&&(a.relatedTarget=i===a.target?d.toElement:i),!a.which&&h!==b&&(a.which=h&1?1:h&2?3:h&4?2:0);return a}},fix:function(a){if(a[f.expando])return a;var d,e,g=a,h=f.event.fixHooks[a.type]||{},i=h.props?this.props.concat(h.props):this.props;a=f.Event(g);for(d=i.length;d;)e=i[--d],a[e]=g[e];a.target||(a.target=g.srcElement||c),a.target.nodeType===3&&(a.target=a.target.parentNode),a.metaKey===b&&(a.metaKey=a.ctrlKey);return h.filter?h.filter(a,g):a},special:{ready:{setup:f.bindReady},load:{noBubble:!0},focus:{delegateType:"focusin"},blur:{delegateType:"focusout"},beforeunload:{setup:function(a,b,c){f.isWindow(this)&&(this.onbeforeunload=c)},teardown:function(a,b){this.onbeforeunload===b&&(this.onbeforeunload=null)}}},simulate:function(a,b,c,d){var e=f.extend(new f.Event,c,{type:a,isSimulated:!0,originalEvent:{}});d?f.event.trigger(e,null,b):f.event.dispatch.call(b,e),e.isDefaultPrevented()&&c.preventDefault()}},f.event.handle=f.event.dispatch,f.removeEvent=c.removeEventListener?function(a,b,c){a.removeEventListener&&a.removeEventListener(b,c,!1)}:function(a,b,c){a.detachEvent&&a.detachEvent("on"+b,c)},f.Event=function(a,b){if(!(this instanceof f.Event))return new f.Event(a,b);a&&a.type?(this.originalEvent=a,this.type=a.type,this.isDefaultPrevented=a.defaultPrevented||a.returnValue===!1||a.getPreventDefault&&a.getPreventDefault()?K:J):this.type=a,b&&f.extend(this,b),this.timeStamp=a&&a.timeStamp||f.now(),this[f.expando]=!0},f.Event.prototype={preventDefault:function(){this.isDefaultPrevented=K;var a=this.originalEvent;!a||(a.preventDefault?a.preventDefault():a.returnValue=!1)},stopPropagation:function(){this.isPropagationStopped=K;var a=this.originalEvent;!a||(a.stopPropagation&&a.stopPropagation(),a.cancelBubble=!0)},stopImmediatePropagation:function(){this.isImmediatePropagationStopped=K,this.stopPropagation()},isDefaultPrevented:J,isPropagationStopped:J,isImmediatePropagationStopped:J},f.each({mouseenter:"mouseover",mouseleave:"mouseout"},function(a,b){f.event.special[a]={delegateType:b,bindType:b,handle:function(a){var c=this,d=a.relatedTarget,e=a.handleObj,g=e.selector,h;if(!d||d!==c&&!f.contains(c,d))a.type=e.origType,h=e.handler.apply(this,arguments),a.type=b;return h}}}),f.support.submitBubbles||(f.event.special.submit={setup:function(){if(f.nodeName(this,"form"))return!1;f.event.add(this,"click._submit keypress._submit",function(a){var c=a.target,d=f.nodeName(c,"input")||f.nodeName(c,"button")?c.form:b;d&&!d._submit_attached&&(f.event.add(d,"submit._submit",function(a){this.parentNode&&!a.isTrigger&&f.event.simulate("submit",this.parentNode,a,!0)}),d._submit_attached=!0)})},teardown:function(){if(f.nodeName(this,"form"))return!1;f.event.remove(this,"._submit")}}),f.support.changeBubbles||(f.event.special.change={setup:function(){if(z.test(this.nodeName)){if(this.type==="checkbox"||this.type==="radio")f.event.add(this,"propertychange._change",function(a){a.originalEvent.propertyName==="checked"&&(this._just_changed=!0)}),f.event.add(this,"click._change",function(a){this._just_changed&&!a.isTrigger&&(this._just_changed=!1,f.event.simulate("change",this,a,!0))});return!1}f.event.add(this,"beforeactivate._change",function(a){var b=a.target;z.test(b.nodeName)&&!b._change_attached&&(f.event.add(b,"change._change",function(a){this.parentNode&&!a.isSimulated&&!a.isTrigger&&f.event.simulate("change",this.parentNode,a,!0)}),b._change_attached=!0)})},handle:function(a){var b=a.target;if(this!==b||a.isSimulated||a.isTrigger||b.type!=="radio"&&b.type!=="checkbox")return a.handleObj.handler.apply(this,arguments)},teardown:function(){f.event.remove(this,"._change");return z.test(this.nodeName)}}),f.support.focusinBubbles||f.each({focus:"focusin",blur:"focusout"},function(a,b){var d=0,e=function(a){f.event.simulate(b,a.target,f.event.fix(a),!0)};f.event.special[b]={setup:function(){d++===0&&c.addEventListener(a,e,!0)},teardown:function(){--d===0&&c.removeEventListener(a,e,!0)}}}),f.fn.extend({on:function(a,c,d,e,g){var h,i;if(typeof a=="object"){typeof c!="string"&&(d=c,c=b);for(i in a)this.on(i,c,d,a[i],g);return this}d==null&&e==null?(e=c,d=c=b):e==null&&(typeof c=="string"?(e=d,d=b):(e=d,d=c,c=b));if(e===!1)e=J;else if(!e)return this;g===1&&(h=e,e=function(a){f().off(a);return h.apply(this,arguments)},e.guid=h.guid||(h.guid=f.guid++));return this.each(function(){f.event.add(this,a,e,d,c)})},one:function(a,b,c,d){return this.on.call(this,a,b,c,d,1)},off:function(a,c,d){if(a&&a.preventDefault&&a.handleObj){var e=a.handleObj;f(a.delegateTarget).off(e.namespace?e.type+"."+e.namespace:e.type,e.selector,e.handler);return this}if(typeof a=="object"){for(var g in a)this.off(g,c,a[g]);return this}if(c===!1||typeof c=="function")d=c,c=b;d===!1&&(d=J);return this.each(function(){f.event.remove(this,a,d,c)})},bind:function(a,b,c){return this.on(a,null,b,c)},unbind:function(a,b){return this.off(a,null,b)},live:function(a,b,c){f(this.context).on(a,this.selector,b,c);return this},die:function(a,b){f(this.context).off(a,this.selector||"**",b);return this},delegate:function(a,b,c,d){return this.on(b,a,c,d)},undelegate:function(a,b,c){return arguments.length==1?this.off(a,"**"):this.off(b,a,c)},trigger:function(a,b){return this.each(function(){f.event.trigger(a,b,this)})},triggerHandler:function(a,b){if(this[0])return f.event.trigger(a,b,this[0],!0)},toggle:function(a){var b=arguments,c=a.guid||f.guid++,d=0,e=function(c){var e=(f._data(this,"lastToggle"+a.guid)||0)%d;f._data(this,"lastToggle"+a.guid,e+1),c.preventDefault();return b[e].apply(this,arguments)||!1};e.guid=c;while(d<b.length)b[d++].guid=c;return this.click(e)},hover:function(a,b){return this.mouseenter(a).mouseleave(b||a)}}),f.each("blur focus focusin focusout load resize scroll unload click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup error contextmenu".split(" "),function(a,b){f.fn[b]=function(a,c){c==null&&(c=a,a=null);return arguments.length>0?this.on(b,null,a,c):this.trigger(b)},f.attrFn&&(f.attrFn[b]=!0),C.test(b)&&(f.event.fixHooks[b]=f.event.keyHooks),D.test(b)&&(f.event.fixHooks[b]=f.event.mouseHooks)}),function(){function x(a,b,c,e,f,g){for(var h=0,i=e.length;h<i;h++){var j=e[h];if(j){var k=!1;j=j[a];while(j){if(j[d]===c){k=e[j.sizset];break}if(j.nodeType===1){g||(j[d]=c,j.sizset=h);if(typeof b!="string"){if(j===b){k=!0;break}}else if(m.filter(b,[j]).length>0){k=j;break}}j=j[a]}e[h]=k}}}function w(a,b,c,e,f,g){for(var h=0,i=e.length;h<i;h++){var j=e[h];if(j){var k=!1;j=j[a];while(j){if(j[d]===c){k=e[j.sizset];break}j.nodeType===1&&!g&&(j[d]=c,j.sizset=h);if(j.nodeName.toLowerCase()===b){k=j;break}j=j[a]}e[h]=k}}}var a=/((?:\((?:\([^()]+\)|[^()]+)+\)|\[(?:\[[^\[\]]*\]|['"][^'"]*['"]|[^\[\]'"]+)+\]|\\.|[^ >+~,(\[\\]+)+|[>+~])(\s*,\s*)?((?:.|\r|\n)*)/g,d="sizcache"+(Math.random()+"").replace(".",""),e=0,g=Object.prototype.toString,h=!1,i=!0,j=/\\/g,k=/\r\n/g,l=/\W/;[0,0].sort(function(){i=!1;return 0});var m=function(b,d,e,f){e=e||[],d=d||c;var h=d;if(d.nodeType!==1&&d.nodeType!==9)return[];if(!b||typeof b!="string")return e;var i,j,k,l,n,q,r,t,u=!0,v=m.isXML(d),w=[],x=b;do{a.exec(""),i=a.exec(x);if(i){x=i[3],w.push(i[1]);if(i[2]){l=i[3];break}}}while(i);if(w.length>1&&p.exec(b))if(w.length===2&&o.relative[w[0]])j=y(w[0]+w[1],d,f);else{j=o.relative[w[0]]?[d]:m(w.shift(),d);while(w.length)b=w.shift(),o.relative[b]&&(b+=w.shift()),j=y(b,j,f)}else{!f&&w.length>1&&d.nodeType===9&&!v&&o.match.ID.test(w[0])&&!o.match.ID.test(w[w.length-1])&&(n=m.find(w.shift(),d,v),d=n.expr?m.filter(n.expr,n.set)[0]:n.set[0]);if(d){n=f?{expr:w.pop(),set:s(f)}:m.find(w.pop(),w.length===1&&(w[0]==="~"||w[0]==="+")&&d.parentNode?d.parentNode:d,v),j=n.expr?m.filter(n.expr,n.set):n.set,w.length>0?k=s(j):u=!1;while(w.length)q=w.pop(),r=q,o.relative[q]?r=w.pop():q="",r==null&&(r=d),o.relative[q](k,r,v)}else k=w=[]}k||(k=j),k||m.error(q||b);if(g.call(k)==="[object Array]")if(!u)e.push.apply(e,k);else if(d&&d.nodeType===1)for(t=0;k[t]!=null;t++)k[t]&&(k[t]===!0||k[t].nodeType===1&&m.contains(d,k[t]))&&e.push(j[t]);else for(t=0;k[t]!=null;t++)k[t]&&k[t].nodeType===1&&e.push(j[t]);else s(k,e);l&&(m(l,h,e,f),m.uniqueSort(e));return e};m.uniqueSort=function(a){if(u){h=i,a.sort(u);if(h)for(var b=1;b<a.length;b++)a[b]===a[b-1]&&a.splice(b--,1)}return a},m.matches=function(a,b){return m(a,null,null,b)},m.matchesSelector=function(a,b){return m(b,null,null,[a]).length>0},m.find=function(a,b,c){var d,e,f,g,h,i;if(!a)return[];for(e=0,f=o.order.length;e<f;e++){h=o.order[e];if(g=o.leftMatch[h].exec(a)){i=g[1],g.splice(1,1);if(i.substr(i.length-1)!=="\\"){g[1]=(g[1]||"").replace(j,""),d=o.find[h](g,b,c);if(d!=null){a=a.replace(o.match[h],"");break}}}}d||(d=typeof b.getElementsByTagName!="undefined"?b.getElementsByTagName("*"):[]);return{set:d,expr:a}},m.filter=function(a,c,d,e){var f,g,h,i,j,k,l,n,p,q=a,r=[],s=c,t=c&&c[0]&&m.isXML(c[0]);while(a&&c.length){for(h in o.filter)if((f=o.leftMatch[h].exec(a))!=null&&f[2]){k=o.filter[h],l=f[1],g=!1,f.splice(1,1);if(l.substr(l.length-1)==="\\")continue;s===r&&(r=[]);if(o.preFilter[h]){f=o.preFilter[h](f,s,d,r,e,t);if(!f)g=i=!0;else if(f===!0)continue}if(f)for(n=0;(j=s[n])!=null;n++)j&&(i=k(j,f,n,s),p=e^i,d&&i!=null?p?g=!0:s[n]=!1:p&&(r.push(j),g=!0));if(i!==b){d||(s=r),a=a.replace(o.match[h],"");if(!g)return[];break}}if(a===q)if(g==null)m.error(a);else break;q=a}return s},m.error=function(a){throw new Error("Syntax error, unrecognized expression: "+a)};var n=m.getText=function(a){var b,c,d=a.nodeType,e="";if(d){if(d===1||d===9){if(typeof a.textContent=="string")return a.textContent;if(typeof a.innerText=="string")return a.innerText.replace(k,"");for(a=a.firstChild;a;a=a.nextSibling)e+=n(a)}else if(d===3||d===4)return a.nodeValue}else for(b=0;c=a[b];b++)c.nodeType!==8&&(e+=n(c));return e},o=m.selectors={order:["ID","NAME","TAG"],match:{ID:/#((?:[\w\u00c0-\uFFFF\-]|\\.)+)/,CLASS:/\.((?:[\w\u00c0-\uFFFF\-]|\\.)+)/,NAME:/\[name=['"]*((?:[\w\u00c0-\uFFFF\-]|\\.)+)['"]*\]/,ATTR:/\[\s*((?:[\w\u00c0-\uFFFF\-]|\\.)+)\s*(?:(\S?=)\s*(?:(['"])(.*?)\3|(#?(?:[\w\u00c0-\uFFFF\-]|\\.)*)|)|)\s*\]/,TAG:/^((?:[\w\u00c0-\uFFFF\*\-]|\\.)+)/,CHILD:/:(only|nth|last|first)-child(?:\(\s*(even|odd|(?:[+\-]?\d+|(?:[+\-]?\d*)?n\s*(?:[+\-]\s*\d+)?))\s*\))?/,POS:/:(nth|eq|gt|lt|first|last|even|odd)(?:\((\d*)\))?(?=[^\-]|$)/,PSEUDO:/:((?:[\w\u00c0-\uFFFF\-]|\\.)+)(?:\((['"]?)((?:\([^\)]+\)|[^\(\)]*)+)\2\))?/},leftMatch:{},attrMap:{"class":"className","for":"htmlFor"},attrHandle:{href:function(a){return a.getAttribute("href")},type:function(a){return a.getAttribute("type")}},relative:{"+":function(a,b){var c=typeof b=="string",d=c&&!l.test(b),e=c&&!d;d&&(b=b.toLowerCase());for(var f=0,g=a.length,h;f<g;f++)if(h=a[f]){while((h=h.previousSibling)&&h.nodeType!==1);a[f]=e||h&&h.nodeName.toLowerCase()===b?h||!1:h===b}e&&m.filter(b,a,!0)},">":function(a,b){var c,d=typeof b=="string",e=0,f=a.length;if(d&&!l.test(b)){b=b.toLowerCase();for(;e<f;e++){c=a[e];if(c){var g=c.parentNode;a[e]=g.nodeName.toLowerCase()===b?g:!1}}}else{for(;e<f;e++)c=a[e],c&&(a[e]=d?c.parentNode:c.parentNode===b);d&&m.filter(b,a,!0)}},"":function(a,b,c){var d,f=e++,g=x;typeof b=="string"&&!l.test(b)&&(b=b.toLowerCase(),d=b,g=w),g("parentNode",b,f,a,d,c)},"~":function(a,b,c){var d,f=e++,g=x;typeof b=="string"&&!l.test(b)&&(b=b.toLowerCase(),d=b,g=w),g("previousSibling",b,f,a,d,c)}},find:{ID:function(a,b,c){if(typeof b.getElementById!="undefined"&&!c){var d=b.getElementById(a[1]);return d&&d.parentNode?[d]:[]}},NAME:function(a,b){if(typeof b.getElementsByName!="undefined"){var c=[],d=b.getElementsByName(a[1]);for(var e=0,f=d.length;e<f;e++)d[e].getAttribute("name")===a[1]&&c.push(d[e]);return c.length===0?null:c}},TAG:function(a,b){if(typeof b.getElementsByTagName!="undefined")return b.getElementsByTagName(a[1])}},preFilter:{CLASS:function(a,b,c,d,e,f){a=" "+a[1].replace(j,"")+" ";if(f)return a;for(var g=0,h;(h=b[g])!=null;g++)h&&(e^(h.className&&(" "+h.className+" ").replace(/[\t\n\r]/g," ").indexOf(a)>=0)?c||d.push(h):c&&(b[g]=!1));return!1},ID:function(a){return a[1].replace(j,"")},TAG:function(a,b){return a[1].replace(j,"").toLowerCase()},CHILD:function(a){if(a[1]==="nth"){a[2]||m.error(a[0]),a[2]=a[2].replace(/^\+|\s*/g,"");var b=/(-?)(\d*)(?:n([+\-]?\d*))?/.exec(a[2]==="even"&&"2n"||a[2]==="odd"&&"2n+1"||!/\D/.test(a[2])&&"0n+"+a[2]||a[2]);a[2]=b[1]+(b[2]||1)-0,a[3]=b[3]-0}else a[2]&&m.error(a[0]);a[0]=e++;return a},ATTR:function(a,b,c,d,e,f){var g=a[1]=a[1].replace(j,"");!f&&o.attrMap[g]&&(a[1]=o.attrMap[g]),a[4]=(a[4]||a[5]||"").replace(j,""),a[2]==="~="&&(a[4]=" "+a[4]+" ");return a},PSEUDO:function(b,c,d,e,f){if(b[1]==="not")if((a.exec(b[3])||"").length>1||/^\w/.test(b[3]))b[3]=m(b[3],null,null,c);else{var g=m.filter(b[3],c,d,!0^f);d||e.push.apply(e,g);return!1}else if(o.match.POS.test(b[0])||o.match.CHILD.test(b[0]))return!0;return b},POS:function(a){a.unshift(!0);return a}},filters:{enabled:function(a){return a.disabled===!1&&a.type!=="hidden"},disabled:function(a){return a.disabled===!0},checked:function(a){return a.checked===!0},selected:function(a){a.parentNode&&a.parentNode.selectedIndex;return a.selected===!0},parent:function(a){return!!a.firstChild},empty:function(a){return!a.firstChild},has:function(a,b,c){return!!m(c[3],a).length},header:function(a){return/h\d/i.test(a.nodeName)},text:function(a){var b=a.getAttribute("type"),c=a.type;return a.nodeName.toLowerCase()==="input"&&"text"===c&&(b===c||b===null)},radio:function(a){return a.nodeName.toLowerCase()==="input"&&"radio"===a.type},checkbox:function(a){return a.nodeName.toLowerCase()==="input"&&"checkbox"===a.type},file:function(a){return a.nodeName.toLowerCase()==="input"&&"file"===a.type},password:function(a){return a.nodeName.toLowerCase()==="input"&&"password"===a.type},submit:function(a){var b=a.nodeName.toLowerCase();return(b==="input"||b==="button")&&"submit"===a.type},image:function(a){return a.nodeName.toLowerCase()==="input"&&"image"===a.type},reset:function(a){var b=a.nodeName.toLowerCase();return(b==="input"||b==="button")&&"reset"===a.type},button:function(a){var b=a.nodeName.toLowerCase();return b==="input"&&"button"===a.type||b==="button"},input:function(a){return/input|select|textarea|button/i.test(a.nodeName)},focus:function(a){return a===a.ownerDocument.activeElement}},setFilters:{first:function(a,b){return b===0},last:function(a,b,c,d){return b===d.length-1},even:function(a,b){return b%2===0},odd:function(a,b){return b%2===1},lt:function(a,b,c){return b<c[3]-0},gt:function(a,b,c){return b>c[3]-0},nth:function(a,b,c){return c[3]-0===b},eq:function(a,b,c){return c[3]-0===b}},filter:{PSEUDO:function(a,b,c,d){var e=b[1],f=o.filters[e];if(f)return f(a,c,b,d);if(e==="contains")return(a.textContent||a.innerText||n([a])||"").indexOf(b[3])>=0;if(e==="not"){var g=b[3];for(var h=0,i=g.length;h<i;h++)if(g[h]===a)return!1;return!0}m.error(e)},CHILD:function(a,b){var c,e,f,g,h,i,j,k=b[1],l=a;switch(k){case"only":case"first":while(l=l.previousSibling)if(l.nodeType===1)return!1;if(k==="first")return!0;l=a;case"last":while(l=l.nextSibling)if(l.nodeType===1)return!1;return!0;case"nth":c=b[2],e=b[3];if(c===1&&e===0)return!0;f=b[0],g=a.parentNode;if(g&&(g[d]!==f||!a.nodeIndex)){i=0;for(l=g.firstChild;l;l=l.nextSibling)l.nodeType===1&&(l.nodeIndex=++i);g[d]=f}j=a.nodeIndex-e;return c===0?j===0:j%c===0&&j/c>=0}},ID:function(a,b){return a.nodeType===1&&a.getAttribute("id")===b},TAG:function(a,b){return b==="*"&&a.nodeType===1||!!a.nodeName&&a.nodeName.toLowerCase()===b},CLASS:function(a,b){return(" "+(a.className||a.getAttribute("class"))+" ").indexOf(b)>-1},ATTR:function(a,b){var c=b[1],d=m.attr?m.attr(a,c):o.attrHandle[c]?o.attrHandle[c](a):a[c]!=null?a[c]:a.getAttribute(c),e=d+"",f=b[2],g=b[4];return d==null?f==="!=":!f&&m.attr?d!=null:f==="="?e===g:f==="*="?e.indexOf(g)>=0:f==="~="?(" "+e+" ").indexOf(g)>=0:g?f==="!="?e!==g:f==="^="?e.indexOf(g)===0:f==="$="?e.substr(e.length-g.length)===g:f==="|="?e===g||e.substr(0,g.length+1)===g+"-":!1:e&&d!==!1},POS:function(a,b,c,d){var e=b[2],f=o.setFilters[e];if(f)return f(a,c,b,d)}}},p=o.match.POS,q=function(a,b){return"\\"+(b-0+1)};for(var r in o.match)o.match[r]=new RegExp(o.match[r].source+/(?![^\[]*\])(?![^\(]*\))/.source),o.leftMatch[r]=new RegExp(/(^(?:.|\r|\n)*?)/.source+o.match[r].source.replace(/\\(\d+)/g,q));var s=function(a,b){a=Array.prototype.slice.call(a,0);if(b){b.push.apply(b,a);return b}return a};try{Array.prototype.slice.call(c.documentElement.childNodes,0)[0].nodeType}catch(t){s=function(a,b){var c=0,d=b||[];if(g.call(a)==="[object Array]")Array.prototype.push.apply(d,a);else if(typeof a.length=="number")for(var e=a.length;c<e;c++)d.push(a[c]);else for(;a[c];c++)d.push(a[c]);return d}}var u,v;c.documentElement.compareDocumentPosition?u=function(a,b){if(a===b){h=!0;return 0}if(!a.compareDocumentPosition||!b.compareDocumentPosition)return a.compareDocumentPosition?-1:1;return a.compareDocumentPosition(b)&4?-1:1}:(u=function(a,b){if(a===b){h=!0;return 0}if(a.sourceIndex&&b.sourceIndex)return a.sourceIndex-b.sourceIndex;var c,d,e=[],f=[],g=a.parentNode,i=b.parentNode,j=g;if(g===i)return v(a,b);if(!g)return-1;if(!i)return 1;while(j)e.unshift(j),j=j.parentNode;j=i;while(j)f.unshift(j),j=j.parentNode;c=e.length,d=f.length;for(var k=0;k<c&&k<d;k++)if(e[k]!==f[k])return v(e[k],f[k]);return k===c?v(a,f[k],-1):v(e[k],b,1)},v=function(a,b,c){if(a===b)return c;var d=a.nextSibling;while(d){if(d===b)return-1;d=d.nextSibling}return 1}),function(){var a=c.createElement("div"),d="script"+(new Date).getTime(),e=c.documentElement;a.innerHTML="<a name='"+d+"'/>",e.insertBefore(a,e.firstChild),c.getElementById(d)&&(o.find.ID=function(a,c,d){if(typeof c.getElementById!="undefined"&&!d){var e=c.getElementById(a[1]);return e?e.id===a[1]||typeof e.getAttributeNode!="undefined"&&e.getAttributeNode("id").nodeValue===a[1]?[e]:b:[]}},o.filter.ID=function(a,b){var c=typeof a.getAttributeNode!="undefined"&&a.getAttributeNode("id");return a.nodeType===1&&c&&c.nodeValue===b}),e.removeChild(a),e=a=null}(),function(){var a=c.createElement("div");a.appendChild(c.createComment("")),a.getElementsByTagName("*").length>0&&(o.find.TAG=function(a,b){var c=b.getElementsByTagName(a[1]);if(a[1]==="*"){var d=[];for(var e=0;c[e];e++)c[e].nodeType===1&&d.push(c[e]);c=d}return c}),a.innerHTML="<a href='#'></a>",a.firstChild&&typeof a.firstChild.getAttribute!="undefined"&&a.firstChild.getAttribute("href")!=="#"&&(o.attrHandle.href=function(a){return a.getAttribute("href",2)}),a=null}(),c.querySelectorAll&&function(){var a=m,b=c.createElement("div"),d="__sizzle__";b.innerHTML="<p class='TEST'></p>";if(!b.querySelectorAll||b.querySelectorAll(".TEST").length!==0){m=function(b,e,f,g){e=e||c;if(!g&&!m.isXML(e)){var h=/^(\w+$)|^\.([\w\-]+$)|^#([\w\-]+$)/.exec(b);if(h&&(e.nodeType===1||e.nodeType===9)){if(h[1])return s(e.getElementsByTagName(b),f);if(h[2]&&o.find.CLASS&&e.getElementsByClassName)return s(e.getElementsByClassName(h[2]),f)}if(e.nodeType===9){if(b==="body"&&e.body)return s([e.body],f);if(h&&h[3]){var i=e.getElementById(h[3]);if(!i||!i.parentNode)return s([],f);if(i.id===h[3])return s([i],f)}try{return s(e.querySelectorAll(b),f)}catch(j){}}else if(e.nodeType===1&&e.nodeName.toLowerCase()!=="object"){var k=e,l=e.getAttribute("id"),n=l||d,p=e.parentNode,q=/^\s*[+~]/.test(b);l?n=n.replace(/'/g,"\\$&"):e.setAttribute("id",n),q&&p&&(e=e.parentNode);try{if(!q||p)return s(e.querySelectorAll("[id='"+n+"'] "+b),f)}catch(r){}finally{l||k.removeAttribute("id")}}}return a(b,e,f,g)};for(var e in a)m[e]=a[e];b=null}}(),function(){var a=c.documentElement,b=a.matchesSelector||a.mozMatchesSelector||a.webkitMatchesSelector||a.msMatchesSelector;if(b){var d=!b.call(c.createElement("div"),"div"),e=!1;try{b.call(c.documentElement,"[test!='']:sizzle")}catch(f){e=!0}m.matchesSelector=function(a,c){c=c.replace(/\=\s*([^'"\]]*)\s*\]/g,"='$1']");if(!m.isXML(a))try{if(e||!o.match.PSEUDO.test(c)&&!/!=/.test(c)){var f=b.call(a,c);if(f||!d||a.document&&a.document.nodeType!==11)return f}}catch(g){}return m(c,null,null,[a]).length>0}}}(),function(){var a=c.createElement("div");a.innerHTML="<div class='test e'></div><div class='test'></div>";if(!!a.getElementsByClassName&&a.getElementsByClassName("e").length!==0){a.lastChild.className="e";if(a.getElementsByClassName("e").length===1)return;o.order.splice(1,0,"CLASS"),o.find.CLASS=function(a,b,c){if(typeof b.getElementsByClassName!="undefined"&&!c)return b.getElementsByClassName(a[1])},a=null}}(),c.documentElement.contains?m.contains=function(a,b){return a!==b&&(a.contains?a.contains(b):!0)}:c.documentElement.compareDocumentPosition?m.contains=function(a,b){return!!(a.compareDocumentPosition(b)&16)}:m.contains=function(){return!1},m.isXML=function(a){var b=(a?a.ownerDocument||a:0).documentElement;return b?b.nodeName!=="HTML":!1};var y=function(a,b,c){var d,e=[],f="",g=b.nodeType?[b]:b;while(d=o.match.PSEUDO.exec(a))f+=d[0],a=a.replace(o.match.PSEUDO,"");a=o.relative[a]?a+"*":a;for(var h=0,i=g.length;h<i;h++)m(a,g[h],e,c);return m.filter(f,e)};m.attr=f.attr,m.selectors.attrMap={},f.find=m,f.expr=m.selectors,f.expr[":"]=f.expr.filters,f.unique=m.uniqueSort,f.text=m.getText,f.isXMLDoc=m.isXML,f.contains=m.contains}();var L=/Until$/,M=/^(?:parents|prevUntil|prevAll)/,N=/,/,O=/^.[^:#\[\.,]*$/,P=Array.prototype.slice,Q=f.expr.match.POS,R={children:!0,contents:!0,next:!0,prev:!0};f.fn.extend({find:function(a){var b=this,c,d;if(typeof a!="string")return f(a).filter(function(){for(c=0,d=b.length;c<d;c++)if(f.contains(b[c],this))return!0});var e=this.pushStack("","find",a),g,h,i;for(c=0,d=this.length;c<d;c++){g=e.length,f.find(a,this[c],e);if(c>0)for(h=g;h<e.length;h++)for(i=0;i<g;i++)if(e[i]===e[h]){e.splice(h--,1);break}}return e},has:function(a){var b=f(a);return this.filter(function(){for(var a=0,c=b.length;a<c;a++)if(f.contains(this,b[a]))return!0})},not:function(a){return this.pushStack(T(this,a,!1),"not",a)},filter:function(a){return this.pushStack(T(this,a,!0),"filter",a)},is:function(a){return!!a&&(typeof a=="string"?Q.test(a)?f(a,this.context).index(this[0])>=0:f.filter(a,this).length>0:this.filter(a).length>0)},closest:function(a,b){var c=[],d,e,g=this[0];if(f.isArray(a)){var h=1;while(g&&g.ownerDocument&&g!==b){for(d=0;d<a.length;d++)f(g).is(a[d])&&c.push({selector:a[d],elem:g,level:h});g=g.parentNode,h++}return c}var i=Q.test(a)||typeof a!="string"?f(a,b||this.context):0;for(d=0,e=this.length;d<e;d++){g=this[d];while(g){if(i?i.index(g)>-1:f.find.matchesSelector(g,a)){c.push(g);break}g=g.parentNode;if(!g||!g.ownerDocument||g===b||g.nodeType===11)break}}c=c.length>1?f.unique(c):c;return this.pushStack(c,"closest",a)},index:function(a){if(!a)return this[0]&&this[0].parentNode?this.prevAll().length:-1;if(typeof a=="string")return f.inArray(this[0],f(a));return f.inArray(a.jquery?a[0]:a,this)},add:function(a,b){var c=typeof a=="string"?f(a,b):f.makeArray(a&&a.nodeType?[a]:a),d=f.merge(this.get(),c);return this.pushStack(S(c[0])||S(d[0])?d:f.unique(d))},andSelf:function(){return this.add(this.prevObject)}}),f.each({parent:function(a){var b=a.parentNode;return b&&b.nodeType!==11?b:null},parents:function(a){return f.dir(a,"parentNode")},parentsUntil:function(a,b,c){return f.dir(a,"parentNode",c)},next:function(a){return f.nth(a,2,"nextSibling")},prev:function(a){return f.nth(a,2,"previousSibling")},nextAll:function(a){return f.dir(a,"nextSibling")},prevAll:function(a){return f.dir(a,"previousSibling")},nextUntil:function(a,b,c){return f.dir(a,"nextSibling",c)},prevUntil:function(a,b,c){return f.dir(a,"previousSibling",c)},siblings:function(a){return f.sibling(a.parentNode.firstChild,a)},children:function(a){return f.sibling(a.firstChild)},contents:function(a){return f.nodeName(a,"iframe")?a.contentDocument||a.contentWindow.document:f.makeArray(a.childNodes)}},function(a,b){f.fn[a]=function(c,d){var e=f.map(this,b,c);L.test(a)||(d=c),d&&typeof d=="string"&&(e=f.filter(d,e)),e=this.length>1&&!R[a]?f.unique(e):e,(this.length>1||N.test(d))&&M.test(a)&&(e=e.reverse());return this.pushStack(e,a,P.call(arguments).join(","))}}),f.extend({filter:function(a,b,c){c&&(a=":not("+a+")");return b.length===1?f.find.matchesSelector(b[0],a)?[b[0]]:[]:f.find.matches(a,b)},dir:function(a,c,d){var e=[],g=a[c];while(g&&g.nodeType!==9&&(d===b||g.nodeType!==1||!f(g).is(d)))g.nodeType===1&&e.push(g),g=g[c];return e},nth:function(a,b,c,d){b=b||1;var e=0;for(;a;a=a[c])if(a.nodeType===1&&++e===b)break;return a},sibling:function(a,b){var c=[];for(;a;a=a.nextSibling)a.nodeType===1&&a!==b&&c.push(a);return c}});var V="abbr|article|aside|audio|canvas|datalist|details|figcaption|figure|footer|header|hgroup|mark|meter|nav|output|progress|section|summary|time|video",W=/ jQuery\d+="(?:\d+|null)"/g,X=/^\s+/,Y=/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/ig,Z=/<([\w:]+)/,$=/<tbody/i,_=/<|&#?\w+;/,ba=/<(?:script|style)/i,bb=/<(?:script|object|embed|option|style)/i,bc=new RegExp("<(?:"+V+")","i"),bd=/checked\s*(?:[^=]|=\s*.checked.)/i,be=/\/(java|ecma)script/i,bf=/^\s*<!(?:\[CDATA\[|\-\-)/,bg={option:[1,"<select multiple='multiple'>","</select>"],legend:[1,"<fieldset>","</fieldset>"],thead:[1,"<table>","</table>"],tr:[2,"<table><tbody>","</tbody></table>"],td:[3,"<table><tbody><tr>","</tr></tbody></table>"],col:[2,"<table><tbody></tbody><colgroup>","</colgroup></table>"],area:[1,"<map>","</map>"],_default:[0,"",""]},bh=U(c);bg.optgroup=bg.option,bg.tbody=bg.tfoot=bg.colgroup=bg.caption=bg.thead,bg.th=bg.td,f.support.htmlSerialize||(bg._default=[1,"div<div>","</div>"]),f.fn.extend({text:function(a){if(f.isFunction(a))return this.each(function(b){var c=f(this);c.text(a.call(this,b,c.text()))});if(typeof a!="object"&&a!==b)return this.empty().append((this[0]&&this[0].ownerDocument||c).createTextNode(a));return f.text(this)},wrapAll:function(a){if(f.isFunction(a))return this.each(function(b){f(this).wrapAll(a.call(this,b))});if(this[0]){var b=f(a,this[0].ownerDocument).eq(0).clone(!0);this[0].parentNode&&b.insertBefore(this[0]),b.map(function(){var a=this;while(a.firstChild&&a.firstChild.nodeType===1)a=a.firstChild;return a}).append(this)}return this},wrapInner:function(a){if(f.isFunction(a))return this.each(function(b){f(this).wrapInner(a.call(this,b))});return this.each(function(){var b=f(this),c=b.contents();c.length?c.wrapAll(a):b.append(a)})},wrap:function(a){var b=f.isFunction(a);return this.each(function(c){f(this).wrapAll(b?a.call(this,c):a)})},unwrap:function(){return this.parent().each(function(){f.nodeName(this,"body")||f(this).replaceWith(this.childNodes)}).end()},append:function(){return this.domManip(arguments,!0,function(a){this.nodeType===1&&this.appendChild(a)})},prepend:function(){return this.domManip(arguments,!0,function(a){this.nodeType===1&&this.insertBefore(a,this.firstChild)})},before:function(){if(this[0]&&this[0].parentNode)return this.domManip(arguments,!1,function(a){this.parentNode.insertBefore(a,this)});if(arguments.length){var a=f.clean(arguments);a.push.apply(a,this.toArray());return this.pushStack(a,"before",arguments)}},after:function(){if(this[0]&&this[0].parentNode)return this.domManip(arguments,!1,function(a){this.parentNode.insertBefore(a,this.nextSibling)});if(arguments.length){var a=this.pushStack(this,"after",arguments);a.push.apply(a,f.clean(arguments));return a}},remove:function(a,b){for(var c=0,d;(d=this[c])!=null;c++)if(!a||f.filter(a,[d]).length)!b&&d.nodeType===1&&(f.cleanData(d.getElementsByTagName("*")),f.cleanData([d])),d.parentNode&&d.parentNode.removeChild(d);return this},empty:function()
+{for(var a=0,b;(b=this[a])!=null;a++){b.nodeType===1&&f.cleanData(b.getElementsByTagName("*"));while(b.firstChild)b.removeChild(b.firstChild)}return this},clone:function(a,b){a=a==null?!1:a,b=b==null?a:b;return this.map(function(){return f.clone(this,a,b)})},html:function(a){if(a===b)return this[0]&&this[0].nodeType===1?this[0].innerHTML.replace(W,""):null;if(typeof a=="string"&&!ba.test(a)&&(f.support.leadingWhitespace||!X.test(a))&&!bg[(Z.exec(a)||["",""])[1].toLowerCase()]){a=a.replace(Y,"<$1></$2>");try{for(var c=0,d=this.length;c<d;c++)this[c].nodeType===1&&(f.cleanData(this[c].getElementsByTagName("*")),this[c].innerHTML=a)}catch(e){this.empty().append(a)}}else f.isFunction(a)?this.each(function(b){var c=f(this);c.html(a.call(this,b,c.html()))}):this.empty().append(a);return this},replaceWith:function(a){if(this[0]&&this[0].parentNode){if(f.isFunction(a))return this.each(function(b){var c=f(this),d=c.html();c.replaceWith(a.call(this,b,d))});typeof a!="string"&&(a=f(a).detach());return this.each(function(){var b=this.nextSibling,c=this.parentNode;f(this).remove(),b?f(b).before(a):f(c).append(a)})}return this.length?this.pushStack(f(f.isFunction(a)?a():a),"replaceWith",a):this},detach:function(a){return this.remove(a,!0)},domManip:function(a,c,d){var e,g,h,i,j=a[0],k=[];if(!f.support.checkClone&&arguments.length===3&&typeof j=="string"&&bd.test(j))return this.each(function(){f(this).domManip(a,c,d,!0)});if(f.isFunction(j))return this.each(function(e){var g=f(this);a[0]=j.call(this,e,c?g.html():b),g.domManip(a,c,d)});if(this[0]){i=j&&j.parentNode,f.support.parentNode&&i&&i.nodeType===11&&i.childNodes.length===this.length?e={fragment:i}:e=f.buildFragment(a,this,k),h=e.fragment,h.childNodes.length===1?g=h=h.firstChild:g=h.firstChild;if(g){c=c&&f.nodeName(g,"tr");for(var l=0,m=this.length,n=m-1;l<m;l++)d.call(c?bi(this[l],g):this[l],e.cacheable||m>1&&l<n?f.clone(h,!0,!0):h)}k.length&&f.each(k,bp)}return this}}),f.buildFragment=function(a,b,d){var e,g,h,i,j=a[0];b&&b[0]&&(i=b[0].ownerDocument||b[0]),i.createDocumentFragment||(i=c),a.length===1&&typeof j=="string"&&j.length<512&&i===c&&j.charAt(0)==="<"&&!bb.test(j)&&(f.support.checkClone||!bd.test(j))&&(f.support.html5Clone||!bc.test(j))&&(g=!0,h=f.fragments[j],h&&h!==1&&(e=h)),e||(e=i.createDocumentFragment(),f.clean(a,i,e,d)),g&&(f.fragments[j]=h?e:1);return{fragment:e,cacheable:g}},f.fragments={},f.each({appendTo:"append",prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},function(a,b){f.fn[a]=function(c){var d=[],e=f(c),g=this.length===1&&this[0].parentNode;if(g&&g.nodeType===11&&g.childNodes.length===1&&e.length===1){e[b](this[0]);return this}for(var h=0,i=e.length;h<i;h++){var j=(h>0?this.clone(!0):this).get();f(e[h])[b](j),d=d.concat(j)}return this.pushStack(d,a,e.selector)}}),f.extend({clone:function(a,b,c){var d,e,g,h=f.support.html5Clone||!bc.test("<"+a.nodeName)?a.cloneNode(!0):bo(a);if((!f.support.noCloneEvent||!f.support.noCloneChecked)&&(a.nodeType===1||a.nodeType===11)&&!f.isXMLDoc(a)){bk(a,h),d=bl(a),e=bl(h);for(g=0;d[g];++g)e[g]&&bk(d[g],e[g])}if(b){bj(a,h);if(c){d=bl(a),e=bl(h);for(g=0;d[g];++g)bj(d[g],e[g])}}d=e=null;return h},clean:function(a,b,d,e){var g;b=b||c,typeof b.createElement=="undefined"&&(b=b.ownerDocument||b[0]&&b[0].ownerDocument||c);var h=[],i;for(var j=0,k;(k=a[j])!=null;j++){typeof k=="number"&&(k+="");if(!k)continue;if(typeof k=="string")if(!_.test(k))k=b.createTextNode(k);else{k=k.replace(Y,"<$1></$2>");var l=(Z.exec(k)||["",""])[1].toLowerCase(),m=bg[l]||bg._default,n=m[0],o=b.createElement("div");b===c?bh.appendChild(o):U(b).appendChild(o),o.innerHTML=m[1]+k+m[2];while(n--)o=o.lastChild;if(!f.support.tbody){var p=$.test(k),q=l==="table"&&!p?o.firstChild&&o.firstChild.childNodes:m[1]==="<table>"&&!p?o.childNodes:[];for(i=q.length-1;i>=0;--i)f.nodeName(q[i],"tbody")&&!q[i].childNodes.length&&q[i].parentNode.removeChild(q[i])}!f.support.leadingWhitespace&&X.test(k)&&o.insertBefore(b.createTextNode(X.exec(k)[0]),o.firstChild),k=o.childNodes}var r;if(!f.support.appendChecked)if(k[0]&&typeof (r=k.length)=="number")for(i=0;i<r;i++)bn(k[i]);else bn(k);k.nodeType?h.push(k):h=f.merge(h,k)}if(d){g=function(a){return!a.type||be.test(a.type)};for(j=0;h[j];j++)if(e&&f.nodeName(h[j],"script")&&(!h[j].type||h[j].type.toLowerCase()==="text/javascript"))e.push(h[j].parentNode?h[j].parentNode.removeChild(h[j]):h[j]);else{if(h[j].nodeType===1){var s=f.grep(h[j].getElementsByTagName("script"),g);h.splice.apply(h,[j+1,0].concat(s))}d.appendChild(h[j])}}return h},cleanData:function(a){var b,c,d=f.cache,e=f.event.special,g=f.support.deleteExpando;for(var h=0,i;(i=a[h])!=null;h++){if(i.nodeName&&f.noData[i.nodeName.toLowerCase()])continue;c=i[f.expando];if(c){b=d[c];if(b&&b.events){for(var j in b.events)e[j]?f.event.remove(i,j):f.removeEvent(i,j,b.handle);b.handle&&(b.handle.elem=null)}g?delete i[f.expando]:i.removeAttribute&&i.removeAttribute(f.expando),delete d[c]}}}});var bq=/alpha\([^)]*\)/i,br=/opacity=([^)]*)/,bs=/([A-Z]|^ms)/g,bt=/^-?\d+(?:px)?$/i,bu=/^-?\d/,bv=/^([\-+])=([\-+.\de]+)/,bw={position:"absolute",visibility:"hidden",display:"block"},bx=["Left","Right"],by=["Top","Bottom"],bz,bA,bB;f.fn.css=function(a,c){if(arguments.length===2&&c===b)return this;return f.access(this,a,c,!0,function(a,c,d){return d!==b?f.style(a,c,d):f.css(a,c)})},f.extend({cssHooks:{opacity:{get:function(a,b){if(b){var c=bz(a,"opacity","opacity");return c===""?"1":c}return a.style.opacity}}},cssNumber:{fillOpacity:!0,fontWeight:!0,lineHeight:!0,opacity:!0,orphans:!0,widows:!0,zIndex:!0,zoom:!0},cssProps:{"float":f.support.cssFloat?"cssFloat":"styleFloat"},style:function(a,c,d,e){if(!!a&&a.nodeType!==3&&a.nodeType!==8&&!!a.style){var g,h,i=f.camelCase(c),j=a.style,k=f.cssHooks[i];c=f.cssProps[i]||i;if(d===b){if(k&&"get"in k&&(g=k.get(a,!1,e))!==b)return g;return j[c]}h=typeof d,h==="string"&&(g=bv.exec(d))&&(d=+(g[1]+1)*+g[2]+parseFloat(f.css(a,c)),h="number");if(d==null||h==="number"&&isNaN(d))return;h==="number"&&!f.cssNumber[i]&&(d+="px");if(!k||!("set"in k)||(d=k.set(a,d))!==b)try{j[c]=d}catch(l){}}},css:function(a,c,d){var e,g;c=f.camelCase(c),g=f.cssHooks[c],c=f.cssProps[c]||c,c==="cssFloat"&&(c="float");if(g&&"get"in g&&(e=g.get(a,!0,d))!==b)return e;if(bz)return bz(a,c)},swap:function(a,b,c){var d={};for(var e in b)d[e]=a.style[e],a.style[e]=b[e];c.call(a);for(e in b)a.style[e]=d[e]}}),f.curCSS=f.css,f.each(["height","width"],function(a,b){f.cssHooks[b]={get:function(a,c,d){var e;if(c){if(a.offsetWidth!==0)return bC(a,b,d);f.swap(a,bw,function(){e=bC(a,b,d)});return e}},set:function(a,b){if(!bt.test(b))return b;b=parseFloat(b);if(b>=0)return b+"px"}}}),f.support.opacity||(f.cssHooks.opacity={get:function(a,b){return br.test((b&&a.currentStyle?a.currentStyle.filter:a.style.filter)||"")?parseFloat(RegExp.$1)/100+"":b?"1":""},set:function(a,b){var c=a.style,d=a.currentStyle,e=f.isNumeric(b)?"alpha(opacity="+b*100+")":"",g=d&&d.filter||c.filter||"";c.zoom=1;if(b>=1&&f.trim(g.replace(bq,""))===""){c.removeAttribute("filter");if(d&&!d.filter)return}c.filter=bq.test(g)?g.replace(bq,e):g+" "+e}}),f(function(){f.support.reliableMarginRight||(f.cssHooks.marginRight={get:function(a,b){var c;f.swap(a,{display:"inline-block"},function(){b?c=bz(a,"margin-right","marginRight"):c=a.style.marginRight});return c}})}),c.defaultView&&c.defaultView.getComputedStyle&&(bA=function(a,b){var c,d,e;b=b.replace(bs,"-$1").toLowerCase(),(d=a.ownerDocument.defaultView)&&(e=d.getComputedStyle(a,null))&&(c=e.getPropertyValue(b),c===""&&!f.contains(a.ownerDocument.documentElement,a)&&(c=f.style(a,b)));return c}),c.documentElement.currentStyle&&(bB=function(a,b){var c,d,e,f=a.currentStyle&&a.currentStyle[b],g=a.style;f===null&&g&&(e=g[b])&&(f=e),!bt.test(f)&&bu.test(f)&&(c=g.left,d=a.runtimeStyle&&a.runtimeStyle.left,d&&(a.runtimeStyle.left=a.currentStyle.left),g.left=b==="fontSize"?"1em":f||0,f=g.pixelLeft+"px",g.left=c,d&&(a.runtimeStyle.left=d));return f===""?"auto":f}),bz=bA||bB,f.expr&&f.expr.filters&&(f.expr.filters.hidden=function(a){var b=a.offsetWidth,c=a.offsetHeight;return b===0&&c===0||!f.support.reliableHiddenOffsets&&(a.style&&a.style.display||f.css(a,"display"))==="none"},f.expr.filters.visible=function(a){return!f.expr.filters.hidden(a)});var bD=/%20/g,bE=/\[\]$/,bF=/\r?\n/g,bG=/#.*$/,bH=/^(.*?):[ \t]*([^\r\n]*)\r?$/mg,bI=/^(?:color|date|datetime|datetime-local|email|hidden|month|number|password|range|search|tel|text|time|url|week)$/i,bJ=/^(?:about|app|app\-storage|.+\-extension|file|res|widget):$/,bK=/^(?:GET|HEAD)$/,bL=/^\/\//,bM=/\?/,bN=/<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/gi,bO=/^(?:select|textarea)/i,bP=/\s+/,bQ=/([?&])_=[^&]*/,bR=/^([\w\+\.\-]+:)(?:\/\/([^\/?#:]*)(?::(\d+))?)?/,bS=f.fn.load,bT={},bU={},bV,bW,bX=["*/"]+["*"];try{bV=e.href}catch(bY){bV=c.createElement("a"),bV.href="",bV=bV.href}bW=bR.exec(bV.toLowerCase())||[],f.fn.extend({load:function(a,c,d){if(typeof a!="string"&&bS)return bS.apply(this,arguments);if(!this.length)return this;var e=a.indexOf(" ");if(e>=0){var g=a.slice(e,a.length);a=a.slice(0,e)}var h="GET";c&&(f.isFunction(c)?(d=c,c=b):typeof c=="object"&&(c=f.param(c,f.ajaxSettings.traditional),h="POST"));var i=this;f.ajax({url:a,type:h,dataType:"html",data:c,complete:function(a,b,c){c=a.responseText,a.isResolved()&&(a.done(function(a){c=a}),i.html(g?f("<div>").append(c.replace(bN,"")).find(g):c)),d&&i.each(d,[c,b,a])}});return this},serialize:function(){return f.param(this.serializeArray())},serializeArray:function(){return this.map(function(){return this.elements?f.makeArray(this.elements):this}).filter(function(){return this.name&&!this.disabled&&(this.checked||bO.test(this.nodeName)||bI.test(this.type))}).map(function(a,b){var c=f(this).val();return c==null?null:f.isArray(c)?f.map(c,function(a,c){return{name:b.name,value:a.replace(bF,"\r\n")}}):{name:b.name,value:c.replace(bF,"\r\n")}}).get()}}),f.each("ajaxStart ajaxStop ajaxComplete ajaxError ajaxSuccess ajaxSend".split(" "),function(a,b){f.fn[b]=function(a){return this.on(b,a)}}),f.each(["get","post"],function(a,c){f[c]=function(a,d,e,g){f.isFunction(d)&&(g=g||e,e=d,d=b);return f.ajax({type:c,url:a,data:d,success:e,dataType:g})}}),f.extend({getScript:function(a,c){return f.get(a,b,c,"script")},getJSON:function(a,b,c){return f.get(a,b,c,"json")},ajaxSetup:function(a,b){b?b_(a,f.ajaxSettings):(b=a,a=f.ajaxSettings),b_(a,b);return a},ajaxSettings:{url:bV,isLocal:bJ.test(bW[1]),global:!0,type:"GET",contentType:"application/x-www-form-urlencoded",processData:!0,async:!0,accepts:{xml:"application/xml, text/xml",html:"text/html",text:"text/plain",json:"application/json, text/javascript","*":bX},contents:{xml:/xml/,html:/html/,json:/json/},responseFields:{xml:"responseXML",text:"responseText"},converters:{"* text":a.String,"text html":!0,"text json":f.parseJSON,"text xml":f.parseXML},flatOptions:{context:!0,url:!0}},ajaxPrefilter:bZ(bT),ajaxTransport:bZ(bU),ajax:function(a,c){function w(a,c,l,m){if(s!==2){s=2,q&&clearTimeout(q),p=b,n=m||"",v.readyState=a>0?4:0;var o,r,u,w=c,x=l?cb(d,v,l):b,y,z;if(a>=200&&a<300||a===304){if(d.ifModified){if(y=v.getResponseHeader("Last-Modified"))f.lastModified[k]=y;if(z=v.getResponseHeader("Etag"))f.etag[k]=z}if(a===304)w="notmodified",o=!0;else try{r=cc(d,x),w="success",o=!0}catch(A){w="parsererror",u=A}}else{u=w;if(!w||a)w="error",a<0&&(a=0)}v.status=a,v.statusText=""+(c||w),o?h.resolveWith(e,[r,w,v]):h.rejectWith(e,[v,w,u]),v.statusCode(j),j=b,t&&g.trigger("ajax"+(o?"Success":"Error"),[v,d,o?r:u]),i.fireWith(e,[v,w]),t&&(g.trigger("ajaxComplete",[v,d]),--f.active||f.event.trigger("ajaxStop"))}}typeof a=="object"&&(c=a,a=b),c=c||{};var d=f.ajaxSetup({},c),e=d.context||d,g=e!==d&&(e.nodeType||e instanceof f)?f(e):f.event,h=f.Deferred(),i=f.Callbacks("once memory"),j=d.statusCode||{},k,l={},m={},n,o,p,q,r,s=0,t,u,v={readyState:0,setRequestHeader:function(a,b){if(!s){var c=a.toLowerCase();a=m[c]=m[c]||a,l[a]=b}return this},getAllResponseHeaders:function(){return s===2?n:null},getResponseHeader:function(a){var c;if(s===2){if(!o){o={};while(c=bH.exec(n))o[c[1].toLowerCase()]=c[2]}c=o[a.toLowerCase()]}return c===b?null:c},overrideMimeType:function(a){s||(d.mimeType=a);return this},abort:function(a){a=a||"abort",p&&p.abort(a),w(0,a);return this}};h.promise(v),v.success=v.done,v.error=v.fail,v.complete=i.add,v.statusCode=function(a){if(a){var b;if(s<2)for(b in a)j[b]=[j[b],a[b]];else b=a[v.status],v.then(b,b)}return this},d.url=((a||d.url)+"").replace(bG,"").replace(bL,bW[1]+"//"),d.dataTypes=f.trim(d.dataType||"*").toLowerCase().split(bP),d.crossDomain==null&&(r=bR.exec(d.url.toLowerCase()),d.crossDomain=!(!r||r[1]==bW[1]&&r[2]==bW[2]&&(r[3]||(r[1]==="http:"?80:443))==(bW[3]||(bW[1]==="http:"?80:443)))),d.data&&d.processData&&typeof d.data!="string"&&(d.data=f.param(d.data,d.traditional)),b$(bT,d,c,v);if(s===2)return!1;t=d.global,d.type=d.type.toUpperCase(),d.hasContent=!bK.test(d.type),t&&f.active++===0&&f.event.trigger("ajaxStart");if(!d.hasContent){d.data&&(d.url+=(bM.test(d.url)?"&":"?")+d.data,delete d.data),k=d.url;if(d.cache===!1){var x=f.now(),y=d.url.replace(bQ,"$1_="+x);d.url=y+(y===d.url?(bM.test(d.url)?"&":"?")+"_="+x:"")}}(d.data&&d.hasContent&&d.contentType!==!1||c.contentType)&&v.setRequestHeader("Content-Type",d.contentType),d.ifModified&&(k=k||d.url,f.lastModified[k]&&v.setRequestHeader("If-Modified-Since",f.lastModified[k]),f.etag[k]&&v.setRequestHeader("If-None-Match",f.etag[k])),v.setRequestHeader("Accept",d.dataTypes[0]&&d.accepts[d.dataTypes[0]]?d.accepts[d.dataTypes[0]]+(d.dataTypes[0]!=="*"?", "+bX+"; q=0.01":""):d.accepts["*"]);for(u in d.headers)v.setRequestHeader(u,d.headers[u]);if(d.beforeSend&&(d.beforeSend.call(e,v,d)===!1||s===2)){v.abort();return!1}for(u in{success:1,error:1,complete:1})v[u](d[u]);p=b$(bU,d,c,v);if(!p)w(-1,"No Transport");else{v.readyState=1,t&&g.trigger("ajaxSend",[v,d]),d.async&&d.timeout>0&&(q=setTimeout(function(){v.abort("timeout")},d.timeout));try{s=1,p.send(l,w)}catch(z){if(s<2)w(-1,z);else throw z}}return v},param:function(a,c){var d=[],e=function(a,b){b=f.isFunction(b)?b():b,d[d.length]=encodeURIComponent(a)+"="+encodeURIComponent(b)};c===b&&(c=f.ajaxSettings.traditional);if(f.isArray(a)||a.jquery&&!f.isPlainObject(a))f.each(a,function(){e(this.name,this.value)});else for(var g in a)ca(g,a[g],c,e);return d.join("&").replace(bD,"+")}}),f.extend({active:0,lastModified:{},etag:{}});var cd=f.now(),ce=/(\=)\?(&|$)|\?\?/i;f.ajaxSetup({jsonp:"callback",jsonpCallback:function(){return f.expando+"_"+cd++}}),f.ajaxPrefilter("json jsonp",function(b,c,d){var e=b.contentType==="application/x-www-form-urlencoded"&&typeof b.data=="string";if(b.dataTypes[0]==="jsonp"||b.jsonp!==!1&&(ce.test(b.url)||e&&ce.test(b.data))){var g,h=b.jsonpCallback=f.isFunction(b.jsonpCallback)?b.jsonpCallback():b.jsonpCallback,i=a[h],j=b.url,k=b.data,l="$1"+h+"$2";b.jsonp!==!1&&(j=j.replace(ce,l),b.url===j&&(e&&(k=k.replace(ce,l)),b.data===k&&(j+=(/\?/.test(j)?"&":"?")+b.jsonp+"="+h))),b.url=j,b.data=k,a[h]=function(a){g=[a]},d.always(function(){a[h]=i,g&&f.isFunction(i)&&a[h](g[0])}),b.converters["script json"]=function(){g||f.error(h+" was not called");return g[0]},b.dataTypes[0]="json";return"script"}}),f.ajaxSetup({accepts:{script:"text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"},contents:{script:/javascript|ecmascript/},converters:{"text script":function(a){f.globalEval(a);return a}}}),f.ajaxPrefilter("script",function(a){a.cache===b&&(a.cache=!1),a.crossDomain&&(a.type="GET",a.global=!1)}),f.ajaxTransport("script",function(a){if(a.crossDomain){var d,e=c.head||c.getElementsByTagName("head")[0]||c.documentElement;return{send:function(f,g){d=c.createElement("script"),d.async="async",a.scriptCharset&&(d.charset=a.scriptCharset),d.src=a.url,d.onload=d.onreadystatechange=function(a,c){if(c||!d.readyState||/loaded|complete/.test(d.readyState))d.onload=d.onreadystatechange=null,e&&d.parentNode&&e.removeChild(d),d=b,c||g(200,"success")},e.insertBefore(d,e.firstChild)},abort:function(){d&&d.onload(0,1)}}}});var cf=a.ActiveXObject?function(){for(var a in ch)ch[a](0,1)}:!1,cg=0,ch;f.ajaxSettings.xhr=a.ActiveXObject?function(){return!this.isLocal&&ci()||cj()}:ci,function(a){f.extend(f.support,{ajax:!!a,cors:!!a&&"withCredentials"in a})}(f.ajaxSettings.xhr()),f.support.ajax&&f.ajaxTransport(function(c){if(!c.crossDomain||f.support.cors){var d;return{send:function(e,g){var h=c.xhr(),i,j;c.username?h.open(c.type,c.url,c.async,c.username,c.password):h.open(c.type,c.url,c.async);if(c.xhrFields)for(j in c.xhrFields)h[j]=c.xhrFields[j];c.mimeType&&h.overrideMimeType&&h.overrideMimeType(c.mimeType),!c.crossDomain&&!e["X-Requested-With"]&&(e["X-Requested-With"]="XMLHttpRequest");try{for(j in e)h.setRequestHeader(j,e[j])}catch(k){}h.send(c.hasContent&&c.data||null),d=function(a,e){var j,k,l,m,n;try{if(d&&(e||h.readyState===4)){d=b,i&&(h.onreadystatechange=f.noop,cf&&delete ch[i]);if(e)h.readyState!==4&&h.abort();else{j=h.status,l=h.getAllResponseHeaders(),m={},n=h.responseXML,n&&n.documentElement&&(m.xml=n),m.text=h.responseText;try{k=h.statusText}catch(o){k=""}!j&&c.isLocal&&!c.crossDomain?j=m.text?200:404:j===1223&&(j=204)}}}catch(p){e||g(-1,p)}m&&g(j,k,m,l)},!c.async||h.readyState===4?d():(i=++cg,cf&&(ch||(ch={},f(a).unload(cf)),ch[i]=d),h.onreadystatechange=d)},abort:function(){d&&d(0,1)}}}});var ck={},cl,cm,cn=/^(?:toggle|show|hide)$/,co=/^([+\-]=)?([\d+.\-]+)([a-z%]*)$/i,cp,cq=[["height","marginTop","marginBottom","paddingTop","paddingBottom"],["width","marginLeft","marginRight","paddingLeft","paddingRight"],["opacity"]],cr;f.fn.extend({show:function(a,b,c){var d,e;if(a||a===0)return this.animate(cu("show",3),a,b,c);for(var g=0,h=this.length;g<h;g++)d=this[g],d.style&&(e=d.style.display,!f._data(d,"olddisplay")&&e==="none"&&(e=d.style.display=""),e===""&&f.css(d,"display")==="none"&&f._data(d,"olddisplay",cv(d.nodeName)));for(g=0;g<h;g++){d=this[g];if(d.style){e=d.style.display;if(e===""||e==="none")d.style.display=f._data(d,"olddisplay")||""}}return this},hide:function(a,b,c){if(a||a===0)return this.animate(cu("hide",3),a,b,c);var d,e,g=0,h=this.length;for(;g<h;g++)d=this[g],d.style&&(e=f.css(d,"display"),e!=="none"&&!f._data(d,"olddisplay")&&f._data(d,"olddisplay",e));for(g=0;g<h;g++)this[g].style&&(this[g].style.display="none");return this},_toggle:f.fn.toggle,toggle:function(a,b,c){var d=typeof a=="boolean";f.isFunction(a)&&f.isFunction(b)?this._toggle.apply(this,arguments):a==null||d?this.each(function(){var b=d?a:f(this).is(":hidden");f(this)[b?"show":"hide"]()}):this.animate(cu("toggle",3),a,b,c);return this},fadeTo:function(a,b,c,d){return this.filter(":hidden").css("opacity",0).show().end().animate({opacity:b},a,c,d)},animate:function(a,b,c,d){function g(){e.queue===!1&&f._mark(this);var b=f.extend({},e),c=this.nodeType===1,d=c&&f(this).is(":hidden"),g,h,i,j,k,l,m,n,o;b.animatedProperties={};for(i in a){g=f.camelCase(i),i!==g&&(a[g]=a[i],delete a[i]),h=a[g],f.isArray(h)?(b.animatedProperties[g]=h[1],h=a[g]=h[0]):b.animatedProperties[g]=b.specialEasing&&b.specialEasing[g]||b.easing||"swing";if(h==="hide"&&d||h==="show"&&!d)return b.complete.call(this);c&&(g==="height"||g==="width")&&(b.overflow=[this.style.overflow,this.style.overflowX,this.style.overflowY],f.css(this,"display")==="inline"&&f.css(this,"float")==="none"&&(!f.support.inlineBlockNeedsLayout||cv(this.nodeName)==="inline"?this.style.display="inline-block":this.style.zoom=1))}b.overflow!=null&&(this.style.overflow="hidden");for(i in a)j=new f.fx(this,b,i),h=a[i],cn.test(h)?(o=f._data(this,"toggle"+i)||(h==="toggle"?d?"show":"hide":0),o?(f._data(this,"toggle"+i,o==="show"?"hide":"show"),j[o]()):j[h]()):(k=co.exec(h),l=j.cur(),k?(m=parseFloat(k[2]),n=k[3]||(f.cssNumber[i]?"":"px"),n!=="px"&&(f.style(this,i,(m||1)+n),l=(m||1)/j.cur()*l,f.style(this,i,l+n)),k[1]&&(m=(k[1]==="-="?-1:1)*m+l),j.custom(l,m,n)):j.custom(l,h,""));return!0}var e=f.speed(b,c,d);if(f.isEmptyObject(a))return this.each(e.complete,[!1]);a=f.extend({},a);return e.queue===!1?this.each(g):this.queue(e.queue,g)},stop:function(a,c,d){typeof a!="string"&&(d=c,c=a,a=b),c&&a!==!1&&this.queue(a||"fx",[]);return this.each(function(){function h(a,b,c){var e=b[c];f.removeData(a,c,!0),e.stop(d)}var b,c=!1,e=f.timers,g=f._data(this);d||f._unmark(!0,this);if(a==null)for(b in g)g[b]&&g[b].stop&&b.indexOf(".run")===b.length-4&&h(this,g,b);else g[b=a+".run"]&&g[b].stop&&h(this,g,b);for(b=e.length;b--;)e[b].elem===this&&(a==null||e[b].queue===a)&&(d?e[b](!0):e[b].saveState(),c=!0,e.splice(b,1));(!d||!c)&&f.dequeue(this,a)})}}),f.each({slideDown:cu("show",1),slideUp:cu("hide",1),slideToggle:cu("toggle",1),fadeIn:{opacity:"show"},fadeOut:{opacity:"hide"},fadeToggle:{opacity:"toggle"}},function(a,b){f.fn[a]=function(a,c,d){return this.animate(b,a,c,d)}}),f.extend({speed:function(a,b,c){var d=a&&typeof a=="object"?f.extend({},a):{complete:c||!c&&b||f.isFunction(a)&&a,duration:a,easing:c&&b||b&&!f.isFunction(b)&&b};d.duration=f.fx.off?0:typeof d.duration=="number"?d.duration:d.duration in f.fx.speeds?f.fx.speeds[d.duration]:f.fx.speeds._default;if(d.queue==null||d.queue===!0)d.queue="fx";d.old=d.complete,d.complete=function(a){f.isFunction(d.old)&&d.old.call(this),d.queue?f.dequeue(this,d.queue):a!==!1&&f._unmark(this)};return d},easing:{linear:function(a,b,c,d){return c+d*a},swing:function(a,b,c,d){return(-Math.cos(a*Math.PI)/2+.5)*d+c}},timers:[],fx:function(a,b,c){this.options=b,this.elem=a,this.prop=c,b.orig=b.orig||{}}}),f.fx.prototype={update:function(){this.options.step&&this.options.step.call(this.elem,this.now,this),(f.fx.step[this.prop]||f.fx.step._default)(this)},cur:function(){if(this.elem[this.prop]!=null&&(!this.elem.style||this.elem.style[this.prop]==null))return this.elem[this.prop];var a,b=f.css(this.elem,this.prop);return isNaN(a=parseFloat(b))?!b||b==="auto"?0:b:a},custom:function(a,c,d){function h(a){return e.step(a)}var e=this,g=f.fx;this.startTime=cr||cs(),this.end=c,this.now=this.start=a,this.pos=this.state=0,this.unit=d||this.unit||(f.cssNumber[this.prop]?"":"px"),h.queue=this.options.queue,h.elem=this.elem,h.saveState=function(){e.options.hide&&f._data(e.elem,"fxshow"+e.prop)===b&&f._data(e.elem,"fxshow"+e.prop,e.start)},h()&&f.timers.push(h)&&!cp&&(cp=setInterval(g.tick,g.interval))},show:function(){var a=f._data(this.elem,"fxshow"+this.prop);this.options.orig[this.prop]=a||f.style(this.elem,this.prop),this.options.show=!0,a!==b?this.custom(this.cur(),a):this.custom(this.prop==="width"||this.prop==="height"?1:0,this.cur()),f(this.elem).show()},hide:function(){this.options.orig[this.prop]=f._data(this.elem,"fxshow"+this.prop)||f.style(this.elem,this.prop),this.options.hide=!0,this.custom(this.cur(),0)},step:function(a){var b,c,d,e=cr||cs(),g=!0,h=this.elem,i=this.options;if(a||e>=i.duration+this.startTime){this.now=this.end,this.pos=this.state=1,this.update(),i.animatedProperties[this.prop]=!0;for(b in i.animatedProperties)i.animatedProperties[b]!==!0&&(g=!1);if(g){i.overflow!=null&&!f.support.shrinkWrapBlocks&&f.each(["","X","Y"],function(a,b){h.style["overflow"+b]=i.overflow[a]}),i.hide&&f(h).hide();if(i.hide||i.show)for(b in i.animatedProperties)f.style(h,b,i.orig[b]),f.removeData(h,"fxshow"+b,!0),f.removeData(h,"toggle"+b,!0);d=i.complete,d&&(i.complete=!1,d.call(h))}return!1}i.duration==Infinity?this.now=e:(c=e-this.startTime,this.state=c/i.duration,this.pos=f.easing[i.animatedProperties[this.prop]](this.state,c,0,1,i.duration),this.now=this.start+(this.end-this.start)*this.pos),this.update();return!0}},f.extend(f.fx,{tick:function(){var a,b=f.timers,c=0;for(;c<b.length;c++)a=b[c],!a()&&b[c]===a&&b.splice(c--,1);b.length||f.fx.stop()},interval:13,stop:function(){clearInterval(cp),cp=null},speeds:{slow:600,fast:200,_default:400},step:{opacity:function(a){f.style(a.elem,"opacity",a.now)},_default:function(a){a.elem.style&&a.elem.style[a.prop]!=null?a.elem.style[a.prop]=a.now+a.unit:a.elem[a.prop]=a.now}}}),f.each(["width","height"],function(a,b){f.fx.step[b]=function(a){f.style(a.elem,b,Math.max(0,a.now)+a.unit)}}),f.expr&&f.expr.filters&&(f.expr.filters.animated=function(a){return f.grep(f.timers,function(b){return a===b.elem}).length});var cw=/^t(?:able|d|h)$/i,cx=/^(?:body|html)$/i;"getBoundingClientRect"in c.documentElement?f.fn.offset=function(a){var b=this[0],c;if(a)return this.each(function(b){f.offset.setOffset(this,a,b)});if(!b||!b.ownerDocument)return null;if(b===b.ownerDocument.body)return f.offset.bodyOffset(b);try{c=b.getBoundingClientRect()}catch(d){}var e=b.ownerDocument,g=e.documentElement;if(!c||!f.contains(g,b))return c?{top:c.top,left:c.left}:{top:0,left:0};var h=e.body,i=cy(e),j=g.clientTop||h.clientTop||0,k=g.clientLeft||h.clientLeft||0,l=i.pageYOffset||f.support.boxModel&&g.scrollTop||h.scrollTop,m=i.pageXOffset||f.support.boxModel&&g.scrollLeft||h.scrollLeft,n=c.top+l-j,o=c.left+m-k;return{top:n,left:o}}:f.fn.offset=function(a){var b=this[0];if(a)return this.each(function(b){f.offset.setOffset(this,a,b)});if(!b||!b.ownerDocument)return null;if(b===b.ownerDocument.body)return f.offset.bodyOffset(b);var c,d=b.offsetParent,e=b,g=b.ownerDocument,h=g.documentElement,i=g.body,j=g.defaultView,k=j?j.getComputedStyle(b,null):b.currentStyle,l=b.offsetTop,m=b.offsetLeft;while((b=b.parentNode)&&b!==i&&b!==h){if(f.support.fixedPosition&&k.position==="fixed")break;c=j?j.getComputedStyle(b,null):b.currentStyle,l-=b.scrollTop,m-=b.scrollLeft,b===d&&(l+=b.offsetTop,m+=b.offsetLeft,f.support.doesNotAddBorder&&(!f.support.doesAddBorderForTableAndCells||!cw.test(b.nodeName))&&(l+=parseFloat(c.borderTopWidth)||0,m+=parseFloat(c.borderLeftWidth)||0),e=d,d=b.offsetParent),f.support.subtractsBorderForOverflowNotVisible&&c.overflow!=="visible"&&(l+=parseFloat(c.borderTopWidth)||0,m+=parseFloat(c.borderLeftWidth)||0),k=c}if(k.position==="relative"||k.position==="static")l+=i.offsetTop,m+=i.offsetLeft;f.support.fixedPosition&&k.position==="fixed"&&(l+=Math.max(h.scrollTop,i.scrollTop),m+=Math.max(h.scrollLeft,i.scrollLeft));return{top:l,left:m}},f.offset={bodyOffset:function(a){var b=a.offsetTop,c=a.offsetLeft;f.support.doesNotIncludeMarginInBodyOffset&&(b+=parseFloat(f.css(a,"marginTop"))||0,c+=parseFloat(f.css(a,"marginLeft"))||0);return{top:b,left:c}},setOffset:function(a,b,c){var d=f.css(a,"position");d==="static"&&(a.style.position="relative");var e=f(a),g=e.offset(),h=f.css(a,"top"),i=f.css(a,"left"),j=(d==="absolute"||d==="fixed")&&f.inArray("auto",[h,i])>-1,k={},l={},m,n;j?(l=e.position(),m=l.top,n=l.left):(m=parseFloat(h)||0,n=parseFloat(i)||0),f.isFunction(b)&&(b=b.call(a,c,g)),b.top!=null&&(k.top=b.top-g.top+m),b.left!=null&&(k.left=b.left-g.left+n),"using"in b?b.using.call(a,k):e.css(k)}},f.fn.extend({position:function(){if(!this[0])return null;var a=this[0],b=this.offsetParent(),c=this.offset(),d=cx.test(b[0].nodeName)?{top:0,left:0}:b.offset();c.top-=parseFloat(f.css(a,"marginTop"))||0,c.left-=parseFloat(f.css(a,"marginLeft"))||0,d.top+=parseFloat(f.css(b[0],"borderTopWidth"))||0,d.left+=parseFloat(f.css(b[0],"borderLeftWidth"))||0;return{top:c.top-d.top,left:c.left-d.left}},offsetParent:function(){return this.map(function(){var a=this.offsetParent||c.body;while(a&&!cx.test(a.nodeName)&&f.css(a,"position")==="static")a=a.offsetParent;return a})}}),f.each(["Left","Top"],function(a,c){var d="scroll"+c;f.fn[d]=function(c){var e,g;if(c===b){e=this[0];if(!e)return null;g=cy(e);return g?"pageXOffset"in g?g[a?"pageYOffset":"pageXOffset"]:f.support.boxModel&&g.document.documentElement[d]||g.document.body[d]:e[d]}return this.each(function(){g=cy(this),g?g.scrollTo(a?f(g).scrollLeft():c,a?c:f(g).scrollTop()):this[d]=c})}}),f.each(["Height","Width"],function(a,c){var d=c.toLowerCase();f.fn["inner"+c]=function(){var a=this[0];return a?a.style?parseFloat(f.css(a,d,"padding")):this[d]():null},f.fn["outer"+c]=function(a){var b=this[0];return b?b.style?parseFloat(f.css(b,d,a?"margin":"border")):this[d]():null},f.fn[d]=function(a){var e=this[0];if(!e)return a==null?null:this;if(f.isFunction(a))return this.each(function(b){var c=f(this);c[d](a.call(this,b,c[d]()))});if(f.isWindow(e)){var g=e.document.documentElement["client"+c],h=e.document.body;return e.document.compatMode==="CSS1Compat"&&g||h&&h["client"+c]||g}if(e.nodeType===9)return Math.max(e.documentElement["client"+c],e.body["scroll"+c],e.documentElement["scroll"+c],e.body["offset"+c],e.documentElement["offset"+c]);if(a===b){var i=f.css(e,d),j=parseFloat(i);return f.isNumeric(j)?j:i}return this.css(d,typeof a=="string"?a:a+"px")}}),a.jQuery=a.$=f,typeof define=="function"&&define.amd&&define.amd.jQuery&&define("jquery",[],function(){return f})})(window);
\ No newline at end of file

Property changes on: TXM/trunk/org.txm.conllu.core/template/lib/ext/jquery.min.js
___________________________________________________________________
Added: svn:mime-type
   + text/plain

Index: TXM/trunk/org.txm.conllu.core/template/lib/ext/webfont.js
===================================================================
--- TXM/trunk/org.txm.conllu.core/template/lib/ext/webfont.js	(revision 0)
+++ TXM/trunk/org.txm.conllu.core/template/lib/ext/webfont.js	(revision 3567)
@@ -0,0 +1,46 @@
+/*
+ * Copyright 2012 Small Batch, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+;(function(window,document,undefined){
+function i(a){return function(){return this[a]}}var j;function n(a,b){var c=arguments.length>2?Array.prototype.slice.call(arguments,2):[];return function(){c.push.apply(c,arguments);return b.apply(a,c)}};function o(a,b){this.K=a;this.c=b}o.prototype.createElement=function(a,b,c){a=this.K.createElement(a);if(b)for(var d in b)if(b.hasOwnProperty(d))d=="style"?q(this,a,b[d]):a.setAttribute(d,b[d]);c&&a.appendChild(this.K.createTextNode(c));return a};function r(a,b,c){a=a.K.getElementsByTagName(b)[0];if(!a)a=document.documentElement;if(a&&a.lastChild){a.insertBefore(c,a.lastChild);return true}return false}function aa(a,b){function c(){document.body?b():setTimeout(c,0)}c()}
+function s(a,b){if(b.parentNode){b.parentNode.removeChild(b);return true}return false}function t(a,b){return a.createElement("link",{rel:"stylesheet",href:b})}function u(a,b){return a.createElement("script",{src:b})}function v(a,b,c){a=b.className.split(/\s+/);for(var d=0,e=a.length;d<e;d++)if(a[d]==c)return;a.push(c);b.className=a.join(" ").replace(/^\s+/,"")}
+function w(a,b,c){a=b.className.split(/\s+/);for(var d=[],e=0,f=a.length;e<f;e++)a[e]!=c&&d.push(a[e]);b.className=d.join(" ").replace(/^\s+/,"").replace(/\s+$/,"")}function x(a,b,c){a=b.className.split(/\s+/);b=0;for(var d=a.length;b<d;b++)if(a[b]==c)return true;return false}function q(a,b,c){if(a.c.getName()=="MSIE")b.style.cssText=c;else b.setAttribute("style",c)};function y(a,b,c,d,e,f,g,h){this.Ba=a;this.Ha=b;this.oa=c;this.na=d;this.Ea=e;this.Da=f;this.ma=g;this.Ia=h}j=y.prototype;j.getName=i("Ba");j.xa=i("Ha");j.Y=i("oa");j.ua=i("na");j.va=i("Ea");j.wa=i("Da");j.ta=i("ma");j.w=i("Ia");function z(a,b){this.c=a;this.k=b}var ba=new y("Unknown","Unknown","Unknown","Unknown","Unknown","Unknown",undefined,false);z.prototype.parse=function(){return this.c.indexOf("MSIE")!=-1?ca(this):this.c.indexOf("Opera")!=-1?da(this):this.c.indexOf("AppleWebKit")!=-1?ea(this):this.c.indexOf("Gecko")!=-1?fa(this):ba};
+function A(a){var b=C(a,a.c,/(iPod|iPad|iPhone|Android)/,1);if(b!="")return b;a=C(a,a.c,/(Linux|Mac_PowerPC|Macintosh|Windows)/,1);if(a!=""){if(a=="Mac_PowerPC")a="Macintosh";return a}return"Unknown"}function D(a){var b=C(a,a.c,/(OS X|Windows NT|Android) ([^;)]+)/,2);if(b)return b;if(b=C(a,a.c,/(iPhone )?OS ([\d_]+)/,2))return b;if(a=C(a,a.c,/Linux ([i\d]+)/,1))return a;return"Unknown"}
+function ca(a){var b=C(a,a.c,/(MSIE [\d\w\.]+)/,1);if(b!=""){var c=b.split(" ");b=c[0];c=c[1];return new y(b,c,b,c,A(a),D(a),E(a,a.k),F(a,c)>=6)}return new y("MSIE","Unknown","MSIE","Unknown",A(a),D(a),E(a,a.k),false)}
+function da(a){var b="Unknown",c="Unknown",d=C(a,a.c,/(Presto\/[\d\w\.]+)/,1);if(d!=""){c=d.split("/");b=c[0];c=c[1]}else{if(a.c.indexOf("Gecko")!=-1)b="Gecko";d=C(a,a.c,/rv:([^\)]+)/,1);if(d!="")c=d}if(a.c.indexOf("Version/")!=-1){d=C(a,a.c,/Version\/([\d\.]+)/,1);if(d!="")return new y("Opera",d,b,c,A(a),D(a),E(a,a.k),F(a,d)>=10)}d=C(a,a.c,/Opera[\/ ]([\d\.]+)/,1);if(d!="")return new y("Opera",d,b,c,A(a),D(a),E(a,a.k),F(a,d)>=10);return new y("Opera","Unknown",b,c,A(a),D(a),E(a,a.k),false)}
+function ea(a){var b=A(a),c=D(a),d=C(a,a.c,/AppleWebKit\/([\d\.\+]+)/,1);if(d=="")d="Unknown";var e="Unknown";if(a.c.indexOf("Chrome")!=-1)e="Chrome";else if(a.c.indexOf("Safari")!=-1)e="Safari";else if(a.c.indexOf("AdobeAIR")!=-1)e="AdobeAIR";var f="Unknown";if(a.c.indexOf("Version/")!=-1)f=C(a,a.c,/Version\/([\d\.\w]+)/,1);else if(e=="Chrome")f=C(a,a.c,/Chrome\/([\d\.]+)/,1);else if(e=="AdobeAIR")f=C(a,a.c,/AdobeAIR\/([\d\.]+)/,1);var g=false;if(e=="AdobeAIR"){g=C(a,f,/\d+\.(\d+)/,1);g=F(a,f)>2||
+F(a,f)==2&&parseInt(g,10)>=5}else{g=C(a,d,/\d+\.(\d+)/,1);g=F(a,d)>=526||F(a,d)>=525&&parseInt(g,10)>=13}return new y(e,f,"AppleWebKit",d,b,c,E(a,a.k),g)}
+function fa(a){var b="Unknown",c="Unknown",d=false;if(a.c.indexOf("Firefox")!=-1){b="Firefox";var e=C(a,a.c,/Firefox\/([\d\w\.]+)/,1);if(e!=""){d=C(a,e,/\d+\.(\d+)/,1);c=e;d=e!=""&&F(a,e)>=3&&parseInt(d,10)>=5}}else if(a.c.indexOf("Mozilla")!=-1)b="Mozilla";e=C(a,a.c,/rv:([^\)]+)/,1);if(e=="")e="Unknown";else if(!d){d=F(a,e);var f=parseInt(C(a,e,/\d+\.(\d+)/,1),10),g=parseInt(C(a,e,/\d+\.\d+\.(\d+)/,1),10);d=d>1||d==1&&f>9||d==1&&f==9&&g>=2||e.match(/1\.9\.1b[123]/)!=null||e.match(/1\.9\.1\.[\d\.]+/)!=
+null}return new y(b,c,"Gecko",e,A(a),D(a),E(a,a.k),d)}function F(a,b){a=C(a,b,/(\d+)/,1);if(a!="")return parseInt(a,10);return-1}function C(a,b,c,d){if((a=b.match(c))&&a[d])return a[d];return""}function E(a,b){if(b.documentMode)return b.documentMode};function ga(a,b,c,d){this.a=a;this.g=b;this.U=c;this.j=d||ha;this.h=new G("-")}var ha="wf";function H(a){v(a.a,a.g,a.h.e(a.j,"loading"));I(a,"loading")}function J(a){w(a.a,a.g,a.h.e(a.j,"loading"));x(a.a,a.g,a.h.e(a.j,"active"))||v(a.a,a.g,a.h.e(a.j,"inactive"));I(a,"inactive")}function ia(a){w(a.a,a.g,a.h.e(a.j,"loading"));w(a.a,a.g,a.h.e(a.j,"inactive"));v(a.a,a.g,a.h.e(a.j,"active"));I(a,"active")}function I(a,b,c,d){a.U[b]&&a.U[b](c,d)};function ja(){this.fa={}}function ka(a,b){var c=[];for(var d in b)if(b.hasOwnProperty(d)){var e=a.fa[d];e&&c.push(e(b[d]))}return c};function L(a,b,c,d,e){this.a=a;this.A=b;this.n=c;this.u=d;this.D=e;this.V=0;this.ja=this.ea=false}L.prototype.watch=function(a,b,c,d,e){for(var f=a.length,g=0;g<f;g++){var h=a[g];b[h]||(b[h]=["n4"]);this.V+=b[h].length}if(e)this.ea=e;for(g=0;g<f;g++){h=a[g];e=b[h];for(var l=c[h],k=0,m=e.length;k<m;k++){var B=e[k],p=this.A,K=h;v(p.a,p.g,p.h.e(p.j,K,B,"loading"));I(p,"fontloading",K,B);p=n(this,this.qa);K=n(this,this.ra);(new d(p,K,this.a,this.n,this.u,this.D,h,B,l)).start()}}};
+L.prototype.qa=function(a,b){var c=this.A;w(c.a,c.g,c.h.e(c.j,a,b,"loading"));w(c.a,c.g,c.h.e(c.j,a,b,"inactive"));v(c.a,c.g,c.h.e(c.j,a,b,"active"));I(c,"fontactive",a,b);this.ja=true;M(this)};L.prototype.ra=function(a,b){var c=this.A;w(c.a,c.g,c.h.e(c.j,a,b,"loading"));x(c.a,c.g,c.h.e(c.j,a,b,"active"))||v(c.a,c.g,c.h.e(c.j,a,b,"inactive"));I(c,"fontinactive",a,b);M(this)};function M(a){if(--a.V==0&&a.ea)a.ja?ia(a.A):J(a.A)};function N(a,b,c,d,e,f,g,h,l){this.H=a;this.$=b;this.a=c;this.n=d;this.u=e;this.D=f;this.Aa=new la;this.v=new O;this.L=g;this.B=h;this.sa=l||ma;this.O=na(this,oa);this.P=na(this,pa);this.ca=this.O;this.da=this.P;this.Q=P(this,oa);this.R=P(this,pa)}var oa="arial,'URW Gothic L',sans-serif",pa="Georgia,'Century Schoolbook L',serif",ma="BESbswy";N.prototype.start=function(){this.ia=this.D();this.J()};
+N.prototype.J=function(){var a=this.n.p(this.Q),b=this.n.p(this.R);if((this.O!=a||this.P!=b)&&this.ca==a&&this.da==b)Q(this,this.H);else if(this.D()-this.ia>=5E3)Q(this,this.$);else{this.ca=a;this.da=b;qa(this)}};function qa(a){a.u(function(b,c){return function(){c.call(b)}}(a,a.J),25)}function Q(a,b){s(a.a,a.Q);s(a.a,a.R);b(a.L,a.B)}function na(a,b){b=P(a,b,true);var c=a.n.p(b);s(a.a,b);return c}function P(a,b,c){b=a.a.createElement("span",{style:R(a,b,a.B,c)},a.sa);r(a.a,"body",b);return b}
+function R(a,b,c,d){c=a.v.expand(c);return"position:absolute;top:-999px;left:-999px;font-size:300px;width:auto;height:auto;line-height:normal;margin:0;padding:0;font-variant:normal;font-family:"+(d?"":a.Aa.quote(a.L)+",")+b+";"+c};function S(a,b,c,d,e){this.a=a;this.X=b;this.g=c;this.u=d;this.c=e;this.M=this.N=0}S.prototype.q=function(a,b){this.X.fa[a]=b};S.prototype.load=function(a){var b=new ga(this.a,this.g,a);this.c.w()?ra(this,b,a):J(b)};S.prototype.ya=function(a,b,c,d){var e=a.Z?a.Z():N;if(d)a.load(n(this,this.Ca,b,c,e));else{a=--this.N==0;this.M--;if(a)this.M==0?J(b):H(b);c.watch([],{},{},e,a)}};
+S.prototype.Ca=function(a,b,c,d,e,f){var g=--this.N==0;g&&H(a);this.u(n(this,function(h,l,k,m,B,p){h.watch(l,k||{},m||{},B,p)},b,d,e,f,c,g))};function ra(a,b,c){c=ka(a.X,c);a.M=a.N=c.length;for(var d=new L(a.a,b,{p:function(h){return h.offsetWidth}},a.u,function(){return(new Date).getTime()}),e=0,f=c.length;e<f;e++){var g=c[e];g.z(a.c,n(a,a.ya,g,b,d))}};function G(a){this.za=a||sa}var sa="-";G.prototype.e=function(){for(var a=[],b=0;b<arguments.length;b++)a.push(arguments[b].replace(/[\W_]+/g,"").toLowerCase());return a.join(this.za)};function la(){this.ha="'"}la.prototype.quote=function(a){var b=[];a=a.split(/,\s*/);for(var c=0;c<a.length;c++){var d=a[c].replace(/['"]/g,"");d.indexOf(" ")==-1?b.push(d):b.push(this.ha+d+this.ha)}return b.join(",")};function O(){this.G=ta;this.o=ua}var ta=["font-style","font-weight"],ua={"font-style":[["n","normal"],["i","italic"],["o","oblique"]],"font-weight":[["1","100"],["2","200"],["3","300"],["4","400"],["5","500"],["6","600"],["7","700"],["8","800"],["9","900"],["4","normal"],["7","bold"]]};function T(a,b,c){this.aa=a;this.Fa=b;this.o=c}T.prototype.compact=function(a,b){for(var c=0;c<this.o.length;c++)if(b==this.o[c][1]){a[this.aa]=this.o[c][0];return}};
+T.prototype.expand=function(a,b){for(var c=0;c<this.o.length;c++)if(b==this.o[c][0]){a[this.aa]=this.Fa+":"+this.o[c][1];return}};O.prototype.compact=function(a){var b=["n","4"];a=a.split(";");for(var c=0,d=a.length;c<d;c++){var e=a[c].replace(/\s+/g,"").split(":");if(e.length==2){var f=e[1];a:{e=e[0];for(var g=0;g<this.G.length;g++)if(e==this.G[g]){e=new T(g,e,this.o[e]);break a}e=null}e&&e.compact(b,f)}}return b.join("")};
+O.prototype.expand=function(a){if(a.length!=2)return null;for(var b=[null,null],c=0,d=this.G.length;c<d;c++){var e=this.G[c],f=a.substr(c,1);(new T(c,e,this.o[e])).expand(b,f)}return b[0]&&b[1]?b.join(";")+";":null};window.WebFont=function(){var a=(new z(navigator.userAgent,document)).parse();return new S(new o(document,a),new ja,document.documentElement,function(b,c){setTimeout(b,c)},a)}();window.WebFont.load=window.WebFont.load;window.WebFont.addModule=window.WebFont.q;y.prototype.getName=y.prototype.getName;y.prototype.getVersion=y.prototype.xa;y.prototype.getEngine=y.prototype.Y;y.prototype.getEngineVersion=y.prototype.ua;y.prototype.getPlatform=y.prototype.va;y.prototype.getPlatformVersion=y.prototype.wa;
+y.prototype.getDocumentMode=y.prototype.ta;y.prototype.isSupportingWebFont=y.prototype.w;function U(a,b){this.a=a;this.d=b}var va={regular:"n4",bold:"n7",italic:"i4",bolditalic:"i7",r:"n4",b:"n7",i:"i4",bi:"i7"};U.prototype.z=function(a,b){return b(a.w())};
+U.prototype.load=function(a){r(this.a,"head",t(this.a,("https:"==document.location.protocol?"https:":"http:")+"//webfonts.fontslive.com/css/"+this.d.key+".css"));var b;b=this.d.families;var c,d,e;c=[];d={};for(var f=0,g=b.length;f<g;f++){e=void 0;var h=void 0;h=void 0;h=b[f].split(":");e=h[0];h=h[1]?wa(this,h[1]):["n4"];e={W:e,T:h};c.push(e.W);d[e.W]=e.T}b={pa:c,T:d};a(b.pa,b.T)};
+function wa(a,b){a=b.split(",");b=[];for(var c=0,d=a.length;c<d;c++){var e=a[c];if(e){var f=va[e];b.push(f?f:e)}}return b}window.WebFont.q("ascender",function(a){var b=(new z(navigator.userAgent,document)).parse();return new U(new o(document,b),a)});function V(a,b,c,d,e,f,g,h,l){V.Ga.call(this,a,b,c,d,e,f,g,h,l);a=["Times New Roman","Lucida Sans Unicode","Courier New","Tahoma","Arial","Microsoft Sans Serif","Times","Lucida Console","Sans","Serif","Monospace"];b=a.length;c={};d=P(this,a[0],true);c[this.n.p(d)]=true;for(e=1;e<b;e++){f=a[e];q(this.a,d,R(this,f,this.B,true));c[this.n.p(d)]=true;if(this.B[1]!="4"){q(this.a,d,R(this,f,this.B[0]+"4",true));c[this.n.p(d)]=true}}s(this.a,d);this.t=c;this.la=false}
+(function(a,b){function c(){}c.prototype=a.prototype;b.prototype=new c;b.Ga=a;b.Ja=a.prototype})(N,V);var xa={Arimo:true,Cousine:true,Tinos:true};V.prototype.J=function(){var a=this.n.p(this.Q),b=this.n.p(this.R);if(!this.la&&a==b&&this.t[a]){this.t={};this.la=this.t[a]=true}if((this.O!=a||this.P!=b)&&!this.t[a]&&!this.t[b])Q(this,this.H);else if(this.D()-this.ia>=5E3)this.t[a]&&this.t[b]&&xa[this.L]?Q(this,this.H):Q(this,this.$);else qa(this)};function ya(a){this.I=a?a:("https:"==window.location.protocol?"https:":"http:")+za;this.f=[];this.S=[]}var za="//fonts.googleapis.com/css";ya.prototype.e=function(){if(this.f.length==0)throw new Error("No fonts to load !");if(this.I.indexOf("kit=")!=-1)return this.I;for(var a=this.f.length,b=[],c=0;c<a;c++)b.push(this.f[c].replace(/ /g,"+"));a=this.I+"?family="+b.join("%7C");if(this.S.length>0)a+="&subset="+this.S.join(",");return a};function Aa(a){this.f=a;this.ga=[];this.ka={};this.F={};this.v=new O}var Ba={ultralight:"n2",light:"n3",regular:"n4",bold:"n7",italic:"i4",bolditalic:"i7",ul:"n2",l:"n3",r:"n4",b:"n7",i:"i4",bi:"i7"},Ca={latin:ma,cyrillic:"&#1081;&#1103;&#1046;",greek:"&#945;&#946;&#931;",khmer:"&#x1780;&#x1781;&#x1782;",Hanuman:"&#x1780;&#x1781;&#x1782;"};
+Aa.prototype.parse=function(){for(var a=this.f.length,b=0;b<a;b++){var c=this.f[b].split(":"),d=c[0],e=["n4"];if(c.length>=2){var f=c[1],g=[];if(f){f=f.split(",");for(var h=f.length,l=0;l<h;l++){var k;k=f[l];if(k.match(/^[\w ]+$/)){var m=Ba[k];if(m)k=m;else{m=k.match(/^(\d*)(\w*)$/);k=m[1];m=m[2];k=(k=this.v.expand([m?m:"n",k?k.substr(0,1):"4"].join("")))?this.v.compact(k):null}}else k="";k&&g.push(k)}}if(g.length>0)e=g;if(c.length==3){c=c[2];g=[];c=c?c.split(","):g;if(c.length>0)if(c=Ca[c[0]])this.F[d]=
+c}}if(!this.F[d])if(c=Ca[d])this.F[d]=c;this.ga.push(d);this.ka[d]=e}};function W(a,b,c){this.c=a;this.a=b;this.d=c}W.prototype.z=function(a,b){b(a.w())};W.prototype.Z=function(){if(this.c.Y()=="AppleWebKit")return V;return N};W.prototype.load=function(a){var b=this.a;this.c.getName()=="MSIE"&&this.d.blocking!=true?aa(b,n(this,this.ba,a)):this.ba(a)};
+W.prototype.ba=function(a){for(var b=this.a,c=new ya(this.d.api),d=this.d.families,e=d.length,f=0;f<e;f++){var g=d[f].split(":");g.length==3&&c.S.push(g.pop());c.f.push(g.join(":"))}d=new Aa(d);d.parse();r(b,"head",t(b,c.e()));a(d.ga,d.ka,d.F)};window.WebFont.q("google",function(a){var b=(new z(navigator.userAgent,document)).parse();return new W(b,new o(document,b),a)});function X(a,b){this.a=a;this.d=b}X.prototype.load=function(a){for(var b=this.d.urls||[],c=this.d.families||[],d=0,e=b.length;d<e;d++)r(this.a,"head",t(this.a,b[d]));a(c)};X.prototype.z=function(a,b){return b(a.w())};window.WebFont.q("custom",function(a){var b=(new z(navigator.userAgent,document)).parse();return new X(new o(document,b),a)});function Y(a,b,c){this.m=a;this.a=b;this.d=c;this.f=[];this.s={};this.v=new O}Y.prototype.C=function(a){return("https:"==this.m.location.protocol?"https:":"http:")+(this.d.api||"//f.fontdeck.com/s/css/js/")+this.m.document.location.hostname+"/"+a+".js"};
+Y.prototype.z=function(a,b){a=this.d.id;var c=this;if(a){this.m.__webfontfontdeckmodule__||(this.m.__webfontfontdeckmodule__={});this.m.__webfontfontdeckmodule__[a]=function(d,e){for(var f=0,g=e.fonts.length;f<g;++f){var h=e.fonts[f];c.f.push(h.name);c.s[h.name]=[c.v.compact("font-weight:"+h.weight+";font-style:"+h.style)]}b(d)};r(this.a,"head",u(this.a,this.C(a)))}else b(true)};Y.prototype.load=function(a){a(this.f,this.s)};
+window.WebFont.q("fontdeck",function(a){var b=(new z(navigator.userAgent,document)).parse();return new Y(window,new o(document,b),a)});function Z(a,b,c,d,e){this.m=a;this.c=b;this.a=c;this.k=d;this.d=e;this.f=[];this.s={}}
+Z.prototype.z=function(a,b){var c=this,d=c.d.projectId;if(d){var e=u(c.a,c.C(d));e.id="__MonotypeAPIScript__"+d;e.onreadystatechange=function(f){if(e.readyState==="loaded"||e.readyState==="complete"){e.onreadystatechange=null;e.onload(f)}};e.onload=function(){if(c.m["__mti_fntLst"+d]){var f=c.m["__mti_fntLst"+d]();if(f&&f.length){var g;for(g=0;g<f.length;g++)c.f.push(f[g].fontfamily)}}b(a.w())};r(this.a,"head",e)}else b(true)};
+Z.prototype.C=function(a){var b=this.protocol(),c=(this.d.api||"fast.fonts.com/jsapi").replace(/^.*http(s?):(\/\/)?/,"");return b+"//"+c+"/"+a+".js"};Z.prototype.load=function(a){a(this.f,this.s)};Z.prototype.protocol=function(){var a=["http:","https:"],b=a[0];if(this.k&&this.k.location&&this.k.location.protocol){var c=0;for(c=0;c<a.length;c++)if(this.k.location.protocol===a[c])return this.k.location.protocol}return b};
+window.WebFont.q("monotype",function(a){var b=(new z(navigator.userAgent,document)).parse();return new Z(window,b,new o(document,b),document,a)});function $(a,b,c){this.m=a;this.a=b;this.d=c;this.f=[];this.s={}}$.prototype.C=function(a){var b="https:"==window.location.protocol?"https:":"http:";return(this.d.api||b+"//use.typekit.com")+"/"+a+".js"};$.prototype.z=function(a,b){var c=this.d.id,d=this.d,e=this;if(c){this.m.__webfonttypekitmodule__||(this.m.__webfonttypekitmodule__={});this.m.__webfonttypekitmodule__[c]=function(f){f(a,d,function(g,h,l){e.f=h;e.s=l;b(g)})};r(this.a,"head",u(this.a,this.C(c)))}else b(true)};
+$.prototype.load=function(a){a(this.f,this.s)};window.WebFont.q("typekit",function(a){var b=(new z(navigator.userAgent,document)).parse();return new $(window,new o(document,b),a)});window.WebFontConfig&&window.WebFont.load(window.WebFontConfig);
+})(this,document);

Property changes on: TXM/trunk/org.txm.conllu.core/template/lib/ext/webfont.js
___________________________________________________________________
Added: svn:mime-type
   + text/plain

Index: TXM/trunk/org.txm.conllu.core/template/conllu.js
===================================================================
--- TXM/trunk/org.txm.conllu.core/template/conllu.js	(revision 0)
+++ TXM/trunk/org.txm.conllu.core/template/conllu.js	(revision 3567)
@@ -0,0 +1,1392 @@
+// -*- Mode: JavaScript; tab-width: 4; indent-tabs-mode: nil; -*-
+// vim:set ft=javascript ts=4 sw=4 sts=4 cindent:
+
+/*
+CoNLL-U format library for JavaScript.
+Home: http://github.com/spyysalo/conllu.js
+Format: http://universaldependencies.github.io/docs/format.html
+
+Author: Sampo Pyysalo
+License: MIT (http://opensource.org/licenses/MIT)
+*/
+
+var ConllU = (function(window, undefined) {
+
+    /*
+     * ConllU.Document: represents CoNLL-U document
+     */
+
+    var Document = function() {
+        this.reset();
+    };
+
+    Document.prototype.reset = function() {
+        this.sentences = [];
+        this.error = false;
+        this.logger = function(s) { /* no-op */ };
+        this.strict = null; // pick heuristically
+    };
+
+    Document.prototype.log = function(message) {
+        this.logger(message);
+    };
+
+    Document.prototype.logError = function(message) {
+        this.log('error: ' + message);
+        this.error = true;
+    };
+
+    /* Parse CoNLL-U format, return Document.
+     * (see http://universaldependencies.github.io/docs/format.html)
+     *
+     * CoNLL-U files contain three types of lines:
+     * 1.  Word lines
+     * 2.  Blank lines marking sentence boundaries
+     * 3.  Comment lines starting with a hash ("#")        
+     *
+     * Each word line has the following format
+     * 1.  ID: Word index, integer starting at 1 for each new sentence; 
+     *     may be a range for tokens with multiple words; may be a decimal
+     *     number for empty nodes.
+     * 2.  FORM: Word form or punctuation symbol.
+     * 3.  LEMMA: Lemma or stem of word form.
+     * 4.  UPOSTAG: Universal part-of-speech tag.
+     * 5.  XPOSTAG: Language-specific part-of-speech tag; underscore
+     *     if not available.
+     * 6.  FEATS: List of morphological features from the Universal 
+     *     feature inventory or from a defined language-specific extension;
+     *      underscore if not available.
+     * 7.  HEAD: Head of the current token, which is either a value of ID
+     *     or zero (0).
+     * 8.  DEPREL: Universal Stanford dependency relation to the HEAD
+     *     (root iff HEAD = 0) or a defined language-specific subtype
+     *     of one.
+     * 9.  DEPS: List of secondary dependencies (head-deprel pairs).
+     * 10. MISC: Any other annotation.
+     */
+    Document.prototype.parse = function(input, logger, strict) {
+        // discard previous state, if any
+        this.reset();
+
+        if (logger !== undefined) {
+            this.logger = logger;
+        }
+        if (strict !== undefined) {
+            this.strict = strict;
+        }
+        
+        // TODO: handle other newline formats
+        var lines = input.split('\n');
+
+        if (this.strict === null) {
+            this.strict = selectParsingMode(input, this.logger);
+        }
+
+        // select splitter to use for dividing the lines into fields.
+        var splitter = selectFieldSplitter(input, this.logger, this.strict);
+
+        var elements = [],            
+            comments = [],
+            beforeSentence = true;
+        for (var idx=0; idx<lines.length; idx++) {
+            var line = lines[idx], that = this;
+
+            var logLineError = function(message) {
+                that.logError('line '+(idx+1)+': '+message+' ("'+line+'")');
+                that.error = true;
+            }
+
+            if (isComment(line)) {
+                if (beforeSentence) {
+                    comments.push(line);
+                } else {
+                    logLineError('comments must precede sentence, ignoring');
+                }
+                continue;
+            }
+
+            // non-comment, assume inside sentence until terminated by
+            // blank line
+            beforeSentence = false;
+
+            var fields = splitter(line);
+
+            if (fields.length === 0) {
+                // empty line, terminates sentence
+                if (elements.length !== 0) {
+                    var sId = 'S' + (this.sentences.length+1);
+                    var sentence = new Sentence(sId, elements, comments);
+                    this.sentences.push(sentence);
+                } else {
+                    logLineError('empty sentence, ignoring');
+                }
+                // reset
+                elements = [];
+                comments = [];
+                beforeSentence = true;
+                continue;
+            }
+
+            if (fields.length !== 10) {
+                logLineError('expected 10 fields, got '+fields.length);
+                repairFields(fields, this.logger);
+            }
+
+            var element = new Element(fields, idx, line);
+
+            var issues = element.validate();
+            for (var j=0; j<issues.length; j++) {
+                logLineError(issues[j]);
+            }
+            if (issues.length !== 0) {
+                if (!element.repair(this.logger)) {
+                    logLineError('repair failed, discarding line');
+                    continue; // failed, ignore line
+                }
+            }
+
+            elements.push(element);
+        }
+
+        // If elements is non-empty, last sentence ended without its
+        // expected terminating empty line. Process, but warn if strict.
+        if (elements.length !== 0) {
+            if (this.strict) {
+                this.logError('missing blank line after last sentence');
+            }
+            var sId = 'S' + (this.sentences.length+1);
+            var sentence = new Sentence(sId, elements, comments);
+            this.sentences.push(sentence);
+            // reset
+            elements = [];
+            comments = [];
+            beforeSentence = true;
+        }
+
+        // If comments is non-empty, there were comments after the
+        // terminating empty line. Warn and discard.
+        if (comments.length !== 0) {
+            this.logError('comments may not occur after last sentence, '+
+                          'ignoring');
+        }
+
+        return this;
+    }
+
+    Document.prototype.toBrat = function(logger, includeEmpty) {
+        if (logger !== undefined) {
+            this.logger = logger;
+        }
+        if (includeEmpty === undefined) {
+            includeEmpty = false;    // hide empty nodes by default
+        }
+
+        // merge brat data over all sentences
+        var mergedBratData = {},
+            textOffset = 0;
+        var categories = [
+            'entities',
+            'attributes',
+            'relations',
+            'comments',
+            'styles',
+            'sentlabels'
+        ];
+        for (var i=0; i<categories.length; i++) {
+            mergedBratData[categories[i]] = [];
+        }
+        mergedBratData['text'] = '';
+        for (var i=0; i<this.sentences.length; i++) {
+            var sentence = this.sentences[i];
+
+            var issues = sentence.validate();
+            for (var j=0; j<issues.length; j++) {
+                this.logError(issues[j]);
+            }
+            if (issues.length !== 0) {
+                if (!sentence.repair(this.logger)) {
+                    this.logError('repair failed, discarding sentence');
+                    continue;
+                }
+            }
+            sentence.setBaseOffset(textOffset !== 0 ? textOffset + 1 : 0);
+            bratData = sentence.toBrat(includeEmpty);
+            
+            // merge
+            if (mergedBratData['text'].length !== 0) {
+                mergedBratData['text'] += '\n';
+                textOffset += 1;
+            }
+            mergedBratData['text'] += bratData['text'];
+            textOffset += bratData['text'].length;
+            for (var j=0; j<categories.length; j++) {
+                var c = categories[j];
+                mergedBratData[c] = mergedBratData[c].concat(bratData[c]);
+            }
+        }
+
+        // to avoid brat breakage on error, don't send empty text
+        if (mergedBratData['text'].length === 0) {
+            mergedBratData['text'] = '<EMPTY>';
+        }
+
+        mergedBratData['error'] = this.error;
+
+        return mergedBratData;
+    };
+
+    /*
+     * ConllU.Sentence: represents CoNLL-U sentence
+     */
+
+    var Sentence = function(sentenceId, elements, comments) {
+        this.id = sentenceId;
+        this.elements = elements;
+        this.comments = comments;
+        this.baseOffset = 0;
+    };
+
+    // set offset of first character in sentence (for standoff
+    // generation)
+    Sentence.prototype.setBaseOffset = function(baseOffset) {
+        this.baseOffset = baseOffset;
+    }
+
+    Sentence.prototype.dependencies = function() {
+        var dependencies = [];
+
+        for (var i=0; i<this.elements.length; i++) {
+            var element = this.elements[i];
+            dependencies = dependencies.concat(element.dependencies());
+        }
+
+        return dependencies;
+    };
+
+    Sentence.prototype.words = function(includeEmpty) {
+        return this.elements.filter(function(e) { 
+            return (e.isWord() || (includeEmpty && e.isEmptyNode()));
+        });
+    };
+
+    Sentence.prototype.multiwords = function() {
+        return this.elements.filter(function(e) {
+            return e.isMultiword();
+        });
+    };
+
+    Sentence.prototype.tokens = function() {
+        // extract token sequence by omitting word IDs that are
+        // included in a multiword token range.
+        var multiwords = this.multiwords();
+        var inRange = {};
+        for (var i=0; i<multiwords.length; i++) {
+            var mw = multiwords[i];
+            for (var j=mw.rangeFrom(); j<=mw.rangeTo(); j++) {
+                inRange[j] = true;
+            }
+        }
+        return this.elements.filter(function(e) {
+            return e.isToken(inRange);
+        });
+    };
+
+    // return words with possible modifications for visualization with
+    // brat
+    Sentence.prototype.bratWords = function(includeEmpty) {
+        var words = this.words(includeEmpty);
+        
+        for (var i=0; i<words.length; i++) {
+            if (isRtl(words[i].form)) {
+                words[i] = deepCopy(words[i]);
+                words[i].form = rtlFix(words[i].form);
+            }
+        }
+
+        return words;
+    };
+
+    // return tokens with possible modifications for visualization
+    // with brat
+    Sentence.prototype.bratTokens = function() {
+        var tokens = this.tokens();
+
+        for (var i=0; i<tokens.length; i++) {
+            tokens[i] = deepCopy(tokens[i]);
+            tokens[i].form = rtlFix(tokens[i].form);
+        }
+
+        return tokens;
+    };
+
+    // return the text of the sentence for visualization with brat
+    Sentence.prototype.bratText = function(includeEmpty) {
+        var words = this.bratWords(includeEmpty);
+        var tokens = this.bratTokens();
+
+        var wordText = words.map(function(w) { return w.form }).join(' ');
+        var tokenText = tokens.map(function(w) { return w.form }).join(' ');
+
+        var combinedText = wordText;
+        if (wordText != tokenText) {
+            combinedText += '\n' + tokenText;
+        }
+
+        return combinedText;
+    };
+
+    // return the annotated text spans of the sentence for visualization
+    // with brat.
+    Sentence.prototype.bratSpans = function(includeEmpty) {
+        var spans = [],
+            offset = this.baseOffset;
+
+        // create an annotation for each word
+        var words = this.bratWords(includeEmpty);
+        for (var i=0; i<words.length; i++) {
+            var length = words[i].form.length;
+            spans.push([this.id+'-T'+words[i].id, words[i].upostag,
+                        [[offset, offset+length]]]);
+            offset += length + 1;
+        }
+
+        return spans;
+    }
+
+    // return attributes of sentence annotations for visualization
+    // with brat.
+    Sentence.prototype.bratAttributes = function(includeEmpty) {
+        var words = this.words(includeEmpty);
+
+        // create attributes for word features
+        var attributes = [],
+            aidseq = 1;
+        for (var i=0; i<words.length; i++) {
+            var word = words[i],
+                tid = this.id+'-T'+word.id;
+            var nameVals = word.features();
+            for (var j=0; j<nameVals.length; j++) {
+                var name = nameVals[j][0], 
+                    value = nameVals[j][1];
+                attributes.push([this.id+'-A'+aidseq++, name, tid, value]);
+            }
+        }
+
+        return attributes;
+    };
+
+    // return relations for sentence dependencies for visualization
+    // with brat.
+    Sentence.prototype.bratRelations = function(includeEmpty) {
+        var dependencies = this.dependencies();
+        var relations = [];
+
+        for (var i=0; i<dependencies.length; i++) {
+            var dep = dependencies[i];
+            relations.push([this.id+'-R'+i, dep[2], 
+                            [ [ 'arg1', this.id+'-T'+dep[1] ],
+                              [ 'arg2', this.id+'-T'+dep[0] ] ] ]);
+        }
+
+        return relations;
+    };
+
+    // return comments (notes) on sentence annotations for
+    // visualization with brat.
+    Sentence.prototype.bratComments = function(includeEmpty) {
+        var words = this.words(includeEmpty);
+
+        // TODO: better visualization for LEMMA, XPOSTAG, and MISC.
+        var comments = [];
+        for (var i=0; i<words.length; i++) {
+            var word = words[i],
+                tid = this.id+'-T'+word.id,
+                label = 'AnnotatorNotes';
+            comments.push([tid, label, 'Lemma: ' + word.lemma]);
+            if (word.xpostag !== '_') {
+                comments.push([tid, label, 'Xpostag: ' + word.xpostag]);
+            }
+            if (word.misc !== '_') {
+                comments.push([tid, label, 'Misc: ' + word.misc]);
+            }
+        }
+
+        return comments;
+    };
+
+    // Return styles on sentence annotations for visualization with
+    // brat. Note: this feature is an extension of both the CoNLL-U
+    // comment format and the basic brat data format.
+    Sentence.prototype.bratStyles = function(includeEmpty) {
+        var styles = [],
+            wildcards = [];
+
+        for (var i=0; i<this.comments.length; i++) {
+            var comment = this.comments[i];
+
+            m = comment.match(/^(\#\s*visual-style\s+)(.*)/);
+            if (!m) {
+                continue;
+            }
+            var styleSpec = m[2];
+
+            // Attempt to parse as a visual style specification. The
+            // expected format is "REF<SPACE>STYLE", where REF
+            // is either a single ID (for a span), a space-separated
+            // ID1 ID2 TYPE triple (for a relation), or a special
+            // wildcard value like "arcs", and STYLE is either
+            // a colon-separated key-value pair or a color.
+            m = styleSpec.match(/^([^\t]+)\s+(\S+)\s*$/);
+            if (!m) {
+                // TODO: avoid console.log
+                console.log('warning: failed to parse: "'+comment+'"');
+                continue;
+            }
+            var reference = m[1], style = m[2];
+
+            // split style into key and value, adding a key to
+            // color-only styles as needed for the reference type.
+            var key, value;
+            m = style.match(/^(\S+):(\S+)$/);
+            if (m) {
+                key = m[1];
+                value = m[2];
+            } else {
+                value = style;
+                if (reference === 'arcs' || reference.indexOf(' ') !== -1) {
+                    key = 'color';
+                } else {
+                    key = 'bgColor';
+                }
+            }
+
+            // store wildcards for separate later processing
+            if (reference.match(/^(nodes|arcs)$/)) {
+                wildcards.push([reference, key, value]);
+                continue;
+            }
+
+            // adjust every ID in reference for brat
+            if (reference.indexOf(' ') === -1) {
+                reference = this.id + '-T' + reference;
+            } else {
+                reference = reference.split(' ');
+                reference[0] = this.id + '-T' + reference[0];
+                reference[1] = this.id + '-T' + reference[1];
+            }
+
+            styles.push([reference, key, value]);
+        }
+
+        // for expanding wildcards, first determine which words / arcs
+        // styles have already been set, and then add the style to
+        // everything that hasn't.
+        var setStyle = {};
+        for (var i=0; i<styles.length; i++) {
+            setStyle[styles[i][0].concat([styles[i][1]])] = true;
+        }
+        for (var i=0; i<wildcards.length; i++) {
+            var reference = wildcards[i][0],
+                key = wildcards[i][1],
+                value = wildcards[i][2];
+            if (reference === 'nodes') {
+                var words = this.words(includeEmpty);
+                for (var j=0; j<words.length; j++) {
+                    var r = this.id + '-T' + words[j].id;
+                    if (!setStyle[r.concat([key])]) {
+                        styles.push([r, key, value]);
+                        setStyle[r.concat([key])] = true;
+                    }
+                }
+            } else if (reference === 'arcs') {
+                var deps = this.dependencies();
+                for (var j=0; j<deps.length; j++) {
+                    var r = [this.id + '-T' + deps[j][1],
+                             this.id + '-T' + deps[j][0],
+                             deps[j][2]];
+                    if (!setStyle[r.concat([key])]) {
+                        styles.push([r, key, value]);
+                        setStyle[r.concat([key])] = true;
+                    }
+                }
+            } else {
+                console.log('internal error');
+            }
+        }
+        
+        return styles;
+    };
+
+    // Return label of sentence for visualization with brat, or null
+    // if not defined. Note: this feature is an extension of both the
+    // CoNLL-U comment format and the basic brat data format.
+    Sentence.prototype.bratLabel = function() {
+        var label = null;
+
+        for (var i=0; i<this.comments.length; i++) {
+            var comment = this.comments[i];
+
+            m = comment.match(/^(\#\s*sentence-label\b)(.*)/);
+            if (!m) {
+                continue;
+            }
+            label = m[2].trim();
+        }
+        return label;
+    };
+
+    // Return representation of sentence in brat embedded format (see
+    // http://brat.nlplab.org/embed.html).
+    // If includeEmpty is truthy, include empty nodes in the representation.
+    // Note: "styles" is an extension, not part of the basic format.
+    Sentence.prototype.toBrat = function(includeEmpty) {
+        var text = this.bratText(includeEmpty);
+        var spans = this.bratSpans(includeEmpty);
+        var attributes = this.bratAttributes(includeEmpty);
+        var relations = this.bratRelations(includeEmpty);
+        var comments = this.bratComments(includeEmpty);
+        var styles = this.bratStyles(includeEmpty);
+        var labels = [this.bratLabel()];
+
+        return {
+            'text': text,
+            'entities': spans,
+            'attributes': attributes,
+            'relations': relations,
+            'comments': comments,
+            'styles': styles,
+            'sentlabels': labels,
+        };
+    };
+
+    Sentence.prototype.elementById = function() {
+        var elementById = {};
+
+        for (var i=0; i<this.elements.length; i++) {
+            elementById[this.elements[i].id] = this.elements[i];
+        }
+
+        return elementById;
+    };
+
+    Sentence.prototype.addError = function(issue, element, issues) {
+        issues.push('line '+(element.lineidx+1)+': '+issue+' ("'+element.line+'")');
+    }
+
+    // Check validity of the sentence. Return list of strings
+    // representing issues found in validation (empty list if none).
+    Sentence.prototype.validate = function() {
+        var issues = [];
+
+        this.validateUniqueIds(issues);
+        this.validateWordSequence(issues);
+        this.validateMultiwordSequence(issues);
+        this.validateEmptyNodeSequence(issues);
+        this.validateReferences(issues);
+
+        return issues;
+    };
+
+    // Check for presence of ID duplicates
+    Sentence.prototype.validateUniqueIds = function(issues) {
+        issues = (issues !== undefined ? issues : []);
+
+        var initialIssueCount = issues.length;
+        var elementById = {};
+
+        for (var i=0; i<this.elements.length; i++) {
+            var element = this.elements[i];
+            if (elementById[element.id] !== undefined) {
+                this.addError('non-unique ID "'+element.id+'"',
+                              element, issues);
+            }
+            elementById[element.id] = element;
+        }
+
+        return issues.length === initialIssueCount;
+    };
+
+    // Check validity of word ID sequence (should be 1,2,3,...)
+    Sentence.prototype.validateWordSequence = function(issues) {
+        issues = (issues !== undefined ? issues : []);
+
+        var initialIssueCount = issues.length;
+        var expectedId = 1;
+
+        for (var i=0; i<this.elements.length; i++) {
+            var element = this.elements[i];
+
+            if (element.isMultiword() || element.isEmptyNode()) {
+                continue; // only check simple word sequence here
+            }
+            
+            if (parseInt(element.id, 10) !== expectedId) {
+                this.addError('word IDs should be 1,2,3,..., ' +
+                              'expected '+expectedId+', got '+element.id,
+                              element, issues);
+            }
+            expectedId = parseInt(element.id, 10) + 1;
+        }
+
+        return issues.length === initialIssueCount;
+    };
+
+    // Check that multiword token ranges are valid
+    Sentence.prototype.validateMultiwordSequence = function(issues) {
+        issues = (issues !== undefined ? issues : []);
+
+        var initialIssueCount = issues.length;
+        var expectedId = 1;
+
+        for (var i=0; i<this.elements.length; i++) {
+            var element = this.elements[i];
+
+            if (element.isMultiword() && element.rangeFrom() !== expectedId) {
+                this.addError('multiword tokens must appear before '+
+                              'first word in their range',
+                              element, issues);
+            } else {
+                expectedId = parseInt(element.id, 10) + 1;
+            }
+        }
+
+        return issues.length === initialIssueCount;
+    };
+
+    Sentence.prototype.validateEmptyNodeSequence = function(issues) {
+        issues = (issues !== undefined ? issues : []);
+
+        var initialIssueCount = issues.length;
+        var previousWordId = '0';    // TODO check https://github.com/UniversalDependencies/docs/issues/382
+        var nextEmptyNodeId = 1;
+
+        for (var i=0; i<this.elements.length; i++) {
+            var element = this.elements[i];
+
+            if (element.isWord()) {
+                previousWordId = element.id;
+                nextEmptyNodeId = 1;
+            } else if (element.isEmptyNode()) {
+                var expectedId = previousWordId + '.' + nextEmptyNodeId;
+                if (element.id !== expectedId) {
+                    this.addError('empty node IDs should be *.1, *.2, ... ' +
+                                  'expected '+expectedId+', got '+element.id,
+                                  element, issues);
+                }
+                nextEmptyNodeId++;
+            }
+        }
+
+        return issues.length === initialIssueCount;
+    }
+
+    // Check validity of ID references in HEAD and DEPS.
+    Sentence.prototype.validateReferences = function(issues) {
+        issues = (issues !== undefined ? issues : []);
+        
+        var initialIssueCount = issues.length;
+        var elementById = this.elementById();
+
+        for (var i=0; i<this.elements.length; i++) {
+            var element = this.elements[i];
+
+            // validate HEAD
+            if (!element.validHeadReference(elementById)) {
+                this.addError('HEAD is not valid ID: "'+element.head+'"',
+                              element, issues);
+            }
+            
+            // validate DEPS
+            var elemDeps = element.dependencies(true);
+            for (var j=0; j<elemDeps.length; j++) {
+                var head = elemDeps[j][1];
+                if (head !== '0' && elementById[head] === undefined) {
+                    this.addError('invalid ID "'+head+'" in DEPS',
+                                  element, issues);
+                }
+            }
+        }
+
+        return issues.length === initialIssueCount;
+    };
+
+    Sentence.prototype.repair = function(log) {
+        log = (log !== undefined ? log : nullLogger);
+
+        if (!this.validateUniqueIds()) {
+            this.repairUniqueIds(log);
+        }
+
+        if (!this.validateWordSequence()) {
+            this.repairWordSequence(log);
+        }
+
+        if (!this.validateMultiwordSequence()) {
+            this.repairMultiwordSequence(log);
+        }
+
+        if (!this.validateEmptyNodeSequence()) {
+            this.repairEmptyNodeSequence(log);
+        }
+
+        if (!this.validateReferences()) {
+            this.repairReferences(log);
+        }
+
+        var issues = this.validate();
+        return issues.length === 0;
+    };
+
+    Sentence.prototype.repairUniqueIds = function(log) {
+        log = (log !== undefined ? log : nullLogger);
+
+        var elementById = {},
+            filtered = [];
+
+        for (var i=0; i<this.elements.length; i++) {
+            var element = this.elements[i];
+            if (elementById[element.id] === undefined) {
+                elementById[element.id] = element;
+                filtered.push(element);
+            } else {
+                log('repair: remove element with duplicate ID "'+element.id+'"');
+            }
+        }
+        this.elements = filtered;
+    
+        return true;
+    };
+
+    Sentence.prototype.repairWordSequence = function(log) {
+        log('TODO: implement ConllU.Sentence.repairWordSequence()');
+        return true;
+    };
+
+    Sentence.prototype.repairMultiwordSequence = function(log) {
+        log('TODO: implement ConllU.Sentence.repairMultiwordSequence()');
+        return true;
+    };
+
+    Sentence.prototype.repairEmptyNodeSequence = function(log) {
+        log('TODO: implement ConllU.Sentence.repairEmptyNodeSequence()');
+        return true;
+    };
+
+    Sentence.prototype.repairReferences = function(log) {
+        log = (log !== undefined ? log : nullLogger);
+
+        var elementById = this.elementById();
+
+        for (var i=0; i<this.elements.length; i++) {
+            var element = this.elements[i];
+
+            // repair HEAD if not valid
+            if (!element.validHeadReference(elementById)) {
+                log('repair: blanking invalid HEAD');
+                element.head = null;
+            }
+
+            // repair DEPS if not valid
+            if (element.deps === '_') {
+                continue;
+            }
+            var deparr = element.deps.split('|'),
+                filtered = [];
+            for (var j=0; j<deparr.length; j++) {
+                var dep = deparr[j];
+                var m = dep.match(dependencyRegex);
+                if (m) {
+                    var head = m[1], deprel = m[2];
+                    if (head === '0' || elementById[head] !== undefined) {
+                        filtered.push(dep);
+                    } else {
+                        log('repair: removing invalid ID from DEPS');
+                        error = true;
+                    }
+                } else {
+                    console.log('internal error: repairReferences(): ' +
+                                'invalid DEPS');
+                }
+            }
+            if (filtered.length === 0) {
+                element.deps = '_';
+            } else {
+                element.deps = filtered.join('|');
+            }
+        }
+        return true;
+    };
+
+    /*
+     * ConllU.Element: represents CoNLL-U word or multiword token
+     */
+
+    // represents CoNLL-U word or multiword token
+    var Element = function(fields, lineidx, line) {
+        this.id = fields[0];
+        this.form = fields[1];
+        this.lemma = fields[2];
+        this.upostag = fields[3];
+        this.xpostag = fields[4];
+        this.feats = fields[5];
+        this.head = fields[6];
+        this.deprel = fields[7];
+        this.deps = fields[8];
+        this.misc = fields[9];
+        this.lineidx = lineidx;
+        this.line = line;
+    };
+
+    // constraints that hold for all fields
+    Element.prototype.validateField = function(field, name, issues,
+                                               allowSpace) {
+        name = (name !== undefined ? name : 'field');
+        issues = (issues !== undefined ? issues : []);
+        if (allowSpace === undefined) {
+            allowSpace = false;
+        }
+
+        if (field === undefined) {
+            issues.push('invalid '+name);
+            return false;
+        } else if (field.length === 0) {
+            issues.push(name+' must not be empty: "'+field+'"');
+            return false;
+        } else if (hasSpace(field) && !allowSpace) {
+            issues.push(name+' must not contain space: "'+field+'"');
+            return false;
+        } else {
+            return true;
+        }
+    };
+
+    Element.prototype.validateId = function(id, issues) {
+        issues = (issues !== undefined ? issues : []);
+        
+        if (!this.validateField(id, 'ID', issues)) {
+            return false;
+        } else if (id.match(/^\d+$/)) {
+            if (id === '0') {
+                issues.push('ID indices must start from 1: "'+id+'"');
+                return false;
+            } else {
+                return true;
+            }
+        } else if (id.match(/^(\d+)-(\d+)$/)) {
+            m = id.match(/^(\d+)-(\d+)$/);
+            if (!m) {
+                console.log('internal error');
+                return false;
+            }
+            var start = parseInt(m[1], 10), 
+                end = parseInt(m[2], 10);
+            if (end < start) {
+                issues.push('ID ranges must have start <= end: "'+id+'"');
+                return false;
+            } else {
+                return true;
+            }
+        } else if (id.match(/^(\d+)\.(\d+)$/)) {
+            m = id.match(/^(\d+)\.(\d+)$/);
+            if (!m) {
+                console.log('internal error');
+                return false;
+            }
+            var iPart = parseInt(m[1], 10),
+                fPart = parseInt(m[2], 10);
+            if (iPart == 0 || fPart == 0) {
+                issues.push('ID indices must start from 1: "'+id+'"');
+                return false;
+            } else {
+                return true;
+            }
+        } else {
+            issues.push('ID must be integer, range, or decimal: "'+id+'"');
+            return false;
+        }
+    };
+
+    Element.prototype.validateForm = function(form, issues) {
+        issues = (issues !== undefined ? issues : []);
+        
+        if (!this.validateField(form, 'FORM', issues, true)) {
+            return false;
+        } else {
+            return true;
+        }
+    };
+
+    Element.prototype.validateLemma = function(lemma, issues) {
+        issues = (issues !== undefined ? issues : []);
+        
+        if (!this.validateField(lemma, 'LEMMA', issues, true)) {
+            return false;
+        } else {
+            return true;
+        }
+    };
+    
+    Element.prototype.validateUpostag = function(upostag, issues) {
+        issues = (issues !== undefined ? issues : []);
+        
+        if (!this.validateField(upostag, 'UPOSTAG', issues)) {
+            return false;
+        } else {
+            return true;
+        }
+    };
+
+    Element.prototype.validateXpostag = function(xpostag, issues) {
+        issues = (issues !== undefined ? issues : []);
+        
+        if (!this.validateField(xpostag, 'XPOSTAG', issues)) {
+            return false;
+        } else {
+            return true;
+        }
+    };
+
+    Element.prototype.validateFeats = function(feats, issues) {
+        issues = (issues !== undefined ? issues : []);
+        
+        if (!this.validateField(feats, 'FEATS', issues)) {
+            return false;
+        } else if (feats === '_') {
+            return true;
+        }
+        var initialIssueCount = issues.length;
+        var featarr = feats.split('|');
+        var featmap = {};
+        var prevName = null;
+        for (var i=0; i<featarr.length; i++) {
+            var feat = featarr[i];
+            var m = feat.match(featureRegex);
+            if (!m) {
+                // TODO more descriptive issue
+                issues.push('invalid FEATS entry: "'+feat+'"');
+                continue;
+            }
+            var name = m[1], valuestr = m[2];
+            if (prevName !== null && 
+                name.toLowerCase() < prevName.toLowerCase()) {
+                issues.push('features must be ordered alphabetically ' +
+                            '(case-insensitive): "'+name+'" < "'+prevName+'"');
+                noIssue = false;
+            }
+            prevName = name;
+            var values = valuestr.split(',');
+            var valuemap = {}, validValues = [];
+            for (var j=0; j<values.length; j++) {
+                var value = values[j];
+                var m = value.match(featureValueRegex);
+                if (!m) {
+                    issues.push('invalid FEATS value: "'+value+'"');
+                    continue;
+                }
+                if (valuemap[value] !== undefined) {
+                    issues.push('duplicate feature value: "'+value+'"');
+                    continue;
+                }
+                valuemap[value] = true;
+                validValues.push(value);
+            }
+            if (featmap[name] !== undefined) {
+                issues.push('duplicate feature name: "'+name+'"');
+                continue;
+            }
+            if (validValues.length !== 0) {
+                featmap[name] = validValues;
+            }
+        }
+        return issues.length === initialIssueCount;
+    };
+
+    Element.prototype.validateHead = function(head, issues) {
+        issues = (issues !== undefined ? issues : []);
+
+        // TODO: consider checking that DEPREL is "root" iff HEAD is 0.
+        
+        if (head === null) {
+            return true; // exceptional case for Element.repair()
+        } else if (!this.validateField(head, 'HEAD', issues)) {
+            return false;
+        } else if (this.isEmptyNode() && head === '_') {
+            return true; // underscore permitted for empty nodes.
+        } else if (!head.match(/^\d+$/)) {
+            issues.push('HEAD must be an ID or zero: "'+head+'"');
+            return false;
+        } else {
+            return true;
+        }
+    };
+
+    Element.prototype.validateDeprel = function(deprel, issues) {
+        issues = (issues !== undefined ? issues : []);
+
+        if (!this.validateField(deprel, 'DEPREL', issues)) {
+            return false;
+        } else {
+            return true;
+        }
+    };
+
+    Element.prototype.validateDeps = function(deps, issues) {
+        issues = (issues !== undefined ? issues : []);
+
+        // TODO: consider checking that deprel is "root" iff head is 0.
+
+        if (!this.validateField(deps, 'DEPS', issues)) {
+            return false;
+        } else if (deps === '_') {
+            return true;
+        }
+        var deparr = deps.split('|');
+        var prevHead = null;
+        // TODO: don't short-circuit on first error
+        for (var i=0; i<deparr.length; i++) {
+            var dep = deparr[i];
+            m = dep.match(/^(\d+(?:\.\d+)?):(\S+)$/);
+            if (!m) {
+                // TODO more descriptive issue
+                issues.push('invalid DEPS: "'+deps+'"');
+                return false;
+            }
+            var head = m[1], deprel = m[2];
+            if (prevHead !== null &&
+                parseFloat(head) < parseFloat(prevHead)) {
+                issues.push('DEPS must be ordered by head index');
+                return false;
+            }
+            prevHead = head;
+        }
+        return true;
+    };
+
+    Element.prototype.validateMisc = function(misc, issues) {
+        issues = (issues !== undefined ? issues : []);
+
+        if (!this.validateField(misc, 'MISC', issues)) {
+            return false;
+        } else {
+            return true;
+        }
+    };
+
+    Element.prototype.validHeadReference = function(elementById) {
+        return (this.head === '_' || this.head === null || this.head === '0' ||
+                elementById[this.head] !== undefined);
+    };
+
+    Element.prototype.isWord = function() {
+        // word iff ID is an integer
+        return !!this.id.match(/^\d+$/);
+    };
+
+    Element.prototype.isMultiword = function() {
+        return !!this.id.match(/^\d+-\d+$/);
+    };
+
+    Element.prototype.isEmptyNode = function() {
+        return !!this.id.match(/^\d+\.\d+$/);
+    };
+
+    Element.prototype.rangeFrom = function() {
+        return parseInt(this.id.match(/^(\d+)-\d+$/)[1], 10);
+    };
+
+    Element.prototype.rangeTo = function() {
+        return parseInt(this.id.match(/^\d+-(\d+)$/)[1], 10);
+    };
+
+    Element.prototype.isToken = function(inRange) {
+        // token iff multiword or not included in a multiword range
+        return this.isMultiword() || !inRange[this.id];
+    };
+
+    // return list of (DEPENDENT, HEAD, DEPREL) lists
+    Element.prototype.dependencies = function(skipHead) {
+        skipHead = (skipHead !== undefined ? skipHead : false);
+
+        var elemDeps = [];
+        if (!skipHead && this.head !== '_' && this.head !== null) {
+            elemDeps.push([this.id, this.head, this.deprel]);
+        }
+        if (this.deps != '_') {
+            var deparr = this.deps.split('|');
+            for (var i=0; i<deparr.length; i++) {
+                var dep = deparr[i];
+                m = dep.match(dependencyRegex);
+                if (m) {
+                    elemDeps.push([this.id, m[1], m[2]]);
+                } else {
+                    console.log('internal error: dependencies(): invalid DEPS',
+                                this.deps);
+                }
+            }
+        }
+        return elemDeps;
+    }
+
+    // return list of (name, value) pairs
+    Element.prototype.features = function() {
+        var nameVals = [];
+        if (this.feats === '_') {
+            return [];
+        }
+        var featarr = this.feats.split('|');
+        for (var i=0; i<featarr.length; i++) {
+            var feat = featarr[i];
+            var m = feat.match(featureRegex);
+            if (!m) {
+                continue;
+            }
+            var name = m[1], valuestr = m[2];
+            var values = valuestr.split(',');
+            for (var j=0; j<values.length; j++) {
+                var value = values[j];
+                var m = value.match(featureValueRegex);
+                if (!m) {
+                    continue;
+                }
+                nameVals.push([name, value]);
+            }
+        }
+        return nameVals;
+    };
+
+    // Check validity of the element. Return list of strings
+    // representing issues found in validation (empty list if none).
+    Element.prototype.validate = function() {
+        var issues = [];
+
+        this.validateId(this.id, issues);
+        this.validateForm(this.form, issues);
+        
+        // multiword tokens (elements with range IDs) are (locally) valid
+        // iff all remaining fields (3-10) contain just an underscore.
+        if (this.isMultiword()) {
+            if (this.lemma != '_' || 
+                this.upostag != '_' ||
+                this.xpostag != '_' ||
+                this.feats != '_' ||
+                this.head != '_' ||
+                this.deprel != '_' ||
+                this.deps != '_' ||
+                this.misc != '_') {
+                issues.push('non-underscore field for multiword token');
+            }
+            return issues;
+        }
+        // if we're here, not a multiword token.
+
+        this.validateLemma(this.lemma, issues);
+        this.validateUpostag(this.upostag, issues);
+        this.validateXpostag(this.xpostag, issues);
+        this.validateFeats(this.feats, issues);
+        this.validateHead(this.head, issues);
+        this.validateDeprel(this.deprel, issues);
+        this.validateDeps(this.deps, issues);
+        this.validateMisc(this.misc, issues);
+
+        return issues;
+    };
+
+    // Attempt to repair a non-valid element. Return true iff the
+    // element is valid following repair, false otherwise.
+    Element.prototype.repair = function(log) {
+        log = (log !== undefined ? log : nullLogger);
+
+        if (!this.validateId(this.id)) {
+            return false; // can't be helped
+        } 
+
+        if (!this.validateForm(this.form)) {
+            log('repair: blanking invalid FORM');
+            this.form = '<ERROR>';
+        }
+
+        if (this.isMultiword()) {
+            // valid as long as everything is blank
+            this.lemma = '_'; 
+            this.upostag = '_';
+            this.xpostag = '_';
+            this.feats = '_';
+            this.head = '_';
+            this.deprel = '_';
+            this.deps = '_';
+            this.misc = '_';
+            return true;
+        }
+        // if we're here, not a multiword token.
+
+        if(!this.validateLemma(this.lemma)) {
+            log('repair: blanking invalid LEMMA');
+            this.lemma = '<ERROR>';
+        }
+
+        if(!this.validateUpostag(this.upostag)) {
+            log('repair: blanking invalid UPOSTAG');
+            this.upostag = '_'; // TODO: not valid
+        }
+
+        if(!this.validateXpostag(this.xpostag)) {
+            log('repair: blanking invalid XPOSTAG');
+            this.xpostag = '_';
+        }
+
+        if(!this.validateFeats(this.feats)) {
+            log('repair: blanking invalid FEATS');
+            this.feats = '_';
+        }
+
+        if(!this.validateHead(this.head)) {
+            log('repair: blanking invalid HEAD');
+            this.head = null; // note: exceptional case
+        }
+
+        if(!this.validateDeprel(this.deprel)) {
+            log('repair: blanking invalid DEPREL');
+            this.deprel = '_'; // TODO: not valid
+        }
+
+        if(!this.validateDeps(this.deps)) {
+            log('repair: blanking invalid DEPS');
+            this.deps = '_';
+        }
+
+        if(!this.validateMisc(this.misc)) {
+            log('repair: blanking invalid MISC');
+            this.misc = '_';
+        }
+
+        var issues = this.validate();
+        return issues.length === 0;
+    };
+
+    /*
+     * Miscellaneous support functions.
+     */
+
+    var repairFields = function(fields, logger) {
+        if (logger === undefined) {
+            logger = nullLogger;
+        }
+        if (fields.length > 10) {
+            logger('repair: discarding fields > 10');
+            fields = fields.slice(0, 10);
+        } else {
+            logger('repair: filling in empty ("_") for missing fields');
+            for (var m=0; m<10-fields.length; m++) {
+                fields.push('_');
+            }
+        }
+    };
+
+    var strictFieldSplitter = function(line) {
+        // strict CoNLL format parsing: only split on TAB, no extra space.
+        if (line.length === 0) {
+            return [];
+        } else {
+            return line.split('\t');
+        }
+    }
+
+    var looseFieldSplitter = function(line) {
+        // loose CoNLL format parsing: split on any space sequence, trim
+        // surrounding space.    
+        line = line.trim();
+        if (line.length === 0) {
+            return [];
+        } else {
+            return line.split(/\s+/);
+        }
+    }
+
+    var selectParsingMode = function(conll, log) {
+        // return whether to use strict mode parsing
+
+        // very simple heuristic: any TABs in the input trigger
+        // strict parsing, loose only if none present.
+        if (conll.indexOf('\t') !== -1) {
+            log('note: TAB found, parsing CoNLL-U in strict mode.')
+            return true;
+        } else {
+            log('note: no TAB found, parsing CoNLL-U in loose mode.')
+            return false;
+        }
+    };
+
+    var selectFieldSplitter = function(conll, log, strict) {
+        // return function to use for dividing lines into fields.
+        if (strict) {
+            return strictFieldSplitter;
+        } else {
+            return looseFieldSplitter;
+        }
+    };
+
+    var isComment = function(line) {
+        return line.length !== 0 && line[0] === '#';
+    };
+
+    var hasSpace = function(s) {
+        return !!s.match(/\s/);
+    };
+
+    var nullLogger = function(message) {
+        return null;
+    }
+
+    /* 
+     * Return true iff given string only contains characters from a
+     * right-to-left Unicode block and is not empty.
+     */
+    var isRtl = function(s) {
+        // range from http://stackoverflow.com/a/14824756
+        return !!s.match(/^[\u0591-\u07FF\uFB1D-\uFDFD\uFE70-\uFEFC]+$/);
+    };
+
+    /*
+     * Return given token with possible modifications to accommodate
+     * issues in brat rendering of right-to-left text
+     * (https://github.com/UniversalDependencies/docs/issues/52)
+     */
+    var rtlFix = function(s) {
+        var prefix = '\u02D1',
+            suffix = '\u02D1';
+        if (isRtl(s)) {
+            s = prefix + s + suffix;
+        }
+        return s;
+    };
+
+    /*
+     * Return a deep copy of the given object. Note: not particularly
+     * efficient, and all fields must be serializable for this to work
+     * correctly.
+     */
+    var deepCopy = function(o) {
+        return JSON.parse(JSON.stringify(o));
+    };
+
+    /*
+     * Regular expressions for various parts of the format.
+     * See https://github.com/UniversalDependencies/docs/issues/33
+     */
+
+    // match single (feature, value[s]) pair in FEATS
+    var featureRegex = /^([A-Z0-9][a-zA-Z0-9]*(?:\[[a-z0-9]+\])?)=([A-Z0-9][a-zA-Z0-9]*(?:,[A-Z0-9][a-zA-Z0-9]*)*)$/;
+
+    // match single feature value in FEATS
+    var featureValueRegex = /^[A-Z0-9][a-zA-Z0-9]*$/;
+
+    // match single (head, deprel) pair in DEPS
+    var dependencyRegex = /^(\d+(?:\.\d+)?):(.*)$/;
+
+    return {
+	Document: Document,
+	Sentence: Sentence,
+        Element: Element,
+    };
+
+})(window);

Property changes on: TXM/trunk/org.txm.conllu.core/template/conllu.js
___________________________________________________________________
Added: svn:mime-type
   + text/plain

Index: TXM/trunk/org.txm.conllu.core/template/static/fonts/Liberation_Sans-Regular.ttf
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: TXM/trunk/org.txm.conllu.core/template/static/fonts/Liberation_Sans-Regular.ttf
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: TXM/trunk/org.txm.conllu.core/template/static/fonts/PT_Sans-Caption-Web-Regular.ttf
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: TXM/trunk/org.txm.conllu.core/template/static/fonts/PT_Sans-Caption-Web-Regular.ttf
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: TXM/trunk/org.txm.conllu.core/template/static/img/visualization-example.png
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: TXM/trunk/org.txm.conllu.core/template/static/img/visualization-example.png
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: TXM/trunk/org.txm.conllu.core/template/static/img/processing.png
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: TXM/trunk/org.txm.conllu.core/template/static/img/processing.png
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: TXM/trunk/org.txm.conllu.core/template/static/img/gh-edit.png
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: TXM/trunk/org.txm.conllu.core/template/static/img/gh-edit.png
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: TXM/trunk/org.txm.conllu.core/template/css/main.css
===================================================================
--- TXM/trunk/org.txm.conllu.core/template/css/main.css	(revision 0)
+++ TXM/trunk/org.txm.conllu.core/template/css/main.css	(revision 3567)
@@ -0,0 +1,514 @@
+/* Base */
+/* ----------------------------------------------------------*/
+
+* {
+  margin: 0;
+  padding: 0;
+}
+
+html, body { height: 100%; }
+
+body {
+  font-family: Helvetica, Arial, sans-serif;
+  font-size: 16px;
+  line-height: 1.5;
+  font-weight: 300;
+  background-color: #fdfdfd;
+}
+
+h1, h2, h3, h4, h5, h6 { font-size: 100%; font-weight: 400; }
+
+a         { color: #2a7ae2; text-decoration: none; }
+a:hover   { color: #000; text-decoration: underline; }
+a:visited { color: #205caa; }
+
+/* Utility */
+
+.wrap:before,
+.wrap:after { content:""; display:table; }
+.wrap:after { clear: both; }
+.wrap {
+  max-width: 800px;
+  padding: 0 30px;
+  margin: 0 auto;
+  zoom: 1;
+}
+
+
+/* Layout Styles */
+/* ----------------------------------------------------------*/
+
+/* Site header */
+
+.site-header {
+  border-top: 5px solid #333;
+  border-bottom: 1px solid #e8e8e8;
+  min-height: 56px;
+  background-color: white;
+}
+
+.site-title,
+.site-title:hover,
+.site-title:visited {
+  display: block;
+  color: #333;
+  font-size: 26px;
+  letter-spacing: -1px;
+  float: left;
+  line-height: 56px;
+  position: relative;
+  z-index: 1;
+}
+
+.site-nav {
+  float: right;
+  line-height: 56px;
+}
+
+.site-nav .menu-icon { display: none; }
+
+.site-nav .page-link {
+  margin-left: 20px;
+  color: #727272;
+  letter-spacing: -.5px;
+}
+
+/* Site footer */
+
+.site-footer {
+  border-top: 1px solid #e8e8e8;
+  padding: 30px 0;
+}
+
+.footer-heading {
+  font-size: 18px;
+  font-weight: 300;
+  letter-spacing: -.5px;
+  margin-bottom: 15px;
+}
+
+.site-footer .column { float: left; margin-bottom: 15px; }
+
+.footer-col-1 {
+  width: 270px; /*fallback*/
+  width: -webkit-calc(35% - 10px);
+  width: -moz-calc(35% - 10px);
+  width: -o-calc(35% - 10px);
+  width: calc(35% - 10px);
+  margin-right: 10px
+}
+.footer-col-2 {
+  width: 175px; /*fallback*/
+  width: -webkit-calc(23.125% - 10px);
+  width: -moz-calc(23.125% - 10px);
+  width: -o-calc(23.125% - 10px);
+  width: calc(23.125% - 10px);
+  margin-right: 10px
+}
+.footer-col-3 {
+  width: 335px; /*fallback*/
+  width: -webkit-calc(41.875%);
+  width: -moz-calc(41.875%);
+  width: -o-calc(41.875%);
+  width: calc(41.875%);
+}
+
+.small-gray,
+.site-footer p {
+  font-size: 15px;
+  letter-spacing: -.3px;
+  color: #828282;
+}
+
+/* Page Content styles */
+/* ----------------------------------------------------------*/
+
+.page-content {
+  padding: 30px 0;
+  background-color: #fff;
+}
+
+
+/* Home styles */
+/* ----------------------------------------------------------*/
+
+.home h1 { margin-bottom: 25px; }
+
+.posts { list-style-type: none; }
+
+.posts li { margin-bottom: 30px; }
+
+.posts .post-link {
+  font-size: 24px;
+  letter-spacing: -1px;
+  line-height: 1;
+}
+
+.posts .post-date {
+  display: block;
+  font-size: 15px;
+  color: #818181;
+}
+
+/* Entry styles */
+/* ----------------------------------------------------------*/
+
+.entry-header { margin: 10px 0 30px; }
+
+.entry-header h1 {
+  font-size: 36px;
+  letter-spacing: -1.75px;
+  line-height: 1;
+  font-weight: 300;
+}
+
+.entry-header .meta {
+  font-size: 15px;
+  color: #818181;
+  margin-top: 5px;
+}
+
+.entry-content { margin: 0 0 30px; }
+
+.entry-content > * { margin: 20px 0; }
+
+.entry-content h1,
+.entry-content h2,
+.entry-content h3,
+.entry-content h4,
+.entry-content h5,
+.entry-content h6 {
+  line-height: 1;
+  font-weight: 300;
+  margin: 40px 0 20px;
+}
+
+.entry-content h2 {
+  font-size: 28px;
+  letter-spacing: -1.25px;
+}
+
+.entry-content h3 {
+  font-size: 22px;
+  letter-spacing: -1px;
+}
+
+.entry-content h4 {
+  font-size: 18px;
+  letter-spacing: -1px;
+}
+
+.entry-content blockquote {
+  border-left: 4px solid #e8e8e8;
+  padding-left: 20px;
+  font-size: 18px;
+  opacity: .6;
+  letter-spacing: -1px;
+  font-style: italic;
+  margin: 30px 0;
+}
+
+.entry-content ul,
+.entry-content ol { padding-left: 20px; }
+
+.entry pre,
+.entry code {
+  border: 1px solid #d5d5e9;
+  background-color: #eef;
+  padding: 8px 12px;
+  -webkit-border-radius: 3px;
+  -moz-border-radius: 3px;
+  border-radius: 3px;
+  font-size: 15px;
+}
+
+.entry code { padding: 1px 5px; }
+
+.entry ul,
+.entry ol { margin-left: 1.35em; }
+
+.entry pre code { 
+  padding: 0;
+  border: none; 
+}
+
+/* terminal */
+.entry pre.terminal {
+  border: 1px solid #000;
+  background-color: #333;
+  color: #FFF;
+  -webkit-border-radius: 3px;
+  -moz-border-radius: 3px;
+  border-radius: 3px;
+}
+
+.entry pre.terminal code { background-color: #333; }
+
+/* Post styles */
+/* ----------------------------------------------------------*/
+
+.post-header { margin: 10px 0 30px; }
+
+.post-header h1 {
+  font-size: 42px;
+  letter-spacing: -1.75px;
+  line-height: 1;
+  font-weight: 300;
+}
+
+.post-header .meta {
+  font-size: 15px;
+  color: #818181;
+  margin-top: 5px;
+}
+
+.post-content { margin: 0 0 30px; }
+
+.post-content > * { margin: 20px 0; }
+
+
+.post-content h1,
+.post-content h2,
+.post-content h3,
+.post-content h4,
+.post-content h5,
+.post-content h6 {
+  line-height: 1;
+  font-weight: 300;
+  margin: 40px 0 20px;
+}
+
+.post-content h2 {
+  font-size: 32px;
+  letter-spacing: -1.25px;
+}
+
+.post-content h3 {
+  font-size: 26px;
+  letter-spacing: -1px;
+}
+
+.post-content h4 {
+  font-size: 20px;
+  letter-spacing: -1px;
+}
+
+.post-content blockquote {
+  border-left: 4px solid #e8e8e8;
+  padding-left: 20px;
+  font-size: 18px;
+  opacity: .6;
+  letter-spacing: -1px;
+  font-style: italic;
+  margin: 30px 0;
+}
+
+.post-content ul,
+.post-content ol { padding-left: 20px; }
+
+.post pre,
+.post code {
+  border: 1px solid #d5d5e9;
+  background-color: #eef;
+  padding: 8px 12px;
+  -webkit-border-radius: 3px;
+  -moz-border-radius: 3px;
+  border-radius: 3px;
+  font-size: 15px;
+}
+
+.post code { padding: 1px 5px; }
+
+.post ul,
+.post ol { margin-left: 1.35em; }
+
+.post pre code { border: none; }
+
+/* terminal */
+.post pre.terminal {
+  border: 1px solid #000;
+  background-color: #333;
+  color: #FFF;
+  -webkit-border-radius: 3px;
+  -moz-border-radius: 3px;
+  border-radius: 3px;
+}
+
+.post pre.terminal code { background-color: #333; }
+
+/* Syntax highlighting styles */
+/* ----------------------------------------------------------*/
+
+.highlight  { background: #ffffff; }
+.highlight .c { color: #999988; font-style: italic } /* Comment */
+.highlight .err { color: #a61717; background-color: #e3d2d2 } /* Error */
+.highlight .k { font-weight: bold } /* Keyword */
+.highlight .o { font-weight: bold } /* Operator */
+.highlight .cm { color: #999988; font-style: italic } /* Comment.Multiline */
+.highlight .cp { color: #999999; font-weight: bold } /* Comment.Preproc */
+.highlight .c1 { color: #999988; font-style: italic } /* Comment.Single */
+.highlight .cs { color: #999999; font-weight: bold; font-style: italic } /* Comment.Special */
+.highlight .gd { color: #000000; background-color: #ffdddd } /* Generic.Deleted */
+.highlight .gd .x { color: #000000; background-color: #ffaaaa } /* Generic.Deleted.Specific */
+.highlight .ge { font-style: italic } /* Generic.Emph */
+.highlight .gr { color: #aa0000 } /* Generic.Error */
+.highlight .gh { color: #999999 } /* Generic.Heading */
+.highlight .gi { color: #000000; background-color: #ddffdd } /* Generic.Inserted */
+.highlight .gi .x { color: #000000; background-color: #aaffaa } /* Generic.Inserted.Specific */
+.highlight .go { color: #888888 } /* Generic.Output */
+.highlight .gp { color: #555555 } /* Generic.Prompt */
+.highlight .gs { font-weight: bold } /* Generic.Strong */
+.highlight .gu { color: #aaaaaa } /* Generic.Subheading */
+.highlight .gt { color: #aa0000 } /* Generic.Traceback */
+.highlight .kc { font-weight: bold } /* Keyword.Constant */
+.highlight .kd { font-weight: bold } /* Keyword.Declaration */
+.highlight .kp { font-weight: bold } /* Keyword.Pseudo */
+.highlight .kr { font-weight: bold } /* Keyword.Reserved */
+.highlight .kt { color: #445588; font-weight: bold } /* Keyword.Type */
+.highlight .m { color: #009999 } /* Literal.Number */
+.highlight .s { color: #d14 } /* Literal.String */
+.highlight .na { color: #008080 } /* Name.Attribute */
+.highlight .nb { color: #0086B3 } /* Name.Builtin */
+.highlight .nc { color: #445588; font-weight: bold } /* Name.Class */
+.highlight .no { color: #008080 } /* Name.Constant */
+.highlight .ni { color: #800080 } /* Name.Entity */
+.highlight .ne { color: #990000; font-weight: bold } /* Name.Exception */
+.highlight .nf { color: #990000; font-weight: bold } /* Name.Function */
+.highlight .nn { color: #555555 } /* Name.Namespace */
+.highlight .nt { color: #000080 } /* Name.Tag */
+.highlight .nv { color: #008080 } /* Name.Variable */
+.highlight .ow { font-weight: bold } /* Operator.Word */
+.highlight .w { color: #bbbbbb } /* Text.Whitespace */
+.highlight .mf { color: #009999 } /* Literal.Number.Float */
+.highlight .mh { color: #009999 } /* Literal.Number.Hex */
+.highlight .mi { color: #009999 } /* Literal.Number.Integer */
+.highlight .mo { color: #009999 } /* Literal.Number.Oct */
+.highlight .sb { color: #d14 } /* Literal.String.Backtick */
+.highlight .sc { color: #d14 } /* Literal.String.Char */
+.highlight .sd { color: #d14 } /* Literal.String.Doc */
+.highlight .s2 { color: #d14 } /* Literal.String.Double */
+.highlight .se { color: #d14 } /* Literal.String.Escape */
+.highlight .sh { color: #d14 } /* Literal.String.Heredoc */
+.highlight .si { color: #d14 } /* Literal.String.Interpol */
+.highlight .sx { color: #d14 } /* Literal.String.Other */
+.highlight .sr { color: #009926 } /* Literal.String.Regex */
+.highlight .s1 { color: #d14 } /* Literal.String.Single */
+.highlight .ss { color: #990073 } /* Literal.String.Symbol */
+.highlight .bp { color: #999999 } /* Name.Builtin.Pseudo */
+.highlight .vc { color: #008080 } /* Name.Variable.Class */
+.highlight .vg { color: #008080 } /* Name.Variable.Global */
+.highlight .vi { color: #008080 } /* Name.Variable.Instance */
+.highlight .il { color: #009999 } /* Literal.Number.Integer.Long */
+
+
+/* media queries */
+/* ----------------------------------------------------------*/
+
+
+@media screen and (max-width: 750px) {
+
+  .footer-col-1 { width: 50%; }
+
+  .footer-col-2 {
+    width: 45%; /*fallback*/
+    width: -webkit-calc(50% - 10px);
+    width: -moz-calc(50% - 10px);
+    width: -o-calc(50% - 10px);
+    width: calc(50% - 10px);
+    margin-right: 0;
+  }
+
+  .site-footer .column.footer-col-3 {
+    width: auto;
+    float: none;
+    clear: both;
+  }
+
+}
+
+@media screen and (max-width: 600px) {
+
+  .wrap { padding: 0 12px; }
+
+  .site-nav {
+    position: fixed;
+    z-index: 10;
+    top: 14px; right: 8px;
+    background-color: white;
+    -webkit-border-radius: 5px;
+    -moz-border-radius: 5px;
+    border-radius: 5px;
+    border: 1px solid #e8e8e8;
+  }
+
+  .site-nav .menu-icon {
+    display: block;
+    font-size: 24px;
+    color: #505050;
+    float: right;
+    width: 36px;
+    text-align: center;
+    line-height: 36px;
+  }
+
+  .site-nav .menu-icon svg { width: 18px; height: 16px; }
+
+  .site-nav .trigger {
+    clear: both;
+    margin-bottom: 5px;
+    display: none;
+  }
+
+  .site-nav:hover .trigger { display: block; }
+
+  .site-nav .page-link {
+    display: block;
+    text-align: right;
+    line-height: 1.25;
+    padding: 5px 10px;
+    margin: 0;
+  }
+
+  .post-header h1 { font-size: 36px; }
+  .post-content h2 { font-size: 28px; }
+  .post-content h3 { font-size: 22px; }
+  .post-content h4 { font-size: 18px; }
+  .post-content blockquote { padding-left: 10px; }
+  .post-content ul,
+  .post-content ol { padding-left: 10px; }
+
+  .site-footer .column {
+    float: none;
+    clear: both;
+    width: auto;
+    margin: 0 0 15px; }
+
+}
+
+/* local styles */
+
+div.documentation-example {
+  border: 1px solid gray;
+  margin:1em;
+  padding:2em;
+}
+
+a.topnav  {
+  float: left;
+  margin-top: 10px;
+  margin-bottom: 10px;
+  margin-left: 0px;
+  margin-right: 40px;
+}
+
+/* span.site-title { */
+/*   clear: both; */
+/* } */
+
+.site-title-topnav {
+  color: #333;
+  font-size: 16px;
+  letter-spacing: -1px;
+  float: right;
+  line-height: 40px;
+}

Property changes on: TXM/trunk/org.txm.conllu.core/template/css/main.css
___________________________________________________________________
Added: svn:mime-type
   + text/plain

Index: TXM/trunk/org.txm.conllu.core/template/css/images/ui-bg_glass_75_d0e5f5_1x400.png
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: TXM/trunk/org.txm.conllu.core/template/css/images/ui-bg_glass_75_d0e5f5_1x400.png
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: TXM/trunk/org.txm.conllu.core/template/css/images/ui-icons_6da8d5_256x240.png
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: TXM/trunk/org.txm.conllu.core/template/css/images/ui-icons_6da8d5_256x240.png
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: TXM/trunk/org.txm.conllu.core/template/css/images/ui-icons_469bdd_256x240.png
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: TXM/trunk/org.txm.conllu.core/template/css/images/ui-icons_469bdd_256x240.png
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: TXM/trunk/org.txm.conllu.core/template/css/images/ui-bg_flat_55_fbec88_40x100.png
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: TXM/trunk/org.txm.conllu.core/template/css/images/ui-bg_flat_55_fbec88_40x100.png
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: TXM/trunk/org.txm.conllu.core/template/css/images/ui-icons_2e83ff_256x240.png
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: TXM/trunk/org.txm.conllu.core/template/css/images/ui-icons_2e83ff_256x240.png
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: TXM/trunk/org.txm.conllu.core/template/css/images/ui-bg_glass_95_fef1ec_1x400.png
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: TXM/trunk/org.txm.conllu.core/template/css/images/ui-bg_glass_95_fef1ec_1x400.png
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: TXM/trunk/org.txm.conllu.core/template/css/images/ui-icons_217bc0_256x240.png
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: TXM/trunk/org.txm.conllu.core/template/css/images/ui-icons_217bc0_256x240.png
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: TXM/trunk/org.txm.conllu.core/template/css/images/ui-icons_d8e7f3_256x240.png
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: TXM/trunk/org.txm.conllu.core/template/css/images/ui-icons_d8e7f3_256x240.png
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: TXM/trunk/org.txm.conllu.core/template/css/images/ui-bg_glass_85_dfeffc_1x400.png
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: TXM/trunk/org.txm.conllu.core/template/css/images/ui-bg_glass_85_dfeffc_1x400.png
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: TXM/trunk/org.txm.conllu.core/template/css/images/ui-bg_inset-hard_100_f5f8f9_1x100.png
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: TXM/trunk/org.txm.conllu.core/template/css/images/ui-bg_inset-hard_100_f5f8f9_1x100.png
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: TXM/trunk/org.txm.conllu.core/template/css/images/ui-icons_f9bd01_256x240.png
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: TXM/trunk/org.txm.conllu.core/template/css/images/ui-icons_f9bd01_256x240.png
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: TXM/trunk/org.txm.conllu.core/template/css/images/ui-bg_inset-hard_100_fcfdfd_1x100.png
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: TXM/trunk/org.txm.conllu.core/template/css/images/ui-bg_inset-hard_100_fcfdfd_1x100.png
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: TXM/trunk/org.txm.conllu.core/template/css/images/ui-icons_cd0a0a_256x240.png
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: TXM/trunk/org.txm.conllu.core/template/css/images/ui-icons_cd0a0a_256x240.png
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: TXM/trunk/org.txm.conllu.core/template/css/images/ui-bg_flat_0_aaaaaa_40x100.png
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: TXM/trunk/org.txm.conllu.core/template/css/images/ui-bg_flat_0_aaaaaa_40x100.png
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: TXM/trunk/org.txm.conllu.core/template/css/images/ui-bg_gloss-wave_55_5c9ccc_500x100.png
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: TXM/trunk/org.txm.conllu.core/template/css/images/ui-bg_gloss-wave_55_5c9ccc_500x100.png
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: TXM/trunk/org.txm.conllu.core/template/css/style-vis.css
===================================================================
--- TXM/trunk/org.txm.conllu.core/template/css/style-vis.css	(revision 0)
+++ TXM/trunk/org.txm.conllu.core/template/css/style-vis.css	(revision 3567)
@@ -0,0 +1,589 @@
+/* -*- Mode: CSS; tab-width: 2; indent-tabs-mode: nil; -*- */
+/* vim:set ft=css ts=2 sw=2 sts=2 autoindent: */
+
+/* Styling for annotations */
+
+#svg {
+  margin: 34px auto 100px;
+  padding-top: 15px;
+}
+
+.center_wrapper {
+  display: table;
+  position: absolute;
+  top: 0;
+  left: 0;
+  height: 100%;
+  width: 100%;
+}
+.center_wrapper > div {
+  display: table-cell;
+  vertical-align: middle;
+}
+.center_wrapper > div > div {
+  /* match jQuery UI .ui-widget-content color */
+  color: #2e6e9e;
+  margin-left: auto;
+  margin-right: auto;
+  width: 30em;
+  font-size: 12px;
+  font-family: 'Liberation Sans', Verdana, Arial, Helvetica, sans-serif;
+}
+.center_wrapper > div > div h1 {
+  text-align: center;
+  font-size: 14px;
+}
+#no_svg_wrapper {
+  display: none;
+}
+
+svg {
+  width: 100%;
+  height: 1px;
+  border: 1px solid #7fa2ff;
+  font-size: 15px;
+  /* font-size: 14px; */
+}
+svg.reselect {
+  border: 1px solid #ff3333;
+}
+div.haserror > svg {
+  border: 1px solid red;
+}
+
+/* "basic" font */
+text {
+  font-size: 13px;
+  font-family: 'Liberation Sans', Verdana, Arial, Helvetica, sans-serif;
+}
+
+@-webkit-keyframes pulse {
+  0% { color: #9999ff; margin-top: 0; }
+  50% { color: #ffffff; margin-top: 7px; }
+  100% { color: #9999ff; margin-top: 0; }
+}
+
+path {
+  pointer-events: none;
+}
+
+/* "basic" font */
+.span text {
+  /*  font-size: 10.5px; */
+  font-size: 10px;
+  text-anchor: middle;
+  font-family: 'PT Sans Caption', sans-serif;
+  pointer-events: none;
+}
+
+/* this should likely match span font */
+.span_type_label {
+  font-size: 11px;
+  font-family: 'PT Sans Caption', sans-serif;
+}
+/* this should likely match arc font */
+.arc_type_label {
+  font-size: 11px;
+  font-family: 'PT Sans Caption', sans-serif;
+}
+.attribute_type_label .ui-button-text {
+  font-size: 11px;
+  font-family: 'PT Sans Caption', sans-serif;
+}
+
+.span rect {
+  stroke-width: 0.75;
+}
+
+.glyph {
+  fill: #444444;
+  font-family: sans-serif;
+  font-weight: bold;
+}
+.attribute_warning {
+  baseline-shift: super;
+  font-size: 70%;
+}
+
+.span rect.False_positive {
+  stroke: #ff4141;
+  stroke-width: 2;
+}
+
+.shadow_True_positive {
+  fill: #00ff00;
+}
+
+.shadow_False_positive {
+  fill: #ff4141;
+}
+
+#commentpopup.comment_False_positive {
+  background-color: #ff4141;
+}
+
+.span rect.False_negative {
+  stroke: #c20000;
+  fill: #ffffff;
+  stroke-width: 2;
+}
+
+.shadow_False_negative {
+  fill: #c20000;
+}
+
+#commentpopup.comment_False_negative {
+  background-color: #c20000;
+}
+
+.span rect.AnnotationError {
+  stroke-width: 1;
+}
+
+.shadow_AnnotationError {
+  fill: #ff0000;
+}
+
+#commentpopup.comment_AnnotationError {
+  background-color: #ff7777;
+}
+
+.span rect.AnnotationWarning {
+  stroke-width: 1;
+}
+
+.shadow_AnnotationWarning {
+  fill: #ff8800;
+}
+
+#commentpopup.comment_AnnotationWarning {
+  background-color: #ff9900;
+}
+
+.shadow_AnnotatorNotes {
+  /* fill: #00cc00; */
+  fill: #3ab7ee;
+}
+#commentpopup.comment_AnnotatorNotes {
+  /* background-color: #00cc00; */
+  /* background-color: #DAF7DC; */
+  background-color: #d7e7ee;
+}
+
+.shadow_Normalized {
+  /* fill: #00cc00; */
+  fill: #3aee37;
+}
+#commentpopup.comment_Normalized {
+  /* background-color: #00cc00; */
+  /* background-color: #DAF7DC; */
+  background-color: #d7eee7;
+}
+rect.Normalized {
+  stroke-width: 1.5;
+}
+
+.shadow_AnnotationIncomplete {
+  fill: #aaaaaa;
+}
+.span rect.AnnotationIncomplete {
+  stroke: #002200;
+  stroke-width: 0.5;
+  fill: #ffffff;
+}
+#commentpopup.comment_AnnotationIncomplete {
+  background-color: #ffff77;
+}
+
+.shadow_AnnotationUnconfirmed {
+  fill: #eeeeee;
+}
+.span rect.AnnotationUnconfirmed {
+  stroke: #002200;
+  stroke-width: 0.5;
+  opacity : 0.5;
+}
+#commentpopup.comment_AnnotationUnconfirmed {
+  background-color: #ddddff;
+}
+
+.span rect.True_positive {
+  /* stroke: #007700; */
+}
+
+rect.shadow_EditHighlight {
+  fill: #ffff99;
+}
+.shadow_EditHighlight_arc {
+  stroke: #ffff99;
+}
+
+.span path {
+  fill: none;
+}
+
+.span path.curly {
+  /* 'stroke' def here blocks 'stroke' set in JS..? */
+  /* stroke: grey; */
+  stroke-width: 0.5;
+}
+
+.span path.boxcross {
+  stroke: black;
+  opacity: 0.5;
+}
+
+.arcs path {
+  stroke: #989898;
+  fill: none;
+  stroke-width: 1;
+}
+
+.arcs .highlight path {
+  stroke: #000000;
+  stroke-width: 1.5;
+  opacity: 1;
+}
+.arcs .highlight text {
+  stroke: black;
+  fill: black;
+  stroke-width: 0.5;
+}
+.span.highlight rect {
+  stroke-width: 2px;
+}
+.span rect.reselect {
+  stroke-width: 2px;
+}
+.span rect.reselectTarget {
+  stroke-width: 2px;
+}
+.arcs .reselect path {
+  stroke-width: 2px;
+  stroke: #ff0000 !important;
+}
+.arcs .reselect text {
+  fill: #ff0000 !important;
+}
+
+.span rect.badTarget {
+  stroke: #f00;
+}
+
+.arcs text {
+  font-size: 9px;
+  text-anchor: middle;
+  font-family: 'PT Sans Caption', sans-serif;
+  /* dominant-baseline: central; */
+  cursor: default;
+}
+
+.background0 {
+  stroke: none;
+  fill: #ffffff;
+}
+
+.background1 {
+  stroke: none;
+  fill: #eeeeee;
+}
+
+.backgroundHighlight {
+  stroke: none;
+  fill: #ffff99;
+}
+
+.sentnum text {
+  display: none; /* sentence number disabled for the time being. */
+  fill: #999999;
+  text-anchor: end;
+}
+
+.sentnum path {
+  display: none; /* sentence number disabled for the time being. */
+  stroke: #999999;
+  stroke-width: 1px;
+}
+
+.span_cue {
+  fill: #eeeeee !important;
+}
+
+.drag_stroke {
+  stroke: black;
+}
+.drag_fill {
+  fill: black;
+}
+
+
+.dialog {
+  display: none;
+}
+#span_free_div, #arc_free_div {
+  float: left;
+}
+fieldset {
+  /* match relevant parts of jQuery UI .ui-widget-content */
+  border: 1px solid #a6c9e2;
+  /* round corners, same as jQuery UI .ui-corner-all */
+  -moz-border-radius: 5px;
+  -webkit-border-radius: 5px;
+  border-radius: 5px;
+  /* to prevent border from running into legend */
+  margin-top: 5px;
+}
+fieldset legend {
+  font-weight: bold;
+  font-size: 90%;
+  -moz-border-radius: 3px;
+  -webkit-border-radius: 3px;
+  border-radius: 3px;
+  background-color: #70a8d2;
+  color: white;
+  padding-left: 0.5em;
+  padding-right: 0.5em;
+}
+.label-like {
+   /* for UI consistency, this should match the "fieldset legend" style;
+      sorry about the duplication. */
+  font-family: monospace;
+  font-weight: bold;
+  font-size: 90%;
+  /* match jQuery UI .ui-widget-content color */
+  color: #2e6e9e;
+}   
+
+.accesskey {
+  text-decoration: underline;
+}
+
+
+.shadow {
+  -moz-box-shadow: 5px 5px 5px #444444;
+  -webkit-box-shadow: 5px 5px 5px #444444;
+  box-shadow: 5px 5px 5px #444444;
+}
+
+#span_selected, #arc_origin, #arc_target {
+  font-weight: bold;
+}
+
+#commentpopup {
+  font-family: 'Liberation Sans', Verdana, Arial, Helvetica, sans-serif;
+  position: fixed;
+  top: 0;
+  left: 0;
+  opacity: 0.95;
+  padding: 10px;
+  display: none;
+  border: 1px outset #000000;
+  background-color: #f5f5f9;
+  /* background-color: #d7e7ee; */
+  /* background-color: #eeeeee; */
+  color: #000000;
+  z-index: 20;
+  -moz-box-shadow: 5px 5px 5px #aaaaaa;
+  -webkit-box-shadow: 5px 5px 5px #aaaaaa;
+  box-shadow: 5px 5px 5px #aaaaaa;
+  -moz-border-radius: 3px;
+  -webkit-border-radius: 3px;
+  border-radius: 3px;
+  max-width: 80%;
+}
+#more_info_readme {
+  height: 350px;
+}
+#readme_container {
+  position: relative;
+}
+#more_readme_button {                   
+  padding: 2px 5px;
+  position: absolute;
+  top: -2px;
+  right: -2px;
+}
+
+.comment_id {
+  vertical-align: top;
+  float:right;
+  font-size: 75%;
+  font-family: monospace;
+  color: #333333;
+}
+.comment_type {
+  /* font-weight: bold; */
+}
+.comment_text {
+  font-weight: bold;
+}
+.comment_type_id_wrapper {
+  /* padding for floating ID */
+  padding-right: 2em;
+}
+.norm_info_label {
+  font-weight: bold;
+  font-size: 80%;
+}
+.norm_info_value {
+  font-size: 80%;
+}
+.norm_info_img {
+  float: right;
+  margin-left: 1em;
+}
+
+#search_form select {
+  width: 100%; /* deal with overflowing selectboxes */
+}
+
+.scroll_fset {
+  height: 200px;
+}
+.scroll_fset fieldset {
+  height: 100%;
+  overflow-x: hidden;
+  overflow-y: hidden;
+}
+/* HACK to display <legend> properly */
+  .scroll_fset {
+    margin-bottom: 2.5em;
+  }
+  .scroll_fset fieldset {
+    padding-bottom: 2em;
+  }
+/* end HACK */
+.scroll_fset div.scroller {
+  overflow: auto;
+  width: 100%;
+  height: 100%;
+}
+
+#span_highlight_link, #arc_highlight_link, #viewspan_highlight_link {
+  float: right;
+}
+
+.unselectable {
+   -moz-user-select: -moz-none;
+   -khtml-user-select: none;
+   -webkit-user-select: none;
+   -o-user-select: none;
+   user-select: none;
+   cursor: default;
+}
+@font-face {
+  font-family: 'Liberation Sans';
+  font-style: normal;
+  font-weight: normal;
+  src: local('Liberation Sans'), local('Liberation-Sans'), url('../static/fonts/Liberation_Sans-Regular.ttf') format('truetype');
+}
+@font-face {
+  font-family: 'PT Sans Caption';
+  font-style: normal;
+  font-weight: normal;
+  src: local('PT Sans Caption'), local('PTSans-Caption'), url('../static/fonts/PT_Sans-Caption-Web-Regular.ttf') format('truetype');
+}
+
+/* Apple iPad, iPhone, iPod */
+
+* {
+   -webkit-tap-highlight-color: rgba(0,0,0,0);
+   -webkit-text-size-adjust: none;
+   select: none;
+}
+
+.span rect.AddedAnnotation {
+  stroke: #ff4141;
+  stroke-width: 2;
+}
+.shadow_AddedAnnotation {
+  fill: #ff4141;
+}
+#commentpopup.comment_AddedAnnotation {
+  background-color: #ffcccc;
+}
+.span rect.MissingAnnotation {
+  stroke: #ffffff;
+  stroke-width: 2;
+}
+.shadow_MissingAnnotation {
+  fill: #ff4141;
+  opacity: 0.3;
+}
+#commentpopup.comment_MissingAnnotation {
+  background-color: #ffcccc;
+}
+.span rect.MissingAnnotation + text {
+  opacity: 0.5;
+}
+.span rect.ChangedAnnotation {
+  stroke: #ffff99;
+  stroke-width: 2;
+}
+.shadow_ChangedAnnotation {
+  fill: #ff4141;
+}
+#commentpopup.comment_ChangedAnnotation {
+  background-color: #ffcccc;
+}
+
+/* embedding */
+pre.embedding {
+  padding: 0;
+  border: none;
+  overflow: visible;
+  -webkit-border-radius: 0;
+  -moz-border-radius: 0;
+  border-radius: 0;
+  background: none;
+  white-space: normal;
+}
+
+/* same margins for <div> and <pre><div> variants */
+.embedding,
+.embedding.embedded-wrapper {
+  margin: 0.5em 0;
+}
+
+pre.embedded-wrapper,
+code.embedded-wrapper,
+.embedded-wrapper {
+  margin: 0;
+  padding: 0;
+  border: none;
+  -webkit-border-radius: 0;
+  -moz-border-radius: 0;
+  border-radius: 0;
+  background: none;
+  white-space: normal;
+}
+
+.show-hide-div {
+  text-align: right;
+}
+.show-hide-toggle {
+  margin-top: 0px;
+  margin-bottom: 0px;
+  margin-left: 10px;
+  margin-right: 10px;
+  -moz-border-bottom-left-radius: 0px;
+  -moz-border-bottom-right-radius: 0px;
+  -webkit-border-bottom-left-radius: 0px;
+  -webkit-border-bottom-right-radius: 0px;
+  border-bottom-left-radius: 0px;
+  border-bottom-right-radius: 0px;
+}
+.show-hide-toggle .ui-button-text {
+  padding: 1px 4px;
+  font-size: 9px;
+}
+.embedded-brat-data {
+  display: block;
+  width: 100%;
+  height: 100px;
+  font-size: 11px;
+  border: 2px inset
+}
+a.doclink {
+  text-decoration: none;
+}
\ No newline at end of file

Property changes on: TXM/trunk/org.txm.conllu.core/template/css/style-vis.css
___________________________________________________________________
Added: svn:mime-type
   + text/plain

Index: TXM/trunk/org.txm.conllu.core/template/css/jquery-ui-redmond.css
===================================================================
--- TXM/trunk/org.txm.conllu.core/template/css/jquery-ui-redmond.css	(revision 0)
+++ TXM/trunk/org.txm.conllu.core/template/css/jquery-ui-redmond.css	(revision 3567)
@@ -0,0 +1,578 @@
+/*
+ * jQuery UI CSS Framework 1.8.12
+ *
+ * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
+ * Dual licensed under the MIT or GPL Version 2 licenses.
+ * http://jquery.org/license
+ *
+ * http://docs.jquery.com/UI/Theming/API
+ */
+
+/* Layout helpers
+----------------------------------*/
+.ui-helper-hidden { display: none; }
+.ui-helper-hidden-accessible { position: absolute !important; clip: rect(1px 1px 1px 1px); clip: rect(1px,1px,1px,1px); }
+.ui-helper-reset { margin: 0; padding: 0; border: 0; outline: 0; line-height: 1.3; text-decoration: none; font-size: 100%; list-style: none; }
+.ui-helper-clearfix:after { content: "."; display: block; height: 0; clear: both; visibility: hidden; }
+.ui-helper-clearfix { display: inline-block; }
+/* required comment for clearfix to work in Opera \*/
+* html .ui-helper-clearfix { height:1%; }
+.ui-helper-clearfix { display:block; }
+/* end clearfix */
+.ui-helper-zfix { width: 100%; height: 100%; top: 0; left: 0; position: absolute; opacity: 0; filter:Alpha(Opacity=0); }
+
+
+/* Interaction Cues
+----------------------------------*/
+.ui-state-disabled { cursor: default !important; }
+
+
+/* Icons
+----------------------------------*/
+
+/* states and images */
+.ui-icon { display: block; text-indent: -99999px; overflow: hidden; background-repeat: no-repeat; }
+
+
+/* Misc visuals
+----------------------------------*/
+
+/* Overlays */
+.ui-widget-overlay { position: absolute; top: 0; left: 0; width: 100%; height: 100%; }
+
+
+/*
+ * jQuery UI CSS Framework 1.8.12
+ *
+ * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
+ * Dual licensed under the MIT or GPL Version 2 licenses.
+ * http://jquery.org/license
+ *
+ * http://docs.jquery.com/UI/Theming/API
+ *
+ * To view and modify this theme, visit http://jqueryui.com/themeroller/?ffDefault=Lucida%20Grande,%20Lucida%20Sans,%20Arial,%20sans-serif&fwDefault=bold&fsDefault=1.1em&cornerRadius=5px&bgColorHeader=5c9ccc&bgTextureHeader=12_gloss_wave.png&bgImgOpacityHeader=55&borderColorHeader=4297d7&fcHeader=ffffff&iconColorHeader=d8e7f3&bgColorContent=fcfdfd&bgTextureContent=06_inset_hard.png&bgImgOpacityContent=100&borderColorContent=a6c9e2&fcContent=222222&iconColorContent=469bdd&bgColorDefault=dfeffc&bgTextureDefault=02_glass.png&bgImgOpacityDefault=85&borderColorDefault=c5dbec&fcDefault=2e6e9e&iconColorDefault=6da8d5&bgColorHover=d0e5f5&bgTextureHover=02_glass.png&bgImgOpacityHover=75&borderColorHover=79b7e7&fcHover=1d5987&iconColorHover=217bc0&bgColorActive=f5f8f9&bgTextureActive=06_inset_hard.png&bgImgOpacityActive=100&borderColorActive=79b7e7&fcActive=e17009&iconColorActive=f9bd01&bgColorHighlight=fbec88&bgTextureHighlight=01_flat.png&bgImgOpacityHighlight=55&borderColorHighlight=fad42e&fcHighlight=363636&iconColorHighlight=2e83ff&bgColorError=fef1ec&bgTextureError=02_glass.png&bgImgOpacityError=95&borderColorError=cd0a0a&fcError=cd0a0a&iconColorError=cd0a0a&bgColorOverlay=aaaaaa&bgTextureOverlay=01_flat.png&bgImgOpacityOverlay=0&opacityOverlay=30&bgColorShadow=aaaaaa&bgTextureShadow=01_flat.png&bgImgOpacityShadow=0&opacityShadow=30&thicknessShadow=8px&offsetTopShadow=-8px&offsetLeftShadow=-8px&cornerRadiusShadow=8px
+ */
+
+
+/* Component containers
+----------------------------------*/
+.ui-widget { font-family: Lucida Grande, Lucida Sans, Arial, sans-serif; font-size: 0.9em; }
+.ui-widget .ui-widget { font-size: 1em; }
+.ui-widget input, .ui-widget select, .ui-widget textarea, .ui-widget button { font-family: Lucida Grande, Lucida Sans, Arial, sans-serif; font-size: 1em; }
+.ui-widget-content { border: 1px solid #a6c9e2; background: #fcfdfd url(images/ui-bg_inset-hard_100_fcfdfd_1x100.png) 50% bottom repeat-x; color: #222222; }
+.ui-widget-content a { color: #222222; }
+.ui-widget-header { border: 1px solid #4297d7; background: #5c9ccc url(images/ui-bg_gloss-wave_55_5c9ccc_500x100.png) 50% 50% repeat-x; color: #ffffff; font-weight: bold; }
+.ui-widget-header a { color: #ffffff; }
+
+/* Interaction states
+----------------------------------*/
+.ui-state-default, .ui-widget-content .ui-state-default, .ui-widget-header .ui-state-default { border: 1px solid #c5dbec; background: #dfeffc url(images/ui-bg_glass_85_dfeffc_1x400.png) 50% 50% repeat-x; font-weight: bold; color: #2e6e9e; }
+.ui-state-default a, .ui-state-default a:link, .ui-state-default a:visited { color: #2e6e9e; text-decoration: none; }
+.ui-state-hover, .ui-widget-content .ui-state-hover, .ui-widget-header .ui-state-hover, .ui-state-focus, .ui-widget-content .ui-state-focus, .ui-widget-header .ui-state-focus { border: 1px solid #79b7e7; background: #d0e5f5 url(images/ui-bg_glass_75_d0e5f5_1x400.png) 50% 50% repeat-x; font-weight: bold; color: #1d5987; }
+.ui-state-hover a, .ui-state-hover a:hover { color: #1d5987; text-decoration: none; }
+.ui-state-active, .ui-widget-content .ui-state-active, .ui-widget-header .ui-state-active { border: 1px solid #79b7e7; background: #f5f8f9 url(images/ui-bg_inset-hard_100_f5f8f9_1x100.png) 50% 50% repeat-x; font-weight: bold; color: #e17009; }
+.ui-state-active a, .ui-state-active a:link, .ui-state-active a:visited { color: #e17009; text-decoration: none; }
+.ui-widget :active { outline: none; }
+
+/* Interaction Cues
+----------------------------------*/
+.ui-state-highlight, .ui-widget-content .ui-state-highlight, .ui-widget-header .ui-state-highlight  {border: 1px solid #fad42e; background: #fbec88 url(images/ui-bg_flat_55_fbec88_40x100.png) 50% 50% repeat-x; color: #363636; }
+.ui-state-highlight a, .ui-widget-content .ui-state-highlight a,.ui-widget-header .ui-state-highlight a { color: #363636; }
+.ui-state-error, .ui-widget-content .ui-state-error, .ui-widget-header .ui-state-error {border: 1px solid #cd0a0a; background: #fef1ec url(images/ui-bg_glass_95_fef1ec_1x400.png) 50% 50% repeat-x; color: #cd0a0a; }
+.ui-state-error a, .ui-widget-content .ui-state-error a, .ui-widget-header .ui-state-error a { color: #cd0a0a; }
+.ui-state-error-text, .ui-widget-content .ui-state-error-text, .ui-widget-header .ui-state-error-text { color: #cd0a0a; }
+.ui-priority-primary, .ui-widget-content .ui-priority-primary, .ui-widget-header .ui-priority-primary { font-weight: bold; }
+.ui-priority-secondary, .ui-widget-content .ui-priority-secondary,  .ui-widget-header .ui-priority-secondary { opacity: .7; filter:Alpha(Opacity=70); font-weight: normal; }
+.ui-state-disabled, .ui-widget-content .ui-state-disabled, .ui-widget-header .ui-state-disabled { opacity: .35; filter:Alpha(Opacity=35); background-image: none; }
+
+/* Icons
+----------------------------------*/
+
+/* states and images */
+.ui-icon { width: 16px; height: 16px; background-image: url(images/ui-icons_469bdd_256x240.png); }
+.ui-widget-content .ui-icon {background-image: url(images/ui-icons_469bdd_256x240.png); }
+.ui-widget-header .ui-icon {background-image: url(images/ui-icons_d8e7f3_256x240.png); }
+.ui-state-default .ui-icon { background-image: url(images/ui-icons_6da8d5_256x240.png); }
+.ui-state-hover .ui-icon, .ui-state-focus .ui-icon {background-image: url(images/ui-icons_217bc0_256x240.png); }
+.ui-state-active .ui-icon {background-image: url(images/ui-icons_f9bd01_256x240.png); }
+.ui-state-highlight .ui-icon {background-image: url(images/ui-icons_2e83ff_256x240.png); }
+.ui-state-error .ui-icon, .ui-state-error-text .ui-icon {background-image: url(images/ui-icons_cd0a0a_256x240.png); }
+
+/* positioning */
+.ui-icon-carat-1-n { background-position: 0 0; }
+.ui-icon-carat-1-ne { background-position: -16px 0; }
+.ui-icon-carat-1-e { background-position: -32px 0; }
+.ui-icon-carat-1-se { background-position: -48px 0; }
+.ui-icon-carat-1-s { background-position: -64px 0; }
+.ui-icon-carat-1-sw { background-position: -80px 0; }
+.ui-icon-carat-1-w { background-position: -96px 0; }
+.ui-icon-carat-1-nw { background-position: -112px 0; }
+.ui-icon-carat-2-n-s { background-position: -128px 0; }
+.ui-icon-carat-2-e-w { background-position: -144px 0; }
+.ui-icon-triangle-1-n { background-position: 0 -16px; }
+.ui-icon-triangle-1-ne { background-position: -16px -16px; }
+.ui-icon-triangle-1-e { background-position: -32px -16px; }
+.ui-icon-triangle-1-se { background-position: -48px -16px; }
+.ui-icon-triangle-1-s { background-position: -64px -16px; }
+.ui-icon-triangle-1-sw { background-position: -80px -16px; }
+.ui-icon-triangle-1-w { background-position: -96px -16px; }
+.ui-icon-triangle-1-nw { background-position: -112px -16px; }
+.ui-icon-triangle-2-n-s { background-position: -128px -16px; }
+.ui-icon-triangle-2-e-w { background-position: -144px -16px; }
+.ui-icon-arrow-1-n { background-position: 0 -32px; }
+.ui-icon-arrow-1-ne { background-position: -16px -32px; }
+.ui-icon-arrow-1-e { background-position: -32px -32px; }
+.ui-icon-arrow-1-se { background-position: -48px -32px; }
+.ui-icon-arrow-1-s { background-position: -64px -32px; }
+.ui-icon-arrow-1-sw { background-position: -80px -32px; }
+.ui-icon-arrow-1-w { background-position: -96px -32px; }
+.ui-icon-arrow-1-nw { background-position: -112px -32px; }
+.ui-icon-arrow-2-n-s { background-position: -128px -32px; }
+.ui-icon-arrow-2-ne-sw { background-position: -144px -32px; }
+.ui-icon-arrow-2-e-w { background-position: -160px -32px; }
+.ui-icon-arrow-2-se-nw { background-position: -176px -32px; }
+.ui-icon-arrowstop-1-n { background-position: -192px -32px; }
+.ui-icon-arrowstop-1-e { background-position: -208px -32px; }
+.ui-icon-arrowstop-1-s { background-position: -224px -32px; }
+.ui-icon-arrowstop-1-w { background-position: -240px -32px; }
+.ui-icon-arrowthick-1-n { background-position: 0 -48px; }
+.ui-icon-arrowthick-1-ne { background-position: -16px -48px; }
+.ui-icon-arrowthick-1-e { background-position: -32px -48px; }
+.ui-icon-arrowthick-1-se { background-position: -48px -48px; }
+.ui-icon-arrowthick-1-s { background-position: -64px -48px; }
+.ui-icon-arrowthick-1-sw { background-position: -80px -48px; }
+.ui-icon-arrowthick-1-w { background-position: -96px -48px; }
+.ui-icon-arrowthick-1-nw { background-position: -112px -48px; }
+.ui-icon-arrowthick-2-n-s { background-position: -128px -48px; }
+.ui-icon-arrowthick-2-ne-sw { background-position: -144px -48px; }
+.ui-icon-arrowthick-2-e-w { background-position: -160px -48px; }
+.ui-icon-arrowthick-2-se-nw { background-position: -176px -48px; }
+.ui-icon-arrowthickstop-1-n { background-position: -192px -48px; }
+.ui-icon-arrowthickstop-1-e { background-position: -208px -48px; }
+.ui-icon-arrowthickstop-1-s { background-position: -224px -48px; }
+.ui-icon-arrowthickstop-1-w { background-position: -240px -48px; }
+.ui-icon-arrowreturnthick-1-w { background-position: 0 -64px; }
+.ui-icon-arrowreturnthick-1-n { background-position: -16px -64px; }
+.ui-icon-arrowreturnthick-1-e { background-position: -32px -64px; }
+.ui-icon-arrowreturnthick-1-s { background-position: -48px -64px; }
+.ui-icon-arrowreturn-1-w { background-position: -64px -64px; }
+.ui-icon-arrowreturn-1-n { background-position: -80px -64px; }
+.ui-icon-arrowreturn-1-e { background-position: -96px -64px; }
+.ui-icon-arrowreturn-1-s { background-position: -112px -64px; }
+.ui-icon-arrowrefresh-1-w { background-position: -128px -64px; }
+.ui-icon-arrowrefresh-1-n { background-position: -144px -64px; }
+.ui-icon-arrowrefresh-1-e { background-position: -160px -64px; }
+.ui-icon-arrowrefresh-1-s { background-position: -176px -64px; }
+.ui-icon-arrow-4 { background-position: 0 -80px; }
+.ui-icon-arrow-4-diag { background-position: -16px -80px; }
+.ui-icon-extlink { background-position: -32px -80px; }
+.ui-icon-newwin { background-position: -48px -80px; }
+.ui-icon-refresh { background-position: -64px -80px; }
+.ui-icon-shuffle { background-position: -80px -80px; }
+.ui-icon-transfer-e-w { background-position: -96px -80px; }
+.ui-icon-transferthick-e-w { background-position: -112px -80px; }
+.ui-icon-folder-collapsed { background-position: 0 -96px; }
+.ui-icon-folder-open { background-position: -16px -96px; }
+.ui-icon-document { background-position: -32px -96px; }
+.ui-icon-document-b { background-position: -48px -96px; }
+.ui-icon-note { background-position: -64px -96px; }
+.ui-icon-mail-closed { background-position: -80px -96px; }
+.ui-icon-mail-open { background-position: -96px -96px; }
+.ui-icon-suitcase { background-position: -112px -96px; }
+.ui-icon-comment { background-position: -128px -96px; }
+.ui-icon-person { background-position: -144px -96px; }
+.ui-icon-print { background-position: -160px -96px; }
+.ui-icon-trash { background-position: -176px -96px; }
+.ui-icon-locked { background-position: -192px -96px; }
+.ui-icon-unlocked { background-position: -208px -96px; }
+.ui-icon-bookmark { background-position: -224px -96px; }
+.ui-icon-tag { background-position: -240px -96px; }
+.ui-icon-home { background-position: 0 -112px; }
+.ui-icon-flag { background-position: -16px -112px; }
+.ui-icon-calendar { background-position: -32px -112px; }
+.ui-icon-cart { background-position: -48px -112px; }
+.ui-icon-pencil { background-position: -64px -112px; }
+.ui-icon-clock { background-position: -80px -112px; }
+.ui-icon-disk { background-position: -96px -112px; }
+.ui-icon-calculator { background-position: -112px -112px; }
+.ui-icon-zoomin { background-position: -128px -112px; }
+.ui-icon-zoomout { background-position: -144px -112px; }
+.ui-icon-search { background-position: -160px -112px; }
+.ui-icon-wrench { background-position: -176px -112px; }
+.ui-icon-gear { background-position: -192px -112px; }
+.ui-icon-heart { background-position: -208px -112px; }
+.ui-icon-star { background-position: -224px -112px; }
+.ui-icon-link { background-position: -240px -112px; }
+.ui-icon-cancel { background-position: 0 -128px; }
+.ui-icon-plus { background-position: -16px -128px; }
+.ui-icon-plusthick { background-position: -32px -128px; }
+.ui-icon-minus { background-position: -48px -128px; }
+.ui-icon-minusthick { background-position: -64px -128px; }
+.ui-icon-close { background-position: -80px -128px; }
+.ui-icon-closethick { background-position: -96px -128px; }
+.ui-icon-key { background-position: -112px -128px; }
+.ui-icon-lightbulb { background-position: -128px -128px; }
+.ui-icon-scissors { background-position: -144px -128px; }
+.ui-icon-clipboard { background-position: -160px -128px; }
+.ui-icon-copy { background-position: -176px -128px; }
+.ui-icon-contact { background-position: -192px -128px; }
+.ui-icon-image { background-position: -208px -128px; }
+.ui-icon-video { background-position: -224px -128px; }
+.ui-icon-script { background-position: -240px -128px; }
+.ui-icon-alert { background-position: 0 -144px; }
+.ui-icon-info { background-position: -16px -144px; }
+.ui-icon-notice { background-position: -32px -144px; }
+.ui-icon-help { background-position: -48px -144px; }
+.ui-icon-check { background-position: -64px -144px; }
+.ui-icon-bullet { background-position: -80px -144px; }
+.ui-icon-radio-off { background-position: -96px -144px; }
+.ui-icon-radio-on { background-position: -112px -144px; }
+.ui-icon-pin-w { background-position: -128px -144px; }
+.ui-icon-pin-s { background-position: -144px -144px; }
+.ui-icon-play { background-position: 0 -160px; }
+.ui-icon-pause { background-position: -16px -160px; }
+.ui-icon-seek-next { background-position: -32px -160px; }
+.ui-icon-seek-prev { background-position: -48px -160px; }
+.ui-icon-seek-end { background-position: -64px -160px; }
+.ui-icon-seek-start { background-position: -80px -160px; }
+/* ui-icon-seek-first is deprecated, use ui-icon-seek-start instead */
+.ui-icon-seek-first { background-position: -80px -160px; }
+.ui-icon-stop { background-position: -96px -160px; }
+.ui-icon-eject { background-position: -112px -160px; }
+.ui-icon-volume-off { background-position: -128px -160px; }
+.ui-icon-volume-on { background-position: -144px -160px; }
+.ui-icon-power { background-position: 0 -176px; }
+.ui-icon-signal-diag { background-position: -16px -176px; }
+.ui-icon-signal { background-position: -32px -176px; }
+.ui-icon-battery-0 { background-position: -48px -176px; }
+.ui-icon-battery-1 { background-position: -64px -176px; }
+.ui-icon-battery-2 { background-position: -80px -176px; }
+.ui-icon-battery-3 { background-position: -96px -176px; }
+.ui-icon-circle-plus { background-position: 0 -192px; }
+.ui-icon-circle-minus { background-position: -16px -192px; }
+.ui-icon-circle-close { background-position: -32px -192px; }
+.ui-icon-circle-triangle-e { background-position: -48px -192px; }
+.ui-icon-circle-triangle-s { background-position: -64px -192px; }
+.ui-icon-circle-triangle-w { background-position: -80px -192px; }
+.ui-icon-circle-triangle-n { background-position: -96px -192px; }
+.ui-icon-circle-arrow-e { background-position: -112px -192px; }
+.ui-icon-circle-arrow-s { background-position: -128px -192px; }
+.ui-icon-circle-arrow-w { background-position: -144px -192px; }
+.ui-icon-circle-arrow-n { background-position: -160px -192px; }
+.ui-icon-circle-zoomin { background-position: -176px -192px; }
+.ui-icon-circle-zoomout { background-position: -192px -192px; }
+.ui-icon-circle-check { background-position: -208px -192px; }
+.ui-icon-circlesmall-plus { background-position: 0 -208px; }
+.ui-icon-circlesmall-minus { background-position: -16px -208px; }
+.ui-icon-circlesmall-close { background-position: -32px -208px; }
+.ui-icon-squaresmall-plus { background-position: -48px -208px; }
+.ui-icon-squaresmall-minus { background-position: -64px -208px; }
+.ui-icon-squaresmall-close { background-position: -80px -208px; }
+.ui-icon-grip-dotted-vertical { background-position: 0 -224px; }
+.ui-icon-grip-dotted-horizontal { background-position: -16px -224px; }
+.ui-icon-grip-solid-vertical { background-position: -32px -224px; }
+.ui-icon-grip-solid-horizontal { background-position: -48px -224px; }
+.ui-icon-gripsmall-diagonal-se { background-position: -64px -224px; }
+.ui-icon-grip-diagonal-se { background-position: -80px -224px; }
+
+
+/* Misc visuals
+----------------------------------*/
+
+/* Corner radius */
+.ui-corner-tl { -moz-border-radius-topleft: 5px; -webkit-border-top-left-radius: 5px; border-top-left-radius: 5px; }
+.ui-corner-tr { -moz-border-radius-topright: 5px; -webkit-border-top-right-radius: 5px; border-top-right-radius: 5px; }
+.ui-corner-bl { -moz-border-radius-bottomleft: 5px; -webkit-border-bottom-left-radius: 5px; border-bottom-left-radius: 5px; }
+.ui-corner-br { -moz-border-radius-bottomright: 5px; -webkit-border-bottom-right-radius: 5px; border-bottom-right-radius: 5px; }
+.ui-corner-top { -moz-border-radius-topleft: 5px; -webkit-border-top-left-radius: 5px; border-top-left-radius: 5px; -moz-border-radius-topright: 5px; -webkit-border-top-right-radius: 5px; border-top-right-radius: 5px; }
+.ui-corner-bottom { -moz-border-radius-bottomleft: 5px; -webkit-border-bottom-left-radius: 5px; border-bottom-left-radius: 5px; -moz-border-radius-bottomright: 5px; -webkit-border-bottom-right-radius: 5px; border-bottom-right-radius: 5px; }
+.ui-corner-right {  -moz-border-radius-topright: 5px; -webkit-border-top-right-radius: 5px; border-top-right-radius: 5px; -moz-border-radius-bottomright: 5px; -webkit-border-bottom-right-radius: 5px; border-bottom-right-radius: 5px; }
+.ui-corner-left { -moz-border-radius-topleft: 5px; -webkit-border-top-left-radius: 5px; border-top-left-radius: 5px; -moz-border-radius-bottomleft: 5px; -webkit-border-bottom-left-radius: 5px; border-bottom-left-radius: 5px; }
+.ui-corner-all { -moz-border-radius: 5px; -webkit-border-radius: 5px; border-radius: 5px; }
+
+/* Overlays */
+.ui-widget-overlay { background: #aaaaaa url(images/ui-bg_flat_0_aaaaaa_40x100.png) 50% 50% repeat-x; opacity: .30;filter:Alpha(Opacity=30); }
+.ui-widget-shadow { margin: -8px 0 0 -8px; padding: 8px; background: #aaaaaa url(images/ui-bg_flat_0_aaaaaa_40x100.png) 50% 50% repeat-x; opacity: .30;filter:Alpha(Opacity=30); -moz-border-radius: 8px; -webkit-border-radius: 8px; border-radius: 8px; }/*
+ * jQuery UI Resizable 1.8.12
+ *
+ * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
+ * Dual licensed under the MIT or GPL Version 2 licenses.
+ * http://jquery.org/license
+ *
+ * http://docs.jquery.com/UI/Resizable#theming
+ */
+.ui-resizable { position: relative;}
+.ui-resizable-handle { position: absolute;font-size: 0.1px;z-index: 99999; display: block;
+	/* http://bugs.jqueryui.com/ticket/7233
+	 - Resizable: resizable handles fail to work in IE if transparent and content overlaps
+	*/
+	background-image:url(data:);
+}
+.ui-resizable-disabled .ui-resizable-handle, .ui-resizable-autohide .ui-resizable-handle { display: none; }
+.ui-resizable-n { cursor: n-resize; height: 7px; width: 100%; top: -5px; left: 0; }
+.ui-resizable-s { cursor: s-resize; height: 7px; width: 100%; bottom: -5px; left: 0; }
+.ui-resizable-e { cursor: e-resize; width: 7px; right: -5px; top: 0; height: 100%; }
+.ui-resizable-w { cursor: w-resize; width: 7px; left: -5px; top: 0; height: 100%; }
+.ui-resizable-se { cursor: se-resize; width: 12px; height: 12px; right: 1px; bottom: 1px; }
+.ui-resizable-sw { cursor: sw-resize; width: 9px; height: 9px; left: -5px; bottom: -5px; }
+.ui-resizable-nw { cursor: nw-resize; width: 9px; height: 9px; left: -5px; top: -5px; }
+.ui-resizable-ne { cursor: ne-resize; width: 9px; height: 9px; right: -5px; top: -5px;}/*
+ * jQuery UI Selectable 1.8.12
+ *
+ * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
+ * Dual licensed under the MIT or GPL Version 2 licenses.
+ * http://jquery.org/license
+ *
+ * http://docs.jquery.com/UI/Selectable#theming
+ */
+.ui-selectable-helper { position: absolute; z-index: 100; border:1px dotted black; }
+/*
+ * jQuery UI Accordion 1.8.12
+ *
+ * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
+ * Dual licensed under the MIT or GPL Version 2 licenses.
+ * http://jquery.org/license
+ *
+ * http://docs.jquery.com/UI/Accordion#theming
+ */
+/* IE/Win - Fix animation bug - #4615 */
+.ui-accordion { width: 100%; }
+.ui-accordion .ui-accordion-header { cursor: pointer; position: relative; margin-top: 1px; zoom: 1; }
+.ui-accordion .ui-accordion-li-fix { display: inline; }
+.ui-accordion .ui-accordion-header-active { border-bottom: 0 !important; }
+.ui-accordion .ui-accordion-header a { display: block; font-size: 1em; padding: .5em .5em .5em .7em; }
+.ui-accordion-icons .ui-accordion-header a { padding-left: 2.2em; }
+.ui-accordion .ui-accordion-header .ui-icon { position: absolute; left: .5em; top: 50%; margin-top: -8px; }
+.ui-accordion .ui-accordion-content { padding: 1em 2.2em; border-top: 0; margin-top: -2px; position: relative; top: 1px; margin-bottom: 2px; overflow: auto; display: none; zoom: 1; }
+.ui-accordion .ui-accordion-content-active { display: block; }
+/*
+ * jQuery UI Autocomplete 1.8.12
+ *
+ * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
+ * Dual licensed under the MIT or GPL Version 2 licenses.
+ * http://jquery.org/license
+ *
+ * http://docs.jquery.com/UI/Autocomplete#theming
+ */
+.ui-autocomplete { position: absolute; cursor: default; }	
+
+/* workarounds */
+* html .ui-autocomplete { width:1px; } /* without this, the menu expands to 100% in IE6 */
+
+/*
+ * jQuery UI Menu 1.8.12
+ *
+ * Copyright 2010, AUTHORS.txt (http://jqueryui.com/about)
+ * Dual licensed under the MIT or GPL Version 2 licenses.
+ * http://jquery.org/license
+ *
+ * http://docs.jquery.com/UI/Menu#theming
+ */
+.ui-menu {
+	list-style:none;
+	padding: 2px;
+	margin: 0;
+	display:block;
+	float: left;
+}
+.ui-menu .ui-menu {
+	margin-top: -3px;
+}
+.ui-menu .ui-menu-item {
+	margin:0;
+	padding: 0;
+	zoom: 1;
+	float: left;
+	clear: left;
+	width: 100%;
+}
+.ui-menu .ui-menu-item a {
+	text-decoration:none;
+	display:block;
+	padding:.2em .4em;
+	line-height:1.5;
+	zoom:1;
+}
+.ui-menu .ui-menu-item a.ui-state-hover,
+.ui-menu .ui-menu-item a.ui-state-active {
+	font-weight: normal;
+	margin: -1px;
+}
+/*
+ * jQuery UI Button 1.8.12
+ *
+ * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
+ * Dual licensed under the MIT or GPL Version 2 licenses.
+ * http://jquery.org/license
+ *
+ * http://docs.jquery.com/UI/Button#theming
+ */
+.ui-button { display: inline-block; position: relative; padding: 0; margin-right: .1em; text-decoration: none !important; cursor: pointer; text-align: center; zoom: 1; overflow: visible; } /* the overflow property removes extra width in IE */
+.ui-button-icon-only { width: 2.2em; } /* to make room for the icon, a width needs to be set here */
+button.ui-button-icon-only { width: 2.4em; } /* button elements seem to need a little more width */
+.ui-button-icons-only { width: 3.4em; } 
+button.ui-button-icons-only { width: 3.7em; } 
+
+/*button text element */
+.ui-button .ui-button-text { display: block; line-height: 1.4;  }
+.ui-button-text-only .ui-button-text { padding: .4em 1em; }
+.ui-button-icon-only .ui-button-text, .ui-button-icons-only .ui-button-text { padding: .4em; text-indent: -9999999px; }
+.ui-button-text-icon-primary .ui-button-text, .ui-button-text-icons .ui-button-text { padding: .4em 1em .4em 2.1em; }
+.ui-button-text-icon-secondary .ui-button-text, .ui-button-text-icons .ui-button-text { padding: .4em 2.1em .4em 1em; }
+.ui-button-text-icons .ui-button-text { padding-left: 2.1em; padding-right: 2.1em; }
+/* no icon support for input elements, provide padding by default */
+input.ui-button { padding: .4em 1em; }
+
+/*button icon element(s) */
+.ui-button-icon-only .ui-icon, .ui-button-text-icon-primary .ui-icon, .ui-button-text-icon-secondary .ui-icon, .ui-button-text-icons .ui-icon, .ui-button-icons-only .ui-icon { position: absolute; top: 50%; margin-top: -8px; }
+.ui-button-icon-only .ui-icon { left: 50%; margin-left: -8px; }
+.ui-button-text-icon-primary .ui-button-icon-primary, .ui-button-text-icons .ui-button-icon-primary, .ui-button-icons-only .ui-button-icon-primary { left: .5em; }
+.ui-button-text-icon-secondary .ui-button-icon-secondary, .ui-button-text-icons .ui-button-icon-secondary, .ui-button-icons-only .ui-button-icon-secondary { right: .5em; }
+.ui-button-text-icons .ui-button-icon-secondary, .ui-button-icons-only .ui-button-icon-secondary { right: .5em; }
+
+/*button sets*/
+.ui-buttonset { margin-right: 7px; }
+.ui-buttonset .ui-button { margin-left: 0; margin-right: -.3em; }
+
+/* workarounds */
+button.ui-button::-moz-focus-inner { border: 0; padding: 0; } /* reset extra padding in Firefox */
+/*
+ * jQuery UI Dialog 1.8.12
+ *
+ * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
+ * Dual licensed under the MIT or GPL Version 2 licenses.
+ * http://jquery.org/license
+ *
+ * http://docs.jquery.com/UI/Dialog#theming
+ */
+.ui-dialog { position: absolute; padding: .2em; width: 300px; overflow: hidden; }
+.ui-dialog .ui-dialog-titlebar { padding: .4em 1em; position: relative;  }
+.ui-dialog .ui-dialog-title { float: left; margin: .1em 16px .1em 0; } 
+.ui-dialog .ui-dialog-titlebar-close { position: absolute; right: .3em; top: 50%; width: 19px; margin: -10px 0 0 0; padding: 1px; height: 18px; }
+.ui-dialog .ui-dialog-titlebar-close span { display: block; margin: 1px; }
+.ui-dialog .ui-dialog-titlebar-close:hover, .ui-dialog .ui-dialog-titlebar-close:focus { padding: 0; }
+.ui-dialog .ui-dialog-content { position: relative; border: 0; padding: .5em 1em; background: none; overflow: auto; zoom: 1; }
+.ui-dialog .ui-dialog-buttonpane { text-align: left; border-width: 1px 0 0 0; background-image: none; margin: .5em 0 0 0; padding: .3em 1em .5em .4em; }
+.ui-dialog .ui-dialog-buttonpane .ui-dialog-buttonset { float: right; }
+.ui-dialog .ui-dialog-buttonpane button { margin: .5em .4em .5em 0; cursor: pointer; }
+.ui-dialog .ui-resizable-se { width: 14px; height: 14px; right: 3px; bottom: 3px; }
+.ui-draggable .ui-dialog-titlebar { cursor: move; }
+/*
+ * jQuery UI Slider 1.8.12
+ *
+ * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
+ * Dual licensed under the MIT or GPL Version 2 licenses.
+ * http://jquery.org/license
+ *
+ * http://docs.jquery.com/UI/Slider#theming
+ */
+.ui-slider { position: relative; text-align: left; }
+.ui-slider .ui-slider-handle { position: absolute; z-index: 2; width: 1.2em; height: 1.2em; cursor: default; }
+.ui-slider .ui-slider-range { position: absolute; z-index: 1; font-size: .7em; display: block; border: 0; background-position: 0 0; }
+
+.ui-slider-horizontal { height: .8em; }
+.ui-slider-horizontal .ui-slider-handle { top: -.3em; margin-left: -.6em; }
+.ui-slider-horizontal .ui-slider-range { top: 0; height: 100%; }
+.ui-slider-horizontal .ui-slider-range-min { left: 0; }
+.ui-slider-horizontal .ui-slider-range-max { right: 0; }
+
+.ui-slider-vertical { width: .8em; height: 100px; }
+.ui-slider-vertical .ui-slider-handle { left: -.3em; margin-left: 0; margin-bottom: -.6em; }
+.ui-slider-vertical .ui-slider-range { left: 0; width: 100%; }
+.ui-slider-vertical .ui-slider-range-min { bottom: 0; }
+.ui-slider-vertical .ui-slider-range-max { top: 0; }/*
+ * jQuery UI Tabs 1.8.12
+ *
+ * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
+ * Dual licensed under the MIT or GPL Version 2 licenses.
+ * http://jquery.org/license
+ *
+ * http://docs.jquery.com/UI/Tabs#theming
+ */
+.ui-tabs { position: relative; padding: .2em; zoom: 1; } /* position: relative prevents IE scroll bug (element with position: relative inside container with overflow: auto appear as "fixed") */
+.ui-tabs .ui-tabs-nav { margin: 0; padding: .2em .2em 0; }
+.ui-tabs .ui-tabs-nav li { list-style: none; float: left; position: relative; top: 1px; margin: 0 .2em 1px 0; border-bottom: 0 !important; padding: 0; white-space: nowrap; }
+.ui-tabs .ui-tabs-nav li a { float: left; padding: .5em 1em; text-decoration: none; }
+.ui-tabs .ui-tabs-nav li.ui-tabs-selected { margin-bottom: 0; padding-bottom: 1px; }
+.ui-tabs .ui-tabs-nav li.ui-tabs-selected a, .ui-tabs .ui-tabs-nav li.ui-state-disabled a, .ui-tabs .ui-tabs-nav li.ui-state-processing a { cursor: text; }
+.ui-tabs .ui-tabs-nav li a, .ui-tabs.ui-tabs-collapsible .ui-tabs-nav li.ui-tabs-selected a { cursor: pointer; } /* first selector in group seems obsolete, but required to overcome bug in Opera applying cursor: text overall if defined elsewhere... */
+.ui-tabs .ui-tabs-panel { display: block; border-width: 0; padding: 1em 1.4em; background: none; }
+.ui-tabs .ui-tabs-hide { display: none !important; }
+/*
+ * jQuery UI Datepicker 1.8.12
+ *
+ * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
+ * Dual licensed under the MIT or GPL Version 2 licenses.
+ * http://jquery.org/license
+ *
+ * http://docs.jquery.com/UI/Datepicker#theming
+ */
+.ui-datepicker { width: 17em; padding: .2em .2em 0; display: none; }
+.ui-datepicker .ui-datepicker-header { position:relative; padding:.2em 0; }
+.ui-datepicker .ui-datepicker-prev, .ui-datepicker .ui-datepicker-next { position:absolute; top: 2px; width: 1.8em; height: 1.8em; }
+.ui-datepicker .ui-datepicker-prev-hover, .ui-datepicker .ui-datepicker-next-hover { top: 1px; }
+.ui-datepicker .ui-datepicker-prev { left:2px; }
+.ui-datepicker .ui-datepicker-next { right:2px; }
+.ui-datepicker .ui-datepicker-prev-hover { left:1px; }
+.ui-datepicker .ui-datepicker-next-hover { right:1px; }
+.ui-datepicker .ui-datepicker-prev span, .ui-datepicker .ui-datepicker-next span { display: block; position: absolute; left: 50%; margin-left: -8px; top: 50%; margin-top: -8px;  }
+.ui-datepicker .ui-datepicker-title { margin: 0 2.3em; line-height: 1.8em; text-align: center; }
+.ui-datepicker .ui-datepicker-title select { font-size:1em; margin:1px 0; }
+.ui-datepicker select.ui-datepicker-month-year {width: 100%;}
+.ui-datepicker select.ui-datepicker-month, 
+.ui-datepicker select.ui-datepicker-year { width: 49%;}
+.ui-datepicker table {width: 100%; font-size: .9em; border-collapse: collapse; margin:0 0 .4em; }
+.ui-datepicker th { padding: .7em .3em; text-align: center; font-weight: bold; border: 0;  }
+.ui-datepicker td { border: 0; padding: 1px; }
+.ui-datepicker td span, .ui-datepicker td a { display: block; padding: .2em; text-align: right; text-decoration: none; }
+.ui-datepicker .ui-datepicker-buttonpane { background-image: none; margin: .7em 0 0 0; padding:0 .2em; border-left: 0; border-right: 0; border-bottom: 0; }
+.ui-datepicker .ui-datepicker-buttonpane button { float: right; margin: .5em .2em .4em; cursor: pointer; padding: .2em .6em .3em .6em; width:auto; overflow:visible; }
+.ui-datepicker .ui-datepicker-buttonpane button.ui-datepicker-current { float:left; }
+
+/* with multiple calendars */
+.ui-datepicker.ui-datepicker-multi { width:auto; }
+.ui-datepicker-multi .ui-datepicker-group { float:left; }
+.ui-datepicker-multi .ui-datepicker-group table { width:95%; margin:0 auto .4em; }
+.ui-datepicker-multi-2 .ui-datepicker-group { width:50%; }
+.ui-datepicker-multi-3 .ui-datepicker-group { width:33.3%; }
+.ui-datepicker-multi-4 .ui-datepicker-group { width:25%; }
+.ui-datepicker-multi .ui-datepicker-group-last .ui-datepicker-header { border-left-width:0; }
+.ui-datepicker-multi .ui-datepicker-group-middle .ui-datepicker-header { border-left-width:0; }
+.ui-datepicker-multi .ui-datepicker-buttonpane { clear:left; }
+.ui-datepicker-row-break { clear:both; width:100%; }
+
+/* RTL support */
+.ui-datepicker-rtl { direction: rtl; }
+.ui-datepicker-rtl .ui-datepicker-prev { right: 2px; left: auto; }
+.ui-datepicker-rtl .ui-datepicker-next { left: 2px; right: auto; }
+.ui-datepicker-rtl .ui-datepicker-prev:hover { right: 1px; left: auto; }
+.ui-datepicker-rtl .ui-datepicker-next:hover { left: 1px; right: auto; }
+.ui-datepicker-rtl .ui-datepicker-buttonpane { clear:right; }
+.ui-datepicker-rtl .ui-datepicker-buttonpane button { float: left; }
+.ui-datepicker-rtl .ui-datepicker-buttonpane button.ui-datepicker-current { float:right; }
+.ui-datepicker-rtl .ui-datepicker-group { float:right; }
+.ui-datepicker-rtl .ui-datepicker-group-last .ui-datepicker-header { border-right-width:0; border-left-width:1px; }
+.ui-datepicker-rtl .ui-datepicker-group-middle .ui-datepicker-header { border-right-width:0; border-left-width:1px; }
+
+/* IE6 IFRAME FIX (taken from datepicker 1.5.3 */
+.ui-datepicker-cover {
+    display: none; /*sorry for IE5*/
+    display/**/: block; /*sorry for IE5*/
+    position: absolute; /*must have*/
+    z-index: -1; /*must have*/
+    filter: mask(); /*must have*/
+    top: -4px; /*must have*/
+    left: -4px; /*must have*/
+    width: 200px; /*must have*/
+    height: 200px; /*must have*/
+}/*
+ * jQuery UI Progressbar 1.8.12
+ *
+ * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
+ * Dual licensed under the MIT or GPL Version 2 licenses.
+ * http://jquery.org/license
+ *
+ * http://docs.jquery.com/UI/Progressbar#theming
+ */
+.ui-progressbar { height:2em; text-align: left; }
+.ui-progressbar .ui-progressbar-value {margin: -1px; height:100%; }
\ No newline at end of file

Property changes on: TXM/trunk/org.txm.conllu.core/template/css/jquery-ui-redmond.css
___________________________________________________________________
Added: svn:mime-type
   + text/plain

Index: TXM/trunk/org.txm.conllu.core/template/index.html
===================================================================
--- TXM/trunk/org.txm.conllu.core/template/index.html	(revision 0)
+++ TXM/trunk/org.txm.conllu.core/template/index.html	(revision 3567)
@@ -0,0 +1,69 @@
+<!DOCTYPE html>
+<html>
+
+<head>
+    
+    <title>UD</title>
+    <meta charset="utf-8"></meta>
+    <meta name="viewport" content="width=device-width"></meta>
+    <meta name="description" content="CoNLL-U format library for JavaScript"></meta>
+
+    <link rel="stylesheet" href="HTMLROOTDIRECTORY/css/jquery-ui-redmond.css"></link>
+    <link rel="stylesheet" href="HTMLROOTDIRECTORY/css/main.css"></link>
+    <link rel="stylesheet" href="HTMLROOTDIRECTORY/css/style-vis.css"></link>
+
+    <script type="text/javascript" src="HTMLROOTDIRECTORY/lib/ext/head.load.min.js"></script>
+</head>
+
+<body>
+
+<code class="conllu-parse" tabs="yes"><pre>
+CONLLUSENTENCE
+
+</pre></code>
+
+</body>
+
+<script type="text/javascript">
+    var root = 'HTMLROOTDIRECTORY/'; // filled in by jekyll
+    head.js(
+        // External libraries
+        root + 'lib/ext/jquery.min.js',
+        root + 'lib/ext/jquery.svg.min.js',
+        root + 'lib/ext/jquery.svgdom.min.js',
+        root + 'lib/ext/jquery-ui.min.js',
+        root + 'lib/ext/waypoints.min.js',
+
+        // brat helper modules
+        root + 'lib/brat/configuration.js',
+        root + 'lib/brat/util.js',
+        root + 'lib/brat/annotation_log.js',
+        root + 'lib/ext/webfont.js',
+        // brat modules
+        root + 'lib/brat/dispatcher.js',
+        root + 'lib/brat/url_monitor.js',
+        root + 'lib/brat/visualizer.js',
+
+        // annotation documentation support
+        'http://spyysalo.github.io/annodoc/lib/local/annodoc.js',
+        root + 'lib/local/config.js',
+
+        // the conllu.js library itself
+        root + 'conllu.js'
+    );
+
+    var webFontURLs = [
+        root + 'static/fonts/PT_Sans-Caption-Web-Regular.ttf',
+        root + 'static/fonts/Liberation_Sans-Regular.ttf'
+    ];
+
+    /* not used here */
+    var documentCollections = {};
+
+    head.ready(function() {
+	// performes all embedding and support functions
+	Annodoc.activate(Config.bratCollData, documentCollections);
+    });
+</script>
+
+</html>

Property changes on: TXM/trunk/org.txm.conllu.core/template/index.html
___________________________________________________________________
Added: svn:mime-type
   + text/plain

Index: TXM/trunk/org.txm.conllu.core/template/README.md
===================================================================
--- TXM/trunk/org.txm.conllu.core/template/README.md	(revision 0)
+++ TXM/trunk/org.txm.conllu.core/template/README.md	(revision 3567)
@@ -0,0 +1,4 @@
+conllu.js
+=========
+
+CoNLL-U format library for JavaScript
Index: TXM/trunk/org.txm.conllu.core/template/LICENSE
===================================================================
--- TXM/trunk/org.txm.conllu.core/template/LICENSE	(revision 0)
+++ TXM/trunk/org.txm.conllu.core/template/LICENSE	(revision 3567)
@@ -0,0 +1,21 @@
+The MIT License (MIT)
+
+Copyright (c) 2014 Sampo Pyysalo
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
Index: TXM/trunk/org.txm.conllu.core/plugin.xml
===================================================================
--- TXM/trunk/org.txm.conllu.core/plugin.xml	(revision 0)
+++ TXM/trunk/org.txm.conllu.core/plugin.xml	(revision 3567)
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<?eclipse version="3.4"?>
+<plugin>  
+   <extension
+         point="org.txm.PostTXMHOMEInstallationStep">
+      <PostTXMHOMEInstallationStep
+            class="org.txm.conllu.core.InstallGroovyCoNLLUFiles"
+            description="copy scripts for import module"
+            name="CoNLLUFiles">
+      </PostTXMHOMEInstallationStep>
+   </extension>
+   <extension
+         point="org.txm.treesearch.TreeSearchSelector">
+      <TreeSearchSelector
+            class="org.txm.conllu.core.function.UDTreeSearchSelector">
+      </TreeSearchSelector>
+   </extension>
+   <extension
+         point="org.eclipse.core.runtime.preferences">
+      <initializer
+            class="org.txm.conllu.core.preferences.UDPreferences">
+      </initializer>
+      <initializer
+            class="org.txm.conllu.core.preferences.UDTreePreferences">
+      </initializer>
+   </extension>
+
+</plugin>

Property changes on: TXM/trunk/org.txm.conllu.core/plugin.xml
___________________________________________________________________
Added: svn:mime-type
   + text/plain

Index: TXM/trunk/org.txm.conllu.core/.settings/org.eclipse.jdt.groovy.core.prefs
===================================================================
--- TXM/trunk/org.txm.conllu.core/.settings/org.eclipse.jdt.groovy.core.prefs	(revision 0)
+++ TXM/trunk/org.txm.conllu.core/.settings/org.eclipse.jdt.groovy.core.prefs	(revision 3567)
@@ -0,0 +1,3 @@
+eclipse.preferences.version=1
+groovy.compiler.level=30
+groovy.script.filters=**/*.dsld,y,**/*.gradle,n

Property changes on: TXM/trunk/org.txm.conllu.core/.settings/org.eclipse.jdt.groovy.core.prefs
___________________________________________________________________
Added: svn:mime-type
   + text/plain

Index: TXM/trunk/org.txm.conllu.core/.classpath
===================================================================
--- TXM/trunk/org.txm.conllu.core/.classpath	(revision 0)
+++ TXM/trunk/org.txm.conllu.core/.classpath	(revision 3567)
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
+	<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins">
+		<accessrules>
+			<accessrule kind="accessible" pattern="**"/>
+		</accessrules>
+	</classpathentry>
+	<classpathentry kind="src" path="src"/>
+	<classpathentry kind="src" path="template"/>
+	<classpathentry exported="true" kind="con" path="GROOVY_SUPPORT"/>
+	<classpathentry exported="true" kind="con" path="GROOVY_DSL_SUPPORT"/>
+	<classpathentry kind="output" path="bin"/>
+</classpath>

Property changes on: TXM/trunk/org.txm.conllu.core/.classpath
___________________________________________________________________
Added: svn:mime-type
   + text/plain

Index: TXM/trunk/org.txm.conllu.core/META-INF/MANIFEST.MF
===================================================================
--- TXM/trunk/org.txm.conllu.core/META-INF/MANIFEST.MF	(revision 0)
+++ TXM/trunk/org.txm.conllu.core/META-INF/MANIFEST.MF	(revision 3567)
@@ -0,0 +1,17 @@
+Manifest-Version: 1.0
+Automatic-Module-Name: org.txm.connlu.core
+Bundle-SymbolicName: org.txm.conllu.core;singleton:=true
+Export-Package: org.txm.conllu.core,
+ org.txm.conllu.core.function,
+ org.txm.conllu.core.preferences
+Bundle-Name: org.txm.conllu.core
+Bundle-Version: 1.0.0.qualifier
+Require-Bundle: org.txm.core;visibility:=reexport,
+ org.txm.groovy.core;bundle-version="1.0.0";visibility:=reexport,
+ org.txm.treesearch.core;bundle-version="1.0.0";visibility:=reexport,
+ org.txm.libs.deptreeviz;bundle-version="0.3.0";visibility:=reexport,
+ org.txm.tigersearch.core;bundle-version="1.0.0"
+Bundle-ManifestVersion: 2
+Bundle-RequiredExecutionEnvironment: JavaSE-1.8
+Bundle-Vendor: Textometrie.org
+

Property changes on: TXM/trunk/org.txm.conllu.core/META-INF/MANIFEST.MF
___________________________________________________________________
Added: svn:mime-type
   + text/plain

Index: TXM/trunk/org.txm.conllu.core/.project
===================================================================
--- TXM/trunk/org.txm.conllu.core/.project	(revision 0)
+++ TXM/trunk/org.txm.conllu.core/.project	(revision 3567)
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>org.txm.conllu.core</name>
+	<comment></comment>
+	<projects>
+	</projects>
+	<buildSpec>
+		<buildCommand>
+			<name>org.eclipse.jdt.core.javabuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.pde.ManifestBuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.pde.SchemaBuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+	</buildSpec>
+	<natures>
+		<nature>org.eclipse.jdt.groovy.core.groovyNature</nature>
+		<nature>org.eclipse.pde.PluginNature</nature>
+		<nature>org.eclipse.jdt.core.javanature</nature>
+	</natures>
+</projectDescription>

Property changes on: TXM/trunk/org.txm.conllu.core/.project
___________________________________________________________________
Added: svn:mime-type
   + text/plain

Index: TXM/trunk/org.txm.conllu.core/groovy/org/txm/scripts/importer/conllu/tigerXml-commentOutLongSentences.xsl
===================================================================
--- TXM/trunk/org.txm.conllu.core/groovy/org/txm/scripts/importer/conllu/tigerXml-commentOutLongSentences.xsl	(revision 0)
+++ TXM/trunk/org.txm.conllu.core/groovy/org/txm/scripts/importer/conllu/tigerXml-commentOutLongSentences.xsl	(revision 3567)
@@ -0,0 +1,36 @@
+<!-- The Identity Transformation -->
+<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:tei="http://www.tei-c.org/ns/1.0" xmlns:xs="http://www.w3.org/2001/XMLSchema">
+  
+  <!-- This stylesheet comments out the sentences containing more than 100 terminal nodes in Tiger XML files.
+    To change the theshold, puse the maxLength parameter.
+  
+  Written by A. Lavrentiev, CNRS, UMR IHRIM 2021-07-16
+  Licence: GNU GPL v.3
+  -->
+  
+  <!-- Whenever you match any node or any attribute -->
+  <xsl:template match="node()|@*">
+    <!-- Copy the current node -->
+    <xsl:copy>
+      <!-- Including any attributes it has and any child nodes -->
+      <xsl:apply-templates select="@*|node()"/>
+    </xsl:copy>
+  </xsl:template>
+  
+  <xsl:param name="maxLength" as="xs:integer">100</xsl:param>
+  
+  <xsl:template match="s">
+    <xsl:choose>
+      <xsl:when test="count(graph/terminals/t) gt $maxLength">
+        <xsl:comment>
+          Sentence too long (<xsl:value-of select="count(graph/terminals/t)"/> tokens) :
+          <xsl:for-each select="graph/terminals/t"><xsl:value-of select="@word"/><xsl:text> </xsl:text></xsl:for-each>
+        </xsl:comment>
+      </xsl:when>
+      <xsl:otherwise>
+        <xsl:copy-of select="."/>
+      </xsl:otherwise>
+    </xsl:choose>
+  </xsl:template>
+  
+</xsl:stylesheet>

Property changes on: TXM/trunk/org.txm.conllu.core/groovy/org/txm/scripts/importer/conllu/tigerXml-commentOutLongSentences.xsl
___________________________________________________________________
Added: svn:mime-type
   + text/plain

Index: TXM/trunk/org.txm.conllu.core/groovy/org/txm/scripts/importer/conllu/CoNLLUImporter.groovy
===================================================================
--- TXM/trunk/org.txm.conllu.core/groovy/org/txm/scripts/importer/conllu/CoNLLUImporter.groovy	(revision 0)
+++ TXM/trunk/org.txm.conllu.core/groovy/org/txm/scripts/importer/conllu/CoNLLUImporter.groovy	(revision 3567)
@@ -0,0 +1,322 @@
+package org.txm.scripts.importer.conllu
+
+import org.txm.Toolbox
+import org.txm.importer.xtz.ImportModule;
+import org.txm.metadatas.Metadatas
+import org.txm.utils.io.FileCopy
+import org.txm.utils.io.IOUtils
+import org.txm.importer.xtz.*
+import org.txm.scripts.importer.xtz.*
+import org.txm.conllu.core.function.ImportCoNLLUAnnotations
+import org.txm.conllu.core.preferences.UDPreferences
+import org.txm.importer.ApplyXsl2;
+import javax.xml.stream.*
+import org.txm.utils.AsciiUtils
+import org.txm.utils.ConsoleProgressBar
+import org.txm.utils.FileUtils
+import org.txm.conllu.core.preferences.UDPreferences
+/**
+ * Only build the Metadatas object since all XML-TXM files already exists.
+ * Metadatas is used to build text order.
+ * 
+ * 
+ * @author mdecorde
+ *
+ */
+class CoNLLUImporter extends XTZImporter {
+	
+	public CoNLLUImporter(ImportModule module) {
+		super(module);
+	}
+	
+	@Override
+	public void process() {
+		
+		File connluSrcDirectory = inputDirectory
+		
+		boolean usenewdocid =  UDPreferences.getInstance().getString(UDPreferences.IMPORT_USE_NEW_DOC_ID); // THE conllu -> Tiger XSL MUST HAVE THE SAME BEHAVIOR BEFORE //
+		
+		if (usenewdocid) {
+			connluSrcDirectory = new File(outputDirectory.getParentFile().getParentFile(), "conllu")
+			connluSrcDirectory.deleteDir();
+			connluSrcDirectory.mkdirs();
+			
+			println "Convert CoNLL-U to XML-TEI..."
+			if (!splitCoNLLUFiles(inputDirectory, connluSrcDirectory, project)) {
+				return;
+			}
+		}
+		File srcDirectory = new File(outputDirectory.getParentFile().getParentFile(), "conllu2tei")
+		srcDirectory.deleteDir();
+		srcDirectory.mkdirs();
+		
+		println "Convert CoNLL-U to XML-TEI..."
+		convertCoNLLU2TEI(connluSrcDirectory, srcDirectory, project)
+		
+		inputDirectory = srcDirectory // switch source directory
+		
+		super.process();
+	}
+	
+	public static def splitCoNLLUFiles(File inputDirectory, File srcDirectory, def project) {
+		def files = inputDirectory.listFiles()
+		
+		if (files == null) {
+			println "Aborting. No CONLL file found in $inputDirectory."
+			return false
+		}
+		
+		ConsoleProgressBar cpb_texts = new ConsoleProgressBar(files.size())
+		
+		println "Splitting CoNLL-U files..."
+		for (File master : files) {
+			
+			cpb_texts.tick()
+			
+			if (!master.getName().endsWith(".conllu")) {
+				continue;
+			}
+			
+			String orig_text_id = FileUtils.stripExtension(master)
+			String current_text_id = FileUtils.stripExtension(master)
+			File conlluFile = new File(srcDirectory, current_text_id+".conllu")
+			def writer = conlluFile.newWriter("UTF-8", true)
+			
+			master.eachLine("UTF-8") { line ->
+				if (line.startsWith("# newdoc id = ")) {
+					
+					String text_id = line.substring("# newdoc id = ".length())
+					if (!text_id.equals(current_text_id)) {
+						writer.close()
+						current_text_id = text_id
+						conlluFile = new File(srcDirectory, current_text_id+".conllu")
+						writer = conlluFile.newWriter("UTF-8", true)
+					}
+				}
+				
+				writer.println(line)
+			}
+		}
+		cpb_texts.done()
+		return true
+	}
+	
+	public static def convertCoNLLU2TEI(File inputDirectory, File srcDirectory, def project) {
+		
+		def files = inputDirectory.listFiles()
+		
+		if (files == null) {
+			println "Aborting. No CONLL file found in $inputDirectory."
+			return false
+		}
+		
+		
+		
+		def properties = Arrays.asList(ImportCoNLLUAnnotations.UD_PROPERTY_NAMES)
+		
+		String prefix = UDPreferences.getInstance().getProjectPreferenceValue(project, UDPreferences.UDPREFIX, UDPreferences.getInstance().getString(UDPreferences.UDPREFIX));
+		
+		UDPreferences.getInstance().setProjectPreferenceValue(project, UDPreferences.UDPREFIX, prefix); // copy the current preference into the corpus preference
+		
+		boolean keepContractions =  UDPreferences.getInstance().getString(UDPreferences.KEEP_CONTRACTIONS)
+		
+		def headPropertiesToProject = UDPreferences.getInstance().getString(UDPreferences.IMPORT_HEAD_TO_PROJECT).split(",") as Set
+		
+		def depsPropertiesToProject = UDPreferences.getInstance().getString(UDPreferences.IMPORT_DEPS_TO_PROJECT).split(",") as Set
+		
+		ConsoleProgressBar cpb_texts = new ConsoleProgressBar(files.size())
+		
+		println "Parsing CoNLL-U files..."
+		for (File master : files) {
+			
+			cpb_texts.tick()
+			
+			if (!master.getName().endsWith(".conllu")) {
+				continue;
+			}
+			
+			def content = []; // list of sentence
+			
+			String text_id = FileUtils.stripExtension(master);
+			String sent_id = "";
+			String par_id = "1";
+			def comments = []; // /text/par/sent
+			def words = []
+			
+			master.eachLine("UTF-8") { line ->
+				
+				if (line.startsWith("# newdoc id = ")) {
+					// already set or ignored
+				} else if (line.startsWith("# sent_id = ")) {
+					sent_id = line.substring("# sent_id = ".length())
+				} else if (line.startsWith("# newpar id = ")) {
+					par_id = line.substring("# newpar id = ".length())
+				} else if (line.startsWith("#")) {
+					comments << line
+				} else if (line.trim().isEmpty()) {
+					if (words.size() > 0) {
+						def sentence = [par_id, sent_id, words, comments]
+						content.add(sentence)
+						
+						sent_id = "";
+						par_id = "1";
+						comments = [];
+						words = []
+					}
+					
+				} else {
+					
+					HashMap<String, String> wProperties = new HashMap<String, String>()
+					
+					def split = line.split("\t")
+					if (split.size() == properties.size()) {
+						String id = split[0]
+						for (int i = 0 ; i < split.size() ; i++) {
+							wProperties[properties[i]] = split[i]
+						}
+						
+						if (wProperties.get("id").equals("1")) { // it's a new sentence, store the current if any and starts a new sentence
+							if (words.size() > 0) {
+								def sentence = [par_id, sent_id, words, comments]
+								content.add(sentence)
+								
+								sent_id = "";
+								par_id = "1";
+								comments = [];
+								words = []
+							}
+						}
+						
+						words << wProperties
+					} else {
+						//println "Warning: not a line: "+line
+					}
+				}
+			}
+			
+			if (content.size() == 0) {
+				continue;
+			}
+			
+			File xmlFile = new File(srcDirectory, text_id+".xml")
+			// println "xmlFile=$xmlFile"
+			BufferedOutputStream output = new BufferedOutputStream(new FileOutputStream(xmlFile))
+			XMLOutputFactory factory = XMLOutputFactory.newInstance()
+			XMLStreamWriter writer = factory.createXMLStreamWriter(output, "UTF-8")
+			
+			writer.writeStartDocument("UTF-8","1.0")
+			writer.writeStartElement ("TEI")
+			writer.writeDefaultNamespace("http://www.tei-c.org/ns/1.0")
+			writer.writeNamespace("txm", "http://textometrie.org/1.0")
+			writer.writeCharacters("\n")
+			writer.writeStartElement ("teiHeader")
+			writer.writeEndElement()
+			writer.writeCharacters("\n")
+			writer.writeStartElement ("text")
+			
+			writer.writeCharacters("\n")
+			
+			String current_par_id = null
+			
+			for (def sentence : content) { // for all paragraph of the current text
+				
+				par_id = sentence[0]
+				sent_id = sentence[1]
+				words = sentence[2]
+				comments = sentence[3]
+				
+				if (current_par_id == null || par_id != current_par_id) {
+					if (current_par_id != null) {
+						writer.writeEndElement() // p
+					}
+					writer.writeStartElement ("p");
+					writer.writeAttribute("id", par_id)
+					writer.writeCharacters("\n")
+					
+					current_par_id = par_id
+				}
+				
+				writer.writeStartElement ("s")
+				writer.writeAttribute("id", sent_id)
+				writer.writeCharacters("\n")
+				
+				for (def comment : comments) {
+					writer.writeComment(comment.replace("--", "―"))
+					writer.writeCharacters("\n")
+				}
+				
+				if (!keepContractions) { // merge properties in the "-" word and remove the parts
+					for (int i = 0 ; i < words.size() ; i++) {
+						def word = words[i]
+						String id = word[0]
+						
+						if (id.contains("-")) { // multi-word line
+							int index = id.indexOf("-")
+							String id1 = id.substring(0, index)
+							String id2 = id.substring(index+1)
+							def token1 = sentence[id1]
+							def token2 = sentence[id2]
+							
+							if (token1 == null || token2 == null) {
+								println "Error: text $text_id paragraph $par_id sent $sent_id word $id has wrong token ids $id1 and $id2 -> $token1 and $token2"
+								continue
+							}
+							
+							for (String p : properties) {
+								if (p == "id") continue // don't merge the form property
+									if (p == "form") continue // don't merge the form property
+									word[p] =  token1[p] + "+" + token2[p]
+							}
+							words.remove(i+1) // remove the token
+							words.remove(i+1) // remove the token
+						}
+					}
+				}
+				
+				if (headPropertiesToProject.size() > 0 || depsPropertiesToProject.size() > 0) {
+					LinkedHashMap sentencehash = new LinkedHashMap()
+					//println "WORDS="+words
+					for (def word : words) {
+						sentencehash[word["id"]] = word
+					}
+					//println "SENTENCE="+sentencehash
+					ImportCoNLLUAnnotations.buildPropertiesProjections(sentencehash, headPropertiesToProject, depsPropertiesToProject)
+				}
+				
+				for (def word : words) {
+					
+					def id = word["id"]
+					
+					writer.writeStartElement ("w")
+					for (String p : word.keySet()) {
+						if (p == "feats") word[p] = "|"+word[p]+"|"
+						//println "WORD="+word
+						writer.writeAttribute(prefix+p, word[p])
+					}
+					
+					writer.writeCharacters(word["form"])
+					writer.writeEndElement() // w
+					writer.writeCharacters(" ")
+				}
+				writer.writeCharacters("\n")
+				writer.writeEndElement() // s
+			}
+			
+			if (current_par_id != null) {
+				writer.writeEndElement() // p
+				writer.writeCharacters("\n")
+			}
+			
+			writer.writeEndElement() // text
+			writer.writeCharacters("\n")
+			writer.writeEndElement() // TEI
+			writer.close()
+			output.close()
+		}
+		
+		cpb_texts.done()
+		
+		return true
+	}
+	
+}
Index: TXM/trunk/org.txm.conllu.core/groovy/org/txm/scripts/importer/conllu/conll2tiger-ud.pl.tdy
===================================================================
--- TXM/trunk/org.txm.conllu.core/groovy/org/txm/scripts/importer/conllu/conll2tiger-ud.pl.tdy	(revision 0)
+++ TXM/trunk/org.txm.conllu.core/groovy/org/txm/scripts/importer/conllu/conll2tiger-ud.pl.tdy	(revision 3567)
@@ -0,0 +1,1166 @@
+#!/usr/bin/perl
+
+use File::Basename;
+
+my $CMD      = "conll2tiger.pl";
+my $VERSION  = "1.5";
+my $MODIFIED = "8/12/2015";        # angepasst für Perseus CoNLL erzeugt mit conll.pl -l.  CHECK: funktioniert SRCMF noch?
+
+# columns (default are the predicted values in CoNLL 2009 format)
+my $coll   = 2;                    # lemma
+my $colm   = 3;                    # morph (pos)
+my $colf   = 5;                    # features
+my $colh   = 6;                    # head
+my $cold   = 7;                    # deprel
+my $outdir = "conllexport";        # deprel
+my $split  = 1000;                 # split output after nr sentences
+
+# tree structure
+my %dominates          = ();
+my %deprel             = ();                                         # deprel{nr} = deprel
+my @daughters          = ();                                         # daughter nodes, stored in %dominates
+my %duplicates         = my %relators = my %notes = my %aux = ();    # store nodes of duplicates, relators
+my $type               = "--";                                       # node attribute
+my $vform              = my $vlemma = "--";                          # node attributes for verbs store form and lemma
+my $label              = "D";                                        # default edge label
+my $nt_features_header = '';                                         # option -x
+my $nt_features        = '';                                         # option -x
+my $nt_empty_features  = '';                                         # option -x
+my @scodes             = ();                                         # option -x
+my $add_to_sentcode    = '';
+my $rootname           = 'root';                                     # default
+my $featcol            = 13;
+
+######################################################################
+#  conll2tiger.pl: converts CoNLL-U from the Universal Dependecies
+#  treebanks to TigerXML
+#          Achim Stein <achim.stein@ling.uni-stuttgart.de>
+# License : GNU GPL v. 3 (see the LICENSE file)
+######################################################################
+# TO DO:
+# - coordination
+# - Umgang mit zu langen, gesplitteten Sätzen (conll.pl -r 100)
+#   - dafür wurde als Wort-ID statt $w (for-Zähler) $wnr verwendet
+#   - es gibt aber noch unbound nodes wenn Regens entfernt (im anderen Teil) ist
+######################################################################
+# Modifications by Alexei Lavrentiev <alexei.lavrentev@ens-lyon.fr>
+# for Profiterole project (2019-2021)
+
+# 2019-09-25
+# - updated default column numbers for CONNL-U SRCMF format
+# - added processing for comment lines
+# - added @textid to terminal nodes
+# - deleted ppos, pmor et plemma (predicted tags and lemmas)
+# - replaced specific SRCMF with standard UD tags
+
+# Update 2020-05-13
+# - added @editionId for synchronization with BFM word ID
+
+# Update 2021-03-22
+# - using $infilename for @textid
+# - added support for .conllu extension
+
+# Update 2021-03-29
+# - added editionId to declarations in main.xml
+
+# Update 2021-07-16
+# - added "punct" to cat values
+
+# Update 2021-07-20
+# - added cat value list compiled from
+#   https://universaldependencies.org/ext-dep-index.html and the previous
+#   version. All relation types and subtypes from the UD 2.8 corpora
+#   should be there.
+# - contractions indexed
+######################################################################
+
+my $HELP = "
+==================================================================
+$CMD $VERSION: Help
+==================================================================
+FUNKTION: converts CoNLL parser output to TigerXML (for mate tools)
+          creates master file, splits input files, corrects unbound nodes
+SYNTAX:      $CMD [Options] <CoNLL file>
+OPTIONEN:
+ -c          ignore coordination (delete coordx- prefix in deprel)
+ -C str      corpus specials: nca
+ -h          show help
+ -o          create all files in this output directory (default: $outdir)
+set COLUMNS for required info (0 = column 1, 1 = column 2, etc.)
+ -D nr       colum for deprel default=$cold
+ -H nr       colum for head default=$colh
+ -M nr       colum for morphology (POS) default=$colm
+ -F nr       colum for morph. features default=$colf
+ -R str      Root category (default: $rootname)
+ -s nr       split output files after each nr sentence (default = $split)
+ -x str,...  include these attributes if present in the -X column of the first word
+             (the first code is also copied into the sentence id)
+ -X nr       the column where attributes are stored (default: $featcol)
+EXAMPLE:
+  - For mate parser output: no further options required
+    $CMD parsed.conll
+  - For Le Monde 2005: include attributes
+    gunzip -c parsed.conll.gz | conll2tiger.pl -x date,artnr,rubr
+  - For NCA:
+    conll2tiger.pl -C nca -x id,deaf,titreDees,editionDees,manuscritDees,regionDees,coefficientRegionDees,dateMoyenneDees,codeRegional,coefficientRegional,vers,ponctuation,mots,passage,commentairePhilologique,qualite,sourceQualite,commentaireForme,auteur,dateComposition,dateManuscrit,lieuComposition,lieuManuscrit,sourceDateComposition,sourceDateManuscrit,sourceLieuComposition,sourceLieuManuscrit,genre,traditionTextuelle,analyses,lignes,editionNCA tagged-oldfrench-lrec2014-dep.conll
+";
+
+###########################################################################
+#                    DO NOT MODIFY FOLLOWING CODE !
+###########################################################################
+
+###########################################################################
+# parse the command line
+###########################################################################
+
+use Getopt::Std;
+getopts('c:C:hD:H:M:o:R:s:x:X:');
+
+if ( defined($opt_h) ) {
+    print STDERR "$HELP";
+    exit(0);
+}
+
+if ( defined($opt_o) ) {
+    $outdir = $opt_o;
+}
+if ( defined($opt_C) ) {
+    $corpus = $opt_C;
+}
+if ( defined($opt_D) ) {
+    $cold = $opt_D;
+}
+if ( defined($opt_H) ) {
+    $colh = $opt_H;
+}
+if ( defined($opt_M) ) {
+    $colm = $opt_M;
+}
+
+if ( defined($opt_R) ) {
+    $rootname = $opt_R;
+}
+
+if ( defined($opt_s) ) {
+    $split = $opt_s;
+}
+
+if ( defined($opt_X) ) {
+    $featcol = $opt_X;
+}
+
+if ( defined($opt_x) ) {
+    @scodes = split( ",", $opt_x );
+    for ( my $i = 0 ; $i <= $#scodes ; $i++ ) {
+        $nt_features_header = $nt_features_header . sprintf( "<feature name=\"%s\" domain=\"NT\"></feature>\n", $scodes[$i] );
+    }
+    $nt_features_header =~ s/\bid\b/ncaid/;    # avoid reserved Tiger attribute "id"
+}
+
+my @colnames = ( "url", "ID", "FORM", "LEMMA", "PLEMMA", "POS", "PPOS", "FEAT", "PFEAT", "HEAD", "PHEAD", "DEPREL", "PDEPREL" );
+
+# my %pos = %lemma = %form = %deprel = %head = %governs = %cat2abbrev = %abbrev2cat = %coordnr_cat = %coordnr_head = %w_coordnr = %w_head = %w_deprel = %first_coordnr = %coordnr_first = %verb_head = ();
+my @coordelements = ();
+
+my $id = my $form = my $lemma = my $plemma = my $pos = my $ppos = my $feat = my $pfeat = my $head = my $phead = my $deprel = my $pdeprel = my $edition_id = "";
+
+my $timestamp = `date`;
+chomp($timestamp);
+
+my $infile = $ARGV[0];
+$infile =~ s/\.conllu?//i;
+if ( $infile eq '' ) {
+    $infile = 'subcorpus';
+}
+my $counter = 1;
+$suffix = sprintf( "%05d", $counter );
+$infilename = basename($infile);
+
+$foo = `if [ ! -d $outdir ];then mkdir $outdir;fi`;
+open( XML,    ">$outdir/$infilename-$suffix.xml" ) or die "\nopen file error of $outdir/$infilename-$suffix.xml\n";
+open( LOG,    ">$outdir/conversion.log" )          or die "\nopen file error of conversion.log\n";
+open( MASTER, ">$outdir/main.xml" )                or die "\nopen file error of main.xml\n";
+write_xml_header();
+write_master_header();
+
+# flush output for log and master file
+select(LOG);
+$| = 1;
+select(MASTER);
+$| = 1;
+
+$commandline = $0 . " " . ( join " ", @ARGV );
+print LOG "$commandline\n\n";
+
+print MASTER "<subcorpus name='$infilename-$suffix' external='file:$infilename-$suffix.xml'/>\n";
+
+$/ = "";    # treat empty line as RS
+while (<>) {
+    if ( $. % $split == 0 ) {
+        print XML "</subcorpus>\n";
+        close(XML);
+        $suffix = sprintf( "%05d", ++$counter );
+        open( XML, ">$outdir/$infilename-$suffix.xml" ) or die "\nopen file error\n";
+        write_xml_header();
+        print MASTER "<subcorpus name='$infilename-$suffix' external='file:$infilename-$suffix.xml'/>\n";
+    }
+
+    # ----------------------------------------
+    # set root (or fake root if ROOT is missing)
+    # ----------------------------------------
+    $rootnode = $fakeroot = 0;    # m = Treat string as multiple lines, so that ^ matches beginning of line
+    $thisrootname = $rootname;
+    ($rootnode) = (/^(\d+?)\s.*?\b$rootname\b/m);    # real root marked by parser
+    if ( $rootnode == 0 ) {
+
+        #    ($rootnode) = (/^(\d+?)\t.*?\t-1\t0\t/m);  # no marked ROOT, but top node (head = 0)   TOO SPECIFIC
+        #    ($rootnode) = (/^(\d+?)\t.*?\t.*?\t.*?\t.*?\t.*?\t.*?\t.*?\t0\t/m);  # no marked ROOT, but top node (head = 0) in col9 (original by Achim Stein)
+        ($rootnode) = (/^(\d+?)\t.*?\t.*?\t.*?\t.*?\t.*?\t0\t/m);    # no marked ROOT, but top node (head = 0) in col7 (updated by AL)
+        print LOG " Warning sentence $.: not marked root ($rootname), using top node $rootnode\n";
+        $fakeroot     = 1;
+        $thisrootname = 'nSnt';
+    }
+    if ( $rootnode == 0 ) {
+        $rootnode = 1;                                               # set fake root if nothing goes
+        print LOG " Error sentence $.: setting fake root to first word:\n$_\n";
+        $fakeroot     = 2;
+        $thisrootname = 'Err';
+    }
+
+    my @cols = ();
+    @words     = split(/\n/);
+    @terminals = ();
+
+    %dominates = ();                                                 # empty at beginning of sentence
+    %deprel    = ();                                                 # empty at beginning of sentence
+    %aux       = ();                                                 # empty at beginning of sentence
+    @daughters = ();
+
+    my $commentlines = 0;                                            #added by AL
+
+    #  my $contractions = 0; #added by AL
+    #  my $text_id = "unknown_text";
+    my $text_id = $infilename;
+    my $sent_id = "0";
+
+    # ----------------------------------------
+    # loop through words #1: write tokens (terminal nodes) to XML file
+    # store tree relevant information for loop #2
+    # ----------------------------------------
+    for ( my $w = 0 ; $w <= $#words ; $w++ ) {
+
+        # Added by AL for comment lines
+        if ( $words[$w] =~ /^#/ ) {
+            if ( $words[$w] =~ /^# newdoc/ ) {
+                $text_id = $words[$w];
+                $text_id =~ s/# newdoc id = //;
+            }
+            elsif ( $words[$w] =~ /^# sent_id/ ) {
+                $sent_id = $words[$w];
+                $sent_id =~ s/# sent_id = //;
+            }
+
+            #	print LOG "Comment line loop 1: $words[$w]\n";
+            $commentlines++;
+            next;
+        }
+
+        # Added by AL for contractions
+        elsif ( $words[$w] =~ /^\d+-\d+/ ) {
+
+            #	print LOG "Contraction line loop 1: $words[$w]\n";
+            $commentlines++;
+
+            #	$contractions++;
+            next;
+        }
+        else {
+            if ( defined($opt_c) ) {
+                $words[$w] =~ s/coord(\d+)-//g;
+            }
+            @cols       = split( /\t/, $words[$w] );
+            $wnr        = $cols[0];
+            $word       = $cols[1];
+            $lemma      = $cols[2];
+            $plemma     = $cols[2];                    # predicted
+            $pos        = $cols[3];
+            $ppos       = $cols[4];                    # predicted
+            $mor        = $cols[5];
+            $pmor       = $cols[5];                    # predicted
+            $cat        = $cols[$cold];
+            $edition_id = $cols[9];
+            $edition_id =~ s/^.*XmlId=([^|]+).*$/\1/g;
+
+            if ( $cat =~ /[<>]/ ) {
+                print LOG "Warning in line $.: illegal node name: \"$cat\" -> \"Err2\"\n";
+                $cat = 'Err2';
+            }
+
+            # NCA: enclose lemmas in underscores (easier for regex construction)
+            if ( $corpus =~ /nca/i ) {
+                $lemma = "_" . "$lemma" . "_";
+            }
+
+            clean_data();
+
+            # get attribute-value pairs from col #13 of first word (option -x)
+            if ( $opt_x == "all" ) {
+                $cols[$featcol] = "all=" . $cols[$featcol];
+            }
+            if ( $w == 0 && $cols[$featcol] =~ /=/ ) {
+
+                #      print STDERR "========== getting att-value for word $w: $cols[$featcol] scodes=@scodes\n";
+                $nt_features = $nt_empty_features = '';
+
+                #      while($cols[$featcol] =~ m/ (.*?)="([^"]*)"/gs) {   # quoted values
+                while ( $cols[$featcol] =~ m/ ?([^=]*?)="?([^, ]+)\b"?\b/gs ) {    # maybe unquoted values (e.g. Le Monde 2005)
+                    $att = $1;
+                    $val = $2;
+
+                    # pick the attributes that match those of the command line option -x
+                    for ( my $t = 0 ; $t <= $#scodes ; $t++ ) {
+                        if ( $att eq $scodes[$t] ) {
+                            $val =~ s/\&/\&amp;/g;                                 #  replace "&" in values (appears in URLs)
+                            if ( $t == 0 ) { $add_to_sentcode = "_$att$val"; }
+                            $nt_features = $nt_features . " $att=\"$val\"";
+
+                            #	    print STDERR "$./$w/$featcol: $cols[$featcol] --- nt_features: $nt_features\n";
+                        }
+                        if ( $att eq $scodes[$t] ) { $nt_empty_features = $nt_empty_features . " $att=\"--\""; }
+                    }
+                }
+
+                # replace the reserved feature 'id' (Tiger)
+                $add_to_sentcode =~ s/\bid=/ncaid=/;
+                $nt_features =~ s/\bid=/ncaid=/;
+                $nt_empty_features =~ s/\bid=/ncaid=/;
+            }    # if col 13 contains attributes
+            else {
+                if ( defined($opt_x) && ( $w == 0 ) ) {
+                    print STDERR "Warning: sentence=$.  option -x is defined, but no attribute=value declarations were found!\n";
+                }
+            }
+
+            # store output for terminal node in array, output later. For double categories make a duplicate node.
+            $tempid = sprintf( "%d_%d", $., $wnr );
+
+#    push(@terminals, sprintf("      <t id=\"s%d_%d\" word=\"%s\" pos=\"%s\" mor=\"%s\" lemma=\"%s\" ppos=\"%s\" pmor=\"%s\" plemma=\"%s\" textid=\"%s\" editionId=\"%s\"/>\n", $., $wnr, $word, $pos, $mor, $lemma, $ppos, $pmor, $plemma, $text_id, $edition_id));
+            push( @terminals,
+                sprintf( "      <t id=\"s%d_%d\" word=\"%s\" pos=\"%s\" mor=\"%s\" lemma=\"%s\" textid=\"%s\" editionId=\"%s\"/>\n", $., $wnr, $word, $pos, $mor, $lemma, $text_id, $edition_id ) );
+            if ( $cat =~ /_/ ) {
+
+#      push(@terminals, sprintf("      <t id=\"s%d_%d_dupl\" word=\"%s\" pos=\"%s\" mor=\"%s\" lemma=\"%s\" ppos=\"%s\" pmor=\"%s\" plemma=\"%s\" textid=\"%s\" editionId=\"%s\"/>\n", $., $wnr, "*", "_", "_", "_", "_", "_", "_", $text_id, $edition_id));
+                push( @terminals,
+                    sprintf( "      <t id=\"s%d_%d_dupl\" word=\"%s\" pos=\"%s\" mor=\"%s\" lemma=\"%s\" textid=\"%s\" editionId=\"%s\"/>\n", $., $wnr, "*", "_", "_", "_", $text_id, $edition_id ) );
+                $duplicates{$tempid} = 1;    # store, check later to attach the duplicates to the mother
+            }
+
+            # associate Aux with main verb, to create an attribute in the verb node in loop #2 (TODO: more than one Aux)
+            if ( $cat =~ /Aux/ ) {
+                $aux{ $cols[$colh] } = "$word" . "_" . "$plemma";    # $aux{head} = word_lemma (of Aux)
+            }
+
+            # ----------------------------------------
+            # store information needed for tree
+            # ----------------------------------------
+            # if fake rootnode == 1: nSnt as root node
+            if ( ( $fakeroot == 1 ) && ( $w - $commentlines + 1 == $rootnode ) ) {
+                $cat = 'nSnt';
+                $notes{$tempid} = 'Warning no marked ROOT node in CoNLL';    # TODO: geht nicht
+            }
+
+            # if fake rootnode == 2: flatten structure: attach all words to the first word
+            if ( ( $fakeroot == 2 ) && ( $w - $commentlines + 1 != $rootnode ) ) {
+                $cols[$colh] = 1;
+                $notes{$tempid} = 'Error neither ROOT node nor top node in CoNLL';
+            }
+
+            # correct unbound words in parser output (phead = 0, but not marked as ROOT)
+            if ( ( $cols[$colh] eq "0" ) && ( $w - $commentlines + 1 != $rootnode ) ) {    #AL: added: -$commentlines
+                printf LOG " Warning sentence $. ($tempid): unbound node %d (attached to root %d)\n", ( $w - $commentlines + 1 ), $rootnode;
+                $cols[$colh]    = $rootnode;
+                $cat            = 'Err';                                                   # let Err instead of deprel appear in dom attribute
+                $notes{$tempid} = 'Warning unbound node in CoNLL';
+            }
+
+            # store for R edge labels
+            if ( $cols[$cold] =~ /RelN?C/ ) {
+                $relators{$tempid} = 1;
+            }
+
+            # store deprel for dom attribute
+            $deprel{$tempid} = $cat;                                                       # $cols[$cold];
+                                                                                           # if real root, add this node to daughter array, store array in hash dominates{head}{@daughters}
+            if ( ( $fakeroot < 2 ) && ( $w - $commentlines + 1 != $rootnode ) ) {
+                @daughters = @{ $dominates{ $cols[$colh] } };                              # get the array from the hash of the dominating node
+                push( @daughters, $wnr );
+                $dominates{ $cols[$colh] } = [@daughters];
+            }
+        }    # for each word loop #1
+    }    # AL condition end
+
+    # print graph code (needs root attribute) and terminal nodes
+    if ( $rootnode == 0 ) {
+        $noroot++;
+        print LOG "Error sentence $. ($tempid): root node not found:\n$_\n";
+        next;
+    }
+    else {
+        printf XML "<s id=\"s%s%s\" textid=\"$text_id\" sentid=\"$sent_id\">\n", $., $add_to_sentcode;
+        print XML "  <graph root=\"n$._$rootnode\">\n";
+        print XML "    <terminals>\n";
+        for ( my $t = 0 ; $t <= $#terminals ; $t++ ) {
+            print XML $terminals[$t];
+        }
+        print XML "    </terminals>\n";
+    }
+
+    # ----------------------------------------
+    # loop through words #2 to build Tiger tree (non terminal nodes)
+    # ----------------------------------------
+    print XML "    <nonterminals>\n";
+    for ( my $i = 0 ; $i <= $#words ; $i++ ) {
+
+        #Added AL for comment lines
+        if ( $words[$i] =~ /^#/ ) {
+
+            #       print LOG "Comment line loop 2 : $words[$i]\n";
+            next;
+        }
+
+        #Added AL for contractions
+        if ( $words[$i] =~ /^\d+-\d+/ ) {
+
+            #       print LOG "Contraction loop 2 : $words[$i]\n";
+            next;
+        }
+
+        else {
+
+            @cols = split( /\t/, $words[$i] );
+            $w = $cols[0];
+            ### TODO: redundante Variablenzuweisung (= loop #1)??
+            $word   = $cols[1];
+            $lemma  = $cols[2];
+            $plemma = $cols[3];       # predicted
+            $pos    = $cols[4];
+            $ppos   = $cols[5];       # predicted
+            $mor    = $cols[6];
+            $pmor   = $cols[7];       # predicted
+            $cat    = $cols[$cold];
+
+            if ( $cat =~ /[<>]/ ) {
+                print Log "Warning in line $.: illegal node name: \"$cat\" -> \"Err2\"\n";
+                $cat = 'Err2';
+            }
+
+            #  OF parser has not learned punctuation: set cat for punctuation to PON
+            if ( ( $corpus =~ /nca/i ) && ( $pos eq 'PON' ) ) {
+                $cols[$cold] = $cat = 'Pon';
+            }
+
+            clean_data();
+
+            # retrieve daughters, make dom attribute (string of dominated nodes)
+            @daughters = @{ $dominates{"$w"} };
+            $dom       = '';
+            for ( my $d = 0 ; $d <= $#daughters ; $d++ ) {
+                $dom = $dom . "_" . $deprel{"$._$daughters[$d]"};
+            }
+            if ( $dom =~ /_/ ) {
+                $dom =~ s/^_//;
+            }
+            else {
+                $dom = '--';
+            }
+
+            # if verbal, set node attributes for verb form and lemma
+            $type = "nV";
+            $vform = $vlemma = "--";
+            if ( $pos =~ /VER/ ) {    # AL: $ppos -> $pos
+                if    ( $mor =~ /infi/ )       { $type = "VInf"; }    #AL: $pmor -> $mor
+                elsif ( $pmor =~ /pper|ppre/ ) { $type = "VPar"; }
+                else                           { $type = "VFin"; }
+
+                # if Aux is present, create attribute for main verb
+                if ( $aux{$w} =~ /(.*?)_(.*)/ ) {
+                    $vform  = "$1";
+                    $vlemma = "$2";
+                }
+
+                # else create attr for simple verb
+                else {
+                    $vform  = $word;
+                    $vlemma = $lemma;    # AL: $plemma -> $lemma (always void in SRCMF)
+                }
+
+                # NCA: enclose lemmas in underscores (easier for regex construction)
+                if ( $corpus =~ /nca/i ) {
+                    $vlemma = "_" . "$vlemma" . "_";
+                }
+            }
+
+            # call output function (twice for duplicate categories)
+            if ( $cat =~ /(.*?)_(.*)/ ) {
+                write_nonterminals( "$2", "" );         # RelNC is always node (see clean categories), function is duplicate, e.g. SjPer_RelNC
+                write_nonterminals( "$1", "_dupl" );    # other category is duplicate
+            }
+            else {
+                write_nonterminals($cat);
+            }
+        }    # for words
+    }    #AL end condition
+
+    print XML "    </nonterminals>\n";
+    print XML "  </graph>\n";
+    print XML "</s>\n";
+    if ( $. % 100 == 0 ) { print STDERR "\b\b\b\b\b\b\b\b"; printf STDERR "%08d", $.; }
+}    # main
+print XML "</subcorpus>\n";
+print STDERR "\n$CMD: $. sentences converted. Results in $outdir. Log in $outdir/conversion.log.\n";
+print STDERR "   Hint 1: on OS X convert master file to MacRoman, e.g  iconv -f latin1 -t macroman\n";
+print STDERR "   Hint 2: use tiger.pl -c <Tiger XML file> to detect unbound nodes.\n";
+print STDERR "   Hint 3: build reliable feature declarations using tiger.sh\n";
+print STDERR "           tiger.sh -a \"lemma word pos ppos\"  (for terminals)\n";
+print STDERR "           tiger.sh -A \"lemma word pos ppos\"  (for non-terminals)\n";
+if ( $noroot > 0 ) { print STDERR "$noroot sentences ignored: root not found (see log file)\n"; }
+write_master_footer();
+close(MASTER);
+close(XML);
+close(LOG);
+
+exit;
+
+# ----------------------------------------
+# sub
+# ----------------------------------------
+
+sub write_xml_header {
+    print XML "<?xml version=\"1.0\" encoding=\"UTF-8\"?>
+  <subcorpus name=\"$infilename-$suffix\">
+";
+}
+
+sub write_master_header {
+    printf MASTER '<?xml version="1.0" encoding="UTF-8"?>
+';
+
+    printf MASTER "<corpus id=\"$corpus\">
+<head>
+  <meta><name>$corpus</name> 
+    <author>ILR Stuttgart</author> 
+    <date></date> 
+    <description>Parsed with mate tools using a SRCMF-based grammar model (http://srcmf.org). </description> 
+    <format>SRCMF</format>
+    <history>TigerXML converted by conll2tiger.pl</history>
+  </meta>
+";
+
+    #  printf MASTER '<annotation>
+    #<feature name="word" domain="T" ></feature>
+    #<feature name="pos" domain="T" ></feature>
+    #<feature name="mor" domain="T" ></feature>
+    #<feature name="lemma" domain="T" ></feature>
+    #<feature name="ppos" domain="T" ></feature>
+    #<feature name="pmor" domain="T" ></feature>
+    #<feature name="plemma" domain="T" ></feature>
+    #<feature name="cat" domain="NT" >
+    #  <value name="Apst">apostrophe</value>
+    #  <value name="AtObj">attribut d objet</value>
+    #  <value name="AtRfc">attribut réfléchi</value>
+    #  <value name="AtSj">attribut de sujet</value>
+    #  <value name="AttributReflechi">attribut réfléchi</value>
+    #  <value name="Aux">auxilié</value>
+    #  <value name="AuxA">auxilié actif</value>
+    #  <value name="AuxP">auxilié passif</value>
+    #  <value name="Circ">circonstant</value>
+    #  <value name="Circ_RelNC">circonstant pronom relatif</value>
+    #  <value name="Cmpl">complément</value>
+    #  <value name="Cmpl_RelNC">complément pronom relatif</value>
+    #  <value name="Coo">coordination</value>
+    #  <value name="Det">déterminant</value>
+    #  <value name="Err">unbound node in CoNLL input</value>
+    #  <value name="Err2">illegal node name was replaced</value>
+    #  <value name="GpCoo">coordonné</value>
+    #  <value name="Ignorer">Ignorer</value>
+    #  <value name="Insrt">incidente</value>
+    #  <value name="Intj">interjection</value>
+    #  <value name="Lac">lacune</value>
+    #  <value name="ModA">modifieur attaché</value>
+    #  <value name="ModD">modifieur détaché</value>
+    #  <value name="Ng">négation</value>
+    #  <value name="NgPrt">forclusif</value>
+    #  <value name="Obj">objet</value>
+    #  <value name="Obj_RelNC">direct object pronom relatif</value>
+    #  <value name="Pon">ponctuation</value>
+    #  <value name="PON">ponctuation</value>
+    #  <value name="Regim">régime</value>
+    #  <value name="RelC">relateur coordonnant</value>
+    #  <value name="RelNC">relateur non coordonnant</value>
+    #  <value name="Rfc">réfléchi</value>
+    #  <value name="Rfx">réfléxif renforcé</value>
+    #  <value name="SjImp">sujet impersonnel</value>
+    #  <value name="SjPer">sujet personnel</value>
+    #  <value name="SjPer_RelNC">sujet personnel pronom relatif</value>
+    #  <value name="Snt">phrase</value>
+    #  <value name="ROOT">phrase</value>
+    #  <value name="StructureMaximale">structure maximale</value>
+    #  <value name="VFin">verbe fini</value>
+    #  <value name="VInf">verbe infinitif</value>
+    #  <value name="nMax">structure non-maximale</value>
+    #  <value name="nSnt">non-phrase</value>
+    #</feature>
+    #<feature name="coord" domain="NT" ></feature>
+    #<feature name="dom" domain="NT" ></feature>
+    #<feature name="type" domain="NT" >
+    #  <value name="nV">élément non-verbal</value>
+    #  <value name="VFin">verbe fini</value>
+    #  <value name="VInf">verbe infinitif</value>
+    #  <value name="VPar">verbe participial</value>
+    #  <value name="--">nil</value>
+    #</feature>
+    #<feature name="vform" domain="NT"></feature>
+    #<feature name="vlemma" domain="NT"></feature>
+    #<feature name="note" domain="NT"></feature>
+    #<feature name="snr" domain="NT"></feature>
+    #';
+
+    printf MASTER '<annotation>
+<feature name="word" domain="T" ></feature>
+<feature name="pos" domain="T" ></feature>
+<feature name="mor" domain="T" ></feature>
+<feature name="lemma" domain="T" ></feature>
+<feature name="textid" domain="T" ></feature>
+<feature name="editionId" domain="T" ></feature>
+<feature name="cat" domain="NT" >
+  <value name="__UNDEF__">UNDEFINED !!!</value>
+  <value name="acl:adv">acl:adv</value> <!-- Ukrainian -->
+  <value name="acl:attr">acl:attr</value> <!-- Chukchi -->
+  <value name="acl:cleft">acl:cleft</value> <!-- Norwegian, Swedish -->
+  <value name="acl:fixed">acl:fixed</value> <!-- Beja -->
+  <value name="acl:inf">acl:inf</value> <!-- Portuguese -->
+  <value name="acl:relat">acl:relat</value> <!-- Chukchi -->
+  <value name="acl:relcl">relative clause modifier</value> <!-- Akkadian, Albanian, Apurina, Arabic, Armenian, Assyrian, Beja, Belarusian, Breton, Bulgarian, Chinese, Czech, Danish, Dutch, English, Erzya, Estonian, Faroese, Finnish, French, German, Greek, Hebrew, Hindi, Hindi English, Icelandic, Indonesian, Irish, Italian, Karelian, Kazakh, Komi Permyak, Komi Zyrian, Korean, Latin, Lithuanian, Livvi, Manx, Marathi, Moksha, Naija, North Sami, Norwegian, Old East Slavic, Old French, Persian, Polish, Portuguese, Russian, Sanskrit, Scottish Gaelic, Slovak, Spanish, Swedish, Swedish Sign Language, Swiss German, Tagalog, Tamil, Telugu, Thai, Ukrainian, Urdu, Welsh, Western Armenian, Wolof -->
+  <value name="acl">clausal modifier of noun (adnominal clause)</value>
+  <value name="advcl:abs">advcl:abs</value> <!-- Latin -->
+  <value name="advcl:cau">advcl:cau</value> <!-- Moksha -->
+  <value name="advcl:cleft">advcl:cleft</value> <!-- French, Naija -->
+  <value name="advcl:cmpr">advcl:cmpr</value> <!-- Latin, Polish -->
+  <value name="advcl:cond">advcl:cond</value> <!-- Tamil, Telugu, Uyghur -->
+  <value name="advcl:coverb">advcl:coverb</value> <!-- Cantonese -->
+  <value name="advcl:eval">advcl:eval</value> <!-- Komi Zyrian -->
+  <value name="advcl:lcl">advcl:lcl</value> <!-- Komi Permyak -->
+  <value name="advcl:lto">advcl:lto</value> <!-- Komi Zyrian -->
+  <value name="advcl:mcl">advcl:mcl</value> <!-- Komi Permyak -->
+  <value name="advcl:pred">advcl:pred</value> <!-- Latin -->
+  <value name="advcl:relcl">advcl:relcl</value> <!-- Polish, Western Armenian -->
+  <value name="advcl:sp">advcl:sp</value> <!-- Ukrainian -->
+  <value name="advcl:svc">advcl:svc</value> <!-- Ukrainian -->
+  <value name="advcl:tcl">advcl:tcl</value> <!-- Apurina, Erzya, Komi Permyak, Komi Zyrian, Moksha, Romanian, Skolt Sami -->
+  <value name="advcl">adverbial clause modifier</value>
+  <value name="advmod:arg">advmod:arg</value> <!-- Polish -->
+  <value name="advmod:cau">advmod:cau</value> <!-- Erzya, Komi Zyrian, Moksha -->
+  <value name="advmod:comp">advmod:comp</value> <!-- Erzya -->
+  <value name="advmod:deg">advmod:deg</value> <!-- Erzya, Komi Permyak, Komi Zyrian, Moksha, Skolt Sami -->
+  <value name="advmod:det">advmod:det</value> <!-- Ukrainian -->
+  <value name="advmod:df">advmod:df</value> <!-- Cantonese, Chinese -->
+  <value name="advmod:emph">emphasizing word, intensifier</value> <!-- Akkadian, Arabic, Armenian, Catalan, Chukchi, Croatian, Czech, Indonesian, Komi Zyrian, Latin, Lithuanian, Polish, Sanskrit, Slovak, South Levantine Arabic, Tamil, Turkish, Turkish German, Upper Sorbian, Uyghur, Western Armenian -->
+  <value name="advmod:eval">advmod:eval</value> <!-- Erzya, Komi Zyrian, Moksha, Skolt Sami -->
+  <value name="advmod:fixed">advmod:fixed</value> <!-- Beja -->
+  <value name="advmod:foc">advmod:foc</value> <!-- Erzya, Komi Zyrian, Moksha, Skolt Sami -->
+  <value name="advmod:freq">advmod:freq</value> <!-- Komi Zyrian, Moksha -->
+  <value name="advmod:lfrom">advmod:lfrom</value> <!-- Erzya, Komi Zyrian, Moksha -->
+  <value name="advmod:lmod">locative adverbial modifier</value> <!-- Apurina, Danish, Erzya, Komi Permyak, Komi Zyrian, Moksha, Skolt Sami -->
+  <value name="advmod:lmp">advmod:lmp</value> <!-- Erzya, Komi Zyrian -->
+  <value name="advmod:locy">advmod:locy</value> <!-- Hungarian -->
+  <value name="advmod:lto">advmod:lto</value> <!-- Erzya, Komi Zyrian, Moksha -->
+  <value name="advmod:mmod">advmod:mmod</value> <!-- Erzya, Komi Permyak, Komi Zyrian, Moksha, Skolt Sami -->
+  <value name="advmod:mode">advmod:mode</value> <!-- Hungarian -->
+  <value name="advmod:neg">advmod:neg</value> <!-- Apurina, Buryat, Kiche, Kurmanji, Latin, Maltese, Polish, Skolt Sami -->
+  <value name="advmod:obl">adverbial modifier + oblique nominal</value> <!-- Old French -->
+  <value name="advmod:que">advmod:que</value> <!-- Hungarian -->
+  <value name="advmod:tfrom">advmod:tfrom</value> <!-- Hungarian -->
+  <value name="advmod:tlocy">advmod:tlocy</value> <!-- Hungarian -->
+  <value name="advmod:tmod">advmod:tmod</value> <!-- Apurina, Erzya, Komi Permyak, Komi Zyrian, Moksha, Romanian, Skolt Sami -->
+  <value name="advmod:to">advmod:to</value> <!-- Hungarian -->
+  <value name="advmod:tto">advmod:tto</value> <!-- Hungarian -->
+  <value name="advmod">adverbial modifier</value>
+  <value name="amod:att">amod:att</value> <!-- Hungarian -->
+  <value name="amod:attlvc">amod:attlvc</value> <!-- Hungarian -->
+  <value name="amod:flat">amod:flat</value> <!-- Polish -->
+  <value name="amod">adjectival modifier</value>
+  <value name="appos:trans">appos:trans</value> <!-- Turkish German -->
+  <value name="appos">appositional modifier</value>
+  <value name="aux:aff">aux:aff</value> <!-- Beja -->
+  <value name="aux:aspect">aux:aspect</value> <!-- Komi Zyrian -->
+  <value name="aux:caus">aux:caus</value> <!-- Armenian, French, Western Armenian -->
+  <value name="aux:clitic">aux:clitic</value> <!-- Polish -->
+  <value name="aux:cnd">aux:cnd</value> <!-- Erzya, Komi Permyak, Komi Zyrian, Polish -->
+  <value name="aux:ex">aux:ex</value> <!-- Armenian, Western Armenian -->
+  <value name="aux:imp">aux:imp</value> <!-- Erzya, Polish -->
+  <value name="aux:nec">aux:nec</value> <!-- Komi Zyrian, Moksha, Skolt Sami -->
+  <value name="aux:neg">aux:neg</value> <!-- Chukchi, Erzya, Komi Permyak, Komi Zyrian, Maltese, Moksha, North Sami, Skolt Sami, Tamil -->
+  <value name="aux:opt">aux:opt</value> <!-- Erzya, Moksha -->
+  <value name="aux:part">aux:part</value> <!-- Maltese -->
+  <value name="aux:pass">passive auxilary</value> <!-- Afrikaans, Ancient Greek, Arabic, Assyrian, Belarusian, Bhojpuri, Breton, Bulgarian, Buryat, Chinese, Czech, Dutch, English, Faroese, Finnish, French, Frisian Dutch, Galician, German, Hindi, Italian, Kangri, Karelian, Latin, Latvian, Lithuanian, Maltese, Marathi, Norwegian, Old Church Slavonic, Old East Slavic, Old French, Persian, Polish, Portuguese, Romanian, Russian, Slovak, Spanish, Swedish, Swiss German, Tamil, Thai, Turkish German, Upper Sorbian, Vietnamese -->
+  <value name="aux:pot">aux:pot</value> <!-- Komi Zyrian -->
+  <value name="aux:q">aux:q</value> <!-- Erzya, Turkish, Turkish German -->
+  <value name="aux:tense">aux:tense</value> <!-- French, Komi Zyrian, Skolt Sami -->
+  <value name="aux">auxiliary</value>
+  <value name="case:acc">case:acc</value> <!-- Hebrew -->
+  <value name="case:adv">case:adv</value> <!-- Indonesian -->
+  <value name="case:aff">case:aff</value> <!-- Beja -->
+  <value name="case:det">preposition with determiner</value> <!-- Maltese, Old French -->
+  <value name="case:gen">case:gen</value> <!-- Hebrew -->
+  <value name="case:loc">case:loc</value> <!-- Armenian, Cantonese, Chinese, Western Armenian -->
+  <value name="case:pred">case:pred</value> <!-- Welsh -->
+  <value name="case:voc">case:voc</value> <!-- Irish, Scottish Gaelic -->
+  <value name="case">case marking</value>
+  <value name="cc:nc">cc:nc</value> <!-- Old French -->
+  <value name="cc:nc">Coordinated conjunct : non coordonant</value>
+  <value name="cc:preconj">cc:preconj</value> <!-- Arabic, English, Erzya, Estonian, Faroese, Finnish, German, Indonesian, Komi Permyak, Komi Zyrian, Moksha, North Sami, Persian, Polish, Portuguese, Romanian, Slovenian, Spanish, Thai, Turkish -->
+  <value name="cc:preconj">preconjunct</value>
+  <value name="cc">Coordinating conjunction</value>
+  <value name="cc">coordinating conjunction</value>
+  <value name="ccomp:cleft">ccomp:cleft</value> <!-- Polish -->
+  <value name="ccomp:obj">ccomp:obj</value> <!-- Hungarian, Polish -->
+  <value name="ccomp:obl">ccomp:obl</value> <!-- Hungarian -->
+  <value name="ccomp:pmod">ccomp:pmod</value> <!-- Romanian -->
+  <value name="ccomp:pred">ccomp:pred</value> <!-- Hungarian -->
+  <value name="ccomp">clausal complement</value>
+  <value name="clf">classifier</value>
+  <value name="compound:a">compound:a</value> <!-- Indonesian -->
+  <value name="compound:affix">compound:affix</value> <!-- Hebrew -->
+  <value name="compound:dir">compound:dir</value> <!-- Cantonese, Chinese -->
+  <value name="compound:ext">compound:ext</value> <!-- Cantonese, Chinese -->
+  <value name="compound:lvc">compound:lvc</value> <!-- Armenian, Hindi, Kazakh, Khunsari, Korean, Kurmanji, Marathi, Nayini, Persian, Soi, Tamil, Telugu, Turkish, Turkish German, Uyghur, Western Armenian -->
+  <value name="compound:lvc">light verb construction</value>
+  <value name="compound:nn">compound:nn</value> <!-- Finnish, Livvi, North Sami -->
+  <value name="compound:preverb">compound:preverb</value> <!-- Hungarian -->
+  <value name="compound:prt">compound:prt</value> <!-- Afrikaans, Arabic, Danish, Dutch, English, Erzya, Estonian, Faroese, Finnish, Frisian Dutch, German, Icelandic, Irish, Karelian, Komi Permyak, Naija, Norwegian, Persian, Spanish, Swedish, Swedish Sign Language, Swiss German, Tamil, Thai, Turkish German, Wolof, Yoruba -->
+  <value name="compound:prt">phrasal verb particle</value>
+  <value name="compound:quant">compound:quant</value> <!-- Cantonese -->
+  <value name="compound:redup">reduplicated compounds</value> <!-- Armenian, Bambara, Classical Chinese, Erzya, Hindi, Kurmanji, Marathi, Naija, Tagalog, Tamil, Telugu, Turkish, Turkish German, Uyghur, Welsh, Western Armenian -->
+  <value name="compound:smixut">compound:smixut</value> <!-- Hebrew -->
+  <value name="compound:svc">serial verb compounds</value> <!-- Amharic, Armenian, Marathi, Mbya Guarani, Naija, Swedish Sign Language, Telugu, Ukrainian, Western Armenian, Wolof, Yoruba -->
+  <value name="compound:vo">compound:vo</value> <!-- Cantonese, Chinese -->
+  <value name="compound:vv">compound:vv</value> <!-- Cantonese, Chinese -->
+  <value name="compound">compound</value>
+  <value name="conj:expl">conj:expl</value> <!-- Latin -->
+  <value name="conj:extend">conj:extend</value> <!-- Slovenian -->
+  <value name="conj:svc">conj:svc</value> <!-- Ukrainian -->
+  <value name="conj">conjunct</value>
+  <value name="cop:expl">cop:expl</value> <!-- Maltese -->
+  <value name="cop:locat">cop:locat</value> <!-- Polish -->
+  <value name="cop:own">cop:own</value> <!-- Finnish, Karelian, Livvi, Marathi -->
+  <value name="cop">copula</value>
+  <value name="csubj:cleft">csubj:cleft</value> <!-- Irish, Latin, Manx, Scottish Gaelic -->
+  <value name="csubj:cop">csubj:cop</value> <!-- Erzya, Estonian, Finnish, Irish, Komi Zyrian, Livvi, Manx, Moksha, Scottish Gaelic, Turkish -->
+  <value name="csubj:pass">clausal passive subject</value> <!-- Albanian, Amharic, Ancient Greek, Arabic, Armenian, Belarusian, Bulgarian, Catalan, Chinese, Classical Chinese, Czech, English, French, German, Gothic, Greek, Indonesian, Italian, Korean, Latin, Latvian, Lithuanian, Norwegian, Old Church Slavonic, Old East Slavic, Polish, Portuguese, Romanian, Russian, Sanskrit, Slovak, Spanish, Swedish, Western Armenian -->
+  <value name="csubj">clausal subject</value>
+  <value name="dep:aff">dep:aff</value> <!-- Beja -->
+  <value name="dep:agr">dep:agr</value> <!-- Kiche -->
+  <value name="dep:alt">dep:alt</value> <!-- Upper Sorbian -->
+  <value name="dep:ana">dep:ana</value> <!-- Yupik -->
+  <value name="dep:aux">dep:aux</value> <!-- Yupik -->
+  <value name="dep:comp">dep:comp</value> <!-- Beja, French -->
+  <value name="dep:conj">dep:conj</value> <!-- Beja -->
+  <value name="dep:cop">dep:cop</value> <!-- Yupik -->
+  <value name="dep:emo">dep:emo</value> <!-- Yupik -->
+  <value name="dep:infl">dep:infl</value> <!-- Yupik -->
+  <value name="dep:mark">dep:mark</value> <!-- Yupik -->
+  <value name="dep:mod">dep:mod</value> <!-- Mbya Guarani -->
+  <value name="dep:pos">dep:pos</value> <!-- Yupik -->
+  <value name="dep:redup">dep:redup</value> <!-- Beja -->
+  <value name="dep:ss">dep:ss</value> <!-- Kiche -->
+  <value name="dep">unspecified dependency</value>
+  <value name="det:adj">det:adj</value> <!-- Albanian -->
+  <value name="det:noun">det:noun</value> <!-- Albanian -->
+  <value name="det:numgov">pronominal quantifier governing the case of the noun</value> <!-- Czech, Polish, Serbian, Slovak, Ukrainian, Upper Sorbian -->
+  <value name="det:nummod">pronominal quantifier agreeing in case with the noun</value> <!-- Czech, Polish, Ukrainian -->
+  <value name="det:poss">possessive determiner</value> <!-- Akkadian, Armenian, German, Italian, Korean, Polish, Portuguese, Western Armenian -->
+  <value name="det:predet">det:predet</value> <!-- English, Italian, Persian -->
+  <value name="det:pron">det:pron</value> <!-- Albanian -->
+  <value name="det:rel">det:rel</value> <!-- Bambara -->
+  <value name="det">determiner</value>
+  <value name="discourse:emo">discourse:emo</value> <!-- Irish, Italian, Polish -->
+  <value name="discourse:filler">discourse:filler</value> <!-- Norwegian, Slovenian -->
+  <value name="discourse:intj">discourse:intj</value> <!-- Polish -->
+  <value name="discourse:sp">discourse:sp</value> <!-- Cantonese, Chinese, Classical Chinese -->
+  <value name="discourse">discourse element</value>
+  <value name="dislocated:cleft">dislocated:cleft</value> <!-- Mbya Guarani -->
+  <value name="dislocated:csubj">dislocated:csubj</value> <!-- Latin -->
+  <value name="dislocated:nsubj">dislocated:nsubj</value> <!-- Latin -->
+  <value name="dislocated:obj">dislocated:obj</value> <!-- Latin -->
+  <value name="dislocated:subj">dislocated:subj</value> <!-- Beja -->
+  <value name="dislocated">dislocated elements</value>
+  <value name="expl:comp">expl:comp</value> <!-- French -->
+  <value name="expl:impers">impersonal expletive</value> <!-- Italian, Polish, Romanian, Spanish -->
+  <value name="expl:pass">reflexive pronoun used in reflexive passive</value> <!-- Catalan, Czech, French, Italian, Latin, Portuguese, Romanian, Slovak, Spanish, Upper Sorbian -->
+  <value name="expl:poss">expl:poss</value> <!-- Romanian -->
+  <value name="expl:pv">reflexive clitic with an inherently reflexive verb</value> <!-- Czech, Dutch, German, Old East Slavic, Polish, Portuguese, Romanian, Slovak, Spanish, Turkish German, Upper Sorbian -->
+  <value name="expl:subj">expl:subj</value> <!-- French, Naija -->
+  <value name="expl">expletive</value>
+  <value name="fixed">fixed multiword expression</value>
+  <value name="flat:abs">flat:abs</value> <!-- Ukrainian -->
+  <value name="flat:dist">flat:dist</value> <!-- Western Armenian -->
+  <value name="flat:foreign">foreign words</value> <!-- Arabic, Belarusian, Buryat, Chinese, Chukchi, Croatian, Czech, English, Estonian, Faroese, Finnish, French, Galician, Icelandic, Indonesian, Irish, Italian, Komi Zyrian, Latin, Latvian, Lithuanian, Manx, Naija, Norwegian, Persian, Polish, Portuguese, Russian, Scottish Gaelic, Slovak, Slovenian, South Levantine Arabic, Ukrainian, Upper Sorbian -->
+  <value name="flat:name">names</value> <!-- Ancient Greek, Belarusian, Breton, Chinese, Chukchi, Erzya, Faroese, Finnish, French, Frisian Dutch, Galician, German, Gothic, Hebrew, Hindi, Hungarian, Icelandic, Indonesian, Irish, Italian, Karelian, Kazakh, Komi Permyak, Komi Zyrian, Korean, Latin, Latvian, Livvi, Maltese, Moksha, Norwegian, Old Church Slavonic, Old East Slavic, Persian, Portuguese, Russian, Scottish Gaelic, Skolt Sami, Slovenian, Spanish, Swedish, Thai, Ukrainian, Welsh, Western Armenian -->
+  <value name="flat:num">flat:num</value> <!-- Komi Zyrian, Persian -->
+  <value name="flat:range">flat:range</value> <!-- Ukrainian, Western Armenian -->
+  <value name="flat:repeat">flat:repeat</value> <!-- Ukrainian -->
+  <value name="flat:sibl">flat:sibl</value> <!-- Ukrainian -->
+  <value name="flat:title">flat:title</value> <!-- Ukrainian -->
+  <value name="flat:vv">flat:vv</value> <!-- Classical Chinese -->
+  <value name="flat">name multiword expression</value>
+  <value name="goeswith">goes with</value>
+  <value name="iobj:agent">iobj:agent</value> <!-- Armenian, French, Western Armenian -->
+  <value name="iobj:appl">iobj:appl</value> <!-- Wolof -->
+  <value name="iobj:patient">iobj:patient</value> <!-- Tagalog -->
+  <value name="iobj">indirect object</value>
+  <value name="list">list</value>
+  <value name="mark:adv">mark:adv</value> <!-- Cantonese, Chinese -->
+  <value name="mark:advmod">adverbial modifier confusable with a subordination marker</value> <!-- Old French -->
+  <value name="mark:aff">mark:aff</value> <!-- Beja -->
+  <value name="mark:obj">marker + object</value> <!--Old French, no doc -->
+  <value name="mark:obl">marker + oblique nominal</value> <!--Old French, no doc -->
+  <value name="mark:prt">mark:prt</value> <!-- Chinese, Irish, Scottish Gaelic -->
+  <value name="mark:q">mark:q</value> <!-- Hebrew -->
+  <value name="mark:rel">mark:rel</value> <!-- Cantonese, Chinese -->
+  <value name="mark">marker</value>
+  <value name="nmod:agent">nmod:agent</value> <!-- Welsh -->
+  <value name="nmod:appos">nmod:appos</value> <!-- French, Komi Zyrian, Moksha -->
+  <value name="nmod:arg">nmod:arg</value> <!-- Polish, Yupik -->
+  <value name="nmod:att">nmod:att</value> <!-- Hungarian -->
+  <value name="nmod:attlvc">nmod:attlvc</value> <!-- Hungarian -->
+  <value name="nmod:attr">nmod:attr</value> <!-- Chukchi -->
+  <value name="nmod:bahuv">nmod:bahuv</value> <!-- Moksha -->
+  <value name="nmod:cau">nmod:cau</value> <!-- Uyghur -->
+  <value name="nmod:comp">nmod:comp</value> <!-- Erzya, Komi Zyrian, Moksha, Turkish, Uyghur -->
+  <value name="nmod:flat">nmod:flat</value> <!-- Polish -->
+  <value name="nmod:gen">nmod:gen</value> <!-- Breton -->
+  <value name="nmod:gobj">nmod:gobj</value> <!-- Erzya, Finnish -->
+  <value name="nmod:gsubj">nmod:gsubj</value> <!-- Erzya, Finnish, Karelian -->
+  <value name="nmod:lfrom">nmod:lfrom</value> <!-- Komi Zyrian -->
+  <value name="nmod:lmod">nmod:lmod</value> <!-- Erzya, Indonesian, Komi Permyak, Komi Zyrian, Moksha -->
+  <value name="nmod:npmod">nmod:npmod</value> <!-- Armenian, English, Western Armenian -->
+  <value name="nmod:obj">nmod:obj</value> <!-- Komi Zyrian -->
+  <value name="nmod:obl">nmod:obl</value> <!-- Hungarian -->
+  <value name="nmod:part">nmod:part</value> <!-- Turkish, Uyghur -->
+  <value name="nmod:poss">possessive nominal modifier</value> <!-- Akkadian, Albanian, Apurina, Arabic, Armenian, Assyrian, Bambara, Beja, Breton, Chukchi, Danish, Dutch, English, Erzya, Faroese, Finnish, Frisian Dutch, German, Hebrew, Hindi, Icelandic, Indonesian, Irish, Karelian, Kazakh, Khunsari, Komi Permyak, Komi Zyrian, Korean, Kurmanji, Latin, Livvi, Maltese, Manx, Marathi, Moksha, Naija, Nayini, North Sami, Persian, Polish, Sanskrit, Scottish Gaelic, Skolt Sami, Soi, South Levantine Arabic, Swedish, Swedish Sign Language, Swiss German, Tagalog, Tamil, Telugu, Thai, Turkish, Uyghur, Warlpiri, Welsh, Western Armenian, Wolof -->
+  <value name="nmod:pred">nmod:pred</value> <!-- Polish -->
+  <value name="nmod:prp">nmod:prp</value> <!-- Komi Zyrian -->
+  <value name="nmod:redup">nmod:redup</value> <!-- Welsh -->
+  <value name="nmod:relat">nmod:relat</value> <!-- Chukchi -->
+  <value name="nmod:subj">nmod:subj</value> <!-- Komi Zyrian -->
+  <value name="nmod:tmod">temporal modifier</value> <!-- Chinese, English, Indonesian, Moksha, Romanian, Telugu, Uyghur -->
+  <value name="nmod">nominal modifier</value>
+  <value name="nsubj:advmod">fused subject pronoun and adverb</value> <!-- Old French -->
+  <value name="nsubj:aff">nsubj:aff</value> <!-- Beja -->
+  <value name="nsubj:bfoc">nsubj:bfoc</value> <!-- Tagalog -->
+  <value name="nsubj:caus">nsubj:caus</value> <!-- Armenian, French, Western Armenian -->
+  <value name="nsubj:cleft">nsubj:cleft</value> <!-- Latin -->
+  <value name="nsubj:cop">nsubj:cop</value> <!-- Apurina, Breton, Erzya, Estonian, Finnish, Hebrew, Karelian, Komi Permyak, Komi Zyrian, Livvi, Moksha, Sanskrit, Skolt Sami, Turkish -->
+  <value name="nsubj:ifoc">nsubj:ifoc</value> <!-- Tagalog -->
+  <value name="nsubj:lfoc">nsubj:lfoc</value> <!-- Tagalog -->
+  <value name="nsubj:lvc">nsubj:lvc</value> <!-- Hungarian -->
+  <value name="nsubj:nc">nsubj:nc</value> <!-- Persian, Tamil, Telugu -->
+  <value name="nsubj:obj">fused subject and object pronoun</value> <!-- Old French -->
+  <value name="nsubj:pass">passive nominal subject</value> <!-- Afrikaans, Amharic, Ancient Greek, Arabic, Armenian, Assyrian, Belarusian, Bulgarian, Buryat, Cantonese, Catalan, Chinese, Classical Chinese, Czech, Dutch, English, Faroese, French, Frisian Dutch, Galician, German, Gothic, Greek, Hindi, Indonesian, Italian, Korean, Latin, Latvian, Lithuanian, Maltese, Marathi, Moksha, Norwegian, Old Church Slavonic, Old East Slavic, Persian, Polish, Portuguese, Romanian, Russian, Sanskrit, Skolt Sami, Slovak, Spanish, Swedish, Swiss German, Tagalog, Tamil, Thai, Turkish German, Upper Sorbian, Western Armenian -->
+  <value name="nsubj:periph">nsubj:periph</value> <!-- Cantonese -->
+  <value name="nsubj">Nominal subject</value>
+  <value name="nummod:det">nummod:det</value> <!-- Beja -->
+  <value name="nummod:entity">numeric modifier governed by a noun</value> <!-- Russian -->
+  <value name="nummod:flat">nummod:flat</value> <!-- Polish -->
+  <value name="nummod:gov">numeric modifier governing the case of the noun</value> <!-- Belarusian, Czech, Lithuanian, Old East Slavic, Polish, Russian, Sanskrit, Serbian, Ukrainian, Upper Sorbian -->
+  <value name="nummod">numeric modifier</value>
+  <value name="obj:advmod">fused adverb and object pronoun</value> <!-- Old French -->
+  <value name="obj:advneg">fused negation and object pronoun</value> <!-- no doc for advneg -->
+  <value name="obj:agent">obj:agent</value> <!-- Apurina, French, Tagalog -->
+  <value name="obj:appl">obj:appl</value> <!-- Wolof -->
+  <value name="obj:caus">obj:caus</value> <!-- Wolof -->
+  <value name="obj:lvc">obj:lvc</value> <!-- French, Hungarian, Naija -->
+  <value name="obj:obl">fused oblique and object pronoun</value> <!-- Old French -->
+  <value name="obj:periph">obj:periph</value> <!-- Cantonese, Chinese -->
+  <value name="obj">object</value>
+  <value name="obl:advmod">adverbial modifier confusable with an oblique dependent</value> <!-- Old French -->
+  <value name="obl:agent">agent modifier</value> <!-- Ancient Greek, Armenian, Belarusian, Breton, Cantonese, Chinese, Czech, Dutch, Erzya, French, German, Gothic, Greek, Hindi, Indonesian, Italian, Komi Zyrian, Latin, Lithuanian, Maltese, Moksha, Naija, Old Church Slavonic, Old East Slavic, Polish, Portuguese, Romanian, Russian, Sanskrit, Skolt Sami, Swedish, Tamil, Turkish, Welsh, Western Armenian -->
+  <value name="obl:appl">obl:appl</value> <!-- Wolof -->
+  <value name="obl:arg">oblique argument</value> <!-- Arabic, Beja, Czech, French, German, Greek, Icelandic, Latin, Lithuanian, Maltese, Naija, Persian, Polish, Sanskrit, Slovak, South Levantine Arabic, Tamil -->
+  <value name="obl:cau">obl:cau</value> <!-- Erzya, Komi Zyrian, Moksha, Telugu -->
+  <value name="obl:cmp">obl:cmp</value> <!-- Telugu -->
+  <value name="obl:cmpr">obl:cmpr</value> <!-- Latin, Polish, Tamil -->
+  <value name="obl:comp">obl:comp</value> <!-- Moksha -->
+  <value name="obl:dat">obl:dat</value> <!-- Kurmanji -->
+  <value name="obl:freq">obl:freq</value> <!-- Moksha -->
+  <value name="obl:inst">obl:inst</value> <!-- Erzya, Moksha, Tamil -->
+  <value name="obl:lfrom">obl:lfrom</value> <!-- Erzya, Komi Zyrian, Moksha -->
+  <value name="obl:lmod">locative modifier</value> <!-- Apurina, Classical Chinese, Danish, Erzya, Komi Permyak, Komi Zyrian, Moksha, Skolt Sami, Tamil -->
+  <value name="obl:lmp">obl:lmp</value> <!-- Erzya, Komi Zyrian, Moksha -->
+  <value name="obl:lto">obl:lto</value> <!-- Erzya, Komi Zyrian, Moksha -->
+  <value name="obl:lvc">obl:lvc</value> <!-- Hungarian -->
+  <value name="obl:mcl">obl:mcl</value> <!-- Komi Zyrian -->
+  <value name="obl:mod"> oblique modifier</value> <!-- Beja, French, Naija, Yupik -->
+  <value name="obl:npmod">obl:npmod</value> <!-- Coptic, English -->
+  <value name="obl:orphan">obl:orphan</value> <!-- Polish -->
+  <value name="obl:own">obl:own</value> <!-- Kazakh -->
+  <value name="obl:patient">obl:patient</value> <!-- Cantonese, Chinese -->
+  <value name="obl:pmod">obl:pmod</value> <!-- Romanian, Tamil -->
+  <value name="obl:poss">obl:poss</value> <!-- Thai -->
+  <value name="obl:prep">obl:prep</value> <!-- Irish -->
+  <value name="obl:sentcon">obl:sentcon</value> <!-- Mbya Guarani -->
+  <value name="obl:smod">obl:smod</value> <!-- Scottish Gaelic -->
+  <value name="obl:tmod">obl:tmod</value> <!-- Apurina, Arabic, Cantonese, Chinese, Classical Chinese, Danish, English, Erzya, Frisian Dutch, German, Hindi, Indonesian, Irish, Italian, Komi Permyak, Komi Zyrian, Korean, Manx, Moksha, Portuguese, Scottish Gaelic, Skolt Sami, Spanish, Tamil, Telugu, Thai, Turkish, Uyghur, Warlpiri -->
+  <value name="obl:tmod">temporal modifier</value>
+  <value name="obl">oblique nominal</value>
+  <value name="orphan:missing">textual gap in the source</value> <!-- Latin -->
+  <value name="orphan">remnant in ellipsis</value>
+  <value name="parataxis:appos">parataxis:appos</value> <!-- Italian -->
+  <value name="parataxis:conj">parataxis:conj</value> <!-- Naija -->
+  <value name="parataxis:coord">parataxis:coord</value> <!-- Beja -->
+  <value name="parataxis:deletion">parataxis:deletion</value> <!-- Norwegian -->
+  <value name="parataxis:discourse">parataxis:discourse</value> <!-- Italian, Naija, Slovenian, Turkish German, Ukrainian -->
+  <value name="parataxis:dislocated">parataxis:dislocated</value> <!-- Naija -->
+  <value name="parataxis:hashtag">parataxis:hashtag</value> <!-- Irish, Italian -->
+  <value name="parataxis:insert">parataxis:insert</value> <!-- French, Italian, Polish -->
+  <value name="parataxis:mod">parataxis:mod</value> <!-- Beja -->
+  <value name="parataxis:newsent">parataxis:newsent</value> <!-- Ukrainian -->
+  <value name="parataxis:nsubj">parataxis:nsubj</value> <!-- Italian -->
+  <value name="parataxis:obj">parataxis:obj</value> <!-- Bambara, Italian, Polish -->
+  <value name="parataxis:parenth">parataxis:parenth</value> <!-- French, Naija -->
+  <value name="parataxis:rel">parataxis:rel</value> <!-- Ukrainian -->
+  <value name="parataxis:rep">parataxis:rep</value> <!-- Chukchi, Latin, Mbya Guarani -->
+  <value name="parataxis:restart">parataxis:restart</value> <!-- Slovenian -->
+  <value name="parataxis:rt">parataxis:rt</value> <!-- Irish -->
+  <value name="parataxis:sentence">parataxis:sentence</value> <!-- Irish -->
+  <value name="parataxis:trans">parataxis:trans</value> <!-- Turkish German -->
+  <value name="parataxis:url">parataxis:url</value> <!-- Irish -->
+  <value name="parataxis">parataxis</value>
+  <value name="punct">punctuation</value>
+  <value name="remnant">Remnant ?</value> <!-- no doc, replace with orphan? -->
+  <value name="reparandum">overridden disfluency</value>
+  <value name="root">root</value>
+  <value name="vocative:cl">vocative:cl</value> <!-- Ukrainian -->
+  <value name="vocative:mention">vocative:mention</value> <!-- Irish, Italian -->
+  <value name="vocative">vocative</value>
+  <value name="xcomp:cleft">xcomp:cleft</value> <!-- Polish -->
+  <value name="xcomp:ds">xcomp:ds</value> <!-- Erzya, Finnish, Karelian, Komi Permyak, Livvi -->
+  <value name="xcomp:obj">xcomp:obj</value> <!-- North Sami, Polish -->
+  <value name="xcomp:pred">xcomp:pred</value> <!-- Irish, Latin, Manx, North Sami, Polish, Scottish Gaelic -->
+  <value name="xcomp:sp">xcomp:sp</value> <!-- Ukrainian -->
+  <value name="xcomp:subj">xcomp:subj</value> <!-- Polish -->
+  <value name="xcomp">open clausal complement</value>
+</feature>
+<feature name="coord" domain="NT" ></feature>
+<feature name="dom" domain="NT" ></feature>
+<feature name="type" domain="NT" >
+  <value name="nV">élément non-verbal</value>
+  <value name="VFin">finite verb</value>
+  <value name="VInf">infinitive</value>
+  <value name="VPar">participle</value>
+  <value name="--">nil</value>
+</feature>
+<feature name="vform" domain="NT"></feature>
+<feature name="vlemma" domain="NT"></feature>
+<feature name="note" domain="NT"></feature>
+<feature name="snr" domain="NT"></feature>
+';
+
+    printf MASTER "$nt_features_header";
+
+    printf MASTER '
+<edgelabel>
+  <value name="D">dependency</value>
+  <value name="L">lexical</value>
+  <value name="R">relator</value>
+  <value name="*">not bound</value>
+</edgelabel>
+<secedgelabel>
+  <value name="cluster">between elements of GpCoo</value>
+  <value name="coord">between members of Coo</value>
+  <value name="dupl">between duplicated nodes</value>
+</secedgelabel>
+</annotation>
+</head>
+<body>
+';
+}
+
+#  <value name="M">main</value>
+#  <value name="P">part</value>
+
+sub write_master_footer {
+    print MASTER '</body>
+</corpus>
+';
+}
+
+$TEMP = '
+<feature name="nodom" domain="NT" ></feature>
+<feature name="headpos" domain="NT" ></feature>
+<feature name="annotationFile" domain="NT" ></feature>
+<feature name="annotationUri" domain="NT" ></feature>
+';
+
+sub define_cat_hashes {
+
+    #  $abbrev2cat{"Apst"} = "Apostrophe";
+    #  $abbrev2cat{"AtObj"} = "AttributObjet";
+    #  $abbrev2cat{"AtRfc"} = "AttributReflechi";
+    #  $abbrev2cat{"AtSj"} = "AttributSujet";
+    #  $abbrev2cat{"AuxA"} = "Auxilie-Actif";
+    #  $abbrev2cat{"AuxP"} = "Auxilie-Passif";
+    #  $abbrev2cat{"Circ"} = "Circonstant";
+    #  $abbrev2cat{"Cmpl"} = "Complement";
+    #  $abbrev2cat{"GpCoo"} = "Coordonne";
+    #  $abbrev2cat{"Coo"} = "Coordination";
+    #  $abbrev2cat{"Det"} = "Determinant";
+    #  $abbrev2cat{"NgPrt"} = "Forclusif";
+    #  $abbrev2cat{"Insrt"} = "Incidente";
+    #  $abbrev2cat{"Intj"} = "Interjection";
+    #  $abbrev2cat{"ModA"} = "ModifieurAttache";
+    #  $abbrev2cat{"ModD"} = "ModifieurDetache";
+    #  $abbrev2cat{"Ng"} = "Negation";
+    #  $abbrev2cat{"VInf"} = "NoeudVerbal-Infinitif";
+    #  $abbrev2cat{"VPrt"} = "NoeudVerbal-Participe"; #?
+    #  $abbrev2cat{"VFin"} = "NoeudVerbal-Personnel";
+    #  $abbrev2cat{"nSnt"} = "NonPhrase";
+    #  $abbrev2cat{"Obj"} = "Objet";
+    #  $abbrev2cat{"Snt"} = "Phrase";
+    #  $abbrev2cat{"Pon"} = "Ponctuation";
+    #  $abbrev2cat{"Rfc"} = "Reflechi";
+    #  $abbrev2cat{"Rfx"} = "ReflexifRenforce";
+    #  $abbrev2cat{"RelC"} = "Relateur-Coordonnant";
+    #  $abbrev2cat{"RelNC"} = "Relateur-NonCoordonnant";
+    #  $abbrev2cat{"nMax"} = "StructureNonMaximale";
+    #  $abbrev2cat{"SjImp"} = "SujetImpersonnel";
+    #  $abbrev2cat{"SjPer"} = "SujetPersonnel";
+    #  $abbrev2cat{"Lac"} = "Lacune";
+    #  $abbrev2cat{"Aux"} = "Auxilie";
+    #  $abbrev2cat{"Regim"} = "Regime";
+
+    $abbrev2cat{"acl"}        = "Clausal modifier of noun";
+    $abbrev2cat{"advcl"}      = "Adverbial clause modifier";
+    $abbrev2cat{"advmod"}     = "Adverbial modifier";
+    $abbrev2cat{"amod"}       = "Adjectival modifier";
+    $abbrev2cat{"appos"}      = "Appositional modifier";
+    $abbrev2cat{"aux"}        = "Auxiliary";
+    $abbrev2cat{"cc-nc"}      = "Coordinated conjunct : non coordonant";
+    $abbrev2cat{"cc"}         = "Coordinating conjunction";
+    $abbrev2cat{"ccomp"}      = "Clausal complement";
+    $abbrev2cat{"conj"}       = "Conjunct";
+    $abbrev2cat{"cop"}        = "Copula";
+    $abbrev2cat{"csubj"}      = "Clausal subject";
+    $abbrev2cat{"det"}        = "Determiner";
+    $abbrev2cat{"dislocated"} = "Dislocated elements";
+    $abbrev2cat{"expl"}       = "Expletive";
+    $abbrev2cat{"iobj"}       = "Indirect object";
+    $abbrev2cat{"mark"}       = "Marker";
+    $abbrev2cat{"nmod"}       = "Nominal modifier";
+    $abbrev2cat{"nsubj"}      = "Nominal subject";
+    $abbrev2cat{"nummod"}     = "Numeric modifier";
+    $abbrev2cat{"obj"}        = "Object";
+    $abbrev2cat{"obl"}        = " Oblique nominal";
+    $abbrev2cat{"orphan"}     = "Remnant in ellipsis";
+    $abbrev2cat{"remnant"}    = "Remnant ?";
+    $abbrev2cat{"vocative"}   = "Vocative";
+    $abbrev2cat{"xcomp"}      = "Open clausal complement";
+}
+
+sub print_sentence {
+    for ( my $q = 0 ; $q <= $#words ; $q++ ) {
+        print "$words[$q]\n";
+    }
+}
+
+sub write_nonterminals {
+    my $print_nt_features;
+    if ( $_[1] =~ /dupl/ ) {
+        $dupl = '_dupl';
+    }
+    else {
+        $dupl = '';
+    }
+    if ( $nt_features ne '' ) {
+        $print_nt_features = $nt_empty_features;
+        if ( $_[0] =~ /$thisrootname/ ) {
+            $print_nt_features = $nt_features;
+        }
+    }
+    printf XML "      <nt id=\"n%d_%d%s\" cat=\"%s\" coord=\"--\" dom=\"%s\" type=\"%s\" vform=\"%s\" vlemma=\"%s\"%s note=\"%s\" snr=\"%d\">\n", $., $w, $dupl, $_[0], $dom, $type, $vform, $vlemma,
+      $print_nt_features, notes("$._$w"), $.;
+    printf XML "        <edge idref=\"s%d_%d%s\" label=\"L\"/>\n", $., $w, $dupl;
+
+    # link duplicate with primary original node
+    if ( $_[1] =~ /dupl/ ) {
+        printf XML "        <secedge idref=\"s%d_%d\" label=\"dupl\"/>\n", $., $w;
+    }
+
+    # if node is not a duplicate: attach all the daughters
+    if ( $_[1] !~ /dupl/ ) {
+        for ( my $d = 0 ; $d <= $#daughters ; $d++ ) {
+            $daughter = $daughters[$d];
+            if ( "$._$w" ne "$._$daughter" ) {    # avoid cycles
+                printf XML "        <edge idref=\"n%d_%d%s\" label=\"%s\"/>\n", $., $daughter, $dupl, edge_label("$._$daughter");
+            }
+
+            # check if a duplicate of this node must be attached
+            if ( $duplicates{"$._$daughter"} == 1 ) {
+                printf XML "        <edge idref=\"n%d_%d_dupl\" label=\"%s\"/>\n", $., $daughter, edge_label("$._$daughter_dupl");
+            }
+        }
+    }
+    print XML "      </nt>\n";
+}
+
+# checks if node is stored as in hash of relators
+sub edge_label {
+    if ( $relators{ $_[0] } == 1 ) {
+        return 'R';
+    }
+    return 'D';
+}
+
+# retrives notes for this node
+sub notes {
+    if ( $notes{ $_[0] } ne '' ) {
+        return "$notes{$_[0]}";
+    }
+    return '--';
+}
+
+# conversions, bug fixes
+sub clean_data {
+
+    # conversions of values, some necessary some for convenience
+    $word =~ s/"/'/g;
+    $word =~ s/\&/(and)/g;
+    $word =~ s/<</«/g;
+    $word =~ s/>>/»/g;
+    $word =~ s/[<>]//g;
+    $pos =~ s/:/_/g;
+    $mor =~ s/\|/_/g;
+    $ppos =~ s/:/_/g;
+    $pmor =~ s/\|/_/g;
+    $lemma =~ s/\|/_/g;
+    $lemma =~ s/[<>]//g;
+    $lemma =~ s/"/'/g;
+    $lemma =~ s/\&/(and)/g;
+    $plemma =~ s/\|/_/g;
+    $plemma =~ s/[<>]//g;
+    $plemma =~ s/"/'/g;
+    $plemma =~ s/\&/(and)/g;
+
+    # clean categories
+    $cat =~ s/ROOT/$thisrootname/;    # top node, for compatibility with SRCMF
+
+    #    $cat =~ s/Ponctuation/Pon/;
+    # correct some bugs in parse
+    #    $cat =~ s/Sujet/SjPer/;
+    #    $cat =~ s/Modifieur/ModA/;
+    #    $cat =~ s/Parenthese/Insrt/;
+    $cat =~ s/\-/_/g;
+    $cat =~ s/RelNC_(.*)/$1_RelNC/;    # RelNC always 2nd node, for consistency in duplicates
+    return;
+}
+
Index: TXM/trunk/org.txm.conllu.core/groovy/org/txm/scripts/importer/conllu/conll2tigerud2.groovy
===================================================================
--- TXM/trunk/org.txm.conllu.core/groovy/org/txm/scripts/importer/conllu/conll2tigerud2.groovy	(revision 0)
+++ TXM/trunk/org.txm.conllu.core/groovy/org/txm/scripts/importer/conllu/conll2tigerud2.groovy	(revision 3567)
@@ -0,0 +1,1136 @@
+
+def CMD="conll2tiger.pl";
+def VERSION = "1.5";
+def MODIFIED = "8/12/2015";   // angepasst für Perseus CoNLL erzeugt mit conll.pl -l.  CHECK: funktioniert SRCMF noch?
+
+// columns (default are the predicted values in CoNLL 2009 format)
+def coll = 2;  // lemma
+def colm = 3;  // morph (pos)
+def colf = 5;  // features
+def colh = 6;  // head
+def cold = 7; // deprel
+def outdir = "conllexport"; // deprel
+def split = 1000; // split output after nr sentences
+
+// tree structure
+def dominates  = [:];
+def deprel  = [:];  // deprel{nr} = deprel
+def daughters = []; // daughter nodes, stored in %dominates
+def duplicates = [:];
+def relators = [:];
+def notes = [:]
+def aux = [:]; // store nodes of duplicates, relators
+def type = "--"; // node attribute
+def vform = "--"
+def vlemma = "--"; // node attributes for verbs store form and lemma
+def label = "D"; // default edge label
+def nt_features_header = ''; // option -x
+def nt_features = ''; // option -x
+def nt_empty_features = ''; // option -x
+def scodes = []; // option -x
+def add_to_sentcode = '';
+def rootname = 'root';  // default
+def featcol = 13;
+
+//#####################################################################
+//  conll2tiger.pl: converts CoNLL-U from the Universal Dependecies
+//  treebanks to TigerXML
+//    Achim Stein <achim.stein@ling.uni-stuttgart.de>
+// License : GNU GPL v. 3 (see the LICENSE file)
+//#####################################################################
+// TO DO:
+// - coordination
+// - Umgang mit zu langen, gesplitteten Sätzen (conll.pl -r 100)
+//   - dafür wurde als Wort-ID statt $w (for-Zähler) $wnr verwendet
+//   - es gibt aber noch unbound nodes wenn Regens entfernt (im anderen Teil) ist
+//#####################################################################
+// Modifications by Alexei Lavrentiev <alexei.lavrentev@ens-lyon.fr>
+// for Profiterole project (2019-2021)
+
+// 2019-09-25
+// - updated default column numbers for CONNL-U SRCMF format
+// - added processing for comment lines
+// - added @textid to terminal nodes
+// - deleted ppos, pmor et plemma (predicted tags and lemmas)
+// - replaced specific SRCMF with standard UD tags
+
+// Update 2020-05-13
+// - added @editionId for synchronization with BFM word ID
+
+// Update 2021-03-22
+// - using $infilename for @textid
+// - added support for .conllu extension
+
+// Update 2021-03-29
+// - added editionId to declarations in main.xml
+
+// Update 2021-07-16
+// - added "punct" to cat values
+
+// Update 2021-07-20
+// - added cat value list compiled from
+//   https://universaldependencies.org/ext-dep-index.html and the previous
+//   version. All relation types and subtypes from the UD 2.8 corpora
+//   should be there.
+// - contractions indexed
+//#####################################################################
+
+def HELP = """
+==================================================================
+$CMD $VERSION: Help
+==================================================================
+FUNKTION: converts CoNLL parser output to TigerXML (for mate tools) 
+	   creates master file, splits input files, corrects unbound nodes
+SYNTAX:   $CMD [Options] <CoNLL file>
+OPTIONEN: 
+	-c    ignore coordination (delete coordx- prefix in deprel) 
+	-C str   corpus specials: nca 
+	-h    show help 
+	-o    create all files in this output directory (default: $outdir)
+set COLUMNS for required info (0 = column 1, 1 = column 2, etc.) 
+	-D nr    colum for deprel default=$cold 
+	-H nr    colum for head default=$colh 
+	-M nr    colum for morphology (POS) default=$colm 
+	-F nr    colum for morph. features default=$colf 
+	-R str   Root category (default: $rootname) 
+	-s nr    split output files after each nr sentence (default = $split) 
+	-x str,...  include these attributes if present in the -X column of the first word 
+	   (the first code is also copied into the sentence id) 
+	-X nr    the column where attributes are stored (default: $featcol)
+EXAMPLE: 
+	 - For mate parser output: no further options required 
+	$CMD parsed.conll 
+	 - For Le Monde 2005: include attributes 
+	gunzip -c parsed.conll.gz | conll2tiger.pl -x date,artnr,rubr 
+	 - For NCA: 
+	conll2tiger.pl -C nca -x id,deaf,titreDees,editionDees,manuscritDees,regionDees,coefficientRegionDees,dateMoyenneDees,codeRegional,coefficientRegional,vers,ponctuation,mots,passage,commentairePhilologique,qualite,sourceQualite,commentaireForme,auteur,dateComposition,dateManuscrit,lieuComposition,lieuManuscrit,sourceDateComposition,sourceDateManuscrit,sourceLieuComposition,sourceLieuManuscrit,genre,traditionTextuelle,analyses,lignes,editionNCA tagged-oldfrench-lrec2014-dep.conll
+""";
+
+//##########################################################################
+//     DO NOT MODIFY FOLLOWING CODE !
+//##########################################################################
+
+
+//##########################################################################
+// parse the command line
+//##########################################################################
+
+getopts('c:C:hD:H:M:o:R:s:x:X:');
+
+if (defined(opt_h)) {
+	println "** " + "$HELP";
+	return 0;
+}
+
+if (defined(opt_o)) {
+	outdir = opt_o
+}
+if (defined(opt_C)) {
+	corpus = opt_C;
+}
+if (defined(opt_D)) {
+	cold = opt_D
+}
+if (defined(opt_H)) {
+	colh = opt_H
+}
+if (defined(opt_M)) {
+	colm = opt_M
+}
+
+if (defined(opt_R)) {
+	rootname = opt_R;
+}
+
+if (defined(opt_s)) {
+	split = opt_s
+}
+
+if (defined(opt_X)) {
+	featcol = opt_X;
+}
+
+if (defined(opt_x)) {
+	scodes = opt_x.split(",");
+	for (def i = 0; i <= scodes.size(); i++) {
+		nt_features_header = nt_features_header + sprintf("<feature name=\"%s\" domain=\"NT\"></feature>\n", scodes[i]);
+	}
+	nt_features_header =~ s/\bid\b/ncaid/;  // avoid reserved Tiger attribute "id"
+}
+
+
+def colnames = ["url", "ID", "FORM", "LEMMA", "PLEMMA", "POS", "PPOS", "FEAT", "PFEAT", "HEAD", "PHEAD", "DEPREL", "PDEPREL"];
+// def pos = [:]%lemma = %form = hDeprel = %head = %governs = %cat2abbrev = %abbrev2cat = %coordnr_cat = %coordnr_head = %w_coordnr = %w_head = %w_deprel = %first_coordnr = %coordnr_first = %verb_head = [:];
+def coordelements = [];
+
+def id = def form = def lemma = def plemma = def pos = def ppos = def feat = def pfeat = def head = def phead = def deprel = def pdeprel = def edition_id = "";
+
+def timestamp = `date`;
+chomp(timestamp);
+
+def infile = ARGV[0];
+infile =~ s/\.conllu?//i;
+if (infile == '') { 
+	 infile = 'subcorpus';
+}
+def counter = 1;
+suffix = sprintf("%05d", counter);
+infilename = basename(infile);
+
+foo = `if [ ! -d outdir ];then mkdir outdir;fi`;
+open(XML, ">$outdir/$infilename-$suffix.xml")  or die "\nopen file error of $outdir/$infilename-$suffix.xml\n";
+open(LOG, ">$outdir/conversion.log")  or die "\nopen file error of conversion.log\n";
+open(MASTER, ">$outdir/main.xml")  or die "\nopen file error of main.xml\n";
+write_xml_header();
+write_master_header();
+
+// flush output for log and master file
+select(LOG); $| = 1; 
+select(MASTER); $| = 1;
+
+commandline = $0 + " " + (join " ", @ARGV);
+LOG << "$commandline\n\n";
+
+MASTER << "<subcorpus name='$infilename-$suffix' external='file:$infilename-$suffix.xml'/>\n";
+
+$/ = ""; // treat empty line as RS
+while (<>) { 
+	 if ($. % split == 0) { 
+	XML << "</subcorpus>\n"; 
+	close(XML); 
+	suffix = sprintf("%05d", ++counter); 
+	open(XML, ">$outdir/$infilename-$suffix.xml")  or die "\nopen file error\n"; 
+	write_xml_header(); 
+	MASTER << "<subcorpus name='$infilename-$suffix' external='file:$infilename-$suffix.xml'/>\n"; 
+	 }
+ 
+	 // ---------------------------------------- 
+	 // set root (or fake root if ROOT is missing) 
+	 // ---------------------------------------- 
+	 rootnode = fakeroot = 0; // m = Treat string as multiple lines, so that ^ matches beginning of line 
+	 thisrootname = rootname; 
+	 (rootnode) = (/^(\d+?)\s.*?\b$rootname\b/m);  // real root marked by parser 
+	 if (rootnode == 0) {
+// (rootnode) = (/^(\d+?)\t.*?\t-1\t0\t/m);  // no marked ROOT, but top node (head = 0)   TOO SPECIFIC
+// (rootnode) = (/^(\d+?)\t.*?\t.*?\t.*?\t.*?\t.*?\t.*?\t.*?\t0\t/m);  // no marked ROOT, but top node (head = 0) in col9 (original by Achim Stein) 
+	(rootnode) = (/^(\d+?)\t.*?\t.*?\t.*?\t.*?\t.*?\t0\t/m);  // no marked ROOT, but top node (head = 0) in col7 (updated by AL) 
+	LOG << " Warning sentence $.: not marked root ($rootname), using top node $rootnode\n"; 
+	fakeroot = 1; 
+	thisrootname = 'nSnt'; 
+	 } 
+	 if (rootnode == 0) { 
+	rootnode = 1;   // set fake root if nothing goes 
+	LOG << " Error sentence $.: setting fake root to first word:\n$_\n"; 
+	fakeroot = 2; 
+	thisrootname = 'Err'; 
+	 }
+ 
+	 def cols = []; 
+	 @words = split (/\n/); 
+	 @terminals = [];
+ 
+	 %dominates = [:]; // empty at beginning of sentence 
+	 hDeprel = [:]; // empty at beginning of sentence 
+	 %aux = [:]; // empty at beginning of sentence 
+	 daughters = [];
+ 
+	 def commentlines = 0; #added by AL
+//  def contractions = 0; #added by AL
+//  def text_id = "unknown_text";
+def text_id = infilename; 
+	 def sent_id = "0";
+ 
+	 // ---------------------------------------- 
+	 // loop through words #1: write tokens (terminal nodes) to XML file 
+	 // store tree relevant information for loop #2 
+	 // ---------------------------------------- 
+	 for (def w = 0; w <= words.size(); w++) {
+// Added by AL for comment lines 
+	if (words[w] =~ /^#/) {
+	if (words[w] =~ /^# newdoc/) {
+		text_id = words[w];
+		text_id =~ s/# newdoc id = //;
+	}
+	elsif (words[w] =~ /^# sent_id/) {
+		sent_id = words[w];
+		sent_id =~ s/# sent_id = //;
+	}
+//	LOG << "Comment line loop 1: words[w]\n";
+	commentlines++;
+	next; 
+	}
+// Added by AL for contractions 
+	elsif (words[w] =~ /^\d+-\d+/) {
+//	LOG << "Contraction line loop 1: words[w]\n";
+	commentlines++;
+//	contractions++;
+	next; 
+	} 
+	else { 
+	if (defined (opt_c)) { 
+	  words[w] =~ s/coord(\d+)-//g; 
+	} 
+	@cols = split (/\t/, words[w]); 
+	wnr = cols[0]; 
+	word = cols[1]; 
+	lemma = cols[2]; 
+	plemma = cols[2]; // predicted 
+	pos = cols[3]; 
+	ppos = cols[4]; // predicted 
+	mor = cols[5]; 
+	pmor = cols[5]; // predicted 
+	cat = cols[cold]; 
+	edition_id = cols[9]; 
+	edition_id =~ s/^.*XmlId=([^|]+).*$/\1/g;
+ 
+	if (cat =~ /[<>]/) { 
+	  LOG << "Warning in line $.: illegal node name: \"$cat\" -> \"Err2\"\n"; 
+	  cat = 'Err2'; 
+	}
+ 
+	// NCA: enclose lemmas in underscores (easier for regex construction) 
+	if (corpus =~ /nca/i) { 
+	  lemma = "_" + "$lemma" + "_" 
+	}
+ 
+	clean_data();
+ 
+	// get attribute-value pairs from col #13 of first word (option -x) 
+	if (opt_x == "all") {
+	  cols[featcol] = "all=" + cols[featcol]; 
+	} 
+	if (w == 0 && cols[featcol] =~ /=/) {
+//   println "** " + "========== getting att-value for word w: cols[featcol] scodes=@scodes\n"; 
+		nt_features = nt_empty_features = '';
+//   while(cols[featcol] =~ m/ (.*?)="([^"]*)"/gs) {   // quoted values 
+	  while(cols[featcol] =~ m/ ?([^=]*?)="?([^, ]+)\b"?\b/gs) {  // maybe unquoted values (e.g. Le Monde 2005)
+	att = $1;
+	val = $2;
+	// pick the attributes that match those of the command line option -x
+	for (def t = 0; t <= scodes.size(); t++) {
+	  if (att == scodes[t]) {
+	 val =~ s/\&/\&amp;/g;  //  replace "&" in values (appears in URLs)
+	 if (t == 0) { add_to_sentcode = "_$att$val"; }
+	 nt_features = nt_features + " $att=\"$val\"";
+//	 println "** " + "$./$w/$featcol: $cols[$featcol] --- nt_features: $nt_features\n";
+	  }
+	  if (att == scodes[t]) { nt_empty_features = nt_empty_features + " $att=\"--\"";}
+	} 
+	  } 
+	  // replace the reserved feature 'id' (Tiger) 
+	  add_to_sentcode =~ s/\bid=/ncaid=/; 
+	  nt_features =~ s/\bid=/ncaid=/; 
+	  nt_empty_features =~ s/\bid=/ncaid=/; 
+	} // if col 13 contains attributes 
+	else { 
+	  if (defined(opt_x) && (w == 0)) {
+	println "** " + "Warning: sentence=$.  option -x is defined, but no attribute=value declarations were found!\n"; 
+	  } 
+	}
+
+ 
+	// store output for terminal node in array, output later. For double categories make a duplicate node. 
+	tempid = sprintf("%d_%d", $., wnr);
+// push(@terminals, sprintf("   <t id=\"s%d_%d\" word=\"%s\" pos=\"%s\" mor=\"%s\" lemma=\"%s\" ppos=\"%s\" pmor=\"%s\" plemma=\"%s\" textid=\"%s\" editionId=\"%s\"/>\n", $., wnr, word, pos, mor, lemma, ppos, pmor, plemma, text_id, edition_id)); 
+	push(@terminals, sprintf("   <t id=\"s%d_%d\" word=\"%s\" pos=\"%s\" mor=\"%s\" lemma=\"%s\" textid=\"%s\" editionId=\"%s\"/>\n", $., wnr, word, pos, mor, lemma, text_id, edition_id)); 
+	if (cat =~ /_/) {
+//   push(@terminals, sprintf("   <t id=\"s%d_%d_dupl\" word=\"%s\" pos=\"%s\" mor=\"%s\" lemma=\"%s\" ppos=\"%s\" pmor=\"%s\" plemma=\"%s\" textid=\"%s\" editionId=\"%s\"/>\n", $., wnr, "*", "_", "_", "_", "_", "_", "_", text_id, edition_id)); 
+	  push(@terminals, sprintf("   <t id=\"s%d_%d_dupl\" word=\"%s\" pos=\"%s\" mor=\"%s\" lemma=\"%s\" textid=\"%s\" editionId=\"%s\"/>\n", $., wnr, "*", "_", "_", "_", text_id, edition_id)); 
+	  duplicates{tempid} = 1; // store, check later to attach the duplicates to the mother 
+	}
+ 
+	// associate Aux with main verb, to create an attribute in the verb node in loop #2 (TODO: more than one Aux) 
+	if (cat =~ /Aux/) { 
+	  aux{cols[colh]} = "$word" + "_" + "$plemma"; // aux{head} = word_lemma (of Aux) 
+	}
+ 
+	// ---------------------------------------- 
+	// store information needed for tree 
+	// ---------------------------------------- 
+	// if fake rootnode == 1: nSnt as root node 
+	if ((fakeroot == 1) && (w-commentlines+1 == rootnode)) { 
+	  cat = 'nSnt'; 
+	  notes{tempid} = 'Warning no marked ROOT node in CoNLL';  // TODO: geht nicht 
+	} 
+	// if fake rootnode == 2: flatten structure: attach all words to the first word 
+	if ((fakeroot == 2) && (w-commentlines+1 != rootnode)) { 
+	  cols[colh] = 1; 
+	  notes{tempid} = 'Error neither ROOT node nor top node in CoNLL';  
+	} 
+	// correct unbound words in parser output (phead = 0, but not marked as ROOT) 
+	if ((cols[colh] == "0") && (w-commentlines+1 != rootnode)) { // AL: added: -commentlines 
+	  printf LOG " Warning sentence $. ($tempid): unbound node %d (attached to root %d)\n", (w-commentlines+1), rootnode; 
+	  cols[colh] = rootnode; 
+	  cat = 'Err';  // let Err instead of deprel appear in dom attribute 
+	  notes{tempid} = 'Warning unbound node in CoNLL';  
+	} 
+	// store for R edge labels 
+	if (cols[cold] =~ /RelN?C/) { 
+	  relators{tempid} = 1;  
+	} 
+	// store deprel for dom attribute 
+	deprel[tempid] = cat; // cols[cold]; 
+	// if real root, add this node to daughter array, store array in hash dominates{head}{@daughters} 
+	if ((fakeroot < 2) && (w-commentlines+1 != rootnode)) { 
+	  daughters = @{dominates[ols[colh]}};  // get the array from the hash of the dominating node 
+	  push(daughters, wnr); 
+	  dominates[cols[colh]] = [daughters]; 
+	} 
+	 } // for each word loop #1
+} // AL condition end
+ 
+	 // print graph code (needs root attribute) and terminal nodes 
+	 if (rootnode == 0) { 
+	noroot++; 
+	LOG << "Error sentence $. ($tempid): root node not found:\n$_\n"; next; 
+	 } else { 
+	printf XML "<s id=\"s%s%s\" textid=\"$text_id\" sentid=\"$sent_id\">\n", $., add_to_sentcode; 
+	XML << "  <graph root=\"n$._$rootnode\">\n"; 
+	XML << " <terminals>\n"; 
+	for (def t = 0; t <= terminals.size(); t++) { 
+	  XML << terminals[t]; 
+	} 
+	XML << " </terminals>\n"; 
+	 } 
+	  
+	 // ---------------------------------------- 
+	 // loop through words #2 to build Tiger tree (non terminal nodes) 
+	 // ---------------------------------------- 
+	 XML << " <nonterminals>\n"; 
+	 for (def i = 0; i <= words.size(); i++) {
+//Added AL for comment lines 
+	if (words[i] =~ /^#/) {
+//    LOG << "Comment line loop 2 : $words[$i]\n"; 
+	   next; 
+	}
+//Added AL for contractions 
+	if (words[i] =~ /^\d+-\d+/) {
+//    LOG << "Contraction loop 2 : $words[$i]\n"; 
+	   next; 
+	} 
+	   
+	else {
+ 
+	@cols = split (/\t/, words[i]); 
+	w = cols[0]; 
+	// TODO: redundante Variablenzuweisung (= loop #1)?? 
+	word = cols[1]; 
+	lemma = cols[2]; 
+	plemma = cols[3]; // predicted 
+	pos = cols[4]; 
+	ppos = cols[5]; // predicted 
+	mor = cols[6]; 
+	pmor = cols[7]; // predicted 
+	cat = cols[cold];
+ 
+	if (cat =~ /[<>]/) { 
+	  print Log "Warning in line $.: illegal node name: \"$cat\" -> \"Err2\"\n"; 
+	  cat = 'Err2'; 
+	}
+ 
+	//  OF parser has not learned punctuation: set cat for punctuation to PON 
+	if ((corpus =~ /nca/i) && (pos == 'PON')) { 
+	  cols[cold] = cat = 'Pon'; 
+	}
+ 
+	clean_data();
+ 
+	// retrieve daughters, make dom attribute (string of dominated nodes) 
+	daughters = @{dominates["$w"]}; 
+	dom = ''; 
+	for (def d = 0; d <= daughters.size(); d++) { 
+	  dom = dom + "_" + deprel["$._$daughters{$d}"]; 
+	} 
+	if (dom =~ /_/) { 
+	  dom =~ s/^_//; 
+	} else { 
+	  dom = '--'; 
+	}
+ 
+	// if verbal, set node attributes for verb form and lemma 
+	type = "nV"; 
+	vform = vlemma = "--"; 
+	if (pos =~ /VER/) { // AL: ppos -> pos 
+	  if (mor =~ /infi/) { type = "VInf"; } // AL: pmor -> mor 
+	  elsif (pmor =~ /pper|ppre/) { type = "VPar"; } 
+	  else { type = "VFin"; } 
+	  // if Aux is present, create attribute for main verb  
+	  if (aux{w} =~ /(.*?)_(.*)/) {
+	vform = "$1";
+	vlemma = "$2"; 
+	  } 
+	  // else create attr for simple verb 
+	  else {
+	vform = word;
+	vlemma = lemma; // AL: plemma -> lemma (always void in SRCMF) 
+	  } 
+	  // NCA: enclose lemmas in underscores (easier for regex construction) 
+	  if (corpus =~ /nca/i) {
+	vlemma = "_" + "$vlemma" + "_" 
+	  } 
+	}
+ 
+	// call output function (twice for duplicate categories) 
+	if (cat =~ /(.*?)_(.*)/) { 
+	  write_nonterminals("$2", "");   // RelNC is always node (see clean categories), function is duplicate, e.g. SjPer_RelNC 
+	  write_nonterminals("$1", "_dupl");  // other category is duplicate 
+	} else { 
+	  write_nonterminals(cat); 
+	} 
+	 } // for words
+} #AL end condition
+ 
+	 XML << " </nonterminals>\n"; 
+	 XML << "  </graph>\n"; 
+	 XML << "</s>\n"; 
+	 if ($. % 100 == 0) { println "** " + "\b\b\b\b\b\b\b\b"; printf STDERR "%08d", $.;}
+} // main
+XML << "</subcorpus>\n";
+println "** " + "\n$CMD: $. sentences converted. Results in $outdir. Log in $outdir/conversion.log.\n";
+println "** " + "   Hint 1: on OS X convert master file to MacRoman, e.g  iconv -f latin1 -t macroman\n";
+println "** " + "   Hint 2: use tiger.pl -c <Tiger XML file> to detect unbound nodes.\n";
+println "** " + "   Hint 3: build reliable feature declarations using tiger.sh\n";
+println "** " + "     tiger.sh -a \"lemma word pos ppos\"  (for terminals)\n";
+println "** " + "     tiger.sh -A \"lemma word pos ppos\"  (for non-terminals)\n";
+if (noroot > 0) {println "** " + "$noroot sentences ignored: root not found (see log file)\n";}
+write_master_footer();
+close(MASTER);
+close(XML);
+close(LOG);
+
+exit;
+
+
+
+// ----------------------------------------
+// sub
+// ----------------------------------------
+
+def write_xml_header { 
+	 XML << """<?xml version=\"1.0\" encoding=\"UTF-8\"?> 
+	 <subcorpus name=\"$infilename-$suffix\">
+""";
+}
+
+def write_master_header { 
+	 printf MASTER """<?xml version="1.0" encoding="UTF-8"?>
+""";
+ 
+	 printf MASTER """<corpus id=\"$corpus\">
+<head> 
+	 <meta><name>$corpus</name>  
+	<author>ILR Stuttgart</author>  
+	<date></date>  
+	<description>Parsed with mate tools using a SRCMF-based grammar model (http://srcmf.org). </description>  
+	<format>SRCMF</format> 
+	<history>TigerXML converted by conll2tiger.pl</history> 
+	 </meta>
+""";
+
+//  printf MASTER '<annotation>
+//<feature name="word" domain="T" ></feature>
+//<feature name="pos" domain="T" ></feature>
+//<feature name="mor" domain="T" ></feature>
+//<feature name="lemma" domain="T" ></feature>
+//<feature name="ppos" domain="T" ></feature>
+//<feature name="pmor" domain="T" ></feature>
+//<feature name="plemma" domain="T" ></feature>
+//<feature name="cat" domain="NT" >
+//  <value name="Apst">apostrophe</value>
+//  <value name="AtObj">attribut d objet</value>
+//  <value name="AtRfc">attribut réfléchi</value>
+//  <value name="AtSj">attribut de sujet</value>
+//  <value name="AttributReflechi">attribut réfléchi</value>
+//  <value name="Aux">auxilié</value>
+//  <value name="AuxA">auxilié actif</value>
+//  <value name="AuxP">auxilié passif</value>
+//  <value name="Circ">circonstant</value>
+//  <value name="Circ_RelNC">circonstant pronom relatif</value>
+//  <value name="Cmpl">complément</value>
+//  <value name="Cmpl_RelNC">complément pronom relatif</value>
+//  <value name="Coo">coordination</value>
+//  <value name="Det">déterminant</value>
+//  <value name="Err">unbound node in CoNLL input</value>
+//  <value name="Err2">illegal node name was replaced</value>
+//  <value name="GpCoo">coordonné</value>
+//  <value name="Ignorer">Ignorer</value>
+//  <value name="Insrt">incidente</value>
+//  <value name="Intj">interjection</value>
+//  <value name="Lac">lacune</value>
+//  <value name="ModA">modifieur attaché</value>
+//  <value name="ModD">modifieur détaché</value>
+//  <value name="Ng">négation</value>
+//  <value name="NgPrt">forclusif</value>
+//  <value name="Obj">objet</value>
+//  <value name="Obj_RelNC">direct object pronom relatif</value>
+//  <value name="Pon">ponctuation</value>
+//  <value name="PON">ponctuation</value>
+//  <value name="Regim">régime</value>
+//  <value name="RelC">relateur coordonnant</value>
+//  <value name="RelNC">relateur non coordonnant</value>
+//  <value name="Rfc">réfléchi</value>
+//  <value name="Rfx">réfléxif renforcé</value>
+//  <value name="SjImp">sujet impersonnel</value>
+//  <value name="SjPer">sujet personnel</value>
+//  <value name="SjPer_RelNC">sujet personnel pronom relatif</value>
+//  <value name="Snt">phrase</value>
+//  <value name="ROOT">phrase</value>
+//  <value name="StructureMaximale">structure maximale</value>
+//  <value name="VFin">verbe fini</value>
+//  <value name="VInf">verbe infinitif</value>
+//  <value name="nMax">structure non-maximale</value>
+//  <value name="nSnt">non-phrase</value>
+//</feature>
+//<feature name="coord" domain="NT" ></feature>
+//<feature name="dom" domain="NT" ></feature>
+//<feature name="type" domain="NT" >
+//  <value name="nV">élément non-verbal</value>
+//  <value name="VFin">verbe fini</value>
+//  <value name="VInf">verbe infinitif</value>
+//  <value name="VPar">verbe participial</value>
+//  <value name="--">nil</value>
+//</feature>
+//<feature name="vform" domain="NT"></feature>
+//<feature name="vlemma" domain="NT"></feature>
+//<feature name="note" domain="NT"></feature>
+//<feature name="snr" domain="NT"></feature>
+//';
+ 
+	 printf MASTER """<annotation>
+<feature name="word" domain="T" ></feature>
+<feature name="pos" domain="T" ></feature>
+<feature name="mor" domain="T" ></feature>
+<feature name="lemma" domain="T" ></feature>
+<feature name="textid" domain="T" ></feature>
+<feature name="editionId" domain="T" ></feature>
+<feature name="cat" domain="NT" > 
+	 <value name="__UNDEF__">UNDEFINED !!!</value> 
+	 <value name="acl:adv">acl:adv</value> <!-- Ukrainian --> 
+	 <value name="acl:attr">acl:attr</value> <!-- Chukchi --> 
+	 <value name="acl:cleft">acl:cleft</value> <!-- Norwegian, Swedish --> 
+	 <value name="acl:fixed">acl:fixed</value> <!-- Beja --> 
+	 <value name="acl:inf">acl:inf</value> <!-- Portuguese --> 
+	 <value name="acl:relat">acl:relat</value> <!-- Chukchi --> 
+	 <value name="acl:relcl">relative clause modifier</value> <!-- Akkadian, Albanian, Apurina, Arabic, Armenian, Assyrian, Beja, Belarusian, Breton, Bulgarian, Chinese, Czech, Danish, Dutch, English, Erzya, Estonian, Faroese, Finnish, French, German, Greek, Hebrew, Hindi, Hindi English, Icelandic, Indonesian, Irish, Italian, Karelian, Kazakh, Komi Permyak, Komi Zyrian, Korean, Latin, Lithuanian, Livvi, Manx, Marathi, Moksha, Naija, North Sami, Norwegian, Old East Slavic, Old French, Persian, Polish, Portuguese, Russian, Sanskrit, Scottish Gaelic, Slovak, Spanish, Swedish, Swedish Sign Language, Swiss German, Tagalog, Tamil, Telugu, Thai, Ukrainian, Urdu, Welsh, Western Armenian, Wolof --> 
+	 <value name="acl">clausal modifier of noun (adnominal clause)</value> 
+	 <value name="advcl:abs">advcl:abs</value> <!-- Latin --> 
+	 <value name="advcl:cau">advcl:cau</value> <!-- Moksha --> 
+	 <value name="advcl:cleft">advcl:cleft</value> <!-- French, Naija --> 
+	 <value name="advcl:cmpr">advcl:cmpr</value> <!-- Latin, Polish --> 
+	 <value name="advcl:cond">advcl:cond</value> <!-- Tamil, Telugu, Uyghur --> 
+	 <value name="advcl:coverb">advcl:coverb</value> <!-- Cantonese --> 
+	 <value name="advcl:eval">advcl:eval</value> <!-- Komi Zyrian --> 
+	 <value name="advcl:lcl">advcl:lcl</value> <!-- Komi Permyak --> 
+	 <value name="advcl:lto">advcl:lto</value> <!-- Komi Zyrian --> 
+	 <value name="advcl:mcl">advcl:mcl</value> <!-- Komi Permyak --> 
+	 <value name="advcl:pred">advcl:pred</value> <!-- Latin --> 
+	 <value name="advcl:relcl">advcl:relcl</value> <!-- Polish, Western Armenian --> 
+	 <value name="advcl:sp">advcl:sp</value> <!-- Ukrainian --> 
+	 <value name="advcl:svc">advcl:svc</value> <!-- Ukrainian --> 
+	 <value name="advcl:tcl">advcl:tcl</value> <!-- Apurina, Erzya, Komi Permyak, Komi Zyrian, Moksha, Romanian, Skolt Sami --> 
+	 <value name="advcl">adverbial clause modifier</value> 
+	 <value name="advmod:arg">advmod:arg</value> <!-- Polish --> 
+	 <value name="advmod:cau">advmod:cau</value> <!-- Erzya, Komi Zyrian, Moksha --> 
+	 <value name="advmod:comp">advmod:comp</value> <!-- Erzya --> 
+	 <value name="advmod:deg">advmod:deg</value> <!-- Erzya, Komi Permyak, Komi Zyrian, Moksha, Skolt Sami --> 
+	 <value name="advmod:det">advmod:det</value> <!-- Ukrainian --> 
+	 <value name="advmod:df">advmod:df</value> <!-- Cantonese, Chinese --> 
+	 <value name="advmod:emph">emphasizing word, intensifier</value> <!-- Akkadian, Arabic, Armenian, Catalan, Chukchi, Croatian, Czech, Indonesian, Komi Zyrian, Latin, Lithuanian, Polish, Sanskrit, Slovak, South Levantine Arabic, Tamil, Turkish, Turkish German, Upper Sorbian, Uyghur, Western Armenian --> 
+	 <value name="advmod:eval">advmod:eval</value> <!-- Erzya, Komi Zyrian, Moksha, Skolt Sami --> 
+	 <value name="advmod:fixed">advmod:fixed</value> <!-- Beja --> 
+	 <value name="advmod:foc">advmod:foc</value> <!-- Erzya, Komi Zyrian, Moksha, Skolt Sami --> 
+	 <value name="advmod:freq">advmod:freq</value> <!-- Komi Zyrian, Moksha --> 
+	 <value name="advmod:lfrom">advmod:lfrom</value> <!-- Erzya, Komi Zyrian, Moksha --> 
+	 <value name="advmod:lmod">locative adverbial modifier</value> <!-- Apurina, Danish, Erzya, Komi Permyak, Komi Zyrian, Moksha, Skolt Sami --> 
+	 <value name="advmod:lmp">advmod:lmp</value> <!-- Erzya, Komi Zyrian --> 
+	 <value name="advmod:locy">advmod:locy</value> <!-- Hungarian --> 
+	 <value name="advmod:lto">advmod:lto</value> <!-- Erzya, Komi Zyrian, Moksha --> 
+	 <value name="advmod:mmod">advmod:mmod</value> <!-- Erzya, Komi Permyak, Komi Zyrian, Moksha, Skolt Sami --> 
+	 <value name="advmod:mode">advmod:mode</value> <!-- Hungarian --> 
+	 <value name="advmod:neg">advmod:neg</value> <!-- Apurina, Buryat, Kiche, Kurmanji, Latin, Maltese, Polish, Skolt Sami --> 
+	 <value name="advmod:obl">adverbial modifier + oblique nominal</value> <!-- Old French --> 
+	 <value name="advmod:que">advmod:que</value> <!-- Hungarian --> 
+	 <value name="advmod:tfrom">advmod:tfrom</value> <!-- Hungarian --> 
+	 <value name="advmod:tlocy">advmod:tlocy</value> <!-- Hungarian --> 
+	 <value name="advmod:tmod">advmod:tmod</value> <!-- Apurina, Erzya, Komi Permyak, Komi Zyrian, Moksha, Romanian, Skolt Sami --> 
+	 <value name="advmod:to">advmod:to</value> <!-- Hungarian --> 
+	 <value name="advmod:tto">advmod:tto</value> <!-- Hungarian --> 
+	 <value name="advmod">adverbial modifier</value> 
+	 <value name="amod:att">amod:att</value> <!-- Hungarian --> 
+	 <value name="amod:attlvc">amod:attlvc</value> <!-- Hungarian --> 
+	 <value name="amod:flat">amod:flat</value> <!-- Polish --> 
+	 <value name="amod">adjectival modifier</value> 
+	 <value name="appos:trans">appos:trans</value> <!-- Turkish German --> 
+	 <value name="appos">appositional modifier</value> 
+	 <value name="aux:aff">aux:aff</value> <!-- Beja --> 
+	 <value name="aux:aspect">aux:aspect</value> <!-- Komi Zyrian --> 
+	 <value name="aux:caus">aux:caus</value> <!-- Armenian, French, Western Armenian --> 
+	 <value name="aux:clitic">aux:clitic</value> <!-- Polish --> 
+	 <value name="aux:cnd">aux:cnd</value> <!-- Erzya, Komi Permyak, Komi Zyrian, Polish --> 
+	 <value name="aux:ex">aux:ex</value> <!-- Armenian, Western Armenian --> 
+	 <value name="aux:imp">aux:imp</value> <!-- Erzya, Polish --> 
+	 <value name="aux:nec">aux:nec</value> <!-- Komi Zyrian, Moksha, Skolt Sami --> 
+	 <value name="aux:neg">aux:neg</value> <!-- Chukchi, Erzya, Komi Permyak, Komi Zyrian, Maltese, Moksha, North Sami, Skolt Sami, Tamil --> 
+	 <value name="aux:opt">aux:opt</value> <!-- Erzya, Moksha --> 
+	 <value name="aux:part">aux:part</value> <!-- Maltese --> 
+	 <value name="aux:pass">passive auxilary</value> <!-- Afrikaans, Ancient Greek, Arabic, Assyrian, Belarusian, Bhojpuri, Breton, Bulgarian, Buryat, Chinese, Czech, Dutch, English, Faroese, Finnish, French, Frisian Dutch, Galician, German, Hindi, Italian, Kangri, Karelian, Latin, Latvian, Lithuanian, Maltese, Marathi, Norwegian, Old Church Slavonic, Old East Slavic, Old French, Persian, Polish, Portuguese, Romanian, Russian, Slovak, Spanish, Swedish, Swiss German, Tamil, Thai, Turkish German, Upper Sorbian, Vietnamese --> 
+	 <value name="aux:pot">aux:pot</value> <!-- Komi Zyrian --> 
+	 <value name="aux:q">aux:q</value> <!-- Erzya, Turkish, Turkish German --> 
+	 <value name="aux:tense">aux:tense</value> <!-- French, Komi Zyrian, Skolt Sami --> 
+	 <value name="aux">auxiliary</value> 
+	 <value name="case:acc">case:acc</value> <!-- Hebrew --> 
+	 <value name="case:adv">case:adv</value> <!-- Indonesian --> 
+	 <value name="case:aff">case:aff</value> <!-- Beja --> 
+	 <value name="case:det">preposition with determiner</value> <!-- Maltese, Old French --> 
+	 <value name="case:gen">case:gen</value> <!-- Hebrew --> 
+	 <value name="case:loc">case:loc</value> <!-- Armenian, Cantonese, Chinese, Western Armenian --> 
+	 <value name="case:pred">case:pred</value> <!-- Welsh --> 
+	 <value name="case:voc">case:voc</value> <!-- Irish, Scottish Gaelic --> 
+	 <value name="case">case marking</value> 
+	 <value name="cc:nc">cc:nc</value> <!-- Old French --> 
+	 <value name="cc:nc">Coordinated conjunct : non coordonant</value> 
+	 <value name="cc:preconj">cc:preconj</value> <!-- Arabic, English, Erzya, Estonian, Faroese, Finnish, German, Indonesian, Komi Permyak, Komi Zyrian, Moksha, North Sami, Persian, Polish, Portuguese, Romanian, Slovenian, Spanish, Thai, Turkish --> 
+	 <value name="cc:preconj">preconjunct</value> 
+	 <value name="cc">Coordinating conjunction</value> 
+	 <value name="cc">coordinating conjunction</value> 
+	 <value name="ccomp:cleft">ccomp:cleft</value> <!-- Polish --> 
+	 <value name="ccomp:obj">ccomp:obj</value> <!-- Hungarian, Polish --> 
+	 <value name="ccomp:obl">ccomp:obl</value> <!-- Hungarian --> 
+	 <value name="ccomp:pmod">ccomp:pmod</value> <!-- Romanian --> 
+	 <value name="ccomp:pred">ccomp:pred</value> <!-- Hungarian --> 
+	 <value name="ccomp">clausal complement</value> 
+	 <value name="clf">classifier</value> 
+	 <value name="compound:a">compound:a</value> <!-- Indonesian --> 
+	 <value name="compound:affix">compound:affix</value> <!-- Hebrew --> 
+	 <value name="compound:dir">compound:dir</value> <!-- Cantonese, Chinese --> 
+	 <value name="compound:ext">compound:ext</value> <!-- Cantonese, Chinese --> 
+	 <value name="compound:lvc">compound:lvc</value> <!-- Armenian, Hindi, Kazakh, Khunsari, Korean, Kurmanji, Marathi, Nayini, Persian, Soi, Tamil, Telugu, Turkish, Turkish German, Uyghur, Western Armenian --> 
+	 <value name="compound:lvc">light verb construction</value> 
+	 <value name="compound:nn">compound:nn</value> <!-- Finnish, Livvi, North Sami --> 
+	 <value name="compound:preverb">compound:preverb</value> <!-- Hungarian --> 
+	 <value name="compound:prt">compound:prt</value> <!-- Afrikaans, Arabic, Danish, Dutch, English, Erzya, Estonian, Faroese, Finnish, Frisian Dutch, German, Icelandic, Irish, Karelian, Komi Permyak, Naija, Norwegian, Persian, Spanish, Swedish, Swedish Sign Language, Swiss German, Tamil, Thai, Turkish German, Wolof, Yoruba --> 
+	 <value name="compound:prt">phrasal verb particle</value> 
+	 <value name="compound:quant">compound:quant</value> <!-- Cantonese --> 
+	 <value name="compound:redup">reduplicated compounds</value> <!-- Armenian, Bambara, Classical Chinese, Erzya, Hindi, Kurmanji, Marathi, Naija, Tagalog, Tamil, Telugu, Turkish, Turkish German, Uyghur, Welsh, Western Armenian --> 
+	 <value name="compound:smixut">compound:smixut</value> <!-- Hebrew --> 
+	 <value name="compound:svc">serial verb compounds</value> <!-- Amharic, Armenian, Marathi, Mbya Guarani, Naija, Swedish Sign Language, Telugu, Ukrainian, Western Armenian, Wolof, Yoruba --> 
+	 <value name="compound:vo">compound:vo</value> <!-- Cantonese, Chinese --> 
+	 <value name="compound:vv">compound:vv</value> <!-- Cantonese, Chinese --> 
+	 <value name="compound">compound</value> 
+	 <value name="conj:expl">conj:expl</value> <!-- Latin --> 
+	 <value name="conj:extend">conj:extend</value> <!-- Slovenian --> 
+	 <value name="conj:svc">conj:svc</value> <!-- Ukrainian --> 
+	 <value name="conj">conjunct</value> 
+	 <value name="cop:expl">cop:expl</value> <!-- Maltese --> 
+	 <value name="cop:locat">cop:locat</value> <!-- Polish --> 
+	 <value name="cop:own">cop:own</value> <!-- Finnish, Karelian, Livvi, Marathi --> 
+	 <value name="cop">copula</value> 
+	 <value name="csubj:cleft">csubj:cleft</value> <!-- Irish, Latin, Manx, Scottish Gaelic --> 
+	 <value name="csubj:cop">csubj:cop</value> <!-- Erzya, Estonian, Finnish, Irish, Komi Zyrian, Livvi, Manx, Moksha, Scottish Gaelic, Turkish --> 
+	 <value name="csubj:pass">clausal passive subject</value> <!-- Albanian, Amharic, Ancient Greek, Arabic, Armenian, Belarusian, Bulgarian, Catalan, Chinese, Classical Chinese, Czech, English, French, German, Gothic, Greek, Indonesian, Italian, Korean, Latin, Latvian, Lithuanian, Norwegian, Old Church Slavonic, Old East Slavic, Polish, Portuguese, Romanian, Russian, Sanskrit, Slovak, Spanish, Swedish, Western Armenian --> 
+	 <value name="csubj">clausal subject</value> 
+	 <value name="dep:aff">dep:aff</value> <!-- Beja --> 
+	 <value name="dep:agr">dep:agr</value> <!-- Kiche --> 
+	 <value name="dep:alt">dep:alt</value> <!-- Upper Sorbian --> 
+	 <value name="dep:ana">dep:ana</value> <!-- Yupik --> 
+	 <value name="dep:aux">dep:aux</value> <!-- Yupik --> 
+	 <value name="dep:comp">dep:comp</value> <!-- Beja, French --> 
+	 <value name="dep:conj">dep:conj</value> <!-- Beja --> 
+	 <value name="dep:cop">dep:cop</value> <!-- Yupik --> 
+	 <value name="dep:emo">dep:emo</value> <!-- Yupik --> 
+	 <value name="dep:infl">dep:infl</value> <!-- Yupik --> 
+	 <value name="dep:mark">dep:mark</value> <!-- Yupik --> 
+	 <value name="dep:mod">dep:mod</value> <!-- Mbya Guarani --> 
+	 <value name="dep:pos">dep:pos</value> <!-- Yupik --> 
+	 <value name="dep:redup">dep:redup</value> <!-- Beja --> 
+	 <value name="dep:ss">dep:ss</value> <!-- Kiche --> 
+	 <value name="dep">unspecified dependency</value> 
+	 <value name="det:adj">det:adj</value> <!-- Albanian --> 
+	 <value name="det:noun">det:noun</value> <!-- Albanian --> 
+	 <value name="det:numgov">pronominal quantifier governing the case of the noun</value> <!-- Czech, Polish, Serbian, Slovak, Ukrainian, Upper Sorbian --> 
+	 <value name="det:nummod">pronominal quantifier agreeing in case with the noun</value> <!-- Czech, Polish, Ukrainian --> 
+	 <value name="det:poss">possessive determiner</value> <!-- Akkadian, Armenian, German, Italian, Korean, Polish, Portuguese, Western Armenian --> 
+	 <value name="det:predet">det:predet</value> <!-- English, Italian, Persian --> 
+	 <value name="det:pron">det:pron</value> <!-- Albanian --> 
+	 <value name="det:rel">det:rel</value> <!-- Bambara --> 
+	 <value name="det">determiner</value> 
+	 <value name="discourse:emo">discourse:emo</value> <!-- Irish, Italian, Polish --> 
+	 <value name="discourse:filler">discourse:filler</value> <!-- Norwegian, Slovenian --> 
+	 <value name="discourse:intj">discourse:intj</value> <!-- Polish --> 
+	 <value name="discourse:sp">discourse:sp</value> <!-- Cantonese, Chinese, Classical Chinese --> 
+	 <value name="discourse">discourse element</value> 
+	 <value name="dislocated:cleft">dislocated:cleft</value> <!-- Mbya Guarani --> 
+	 <value name="dislocated:csubj">dislocated:csubj</value> <!-- Latin --> 
+	 <value name="dislocated:nsubj">dislocated:nsubj</value> <!-- Latin --> 
+	 <value name="dislocated:obj">dislocated:obj</value> <!-- Latin --> 
+	 <value name="dislocated:subj">dislocated:subj</value> <!-- Beja --> 
+	 <value name="dislocated">dislocated elements</value> 
+	 <value name="expl:comp">expl:comp</value> <!-- French --> 
+	 <value name="expl:impers">impersonal expletive</value> <!-- Italian, Polish, Romanian, Spanish --> 
+	 <value name="expl:pass">reflexive pronoun used in reflexive passive</value> <!-- Catalan, Czech, French, Italian, Latin, Portuguese, Romanian, Slovak, Spanish, Upper Sorbian --> 
+	 <value name="expl:poss">expl:poss</value> <!-- Romanian --> 
+	 <value name="expl:pv">reflexive clitic with an inherently reflexive verb</value> <!-- Czech, Dutch, German, Old East Slavic, Polish, Portuguese, Romanian, Slovak, Spanish, Turkish German, Upper Sorbian --> 
+	 <value name="expl:subj">expl:subj</value> <!-- French, Naija --> 
+	 <value name="expl">expletive</value> 
+	 <value name="fixed">fixed multiword expression</value> 
+	 <value name="flat:abs">flat:abs</value> <!-- Ukrainian --> 
+	 <value name="flat:dist">flat:dist</value> <!-- Western Armenian --> 
+	 <value name="flat:foreign">foreign words</value> <!-- Arabic, Belarusian, Buryat, Chinese, Chukchi, Croatian, Czech, English, Estonian, Faroese, Finnish, French, Galician, Icelandic, Indonesian, Irish, Italian, Komi Zyrian, Latin, Latvian, Lithuanian, Manx, Naija, Norwegian, Persian, Polish, Portuguese, Russian, Scottish Gaelic, Slovak, Slovenian, South Levantine Arabic, Ukrainian, Upper Sorbian --> 
+	 <value name="flat:name">names</value> <!-- Ancient Greek, Belarusian, Breton, Chinese, Chukchi, Erzya, Faroese, Finnish, French, Frisian Dutch, Galician, German, Gothic, Hebrew, Hindi, Hungarian, Icelandic, Indonesian, Irish, Italian, Karelian, Kazakh, Komi Permyak, Komi Zyrian, Korean, Latin, Latvian, Livvi, Maltese, Moksha, Norwegian, Old Church Slavonic, Old East Slavic, Persian, Portuguese, Russian, Scottish Gaelic, Skolt Sami, Slovenian, Spanish, Swedish, Thai, Ukrainian, Welsh, Western Armenian --> 
+	 <value name="flat:num">flat:num</value> <!-- Komi Zyrian, Persian --> 
+	 <value name="flat:range">flat:range</value> <!-- Ukrainian, Western Armenian --> 
+	 <value name="flat:repeat">flat:repeat</value> <!-- Ukrainian --> 
+	 <value name="flat:sibl">flat:sibl</value> <!-- Ukrainian --> 
+	 <value name="flat:title">flat:title</value> <!-- Ukrainian --> 
+	 <value name="flat:vv">flat:vv</value> <!-- Classical Chinese --> 
+	 <value name="flat">name multiword expression</value> 
+	 <value name="goeswith">goes with</value> 
+	 <value name="iobj:agent">iobj:agent</value> <!-- Armenian, French, Western Armenian --> 
+	 <value name="iobj:appl">iobj:appl</value> <!-- Wolof --> 
+	 <value name="iobj:patient">iobj:patient</value> <!-- Tagalog --> 
+	 <value name="iobj">indirect object</value> 
+	 <value name="list">list</value> 
+	 <value name="mark:adv">mark:adv</value> <!-- Cantonese, Chinese --> 
+	 <value name="mark:advmod">adverbial modifier confusable with a subordination marker</value> <!-- Old French --> 
+	 <value name="mark:aff">mark:aff</value> <!-- Beja --> 
+	 <value name="mark:obj">marker + object</value> <!--Old French, no doc --> 
+	 <value name="mark:obl">marker + oblique nominal</value> <!--Old French, no doc --> 
+	 <value name="mark:prt">mark:prt</value> <!-- Chinese, Irish, Scottish Gaelic --> 
+	 <value name="mark:q">mark:q</value> <!-- Hebrew --> 
+	 <value name="mark:rel">mark:rel</value> <!-- Cantonese, Chinese --> 
+	 <value name="mark">marker</value> 
+	 <value name="nmod:agent">nmod:agent</value> <!-- Welsh --> 
+	 <value name="nmod:appos">nmod:appos</value> <!-- French, Komi Zyrian, Moksha --> 
+	 <value name="nmod:arg">nmod:arg</value> <!-- Polish, Yupik --> 
+	 <value name="nmod:att">nmod:att</value> <!-- Hungarian --> 
+	 <value name="nmod:attlvc">nmod:attlvc</value> <!-- Hungarian --> 
+	 <value name="nmod:attr">nmod:attr</value> <!-- Chukchi --> 
+	 <value name="nmod:bahuv">nmod:bahuv</value> <!-- Moksha --> 
+	 <value name="nmod:cau">nmod:cau</value> <!-- Uyghur --> 
+	 <value name="nmod:comp">nmod:comp</value> <!-- Erzya, Komi Zyrian, Moksha, Turkish, Uyghur --> 
+	 <value name="nmod:flat">nmod:flat</value> <!-- Polish --> 
+	 <value name="nmod:gen">nmod:gen</value> <!-- Breton --> 
+	 <value name="nmod:gobj">nmod:gobj</value> <!-- Erzya, Finnish --> 
+	 <value name="nmod:gsubj">nmod:gsubj</value> <!-- Erzya, Finnish, Karelian --> 
+	 <value name="nmod:lfrom">nmod:lfrom</value> <!-- Komi Zyrian --> 
+	 <value name="nmod:lmod">nmod:lmod</value> <!-- Erzya, Indonesian, Komi Permyak, Komi Zyrian, Moksha --> 
+	 <value name="nmod:npmod">nmod:npmod</value> <!-- Armenian, English, Western Armenian --> 
+	 <value name="nmod:obj">nmod:obj</value> <!-- Komi Zyrian --> 
+	 <value name="nmod:obl">nmod:obl</value> <!-- Hungarian --> 
+	 <value name="nmod:part">nmod:part</value> <!-- Turkish, Uyghur --> 
+	 <value name="nmod:poss">possessive nominal modifier</value> <!-- Akkadian, Albanian, Apurina, Arabic, Armenian, Assyrian, Bambara, Beja, Breton, Chukchi, Danish, Dutch, English, Erzya, Faroese, Finnish, Frisian Dutch, German, Hebrew, Hindi, Icelandic, Indonesian, Irish, Karelian, Kazakh, Khunsari, Komi Permyak, Komi Zyrian, Korean, Kurmanji, Latin, Livvi, Maltese, Manx, Marathi, Moksha, Naija, Nayini, North Sami, Persian, Polish, Sanskrit, Scottish Gaelic, Skolt Sami, Soi, South Levantine Arabic, Swedish, Swedish Sign Language, Swiss German, Tagalog, Tamil, Telugu, Thai, Turkish, Uyghur, Warlpiri, Welsh, Western Armenian, Wolof --> 
+	 <value name="nmod:pred">nmod:pred</value> <!-- Polish --> 
+	 <value name="nmod:prp">nmod:prp</value> <!-- Komi Zyrian --> 
+	 <value name="nmod:redup">nmod:redup</value> <!-- Welsh --> 
+	 <value name="nmod:relat">nmod:relat</value> <!-- Chukchi --> 
+	 <value name="nmod:subj">nmod:subj</value> <!-- Komi Zyrian --> 
+	 <value name="nmod:tmod">temporal modifier</value> <!-- Chinese, English, Indonesian, Moksha, Romanian, Telugu, Uyghur --> 
+	 <value name="nmod">nominal modifier</value> 
+	 <value name="nsubj:advmod">fused subject pronoun and adverb</value> <!-- Old French --> 
+	 <value name="nsubj:aff">nsubj:aff</value> <!-- Beja --> 
+	 <value name="nsubj:bfoc">nsubj:bfoc</value> <!-- Tagalog --> 
+	 <value name="nsubj:caus">nsubj:caus</value> <!-- Armenian, French, Western Armenian --> 
+	 <value name="nsubj:cleft">nsubj:cleft</value> <!-- Latin --> 
+	 <value name="nsubj:cop">nsubj:cop</value> <!-- Apurina, Breton, Erzya, Estonian, Finnish, Hebrew, Karelian, Komi Permyak, Komi Zyrian, Livvi, Moksha, Sanskrit, Skolt Sami, Turkish --> 
+	 <value name="nsubj:ifoc">nsubj:ifoc</value> <!-- Tagalog --> 
+	 <value name="nsubj:lfoc">nsubj:lfoc</value> <!-- Tagalog --> 
+	 <value name="nsubj:lvc">nsubj:lvc</value> <!-- Hungarian --> 
+	 <value name="nsubj:nc">nsubj:nc</value> <!-- Persian, Tamil, Telugu --> 
+	 <value name="nsubj:obj">fused subject and object pronoun</value> <!-- Old French --> 
+	 <value name="nsubj:pass">passive nominal subject</value> <!-- Afrikaans, Amharic, Ancient Greek, Arabic, Armenian, Assyrian, Belarusian, Bulgarian, Buryat, Cantonese, Catalan, Chinese, Classical Chinese, Czech, Dutch, English, Faroese, French, Frisian Dutch, Galician, German, Gothic, Greek, Hindi, Indonesian, Italian, Korean, Latin, Latvian, Lithuanian, Maltese, Marathi, Moksha, Norwegian, Old Church Slavonic, Old East Slavic, Persian, Polish, Portuguese, Romanian, Russian, Sanskrit, Skolt Sami, Slovak, Spanish, Swedish, Swiss German, Tagalog, Tamil, Thai, Turkish German, Upper Sorbian, Western Armenian --> 
+	 <value name="nsubj:periph">nsubj:periph</value> <!-- Cantonese --> 
+	 <value name="nsubj">Nominal subject</value> 
+	 <value name="nummod:det">nummod:det</value> <!-- Beja --> 
+	 <value name="nummod:entity">numeric modifier governed by a noun</value> <!-- Russian --> 
+	 <value name="nummod:flat">nummod:flat</value> <!-- Polish --> 
+	 <value name="nummod:gov">numeric modifier governing the case of the noun</value> <!-- Belarusian, Czech, Lithuanian, Old East Slavic, Polish, Russian, Sanskrit, Serbian, Ukrainian, Upper Sorbian --> 
+	 <value name="nummod">numeric modifier</value> 
+	 <value name="obj:advmod">fused adverb and object pronoun</value> <!-- Old French --> 
+	 <value name="obj:advneg">fused negation and object pronoun</value> <!-- no doc for advneg --> 
+	 <value name="obj:agent">obj:agent</value> <!-- Apurina, French, Tagalog --> 
+	 <value name="obj:appl">obj:appl</value> <!-- Wolof --> 
+	 <value name="obj:caus">obj:caus</value> <!-- Wolof --> 
+	 <value name="obj:lvc">obj:lvc</value> <!-- French, Hungarian, Naija --> 
+	 <value name="obj:obl">fused oblique and object pronoun</value> <!-- Old French --> 
+	 <value name="obj:periph">obj:periph</value> <!-- Cantonese, Chinese --> 
+	 <value name="obj">object</value> 
+	 <value name="obl:advmod">adverbial modifier confusable with an oblique dependent</value> <!-- Old French --> 
+	 <value name="obl:agent">agent modifier</value> <!-- Ancient Greek, Armenian, Belarusian, Breton, Cantonese, Chinese, Czech, Dutch, Erzya, French, German, Gothic, Greek, Hindi, Indonesian, Italian, Komi Zyrian, Latin, Lithuanian, Maltese, Moksha, Naija, Old Church Slavonic, Old East Slavic, Polish, Portuguese, Romanian, Russian, Sanskrit, Skolt Sami, Swedish, Tamil, Turkish, Welsh, Western Armenian --> 
+	 <value name="obl:appl">obl:appl</value> <!-- Wolof --> 
+	 <value name="obl:arg">oblique argument</value> <!-- Arabic, Beja, Czech, French, German, Greek, Icelandic, Latin, Lithuanian, Maltese, Naija, Persian, Polish, Sanskrit, Slovak, South Levantine Arabic, Tamil --> 
+	 <value name="obl:cau">obl:cau</value> <!-- Erzya, Komi Zyrian, Moksha, Telugu --> 
+	 <value name="obl:cmp">obl:cmp</value> <!-- Telugu --> 
+	 <value name="obl:cmpr">obl:cmpr</value> <!-- Latin, Polish, Tamil --> 
+	 <value name="obl:comp">obl:comp</value> <!-- Moksha --> 
+	 <value name="obl:dat">obl:dat</value> <!-- Kurmanji --> 
+	 <value name="obl:freq">obl:freq</value> <!-- Moksha --> 
+	 <value name="obl:inst">obl:inst</value> <!-- Erzya, Moksha, Tamil --> 
+	 <value name="obl:lfrom">obl:lfrom</value> <!-- Erzya, Komi Zyrian, Moksha --> 
+	 <value name="obl:lmod">locative modifier</value> <!-- Apurina, Classical Chinese, Danish, Erzya, Komi Permyak, Komi Zyrian, Moksha, Skolt Sami, Tamil --> 
+	 <value name="obl:lmp">obl:lmp</value> <!-- Erzya, Komi Zyrian, Moksha --> 
+	 <value name="obl:lto">obl:lto</value> <!-- Erzya, Komi Zyrian, Moksha --> 
+	 <value name="obl:lvc">obl:lvc</value> <!-- Hungarian --> 
+	 <value name="obl:mcl">obl:mcl</value> <!-- Komi Zyrian --> 
+	 <value name="obl:mod"> oblique modifier</value> <!-- Beja, French, Naija, Yupik --> 
+	 <value name="obl:npmod">obl:npmod</value> <!-- Coptic, English --> 
+	 <value name="obl:orphan">obl:orphan</value> <!-- Polish --> 
+	 <value name="obl:own">obl:own</value> <!-- Kazakh --> 
+	 <value name="obl:patient">obl:patient</value> <!-- Cantonese, Chinese --> 
+	 <value name="obl:pmod">obl:pmod</value> <!-- Romanian, Tamil --> 
+	 <value name="obl:poss">obl:poss</value> <!-- Thai --> 
+	 <value name="obl:prep">obl:prep</value> <!-- Irish --> 
+	 <value name="obl:sentcon">obl:sentcon</value> <!-- Mbya Guarani --> 
+	 <value name="obl:smod">obl:smod</value> <!-- Scottish Gaelic --> 
+	 <value name="obl:tmod">obl:tmod</value> <!-- Apurina, Arabic, Cantonese, Chinese, Classical Chinese, Danish, English, Erzya, Frisian Dutch, German, Hindi, Indonesian, Irish, Italian, Komi Permyak, Komi Zyrian, Korean, Manx, Moksha, Portuguese, Scottish Gaelic, Skolt Sami, Spanish, Tamil, Telugu, Thai, Turkish, Uyghur, Warlpiri --> 
+	 <value name="obl:tmod">temporal modifier</value> 
+	 <value name="obl">oblique nominal</value> 
+	 <value name="orphan:missing">textual gap in the source</value> <!-- Latin --> 
+	 <value name="orphan">remnant in ellipsis</value> 
+	 <value name="parataxis:appos">parataxis:appos</value> <!-- Italian --> 
+	 <value name="parataxis:conj">parataxis:conj</value> <!-- Naija --> 
+	 <value name="parataxis:coord">parataxis:coord</value> <!-- Beja --> 
+	 <value name="parataxis:deletion">parataxis:deletion</value> <!-- Norwegian --> 
+	 <value name="parataxis:discourse">parataxis:discourse</value> <!-- Italian, Naija, Slovenian, Turkish German, Ukrainian --> 
+	 <value name="parataxis:dislocated">parataxis:dislocated</value> <!-- Naija --> 
+	 <value name="parataxis:hashtag">parataxis:hashtag</value> <!-- Irish, Italian --> 
+	 <value name="parataxis:insert">parataxis:insert</value> <!-- French, Italian, Polish --> 
+	 <value name="parataxis:mod">parataxis:mod</value> <!-- Beja --> 
+	 <value name="parataxis:newsent">parataxis:newsent</value> <!-- Ukrainian --> 
+	 <value name="parataxis:nsubj">parataxis:nsubj</value> <!-- Italian --> 
+	 <value name="parataxis:obj">parataxis:obj</value> <!-- Bambara, Italian, Polish --> 
+	 <value name="parataxis:parenth">parataxis:parenth</value> <!-- French, Naija --> 
+	 <value name="parataxis:rel">parataxis:rel</value> <!-- Ukrainian --> 
+	 <value name="parataxis:rep">parataxis:rep</value> <!-- Chukchi, Latin, Mbya Guarani --> 
+	 <value name="parataxis:restart">parataxis:restart</value> <!-- Slovenian --> 
+	 <value name="parataxis:rt">parataxis:rt</value> <!-- Irish --> 
+	 <value name="parataxis:sentence">parataxis:sentence</value> <!-- Irish --> 
+	 <value name="parataxis:trans">parataxis:trans</value> <!-- Turkish German --> 
+	 <value name="parataxis:url">parataxis:url</value> <!-- Irish --> 
+	 <value name="parataxis">parataxis</value> 
+	 <value name="punct">punctuation</value> 
+	 <value name="remnant">Remnant ?</value> <!-- no doc, replace with orphan? --> 
+	 <value name="reparandum">overridden disfluency</value> 
+	 <value name="root">root</value> 
+	 <value name="vocative:cl">vocative:cl</value> <!-- Ukrainian --> 
+	 <value name="vocative:mention">vocative:mention</value> <!-- Irish, Italian --> 
+	 <value name="vocative">vocative</value> 
+	 <value name="xcomp:cleft">xcomp:cleft</value> <!-- Polish --> 
+	 <value name="xcomp:ds">xcomp:ds</value> <!-- Erzya, Finnish, Karelian, Komi Permyak, Livvi --> 
+	 <value name="xcomp:obj">xcomp:obj</value> <!-- North Sami, Polish --> 
+	 <value name="xcomp:pred">xcomp:pred</value> <!-- Irish, Latin, Manx, North Sami, Polish, Scottish Gaelic --> 
+	 <value name="xcomp:sp">xcomp:sp</value> <!-- Ukrainian --> 
+	 <value name="xcomp:subj">xcomp:subj</value> <!-- Polish --> 
+	 <value name="xcomp">open clausal complement</value>
+</feature>
+<feature name="coord" domain="NT" ></feature>
+<feature name="dom" domain="NT" ></feature>
+<feature name="type" domain="NT" > 
+	 <value name="nV">élément non-verbal</value> 
+	 <value name="VFin">finite verb</value> 
+	 <value name="VInf">infinitive</value> 
+	 <value name="VPar">participle</value> 
+	 <value name="--">nil</value>
+</feature>
+<feature name="vform" domain="NT"></feature>
+<feature name="vlemma" domain="NT"></feature>
+<feature name="note" domain="NT"></feature>
+<feature name="snr" domain="NT"></feature>
+""";
+
+
+ 
+	 printf MASTER "$nt_features_header";
+ 
+	 printf MASTER """
+<edgelabel> 
+	 <value name="D">dependency</value> 
+	 <value name="L">lexical</value> 
+	 <value name="R">relator</value> 
+	 <value name="*">not bound</value>
+</edgelabel>
+<secedgelabel> 
+	 <value name="cluster">between elements of GpCoo</value> 
+	 <value name="coord">between members of Coo</value> 
+	 <value name="dupl">between duplicated nodes</value>
+</secedgelabel>
+</annotation>
+</head>
+<body>
+""";
+}
+
+//  <value name="M">main</value>
+//  <value name="P">part</value>
+
+
+def write_master_footer {
+MASTER << """</body>
+</corpus>
+""";
+}
+
+
+TEMP="""
+<feature name="nodom" domain="NT" ></feature>
+<feature name="headpos" domain="NT" ></feature>
+<feature name="annotationFile" domain="NT" ></feature>
+<feature name="annotationUri" domain="NT" ></feature>
+""";
+
+
+def define_cat_hashes {
+//  abbrev2cat{"Apst"} = "Apostrophe";
+//  abbrev2cat{"AtObj"} = "AttributObjet";
+//  abbrev2cat{"AtRfc"} = "AttributReflechi";
+//  abbrev2cat{"AtSj"} = "AttributSujet";
+//  abbrev2cat{"AuxA"} = "Auxilie-Actif";
+//  abbrev2cat{"AuxP"} = "Auxilie-Passif";
+//  abbrev2cat{"Circ"} = "Circonstant";
+//  abbrev2cat{"Cmpl"} = "Complement";
+//  abbrev2cat{"GpCoo"} = "Coordonne";
+//  abbrev2cat{"Coo"} = "Coordination";
+//  abbrev2cat{"Det"} = "Determinant";
+//  abbrev2cat{"NgPrt"} = "Forclusif";
+//  abbrev2cat{"Insrt"} = "Incidente";
+//  abbrev2cat{"Intj"} = "Interjection";
+//  abbrev2cat{"ModA"} = "ModifieurAttache";
+//  abbrev2cat{"ModD"} = "ModifieurDetache";
+//  abbrev2cat{"Ng"} = "Negation";
+//  abbrev2cat{"VInf"} = "NoeudVerbal-Infinitif";
+//  abbrev2cat{"VPrt"} = "NoeudVerbal-Participe"; #?
+//  abbrev2cat{"VFin"} = "NoeudVerbal-Personnel";
+//  abbrev2cat{"nSnt"} = "NonPhrase";
+//  abbrev2cat{"Obj"} = "Objet";
+//  abbrev2cat{"Snt"} = "Phrase";
+//  abbrev2cat{"Pon"} = "Ponctuation";
+//  abbrev2cat{"Rfc"} = "Reflechi";
+//  abbrev2cat{"Rfx"} = "ReflexifRenforce";
+//  abbrev2cat{"RelC"} = "Relateur-Coordonnant";
+//  abbrev2cat{"RelNC"} = "Relateur-NonCoordonnant";
+//  abbrev2cat{"nMax"} = "StructureNonMaximale";
+//  abbrev2cat{"SjImp"} = "SujetImpersonnel";
+//  abbrev2cat{"SjPer"} = "SujetPersonnel";
+//  abbrev2cat{"Lac"} = "Lacune";
+//  abbrev2cat{"Aux"} = "Auxilie";
+//  abbrev2cat{"Regim"} = "Regime";
+
+
+abbrev2cat{"acl"} = "Clausal modifier of noun";
+abbrev2cat{"advcl"} = "Adverbial clause modifier";
+abbrev2cat{"advmod"} = "Adverbial modifier";
+abbrev2cat{"amod"} = "Adjectival modifier";
+abbrev2cat{"appos"} = "Appositional modifier";
+abbrev2cat{"aux"} = "Auxiliary";
+abbrev2cat{"cc-nc"} = "Coordinated conjunct : non coordonant";
+abbrev2cat{"cc"} = "Coordinating conjunction";
+abbrev2cat{"ccomp"} = "Clausal complement";
+abbrev2cat{"conj"} = "Conjunct";
+abbrev2cat{"cop"} = "Copula";
+abbrev2cat{"csubj"} = "Clausal subject";
+abbrev2cat{"det"} = "Determiner";
+abbrev2cat{"dislocated"} = "Dislocated elements";
+abbrev2cat{"expl"} = "Expletive";
+abbrev2cat{"iobj"} = "Indirect object";
+abbrev2cat{"mark"} = "Marker";
+abbrev2cat{"nmod"} = "Nominal modifier";
+abbrev2cat{"nsubj"} = "Nominal subject";
+abbrev2cat{"nummod"} = "Numeric modifier";
+abbrev2cat{"obj"} = "Object";
+abbrev2cat{"obl"} = " Oblique nominal";
+abbrev2cat{"orphan"} = "Remnant in ellipsis";
+abbrev2cat{"remnant"} = "Remnant ?";
+abbrev2cat{"vocative"} = "Vocative";
+abbrev2cat{"xcomp"} = "Open clausal complement";
+}
+
+def print_sentence { 
+	for (def q = 0; q <= words.size(); q++) { 
+	  print "$words[$q]\n"; 
+	}
+}
+
+def write_nonterminals { 
+	 def print_nt_features; 
+	 if ($_[1] =~ /dupl/) { 
+	dupl = '_dupl'; 
+	 } else { 
+	dupl = ''; 
+	 } 
+	 if (nt_features != '') { 
+	print_nt_features = nt_empty_features; 
+	if ($_[0] =~ /$thisrootname/) { 
+	  print_nt_features = nt_features; 
+	} 
+	 } 
+	 printf XML "   <nt id=\"n%d_%d%s\" cat=\"%s\" coord=\"--\" dom=\"%s\" type=\"%s\" vform=\"%s\" vlemma=\"%s\"%s note=\"%s\" snr=\"%d\">\n", $., w, dupl, $_[0], dom, type, vform, vlemma, print_nt_features, notes("$._$w"), $.; 
+	 printf XML "  <edge idref=\"s%d_%d%s\" label=\"L\"/>\n", $., w, dupl; 
+	 // link duplicate with primary original node 
+	 if ($_[1] =~ /dupl/) { 
+	printf XML "  <secedge idref=\"s%d_%d\" label=\"dupl\"/>\n", $., w; 
+	 } 
+	 // if node is not a duplicate: attach all the daughters 
+	 if ($_[1] !~ /dupl/) { 
+	for (def d = 0; d <= daughters.size(); d++) { 
+	  daughter = daughters[d]; 
+	  if ("$._$w" != "$._$daughter") { // avoid cycles
+	printf XML "  <edge idref=\"n%d_%d%s\" label=\"%s\"/>\n", $., daughter, dupl, edge_label("$._$daughter"); 
+	  } 
+	  // check if a duplicate of this node must be attached 
+	  if (duplicates{"$._$daughter"} == 1) {
+	printf XML "  <edge idref=\"n%d_%d_dupl\" label=\"%s\"/>\n", $., daughter, edge_label("$._$daughter_dupl"); 
+	  } 
+	} 
+	 } 
+	 XML << "   </nt>\n";
+}
+
+// checks if node is stored as in hash of relators
+def edge_label { 
+	 if (relators{$_[0]} == 1) { 
+	return 'R'; 
+	 } 
+	 return 'D';
+}
+
+// retrives notes for this node
+def notes { 
+	 if (notes{$_[0]} != '') { 
+	return "$notes{$_[0]}"; 
+	 } 
+	 return '--';
+}
+
+// conversions, bug fixes
+def clean_data { 
+	// conversions of values, some necessary some for convenience 
+	word =~ s/"/'/g; 
+	word =~ s/\&/(and)/g; 
+	word =~ s/<</«/g; 
+	word =~ s/>>/»/g; 
+	word =~ s/[<>]//g; 
+	pos =~ s/:/_/g; 
+	mor =~ s/\|/_/g; 
+	ppos =~ s/:/_/g; 
+	pmor =~ s/\|/_/g; 
+	lemma =~ s/\|/_/g; 
+	lemma =~ s/[<>]//g; 
+	lemma =~ s/"/'/g; 
+	lemma =~ s/\&/(and)/g; 
+	plemma =~ s/\|/_/g; 
+	plemma =~ s/[<>]//g; 
+	plemma =~ s/"/'/g; 
+	plemma =~ s/\&/(and)/g;
+ 
+	// clean categories 
+	cat =~ s/ROOT/$thisrootname/;  // top node, for compatibility with SRCMF
+// cat =~ s/Ponctuation/Pon/; 
+	// correct some bugs in parse
+// cat =~ s/Sujet/SjPer/;
+// cat =~ s/Modifieur/ModA/;
+// cat =~ s/Parenthese/Insrt/; 
+	cat =~ s/\-/_/g; 
+	cat =~ s/RelNC_(.*)/$1_RelNC/;  // RelNC always 2nd node, for consistency in duplicates 
+	 return;
+}
+
+
Index: TXM/trunk/org.txm.conllu.core/groovy/org/txm/scripts/importer/conllu/tigerXml-sortBfmByDate.xsl
===================================================================
--- TXM/trunk/org.txm.conllu.core/groovy/org/txm/scripts/importer/conllu/tigerXml-sortBfmByDate.xsl	(revision 0)
+++ TXM/trunk/org.txm.conllu.core/groovy/org/txm/scripts/importer/conllu/tigerXml-sortBfmByDate.xsl	(revision 3567)
@@ -0,0 +1,283 @@
+<!-- The Identity Transformation -->
+<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:tei="http://www.tei-c.org/ns/1.0" xmlns:xs="http://www.w3.org/2001/XMLSchema" exclude-result-prefixes="#all">
+  
+  <!-- This stylesheet sorts the BFM texts by date in the main.xml file of TIGER Search indexes.
+  To use for other texts, replace the text-order variable. There must be a text element for every text file 
+  where the @id is the file name and @order is the sorting key.
+  
+  Written by A. Lavrentiev, CNRS, UMR IHRIM, 2021-07-16
+  GNU GPL v.3
+  -->
+  
+  
+  <!-- Whenever you match any node or any attribute -->
+  <xsl:template match="node()|@*">
+    <!-- Copy the current node -->
+    <xsl:copy>
+      <!-- Including any attributes it has and any child nodes -->
+      <xsl:apply-templates select="@*|node()"/>
+    </xsl:copy>
+  </xsl:template>
+  
+  <xsl:output indent="yes"/>
+  
+  <xsl:template match="corpus">
+    <xsl:copy>
+      <xsl:apply-templates select="@*"/>
+      <xsl:apply-templates select="head"/>
+      <body>
+        <xsl:for-each select="$text-order/text">
+          <xsl:sort select="@order"/>
+          <xsl:variable name="text-id"><xsl:value-of select="@id"/></xsl:variable>
+          <xsl:for-each select="$text-list/text">
+            <xsl:if test="@id = $text-id">
+              <subcorpus name='{@id}-{@n}' external='file:{@id}-{@n}.xml'/>
+            </xsl:if>
+          </xsl:for-each>
+        </xsl:for-each>
+      </body>
+    </xsl:copy>
+  </xsl:template>
+  
+  
+  <xsl:variable name="text-list">
+    <xsl:for-each select="//subcorpus">
+      <text id="{replace(@name,'-\d+$','')}" n="{replace(@name,'^.+-(\d+)$','$1')}"></text>
+    </xsl:for-each>
+  </xsl:variable>
+  
+  <xsl:variable name="text-order">
+    <text id="strasbBfm" order="0842strasbBfm"/>
+    <text id="eulaliBfm" order="0883eulaliBfm"/>
+    <text id="jonas" order="0945jonas"/>
+    <text id="passion" order="1000passion"/>
+    <text id="slethgier" order="1000slethgier"/>
+    <text id="AlexisS2_Prologue" order="1050aAlexisS2_Prologue"/>
+    <text id="AlexisRaM" order="1050bAlexisRaM"/>
+    <text id="roland" order="1100roland"/>
+    <text id="leiswillelm" order="1112leiswillelm"/>
+    <text id="comput" order="1116comput"/>
+    <text id="EpreuveJudic" order="1117EpreuveJudic"/>
+    <text id="Lapidal" order="1117Lapidal"/>
+    <text id="oxfps" order="1125oxfps"/>
+    <text id="bestiaire" order="1128bestiaire"/>
+    <text id="gormont" order="1130gormont"/>
+    <text id="Juise" order="1137Juise"/>
+    <text id="DescrEngl" order="1140DescrEngl"/>
+    <text id="guill1" order="1140guill1"/>
+    <text id="Lapidfp" order="1150Lapidfp"/>
+    <text id="PsArundP" order="1150PsArundP"/>
+    <text id="PsOrne" order="1150PsOrne"/>
+    <text id="thebes1" order="1150thebes1"/>
+    <text id="thebes2" order="1150thebes2"/>
+    <text id="brut2" order="1155brut2"/>
+    <text id="ChronSMichelBo" order="1155ChronSMichelBo"/>
+    <text id="eneas1" order="1155eneas1"/>
+    <text id="eneas2" order="1155eneas2"/>
+    <text id="floire_jl" order="1155floire_jl"/>
+    <text id="cambps" order="1157cambps"/>
+    <text id="pyrame" order="1157pyrame"/>
+    <text id="mf" order="1160mf"/>
+    <text id="CommPsia1a" order="1164CommPsia1a"/>
+    <text id="ProvSerlo" order="1165ProvSerlo"/>
+    <text id="philomena" order="1167philomena"/>
+    <text id="ErecKu" order="1170ErecKu"/>
+    <text id="narcisse_lai" order="1170narcisse_lai"/>
+    <text id="rou1" order="1170rou1"/>
+    <text id="rou2" order="1170rou2"/>
+    <text id="becket" order="1173becket"/>
+    <text id="BenDuc1b" order="1174BenDuc1b"/>
+    <text id="Fantosme" order="1174Fantosme"/>
+    <text id="thomas" order="1174thomas"/>
+    <text id="MirNDOrl" order="1175MirNDOrl"/>
+    <text id="RecMedJute" order="1175RecMedJute"/>
+    <text id="CligesKu" order="1176CligesKu"/>
+    <text id="CharretteKu" order="1179CharretteKu"/>
+    <text id="YvainKu" order="1179YvainKu"/>
+    <text id="beroul" order="1180beroul"/>
+    <text id="eracle" order="1180eracle"/>
+    <text id="renart1" order="1180renart1"/>
+    <text id="adgar" order="1183adgar"/>
+    <text id="BrutCist" order="1183BrutCist"/>
+    <text id="DialGreg1" order="1183DialGreg1"/>
+    <text id="DialGreg2" order="1183DialGreg2"/>
+    <text id="EpMontDeu" order="1183EpMontDeu"/>
+    <text id="guingamor" order="1183guingamor"/>
+    <text id="orange" order="1183orange"/>
+    <text id="PercevalKu" order="1183PercevalKu"/>
+    <text id="RecCoulTit" order="1183RecCoulTit"/>
+    <text id="RegleSBenCotton" order="1183RegleSBenCotton"/>
+    <text id="SBernAn" order="1183SBernAn"/>
+    <text id="SermMadn" order="1183SermMadn"/>
+    <text id="cobe" order="1185cobe"/>
+    <text id="SBernCant" order="1187SBernCant"/>
+    <text id="graelent" order="1189graelent"/>
+    <text id="BlondNesle" order="1190BlondNesle"/>
+    <text id="espine" order="1190espine"/>
+    <text id="melion" order="1190melion"/>
+    <text id="qlr" order="1190qlr"/>
+    <text id="tydorel" order="1190tydorel"/>
+    <text id="vidame" order="1190vidame"/>
+    <text id="bodelnic" order="1195bodelnic"/>
+    <text id="amiamil" order="1200amiamil"/>
+    <text id="conttyr_a" order="1200conttyr_a"/>
+    <text id="DialAme" order="1200DialAme"/>
+    <text id="Elucidaireiii" order="1200Elucidaireiii"/>
+    <text id="SAgnesDob" order="1200SAgnesDob"/>
+    <text id="escoufle" order="1201escoufle"/>
+    <text id="desire" order="1205desire"/>
+    <text id="villehardouin1" order="1206villehardouin1"/>
+    <text id="villehardouin2" order="1206villehardouin2"/>
+    <text id="belinc" order="1207belinc"/>
+    <text id="lecheor" order="1209lecheor"/>
+    <text id="nabaret" order="1209nabaret"/>
+    <text id="clari" order="1210clari"/>
+    <text id="dole" order="1210dole"/>
+    <text id="trot" order="1210trot"/>
+    <text id="aucassin" order="1212aucassin"/>
+    <text id="galeran" order="1212galeran"/>
+    <text id="tyolet" order="1212tyolet"/>
+    <text id="doon" order="1215doon"/>
+    <text id="renart10" order="1216renart10"/>
+    <text id="renart11" order="1216renart11"/>
+    <text id="ombre" order="1220ombre"/>
+    <text id="bibleberze" order="1221bibleberze"/>
+    <text id="gcoin1" order="1222gcoin1"/>
+    <text id="gcoin2" order="1222gcoin2"/>
+    <text id="gcoin3" order="1222gcoin3"/>
+    <text id="gcoin4" order="1222gcoin4"/>
+    <text id="SEustPr1" order="1225SEustPr1"/>
+    <text id="tdechamp" order="1226tdechamp"/>
+    <text id="qgraal_cm" order="1227qgraal_cm"/>
+    <text id="rosel" order="1227rosel"/>
+    <text id="violette" order="1228violette"/>
+    <text id="fournival" order="1230fournival"/>
+    <text id="merlin_suite_litt" order="1232merlin_suite_litt"/>
+    <text id="jehan" order="1235jehan"/>
+    <text id="SLambert" order="1242SLambert"/>
+    <text id="edconfcambr" order="1245edconfcambr"/>
+    <text id="ImMondePrK" order="1246ImMondePrK"/>
+    <text id="sarrasin" order="1249sarrasin"/>
+    <text id="atrper" order="1250atrper"/>
+    <text id="bestam" order="1250bestam"/>
+    <text id="chartes_aube13" order="1250chartes_aube13"/>
+    <text id="chartes_hain13" order="1250chartes_hain13"/>
+    <text id="ChirAlbT" order="1250ChirAlbT"/>
+    <text id="OrnDamesR" order="1250OrnDamesR"/>
+    <text id="raoul" order="1250raoul"/>
+    <text id="vergy" order="1250vergy"/>
+    <text id="menreims" order="1260menreims"/>
+    <text id="MirNDChartr" order="1262MirNDChartr"/>
+    <text id="RutebZ" order="1267RutebZ"/>
+    <text id="mestiersparis" order="1268mestiersparis"/>
+    <text id="trispr" order="1270trispr"/>
+    <text id="rosem1" order="1274rosem1"/>
+    <text id="rosem2" order="1274rosem2"/>
+    <text id="rosem3" order="1274rosem3"/>
+    <text id="SBath1" order="1275SBath1"/>
+    <text id="SGenPr1" order="1275SGenPr1"/>
+    <text id="grchron1" order="1277grchron1"/>
+    <text id="roisin" order="1280roisin"/>
+    <text id="JAntInv" order="1282JAntInv"/>
+    <text id="JAntRect" order="1282JAntRect"/>
+    <text id="beauma1" order="1283beauma1"/>
+    <text id="SGenPr3" order="1287SGenPr3"/>
+    <text id="joinville" order="1307joinville"/>
+    <text id="fauvel" order="1310fauvel"/>
+    <text id="fouke" order="1317fouke"/>
+    <text id="passbonnes" order="1317passbonnes"/>
+    <text id="passpal" order="1317passpal"/>
+    <text id="plaidsmortemer" order="1320plaidsmortemer"/>
+    <text id="moree" order="1322moree"/>
+    <text id="sardos" order="1324sardos"/>
+    <text id="prunier" order="1325prunier"/>
+    <text id="SBath4" order="1335SBath4"/>
+    <text id="magloire3" order="1337magloire3"/>
+    <text id="grchron9" order="1340grchron9"/>
+    <text id="GuillMachFortuneH" order="1341GuillMachFortuneH"/>
+    <text id="GuillMachLyonH" order="1342GuillMachLyonH"/>
+    <text id="ChaceOisiiT" order="1350ChaceOisiiT"/>
+    <text id="GuillMachPlourH" order="1350GuillMachPlourH"/>
+    <text id="prov" order="1350prov"/>
+    <text id="hlanc" order="1354hlanc"/>
+    <text id="daudin" order="1365daudin"/>
+    <text id="SGenPr2" order="1367SGenPr2"/>
+    <text id="Berin1" order="1370Berin1"/>
+    <text id="Berin2" order="1370Berin2"/>
+    <text id="oresme" order="1370oresme"/>
+    <text id="grchron_j2c5" order="1381grchron_j2c5"/>
+    <text id="regcrim1" order="1390regcrim1"/>
+    <text id="regcrim2" order="1390regcrim2"/>
+    <text id="dictier" order="1392dictier"/>
+    <text id="melusine" order="1392melusine"/>
+    <text id="menagier" order="1393menagier"/>
+    <text id="griseld" order="1395griseld"/>
+    <text id="maniere1396" order="1396maniere1396"/>
+    <text id="anglure" order="1398anglure"/>
+    <text id="maniere1399" order="1399maniere1399"/>
+    <text id="dizsages" order="1400dizsages"/>
+    <text id="ponthus" order="1400ponthus"/>
+    <text id="QJoyesKa" order="1400QJoyesKa"/>
+    <text id="froissart1" order="1402froissart1"/>
+    <text id="gerson_trinite" order="1402gerson_trinite"/>
+    <text id="cdo_peche" order="1404cdo_peche"/>
+    <text id="CoutHector1" order="1404CoutHector1"/>
+    <text id="pizan_charlesv1" order="1404pizan_charlesv1"/>
+    <text id="pizan_charlesv2" order="1404pizan_charlesv2"/>
+    <text id="donait" order="1405donait"/>
+    <text id="CoutRoum" order="1407CoutRoum"/>
+    <text id="baye1" order="1409baye1"/>
+    <text id="baye2" order="1409baye2"/>
+    <text id="LaurPremCas2_l6" order="1409LaurPremCas2_l6"/>
+    <text id="DocSMichel_a" order="1411DocSMichel_a"/>
+    <text id="cdo_retenue" order="1414cdo_retenue"/>
+    <text id="cdo_ballades" order="1415cdo_ballades"/>
+    <text id="maniere1415" order="1415maniere1415"/>
+    <text id="SBath3" order="1417SBath3"/>
+    <text id="quadrilogue" order="1422quadrilogue"/>
+    <text id="parlangl" order="1425parlangl"/>
+    <text id="morchesne" order="1426morchesne"/>
+    <text id="cdo_complaintes" order="1433cdo_complaintes"/>
+    <text id="SGenPr4" order="1433SGenPr4"/>
+    <text id="cdo_songe" order="1437cdo_songe"/>
+    <text id="ursins" order="1438ursins"/>
+    <text id="cdo_rondeaux" order="1443cdo_rondeaux"/>
+    <text id="monstre" order="1443monstre"/>
+    <text id="VidPierrePetit" order="1444VidPierrePetit"/>
+    <text id="louis11_215" order="1450louis11_215"/>
+    <text id="SBath2" order="1450SBath2"/>
+    <text id="SGenPr5" order="1450SGenPr5"/>
+    <text id="coutpoit_a" order="1451coutpoit_a"/>
+    <text id="saintre" order="1456saintre"/>
+    <text id="artois" order="1460artois"/>
+    <text id="jouvencel1" order="1461jouvencel1"/>
+    <text id="jouvencel2" order="1461jouvencel2"/>
+    <text id="villon" order="1461villon"/>
+    <text id="cnn" order="1462cnn"/>
+    <text id="pathelin" order="1462pathelin"/>
+    <text id="louis11_223" order="1463louis11_223"/>
+    <text id="louis11_234" order="1467louis11_234"/>
+    <text id="quenouilles1" order="1468quenouilles1"/>
+    <text id="louis11_248" order="1470louis11_248"/>
+    <text id="quenouilles2" order="1470quenouilles2"/>
+    <text id="passauv" order="1477passauv"/>
+    <text id="archier" order="1479archier"/>
+    <text id="theologie" order="1479theologie"/>
+    <text id="tringant" order="1480tringant"/>
+    <text id="mirsnicjuif" order="1483mirsnicjuif"/>
+    <text id="molinet1" order="1490molinet1"/>
+    <text id="jehpar" order="1494jehpar"/>
+    <text id="ressource" order="1494ressource"/>
+    <text id="phares" order="1496phares"/>
+    <text id="commyn1" order="1497commyn1"/>
+    <text id="commyn2" order="1497commyn2"/>
+    <text id="commyn3" order="1497commyn3"/>
+    <text id="commyn4" order="1497commyn4"/>
+    <text id="commyn5" order="1497commyn5"/>
+    <text id="commyn6" order="1497commyn6"/>
+    <text id="commyn7" order="1497commyn7"/>
+    <text id="commyn8" order="1497commyn8"/>
+    <text id="vigneulles" order="1510vigneulles"/>
+  </xsl:variable>
+  
+</xsl:stylesheet>

Property changes on: TXM/trunk/org.txm.conllu.core/groovy/org/txm/scripts/importer/conllu/tigerXml-sortBfmByDate.xsl
___________________________________________________________________
Added: svn:mime-type
   + text/plain

Index: TXM/trunk/org.txm.conllu.core/groovy/org/txm/scripts/importer/conllu/conll2tiger-ud.pl
===================================================================
--- TXM/trunk/org.txm.conllu.core/groovy/org/txm/scripts/importer/conllu/conll2tiger-ud.pl	(revision 0)
+++ TXM/trunk/org.txm.conllu.core/groovy/org/txm/scripts/importer/conllu/conll2tiger-ud.pl	(revision 3567)
@@ -0,0 +1,1183 @@
+#!/usr/bin/perl
+
+use File::Basename;
+
+my $CMD      = "conll2tiger.pl";
+my $VERSION  = "1.5";
+my $MODIFIED = "8/12/2015";        # angepasst für Perseus CoNLL erzeugt mit conll.pl -l.  CHECK: funktioniert SRCMF noch?
+
+# columns (default are the predicted values in CoNLL 2009 format)
+my $coll   = 2;                    # lemma
+my $colm   = 3;                    # morph (pos)
+my $colf   = 5;                    # features
+my $colh   = 6;                    # head
+my $cold   = 7;                    # deprel
+my $outdir = "conllexport";        # deprel
+my $split  = 1000;                 # split output after nr sentences
+
+# tree structure
+my %dominates          = ();
+my %deprel             = ();                                         # deprel{nr} = deprel
+my @daughters          = ();                                         # daughter nodes, stored in %dominates
+my %duplicates         = my %relators = my %notes = my %aux = ();    # store nodes of duplicates, relators
+my $type               = "--";                                       # node attribute
+my $vform              = my $vlemma = "--";                          # node attributes for verbs store form and lemma
+my $label              = "D";                                        # default edge label
+my $nt_features_header = '';                                         # option -x
+my $nt_features        = '';                                         # option -x
+my $nt_empty_features  = '';                                         # option -x
+my @scodes             = ();                                         # option -x
+my $add_to_sentcode    = '';
+my $rootname           = 'root';                                     # default
+my $featcol            = 13;
+
+######################################################################
+#  conll2tiger.pl: converts CoNLL-U from the Universal Dependecies
+#  treebanks to TigerXML
+#          Achim Stein <achim.stein@ling.uni-stuttgart.de>
+# License : GNU GPL v. 3 (see the LICENSE file)
+######################################################################
+# TO DO:
+# - coordination
+# - Umgang mit zu langen, gesplitteten Sätzen (conll.pl -r 100)
+#   - dafür wurde als Wort-ID statt $w (for-Zähler) $wnr verwendet
+#   - es gibt aber noch unbound nodes wenn Regens entfernt (im anderen Teil) ist
+######################################################################
+# Modifications by Alexei Lavrentiev <alexei.lavrentev@ens-lyon.fr>
+# for Profiterole project (2019-2021)
+
+# 2019-09-25
+# - updated default column numbers for CONNL-U SRCMF format
+# - added processing for comment lines
+# - added @textid to terminal nodes
+# - deleted ppos, pmor et plemma (predicted tags and lemmas)
+# - replaced specific SRCMF with standard UD tags
+
+# Update 2020-05-13
+# - added @editionId for synchronization with BFM word ID
+
+# Update 2021-03-22
+# - using $infilename for @textid
+# - added support for .conllu extension
+
+# Update 2021-03-29
+# - added editionId to declarations in main.xml
+
+# Update 2021-07-16
+# - added "punct" to cat values
+
+# Update 2021-07-20
+# - added cat value list compiled from
+#   https://universaldependencies.org/ext-dep-index.html and the previous
+#   version. All relation types and subtypes from the UD 2.8 corpora
+#   should be there.
+# - contractions indexed
+######################################################################
+
+my $HELP = "
+==================================================================
+$CMD $VERSION: Help
+==================================================================
+FUNKTION: converts CoNLL parser output to TigerXML (for mate tools)
+          creates master file, splits input files, corrects unbound nodes
+SYNTAX:      $CMD [Options] <CoNLL file>
+OPTIONEN:
+ -c          ignore coordination (delete coordx- prefix in deprel)
+ -C str      corpus specials: nca
+ -h          show help
+ -o          create all files in this output directory (default: $outdir)
+set COLUMNS for required info (0 = column 1, 1 = column 2, etc.)
+ -D nr       colum for deprel default=$cold
+ -H nr       colum for head default=$colh
+ -M nr       colum for morphology (POS) default=$colm
+ -F nr       colum for morph. features default=$colf
+ -R str      Root category (default: $rootname)
+ -s nr       split output files after each nr sentence (default = $split)
+ -x str,...  include these attributes if present in the -X column of the first word
+             (the first code is also copied into the sentence id)
+ -X nr       the column where attributes are stored (default: $featcol)
+EXAMPLE:
+  - For mate parser output: no further options required
+    $CMD parsed.conll
+  - For Le Monde 2005: include attributes
+    gunzip -c parsed.conll.gz | conll2tiger.pl -x date,artnr,rubr
+  - For NCA:
+    conll2tiger.pl -C nca -x id,deaf,titreDees,editionDees,manuscritDees,regionDees,coefficientRegionDees,dateMoyenneDees,codeRegional,coefficientRegional,vers,ponctuation,mots,passage,commentairePhilologique,qualite,sourceQualite,commentaireForme,auteur,dateComposition,dateManuscrit,lieuComposition,lieuManuscrit,sourceDateComposition,sourceDateManuscrit,sourceLieuComposition,sourceLieuManuscrit,genre,traditionTextuelle,analyses,lignes,editionNCA tagged-oldfrench-lrec2014-dep.conll
+";
+
+###########################################################################
+#                    DO NOT MODIFY FOLLOWING CODE !
+###########################################################################
+
+###########################################################################
+# parse the command line
+###########################################################################
+
+use Getopt::Std;
+getopts('c:C:hD:H:M:o:R:s:x:X:');
+
+if ( defined($opt_h) ) {
+	print STDERR "$HELP";
+	exit(0);
+}
+
+if ( defined($opt_o) ) {
+	$outdir = $opt_o;
+}
+if ( defined($opt_C) ) {
+	$corpus = $opt_C;
+}
+if ( defined($opt_D) ) {
+	$cold = $opt_D;
+}
+if ( defined($opt_H) ) {
+	$colh = $opt_H;
+}
+if ( defined($opt_M) ) {
+	$colm = $opt_M;
+}
+
+if ( defined($opt_R) ) {
+	$rootname = $opt_R;
+}
+
+if ( defined($opt_s) ) {
+	$split = $opt_s;
+}
+
+if ( defined($opt_X) ) {
+	$featcol = $opt_X;
+}
+
+if ( defined($opt_x) ) {
+	@scodes = split( ",", $opt_x );
+	for ( my $i = 0 ; $i <= $#scodes ; $i++ ) {
+		$nt_features_header = $nt_features_header . sprintf( "<feature name=\"%s\" domain=\"NT\"></feature>\n", $scodes[$i] );
+	}
+	$nt_features_header =~ s/\bid\b/ncaid/;    # avoid reserved Tiger attribute "id"
+}
+
+my @colnames = ( "url", "ID", "FORM", "LEMMA", "PLEMMA", "POS", "PPOS", "FEAT", "PFEAT", "HEAD", "PHEAD", "DEPREL", "PDEPREL" );
+
+# my %pos = %lemma = %form = %deprel = %head = %governs = %cat2abbrev = %abbrev2cat = %coordnr_cat = %coordnr_head = %w_coordnr = %w_head = %w_deprel = %first_coordnr = %coordnr_first = %verb_head = ();
+my @coordelements = ();
+
+my $id = my $form = my $lemma = my $plemma = my $pos = my $ppos = my $feat = my $pfeat = my $head = my $phead = my $deprel = my $pdeprel = my $edition_id = "";
+
+my $timestamp = gmtime();
+chomp($timestamp);
+
+my $infile = $ARGV[0];
+$infile =~ s/\.conllu?//i;
+if ( $infile eq '' ) {
+	$infile = 'subcorpus';
+}
+#MD disable the counter and suffix variables and file renaming "$infilename-$suffix" -> "$infilename"
+#my $counter = 1;
+#$suffix = sprintf( "%05d", $counter );
+$infilename = basename($infile);
+
+mkdir("$outdir");
+open( XML, ">$outdir/$infilename.xml" )
+  or die "\nopen file error of $outdir/$infilename.xml\n";
+open( LOG, ">$outdir/conversion.log" )
+  or die "\nopen file error of conversion.log\n";
+open( MASTER, ">$outdir/main.xml" ) or die "\nopen file error of main.xml\n";
+write_xml_header();
+write_master_header();
+
+# flush output for log and master file
+select(LOG);
+$| = 1;
+select(MASTER);
+$| = 1;
+
+$commandline = $0 . " " . ( join " ", @ARGV );
+print LOG "$commandline\n\n";
+
+print MASTER "<subcorpus name='$infilename' external='file:$infilename.xml'/>\n";
+
+$/ = "";    # treat empty line as RS
+while (<>) {
+	if ( $. % $split == 0 ) {
+		print XML "</subcorpus>\n";
+		close(XML);
+		#$suffix = sprintf( "%05d", ++$counter );
+		open( XML, ">$outdir/$infilename.xml" )
+		  or die "\nopen file error\n";
+		write_xml_header();
+		print MASTER "<subcorpus name='$infilename' external='file:$infilename.xml'/>\n";
+	}
+
+	# ----------------------------------------
+	# set root (or fake root if ROOT is missing)
+	# ----------------------------------------
+	$rootnode = $fakeroot = 0;    # m = Treat string as multiple lines, so that ^ matches beginning of line
+	$thisrootname = $rootname;
+	($rootnode) = (/^(\d+?)\s.*?\b$rootname\b/m);    # real root marked by parser
+	if ( $rootnode == 0 ) {
+
+		#    ($rootnode) = (/^(\d+?)\t.*?\t-1\t0\t/m);  # no marked ROOT, but top node (head = 0)   TOO SPECIFIC
+		#    ($rootnode) = (/^(\d+?)\t.*?\t.*?\t.*?\t.*?\t.*?\t.*?\t.*?\t0\t/m);  # no marked ROOT, but top node (head = 0) in col9 (original by Achim Stein)
+		($rootnode) = (/^(\d+?)\t.*?\t.*?\t.*?\t.*?\t.*?\t0\t/m);                                     # no marked ROOT, but top node (head = 0) in col7 (updated by AL)
+		print LOG " Warning sentence $.: not marked root ($rootname), using top node $rootnode\n";
+		$fakeroot     = 1;
+		$thisrootname = 'nSnt';
+	}
+	if ( $rootnode == 0 ) {
+		$rootnode = 1;                                                                                # set fake root if nothing goes
+		print LOG " Error sentence $.: setting fake root to first word:\n$_\n";
+		$fakeroot     = 2;
+		$thisrootname = 'Err';
+	}
+
+	my @cols = ();
+	@words     = split(/\n/);
+	@terminals = ();
+
+	%dominates = ();                                                                                  # empty at beginning of sentence
+	%deprel    = ();                                                                                  # empty at beginning of sentence
+	%aux       = ();                                                                                  # empty at beginning of sentence
+	@daughters = ();
+
+	my $commentlines = 0;                                                                             #added by AL
+
+	#  my $contractions = 0; #added by AL
+	#  my $text_id = "unknown_text";
+	my $text_id = $infilename;
+	my $sent_id = "0";
+
+	# ----------------------------------------
+	# loop through words #1: write tokens (terminal nodes) to XML file
+	# store tree relevant information for loop #2
+	# ----------------------------------------
+	for ( my $w = 0 ; $w <= $#words ; $w++ ) {
+
+		# Added by AL for comment lines
+		if ( $words[$w] =~ /^#/ ) {
+			if ( $words[$w] =~ /^# newdoc/ ) {
+				$text_id = $words[$w];
+				$text_id =~ s/# newdoc id = //;
+			}
+			elsif ( $words[$w] =~ /^# sent_id/ ) {
+				$sent_id = $words[$w];
+				$sent_id =~ s/# sent_id = //;
+			}
+
+			#	print LOG "Comment line loop 1: $words[$w]\n";
+			$commentlines++;
+			next;
+		}
+		# Added by AL for contractions
+		elsif ( $words[$w] =~ /^\d+-\d+/ ) {
+
+			#	print LOG "Contraction line loop 1: $words[$w]\n";
+			$commentlines++;
+
+			#	$contractions++;
+			next;
+		}
+		else {
+			if ( defined($opt_c) ) {
+				$words[$w] =~ s/coord(\d+)-//g;
+			}
+			@cols       = split( /\t/, $words[$w] );
+			$wnr        = $cols[0];
+			$word       = $cols[1];
+			$lemma      = $cols[2];
+			$plemma     = $cols[2];                    # predicted
+			$pos        = $cols[3];
+			$ppos       = $cols[4];                    # predicted
+			$mor        = $cols[5];
+			$pmor       = $cols[5];                    # predicted
+			$cat        = $cols[$cold];
+			$edition_id = $cols[9];
+			$edition_id =~ s/^.*XmlId=([^|]+).*$/\1/g;
+
+			if ( $cat =~ /[<>]/ ) {
+				print LOG "Warning in line $.: illegal node name: \"$cat\" -> \"Err2\"\n";
+				$cat = 'Err2';
+			}
+
+			# NCA: enclose lemmas in underscores (easier for regex construction)
+			if ( $corpus =~ /nca/i ) {
+				$lemma = "_" . "$lemma" . "_";
+			}
+
+			clean_data();
+
+			# get attribute-value pairs from col #13 of first word (option -x)
+			if ( $opt_x == "all" ) {
+				$cols[$featcol] = "all=" . $cols[$featcol];
+			}
+			if ( $w == 0 && $cols[$featcol] =~ /=/ ) {
+
+				#      print STDERR "========== getting att-value for word $w: $cols[$featcol] scodes=@scodes\n";
+				$nt_features = $nt_empty_features = '';
+
+				#      while($cols[$featcol] =~ m/ (.*?)="([^"]*)"/gs) {   # quoted values
+				while ( $cols[$featcol] =~ m/ ?([^=]*?)="?([^, ]+)\b"?\b/gs ) {    # maybe unquoted values (e.g. Le Monde 2005)
+					$att = $1;
+					$val = $2;
+
+					# pick the attributes that match those of the command line option -x
+					for ( my $t = 0 ; $t <= $#scodes ; $t++ ) {
+						if ( $att eq $scodes[$t] ) {
+							$val =~ s/\&/\&amp;/g;                                 #  replace "&" in values (appears in URLs)
+							if ( $t == 0 ) { $add_to_sentcode = "_$att$val"; }
+							$nt_features = $nt_features . " $att=\"$val\"";
+
+							#	    print STDERR "$./$w/$featcol: $cols[$featcol] --- nt_features: $nt_features\n";
+						}
+						if ( $att eq $scodes[$t] ) {
+							$nt_empty_features = $nt_empty_features . " $att=\"--\"";
+						}
+					}
+				}
+
+				# replace the reserved feature 'id' (Tiger)
+				$add_to_sentcode =~ s/\bid=/ncaid=/;
+				$nt_features =~ s/\bid=/ncaid=/;
+				$nt_empty_features =~ s/\bid=/ncaid=/;
+			}    # if col 13 contains attributes
+			else {
+				if ( defined($opt_x) && ( $w == 0 ) ) {
+					print STDERR "Warning: sentence=$.  option -x is defined, but no attribute=value declarations were found!\n";
+				}
+			}
+
+			# store output for terminal node in array, output later. For double categories make a duplicate node.
+			$tempid = sprintf( "%d_%d", $., $wnr );
+
+#    push(@terminals, sprintf("      <t id=\"s%d_%d\" word=\"%s\" pos=\"%s\" mor=\"%s\" lemma=\"%s\" ppos=\"%s\" pmor=\"%s\" plemma=\"%s\" textid=\"%s\" editionId=\"%s\"/>\n", $., $wnr, $word, $pos, $mor, $lemma, $ppos, $pmor, $plemma, $text_id, $edition_id));
+			push( @terminals,
+				sprintf( "      <t id=\"s%d_%d\" word=\"%s\" pos=\"%s\" mor=\"%s\" lemma=\"%s\" textid=\"%s\" editionId=\"%s\"/>\n", $., $wnr, $word, $pos, $mor, $lemma, $text_id, $edition_id ) );
+			if ( $cat =~ /_/ ) {
+
+#      push(@terminals, sprintf("      <t id=\"s%d_%d_dupl\" word=\"%s\" pos=\"%s\" mor=\"%s\" lemma=\"%s\" ppos=\"%s\" pmor=\"%s\" plemma=\"%s\" textid=\"%s\" editionId=\"%s\"/>\n", $., $wnr, "*", "_", "_", "_", "_", "_", "_", $text_id, $edition_id));
+				push( @terminals,
+					sprintf( "      <t id=\"s%d_%d_dupl\" word=\"%s\" pos=\"%s\" mor=\"%s\" lemma=\"%s\" textid=\"%s\" editionId=\"%s\"/>\n", $., $wnr, "*", "_", "_", "_", $text_id, $edition_id ) );
+				$duplicates{$tempid} = 1;    # store, check later to attach the duplicates to the mother
+			}
+
+			# associate Aux with main verb, to create an attribute in the verb node in loop #2 (TODO: more than one Aux)
+			if ( $cat =~ /Aux/ ) {
+				$aux{ $cols[$colh] } = "$word" . "_" . "$plemma";    # $aux{head} = word_lemma (of Aux)
+			}
+
+			# ----------------------------------------
+			# store information needed for tree
+			# ----------------------------------------
+			# if fake rootnode == 1: nSnt as root node
+			if ( ( $fakeroot == 1 ) && ( $w - $commentlines + 1 == $rootnode ) ) {
+				$cat = 'nSnt';
+				$notes{$tempid} = 'Warning no marked ROOT node in CoNLL';    # TODO: geht nicht
+			}
+
+			# if fake rootnode == 2: flatten structure: attach all words to the first word
+			if ( ( $fakeroot == 2 ) && ( $w - $commentlines + 1 != $rootnode ) ) {
+				$cols[$colh] = 1;
+				$notes{$tempid} = 'Error neither ROOT node nor top node in CoNLL';
+			}
+
+			# correct unbound words in parser output (phead = 0, but not marked as ROOT)
+			if (   ( $cols[$colh] eq "0" )
+				&& ( $w - $commentlines + 1 != $rootnode ) )
+			{    #AL: added: -$commentlines
+				printf LOG
+				  " Warning sentence $. ($tempid): unbound node %d (attached to root %d)\n",
+				  ( $w - $commentlines + 1 ), $rootnode;
+				$cols[$colh]    = $rootnode;
+				$cat            = 'Err';                             # let Err instead of deprel appear in dom attribute
+				$notes{$tempid} = 'Warning unbound node in CoNLL';
+			}
+
+			# store for R edge labels
+			if ( $cols[$cold] =~ /RelN?C/ ) {
+				$relators{$tempid} = 1;
+			}
+
+			# store deprel for dom attribute
+			$deprel{$tempid} = $cat;                                 # $cols[$cold];
+			                                                         # if real root, add this node to daughter array, store array in hash dominates{head}{@daughters}
+			if ( ( $fakeroot < 2 ) && ( $w - $commentlines + 1 != $rootnode ) ) {
+				@daughters = @{ $dominates{ $cols[$colh] } };        # get the array from the hash of the dominating node
+				push( @daughters, $wnr );
+				$dominates{ $cols[$colh] } = [@daughters];
+			}
+		}    # for each word loop #1
+	}    # AL condition end
+
+	# print graph code (needs root attribute) and terminal nodes
+	if ( $rootnode == 0 ) {
+		$noroot++;
+		print LOG "Error sentence $. ($tempid): root node not found:\n$_\n";
+		next;
+	}
+	else {
+		printf XML "<s id=\"s%s%s\" textid=\"$text_id\" sentid=\"$sent_id\">\n", $., $add_to_sentcode;
+		print XML "  <graph root=\"n$._$rootnode\">\n";
+		print XML "    <terminals>\n";
+		for ( my $t = 0 ; $t <= $#terminals ; $t++ ) {
+			print XML $terminals[$t];
+		}
+		print XML "    </terminals>\n";
+	}
+
+	# ----------------------------------------
+	# loop through words #2 to build Tiger tree (non terminal nodes)
+	# ----------------------------------------
+	print XML "    <nonterminals>\n";
+	for ( my $i = 0 ; $i <= $#words ; $i++ ) {
+
+		#Added AL for comment lines
+		if ( $words[$i] =~ /^#/ ) {
+
+			#       print LOG "Comment line loop 2 : $words[$i]\n";
+			next;
+		}
+
+		#Added AL for contractions
+		if ( $words[$i] =~ /^\d+-\d+/ ) {
+
+			#       print LOG "Contraction loop 2 : $words[$i]\n";
+			next;
+		}
+
+		else {
+
+			@cols = split( /\t/, $words[$i] );
+			$w = $cols[0];
+			### TODO: redundante Variablenzuweisung (= loop #1)??
+			$word   = $cols[1];
+			$lemma  = $cols[2];
+			$plemma = $cols[3];       # predicted
+			$pos    = $cols[4];
+			$ppos   = $cols[5];       # predicted
+			$mor    = $cols[6];
+			$pmor   = $cols[7];       # predicted
+			$cat    = $cols[$cold];
+
+			if ( $cat =~ /[<>]/ ) {
+				print Log "Warning in line $.: illegal node name: \"$cat\" -> \"Err2\"\n";
+				$cat = 'Err2';
+			}
+
+			#  OF parser has not learned punctuation: set cat for punctuation to PON
+			if ( ( $corpus =~ /nca/i ) && ( $pos eq 'PON' ) ) {
+				$cols[$cold] = $cat = 'Pon';
+			}
+
+			clean_data();
+
+			# retrieve daughters, make dom attribute (string of dominated nodes)
+			@daughters = @{ $dominates{"$w"} };
+			$dom       = '';
+			for ( my $d = 0 ; $d <= $#daughters ; $d++ ) {
+				$dom = $dom . "_" . $deprel{"$._$daughters[$d]"};
+			}
+			if ( $dom =~ /_/ ) {
+				$dom =~ s/^_//;
+			}
+			else {
+				$dom = '--';
+			}
+
+			# if verbal, set node attributes for verb form and lemma
+			$type = "nV";
+			$vform = $vlemma = "--";
+			if ( $pos =~ /VER/ ) {    # AL: $ppos -> $pos
+				if    ( $mor =~ /infi/ )       { $type = "VInf"; }    #AL: $pmor -> $mor
+				elsif ( $pmor =~ /pper|ppre/ ) { $type = "VPar"; }
+				else                           { $type = "VFin"; }
+
+				# if Aux is present, create attribute for main verb
+				if ( $aux{$w} =~ /(.*?)_(.*)/ ) {
+					$vform  = "$1";
+					$vlemma = "$2";
+				}
+
+				# else create attr for simple verb
+				else {
+					$vform  = $word;
+					$vlemma = $lemma;    # AL: $plemma -> $lemma (always void in SRCMF)
+				}
+
+				# NCA: enclose lemmas in underscores (easier for regex construction)
+				if ( $corpus =~ /nca/i ) {
+					$vlemma = "_" . "$vlemma" . "_";
+				}
+			}
+
+			# call output function (twice for duplicate categories)
+			if ( $cat =~ /(.*?)_(.*)/ ) {
+				write_nonterminals( "$2", "" );         # RelNC is always node (see clean categories), function is duplicate, e.g. SjPer_RelNC
+				write_nonterminals( "$1", "_dupl" );    # other category is duplicate
+			}
+			else {
+				write_nonterminals($cat);
+			}
+		}    # for words
+	}    #AL end condition
+
+	print XML "    </nonterminals>\n";
+	print XML "  </graph>\n";
+	print XML "</s>\n";
+	if ( $. % 100 == 0 ) {
+		#print STDERR "\b\b\b\b\b\b\b\b";
+		#printf STDERR "%08d", $.;
+	}
+}    # main
+print XML "</subcorpus>\n";
+#print STDERR "\n$CMD: $. sentences converted. Results in $outdir. Log in $outdir/conversion.log.\n";
+#print STDERR "   Hint 1: on OS X convert master file to MacRoman, e.g  iconv -f latin1 -t macroman\n";
+#print STDERR "   Hint 2: use tiger.pl -c <Tiger XML file> to detect unbound nodes.\n";
+#print STDERR "   Hint 3: build reliable feature declarations using tiger.sh\n";
+#print STDERR "           tiger.sh -a \"lemma word pos ppos\"  (for terminals)\n";
+#print STDERR "           tiger.sh -A \"lemma word pos ppos\"  (for non-terminals)\n";
+
+if ( $noroot > 0 ) {
+	print STDERR "$noroot sentences ignored: root not found (see log file)\n";
+}
+write_master_footer();
+close(MASTER);
+close(XML);
+close(LOG);
+
+exit;
+
+# ----------------------------------------
+# sub
+# ----------------------------------------
+
+sub write_xml_header {
+	print XML "<?xml version=\"1.0\" encoding=\"UTF-8\"?>
+  <subcorpus name=\"$infilename\">
+";
+}
+
+sub write_master_header {
+	printf MASTER '<?xml version="1.0" encoding="UTF-8"?>
+';
+
+	printf MASTER "<corpus id=\"$corpus\">
+<head>
+  <meta><name>$corpus</name> 
+    <author>ILR Stuttgart</author> 
+    <date></date> 
+    <description>Parsed with mate tools using a SRCMF-based grammar model (http://srcmf.org). </description> 
+    <format>SRCMF</format>
+    <history>TigerXML converted by conll2tiger.pl</history>
+  </meta>
+";
+
+	#  printf MASTER '<annotation>
+	#<feature name="word" domain="T" ></feature>
+	#<feature name="pos" domain="T" ></feature>
+	#<feature name="mor" domain="T" ></feature>
+	#<feature name="lemma" domain="T" ></feature>
+	#<feature name="ppos" domain="T" ></feature>
+	#<feature name="pmor" domain="T" ></feature>
+	#<feature name="plemma" domain="T" ></feature>
+	#<feature name="cat" domain="NT" >
+	#  <value name="Apst">apostrophe</value>
+	#  <value name="AtObj">attribut d objet</value>
+	#  <value name="AtRfc">attribut réfléchi</value>
+	#  <value name="AtSj">attribut de sujet</value>
+	#  <value name="AttributReflechi">attribut réfléchi</value>
+	#  <value name="Aux">auxilié</value>
+	#  <value name="AuxA">auxilié actif</value>
+	#  <value name="AuxP">auxilié passif</value>
+	#  <value name="Circ">circonstant</value>
+	#  <value name="Circ_RelNC">circonstant pronom relatif</value>
+	#  <value name="Cmpl">complément</value>
+	#  <value name="Cmpl_RelNC">complément pronom relatif</value>
+	#  <value name="Coo">coordination</value>
+	#  <value name="Det">déterminant</value>
+	#  <value name="Err">unbound node in CoNLL input</value>
+	#  <value name="Err2">illegal node name was replaced</value>
+	#  <value name="GpCoo">coordonné</value>
+	#  <value name="Ignorer">Ignorer</value>
+	#  <value name="Insrt">incidente</value>
+	#  <value name="Intj">interjection</value>
+	#  <value name="Lac">lacune</value>
+	#  <value name="ModA">modifieur attaché</value>
+	#  <value name="ModD">modifieur détaché</value>
+	#  <value name="Ng">négation</value>
+	#  <value name="NgPrt">forclusif</value>
+	#  <value name="Obj">objet</value>
+	#  <value name="Obj_RelNC">direct object pronom relatif</value>
+	#  <value name="Pon">ponctuation</value>
+	#  <value name="PON">ponctuation</value>
+	#  <value name="Regim">régime</value>
+	#  <value name="RelC">relateur coordonnant</value>
+	#  <value name="RelNC">relateur non coordonnant</value>
+	#  <value name="Rfc">réfléchi</value>
+	#  <value name="Rfx">réfléxif renforcé</value>
+	#  <value name="SjImp">sujet impersonnel</value>
+	#  <value name="SjPer">sujet personnel</value>
+	#  <value name="SjPer_RelNC">sujet personnel pronom relatif</value>
+	#  <value name="Snt">phrase</value>
+	#  <value name="ROOT">phrase</value>
+	#  <value name="StructureMaximale">structure maximale</value>
+	#  <value name="VFin">verbe fini</value>
+	#  <value name="VInf">verbe infinitif</value>
+	#  <value name="nMax">structure non-maximale</value>
+	#  <value name="nSnt">non-phrase</value>
+	#</feature>
+	#<feature name="coord" domain="NT" ></feature>
+	#<feature name="dom" domain="NT" ></feature>
+	#<feature name="type" domain="NT" >
+	#  <value name="nV">élément non-verbal</value>
+	#  <value name="VFin">verbe fini</value>
+	#  <value name="VInf">verbe infinitif</value>
+	#  <value name="VPar">verbe participial</value>
+	#  <value name="--">nil</value>
+	#</feature>
+	#<feature name="vform" domain="NT"></feature>
+	#<feature name="vlemma" domain="NT"></feature>
+	#<feature name="note" domain="NT"></feature>
+	#<feature name="snr" domain="NT"></feature>
+	#';
+
+	printf MASTER '<annotation>
+<feature name="word" domain="T" ></feature>
+<feature name="pos" domain="T" ></feature>
+<feature name="mor" domain="T" ></feature>
+<feature name="lemma" domain="T" ></feature>
+<feature name="textid" domain="T" ></feature>
+<feature name="editionId" domain="T" ></feature>
+<feature name="cat" domain="NT" >
+  <value name="__UNDEF__">UNDEFINED !!!</value>
+  <value name="acl:adv">acl:adv</value> <!-- Ukrainian -->
+  <value name="acl:attr">acl:attr</value> <!-- Chukchi -->
+  <value name="acl:cleft">acl:cleft</value> <!-- Norwegian, Swedish -->
+  <value name="acl:fixed">acl:fixed</value> <!-- Beja -->
+  <value name="acl:inf">acl:inf</value> <!-- Portuguese -->
+  <value name="acl:relat">acl:relat</value> <!-- Chukchi -->
+  <value name="acl:relcl">relative clause modifier</value> <!-- Akkadian, Albanian, Apurina, Arabic, Armenian, Assyrian, Beja, Belarusian, Breton, Bulgarian, Chinese, Czech, Danish, Dutch, English, Erzya, Estonian, Faroese, Finnish, French, German, Greek, Hebrew, Hindi, Hindi English, Icelandic, Indonesian, Irish, Italian, Karelian, Kazakh, Komi Permyak, Komi Zyrian, Korean, Latin, Lithuanian, Livvi, Manx, Marathi, Moksha, Naija, North Sami, Norwegian, Old East Slavic, Old French, Persian, Polish, Portuguese, Russian, Sanskrit, Scottish Gaelic, Slovak, Spanish, Swedish, Swedish Sign Language, Swiss German, Tagalog, Tamil, Telugu, Thai, Ukrainian, Urdu, Welsh, Western Armenian, Wolof -->
+  <value name="acl">clausal modifier of noun (adnominal clause)</value>
+  <value name="advcl:abs">advcl:abs</value> <!-- Latin -->
+  <value name="advcl:cau">advcl:cau</value> <!-- Moksha -->
+  <value name="advcl:cleft">advcl:cleft</value> <!-- French, Naija -->
+  <value name="advcl:cmpr">advcl:cmpr</value> <!-- Latin, Polish -->
+  <value name="advcl:cond">advcl:cond</value> <!-- Tamil, Telugu, Uyghur -->
+  <value name="advcl:coverb">advcl:coverb</value> <!-- Cantonese -->
+  <value name="advcl:eval">advcl:eval</value> <!-- Komi Zyrian -->
+  <value name="advcl:lcl">advcl:lcl</value> <!-- Komi Permyak -->
+  <value name="advcl:lto">advcl:lto</value> <!-- Komi Zyrian -->
+  <value name="advcl:mcl">advcl:mcl</value> <!-- Komi Permyak -->
+  <value name="advcl:pred">advcl:pred</value> <!-- Latin -->
+  <value name="advcl:relcl">advcl:relcl</value> <!-- Polish, Western Armenian -->
+  <value name="advcl:sp">advcl:sp</value> <!-- Ukrainian -->
+  <value name="advcl:svc">advcl:svc</value> <!-- Ukrainian -->
+  <value name="advcl:tcl">advcl:tcl</value> <!-- Apurina, Erzya, Komi Permyak, Komi Zyrian, Moksha, Romanian, Skolt Sami -->
+  <value name="advcl">adverbial clause modifier</value>
+  <value name="advmod:arg">advmod:arg</value> <!-- Polish -->
+  <value name="advmod:cau">advmod:cau</value> <!-- Erzya, Komi Zyrian, Moksha -->
+  <value name="advmod:comp">advmod:comp</value> <!-- Erzya -->
+  <value name="advmod:deg">advmod:deg</value> <!-- Erzya, Komi Permyak, Komi Zyrian, Moksha, Skolt Sami -->
+  <value name="advmod:det">advmod:det</value> <!-- Ukrainian -->
+  <value name="advmod:df">advmod:df</value> <!-- Cantonese, Chinese -->
+  <value name="advmod:emph">emphasizing word, intensifier</value> <!-- Akkadian, Arabic, Armenian, Catalan, Chukchi, Croatian, Czech, Indonesian, Komi Zyrian, Latin, Lithuanian, Polish, Sanskrit, Slovak, South Levantine Arabic, Tamil, Turkish, Turkish German, Upper Sorbian, Uyghur, Western Armenian -->
+  <value name="advmod:eval">advmod:eval</value> <!-- Erzya, Komi Zyrian, Moksha, Skolt Sami -->
+  <value name="advmod:fixed">advmod:fixed</value> <!-- Beja -->
+  <value name="advmod:foc">advmod:foc</value> <!-- Erzya, Komi Zyrian, Moksha, Skolt Sami -->
+  <value name="advmod:freq">advmod:freq</value> <!-- Komi Zyrian, Moksha -->
+  <value name="advmod:lfrom">advmod:lfrom</value> <!-- Erzya, Komi Zyrian, Moksha -->
+  <value name="advmod:lmod">locative adverbial modifier</value> <!-- Apurina, Danish, Erzya, Komi Permyak, Komi Zyrian, Moksha, Skolt Sami -->
+  <value name="advmod:lmp">advmod:lmp</value> <!-- Erzya, Komi Zyrian -->
+  <value name="advmod:locy">advmod:locy</value> <!-- Hungarian -->
+  <value name="advmod:lto">advmod:lto</value> <!-- Erzya, Komi Zyrian, Moksha -->
+  <value name="advmod:mmod">advmod:mmod</value> <!-- Erzya, Komi Permyak, Komi Zyrian, Moksha, Skolt Sami -->
+  <value name="advmod:mode">advmod:mode</value> <!-- Hungarian -->
+  <value name="advmod:neg">advmod:neg</value> <!-- Apurina, Buryat, Kiche, Kurmanji, Latin, Maltese, Polish, Skolt Sami -->
+  <value name="advmod:obl">adverbial modifier + oblique nominal</value> <!-- Old French -->
+  <value name="advmod:que">advmod:que</value> <!-- Hungarian -->
+  <value name="advmod:tfrom">advmod:tfrom</value> <!-- Hungarian -->
+  <value name="advmod:tlocy">advmod:tlocy</value> <!-- Hungarian -->
+  <value name="advmod:tmod">advmod:tmod</value> <!-- Apurina, Erzya, Komi Permyak, Komi Zyrian, Moksha, Romanian, Skolt Sami -->
+  <value name="advmod:to">advmod:to</value> <!-- Hungarian -->
+  <value name="advmod:tto">advmod:tto</value> <!-- Hungarian -->
+  <value name="advmod">adverbial modifier</value>
+  <value name="amod:att">amod:att</value> <!-- Hungarian -->
+  <value name="amod:attlvc">amod:attlvc</value> <!-- Hungarian -->
+  <value name="amod:flat">amod:flat</value> <!-- Polish -->
+  <value name="amod">adjectival modifier</value>
+  <value name="appos:trans">appos:trans</value> <!-- Turkish German -->
+  <value name="appos">appositional modifier</value>
+  <value name="aux:aff">aux:aff</value> <!-- Beja -->
+  <value name="aux:aspect">aux:aspect</value> <!-- Komi Zyrian -->
+  <value name="aux:caus">aux:caus</value> <!-- Armenian, French, Western Armenian -->
+  <value name="aux:clitic">aux:clitic</value> <!-- Polish -->
+  <value name="aux:cnd">aux:cnd</value> <!-- Erzya, Komi Permyak, Komi Zyrian, Polish -->
+  <value name="aux:ex">aux:ex</value> <!-- Armenian, Western Armenian -->
+  <value name="aux:imp">aux:imp</value> <!-- Erzya, Polish -->
+  <value name="aux:nec">aux:nec</value> <!-- Komi Zyrian, Moksha, Skolt Sami -->
+  <value name="aux:neg">aux:neg</value> <!-- Chukchi, Erzya, Komi Permyak, Komi Zyrian, Maltese, Moksha, North Sami, Skolt Sami, Tamil -->
+  <value name="aux:opt">aux:opt</value> <!-- Erzya, Moksha -->
+  <value name="aux:part">aux:part</value> <!-- Maltese -->
+  <value name="aux:pass">passive auxilary</value> <!-- Afrikaans, Ancient Greek, Arabic, Assyrian, Belarusian, Bhojpuri, Breton, Bulgarian, Buryat, Chinese, Czech, Dutch, English, Faroese, Finnish, French, Frisian Dutch, Galician, German, Hindi, Italian, Kangri, Karelian, Latin, Latvian, Lithuanian, Maltese, Marathi, Norwegian, Old Church Slavonic, Old East Slavic, Old French, Persian, Polish, Portuguese, Romanian, Russian, Slovak, Spanish, Swedish, Swiss German, Tamil, Thai, Turkish German, Upper Sorbian, Vietnamese -->
+  <value name="aux:pot">aux:pot</value> <!-- Komi Zyrian -->
+  <value name="aux:q">aux:q</value> <!-- Erzya, Turkish, Turkish German -->
+  <value name="aux:tense">aux:tense</value> <!-- French, Komi Zyrian, Skolt Sami -->
+  <value name="aux">auxiliary</value>
+  <value name="case:acc">case:acc</value> <!-- Hebrew -->
+  <value name="case:adv">case:adv</value> <!-- Indonesian -->
+  <value name="case:aff">case:aff</value> <!-- Beja -->
+  <value name="case:det">preposition with determiner</value> <!-- Maltese, Old French -->
+  <value name="case:gen">case:gen</value> <!-- Hebrew -->
+  <value name="case:loc">case:loc</value> <!-- Armenian, Cantonese, Chinese, Western Armenian -->
+  <value name="case:pred">case:pred</value> <!-- Welsh -->
+  <value name="case:voc">case:voc</value> <!-- Irish, Scottish Gaelic -->
+  <value name="case">case marking</value>
+  <value name="cc:nc">cc:nc</value> <!-- Old French -->
+  <value name="cc:nc">Coordinated conjunct : non coordonant</value>
+  <value name="cc:preconj">cc:preconj</value> <!-- Arabic, English, Erzya, Estonian, Faroese, Finnish, German, Indonesian, Komi Permyak, Komi Zyrian, Moksha, North Sami, Persian, Polish, Portuguese, Romanian, Slovenian, Spanish, Thai, Turkish -->
+  <value name="cc:preconj">preconjunct</value>
+  <value name="cc">Coordinating conjunction</value>
+  <value name="cc">coordinating conjunction</value>
+  <value name="ccomp:cleft">ccomp:cleft</value> <!-- Polish -->
+  <value name="ccomp:obj">ccomp:obj</value> <!-- Hungarian, Polish -->
+  <value name="ccomp:obl">ccomp:obl</value> <!-- Hungarian -->
+  <value name="ccomp:pmod">ccomp:pmod</value> <!-- Romanian -->
+  <value name="ccomp:pred">ccomp:pred</value> <!-- Hungarian -->
+  <value name="ccomp">clausal complement</value>
+  <value name="clf">classifier</value>
+  <value name="compound:a">compound:a</value> <!-- Indonesian -->
+  <value name="compound:affix">compound:affix</value> <!-- Hebrew -->
+  <value name="compound:dir">compound:dir</value> <!-- Cantonese, Chinese -->
+  <value name="compound:ext">compound:ext</value> <!-- Cantonese, Chinese -->
+  <value name="compound:lvc">compound:lvc</value> <!-- Armenian, Hindi, Kazakh, Khunsari, Korean, Kurmanji, Marathi, Nayini, Persian, Soi, Tamil, Telugu, Turkish, Turkish German, Uyghur, Western Armenian -->
+  <value name="compound:lvc">light verb construction</value>
+  <value name="compound:nn">compound:nn</value> <!-- Finnish, Livvi, North Sami -->
+  <value name="compound:preverb">compound:preverb</value> <!-- Hungarian -->
+  <value name="compound:prt">compound:prt</value> <!-- Afrikaans, Arabic, Danish, Dutch, English, Erzya, Estonian, Faroese, Finnish, Frisian Dutch, German, Icelandic, Irish, Karelian, Komi Permyak, Naija, Norwegian, Persian, Spanish, Swedish, Swedish Sign Language, Swiss German, Tamil, Thai, Turkish German, Wolof, Yoruba -->
+  <value name="compound:prt">phrasal verb particle</value>
+  <value name="compound:quant">compound:quant</value> <!-- Cantonese -->
+  <value name="compound:redup">reduplicated compounds</value> <!-- Armenian, Bambara, Classical Chinese, Erzya, Hindi, Kurmanji, Marathi, Naija, Tagalog, Tamil, Telugu, Turkish, Turkish German, Uyghur, Welsh, Western Armenian -->
+  <value name="compound:smixut">compound:smixut</value> <!-- Hebrew -->
+  <value name="compound:svc">serial verb compounds</value> <!-- Amharic, Armenian, Marathi, Mbya Guarani, Naija, Swedish Sign Language, Telugu, Ukrainian, Western Armenian, Wolof, Yoruba -->
+  <value name="compound:vo">compound:vo</value> <!-- Cantonese, Chinese -->
+  <value name="compound:vv">compound:vv</value> <!-- Cantonese, Chinese -->
+  <value name="compound">compound</value>
+  <value name="conj:expl">conj:expl</value> <!-- Latin -->
+  <value name="conj:extend">conj:extend</value> <!-- Slovenian -->
+  <value name="conj:svc">conj:svc</value> <!-- Ukrainian -->
+  <value name="conj">conjunct</value>
+  <value name="cop:expl">cop:expl</value> <!-- Maltese -->
+  <value name="cop:locat">cop:locat</value> <!-- Polish -->
+  <value name="cop:own">cop:own</value> <!-- Finnish, Karelian, Livvi, Marathi -->
+  <value name="cop">copula</value>
+  <value name="csubj:cleft">csubj:cleft</value> <!-- Irish, Latin, Manx, Scottish Gaelic -->
+  <value name="csubj:cop">csubj:cop</value> <!-- Erzya, Estonian, Finnish, Irish, Komi Zyrian, Livvi, Manx, Moksha, Scottish Gaelic, Turkish -->
+  <value name="csubj:pass">clausal passive subject</value> <!-- Albanian, Amharic, Ancient Greek, Arabic, Armenian, Belarusian, Bulgarian, Catalan, Chinese, Classical Chinese, Czech, English, French, German, Gothic, Greek, Indonesian, Italian, Korean, Latin, Latvian, Lithuanian, Norwegian, Old Church Slavonic, Old East Slavic, Polish, Portuguese, Romanian, Russian, Sanskrit, Slovak, Spanish, Swedish, Western Armenian -->
+  <value name="csubj">clausal subject</value>
+  <value name="dep:aff">dep:aff</value> <!-- Beja -->
+  <value name="dep:agr">dep:agr</value> <!-- Kiche -->
+  <value name="dep:alt">dep:alt</value> <!-- Upper Sorbian -->
+  <value name="dep:ana">dep:ana</value> <!-- Yupik -->
+  <value name="dep:aux">dep:aux</value> <!-- Yupik -->
+  <value name="dep:comp">dep:comp</value> <!-- Beja, French -->
+  <value name="dep:conj">dep:conj</value> <!-- Beja -->
+  <value name="dep:cop">dep:cop</value> <!-- Yupik -->
+  <value name="dep:emo">dep:emo</value> <!-- Yupik -->
+  <value name="dep:infl">dep:infl</value> <!-- Yupik -->
+  <value name="dep:mark">dep:mark</value> <!-- Yupik -->
+  <value name="dep:mod">dep:mod</value> <!-- Mbya Guarani -->
+  <value name="dep:pos">dep:pos</value> <!-- Yupik -->
+  <value name="dep:redup">dep:redup</value> <!-- Beja -->
+  <value name="dep:ss">dep:ss</value> <!-- Kiche -->
+  <value name="dep">unspecified dependency</value>
+  <value name="det:adj">det:adj</value> <!-- Albanian -->
+  <value name="det:noun">det:noun</value> <!-- Albanian -->
+  <value name="det:numgov">pronominal quantifier governing the case of the noun</value> <!-- Czech, Polish, Serbian, Slovak, Ukrainian, Upper Sorbian -->
+  <value name="det:nummod">pronominal quantifier agreeing in case with the noun</value> <!-- Czech, Polish, Ukrainian -->
+  <value name="det:poss">possessive determiner</value> <!-- Akkadian, Armenian, German, Italian, Korean, Polish, Portuguese, Western Armenian -->
+  <value name="det:predet">det:predet</value> <!-- English, Italian, Persian -->
+  <value name="det:pron">det:pron</value> <!-- Albanian -->
+  <value name="det:rel">det:rel</value> <!-- Bambara -->
+  <value name="det">determiner</value>
+  <value name="discourse:emo">discourse:emo</value> <!-- Irish, Italian, Polish -->
+  <value name="discourse:filler">discourse:filler</value> <!-- Norwegian, Slovenian -->
+  <value name="discourse:intj">discourse:intj</value> <!-- Polish -->
+  <value name="discourse:sp">discourse:sp</value> <!-- Cantonese, Chinese, Classical Chinese -->
+  <value name="discourse">discourse element</value>
+  <value name="dislocated:cleft">dislocated:cleft</value> <!-- Mbya Guarani -->
+  <value name="dislocated:csubj">dislocated:csubj</value> <!-- Latin -->
+  <value name="dislocated:nsubj">dislocated:nsubj</value> <!-- Latin -->
+  <value name="dislocated:obj">dislocated:obj</value> <!-- Latin -->
+  <value name="dislocated:subj">dislocated:subj</value> <!-- Beja -->
+  <value name="dislocated">dislocated elements</value>
+  <value name="expl:comp">expl:comp</value> <!-- French -->
+  <value name="expl:impers">impersonal expletive</value> <!-- Italian, Polish, Romanian, Spanish -->
+  <value name="expl:pass">reflexive pronoun used in reflexive passive</value> <!-- Catalan, Czech, French, Italian, Latin, Portuguese, Romanian, Slovak, Spanish, Upper Sorbian -->
+  <value name="expl:poss">expl:poss</value> <!-- Romanian -->
+  <value name="expl:pv">reflexive clitic with an inherently reflexive verb</value> <!-- Czech, Dutch, German, Old East Slavic, Polish, Portuguese, Romanian, Slovak, Spanish, Turkish German, Upper Sorbian -->
+  <value name="expl:subj">expl:subj</value> <!-- French, Naija -->
+  <value name="expl">expletive</value>
+  <value name="fixed">fixed multiword expression</value>
+  <value name="flat:abs">flat:abs</value> <!-- Ukrainian -->
+  <value name="flat:dist">flat:dist</value> <!-- Western Armenian -->
+  <value name="flat:foreign">foreign words</value> <!-- Arabic, Belarusian, Buryat, Chinese, Chukchi, Croatian, Czech, English, Estonian, Faroese, Finnish, French, Galician, Icelandic, Indonesian, Irish, Italian, Komi Zyrian, Latin, Latvian, Lithuanian, Manx, Naija, Norwegian, Persian, Polish, Portuguese, Russian, Scottish Gaelic, Slovak, Slovenian, South Levantine Arabic, Ukrainian, Upper Sorbian -->
+  <value name="flat:name">names</value> <!-- Ancient Greek, Belarusian, Breton, Chinese, Chukchi, Erzya, Faroese, Finnish, French, Frisian Dutch, Galician, German, Gothic, Hebrew, Hindi, Hungarian, Icelandic, Indonesian, Irish, Italian, Karelian, Kazakh, Komi Permyak, Komi Zyrian, Korean, Latin, Latvian, Livvi, Maltese, Moksha, Norwegian, Old Church Slavonic, Old East Slavic, Persian, Portuguese, Russian, Scottish Gaelic, Skolt Sami, Slovenian, Spanish, Swedish, Thai, Ukrainian, Welsh, Western Armenian -->
+  <value name="flat:num">flat:num</value> <!-- Komi Zyrian, Persian -->
+  <value name="flat:range">flat:range</value> <!-- Ukrainian, Western Armenian -->
+  <value name="flat:repeat">flat:repeat</value> <!-- Ukrainian -->
+  <value name="flat:sibl">flat:sibl</value> <!-- Ukrainian -->
+  <value name="flat:title">flat:title</value> <!-- Ukrainian -->
+  <value name="flat:vv">flat:vv</value> <!-- Classical Chinese -->
+  <value name="flat">name multiword expression</value>
+  <value name="goeswith">goes with</value>
+  <value name="iobj:agent">iobj:agent</value> <!-- Armenian, French, Western Armenian -->
+  <value name="iobj:appl">iobj:appl</value> <!-- Wolof -->
+  <value name="iobj:patient">iobj:patient</value> <!-- Tagalog -->
+  <value name="iobj">indirect object</value>
+  <value name="list">list</value>
+  <value name="mark:adv">mark:adv</value> <!-- Cantonese, Chinese -->
+  <value name="mark:advmod">adverbial modifier confusable with a subordination marker</value> <!-- Old French -->
+  <value name="mark:aff">mark:aff</value> <!-- Beja -->
+  <value name="mark:obj">marker + object</value> <!--Old French, no doc -->
+  <value name="mark:obl">marker + oblique nominal</value> <!--Old French, no doc -->
+  <value name="mark:prt">mark:prt</value> <!-- Chinese, Irish, Scottish Gaelic -->
+  <value name="mark:q">mark:q</value> <!-- Hebrew -->
+  <value name="mark:rel">mark:rel</value> <!-- Cantonese, Chinese -->
+  <value name="mark">marker</value>
+  <value name="nmod:agent">nmod:agent</value> <!-- Welsh -->
+  <value name="nmod:appos">nmod:appos</value> <!-- French, Komi Zyrian, Moksha -->
+  <value name="nmod:arg">nmod:arg</value> <!-- Polish, Yupik -->
+  <value name="nmod:att">nmod:att</value> <!-- Hungarian -->
+  <value name="nmod:attlvc">nmod:attlvc</value> <!-- Hungarian -->
+  <value name="nmod:attr">nmod:attr</value> <!-- Chukchi -->
+  <value name="nmod:bahuv">nmod:bahuv</value> <!-- Moksha -->
+  <value name="nmod:cau">nmod:cau</value> <!-- Uyghur -->
+  <value name="nmod:comp">nmod:comp</value> <!-- Erzya, Komi Zyrian, Moksha, Turkish, Uyghur -->
+  <value name="nmod:flat">nmod:flat</value> <!-- Polish -->
+  <value name="nmod:gen">nmod:gen</value> <!-- Breton -->
+  <value name="nmod:gobj">nmod:gobj</value> <!-- Erzya, Finnish -->
+  <value name="nmod:gsubj">nmod:gsubj</value> <!-- Erzya, Finnish, Karelian -->
+  <value name="nmod:lfrom">nmod:lfrom</value> <!-- Komi Zyrian -->
+  <value name="nmod:lmod">nmod:lmod</value> <!-- Erzya, Indonesian, Komi Permyak, Komi Zyrian, Moksha -->
+  <value name="nmod:npmod">nmod:npmod</value> <!-- Armenian, English, Western Armenian -->
+  <value name="nmod:obj">nmod:obj</value> <!-- Komi Zyrian -->
+  <value name="nmod:obl">nmod:obl</value> <!-- Hungarian -->
+  <value name="nmod:part">nmod:part</value> <!-- Turkish, Uyghur -->
+  <value name="nmod:poss">possessive nominal modifier</value> <!-- Akkadian, Albanian, Apurina, Arabic, Armenian, Assyrian, Bambara, Beja, Breton, Chukchi, Danish, Dutch, English, Erzya, Faroese, Finnish, Frisian Dutch, German, Hebrew, Hindi, Icelandic, Indonesian, Irish, Karelian, Kazakh, Khunsari, Komi Permyak, Komi Zyrian, Korean, Kurmanji, Latin, Livvi, Maltese, Manx, Marathi, Moksha, Naija, Nayini, North Sami, Persian, Polish, Sanskrit, Scottish Gaelic, Skolt Sami, Soi, South Levantine Arabic, Swedish, Swedish Sign Language, Swiss German, Tagalog, Tamil, Telugu, Thai, Turkish, Uyghur, Warlpiri, Welsh, Western Armenian, Wolof -->
+  <value name="nmod:pred">nmod:pred</value> <!-- Polish -->
+  <value name="nmod:prp">nmod:prp</value> <!-- Komi Zyrian -->
+  <value name="nmod:redup">nmod:redup</value> <!-- Welsh -->
+  <value name="nmod:relat">nmod:relat</value> <!-- Chukchi -->
+  <value name="nmod:subj">nmod:subj</value> <!-- Komi Zyrian -->
+  <value name="nmod:tmod">temporal modifier</value> <!-- Chinese, English, Indonesian, Moksha, Romanian, Telugu, Uyghur -->
+  <value name="nmod">nominal modifier</value>
+  <value name="nsubj:advmod">fused subject pronoun and adverb</value> <!-- Old French -->
+  <value name="nsubj:aff">nsubj:aff</value> <!-- Beja -->
+  <value name="nsubj:bfoc">nsubj:bfoc</value> <!-- Tagalog -->
+  <value name="nsubj:caus">nsubj:caus</value> <!-- Armenian, French, Western Armenian -->
+  <value name="nsubj:cleft">nsubj:cleft</value> <!-- Latin -->
+  <value name="nsubj:cop">nsubj:cop</value> <!-- Apurina, Breton, Erzya, Estonian, Finnish, Hebrew, Karelian, Komi Permyak, Komi Zyrian, Livvi, Moksha, Sanskrit, Skolt Sami, Turkish -->
+  <value name="nsubj:ifoc">nsubj:ifoc</value> <!-- Tagalog -->
+  <value name="nsubj:lfoc">nsubj:lfoc</value> <!-- Tagalog -->
+  <value name="nsubj:lvc">nsubj:lvc</value> <!-- Hungarian -->
+  <value name="nsubj:nc">nsubj:nc</value> <!-- Persian, Tamil, Telugu -->
+  <value name="nsubj:obj">fused subject and object pronoun</value> <!-- Old French -->
+  <value name="nsubj:pass">passive nominal subject</value> <!-- Afrikaans, Amharic, Ancient Greek, Arabic, Armenian, Assyrian, Belarusian, Bulgarian, Buryat, Cantonese, Catalan, Chinese, Classical Chinese, Czech, Dutch, English, Faroese, French, Frisian Dutch, Galician, German, Gothic, Greek, Hindi, Indonesian, Italian, Korean, Latin, Latvian, Lithuanian, Maltese, Marathi, Moksha, Norwegian, Old Church Slavonic, Old East Slavic, Persian, Polish, Portuguese, Romanian, Russian, Sanskrit, Skolt Sami, Slovak, Spanish, Swedish, Swiss German, Tagalog, Tamil, Thai, Turkish German, Upper Sorbian, Western Armenian -->
+  <value name="nsubj:periph">nsubj:periph</value> <!-- Cantonese -->
+  <value name="nsubj">Nominal subject</value>
+  <value name="nummod:det">nummod:det</value> <!-- Beja -->
+  <value name="nummod:entity">numeric modifier governed by a noun</value> <!-- Russian -->
+  <value name="nummod:flat">nummod:flat</value> <!-- Polish -->
+  <value name="nummod:gov">numeric modifier governing the case of the noun</value> <!-- Belarusian, Czech, Lithuanian, Old East Slavic, Polish, Russian, Sanskrit, Serbian, Ukrainian, Upper Sorbian -->
+  <value name="nummod">numeric modifier</value>
+  <value name="obj:advmod">fused adverb and object pronoun</value> <!-- Old French -->
+  <value name="obj:advneg">fused negation and object pronoun</value> <!-- no doc for advneg -->
+  <value name="obj:agent">obj:agent</value> <!-- Apurina, French, Tagalog -->
+  <value name="obj:appl">obj:appl</value> <!-- Wolof -->
+  <value name="obj:caus">obj:caus</value> <!-- Wolof -->
+  <value name="obj:lvc">obj:lvc</value> <!-- French, Hungarian, Naija -->
+  <value name="obj:obl">fused oblique and object pronoun</value> <!-- Old French -->
+  <value name="obj:periph">obj:periph</value> <!-- Cantonese, Chinese -->
+  <value name="obj">object</value>
+  <value name="obl:advmod">adverbial modifier confusable with an oblique dependent</value> <!-- Old French -->
+  <value name="obl:agent">agent modifier</value> <!-- Ancient Greek, Armenian, Belarusian, Breton, Cantonese, Chinese, Czech, Dutch, Erzya, French, German, Gothic, Greek, Hindi, Indonesian, Italian, Komi Zyrian, Latin, Lithuanian, Maltese, Moksha, Naija, Old Church Slavonic, Old East Slavic, Polish, Portuguese, Romanian, Russian, Sanskrit, Skolt Sami, Swedish, Tamil, Turkish, Welsh, Western Armenian -->
+  <value name="obl:appl">obl:appl</value> <!-- Wolof -->
+  <value name="obl:arg">oblique argument</value> <!-- Arabic, Beja, Czech, French, German, Greek, Icelandic, Latin, Lithuanian, Maltese, Naija, Persian, Polish, Sanskrit, Slovak, South Levantine Arabic, Tamil -->
+  <value name="obl:cau">obl:cau</value> <!-- Erzya, Komi Zyrian, Moksha, Telugu -->
+  <value name="obl:cmp">obl:cmp</value> <!-- Telugu -->
+  <value name="obl:cmpr">obl:cmpr</value> <!-- Latin, Polish, Tamil -->
+  <value name="obl:comp">obl:comp</value> <!-- Moksha -->
+  <value name="obl:dat">obl:dat</value> <!-- Kurmanji -->
+  <value name="obl:freq">obl:freq</value> <!-- Moksha -->
+  <value name="obl:inst">obl:inst</value> <!-- Erzya, Moksha, Tamil -->
+  <value name="obl:lfrom">obl:lfrom</value> <!-- Erzya, Komi Zyrian, Moksha -->
+  <value name="obl:lmod">locative modifier</value> <!-- Apurina, Classical Chinese, Danish, Erzya, Komi Permyak, Komi Zyrian, Moksha, Skolt Sami, Tamil -->
+  <value name="obl:lmp">obl:lmp</value> <!-- Erzya, Komi Zyrian, Moksha -->
+  <value name="obl:lto">obl:lto</value> <!-- Erzya, Komi Zyrian, Moksha -->
+  <value name="obl:lvc">obl:lvc</value> <!-- Hungarian -->
+  <value name="obl:mcl">obl:mcl</value> <!-- Komi Zyrian -->
+  <value name="obl:mod"> oblique modifier</value> <!-- Beja, French, Naija, Yupik -->
+  <value name="obl:npmod">obl:npmod</value> <!-- Coptic, English -->
+  <value name="obl:orphan">obl:orphan</value> <!-- Polish -->
+  <value name="obl:own">obl:own</value> <!-- Kazakh -->
+  <value name="obl:patient">obl:patient</value> <!-- Cantonese, Chinese -->
+  <value name="obl:pmod">obl:pmod</value> <!-- Romanian, Tamil -->
+  <value name="obl:poss">obl:poss</value> <!-- Thai -->
+  <value name="obl:prep">obl:prep</value> <!-- Irish -->
+  <value name="obl:sentcon">obl:sentcon</value> <!-- Mbya Guarani -->
+  <value name="obl:smod">obl:smod</value> <!-- Scottish Gaelic -->
+  <value name="obl:tmod">obl:tmod</value> <!-- Apurina, Arabic, Cantonese, Chinese, Classical Chinese, Danish, English, Erzya, Frisian Dutch, German, Hindi, Indonesian, Irish, Italian, Komi Permyak, Komi Zyrian, Korean, Manx, Moksha, Portuguese, Scottish Gaelic, Skolt Sami, Spanish, Tamil, Telugu, Thai, Turkish, Uyghur, Warlpiri -->
+  <value name="obl:tmod">temporal modifier</value>
+  <value name="obl">oblique nominal</value>
+  <value name="orphan:missing">textual gap in the source</value> <!-- Latin -->
+  <value name="orphan">remnant in ellipsis</value>
+  <value name="parataxis:appos">parataxis:appos</value> <!-- Italian -->
+  <value name="parataxis:conj">parataxis:conj</value> <!-- Naija -->
+  <value name="parataxis:coord">parataxis:coord</value> <!-- Beja -->
+  <value name="parataxis:deletion">parataxis:deletion</value> <!-- Norwegian -->
+  <value name="parataxis:discourse">parataxis:discourse</value> <!-- Italian, Naija, Slovenian, Turkish German, Ukrainian -->
+  <value name="parataxis:dislocated">parataxis:dislocated</value> <!-- Naija -->
+  <value name="parataxis:hashtag">parataxis:hashtag</value> <!-- Irish, Italian -->
+  <value name="parataxis:insert">parataxis:insert</value> <!-- French, Italian, Polish -->
+  <value name="parataxis:mod">parataxis:mod</value> <!-- Beja -->
+  <value name="parataxis:newsent">parataxis:newsent</value> <!-- Ukrainian -->
+  <value name="parataxis:nsubj">parataxis:nsubj</value> <!-- Italian -->
+  <value name="parataxis:obj">parataxis:obj</value> <!-- Bambara, Italian, Polish -->
+  <value name="parataxis:parenth">parataxis:parenth</value> <!-- French, Naija -->
+  <value name="parataxis:rel">parataxis:rel</value> <!-- Ukrainian -->
+  <value name="parataxis:rep">parataxis:rep</value> <!-- Chukchi, Latin, Mbya Guarani -->
+  <value name="parataxis:restart">parataxis:restart</value> <!-- Slovenian -->
+  <value name="parataxis:rt">parataxis:rt</value> <!-- Irish -->
+  <value name="parataxis:sentence">parataxis:sentence</value> <!-- Irish -->
+  <value name="parataxis:trans">parataxis:trans</value> <!-- Turkish German -->
+  <value name="parataxis:url">parataxis:url</value> <!-- Irish -->
+  <value name="parataxis">parataxis</value>
+  <value name="punct">punctuation</value>
+  <value name="remnant">Remnant ?</value> <!-- no doc, replace with orphan? -->
+  <value name="reparandum">overridden disfluency</value>
+  <value name="root">root</value>
+  <value name="vocative:cl">vocative:cl</value> <!-- Ukrainian -->
+  <value name="vocative:mention">vocative:mention</value> <!-- Irish, Italian -->
+  <value name="vocative">vocative</value>
+  <value name="xcomp:cleft">xcomp:cleft</value> <!-- Polish -->
+  <value name="xcomp:ds">xcomp:ds</value> <!-- Erzya, Finnish, Karelian, Komi Permyak, Livvi -->
+  <value name="xcomp:obj">xcomp:obj</value> <!-- North Sami, Polish -->
+  <value name="xcomp:pred">xcomp:pred</value> <!-- Irish, Latin, Manx, North Sami, Polish, Scottish Gaelic -->
+  <value name="xcomp:sp">xcomp:sp</value> <!-- Ukrainian -->
+  <value name="xcomp:subj">xcomp:subj</value> <!-- Polish -->
+  <value name="xcomp">open clausal complement</value>
+</feature>
+<feature name="coord" domain="NT" ></feature>
+<feature name="dom" domain="NT" ></feature>
+<feature name="type" domain="NT" >
+  <value name="nV">élément non-verbal</value>
+  <value name="VFin">finite verb</value>
+  <value name="VInf">infinitive</value>
+  <value name="VPar">participle</value>
+  <value name="--">nil</value>
+</feature>
+<feature name="vform" domain="NT"></feature>
+<feature name="vlemma" domain="NT"></feature>
+<feature name="note" domain="NT"></feature>
+<feature name="snr" domain="NT"></feature>
+';
+
+	printf MASTER "$nt_features_header";
+
+	printf MASTER '
+<edgelabel>
+  <value name="D">dependency</value>
+  <value name="L">lexical</value>
+  <value name="R">relator</value>
+  <value name="*">not bound</value>
+</edgelabel>
+<secedgelabel>
+  <value name="cluster">between elements of GpCoo</value>
+  <value name="coord">between members of Coo</value>
+  <value name="dupl">between duplicated nodes</value>
+</secedgelabel>
+</annotation>
+</head>
+<body>
+';
+}
+
+#  <value name="M">main</value>
+#  <value name="P">part</value>
+
+sub write_master_footer {
+	print MASTER '</body>
+</corpus>
+';
+}
+
+$TEMP = '
+<feature name="nodom" domain="NT" ></feature>
+<feature name="headpos" domain="NT" ></feature>
+<feature name="annotationFile" domain="NT" ></feature>
+<feature name="annotationUri" domain="NT" ></feature>
+';
+
+sub define_cat_hashes {
+
+	#  $abbrev2cat{"Apst"} = "Apostrophe";
+	#  $abbrev2cat{"AtObj"} = "AttributObjet";
+	#  $abbrev2cat{"AtRfc"} = "AttributReflechi";
+	#  $abbrev2cat{"AtSj"} = "AttributSujet";
+	#  $abbrev2cat{"AuxA"} = "Auxilie-Actif";
+	#  $abbrev2cat{"AuxP"} = "Auxilie-Passif";
+	#  $abbrev2cat{"Circ"} = "Circonstant";
+	#  $abbrev2cat{"Cmpl"} = "Complement";
+	#  $abbrev2cat{"GpCoo"} = "Coordonne";
+	#  $abbrev2cat{"Coo"} = "Coordination";
+	#  $abbrev2cat{"Det"} = "Determinant";
+	#  $abbrev2cat{"NgPrt"} = "Forclusif";
+	#  $abbrev2cat{"Insrt"} = "Incidente";
+	#  $abbrev2cat{"Intj"} = "Interjection";
+	#  $abbrev2cat{"ModA"} = "ModifieurAttache";
+	#  $abbrev2cat{"ModD"} = "ModifieurDetache";
+	#  $abbrev2cat{"Ng"} = "Negation";
+	#  $abbrev2cat{"VInf"} = "NoeudVerbal-Infinitif";
+	#  $abbrev2cat{"VPrt"} = "NoeudVerbal-Participe"; #?
+	#  $abbrev2cat{"VFin"} = "NoeudVerbal-Personnel";
+	#  $abbrev2cat{"nSnt"} = "NonPhrase";
+	#  $abbrev2cat{"Obj"} = "Objet";
+	#  $abbrev2cat{"Snt"} = "Phrase";
+	#  $abbrev2cat{"Pon"} = "Ponctuation";
+	#  $abbrev2cat{"Rfc"} = "Reflechi";
+	#  $abbrev2cat{"Rfx"} = "ReflexifRenforce";
+	#  $abbrev2cat{"RelC"} = "Relateur-Coordonnant";
+	#  $abbrev2cat{"RelNC"} = "Relateur-NonCoordonnant";
+	#  $abbrev2cat{"nMax"} = "StructureNonMaximale";
+	#  $abbrev2cat{"SjImp"} = "SujetImpersonnel";
+	#  $abbrev2cat{"SjPer"} = "SujetPersonnel";
+	#  $abbrev2cat{"Lac"} = "Lacune";
+	#  $abbrev2cat{"Aux"} = "Auxilie";
+	#  $abbrev2cat{"Regim"} = "Regime";
+
+	$abbrev2cat{"acl"}        = "Clausal modifier of noun";
+	$abbrev2cat{"advcl"}      = "Adverbial clause modifier";
+	$abbrev2cat{"advmod"}     = "Adverbial modifier";
+	$abbrev2cat{"amod"}       = "Adjectival modifier";
+	$abbrev2cat{"appos"}      = "Appositional modifier";
+	$abbrev2cat{"aux"}        = "Auxiliary";
+	$abbrev2cat{"cc-nc"}      = "Coordinated conjunct : non coordonant";
+	$abbrev2cat{"cc"}         = "Coordinating conjunction";
+	$abbrev2cat{"ccomp"}      = "Clausal complement";
+	$abbrev2cat{"conj"}       = "Conjunct";
+	$abbrev2cat{"cop"}        = "Copula";
+	$abbrev2cat{"csubj"}      = "Clausal subject";
+	$abbrev2cat{"det"}        = "Determiner";
+	$abbrev2cat{"dislocated"} = "Dislocated elements";
+	$abbrev2cat{"expl"}       = "Expletive";
+	$abbrev2cat{"iobj"}       = "Indirect object";
+	$abbrev2cat{"mark"}       = "Marker";
+	$abbrev2cat{"nmod"}       = "Nominal modifier";
+	$abbrev2cat{"nsubj"}      = "Nominal subject";
+	$abbrev2cat{"nummod"}     = "Numeric modifier";
+	$abbrev2cat{"obj"}        = "Object";
+	$abbrev2cat{"obl"}        = " Oblique nominal";
+	$abbrev2cat{"orphan"}     = "Remnant in ellipsis";
+	$abbrev2cat{"remnant"}    = "Remnant ?";
+	$abbrev2cat{"vocative"}   = "Vocative";
+	$abbrev2cat{"xcomp"}      = "Open clausal complement";
+}
+
+sub print_sentence {
+	for ( my $q = 0 ; $q <= $#words ; $q++ ) {
+		print "$words[$q]\n";
+	}
+}
+
+sub write_nonterminals {
+	my $print_nt_features;
+	if ( $_[1] =~ /dupl/ ) {
+		$dupl = '_dupl';
+	}
+	else {
+		$dupl = '';
+	}
+	if ( $nt_features ne '' ) {
+		$print_nt_features = $nt_empty_features;
+		if ( $_[0] =~ /$thisrootname/ ) {
+			$print_nt_features = $nt_features;
+		}
+	}
+	printf XML
+	  "      <nt id=\"n%d_%d%s\" cat=\"%s\" coord=\"--\" dom=\"%s\" type=\"%s\" vform=\"%s\" vlemma=\"%s\"%s note=\"%s\" snr=\"%d\">\n",
+	  $., $w, $dupl, $_[0], $dom, $type, $vform, $vlemma, $print_nt_features,
+	  notes("$._$w"), $.;
+	printf XML "        <edge idref=\"s%d_%d%s\" label=\"L\"/>\n", $., $w, $dupl;
+
+	# link duplicate with primary original node
+	if ( $_[1] =~ /dupl/ ) {
+		printf XML "        <secedge idref=\"s%d_%d\" label=\"dupl\"/>\n", $., $w;
+	}
+
+	# if node is not a duplicate: attach all the daughters
+	if ( $_[1] !~ /dupl/ ) {
+		for ( my $d = 0 ; $d <= $#daughters ; $d++ ) {
+			$daughter = $daughters[$d];
+			if ( "$._$w" ne "$._$daughter" ) {    # avoid cycles
+				printf XML "        <edge idref=\"n%d_%d%s\" label=\"%s\"/>\n", $., $daughter, $dupl, edge_label("$._$daughter");
+			}
+
+			# check if a duplicate of this node must be attached
+			if ( $duplicates{"$._$daughter"} == 1 ) {
+				printf XML "        <edge idref=\"n%d_%d_dupl\" label=\"%s\"/>\n", $., $daughter, edge_label("$._$daughter_dupl");
+			}
+		}
+	}
+	print XML "      </nt>\n";
+}
+
+# checks if node is stored as in hash of relators
+sub edge_label {
+	if ( $relators{ $_[0] } == 1 ) {
+		return 'R';
+	}
+	return 'D';
+}
+
+# retrives notes for this node
+sub notes {
+	if ( $notes{ $_[0] } ne '' ) {
+		return "$notes{$_[0]}";
+	}
+	return '--';
+}
+
+# conversions, bug fixes
+sub clean_data {
+
+	# conversions of values, some necessary some for convenience
+	$word =~ s/"/'/g;
+	$word =~ s/\&/(and)/g;
+	$word =~ s/<</«/g;
+	$word =~ s/>>/»/g;
+	$word =~ s/[<>]//g;
+	$pos =~ s/:/_/g;
+	$mor =~ s/\|/_/g;
+	$ppos =~ s/:/_/g;
+	$pmor =~ s/\|/_/g;
+	$lemma =~ s/\|/_/g;
+	$lemma =~ s/[<>]//g;
+	$lemma =~ s/"/'/g;
+	$lemma =~ s/\&/(and)/g;
+	$plemma =~ s/\|/_/g;
+	$plemma =~ s/[<>]//g;
+	$plemma =~ s/"/'/g;
+	$plemma =~ s/\&/(and)/g;
+
+	# clean categories
+	$cat =~ s/ROOT/$thisrootname/;    # top node, for compatibility with SRCMF
+
+	#    $cat =~ s/Ponctuation/Pon/;
+	# correct some bugs in parse
+	#    $cat =~ s/Sujet/SjPer/;
+	#    $cat =~ s/Modifieur/ModA/;
+	#    $cat =~ s/Parenthese/Insrt/;
+	$cat =~ s/\-/_/g;
+	$cat =~ s/RelNC_(.*)/$1_RelNC/;    # RelNC always 2nd node, for consistency in duplicates
+	return;
+}
+
Index: TXM/trunk/org.txm.conllu.core/groovy/org/txm/scripts/importer/conllu/conllu.js
===================================================================
--- TXM/trunk/org.txm.conllu.core/groovy/org/txm/scripts/importer/conllu/conllu.js	(revision 0)
+++ TXM/trunk/org.txm.conllu.core/groovy/org/txm/scripts/importer/conllu/conllu.js	(revision 3567)
@@ -0,0 +1,1392 @@
+// -*- Mode: JavaScript; tab-width: 4; indent-tabs-mode: nil; -*-
+// vim:set ft=javascript ts=4 sw=4 sts=4 cindent:
+
+/*
+CoNLL-U format library for JavaScript.
+Home: http://github.com/spyysalo/conllu.js
+Format: http://universaldependencies.github.io/docs/format.html
+
+Author: Sampo Pyysalo
+License: MIT (http://opensource.org/licenses/MIT)
+*/
+
+var ConllU = (function(window, undefined) {
+
+    /*
+     * ConllU.Document: represents CoNLL-U document
+     */
+
+    var Document = function() {
+        this.reset();
+    };
+
+    Document.prototype.reset = function() {
+        this.sentences = [];
+        this.error = false;
+        this.logger = function(s) { /* no-op */ };
+        this.strict = null; // pick heuristically
+    };
+
+    Document.prototype.log = function(message) {
+        this.logger(message);
+    };
+
+    Document.prototype.logError = function(message) {
+        this.log('error: ' + message);
+        this.error = true;
+    };
+
+    /* Parse CoNLL-U format, return Document.
+     * (see http://universaldependencies.github.io/docs/format.html)
+     *
+     * CoNLL-U files contain three types of lines:
+     * 1.  Word lines
+     * 2.  Blank lines marking sentence boundaries
+     * 3.  Comment lines starting with a hash ("#")        
+     *
+     * Each word line has the following format
+     * 1.  ID: Word index, integer starting at 1 for each new sentence; 
+     *     may be a range for tokens with multiple words; may be a decimal
+     *     number for empty nodes.
+     * 2.  FORM: Word form or punctuation symbol.
+     * 3.  LEMMA: Lemma or stem of word form.
+     * 4.  UPOSTAG: Universal part-of-speech tag.
+     * 5.  XPOSTAG: Language-specific part-of-speech tag; underscore
+     *     if not available.
+     * 6.  FEATS: List of morphological features from the Universal 
+     *     feature inventory or from a defined language-specific extension;
+     *      underscore if not available.
+     * 7.  HEAD: Head of the current token, which is either a value of ID
+     *     or zero (0).
+     * 8.  DEPREL: Universal Stanford dependency relation to the HEAD
+     *     (root iff HEAD = 0) or a defined language-specific subtype
+     *     of one.
+     * 9.  DEPS: List of secondary dependencies (head-deprel pairs).
+     * 10. MISC: Any other annotation.
+     */
+    Document.prototype.parse = function(input, logger, strict) {
+        // discard previous state, if any
+        this.reset();
+
+        if (logger !== undefined) {
+            this.logger = logger;
+        }
+        if (strict !== undefined) {
+            this.strict = strict;
+        }
+        
+        // TODO: handle other newline formats
+        var lines = input.split('\n');
+
+        if (this.strict === null) {
+            this.strict = selectParsingMode(input, this.logger);
+        }
+
+        // select splitter to use for dividing the lines into fields.
+        var splitter = selectFieldSplitter(input, this.logger, this.strict);
+
+        var elements = [],            
+            comments = [],
+            beforeSentence = true;
+        for (var idx=0; idx<lines.length; idx++) {
+            var line = lines[idx], that = this;
+
+            var logLineError = function(message) {
+                that.logError('line '+(idx+1)+': '+message+' ("'+line+'")');
+                that.error = true;
+            }
+
+            if (isComment(line)) {
+                if (beforeSentence) {
+                    comments.push(line);
+                } else {
+                    logLineError('comments must precede sentence, ignoring');
+                }
+                continue;
+            }
+
+            // non-comment, assume inside sentence until terminated by
+            // blank line
+            beforeSentence = false;
+
+            var fields = splitter(line);
+
+            if (fields.length === 0) {
+                // empty line, terminates sentence
+                if (elements.length !== 0) {
+                    var sId = 'S' + (this.sentences.length+1);
+                    var sentence = new Sentence(sId, elements, comments);
+                    this.sentences.push(sentence);
+                } else {
+                    logLineError('empty sentence, ignoring');
+                }
+                // reset
+                elements = [];
+                comments = [];
+                beforeSentence = true;
+                continue;
+            }
+
+            if (fields.length !== 10) {
+                logLineError('expected 10 fields, got '+fields.length);
+                repairFields(fields, this.logger);
+            }
+
+            var element = new Element(fields, idx, line);
+
+            var issues = element.validate();
+            for (var j=0; j<issues.length; j++) {
+                logLineError(issues[j]);
+            }
+            if (issues.length !== 0) {
+                if (!element.repair(this.logger)) {
+                    logLineError('repair failed, discarding line');
+                    continue; // failed, ignore line
+                }
+            }
+
+            elements.push(element);
+        }
+
+        // If elements is non-empty, last sentence ended without its
+        // expected terminating empty line. Process, but warn if strict.
+        if (elements.length !== 0) {
+            if (this.strict) {
+                this.logError('missing blank line after last sentence');
+            }
+            var sId = 'S' + (this.sentences.length+1);
+            var sentence = new Sentence(sId, elements, comments);
+            this.sentences.push(sentence);
+            // reset
+            elements = [];
+            comments = [];
+            beforeSentence = true;
+        }
+
+        // If comments is non-empty, there were comments after the
+        // terminating empty line. Warn and discard.
+        if (comments.length !== 0) {
+            this.logError('comments may not occur after last sentence, '+
+                          'ignoring');
+        }
+
+        return this;
+    }
+
+    Document.prototype.toBrat = function(logger, includeEmpty) {
+        if (logger !== undefined) {
+            this.logger = logger;
+        }
+        if (includeEmpty === undefined) {
+            includeEmpty = false;    // hide empty nodes by default
+        }
+
+        // merge brat data over all sentences
+        var mergedBratData = {},
+            textOffset = 0;
+        var categories = [
+            'entities',
+            'attributes',
+            'relations',
+            'comments',
+            'styles',
+            'sentlabels'
+        ];
+        for (var i=0; i<categories.length; i++) {
+            mergedBratData[categories[i]] = [];
+        }
+        mergedBratData['text'] = '';
+        for (var i=0; i<this.sentences.length; i++) {
+            var sentence = this.sentences[i];
+
+            var issues = sentence.validate();
+            for (var j=0; j<issues.length; j++) {
+                this.logError(issues[j]);
+            }
+            if (issues.length !== 0) {
+                if (!sentence.repair(this.logger)) {
+                    this.logError('repair failed, discarding sentence');
+                    continue;
+                }
+            }
+            sentence.setBaseOffset(textOffset !== 0 ? textOffset + 1 : 0);
+            bratData = sentence.toBrat(includeEmpty);
+            
+            // merge
+            if (mergedBratData['text'].length !== 0) {
+                mergedBratData['text'] += '\n';
+                textOffset += 1;
+            }
+            mergedBratData['text'] += bratData['text'];
+            textOffset += bratData['text'].length;
+            for (var j=0; j<categories.length; j++) {
+                var c = categories[j];
+                mergedBratData[c] = mergedBratData[c].concat(bratData[c]);
+            }
+        }
+
+        // to avoid brat breakage on error, don't send empty text
+        if (mergedBratData['text'].length === 0) {
+            mergedBratData['text'] = '<EMPTY>';
+        }
+
+        mergedBratData['error'] = this.error;
+
+        return mergedBratData;
+    };
+
+    /*
+     * ConllU.Sentence: represents CoNLL-U sentence
+     */
+
+    var Sentence = function(sentenceId, elements, comments) {
+        this.id = sentenceId;
+        this.elements = elements;
+        this.comments = comments;
+        this.baseOffset = 0;
+    };
+
+    // set offset of first character in sentence (for standoff
+    // generation)
+    Sentence.prototype.setBaseOffset = function(baseOffset) {
+        this.baseOffset = baseOffset;
+    }
+
+    Sentence.prototype.dependencies = function() {
+        var dependencies = [];
+
+        for (var i=0; i<this.elements.length; i++) {
+            var element = this.elements[i];
+            dependencies = dependencies.concat(element.dependencies());
+        }
+
+        return dependencies;
+    };
+
+    Sentence.prototype.words = function(includeEmpty) {
+        return this.elements.filter(function(e) { 
+            return (e.isWord() || (includeEmpty && e.isEmptyNode()));
+        });
+    };
+
+    Sentence.prototype.multiwords = function() {
+        return this.elements.filter(function(e) {
+            return e.isMultiword();
+        });
+    };
+
+    Sentence.prototype.tokens = function() {
+        // extract token sequence by omitting word IDs that are
+        // included in a multiword token range.
+        var multiwords = this.multiwords();
+        var inRange = {};
+        for (var i=0; i<multiwords.length; i++) {
+            var mw = multiwords[i];
+            for (var j=mw.rangeFrom(); j<=mw.rangeTo(); j++) {
+                inRange[j] = true;
+            }
+        }
+        return this.elements.filter(function(e) {
+            return e.isToken(inRange);
+        });
+    };
+
+    // return words with possible modifications for visualization with
+    // brat
+    Sentence.prototype.bratWords = function(includeEmpty) {
+        var words = this.words(includeEmpty);
+        
+        for (var i=0; i<words.length; i++) {
+            if (isRtl(words[i].form)) {
+                words[i] = deepCopy(words[i]);
+                words[i].form = rtlFix(words[i].form);
+            }
+        }
+
+        return words;
+    };
+
+    // return tokens with possible modifications for visualization
+    // with brat
+    Sentence.prototype.bratTokens = function() {
+        var tokens = this.tokens();
+
+        for (var i=0; i<tokens.length; i++) {
+            tokens[i] = deepCopy(tokens[i]);
+            tokens[i].form = rtlFix(tokens[i].form);
+        }
+
+        return tokens;
+    };
+
+    // return the text of the sentence for visualization with brat
+    Sentence.prototype.bratText = function(includeEmpty) {
+        var words = this.bratWords(includeEmpty);
+        var tokens = this.bratTokens();
+
+        var wordText = words.map(function(w) { return w.form }).join(' ');
+        var tokenText = tokens.map(function(w) { return w.form }).join(' ');
+
+        var combinedText = wordText;
+        if (wordText != tokenText) {
+            combinedText += '\n' + tokenText;
+        }
+
+        return combinedText;
+    };
+
+    // return the annotated text spans of the sentence for visualization
+    // with brat.
+    Sentence.prototype.bratSpans = function(includeEmpty) {
+        var spans = [],
+            offset = this.baseOffset;
+
+        // create an annotation for each word
+        var words = this.bratWords(includeEmpty);
+        for (var i=0; i<words.length; i++) {
+            var length = words[i].form.length;
+            spans.push([this.id+'-T'+words[i].id, words[i].upostag,
+                        [[offset, offset+length]]]);
+            offset += length + 1;
+        }
+
+        return spans;
+    }
+
+    // return attributes of sentence annotations for visualization
+    // with brat.
+    Sentence.prototype.bratAttributes = function(includeEmpty) {
+        var words = this.words(includeEmpty);
+
+        // create attributes for word features
+        var attributes = [],
+            aidseq = 1;
+        for (var i=0; i<words.length; i++) {
+            var word = words[i],
+                tid = this.id+'-T'+word.id;
+            var nameVals = word.features();
+            for (var j=0; j<nameVals.length; j++) {
+                var name = nameVals[j][0], 
+                    value = nameVals[j][1];
+                attributes.push([this.id+'-A'+aidseq++, name, tid, value]);
+            }
+        }
+
+        return attributes;
+    };
+
+    // return relations for sentence dependencies for visualization
+    // with brat.
+    Sentence.prototype.bratRelations = function(includeEmpty) {
+        var dependencies = this.dependencies();
+        var relations = [];
+
+        for (var i=0; i<dependencies.length; i++) {
+            var dep = dependencies[i];
+            relations.push([this.id+'-R'+i, dep[2], 
+                            [ [ 'arg1', this.id+'-T'+dep[1] ],
+                              [ 'arg2', this.id+'-T'+dep[0] ] ] ]);
+        }
+
+        return relations;
+    };
+
+    // return comments (notes) on sentence annotations for
+    // visualization with brat.
+    Sentence.prototype.bratComments = function(includeEmpty) {
+        var words = this.words(includeEmpty);
+
+        // TODO: better visualization for LEMMA, XPOSTAG, and MISC.
+        var comments = [];
+        for (var i=0; i<words.length; i++) {
+            var word = words[i],
+                tid = this.id+'-T'+word.id,
+                label = 'AnnotatorNotes';
+            comments.push([tid, label, 'Lemma: ' + word.lemma]);
+            if (word.xpostag !== '_') {
+                comments.push([tid, label, 'Xpostag: ' + word.xpostag]);
+            }
+            if (word.misc !== '_') {
+                comments.push([tid, label, 'Misc: ' + word.misc]);
+            }
+        }
+
+        return comments;
+    };
+
+    // Return styles on sentence annotations for visualization with
+    // brat. Note: this feature is an extension of both the CoNLL-U
+    // comment format and the basic brat data format.
+    Sentence.prototype.bratStyles = function(includeEmpty) {
+        var styles = [],
+            wildcards = [];
+
+        for (var i=0; i<this.comments.length; i++) {
+            var comment = this.comments[i];
+
+            m = comment.match(/^(\#\s*visual-style\s+)(.*)/);
+            if (!m) {
+                continue;
+            }
+            var styleSpec = m[2];
+
+            // Attempt to parse as a visual style specification. The
+            // expected format is "REF<SPACE>STYLE", where REF
+            // is either a single ID (for a span), a space-separated
+            // ID1 ID2 TYPE triple (for a relation), or a special
+            // wildcard value like "arcs", and STYLE is either
+            // a colon-separated key-value pair or a color.
+            m = styleSpec.match(/^([^\t]+)\s+(\S+)\s*$/);
+            if (!m) {
+                // TODO: avoid console.log
+                console.log('warning: failed to parse: "'+comment+'"');
+                continue;
+            }
+            var reference = m[1], style = m[2];
+
+            // split style into key and value, adding a key to
+            // color-only styles as needed for the reference type.
+            var key, value;
+            m = style.match(/^(\S+):(\S+)$/);
+            if (m) {
+                key = m[1];
+                value = m[2];
+            } else {
+                value = style;
+                if (reference === 'arcs' || reference.indexOf(' ') !== -1) {
+                    key = 'color';
+                } else {
+                    key = 'bgColor';
+                }
+            }
+
+            // store wildcards for separate later processing
+            if (reference.match(/^(nodes|arcs)$/)) {
+                wildcards.push([reference, key, value]);
+                continue;
+            }
+
+            // adjust every ID in reference for brat
+            if (reference.indexOf(' ') === -1) {
+                reference = this.id + '-T' + reference;
+            } else {
+                reference = reference.split(' ');
+                reference[0] = this.id + '-T' + reference[0];
+                reference[1] = this.id + '-T' + reference[1];
+            }
+
+            styles.push([reference, key, value]);
+        }
+
+        // for expanding wildcards, first determine which words / arcs
+        // styles have already been set, and then add the style to
+        // everything that hasn't.
+        var setStyle = {};
+        for (var i=0; i<styles.length; i++) {
+            setStyle[styles[i][0].concat([styles[i][1]])] = true;
+        }
+        for (var i=0; i<wildcards.length; i++) {
+            var reference = wildcards[i][0],
+                key = wildcards[i][1],
+                value = wildcards[i][2];
+            if (reference === 'nodes') {
+                var words = this.words(includeEmpty);
+                for (var j=0; j<words.length; j++) {
+                    var r = this.id + '-T' + words[j].id;
+                    if (!setStyle[r.concat([key])]) {
+                        styles.push([r, key, value]);
+                        setStyle[r.concat([key])] = true;
+                    }
+                }
+            } else if (reference === 'arcs') {
+                var deps = this.dependencies();
+                for (var j=0; j<deps.length; j++) {
+                    var r = [this.id + '-T' + deps[j][1],
+                             this.id + '-T' + deps[j][0],
+                             deps[j][2]];
+                    if (!setStyle[r.concat([key])]) {
+                        styles.push([r, key, value]);
+                        setStyle[r.concat([key])] = true;
+                    }
+                }
+            } else {
+                console.log('internal error');
+            }
+        }
+        
+        return styles;
+    };
+
+    // Return label of sentence for visualization with brat, or null
+    // if not defined. Note: this feature is an extension of both the
+    // CoNLL-U comment format and the basic brat data format.
+    Sentence.prototype.bratLabel = function() {
+        var label = null;
+
+        for (var i=0; i<this.comments.length; i++) {
+            var comment = this.comments[i];
+
+            m = comment.match(/^(\#\s*sentence-label\b)(.*)/);
+            if (!m) {
+                continue;
+            }
+            label = m[2].trim();
+        }
+        return label;
+    };
+
+    // Return representation of sentence in brat embedded format (see
+    // http://brat.nlplab.org/embed.html).
+    // If includeEmpty is truthy, include empty nodes in the representation.
+    // Note: "styles" is an extension, not part of the basic format.
+    Sentence.prototype.toBrat = function(includeEmpty) {
+        var text = this.bratText(includeEmpty);
+        var spans = this.bratSpans(includeEmpty);
+        var attributes = this.bratAttributes(includeEmpty);
+        var relations = this.bratRelations(includeEmpty);
+        var comments = this.bratComments(includeEmpty);
+        var styles = this.bratStyles(includeEmpty);
+        var labels = [this.bratLabel()];
+
+        return {
+            'text': text,
+            'entities': spans,
+            'attributes': attributes,
+            'relations': relations,
+            'comments': comments,
+            'styles': styles,
+            'sentlabels': labels,
+        };
+    };
+
+    Sentence.prototype.elementById = function() {
+        var elementById = {};
+
+        for (var i=0; i<this.elements.length; i++) {
+            elementById[this.elements[i].id] = this.elements[i];
+        }
+
+        return elementById;
+    };
+
+    Sentence.prototype.addError = function(issue, element, issues) {
+        issues.push('line '+(element.lineidx+1)+': '+issue+' ("'+element.line+'")');
+    }
+
+    // Check validity of the sentence. Return list of strings
+    // representing issues found in validation (empty list if none).
+    Sentence.prototype.validate = function() {
+        var issues = [];
+
+        this.validateUniqueIds(issues);
+        this.validateWordSequence(issues);
+        this.validateMultiwordSequence(issues);
+        this.validateEmptyNodeSequence(issues);
+        this.validateReferences(issues);
+
+        return issues;
+    };
+
+    // Check for presence of ID duplicates
+    Sentence.prototype.validateUniqueIds = function(issues) {
+        issues = (issues !== undefined ? issues : []);
+
+        var initialIssueCount = issues.length;
+        var elementById = {};
+
+        for (var i=0; i<this.elements.length; i++) {
+            var element = this.elements[i];
+            if (elementById[element.id] !== undefined) {
+                this.addError('non-unique ID "'+element.id+'"',
+                              element, issues);
+            }
+            elementById[element.id] = element;
+        }
+
+        return issues.length === initialIssueCount;
+    };
+
+    // Check validity of word ID sequence (should be 1,2,3,...)
+    Sentence.prototype.validateWordSequence = function(issues) {
+        issues = (issues !== undefined ? issues : []);
+
+        var initialIssueCount = issues.length;
+        var expectedId = 1;
+
+        for (var i=0; i<this.elements.length; i++) {
+            var element = this.elements[i];
+
+            if (element.isMultiword() || element.isEmptyNode()) {
+                continue; // only check simple word sequence here
+            }
+            
+            if (parseInt(element.id, 10) !== expectedId) {
+                this.addError('word IDs should be 1,2,3,..., ' +
+                              'expected '+expectedId+', got '+element.id,
+                              element, issues);
+            }
+            expectedId = parseInt(element.id, 10) + 1;
+        }
+
+        return issues.length === initialIssueCount;
+    };
+
+    // Check that multiword token ranges are valid
+    Sentence.prototype.validateMultiwordSequence = function(issues) {
+        issues = (issues !== undefined ? issues : []);
+
+        var initialIssueCount = issues.length;
+        var expectedId = 1;
+
+        for (var i=0; i<this.elements.length; i++) {
+            var element = this.elements[i];
+
+            if (element.isMultiword() && element.rangeFrom() !== expectedId) {
+                this.addError('multiword tokens must appear before '+
+                              'first word in their range',
+                              element, issues);
+            } else {
+                expectedId = parseInt(element.id, 10) + 1;
+            }
+        }
+
+        return issues.length === initialIssueCount;
+    };
+
+    Sentence.prototype.validateEmptyNodeSequence = function(issues) {
+        issues = (issues !== undefined ? issues : []);
+
+        var initialIssueCount = issues.length;
+        var previousWordId = '0';    // TODO check https://github.com/UniversalDependencies/docs/issues/382
+        var nextEmptyNodeId = 1;
+
+        for (var i=0; i<this.elements.length; i++) {
+            var element = this.elements[i];
+
+            if (element.isWord()) {
+                previousWordId = element.id;
+                nextEmptyNodeId = 1;
+            } else if (element.isEmptyNode()) {
+                var expectedId = previousWordId + '.' + nextEmptyNodeId;
+                if (element.id !== expectedId) {
+                    this.addError('empty node IDs should be *.1, *.2, ... ' +
+                                  'expected '+expectedId+', got '+element.id,
+                                  element, issues);
+                }
+                nextEmptyNodeId++;
+            }
+        }
+
+        return issues.length === initialIssueCount;
+    }
+
+    // Check validity of ID references in HEAD and DEPS.
+    Sentence.prototype.validateReferences = function(issues) {
+        issues = (issues !== undefined ? issues : []);
+        
+        var initialIssueCount = issues.length;
+        var elementById = this.elementById();
+
+        for (var i=0; i<this.elements.length; i++) {
+            var element = this.elements[i];
+
+            // validate HEAD
+            if (!element.validHeadReference(elementById)) {
+                this.addError('HEAD is not valid ID: "'+element.head+'"',
+                              element, issues);
+            }
+            
+            // validate DEPS
+            var elemDeps = element.dependencies(true);
+            for (var j=0; j<elemDeps.length; j++) {
+                var head = elemDeps[j][1];
+                if (head !== '0' && elementById[head] === undefined) {
+                    this.addError('invalid ID "'+head+'" in DEPS',
+                                  element, issues);
+                }
+            }
+        }
+
+        return issues.length === initialIssueCount;
+    };
+
+    Sentence.prototype.repair = function(log) {
+        log = (log !== undefined ? log : nullLogger);
+
+        if (!this.validateUniqueIds()) {
+            this.repairUniqueIds(log);
+        }
+
+        if (!this.validateWordSequence()) {
+            this.repairWordSequence(log);
+        }
+
+        if (!this.validateMultiwordSequence()) {
+            this.repairMultiwordSequence(log);
+        }
+
+        if (!this.validateEmptyNodeSequence()) {
+            this.repairEmptyNodeSequence(log);
+        }
+
+        if (!this.validateReferences()) {
+            this.repairReferences(log);
+        }
+
+        var issues = this.validate();
+        return issues.length === 0;
+    };
+
+    Sentence.prototype.repairUniqueIds = function(log) {
+        log = (log !== undefined ? log : nullLogger);
+
+        var elementById = {},
+            filtered = [];
+
+        for (var i=0; i<this.elements.length; i++) {
+            var element = this.elements[i];
+            if (elementById[element.id] === undefined) {
+                elementById[element.id] = element;
+                filtered.push(element);
+            } else {
+                log('repair: remove element with duplicate ID "'+element.id+'"');
+            }
+        }
+        this.elements = filtered;
+    
+        return true;
+    };
+
+    Sentence.prototype.repairWordSequence = function(log) {
+        log('TODO: implement ConllU.Sentence.repairWordSequence()');
+        return true;
+    };
+
+    Sentence.prototype.repairMultiwordSequence = function(log) {
+        log('TODO: implement ConllU.Sentence.repairMultiwordSequence()');
+        return true;
+    };
+
+    Sentence.prototype.repairEmptyNodeSequence = function(log) {
+        log('TODO: implement ConllU.Sentence.repairEmptyNodeSequence()');
+        return true;
+    };
+
+    Sentence.prototype.repairReferences = function(log) {
+        log = (log !== undefined ? log : nullLogger);
+
+        var elementById = this.elementById();
+
+        for (var i=0; i<this.elements.length; i++) {
+            var element = this.elements[i];
+
+            // repair HEAD if not valid
+            if (!element.validHeadReference(elementById)) {
+                log('repair: blanking invalid HEAD');
+                element.head = null;
+            }
+
+            // repair DEPS if not valid
+            if (element.deps === '_') {
+                continue;
+            }
+            var deparr = element.deps.split('|'),
+                filtered = [];
+            for (var j=0; j<deparr.length; j++) {
+                var dep = deparr[j];
+                var m = dep.match(dependencyRegex);
+                if (m) {
+                    var head = m[1], deprel = m[2];
+                    if (head === '0' || elementById[head] !== undefined) {
+                        filtered.push(dep);
+                    } else {
+                        log('repair: removing invalid ID from DEPS');
+                        error = true;
+                    }
+                } else {
+                    console.log('internal error: repairReferences(): ' +
+                                'invalid DEPS');
+                }
+            }
+            if (filtered.length === 0) {
+                element.deps = '_';
+            } else {
+                element.deps = filtered.join('|');
+            }
+        }
+        return true;
+    };
+
+    /*
+     * ConllU.Element: represents CoNLL-U word or multiword token
+     */
+
+    // represents CoNLL-U word or multiword token
+    var Element = function(fields, lineidx, line) {
+        this.id = fields[0];
+        this.form = fields[1];
+        this.lemma = fields[2];
+        this.upostag = fields[3];
+        this.xpostag = fields[4];
+        this.feats = fields[5];
+        this.head = fields[6];
+        this.deprel = fields[7];
+        this.deps = fields[8];
+        this.misc = fields[9];
+        this.lineidx = lineidx;
+        this.line = line;
+    };
+
+    // constraints that hold for all fields
+    Element.prototype.validateField = function(field, name, issues,
+                                               allowSpace) {
+        name = (name !== undefined ? name : 'field');
+        issues = (issues !== undefined ? issues : []);
+        if (allowSpace === undefined) {
+            allowSpace = false;
+        }
+
+        if (field === undefined) {
+            issues.push('invalid '+name);
+            return false;
+        } else if (field.length === 0) {
+            issues.push(name+' must not be empty: "'+field+'"');
+            return false;
+        } else if (hasSpace(field) && !allowSpace) {
+            issues.push(name+' must not contain space: "'+field+'"');
+            return false;
+        } else {
+            return true;
+        }
+    };
+
+    Element.prototype.validateId = function(id, issues) {
+        issues = (issues !== undefined ? issues : []);
+        
+        if (!this.validateField(id, 'ID', issues)) {
+            return false;
+        } else if (id.match(/^\d+$/)) {
+            if (id === '0') {
+                issues.push('ID indices must start from 1: "'+id+'"');
+                return false;
+            } else {
+                return true;
+            }
+        } else if (id.match(/^(\d+)-(\d+)$/)) {
+            m = id.match(/^(\d+)-(\d+)$/);
+            if (!m) {
+                console.log('internal error');
+                return false;
+            }
+            var start = parseInt(m[1], 10), 
+                end = parseInt(m[2], 10);
+            if (end < start) {
+                issues.push('ID ranges must have start <= end: "'+id+'"');
+                return false;
+            } else {
+                return true;
+            }
+        } else if (id.match(/^(\d+)\.(\d+)$/)) {
+            m = id.match(/^(\d+)\.(\d+)$/);
+            if (!m) {
+                console.log('internal error');
+                return false;
+            }
+            var iPart = parseInt(m[1], 10),
+                fPart = parseInt(m[2], 10);
+            if (iPart == 0 || fPart == 0) {
+                issues.push('ID indices must start from 1: "'+id+'"');
+                return false;
+            } else {
+                return true;
+            }
+        } else {
+            issues.push('ID must be integer, range, or decimal: "'+id+'"');
+            return false;
+        }
+    };
+
+    Element.prototype.validateForm = function(form, issues) {
+        issues = (issues !== undefined ? issues : []);
+        
+        if (!this.validateField(form, 'FORM', issues, true)) {
+            return false;
+        } else {
+            return true;
+        }
+    };
+
+    Element.prototype.validateLemma = function(lemma, issues) {
+        issues = (issues !== undefined ? issues : []);
+        
+        if (!this.validateField(lemma, 'LEMMA', issues, true)) {
+            return false;
+        } else {
+            return true;
+        }
+    };
+    
+    Element.prototype.validateUpostag = function(upostag, issues) {
+        issues = (issues !== undefined ? issues : []);
+        
+        if (!this.validateField(upostag, 'UPOSTAG', issues)) {
+            return false;
+        } else {
+            return true;
+        }
+    };
+
+    Element.prototype.validateXpostag = function(xpostag, issues) {
+        issues = (issues !== undefined ? issues : []);
+        
+        if (!this.validateField(xpostag, 'XPOSTAG', issues)) {
+            return false;
+        } else {
+            return true;
+        }
+    };
+
+    Element.prototype.validateFeats = function(feats, issues) {
+        issues = (issues !== undefined ? issues : []);
+        
+        if (!this.validateField(feats, 'FEATS', issues)) {
+            return false;
+        } else if (feats === '_') {
+            return true;
+        }
+        var initialIssueCount = issues.length;
+        var featarr = feats.split('|');
+        var featmap = {};
+        var prevName = null;
+        for (var i=0; i<featarr.length; i++) {
+            var feat = featarr[i];
+            var m = feat.match(featureRegex);
+            if (!m) {
+                // TODO more descriptive issue
+                issues.push('invalid FEATS entry: "'+feat+'"');
+                continue;
+            }
+            var name = m[1], valuestr = m[2];
+            if (prevName !== null && 
+                name.toLowerCase() < prevName.toLowerCase()) {
+                issues.push('features must be ordered alphabetically ' +
+                            '(case-insensitive): "'+name+'" < "'+prevName+'"');
+                noIssue = false;
+            }
+            prevName = name;
+            var values = valuestr.split(',');
+            var valuemap = {}, validValues = [];
+            for (var j=0; j<values.length; j++) {
+                var value = values[j];
+                var m = value.match(featureValueRegex);
+                if (!m) {
+                    issues.push('invalid FEATS value: "'+value+'"');
+                    continue;
+                }
+                if (valuemap[value] !== undefined) {
+                    issues.push('duplicate feature value: "'+value+'"');
+                    continue;
+                }
+                valuemap[value] = true;
+                validValues.push(value);
+            }
+            if (featmap[name] !== undefined) {
+                issues.push('duplicate feature name: "'+name+'"');
+                continue;
+            }
+            if (validValues.length !== 0) {
+                featmap[name] = validValues;
+            }
+        }
+        return issues.length === initialIssueCount;
+    };
+
+    Element.prototype.validateHead = function(head, issues) {
+        issues = (issues !== undefined ? issues : []);
+
+        // TODO: consider checking that DEPREL is "root" iff HEAD is 0.
+        
+        if (head === null) {
+            return true; // exceptional case for Element.repair()
+        } else if (!this.validateField(head, 'HEAD', issues)) {
+            return false;
+        } else if (this.isEmptyNode() && head === '_') {
+            return true; // underscore permitted for empty nodes.
+        } else if (!head.match(/^\d+$/)) {
+            issues.push('HEAD must be an ID or zero: "'+head+'"');
+            return false;
+        } else {
+            return true;
+        }
+    };
+
+    Element.prototype.validateDeprel = function(deprel, issues) {
+        issues = (issues !== undefined ? issues : []);
+
+        if (!this.validateField(deprel, 'DEPREL', issues)) {
+            return false;
+        } else {
+            return true;
+        }
+    };
+
+    Element.prototype.validateDeps = function(deps, issues) {
+        issues = (issues !== undefined ? issues : []);
+
+        // TODO: consider checking that deprel is "root" iff head is 0.
+
+        if (!this.validateField(deps, 'DEPS', issues)) {
+            return false;
+        } else if (deps === '_') {
+            return true;
+        }
+        var deparr = deps.split('|');
+        var prevHead = null;
+        // TODO: don't short-circuit on first error
+        for (var i=0; i<deparr.length; i++) {
+            var dep = deparr[i];
+            m = dep.match(/^(\d+(?:\.\d+)?):(\S+)$/);
+            if (!m) {
+                // TODO more descriptive issue
+                issues.push('invalid DEPS: "'+deps+'"');
+                return false;
+            }
+            var head = m[1], deprel = m[2];
+            if (prevHead !== null &&
+                parseFloat(head) < parseFloat(prevHead)) {
+                issues.push('DEPS must be ordered by head index');
+                return false;
+            }
+            prevHead = head;
+        }
+        return true;
+    };
+
+    Element.prototype.validateMisc = function(misc, issues) {
+        issues = (issues !== undefined ? issues : []);
+
+        if (!this.validateField(misc, 'MISC', issues)) {
+            return false;
+        } else {
+            return true;
+        }
+    };
+
+    Element.prototype.validHeadReference = function(elementById) {
+        return (this.head === '_' || this.head === null || this.head === '0' ||
+                elementById[this.head] !== undefined);
+    };
+
+    Element.prototype.isWord = function() {
+        // word iff ID is an integer
+        return !!this.id.match(/^\d+$/);
+    };
+
+    Element.prototype.isMultiword = function() {
+        return !!this.id.match(/^\d+-\d+$/);
+    };
+
+    Element.prototype.isEmptyNode = function() {
+        return !!this.id.match(/^\d+\.\d+$/);
+    };
+
+    Element.prototype.rangeFrom = function() {
+        return parseInt(this.id.match(/^(\d+)-\d+$/)[1], 10);
+    };
+
+    Element.prototype.rangeTo = function() {
+        return parseInt(this.id.match(/^\d+-(\d+)$/)[1], 10);
+    };
+
+    Element.prototype.isToken = function(inRange) {
+        // token iff multiword or not included in a multiword range
+        return this.isMultiword() || !inRange[this.id];
+    };
+
+    // return list of (DEPENDENT, HEAD, DEPREL) lists
+    Element.prototype.dependencies = function(skipHead) {
+        skipHead = (skipHead !== undefined ? skipHead : false);
+
+        var elemDeps = [];
+        if (!skipHead && this.head !== '_' && this.head !== null) {
+            elemDeps.push([this.id, this.head, this.deprel]);
+        }
+        if (this.deps != '_') {
+            var deparr = this.deps.split('|');
+            for (var i=0; i<deparr.length; i++) {
+                var dep = deparr[i];
+                m = dep.match(dependencyRegex);
+                if (m) {
+                    elemDeps.push([this.id, m[1], m[2]]);
+                } else {
+                    console.log('internal error: dependencies(): invalid DEPS',
+                                this.deps);
+                }
+            }
+        }
+        return elemDeps;
+    }
+
+    // return list of (name, value) pairs
+    Element.prototype.features = function() {
+        var nameVals = [];
+        if (this.feats === '_') {
+            return [];
+        }
+        var featarr = this.feats.split('|');
+        for (var i=0; i<featarr.length; i++) {
+            var feat = featarr[i];
+            var m = feat.match(featureRegex);
+            if (!m) {
+                continue;
+            }
+            var name = m[1], valuestr = m[2];
+            var values = valuestr.split(',');
+            for (var j=0; j<values.length; j++) {
+                var value = values[j];
+                var m = value.match(featureValueRegex);
+                if (!m) {
+                    continue;
+                }
+                nameVals.push([name, value]);
+            }
+        }
+        return nameVals;
+    };
+
+    // Check validity of the element. Return list of strings
+    // representing issues found in validation (empty list if none).
+    Element.prototype.validate = function() {
+        var issues = [];
+
+        this.validateId(this.id, issues);
+        this.validateForm(this.form, issues);
+        
+        // multiword tokens (elements with range IDs) are (locally) valid
+        // iff all remaining fields (3-10) contain just an underscore.
+        if (this.isMultiword()) {
+            if (this.lemma != '_' || 
+                this.upostag != '_' ||
+                this.xpostag != '_' ||
+                this.feats != '_' ||
+                this.head != '_' ||
+                this.deprel != '_' ||
+                this.deps != '_' ||
+                this.misc != '_') {
+                issues.push('non-underscore field for multiword token');
+            }
+            return issues;
+        }
+        // if we're here, not a multiword token.
+
+        this.validateLemma(this.lemma, issues);
+        this.validateUpostag(this.upostag, issues);
+        this.validateXpostag(this.xpostag, issues);
+        this.validateFeats(this.feats, issues);
+        this.validateHead(this.head, issues);
+        this.validateDeprel(this.deprel, issues);
+        this.validateDeps(this.deps, issues);
+        this.validateMisc(this.misc, issues);
+
+        return issues;
+    };
+
+    // Attempt to repair a non-valid element. Return true iff the
+    // element is valid following repair, false otherwise.
+    Element.prototype.repair = function(log) {
+        log = (log !== undefined ? log : nullLogger);
+
+        if (!this.validateId(this.id)) {
+            return false; // can't be helped
+        } 
+
+        if (!this.validateForm(this.form)) {
+            log('repair: blanking invalid FORM');
+            this.form = '<ERROR>';
+        }
+
+        if (this.isMultiword()) {
+            // valid as long as everything is blank
+            this.lemma = '_'; 
+            this.upostag = '_';
+            this.xpostag = '_';
+            this.feats = '_';
+            this.head = '_';
+            this.deprel = '_';
+            this.deps = '_';
+            this.misc = '_';
+            return true;
+        }
+        // if we're here, not a multiword token.
+
+        if(!this.validateLemma(this.lemma)) {
+            log('repair: blanking invalid LEMMA');
+            this.lemma = '<ERROR>';
+        }
+
+        if(!this.validateUpostag(this.upostag)) {
+            log('repair: blanking invalid UPOSTAG');
+            this.upostag = '_'; // TODO: not valid
+        }
+
+        if(!this.validateXpostag(this.xpostag)) {
+            log('repair: blanking invalid XPOSTAG');
+            this.xpostag = '_';
+        }
+
+        if(!this.validateFeats(this.feats)) {
+            log('repair: blanking invalid FEATS');
+            this.feats = '_';
+        }
+
+        if(!this.validateHead(this.head)) {
+            log('repair: blanking invalid HEAD');
+            this.head = null; // note: exceptional case
+        }
+
+        if(!this.validateDeprel(this.deprel)) {
+            log('repair: blanking invalid DEPREL');
+            this.deprel = '_'; // TODO: not valid
+        }
+
+        if(!this.validateDeps(this.deps)) {
+            log('repair: blanking invalid DEPS');
+            this.deps = '_';
+        }
+
+        if(!this.validateMisc(this.misc)) {
+            log('repair: blanking invalid MISC');
+            this.misc = '_';
+        }
+
+        var issues = this.validate();
+        return issues.length === 0;
+    };
+
+    /*
+     * Miscellaneous support functions.
+     */
+
+    var repairFields = function(fields, logger) {
+        if (logger === undefined) {
+            logger = nullLogger;
+        }
+        if (fields.length > 10) {
+            logger('repair: discarding fields > 10');
+            fields = fields.slice(0, 10);
+        } else {
+            logger('repair: filling in empty ("_") for missing fields');
+            for (var m=0; m<10-fields.length; m++) {
+                fields.push('_');
+            }
+        }
+    };
+
+    var strictFieldSplitter = function(line) {
+        // strict CoNLL format parsing: only split on TAB, no extra space.
+        if (line.length === 0) {
+            return [];
+        } else {
+            return line.split('\t');
+        }
+    }
+
+    var looseFieldSplitter = function(line) {
+        // loose CoNLL format parsing: split on any space sequence, trim
+        // surrounding space.    
+        line = line.trim();
+        if (line.length === 0) {
+            return [];
+        } else {
+            return line.split(/\s+/);
+        }
+    }
+
+    var selectParsingMode = function(conll, log) {
+        // return whether to use strict mode parsing
+
+        // very simple heuristic: any TABs in the input trigger
+        // strict parsing, loose only if none present.
+        if (conll.indexOf('\t') !== -1) {
+            log('note: TAB found, parsing CoNLL-U in strict mode.')
+            return true;
+        } else {
+            log('note: no TAB found, parsing CoNLL-U in loose mode.')
+            return false;
+        }
+    };
+
+    var selectFieldSplitter = function(conll, log, strict) {
+        // return function to use for dividing lines into fields.
+        if (strict) {
+            return strictFieldSplitter;
+        } else {
+            return looseFieldSplitter;
+        }
+    };
+
+    var isComment = function(line) {
+        return line.length !== 0 && line[0] === '#';
+    };
+
+    var hasSpace = function(s) {
+        return !!s.match(/\s/);
+    };
+
+    var nullLogger = function(message) {
+        return null;
+    }
+
+    /* 
+     * Return true iff given string only contains characters from a
+     * right-to-left Unicode block and is not empty.
+     */
+    var isRtl = function(s) {
+        // range from http://stackoverflow.com/a/14824756
+        return !!s.match(/^[\u0591-\u07FF\uFB1D-\uFDFD\uFE70-\uFEFC]+$/);
+    };
+
+    /*
+     * Return given token with possible modifications to accommodate
+     * issues in brat rendering of right-to-left text
+     * (https://github.com/UniversalDependencies/docs/issues/52)
+     */
+    var rtlFix = function(s) {
+        var prefix = '\u02D1',
+            suffix = '\u02D1';
+        if (isRtl(s)) {
+            s = prefix + s + suffix;
+        }
+        return s;
+    };
+
+    /*
+     * Return a deep copy of the given object. Note: not particularly
+     * efficient, and all fields must be serializable for this to work
+     * correctly.
+     */
+    var deepCopy = function(o) {
+        return JSON.parse(JSON.stringify(o));
+    };
+
+    /*
+     * Regular expressions for various parts of the format.
+     * See https://github.com/UniversalDependencies/docs/issues/33
+     */
+
+    // match single (feature, value[s]) pair in FEATS
+    var featureRegex = /^([A-Z0-9][a-zA-Z0-9]*(?:\[[a-z0-9]+\])?)=([A-Z0-9][a-zA-Z0-9]*(?:,[A-Z0-9][a-zA-Z0-9]*)*)$/;
+
+    // match single feature value in FEATS
+    var featureValueRegex = /^[A-Z0-9][a-zA-Z0-9]*$/;
+
+    // match single (head, deprel) pair in DEPS
+    var dependencyRegex = /^(\d+(?:\.\d+)?):(.*)$/;
+
+    return {
+	Document: Document,
+	Sentence: Sentence,
+        Element: Element,
+    };
+
+})(window);

Property changes on: TXM/trunk/org.txm.conllu.core/groovy/org/txm/scripts/importer/conllu/conllu.js
___________________________________________________________________
Added: svn:mime-type
   + text/plain

Index: TXM/trunk/org.txm.conllu.core/groovy/org/txm/scripts/importer/conllu/conlluLoader.groovy
===================================================================
--- TXM/trunk/org.txm.conllu.core/groovy/org/txm/scripts/importer/conllu/conlluLoader.groovy	(revision 0)
+++ TXM/trunk/org.txm.conllu.core/groovy/org/txm/scripts/importer/conllu/conlluLoader.groovy	(revision 3567)
@@ -0,0 +1,57 @@
+// Copyright © 2010-2013 ENS de Lyon.
+// Copyright © 2007-2010 ENS de Lyon, CNRS, INRP, University of
+// Lyon 2, University of Franche-Comté, University of Nice
+// Sophia Antipolis, University of Paris 3.
+//
+// The TXM platform is free software: you can redistribute it
+// and/or modify it under the terms of the GNU General Public
+// License as published by the Free Software Foundation,
+// either version 2 of the License, or (at your option) any
+// later version.
+//
+// The TXM platform is distributed in the hope that it will be
+// useful, but WITHOUT ANY WARRANTY; without even the implied
+// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+// PURPOSE. See the GNU General Public License for more
+// details.
+//
+// You should have received a copy of the GNU General
+// Public License along with the TXM platform. If not, see
+// http://www.gnu.org/licenses.
+//
+//
+//
+// $LastChangedDate: 2015-06-03 15:04:53 +0200 (mer., 03 juin 2015) $
+// $LastChangedRevision: 2984 $
+// $LastChangedBy: mdecorde $
+//
+package org.txm.scripts.importer.conllu;
+
+import javax.xml.stream.*
+
+import org.txm.*
+import org.txm.metadatas.*
+import org.txm.objects.*
+import org.txm.importer.scripts.xmltxm.*
+import org.txm.utils.*
+import org.txm.utils.i18n.*
+import org.txm.importer.xtz.*
+
+String userDir = System.getProperty("user.home");
+
+def MONITOR;
+Project project;
+
+try {project=projectBinding;MONITOR=monitor} catch (Exception)
+{	}
+if (project == null) { println "no project set. Aborting"; return; }
+CoNLLUImport i = new CoNLLUImport(project);
+/*
+ * To customize the XTZ import, replace the importer, compiler, annotater or pager objects before calling process()
+		i.importer = new XTZImporter(i)
+		i.compiler = new XTZCompiler(i)
+		i.annotater = new TTAnnotater(i);
+		i.pager = new XTZPager(i)
+ */
+i.process();
+readyToLoad = i.isSuccessful && project.save()
Index: TXM/trunk/org.txm.conllu.core/groovy/org/txm/scripts/importer/conllu/CoNLLUImport.groovy
===================================================================
--- TXM/trunk/org.txm.conllu.core/groovy/org/txm/scripts/importer/conllu/CoNLLUImport.groovy	(revision 0)
+++ TXM/trunk/org.txm.conllu.core/groovy/org/txm/scripts/importer/conllu/CoNLLUImport.groovy	(revision 3567)
@@ -0,0 +1,122 @@
+package org.txm.scripts.importer.conllu;
+
+import java.io.File;
+import java.util.ArrayList;
+
+import ims.tiger.index.writer.*
+import ims.tiger.system.*
+
+import org.txm.Toolbox;
+import org.txm.importer.ApplyXsl2;
+import org.txm.importer.xtz.*
+import org.txm.objects.Project
+import org.txm.utils.io.FileCopy;
+import org.txm.utils.io.IOUtils
+import org.apache.log4j.BasicConfigurator;
+import org.txm.importer.xtz.*
+import org.txm.scripts.importer.xtz.*
+import org.txm.scripts.importer.tigersearch.TSImport
+import org.txm.utils.*
+import org.txm.searchengine.ts.TIGERSearchEngine
+import org.txm.conllu.core.preferences.UDPreferences
+import org.txm.tigersearch.preferences.TigerSearchPreferences
+import org.txm.conllu.core.CallUD2TigerPerlScript
+
+class CoNLLUImport extends XTZImport {
+	
+	public CoNLLUImport(Project params) {
+		super(params);
+	}
+	
+	@Override
+	public void init(Project p) {
+		super.init(p);
+		
+		importer = new CoNLLUImporter(this);
+		compiler = new XTZCompiler(this)
+		annotater = null; // no annotater step to do
+		pager = new XTZPager(this)
+	}
+	
+	/**
+	 * Do a XTZ Import then build the TIGERSearch indexes in the binary corpus "tiger" directory
+	 */
+	@Override
+	public void start() throws InterruptedException {
+		
+		super.start(); // call the usual XTZ import
+		
+		// build the TIGER-XML file
+		CallUD2TigerPerlScript cutps = new CallUD2TigerPerlScript();
+		
+		boolean buildtigerindexes =  UDPreferences.getInstance().getString(UDPreferences.IMPORT_BUILD_TIGERSEARCH_INDEXES); // THE conllu -> Tiger XSL MUST HAVE THE SAME BEHAVIOR BEFORE //
+		if (!buildtigerindexes) {
+			println "Skipping TIGER conversion step."
+			return;
+		}
+		
+		if (cutps.canBuildTSFiles()) {
+			
+			println "Converting CoNLL-U files to TIGER-XML files..."
+			
+			File conlluDirectory = new File(this.binaryDirectory, "conllu")
+			cutps.convertCoNLLUFiles(conlluDirectory.listFiles(), this.binaryDirectory.getAbsolutePath())
+			
+			File tigerXMLDirectory = new File(this.binaryDirectory, "tiger-xml")
+			String driverFilename = TigerSearchPreferences.getInstance().getString(TigerSearchPreferences.DRIVER_FILENAME);
+			File xslfile1 = BundleUtils.getFile("org.txm.conllu.core", "groovy", "/org/txm/scripts/importer/conllu/", "tigerXml-commentOutLongSentences.xsl")
+			//File xslfile2 = BundleUtils.getFile("org.txm.conllu.core", "groovy", "/org/txm/scripts/importer/conllu/", "tigerXml-sortBfmByDate.xsl")
+			
+			println "Post-processing TIGER-XML files..."
+			ApplyXsl2 a1 = new ApplyXsl2(xslfile1);
+			//ApplyXsl2 a2 = new ApplyXsl2(xslfile2);
+			for (File xmlFile : tigerXMLDirectory.listFiles()) {
+				
+				if (!xmlFile.getName().endsWith(".xml")) continue;
+				if (xmlFile.getName().equals(driverFilename)) continue; // don't process the driver
+				
+				File xmlFileTmp = new File(xmlFile.getAbsolutePath()+".tmp")
+				if (!(a1.process(xmlFile, xmlFileTmp) && xmlFile.delete() && xmlFileTmp.renameTo(xmlFile))) {
+					println "Error while applying $xslfile1 to $xmlFile"
+				}
+				
+//				if (!(a2.process(xmlFile, xmlFileTmp) && xmlFile.delete() && xmlFileTmp.renameTo(xmlFile))) {
+//					println "Error while applying $xslfile2 to $xmlFile"
+//				}
+			}
+			
+			println "Patching TIGER-XML driver file..."
+			def tigerxmlFiles = []
+			def xmltxmFilesNames = this.getTXMFilesOrder();
+			//println "xml-txm files: "+xmltxmFilesNames
+			for (String name : xmltxmFilesNames) {
+				name = FileUtils.stripExtension(name);
+				
+				File connluFile = new File(this.binaryDirectory, "tiger-xml/"+name+".xml")
+				//println " test "+connluFile
+				if (connluFile.exists()) {
+					tigerxmlFiles << connluFile
+				}
+			}
+			
+			// patch the subcorpus tags in the driver XML file with the right corpus order
+			File driver = new File(this.binaryDirectory, "tiger-xml/"+driverFilename)
+			String content = IOUtils.getText(driver, "UTF-8");
+			content = content.replaceAll("<subcorpus .+\n", "");
+			String subcorpusList = "";
+			for (String name : xmltxmFilesNames) {
+				name = FileUtils.stripExtension(name);
+				subcorpusList += "<subcorpus name=\"$name\" external=\"file:${name}.xml\"/>\n"
+			}
+			content = content.replaceAll("<body>", "<body>\n"+subcorpusList+"\n"); // get the last main.xml content and patch it with the subcorpus tags
+			IOUtils.setText(driver, content, "UTF-8");
+			// build TIGER indexes
+			if (isSuccessful) {
+				// read from the 'tiger-xml' and write to the 'tiger' directory
+				TIGERSearchEngine.buildTIGERCorpus(tigerXMLDirectory, this.binaryDirectory, corpusName);
+			}
+		} else {
+			println "Can not do the TIGER indexes step."
+		}
+	}
+}
\ No newline at end of file
Index: TXM/trunk/org.txm.conllu.core/src/org/txm/conllu/core/Sentences.java
===================================================================
--- TXM/trunk/org.txm.conllu.core/src/org/txm/conllu/core/Sentences.java	(revision 0)
+++ TXM/trunk/org.txm.conllu.core/src/org/txm/conllu/core/Sentences.java	(revision 3567)
@@ -0,0 +1,43 @@
+package org.txm.conllu.core;
+
+import java.util.ArrayList;
+
+public class Sentences extends ArrayList<Sentence> {
+	
+	private static final long serialVersionUID = 5706212463880734916L;
+	
+	/**
+	 * replace the ud id with the misc XmlId value
+	 * A word with no misc XmlId is removed
+	 */
+	public void replaceIdwithXmlId() {
+		
+		for (Sentence s : this) {
+			
+			s.replaceIdwithXmlId();
+		}
+	}
+	
+	/**
+	 * merge the part word lines in the n-m word lines (the part are removed
+	 */
+	public void removePartTokensWords() {
+		
+		for (Sentence s : this) {
+			
+			s.removePartTokensWords();
+		}
+	}
+	
+	/**
+	 * removes the n-m word lines
+	 */
+	public void removeMultiTokensWords() {
+		
+		for (Sentence s : this) {
+			
+			s.removeMultiTokensWords();
+		}
+	}
+	
+}

Property changes on: TXM/trunk/org.txm.conllu.core/src/org/txm/conllu/core/Sentences.java
___________________________________________________________________
Added: svn:mime-type
   + text/plain

Index: TXM/trunk/org.txm.conllu.core/src/org/txm/conllu/core/CallUD2TigerPerlScript.java
===================================================================
--- TXM/trunk/org.txm.conllu.core/src/org/txm/conllu/core/CallUD2TigerPerlScript.java	(revision 0)
+++ TXM/trunk/org.txm.conllu.core/src/org/txm/conllu/core/CallUD2TigerPerlScript.java	(revision 3567)
@@ -0,0 +1,95 @@
+package org.txm.conllu.core;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Comparator;
+
+import org.eclipse.core.runtime.IStatus;
+import org.txm.core.engines.ScriptEngine;
+import org.txm.core.engines.ScriptEnginesManager;
+import org.txm.tigersearch.preferences.TigerSearchPreferences;
+import org.txm.utils.*;
+import org.txm.utils.io.IOUtils;
+import org.txm.utils.logger.Log;
+
+public class CallUD2TigerPerlScript {
+	
+	public boolean canBuildTSFiles() {
+		ScriptEngine engine = ScriptEnginesManager.getPerlEngine();
+		if (engine == null) {
+			Log.warning("No Perl script engine installed in TXM");
+			return false;
+		}
+		if (!engine.isRunning()) {
+			Log.warning("No Perl script engine ready in TXM. See Perl preferences.");
+			return false;
+		}
+		return true;
+	}
+	
+	public boolean convertCoNLLUFiles(File[] connluFiles, String output_directory) throws IOException {
+		
+		if (connluFiles.length == 0) return false;
+		
+		File tigerXMLDirectory = new File(output_directory, "tiger-xml");
+		File conversionFile = new File(tigerXMLDirectory, "conversion.log");
+		
+		String driverFilename = TigerSearchPreferences.getInstance().getString(TigerSearchPreferences.DRIVER_FILENAME);
+		File mainFullFile = new File(tigerXMLDirectory, driverFilename);
+		
+		File mainFile = new File(tigerXMLDirectory, "main.xml");
+		File perlScript = BundleUtils.getFile("org.txm.conllu.core", "groovy", "/org/txm/scripts/importer/conllu/", "conll2tiger-ud.pl");
+		
+		DeleteDir.deleteDirectory(tigerXMLDirectory);
+		//println "clean&mkdir $tigerXMLDirectory"
+		tigerXMLDirectory.mkdir();
+		
+		//println "Converting..."
+		
+		String subcorpusList = "";
+
+		ConsoleProgressBar cpb = new ConsoleProgressBar(connluFiles.length);
+		for (File f : connluFiles) {
+			cpb.tick();
+			if (!f.getName().endsWith(".conllu")) {
+				continue;
+			}
+			
+			try {
+				//System.out.println("$f... "+"perl '$perlScript' -s 10000 -o '$tigerXMLDirectory' '$f'");
+				ScriptEngine engine = ScriptEnginesManager.getPerlEngine();
+				if (!engine.canExecute(perlScript)) {
+					System.out.println("Error: Perl engine not correctly set to run: "+perlScript);
+					return false;
+				}
+				ArrayList<String> cmd = new ArrayList<String>();
+				cmd.addAll(Arrays.asList("-s", "10000", "-o", tigerXMLDirectory.getAbsolutePath(), f.getAbsolutePath()));
+				//System.out.println("Calling perl with: "+perlScript+" and "+cmd);
+				IStatus status = engine.executeScript(perlScript, cmd);
+				for (String line : IOUtils.getLines(mainFile, "UTF-8")) {
+					if (line.contains("<subcorpus ")) {
+						subcorpusList += line+"\n";
+					}
+				}
+			} catch (Throwable t) { 
+				System.out.println("** Error: "+t+" at "+t.getStackTrace()[0]); 
+			}
+		}
+		cpb.done();
+		
+		//	println "subcorpus-list: "+subcorpusList
+		String content = IOUtils.getText(mainFile, "UTF-8");
+		content = content.replaceAll("<subcorpus .+\n", "");
+		content = content.replaceAll("<body>", "<body>\n"+subcorpusList+"\n"); // get the last main.xml content and patch it with the subcorpus tags
+		IOUtils.setText(mainFullFile, content, "UTF-8");
+		//mainFullFile.setText(mainFile.getText().replaceAll("<body/>", subcorpusList+"\n<body/>"));
+		
+		conversionFile.delete();
+		mainFile.delete();
+		
+		//println "Done."
+		return true;
+	}
+}
\ No newline at end of file

Property changes on: TXM/trunk/org.txm.conllu.core/src/org/txm/conllu/core/CallUD2TigerPerlScript.java
___________________________________________________________________
Added: svn:mime-type
   + text/plain

Index: TXM/trunk/org.txm.conllu.core/src/org/txm/conllu/core/CoNLLU2TIGER.java
===================================================================
--- TXM/trunk/org.txm.conllu.core/src/org/txm/conllu/core/CoNLLU2TIGER.java	(revision 0)
+++ TXM/trunk/org.txm.conllu.core/src/org/txm/conllu/core/CoNLLU2TIGER.java	(revision 3567)
@@ -0,0 +1,139 @@
+package org.txm.conllu.core;
+
+import java.io.BufferedOutputStream;
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.FilenameFilter;
+import java.io.IOException;
+import java.util.LinkedHashMap;
+
+import javax.xml.stream.XMLOutputFactory;
+import javax.xml.stream.XMLStreamException;
+import javax.xml.stream.XMLStreamWriter;
+
+import org.txm.utils.FileUtils;
+import org.txm.utils.logger.Log;
+
+/**
+ * Create a TIGER XML corpus from conllu files
+ * @author mdecorde
+ *
+ */
+public class CoNLLU2TIGER {
+	
+	File conlluDirectory;
+	File tigerDirectory;
+	String corpusName;
+	
+	
+	/** The output. */
+	protected XMLOutputFactory outfactory = XMLOutputFactory.newInstance();
+	
+	protected BufferedOutputStream tigerOutput;
+	protected XMLStreamWriter tigerWriter;
+	
+	protected BufferedOutputStream mainOutput;
+	protected XMLStreamWriter mainWriter;
+	
+	public CoNLLU2TIGER(File conlluDirectory, File tigerDirectory, String corpusName) {
+		
+		this.conlluDirectory = conlluDirectory;
+		this.tigerDirectory = tigerDirectory;
+		this.corpusName = corpusName;
+	}
+	
+	public boolean process() throws IOException, XMLStreamException {
+		File[] conlluFiles = conlluDirectory.listFiles( new FilenameFilter() {
+			
+			@Override
+			public boolean accept(File dir, String name) {
+				
+				return name.endsWith(".conllu");
+			}
+		});
+		
+		if (conlluFiles == null || conlluFiles.length == 0) {
+			Log.warning("** No CoNLLU file found in "+conlluDirectory);
+			return false;
+		}
+		
+		File mainFile = new File(tigerDirectory, "main.xml");
+		mainOutput = new BufferedOutputStream(new FileOutputStream(mainFile), 16 * 1024);
+		mainWriter = outfactory.createXMLStreamWriter(mainOutput, "UTF-8"); // create a new file
+		
+//		printf MASTER "<corpus id=\"$corpus\">
+		mainWriter.writeStartElement("corpus");
+		tigerWriter.writeAttribute("id", corpusName);
+		
+		for (File connluFile : conlluFiles) {
+			
+			
+			String filename = FileUtils.stripExtension(connluFile);
+			File tigerXMLFile = new File(tigerDirectory, filename+".xml");
+			tigerOutput = new BufferedOutputStream(new FileOutputStream(tigerXMLFile), 16 * 1024);
+			tigerWriter = outfactory.createXMLStreamWriter(tigerOutput, "UTF-8"); // create a new file
+			
+			CoNLLUReader reader = new CoNLLUReader(connluFile, null);
+			Sentence s = reader.readNext();
+			
+			// "<subcorpus name='$infilename-$suffix' external='file:$infilename-$suffix.xml'/>\n";
+			tigerWriter.writeEmptyElement("subcorpus");
+			tigerWriter.writeAttribute("name", tigerXMLFile.getName());
+			tigerWriter.writeAttribute("external", "file:"+tigerXMLFile.getName());
+			
+			while (s != null) { // write <s> <t> <nt> and <edge> elements for each sentence
+				
+//				printf XML "<s id=\"s%s%s\" textid=\"$text_id\" sentid=\"$sent_id\">\n", $., $add_to_sentcode;
+				tigerWriter.writeStartElement("s");
+				tigerWriter.writeAttribute("id", s.newdoc_id+"_"+s.sent_id);
+				tigerWriter.writeAttribute("textid", s.newdoc_id);
+				tigerWriter.writeAttribute("sentid", s.sent_id);
+				tigerWriter.writeAttribute("pid", s.newpar_id);
+				
+//				print XML "  <graph root=\"n$._$rootnode\">\n";
+				tigerWriter.writeStartElement("graph");
+				tigerWriter.writeAttribute("root", "._rootnode");
+				
+				// write terminals
+//				print XML "    <terminals>\n";
+				tigerWriter.writeStartElement("terminals");
+				for (String wordid : s.keySet()) {
+					LinkedHashMap<String, String> word = s.get(wordid);
+//					push(@terminals, sprintf("      <t id=\"s%d_%d\" word=\"%s\" pos=\"%s\" mor=\"%s\" lemma=\"%s\" textid=\"%s\" editionId=\"%s\"/>\n", $., $wnr, $word, $pos, $mor, $lemma, $text_id, $edition_id));
+//					push(@terminals, sprintf("      <t id=\"s%d_%d_dupl\" word=\"%s\" pos=\"%s\" mor=\"%s\" lemma=\"%s\" textid=\"%s\" editionId=\"%s\"/>\n", $., $wnr, "*", "_", "_", "_", $text_id, $edition_id));
+					tigerWriter.writeStartElement("t");
+					for (String attr : CoNLLUReader.UD_PROPERTY_NAMES) {
+						tigerWriter.writeAttribute(attr, word.get(attr));
+					}
+					if (s.newdoc_id != null && s.newdoc_id.length() > 0) {
+						tigerWriter.writeAttribute("textid", s.newdoc_id);
+					}
+					if (s.newpar_id != null && s.newpar_id.length() > 0) {
+						tigerWriter.writeAttribute("pid", s.newpar_id);
+					}
+					if (word.get("XmlId") != null) {
+						tigerWriter.writeAttribute("editionId", word.get("XmlId"));
+					}
+				}
+				tigerWriter.writeEndElement(); // terminals
+								
+				// write non-terminals
+				tigerWriter.writeStartElement("nonterminals");
+				for (String wordid : s.keySet()) {
+					
+				}
+				tigerWriter.writeEndElement(); // nonterminals
+				
+				tigerWriter.writeEndElement(); // graph
+				
+				tigerWriter.writeEndElement(); // s
+				
+				s = reader.readNext();
+			}
+			tigerWriter.writeEndElement(); // subcorpus
+			reader.close();
+		}
+		
+		return true;
+	}
+}

Property changes on: TXM/trunk/org.txm.conllu.core/src/org/txm/conllu/core/CoNLLU2TIGER.java
___________________________________________________________________
Added: svn:mime-type
   + text/plain

Index: TXM/trunk/org.txm.conllu.core/src/org/txm/conllu/core/InstallGroovyCoNLLUFiles.java
===================================================================
--- TXM/trunk/org.txm.conllu.core/src/org/txm/conllu/core/InstallGroovyCoNLLUFiles.java	(revision 0)
+++ TXM/trunk/org.txm.conllu.core/src/org/txm/conllu/core/InstallGroovyCoNLLUFiles.java	(revision 3567)
@@ -0,0 +1,53 @@
+package org.txm.conllu.core;
+
+import java.io.File;
+
+import org.txm.PostTXMHOMEInstallationStep;
+import org.txm.Toolbox;
+import org.txm.objects.Workspace;
+import org.txm.utils.BundleUtils;
+
+public class InstallGroovyCoNLLUFiles extends PostTXMHOMEInstallationStep {
+
+	final static String createfolders[] = {"scripts/groovy/lib", "scripts/groovy/user", "scripts/groovy/system"}; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
+	
+	@Override
+	public boolean do_install(Workspace workspace) {
+		File txmhomedir = new File(Toolbox.getTxmHomePath());
+		
+		for (String folder : createfolders) {
+			new File(txmhomedir, folder).mkdirs();
+		}
+		File scriptsDirectory = new File(txmhomedir, "scripts/groovy");
+		File userDirectory = new File(scriptsDirectory, "user");
+		File systemDirectory = new File(scriptsDirectory, "system");
+		
+		String bundle_id = "org.txm.conllu.core";
+		File scriptsPackageDirectory = new File(userDirectory, "org/txm/scripts/importer");
+		File scriptsPackageDirectory2 = new File(systemDirectory, "org/txm/scripts/importer");
+		scriptsPackageDirectory.mkdirs();
+		scriptsPackageDirectory2.mkdirs();
+		BundleUtils.copyFiles(bundle_id, "groovy", "org/txm/scripts/importer", "", scriptsPackageDirectory, true);
+		BundleUtils.copyFiles(bundle_id, "groovy", "org/txm/scripts/importer", "", scriptsPackageDirectory2, true);
+	
+		return scriptsDirectory.exists();
+	}
+
+	@Override
+	public String getName() {
+		return "UD (org.txm.conllu.core)";
+	}
+	
+	@Override
+	public boolean needsReinstall(Workspace workspace) {
+		File txmhomedir = new File(Toolbox.getTxmHomePath());
+		for (String folder : createfolders) {
+			if (!new File(txmhomedir, folder).exists()) {
+				return true;
+			}
+		}
+		
+		
+		return false;
+	}
+}

Property changes on: TXM/trunk/org.txm.conllu.core/src/org/txm/conllu/core/InstallGroovyCoNLLUFiles.java
___________________________________________________________________
Added: svn:mime-type
   + text/plain

Index: TXM/trunk/org.txm.conllu.core/src/org/txm/conllu/core/CoNLLUReader.java
===================================================================
--- TXM/trunk/org.txm.conllu.core/src/org/txm/conllu/core/CoNLLUReader.java	(revision 0)
+++ TXM/trunk/org.txm.conllu.core/src/org/txm/conllu/core/CoNLLUReader.java	(revision 3567)
@@ -0,0 +1,251 @@
+package org.txm.conllu.core;
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.LinkedHashMap;
+import java.util.Set;
+
+import javax.xml.stream.XMLStreamException;
+
+import org.txm.utils.io.IOUtils;
+import org.txm.utils.logger.Log;
+
+public class CoNLLUReader {
+	
+	public static final String[] UD_PROPERTY_NAMES = { "id", "form", "lemma", "upos", "xpos", "feats", "head", "deprel", "deps", "misc" };
+	
+	File coonluFile;
+	private String textId;
+	
+	BufferedReader reader;
+	int nLine = 0;
+	
+	private String line;
+
+	public CoNLLUReader(File coonluFile, String textId) {
+		this.coonluFile = coonluFile;
+		this.textId = textId;
+		
+		if (textId == null || textId.length() == 0) { // no text id provided, using the conllu file name
+			textId = coonluFile.getName().substring(0, coonluFile.getName().length() - 7);
+		}
+	}
+	
+	public Sentence readNext() throws IOException {
+		if (reader == null) {
+			reader = IOUtils.getReader(coonluFile);
+			nLine = 0;
+			line = null;
+		} else if (!reader.ready()) {
+			return null; // the reader is closed
+		}
+		
+		Sentence sentence = new Sentence();
+		sentence.newdoc_id = textId;
+		
+		if (line == null) {
+			line = reader.readLine();
+		}
+		
+		while (line != null) {
+			
+			nLine++;
+			if (line.length() == 0) {
+				line = reader.readLine();
+				continue; // comment
+			}
+			
+			if (line.startsWith("#")) {
+				if (line.startsWith("# sent_id = ")) {
+					
+					// write previous sentence word properties
+					if (sentence.nWords2 > 0) {
+						return sentence; // the line field will be used as it is
+					}
+					
+					sentence.sent_id = line.substring(12).trim();
+				}
+				else if (line.startsWith("# newdoc id = ")) {
+					sentence.newdoc_id = line.substring(14).trim();
+				}
+				else if (line.startsWith("# newpar id = ")) {
+					sentence.newpar_id = line.substring(14).trim();
+				}
+				else {
+					// nothing for now
+				}
+				
+				line = reader.readLine();
+				continue; // comment
+			}
+			
+			String[] split = line.split("\t", 10);
+			if (split.length < 10) {
+				Log.warning("Error: line " + nLine + " : " + line + " -> " + Arrays.toString(split) + " len=" + split.length);
+				line = reader.readLine();
+				continue; // comment
+			}
+			
+			LinkedHashMap<String, String> properties = new LinkedHashMap<>();
+			for (int i = 0; i < split.length; i++) {
+				properties.put(UD_PROPERTY_NAMES[i], split[i]); // add the property name using the prefix ; XML-TXM types are prefixed with '#'
+			}
+			
+			if ("1".equals(properties.get(UD_PROPERTY_NAMES[0])) && sentence.nWords2 > 0) {
+				return sentence; // this is a new sentence !!, return the current one
+			}
+			
+			String misc = split[9];
+			String[] miscValues = misc.split("\\|");
+			for (String miscEntry : miscValues) {
+				if (miscEntry.contains("=")) {
+					String[] s = miscEntry.split("=", 2);
+					properties.put(s[0], s[1]);
+				}
+			}
+			
+			sentence.put(properties.get(UD_PROPERTY_NAMES[0]), properties);
+			sentence.nWords2++;
+			
+			line = reader.readLine();
+		}
+		return sentence;
+	}
+	
+	/**
+	 * 
+	 * @param textId to  force the newdocid UD property
+	 * @return the sentences as an ArrayList
+	 * 
+	 * @throws IOException
+	 * @throws XMLStreamException
+	 */
+	public Sentences readAll() throws IOException, XMLStreamException {
+		
+		// reset the reader
+		if (reader != null) {
+			reader.close();
+		}
+		reader = IOUtils.getReader(coonluFile);
+		nLine = 0;
+		line = null;
+		
+		Sentences sentences = new Sentences();
+		
+		Sentence sentence = readNext();
+		while (sentence != null) {
+			sentences.add(sentence);
+			sentence = readNext();
+		}
+		reader.close();
+		
+		return sentences;
+	}
+	
+	public static void buildPropertiesProjections(Sentence sentence, Set<String> headPropertiesToProject, Set<String> depsPropertiesToProject) throws IOException, XMLStreamException {
+		
+		//System.out.println("Building "+headPropertiesToProject+" and "+depsPropertiesToProject+" in "+sentenceProperties);
+		if (headPropertiesToProject.size() > 0) {
+			
+			for (String wId : sentence.keySet()) {
+				
+				HashMap<String, String> properties = sentence.get(wId); 
+				
+				for (String wheadid : sentence.keySet()) { // find the word head properties
+					
+					HashMap<String, String> headProperties = sentence.get(wheadid); 
+					
+					if (headProperties.get("id").equals(properties.get("head"))) { // a word which head is the current word id
+						// { "form", "lemma", "upos", "xpos", "feats", "deprel", "deps", "misc" };
+						if (headPropertiesToProject.contains("form")) properties.put("head-form", headProperties.get("form"));
+						if (headPropertiesToProject.contains("lemma")) properties.put("head-lemma", headProperties.get("lemma"));
+						if (headPropertiesToProject.contains("upos")) properties.put("head-upos", headProperties.get("upos"));
+						if (headPropertiesToProject.contains("xpos")) properties.put("head-xpos", headProperties.get("xpos"));
+						if (headPropertiesToProject.contains("feats")) properties.put("head-feats", headProperties.get("feats"));
+						if (headPropertiesToProject.contains("deprel")) properties.put("head-deprel", headProperties.get("deprel"));
+						if (headPropertiesToProject.contains("deps")) properties.put("head-deps", headProperties.get("deps"));
+						if (headPropertiesToProject.contains("misc")) properties.put("head-misc", headProperties.get("misc"));
+						break; // the is only one head per word
+					}
+				}
+			}
+		}
+		
+		if (depsPropertiesToProject.size() > 0) {
+			
+			for (String wId : sentence.keySet()) {
+				
+				HashMap<String, String> properties = sentence.get(wId); 
+				HashMap<String, String> newProperties = new HashMap<String, String>();
+				if (depsPropertiesToProject.contains("id")) newProperties.put("dep-id", "|");
+				if (depsPropertiesToProject.contains("form")) newProperties.put("dep-form", "|");
+				if (depsPropertiesToProject.contains("lemma")) newProperties.put("dep-lemma", "|");
+				if (depsPropertiesToProject.contains("upos")) newProperties.put("dep-upos", "|");
+				if (depsPropertiesToProject.contains("xpos")) newProperties.put("dep-xpos", "|");
+				if (depsPropertiesToProject.contains("deprel")) newProperties.put("dep-deprel", "|");
+				if (depsPropertiesToProject.contains("deps")) newProperties.put("dep-deps", "|");
+				if (depsPropertiesToProject.contains("misc")) newProperties.put("dep-misc", "|");
+				
+				// browse each dep properties to build the depXYZ properties
+				for (String wdepid : sentence.keySet()) {
+					
+					HashMap<String, String> depProperties = sentence.get(wdepid); 
+					if (depProperties.get("head").equals(properties.get("id"))) { // a word which head is the current word id
+						
+						if (depsPropertiesToProject.contains("id")) newProperties.put("dep-id", newProperties.get("dep-id")+depProperties.get("id")+"|");
+						if (depsPropertiesToProject.contains("form")) newProperties.put("dep-form", newProperties.get("dep-form")+depProperties.get("form")+"|");
+						if (depsPropertiesToProject.contains("lemma")) newProperties.put("dep-lemma", newProperties.get("dep-lemma")+depProperties.get("lemma")+"|");
+						if (depsPropertiesToProject.contains("upos")) newProperties.put("dep-upos", newProperties.get("dep-upos")+depProperties.get("upos")+"|");
+						if (depsPropertiesToProject.contains("xpos")) newProperties.put("dep-xpos", newProperties.get("dep-xpos")+depProperties.get("xpos")+"|");
+						if (depsPropertiesToProject.contains("deprel")) newProperties.put("dep-deprel", newProperties.get("dep-deprel")+depProperties.get("deprel")+"|");
+						if (depsPropertiesToProject.contains("deps")) newProperties.put("dep-deps", newProperties.get("dep-deps")+depProperties.get("deps")+"|");
+						if (depsPropertiesToProject.contains("misc")) properties.put("dep-misc", newProperties.get("dep-misc")+depProperties.get("misc")+"|");
+					}
+				}
+				
+				for (String newProp : newProperties.keySet()) {
+					properties.put(newProp, newProperties.get(newProp));
+				}
+			}
+		}
+		//System.out.println("Result "+sentenceProperties);
+	}
+	
+	@Override
+	public void finalize() {
+		if (reader != null) try {
+			reader.close();
+		}
+		catch (IOException e) {
+			// TODO Auto-generated catch block
+			e.printStackTrace();
+		}
+	}
+	
+	public static void main(String args[]) throws IOException, XMLStreamException {
+		
+		File file = new File(System.getProperty("user.home"), "TEMP/test2.conllu");
+		Set<String> headPropertiesToProject = new HashSet<String>(Arrays.asList(UD_PROPERTY_NAMES));
+		CoNLLUReader reader = new CoNLLUReader(file, "test");
+		Sentences sentences = reader.readAll();
+		sentences.replaceIdwithXmlId();
+		for (Sentence s : sentences) {
+			buildPropertiesProjections(s, headPropertiesToProject, headPropertiesToProject);
+			for (String w : s.keySet()) {
+				
+				System.out.println(w + "\t" + s.get(w));
+			}
+			System.out.println();
+		}
+	}
+
+	public void close() {
+		
+		finalize();
+	}
+}

Property changes on: TXM/trunk/org.txm.conllu.core/src/org/txm/conllu/core/CoNLLUReader.java
___________________________________________________________________
Added: svn:mime-type
   + text/plain

Index: TXM/trunk/org.txm.conllu.core/src/org/txm/conllu/core/preferences/UDPreferences.java
===================================================================
--- TXM/trunk/org.txm.conllu.core/src/org/txm/conllu/core/preferences/UDPreferences.java	(revision 0)
+++ TXM/trunk/org.txm.conllu.core/src/org/txm/conllu/core/preferences/UDPreferences.java	(revision 3567)
@@ -0,0 +1,55 @@
+package org.txm.conllu.core.preferences;
+
+
+import org.osgi.service.prefs.Preferences;
+import org.txm.core.preferences.TXMPreferences;
+
+/**
+ * Preferences initializer and manager.
+ * 
+ * @author mdecorde
+ *
+ */
+public class UDPreferences extends TXMPreferences {
+	
+	
+	public static String VERSION = "version";
+	
+	public static String UDPREFIX = "ud_prefix";
+	
+	public static String KEEP_CONTRACTIONS = "import_keep_contractions";
+	
+	public static String IMPORT_USE_NEW_DOC_ID = "import_use_new_doc_id";
+	
+	public static String IMPORT_HEAD_TO_PROJECT = "import_head_to_project";
+	
+	public static String IMPORT_DEPS_TO_PROJECT = "import_deps_to_project";
+	
+	public static String IMPORT_BUILD_TIGERSEARCH_INDEXES = "import_build_tiger_indexes";
+	
+	/**
+	 * Gets the instance.
+	 * 
+	 * @return the instance
+	 */
+	public static TXMPreferences getInstance() {
+		if (!TXMPreferences.instances.containsKey(UDPreferences.class)) {
+			new UDPreferences();
+		}
+		return TXMPreferences.instances.get(UDPreferences.class);
+	}
+	
+	
+	@Override
+	public void initializeDefaultPreferences() {
+		super.initializeDefaultPreferences();
+		
+		Preferences preferences = this.getDefaultPreferencesNode();
+		preferences.put(UDPREFIX, "ud-");
+		preferences.put(IMPORT_HEAD_TO_PROJECT, "upos,deprel");
+		preferences.put(IMPORT_DEPS_TO_PROJECT, "upos,deprel");
+		preferences.putBoolean(KEEP_CONTRACTIONS, true);
+		preferences.putBoolean(IMPORT_USE_NEW_DOC_ID, true);
+		preferences.putBoolean(IMPORT_BUILD_TIGERSEARCH_INDEXES, true);
+	}
+}

Property changes on: TXM/trunk/org.txm.conllu.core/src/org/txm/conllu/core/preferences/UDPreferences.java
___________________________________________________________________
Added: svn:mime-type
   + text/plain

Index: TXM/trunk/org.txm.conllu.core/src/org/txm/conllu/core/preferences/UDTreePreferences.java
===================================================================
--- TXM/trunk/org.txm.conllu.core/src/org/txm/conllu/core/preferences/UDTreePreferences.java	(revision 0)
+++ TXM/trunk/org.txm.conllu.core/src/org/txm/conllu/core/preferences/UDTreePreferences.java	(revision 3567)
@@ -0,0 +1,45 @@
+package org.txm.conllu.core.preferences;
+
+
+import org.osgi.service.prefs.Preferences;
+import org.txm.core.preferences.TXMPreferences;
+import org.txm.treesearch.preferences.TreeSearchPreferences;
+
+/**
+ * UD tree Preferences initializer and manager.
+ * 
+ * @author mdecorde
+ *
+ */
+public class UDTreePreferences extends TreeSearchPreferences {
+	
+	public static final String DEPTREEVIZ = "DepTreeViz";
+	public static final String BRAT = "Brat";
+	
+	public static final String ENGINE = "visu_engine";
+	public static final String PRINTCONLLUSENTENCES = "print_ud_seentence";
+	
+	/**
+	 * Gets the instance.
+	 * 
+	 * @return the instance
+	 */
+	public static TXMPreferences getInstance() {
+		if (!TXMPreferences.instances.containsKey(UDTreePreferences.class)) {
+			new UDTreePreferences();
+		}
+		return TXMPreferences.instances.get(UDTreePreferences.class);
+	}
+	
+	
+	@Override
+	public void initializeDefaultPreferences() {
+		super.initializeDefaultPreferences();
+		
+		Preferences preferences = this.getDefaultPreferencesNode();
+		preferences.put(VISUALISATION, DEPTREEVIZ);
+		preferences.putBoolean(PRINTCONLLUSENTENCES, false);
+		preferences.put(TFEATURE, "");
+		preferences.put(NTFEATURE, "feats");
+	}
+}

Property changes on: TXM/trunk/org.txm.conllu.core/src/org/txm/conllu/core/preferences/UDTreePreferences.java
___________________________________________________________________
Added: svn:mime-type
   + text/plain

Index: TXM/trunk/org.txm.conllu.core/src/org/txm/conllu/core/Sentence.java
===================================================================
--- TXM/trunk/org.txm.conllu.core/src/org/txm/conllu/core/Sentence.java	(revision 0)
+++ TXM/trunk/org.txm.conllu.core/src/org/txm/conllu/core/Sentence.java	(revision 3567)
@@ -0,0 +1,119 @@
+package org.txm.conllu.core;
+
+import java.util.Comparator;
+import java.util.HashSet;
+import java.util.LinkedHashMap;
+import java.util.Set;
+import java.util.TreeMap;
+
+public class Sentence extends TreeMap<String, LinkedHashMap<String, String>>{
+	
+	private static final long serialVersionUID = -1585503070690160508L;
+	
+	public int nWords2 = 0;
+	public String sent_id = null;
+	public String newpar_id = null;
+	public String newdoc_id = null;
+	
+	@Override
+	public Comparator<String> comparator() {
+		
+		return new Comparator<String>() {
+
+			@Override
+			public int compare(String o1, String o2) {
+				int idx1 = o1.indexOf("-");
+				int idx2 = o2.indexOf("-");
+				if (idx1 >= 0) {
+					if (idx2 >= 0) {
+						return Integer.parseInt(o1.substring(0, idx1)) - Integer.parseInt(o2.substring(0, idx2));
+					} else {
+						return Integer.parseInt(o1.substring(0, idx1)) - Integer.parseInt(o2);
+					}
+				} else if (idx2 >= 0) {
+					if (idx1 >= 0) {
+						return Integer.parseInt(o1.substring(0, idx1)) - Integer.parseInt(o2.substring(0, idx2));
+					} else {
+						return Integer.parseInt(o1) - Integer.parseInt(o2.substring(0, idx2));
+					}
+				} else {
+					return Integer.parseInt(o1) - Integer.parseInt(o2);
+				}
+			}
+		};
+	}
+	
+	/**
+	 * merge the part word lines in the n-m word lines (the part are removed
+	 */
+	public void removePartTokensWords() {
+		
+		for (String wordid : this.keySet()) {
+			
+			LinkedHashMap<String, String> word = get(wordid);
+			if (word == null) continue;
+			
+			if (wordid.contains("-")) { // multi-word line
+				String[] parts = wordid.split("-");
+				
+				for (String p : CoNLLUReader.UD_PROPERTY_NAMES) {
+					if (p == "id") continue; // don't merge the form property
+					
+					String v = "";
+					if (p == "form") continue; // don't merge the form property
+					
+					for (String part : parts) {
+						if (v.length() > 0) v += "+";
+						v += this.get(part).get(p);
+					}
+					word.put(p, v); // replace value with the concat values
+				}
+				
+				for (String part : parts) {
+					remove(part); // remove the part token
+				}
+			}
+		}
+		
+//		Vector<String> keys = new Vector<String>(this.keySet());
+//		keys.sort(new Comparator<String>() {
+//
+//			@Override
+//			public int compare(String o1, String o2) {
+//				
+//				return Integer.parseInt(o1) - Integer.parseInt(o2);
+//			}
+//		});
+//		for (String w : keys) {
+//			
+//		}
+	}
+	
+	/**
+	 * removes the n-m word lines
+	 */
+	public void removeMultiTokensWords() {
+		
+		Set<String> keys = new HashSet<String>(this.keySet());
+		for (String w : keys) {
+			if (w.contains("-")) {
+				this.remove(w);
+			}
+		}
+	}
+	
+	/**
+	 * replace the ud id with the misc XmlId value
+	 * A word with no misc XmlId is removed
+	 */
+	public void replaceIdwithXmlId() {
+		
+		Set<String> keys = new HashSet<String>(this.keySet());
+		for (String w : keys) {
+			
+			if (this.get(w).get("XmlId") != null) this.put(this.get(w).get("XmlId"), this.get(w));
+			
+			this.remove(w);
+		}
+	}
+}

Property changes on: TXM/trunk/org.txm.conllu.core/src/org/txm/conllu/core/Sentence.java
___________________________________________________________________
Added: svn:mime-type
   + text/plain

Index: TXM/trunk/org.txm.conllu.core/src/org/txm/conllu/core/function/UDTreeSearchSelector.java
===================================================================
--- TXM/trunk/org.txm.conllu.core/src/org/txm/conllu/core/function/UDTreeSearchSelector.java	(revision 0)
+++ TXM/trunk/org.txm.conllu.core/src/org/txm/conllu/core/function/UDTreeSearchSelector.java	(revision 3567)
@@ -0,0 +1,43 @@
+package org.txm.conllu.core.function;
+
+import org.txm.searchengine.core.Query;
+import org.txm.searchengine.cqp.corpus.CQPCorpus;
+import org.txm.searchengine.cqp.corpus.query.CQLQuery;
+import org.txm.treesearch.function.TreeSearch;
+import org.txm.treesearch.function.TreeSearchSelector;
+
+
+public class UDTreeSearchSelector extends TreeSearchSelector {
+	
+	public static String UD = "UD";
+	
+	@Override
+	public String getEngine() {
+		
+		return UD;
+	}
+	
+	@Override
+	public boolean canComputeWith(CQPCorpus corpus) {
+		
+		return UDSearch.hasUDProperties(corpus);
+	}
+	
+	@Override
+	public TreeSearch getTreeSearch(CQPCorpus corpus) {
+		
+		return new UDSearch(corpus);
+	}
+	
+	@Override
+	public TreeSearch getTreeSearch(String resultnodepath, CQPCorpus corpus) {
+		
+		return new UDSearch(resultnodepath, corpus);
+	}
+
+	@Override
+	public Class<? extends Query> getQueryClass() {
+		
+		return CQLQuery.class;
+	}
+}

Property changes on: TXM/trunk/org.txm.conllu.core/src/org/txm/conllu/core/function/UDTreeSearchSelector.java
___________________________________________________________________
Added: svn:mime-type
   + text/plain

Index: TXM/trunk/org.txm.conllu.core/src/org/txm/conllu/core/function/BratPrintTree.java
===================================================================
--- TXM/trunk/org.txm.conllu.core/src/org/txm/conllu/core/function/BratPrintTree.java	(revision 0)
+++ TXM/trunk/org.txm.conllu.core/src/org/txm/conllu/core/function/BratPrintTree.java	(revision 3567)
@@ -0,0 +1,33 @@
+package org.txm.conllu.core.function;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.List;
+
+import org.apache.commons.lang.StringUtils;
+import org.txm.utils.BundleUtils;
+import org.txm.utils.io.IOUtils;
+
+public class BratPrintTree {
+	public static File print(File file, List<String> conll, String[] Tvalues, String[] NTvalues) {
+		
+		try {
+			String bundle_id = "org.txm.conllu.core";
+			File HTMLTEMPATE = BundleUtils.getFile(bundle_id, "template", "/", "index.html");
+			File root = HTMLTEMPATE.getParentFile();
+			
+			String content = IOUtils.getText(HTMLTEMPATE);
+			content = content.replace("HTMLROOTDIRECTORY", root.getAbsolutePath());
+			content = content.replace("CONLLUSENTENCE", StringUtils.join(conll, "\n"));
+			
+			IOUtils.write(file, content);
+			//BundleUtils.copyFiles(bundle_id, "groovy", "org/txm/scripts/importer", "", scriptsPackageDirectory, true);
+		}
+		catch (IOException e) {
+			// TODO Auto-generated catch block
+			e.printStackTrace();
+		}
+		
+		return file;
+	}
+}

Property changes on: TXM/trunk/org.txm.conllu.core/src/org/txm/conllu/core/function/BratPrintTree.java
___________________________________________________________________
Added: svn:mime-type
   + text/plain

Index: TXM/trunk/org.txm.conllu.core/src/org/txm/conllu/core/function/ImportCoNLLUAnnotations.java
===================================================================
--- TXM/trunk/org.txm.conllu.core/src/org/txm/conllu/core/function/ImportCoNLLUAnnotations.java	(revision 0)
+++ TXM/trunk/org.txm.conllu.core/src/org/txm/conllu/core/function/ImportCoNLLUAnnotations.java	(revision 3567)
@@ -0,0 +1,289 @@
+package org.txm.conllu.core.function;
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.LinkedHashMap;
+import java.util.Set;
+
+import javax.xml.stream.XMLStreamException;
+
+import org.apache.commons.lang.StringUtils;
+import org.txm.objects.Text;
+import org.txm.searchengine.cqp.corpus.MainCorpus;
+import org.txm.utils.AsciiUtils;
+import org.txm.utils.io.FileCopy;
+import org.txm.utils.io.IOUtils;
+import org.txm.utils.logger.Log;
+import org.txm.xml.xmltxm.XMLTXMWordPropertiesInjection;
+
+public class ImportCoNLLUAnnotations {
+	
+	public static final String[] UD_PROPERTY_NAMES = { "id", "form", "lemma", "upos", "xpos", "feats", "head", "deprel", "deps", "misc" };
+	
+	public static int _importAnnotations(File coonluFile, MainCorpus mainCorpus, String propertiesPrefix, String textId, Boolean normalize_word_ids, Set<String> headPropertiesToProject, Set<String> depsPropertiesToProject, Set<String> udPropertiesToImport) throws IOException, XMLStreamException {
+		
+		if (textId == null || textId.length() == 0) { // no text id provided, using the conllu file name
+			textId = coonluFile.getName().substring(0, coonluFile.getName().length() - 7);
+		}
+		
+		for (String p : headPropertiesToProject) {
+			udPropertiesToImport.add("head-"+p);
+		}
+		
+		for (String p : depsPropertiesToProject) {
+			udPropertiesToImport.add("dep-"+p);
+		}
+		
+		Log.info("** processing text: " + textId);
+		Text text = mainCorpus.getProject().getText(textId);
+		if (text == null) {
+			Log.warning("No text found with ID=" + textId);
+			return 0;
+		}
+		File xmltxmFile = mainCorpus.getProject().getText(textId).getXMLTXMFile();
+		File xmltxmUpdatedFile = new File(System.getProperty("java.io.tmpdir"), xmltxmFile.getName());
+		
+		XMLTXMWordPropertiesInjection processor = new XMLTXMWordPropertiesInjection(xmltxmFile);
+		HashMap<String, HashMap<String, String>> rules = new HashMap<>();
+		processor.setProperties(rules);
+		
+		BufferedReader reader = IOUtils.getReader(coonluFile);
+		String line = reader.readLine();
+		
+		int nWords2 = 0;
+		int nLine = 0;
+		String sent_id = null;
+		String newpar_id = null;
+		String newdoc_id = null;
+		LinkedHashMap<String, HashMap<String, String>> sentenceProperties = new LinkedHashMap<String, HashMap<String, String>>();
+		while (line != null) {
+			nLine++;
+			if (line.length() == 0) {
+				line = reader.readLine();
+				continue; // comment
+			}
+			
+			if (line.startsWith("#")) {
+				if (line.startsWith("# sent_id = ")) {
+					sent_id = line.substring(12).trim();
+				}
+				else if (line.startsWith("# newdoc id = ")) {
+					newdoc_id = line.substring(14).trim();
+				}
+				else if (line.startsWith("# newpar id = ")) {
+					newpar_id = line.substring(14).trim();
+				}
+				else {
+					// nothing for now
+				}
+				
+				line = reader.readLine();
+				continue; // comment
+			}
+			
+			String[] split = line.split("\t", 10);
+			if (split.length < 10) {
+				Log.warning("Error: line " + nLine + " : " + line + " -> " + Arrays.toString(split) + " len=" + split.length);
+				line = reader.readLine();
+				continue; // comment
+			}
+			
+			if (split[0].equals("1")) { // a new sentence begins, write the previous if any
+				// write previous sentence word properties
+				if (sentenceProperties.size() > 0) {
+					storeSentenceProperties(sentenceProperties, processor, propertiesPrefix, headPropertiesToProject, depsPropertiesToProject, udPropertiesToImport);
+				}
+			}
+			
+			String misc = split[9];
+			String[] miscValues = misc.split("\\|");
+			String wId = null;
+			for (String miscValue : miscValues) {
+				if (miscValue.startsWith("XmlId=")) {
+					wId = miscValue.substring(6);
+				}
+			}
+			
+			HashMap<String, String> properties = new HashMap<>();
+			for (int i = 0; i < split.length; i++) {
+				properties.put(UD_PROPERTY_NAMES[i], split[i]); // add the property name using the prefix ; XML-TXM types are prefixed with '#'
+			}
+			
+			if (sent_id != null) {
+				properties.put("#"+propertiesPrefix+"sentid", sent_id);
+				sent_id = ""; // reset value for next sentence
+			}
+			else {
+				properties.put("#"+propertiesPrefix+"sentid", "");
+			}
+			
+			if (newdoc_id != null) {
+				properties.put("#"+propertiesPrefix+"newdocid", newdoc_id);
+				newdoc_id = null; // reset value for next sentence
+			}
+			else {
+				properties.put("#"+propertiesPrefix+"newdocid", "");
+			}
+			
+			if (newpar_id != null) {
+				properties.put("#"+propertiesPrefix+"newparid", newpar_id);
+				newpar_id = null; // reset value for next sentence
+			}
+			else {
+				properties.put("#"+propertiesPrefix+"newparid", "");
+			}
+			
+			if (wId == null) {
+				Log.warning("No 'XmlId=' found for UD line: " + line);
+			}
+			else {
+				
+				if (normalize_word_ids) {
+					if (!wId.startsWith("w_")) {
+						wId = "w_" + wId.substring(1);
+					}
+					wId = AsciiUtils.buildWordId(wId);
+				}
+				
+				sentenceProperties.put(wId, properties);
+				nWords2++;
+			}
+			line = reader.readLine();
+		}
+		reader.close();
+		
+		// IF ANY write previous sentence word properties 
+		if (sentenceProperties.size() > 0) {
+			storeSentenceProperties(sentenceProperties, processor, propertiesPrefix, headPropertiesToProject, depsPropertiesToProject, udPropertiesToImport);
+		}
+		
+		if (nWords2 == 0) {
+			Log.warning("** No annotation to import in " + coonluFile);
+			return 0;
+		}
+		
+		Log.info("** Loading annotations from : " + coonluFile+" "+processor.getRules().size()+" injections to do.");
+		if (processor.process(xmltxmUpdatedFile)) {
+			if (xmltxmFile.delete() && FileCopy.copy(xmltxmUpdatedFile, xmltxmFile)) {
+				if (processor.getNonActivatedRules().size() > 0) {
+					Log.warning("Warning: some words were not imported: " + StringUtils.join(processor.getNonActivatedRules(), ", "));
+				}
+			}
+			else {
+				Log.warning("** Warning: annotation import failed for replace the corpus XML-TXM file: " + xmltxmFile + ". TEMP file: " + xmltxmUpdatedFile);
+				return 0;
+			}
+		}
+		else {
+			Log.warning("** Warning: annotation import failed for text: " + textId);
+			return 0;
+		}
+		
+		if (processor.getNInsertions() == 0) {
+			Log.warning("** No annotation imported in " + textId);
+		}
+		
+		return processor.getNInsertions();
+	}
+	
+	public static void buildPropertiesProjections(LinkedHashMap<String, HashMap<String, String>> sentenceProperties, Set<String> headPropertiesToProject, Set<String> depsPropertiesToProject) throws IOException, XMLStreamException {
+		
+		//System.out.println("Building "+headPropertiesToProject+" and "+depsPropertiesToProject+" in "+sentenceProperties);
+		if (headPropertiesToProject.size() > 0) {
+			
+			for (String wId : sentenceProperties.keySet()) {
+				
+				HashMap<String, String> properties = sentenceProperties.get(wId); 
+				
+				for (String wheadid : sentenceProperties.keySet()) { // find the word head properties
+					
+					HashMap<String, String> headProperties = sentenceProperties.get(wheadid); 
+					
+					if (headProperties.get("id").equals(properties.get("head"))) { // a word which head is the current word id
+						// { "form", "lemma", "upos", "xpos", "feats", "deprel", "deps", "misc" };
+						if (headPropertiesToProject.contains("form")) properties.put("head-form", headProperties.get("form"));
+						if (headPropertiesToProject.contains("lemma")) properties.put("head-lemma", headProperties.get("lemma"));
+						if (headPropertiesToProject.contains("upos")) properties.put("head-upos", headProperties.get("upos"));
+						if (headPropertiesToProject.contains("xpos")) properties.put("head-xpos", headProperties.get("xpos"));
+						if (headPropertiesToProject.contains("feats")) properties.put("head-feats", headProperties.get("feats"));
+						if (headPropertiesToProject.contains("deprel")) properties.put("head-deprel", headProperties.get("deprel"));
+						if (headPropertiesToProject.contains("deps")) properties.put("head-deps", headProperties.get("deps"));
+						if (headPropertiesToProject.contains("misc")) properties.put("head-misc", headProperties.get("misc"));
+						break; // the is only one head per word
+					}
+				}
+			}
+		}
+		
+		if (depsPropertiesToProject.size() > 0) {
+			
+			for (String wId : sentenceProperties.keySet()) {
+				
+				HashMap<String, String> properties = sentenceProperties.get(wId); 
+				HashMap<String, String> newProperties = new HashMap<String, String>();
+				if (depsPropertiesToProject.contains("id")) newProperties.put("dep-id", "|");
+				if (depsPropertiesToProject.contains("form")) newProperties.put("dep-form", "|");
+				if (depsPropertiesToProject.contains("lemma")) newProperties.put("dep-lemma", "|");
+				if (depsPropertiesToProject.contains("upos")) newProperties.put("dep-upos", "|");
+				if (depsPropertiesToProject.contains("xpos")) newProperties.put("dep-xpos", "|");
+				if (depsPropertiesToProject.contains("deprel")) newProperties.put("dep-deprel", "|");
+				if (depsPropertiesToProject.contains("deps")) newProperties.put("dep-deps", "|");
+				if (depsPropertiesToProject.contains("misc")) newProperties.put("dep-misc", "|");
+				
+				// browse each dep properties to build the depXYZ properties
+				for (String wdepid : sentenceProperties.keySet()) {
+					
+					HashMap<String, String> depProperties = sentenceProperties.get(wdepid); 
+					if (depProperties.get("head").equals(properties.get("id"))) { // a word which head is the current word id
+						
+						if (depsPropertiesToProject.contains("id")) newProperties.put("dep-id", newProperties.get("dep-id")+depProperties.get("id")+"|");
+						if (depsPropertiesToProject.contains("form")) newProperties.put("dep-form", newProperties.get("dep-form")+depProperties.get("form")+"|");
+						if (depsPropertiesToProject.contains("lemma")) newProperties.put("dep-lemma", newProperties.get("dep-lemma")+depProperties.get("lemma")+"|");
+						if (depsPropertiesToProject.contains("upos")) newProperties.put("dep-upos", newProperties.get("dep-upos")+depProperties.get("upos")+"|");
+						if (depsPropertiesToProject.contains("xpos")) newProperties.put("dep-xpos", newProperties.get("dep-xpos")+depProperties.get("xpos")+"|");
+						if (depsPropertiesToProject.contains("deprel")) newProperties.put("dep-deprel", newProperties.get("dep-deprel")+depProperties.get("deprel")+"|");
+						if (depsPropertiesToProject.contains("deps")) newProperties.put("dep-deps", newProperties.get("dep-deps")+depProperties.get("deps")+"|");
+						if (depsPropertiesToProject.contains("misc")) properties.put("dep-misc", newProperties.get("dep-misc")+depProperties.get("misc")+"|");
+					}
+				}
+				
+				for (String newProp : newProperties.keySet()) {
+					properties.put(newProp, newProperties.get(newProp));
+				}
+			}
+		}
+		//System.out.println("Result "+sentenceProperties);
+	}
+	
+	private static void storeSentenceProperties(LinkedHashMap<String, HashMap<String, String>> sentenceProperties, XMLTXMWordPropertiesInjection processor, String propertiesPrefix, Set<String> headPropertiesToProject, Set<String> depsPropertiesToProject, Set<String> udPropertiesToImport) throws IOException, XMLStreamException {
+		
+		buildPropertiesProjections(sentenceProperties, headPropertiesToProject, depsPropertiesToProject);
+		
+		for (String id : sentenceProperties.keySet()) {
+			HashMap<String, String> properties = sentenceProperties.get(id);
+			ArrayList<String> propertyNames = new ArrayList<String>(properties.keySet());
+			
+			for (String p : propertyNames) { // add # to properties to inject, and remove properties not to inject
+				
+				if (p.startsWith("#")) {
+					continue; //property already prefixed with #, do not add the prefix
+				}
+				else if (udPropertiesToImport != null && udPropertiesToImport.size() > 0 && !udPropertiesToImport.contains(p)) {; // keep only the sentence properties to import
+					properties.remove(p);
+					continue; //property already prefixed with #, do not add the prefix
+				}
+				String value = properties.get(p);
+				properties.remove(p);
+				properties.put("#"+propertiesPrefix+p, value);
+			}
+			
+			processor.addProperty(id, properties);
+		}
+		
+		sentenceProperties.clear();
+	}
+}

Property changes on: TXM/trunk/org.txm.conllu.core/src/org/txm/conllu/core/function/ImportCoNLLUAnnotations.java
___________________________________________________________________
Added: svn:mime-type
   + text/plain

Index: TXM/trunk/org.txm.conllu.core/src/org/txm/conllu/core/function/UDSearch.java
===================================================================
--- TXM/trunk/org.txm.conllu.core/src/org/txm/conllu/core/function/UDSearch.java	(revision 0)
+++ TXM/trunk/org.txm.conllu.core/src/org/txm/conllu/core/function/UDSearch.java	(revision 3567)
@@ -0,0 +1,404 @@
+package org.txm.conllu.core.function;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.List;
+
+import org.apache.commons.lang.StringUtils;
+import org.txm.conllu.core.preferences.UDPreferences;
+import org.txm.conllu.core.preferences.UDTreePreferences;
+import org.txm.core.results.TXMParameters;
+import org.txm.libs.deptreeviz.UDPrintTree;
+import org.txm.searchengine.core.Selection;
+import org.txm.searchengine.cqp.CQPSearchEngine;
+import org.txm.searchengine.cqp.clientExceptions.CqiClientException;
+import org.txm.searchengine.cqp.corpus.CQPCorpus;
+import org.txm.searchengine.cqp.corpus.QueryResult;
+import org.txm.searchengine.cqp.corpus.StructuralUnitProperty;
+import org.txm.searchengine.cqp.corpus.WordProperty;
+import org.txm.searchengine.cqp.corpus.query.CQLQuery;
+import org.txm.searchengine.cqp.corpus.query.Match;
+import org.txm.treesearch.function.TreeSearch;
+import org.txm.treesearch.function.TreeSearchSelector;
+import org.txm.utils.TXMProgressMonitor;
+import org.txm.utils.logger.Log;
+
+public class UDSearch extends TreeSearch {
+	
+	protected boolean ready = false;
+	
+	CQPCorpus udSentences;
+
+	private QueryResult matches;
+	
+	public UDSearch(CQPCorpus corpus) {
+		this(null, corpus);
+	}
+	
+	public UDSearch(String parentNodePath, CQPCorpus corpus) {
+		super(parentNodePath, corpus);
+		
+		this.corpus = getParent();
+		
+		ready = hasUDProperties(corpus, UDPreferences.getInstance().getProjectPreferenceValue(corpus.getProject(), UDPreferences.UDPREFIX, UDPreferences.getInstance().getString(UDPreferences.UDPREFIX)));
+	}
+	
+	public UDSearch(String parentNodePath) {
+		this(parentNodePath, null);
+	}
+	
+	public boolean isComputed() {
+		return matches != null;
+	}
+	
+	public boolean isDrawn() {
+		return matches != null;
+	}
+	
+	public Selection getSelection() {
+		return matches;
+	}
+	
+	@Override
+	public boolean toSVG(File svgFile, int sent, int sub, List<String> T, String NT) {
+		
+		if (!isDrawn()) return false; // no result
+		try {
+			//File file = File.createTempFile("txm", ".svg", new File(Toolbox.getTxmHomePath(), "results"));
+			
+			//String engine = UDTreePreferences.getInstance().getString(UDTreePreferences.ENGINE);
+			
+			Match match = this.matches.getMatches().get(sent);
+			org.txm.objects.Match sentence = null;
+			for (org.txm.objects.Match s : udSentences.getMatches()) {
+				if (s.getStart() <= match.getStart() && match.getEnd() <= s.getEnd()) {
+					sentence = s;
+					break;
+				}
+			}
+			
+			if (sentence == null) {
+				Log.warning("Error: match positions not found in sentences positions");
+				return false;
+			}
+			
+			int[] positions = new int[sentence.size()];
+			for (int i = 0 ; i < sentence.size() ; i++) positions[i] = sentence.getStart()+i;
+			
+			String prefix = UDPreferences.getInstance().getProjectPreferenceValue(corpus.getProject(), UDPreferences.UDPREFIX, UDPreferences.getInstance().getString(UDPreferences.UDPREFIX));
+			
+			String[] Tvalues = new String[positions.length];
+			for (int i = 0 ; i < Tvalues.length ; i++) {
+				Tvalues[i] += "";
+			}
+			
+			if (T != null && T.size() > 0) {
+				for (int iT = 0 ; iT < T.size() ; iT++) {
+					String t = T.get(iT);
+					if (corpus.getProperty(t) != null) {
+						String[] tvalues = corpus.getProperty(t).cpos2Str(positions);
+						for (int i = 0 ; i < tvalues.length ; i++) {
+							if (iT > 0) Tvalues[i] += "/";
+							Tvalues[i] += tvalues[i];
+						}
+					}
+				}
+			}
+			
+			String[] NTvalues = null;
+			if (NT != null && corpus.getProperty(NT) != null) {
+				NTvalues = corpus.getProperty(NT).cpos2Str(positions);
+			}
+			HashMap<String, String[]> values = new HashMap<>();
+			for (String p : ImportCoNLLUAnnotations.UD_PROPERTY_NAMES) {
+				values.put(prefix+p, corpus.getProperty(prefix+p).cpos2Str(positions));
+			}
+			
+			ArrayList<String> conll = new ArrayList<String>();
+			
+			for (int p = 0 ; p < positions.length ; p++) {
+				StringBuilder buffer = new StringBuilder();
+				for (String prop : ImportCoNLLUAnnotations.UD_PROPERTY_NAMES) {
+					if (buffer.length() > 0) buffer.append("\t");
+					buffer.append(values.get(prefix+prop)[p]);
+				}
+				
+				conll.add(buffer.toString());
+			}
+			
+			if (UDTreePreferences.getInstance().getBoolean(UDTreePreferences.PRINTCONLLUSENTENCES)) {
+				Log.info("CoNLL-U:");
+				for (String l : conll) {
+					Log.info(l);
+				}
+			}
+			
+			if (UDTreePreferences.BRAT.equals(pVisualisation)) {
+				return BratPrintTree.print(svgFile, conll, Tvalues, NTvalues) != null;
+			} else { // if (engine == null || UDTreePreferences.DEPTREEVIZ.equals(engine)) {
+				return UDPrintTree.print(svgFile, conll, Tvalues, NTvalues) != null;
+			} 
+		}
+		catch (Throwable e) {
+			Log.warning("Error while drawing SVG: "+e+ " at "+e.getStackTrace()[0]);
+			Log.printStackTrace(e);
+			return false;
+		}
+	}
+	
+	protected String[] getAvailableProperties() throws CqiClientException {
+		List<WordProperty> props = corpus.getProperties();
+		String[] sprops = new String[props.size()];
+		
+		for (int i = 0 ; i < props.size() ; i++) {
+			sprops[i] = props.get(i).getName();
+		}
+		
+		Arrays.sort(sprops);
+		return sprops;
+	}
+	
+	public String[] getAvailableTProperties() {
+		
+//		String prefix = UDPreferences.getInstance().getProjectPreferenceValue(corpus.getProject(), UDPreferences.UDPREFIX, UDPreferences.getInstance().getString(UDPreferences.UDPREFIX));
+//		
+//		String[] properties = new String[ImportCoNLLUAnnotations.UD_PROPERTY_NAMES.length];
+//		for (int p = 0 ; p < ImportCoNLLUAnnotations.UD_PROPERTY_NAMES.length ; p++) {
+//			properties[p] = prefix+ImportCoNLLUAnnotations.UD_PROPERTY_NAMES[p];
+//		}
+		try {
+			return getAvailableProperties();
+		}
+		catch (CqiClientException e) {
+			// TODO Auto-generated catch block
+			e.printStackTrace();
+			return new String[0];
+		}
+	}
+	
+	public String[] getAvailableNTProperties() {
+		return new String[0];
+	}
+	
+	@Override
+	public CQPCorpus getParent() {
+		return (CQPCorpus) super.getParent();
+	}
+	
+	public boolean isReady() {
+		return ready;
+	}
+	
+	public int getNSentences() {
+		if (matches == null) return 0;
+		
+			try {
+				return matches.getMatches().size();
+			}
+			catch (CqiClientException e) {
+				// TODO Auto-generated catch block
+				e.printStackTrace();
+				return 0;
+			}//getNMatch();
+	}
+	
+	public int getNSubGraph(int matchNo) {
+		
+		return 1;
+	}
+	
+	public int getSub(int matchNo) {
+		
+		return 1;
+	}
+	
+	/**
+	 * @return the query or the generic one
+	 */
+	public String getQuery() {
+		
+		String prefix = UDPreferences.getInstance().getProjectPreferenceValue(corpus.getProject(), UDPreferences.UDPREFIX, UDPreferences.getInstance().getString(UDPreferences.UDPREFIX));
+		
+		if (pQuery == null || pQuery.getQueryString().length() ==0) {
+			return "["+prefix+"id=\"1\"]";
+		} else {
+			return pQuery.getQueryString();
+		}
+	}
+	
+	@Override
+	public String toString() {
+		if (pQuery != null) {
+			return pQuery.getQueryString().substring(0, Math.min(20, pQuery.getQueryString().length()));
+		}
+		return "" + corpus;
+	}
+	
+	@Override
+	public boolean _toTxt(File outfile, String encoding, String colseparator, String txtseparator) throws Exception {
+		return false;
+	}
+	
+	@Override
+	public void clean() {
+		
+	}
+	
+	/**
+	 * 
+	 * @return the array of extensions to show in the FileDialog SWT widget
+	 */
+	@Override
+	public String[] getExportTXTExtensions() {
+		return new String[] { "*.xml" };
+	}
+	
+	@Override
+	public boolean canCompute() {
+		return corpus != null; // && pQuery != null && pQuery.length() > 0; // if pQuery is empty/null set a default query
+	}
+	
+	@Override
+	public boolean setParameters(TXMParameters parameters) {
+		if (parameters.getString("query") != null) {
+			this.pQuery = new CQLQuery(parameters.getString("query"));
+		}
+		return true;
+	}
+	
+	@Override
+	public boolean saveParameters() throws Exception {
+		return true;
+	}
+	
+	@Override
+	public boolean loadParameters() throws Exception {
+		return super.loadParameters();
+	}
+	
+	@Override
+	protected boolean _compute(TXMProgressMonitor monitor) throws Exception {
+		
+		String prefix = UDPreferences.getInstance().getProjectPreferenceValue(corpus.getProject(), UDPreferences.UDPREFIX, UDPreferences.getInstance().getString(UDPreferences.UDPREFIX));
+		
+		
+		if (pQuery == null || pQuery.getQueryString().length() == 0) {
+			pQuery = new CQLQuery("["+prefix+"deprel=\"root\"]"); // [ud-deprel="root"]
+		}
+		
+		udSentences = corpus.getSubcorpusByName(corpus.getName()+"/ud-sentences");
+		if (udSentences != null) udSentences.compute();
+		
+		if (udSentences == null) {
+			udSentences = corpus.createSubcorpus(new CQLQuery("["+prefix+"id=\"1\"] ["+prefix+"id !=\"1\"]+ [:"+prefix+"id=\"1|__UNDEF__\":]"), "ud-sentences");
+			udSentences.setVisible(false);
+		}
+		
+		matches = udSentences.query((CQLQuery)pQuery, "matches", false);
+		
+		return matches.getNMatch() > 0;
+	}
+	
+	@Override
+	public String getResultType() {
+		return "UD search";
+	}
+	
+	public void setIndexAndSubIndex(int sent, int sub) {
+		this.pIndex = sent;
+		this.pSubIndex = sub;
+	}
+	
+	@Override
+	public boolean hasSubMatchesStrategy() {
+		
+		return false;
+	}
+	
+	public static boolean hasUDProperties(CQPCorpus corpus) {
+		return hasUDProperties(corpus, UDPreferences.getInstance().getProjectPreferenceValue(corpus.getProject(), UDPreferences.UDPREFIX, UDPreferences.getInstance().getString(UDPreferences.UDPREFIX)));
+	}
+	
+	public static boolean hasUDProperties(CQPCorpus corpus, String prefix) {
+		
+		for (String prop : ImportCoNLLUAnnotations.UD_PROPERTY_NAMES) {
+			try {
+				if (corpus.getProperty(prefix+prop) == null) return false;
+			}
+			catch (CqiClientException e) {
+				return false;
+			}
+		}
+		return true;
+	}
+
+	@Override
+	public String getEngine() {
+		
+		return UDTreeSearchSelector.UD;
+	}
+
+	@Override
+	public TreeSearchSelector getSelector() {
+		
+		return new UDTreeSearchSelector();
+	}
+
+	@Override
+	public String[] getTextAndWordIDSOfCurrentSentence() throws Exception {
+		
+		String[] textAndWord = new String[2];
+		
+		WordProperty pid = corpus.getProperty("id");
+		StructuralUnitProperty ptextid = corpus.getStructuralUnitProperty("text_id");
+		
+		org.txm.objects.Match match = this.udSentences.getMatches().get(this.pIndex);
+		int[] positions = new int[match.size()];
+		for (int i = 0 ; i < match.size() ; i++) {
+			positions[i] = match.getStart() + i;
+		}
+		
+		List<String> idvalues = CQPSearchEngine.getEngine().getValuesForProperty(positions, pid);
+		
+		int[] structid = CQPSearchEngine.getCqiClient().cpos2Struc(ptextid.getQualifiedName(), positions);
+		String[] values = CQPSearchEngine.getCqiClient().struc2Str(ptextid.getQualifiedName(), structid);
+		
+		textAndWord[0] = values[0];
+		textAndWord[1] = StringUtils.join(idvalues, ",");
+		
+		return textAndWord;
+	}
+
+	@Override
+	public String getIconPath() {
+		
+		return "platform:/plugin/org.txm.conllu.core/icons/functions/UD.png";
+	}
+
+	@Override
+	public File createTemporaryFile(File resultDir) {
+		
+		try {
+			String engine = this.pVisualisation;//UDTreePreferences.getInstance().getString(UDTreePreferences.VISUALISATION);
+			if (engine.equals(UDTreePreferences.BRAT)) {
+				return File.createTempFile("UDTreeSearch", ".html", resultDir);
+			} else {
+				return File.createTempFile("UDTreeSearch", ".svg", resultDir);
+			}
+		}
+		catch (IOException e) {
+			// TODO Auto-generated catch block
+			e.printStackTrace();
+			return null;
+		} //$NON-NLS-1$ //$NON-NLS-2$ull;
+	}
+
+	@Override
+	public String[] getAvailableVisualisations() {
+		
+		return new String[] {UDTreePreferences.DEPTREEVIZ, UDTreePreferences.BRAT};
+	}
+}

Property changes on: TXM/trunk/org.txm.conllu.core/src/org/txm/conllu/core/function/UDSearch.java
___________________________________________________________________
Added: svn:mime-type
   + text/plain


Property changes on: TXM/trunk/org.txm.conllu.core
___________________________________________________________________
Added: svn:ignore
   + bin


