JAL-1807 still testing
[jalviewjs.git] / bin / jalview / io / FeaturesFile.js
index 458787b..9d03dfb 100644 (file)
-Clazz.declarePackage ("jalview.io");
-Clazz.load (["jalview.io.AlignFile", "java.lang.Enum", "$.Exception"], "jalview.io.FeaturesFile", ["jalview.analysis.SequenceIdMatcher", "jalview.datamodel.AlignedCodonFrame", "$.SequenceDummy", "$.SequenceFeature", "jalview.jsdev.GenericFileAdapter", "jalview.schemes.GraduatedColor", "$.UserColourScheme", "jalview.util.Format", "$.MapList", "$.ParseHtmlBodyAndLinks", "java.awt.Color", "java.lang.Float", "$.StringBuffer", "java.util.ArrayList", "$.Arrays", "$.HashMap", "$.Hashtable", "$.StringTokenizer", "$.Vector"], function () {
-c$ = Clazz.decorateAsClass (function () {
-this.doGffSource = true;
-this.gffversion = 0;
-if (!Clazz.isClassDefined ("jalview.io.FeaturesFile.InvalidGFF3FieldException")) {
-jalview.io.FeaturesFile.$FeaturesFile$InvalidGFF3FieldException$ ();
-}
-this.lastmatchedAl = null;
-this.matcher = null;
-Clazz.instantialize (this, arguments);
-}, jalview.io, "FeaturesFile", jalview.io.AlignFile);
-Clazz.makeConstructor (c$, 
-function () {
-Clazz.superConstructor (this, jalview.io.FeaturesFile, []);
-});
-Clazz.defineMethod (c$, "parse", 
-function (align, colours, removeHTML) {
-return this.parse (align, colours, null, removeHTML, false);
-}, "jalview.datamodel.AlignmentI,java.util.Hashtable,~B");
-Clazz.defineMethod (c$, "parse", 
-function (align, colours, removeHTML, relaxedIdMatching) {
-return this.parse (align, colours, null, removeHTML, relaxedIdMatching);
-}, "jalview.datamodel.AlignmentI,java.util.Map,~B,~B");
-Clazz.defineMethod (c$, "parse", 
-function (align, colours, featureLink, removeHTML) {
-return this.parse (align, colours, featureLink, removeHTML, false);
-}, "jalview.datamodel.AlignmentI,java.util.Map,java.util.Map,~B");
-Clazz.defineMethod (c$, "parse", 
-function (align, colours, featureLink, removeHTML, relaxedIdmatching) {
-var line = null;
-try {
-var seq = null;
-var newseqs =  new java.util.ArrayList ();
-var type;
-var desc;
-var token = null;
-var index;
-var start;
-var end;
-var score;
-var st;
-var sf;
-var featureGroup = null;
-var groupLink = null;
-var typeLink =  new java.util.Hashtable ();
-var GFFFile = true;
-var gffProps =  new java.util.HashMap ();
-while ((line = this.nextLine ()) != null) {
-if (line.startsWith ("#")) {
-if (line.startsWith ("##")) {
-this.processGffPragma (line, gffProps, align, newseqs);
-line = "";
-}continue;
-}st =  new java.util.StringTokenizer (line, "\t");
-if (st.countTokens () == 1) {
-if (line.trim ().equalsIgnoreCase ("GFF")) {
-GFFFile = true;
-continue;
-}}if (st.countTokens () > 1 && st.countTokens () < 4) {
-GFFFile = false;
-type = st.nextToken ();
-if (type.equalsIgnoreCase ("startgroup")) {
-featureGroup = st.nextToken ();
-if (st.hasMoreElements ()) {
-groupLink = st.nextToken ();
-featureLink.put (featureGroup, groupLink);
-}} else if (type.equalsIgnoreCase ("endgroup")) {
-st.nextToken ();
-featureGroup = null;
-groupLink = null;
-} else {
-var colour = null;
-var colscheme = st.nextToken ();
-if (colscheme.indexOf ("|") > -1 || colscheme.trim ().equalsIgnoreCase ("label")) {
-var gcol =  new java.util.StringTokenizer (colscheme, "|", true);
-var threshtype = -1;
-var min = 1.4E-45;
-var max = 3.4028235E38;
-var threshval = NaN;
-var labelCol = false;
-var mincol = gcol.nextToken ();
-if (mincol === "|") {
-System.err.println ("Expected either 'label' or a colour specification in the line: " + line);
-continue;
-}var maxcol = null;
-if (mincol.toLowerCase ().indexOf ("label") == 0) {
-labelCol = true;
-mincol = (gcol.hasMoreTokens () ? gcol.nextToken () : null);
-mincol = (gcol.hasMoreTokens () ? gcol.nextToken () : null);
-}var abso = null;
-var minval;
-var maxval;
-if (mincol != null) {
-if (mincol.equals ("|")) {
-mincol = "";
-} else {
-gcol.nextToken ();
-}maxcol = gcol.nextToken ();
-if (maxcol.equals ("|")) {
-maxcol = "";
-} else {
-gcol.nextToken ();
-}abso = gcol.nextToken ();
-gcol.nextToken ();
-if (abso.toLowerCase ().indexOf ("abso") != 0) {
-minval = abso;
-abso = null;
-} else {
-minval = gcol.nextToken ();
-gcol.nextToken ();
-}maxval = gcol.nextToken ();
-if (gcol.hasMoreTokens ()) {
-gcol.nextToken ();
-}try {
-if (minval.length > 0) {
-min =  new Float (minval).floatValue ();
-}} catch (e) {
-if (Clazz.exceptionOf (e, Exception)) {
-System.err.println ("Couldn't parse the minimum value for graduated colour for type (" + colscheme + ") - did you misspell 'auto' for the optional automatic colour switch ?");
-e.printStackTrace ();
-} else {
-throw e;
-}
-}
-try {
-if (maxval.length > 0) {
-max =  new Float (maxval).floatValue ();
-}} catch (e) {
-if (Clazz.exceptionOf (e, Exception)) {
-System.err.println ("Couldn't parse the maximum value for graduated colour for type (" + colscheme + ")");
-e.printStackTrace ();
-} else {
-throw e;
-}
-}
-} else {
-mincol = "FFFFFF";
-maxcol = "000000";
-}try {
-colour =  new jalview.schemes.GraduatedColor ( new jalview.schemes.UserColourScheme (mincol).findColour ('A'),  new jalview.schemes.UserColourScheme (maxcol).findColour ('A'), min, max);
-} catch (e) {
-if (Clazz.exceptionOf (e, Exception)) {
-System.err.println ("Couldn't parse the graduated colour scheme (" + colscheme + ")");
-e.printStackTrace ();
-} else {
-throw e;
-}
-}
-if (colour != null) {
-(colour).setColourByLabel (labelCol);
-(colour).setAutoScaled (abso == null);
-var ttype = null;
-var tval = null;
-if (gcol.hasMoreTokens ()) {
-ttype = gcol.nextToken ();
-if (ttype.toLowerCase ().startsWith ("below")) {
-(colour).setThreshType (0);
-} else if (ttype.toLowerCase ().startsWith ("above")) {
-(colour).setThreshType (1);
-} else {
-(colour).setThreshType (-1);
-if (!ttype.toLowerCase ().startsWith ("no")) {
-System.err.println ("Ignoring unrecognised threshold type : " + ttype);
-}}}if ((colour).getThreshType () != -1) {
-try {
-gcol.nextToken ();
-tval = gcol.nextToken ();
-(colour).setThresh ( new Float (tval).floatValue ());
-} catch (e) {
-if (Clazz.exceptionOf (e, Exception)) {
-System.err.println ("Couldn't parse threshold value as a float: (" + tval + ")");
-e.printStackTrace ();
-} else {
-throw e;
-}
-}
-}if (gcol.hasMoreTokens ()) {
-System.err.println ("Ignoring additional tokens in parameters in graduated colour specification\n");
-while (gcol.hasMoreTokens ()) {
-System.err.println ("|" + gcol.nextToken ());
-}
-System.err.println ("\n");
-}}} else {
-var ucs =  new jalview.schemes.UserColourScheme (colscheme);
-colour = ucs.findColour ('A');
-}if (colour != null) {
-colours.put (type, colour);
-}if (st.hasMoreElements ()) {
-var link = st.nextToken ();
-typeLink.put (type, link);
-if (featureLink == null) {
-featureLink =  new java.util.Hashtable ();
-}featureLink.put (type, link);
-}}continue;
-}var seqId = "";
-while (st.hasMoreElements ()) {
-if (GFFFile) {
-seqId = token = st.nextToken ();
-seq = this.findName (align, seqId, relaxedIdmatching, newseqs);
-if (seq != null) {
-desc = st.nextToken ();
-var group = null;
-if (this.doGffSource && desc.indexOf (' ') == -1) {
-group =  String.instantialize (desc);
-}type = st.nextToken ();
-try {
-var stt = st.nextToken ();
-if (stt.length == 0 || stt.equals ("-")) {
-start = 0;
-} else {
-start = Integer.parseInt (stt);
-}} catch (ex) {
-if (Clazz.exceptionOf (ex, NumberFormatException)) {
-start = 0;
-} else {
-throw ex;
-}
-}
-try {
-var stt = st.nextToken ();
-if (stt.length == 0 || stt.equals ("-")) {
-end = 0;
-} else {
-end = Integer.parseInt (stt);
-}} catch (ex) {
-if (Clazz.exceptionOf (ex, NumberFormatException)) {
-end = 0;
-} else {
-throw ex;
-}
-}
-if (end == 0) {
-start = 0;
-}try {
-score =  new Float (st.nextToken ()).floatValue ();
-} catch (ex) {
-if (Clazz.exceptionOf (ex, NumberFormatException)) {
-score = 0;
-} else {
-throw ex;
-}
-}
-sf =  new jalview.datamodel.SequenceFeature (type, desc, start, end, score, group);
-try {
-sf.setValue ("STRAND", st.nextToken ());
-sf.setValue ("FRAME", st.nextToken ());
-} catch (ex) {
-if (Clazz.exceptionOf (ex, Exception)) {
-} else {
-throw ex;
-}
-}
-if (st.hasMoreTokens ()) {
-var attributes =  new StringBuffer ();
-var sep = false;
-while (st.hasMoreTokens ()) {
-attributes.append ((sep ? "\t" : "") + st.nextElement ());
-sep = true;
-}
-sf.setValue ("ATTRIBUTES", attributes.toString ());
-}if (this.processOrAddSeqFeature (align, newseqs, seq, sf, GFFFile, relaxedIdmatching)) {
-while ((seq = align.findName (seq, seqId, true)) != null) {
-seq.addSequenceFeature ( new jalview.datamodel.SequenceFeature (sf));
-}
-}break;
-}}if (GFFFile && seq == null) {
-desc = token;
-} else {
-desc = st.nextToken ();
-}if (!st.hasMoreTokens ()) {
-System.err.println ("DEBUG: Run out of tokens when trying to identify the destination for the feature.. giving up.");
-return false;
-}token = st.nextToken ();
-if (!token.equals ("ID_NOT_SPECIFIED")) {
-seq = this.findName (align, seqId = token, relaxedIdmatching, null);
-st.nextToken ();
-} else {
-seqId = null;
-try {
-index = Integer.parseInt (st.nextToken ());
-seq = align.getSequenceAt (index);
-} catch (ex) {
-if (Clazz.exceptionOf (ex, NumberFormatException)) {
-seq = null;
-} else {
-throw ex;
-}
-}
-}if (seq == null) {
-System.out.println ("Sequence not found: " + line);
-break;
-}start = Integer.parseInt (st.nextToken ());
-end = Integer.parseInt (st.nextToken ());
-type = st.nextToken ();
-if (!colours.containsKey (type)) {
-var ucs =  new jalview.schemes.UserColourScheme (type);
-colours.put (type, ucs.findColour ('A'));
-}sf =  new jalview.datamodel.SequenceFeature (type, desc, "", start, end, featureGroup);
-if (st.hasMoreTokens ()) {
-try {
-score =  new Float (st.nextToken ()).floatValue ();
-} catch (ex) {
-if (Clazz.exceptionOf (ex, NumberFormatException)) {
-score = 0;
-} else {
-throw ex;
-}
-}
-sf.setScore (score);
-}if (groupLink != null && removeHTML) {
-sf.addLink (groupLink);
-sf.description += "%LINK%";
-}if (typeLink.containsKey (type) && removeHTML) {
-sf.addLink (typeLink.get (type).toString ());
-sf.description += "%LINK%";
-}this.parseDescriptionHTML (sf, removeHTML);
-seq.addSequenceFeature (sf);
-while (seqId != null && (seq = align.findName (seq, seqId, false)) != null) {
-seq.addSequenceFeature ( new jalview.datamodel.SequenceFeature (sf));
-}
-GFFFile = false;
-}
-}
-this.resetMatcher ();
-} catch (ex) {
-if (Clazz.exceptionOf (ex, Exception)) {
-this.warningMessage = ((this.warningMessage == null) ? "" : this.warningMessage) + "Parsing error at\n" + line;
-System.out.println ("Error parsing feature file: " + ex + "\n" + line);
-ex.printStackTrace (System.err);
-this.resetMatcher ();
-return false;
-} else {
-throw ex;
-}
-}
-return true;
-}, "jalview.datamodel.AlignmentI,java.util.Map,java.util.Map,~B,~B");
-Clazz.defineMethod (c$, "processGffPragma", 
-($fz = function (line, gffProps, align, newseqs) {
-var spacepos = line.indexOf (' ');
-var pragma = spacepos == -1 ? line.substring (2).trim () : line.substring (2, spacepos);
-var gffpragma = jalview.io.FeaturesFile.GFFPRAGMA.get (pragma.toLowerCase ());
-if (gffpragma == null) {
-return;
-}switch (gffpragma) {
-case jalview.io.FeaturesFile.GffPragmas.gff_version:
-try {
-this.gffversion = Integer.parseInt (line.substring (spacepos + 1));
-} finally {
-}
-break;
-case jalview.io.FeaturesFile.GffPragmas.feature_ontology:
-break;
-case jalview.io.FeaturesFile.GffPragmas.attribute_ontology:
-break;
-case jalview.io.FeaturesFile.GffPragmas.source_ontology:
-break;
-case jalview.io.FeaturesFile.GffPragmas.species_build:
-break;
-case jalview.io.FeaturesFile.GffPragmas.hash:
-break;
-case jalview.io.FeaturesFile.GffPragmas.fasta:
-this.process_as_fasta (align, newseqs);
-break;
-default:
-System.err.println ("Ignoring unknown pragma:\n" + line);
-}
-}, $fz.isPrivate = true, $fz), "~S,java.util.Map,jalview.datamodel.AlignmentI,java.util.ArrayList");
-Clazz.defineMethod (c$, "process_as_fasta", 
-($fz = function (align, newseqs) {
-try {
-this.mark ();
-} catch (q) {
-if (Clazz.exceptionOf (q, java.io.IOException)) {
-} else {
-throw q;
-}
-}
-var parser = jalview.jsdev.GenericFileAdapter.getFile ("FastaFile", []);
-var includedseqs = parser.getSeqs ();
-var smatcher =  new jalview.analysis.SequenceIdMatcher (newseqs);
-for (var p = 0, pSize = includedseqs.size (); p < pSize; p++) {
-var dummyseq = smatcher.findIdMatch (includedseqs.get (p));
-if (dummyseq != null) {
-var mseq = includedseqs.get (p);
-if (Clazz.instanceOf (dummyseq, jalview.datamodel.SequenceDummy)) {
-(dummyseq).become (mseq);
-includedseqs.set (p, dummyseq);
-}}}
-for (var seq, $seq = includedseqs.iterator (); $seq.hasNext () && ((seq = $seq.next ()) || true);) {
-align.addSequence (seq);
-}
-}, $fz.isPrivate = true, $fz), "jalview.datamodel.AlignmentI,java.util.List");
-Clazz.defineMethod (c$, "processOrAddSeqFeature", 
-function (align, newseqs, seq, sf, gFFFile, relaxedIdMatching) {
-var attr = sf.getValue ("ATTRIBUTES");
-var add = true;
-if (gFFFile && attr != null) {
-var nattr = 8;
-for (var attset, $attset = 0, $$attset = attr.$plit ("\t"); $attset < $$attset.length && ((attset = $$attset[$attset]) || true); $attset++) {
-if (attset == null || attset.trim ().length == 0) {
-continue;
-}nattr++;
-var set =  new java.util.HashMap ();
-for (var pair, $pair = 0, $$pair = attset.trim ().$plit (";"); $pair < $$pair.length && ((pair = $$pair[$pair]) || true); $pair++) {
-pair = pair.trim ();
-if (pair.length == 0) {
-continue;
-}var eqpos = pair.indexOf ('=');
-var sppos = pair.indexOf (' ');
-var key = null;
-var value = null;
-if (sppos > -1 && (eqpos == -1 || sppos < eqpos)) {
-key = pair.substring (0, sppos);
-value = pair.substring (sppos + 1);
-} else {
-if (eqpos > -1 && (sppos == -1 || eqpos < sppos)) {
-key = pair.substring (0, eqpos);
-value = pair.substring (eqpos + 1);
-} else {
-key = pair;
-}}if (key != null) {
-var vals = set.get (key);
-if (vals == null) {
-vals =  new java.util.ArrayList ();
-set.put (key, vals);
-}if (value != null) {
-vals.add (value.trim ());
-}}}
-try {
-add = new Boolean (add & this.processGffKey (set, nattr, seq, sf, align, newseqs, relaxedIdMatching)).valueOf ();
-} catch (ivfe) {
-if (Clazz.exceptionOf (ivfe, jalview.io.FeaturesFile.InvalidGFF3FieldException)) {
-System.err.println (ivfe);
-} else {
-throw ivfe;
-}
-}
-}
-}if (add) {
-seq.addSequenceFeature (sf);
-}return add;
-}, "jalview.datamodel.AlignmentI,java.util.List,jalview.datamodel.SequenceI,jalview.datamodel.SequenceFeature,~B,~B");
-Clazz.defineMethod (c$, "processGffKey", 
-function (set, nattr, seq, sf, align, newseqs, relaxedIdMatching) {
-var attr;
-if (sf.getType ().equals ("similarity")) {
-var strand = sf.getStrand ();
-var querySeq = this.findNames (align, newseqs, relaxedIdMatching, set.get (attr = "Query"));
-if (querySeq == null || querySeq.size () != 1) {
-throw Clazz.innerTypeInstance (jalview.io.FeaturesFile.InvalidGFF3FieldException, this, null, attr, set, "Expecting exactly one sequence in Query field (got " + set.get (attr) + ")");
-}if (set.containsKey (attr = "Align")) {
-var alco =  new jalview.datamodel.AlignedCodonFrame ();
-var codonmapping = this.constructCodonMappingFromAlign (set, attr, strand);
-alco.addMap (seq, querySeq.get (0), codonmapping);
-align.addCodonFrame (alco);
-return false;
-}}return true;
-}, "java.util.Map,~N,jalview.datamodel.SequenceI,jalview.datamodel.SequenceFeature,jalview.datamodel.AlignmentI,java.util.List,~B");
-Clazz.defineMethod (c$, "constructCodonMappingFromAlign", 
-($fz = function (set, attr, strand) {
-if (strand == 0) {
-throw Clazz.innerTypeInstance (jalview.io.FeaturesFile.InvalidGFF3FieldException, this, null, attr, set, "Invalid strand for a codon mapping (cannot be 0)");
-}var fromrange =  new java.util.ArrayList ();
-var torange =  new java.util.ArrayList ();
-var lastppos = 0;
-var lastpframe = 0;
-for (var range, $range = set.get (attr).iterator (); $range.hasNext () && ((range = $range.next ()) || true);) {
-var ints =  new java.util.ArrayList ();
-var st =  new java.util.StringTokenizer (range, " ");
-while (st.hasMoreTokens ()) {
-var num = st.nextToken ();
-try {
-ints.add ( new Integer (num));
-} catch (nfe) {
-if (Clazz.exceptionOf (nfe, NumberFormatException)) {
-throw Clazz.innerTypeInstance (jalview.io.FeaturesFile.InvalidGFF3FieldException, this, null, attr, set, "Invalid number in field " + num);
-} else {
-throw nfe;
-}
-}
-}
-if (ints.size () != 3) {
-throw Clazz.innerTypeInstance (jalview.io.FeaturesFile.InvalidGFF3FieldException, this, null, attr, set, "Invalid number of fields for this attribute (" + ints.size () + ")");
-}fromrange.add ( new Integer (ints.get (0).intValue ()));
-fromrange.add ( new Integer (ints.get (0).intValue () + strand * ints.get (2).intValue ()));
-if (ints.get (1).equals (new Integer (lastppos)) && lastpframe > 0) {
-lastppos += (ints.get (2)).intValue () / 3;
-lastpframe = (ints.get (2)).intValue () % 3;
-torange.set (torange.size () - 1,  new Integer (lastppos));
-} else {
-torange.add (ints.get (1));
-lastppos = (ints.get (1)).intValue () + (ints.get (2)).intValue () / 3;
-lastpframe = (ints.get (2)).intValue () % 3;
-torange.add ( new Integer (lastppos));
-}}
-if (fromrange.size () % 2 == 1) {
-throw Clazz.innerTypeInstance (jalview.io.FeaturesFile.InvalidGFF3FieldException, this, null, attr, set, "Couldn't parse the DNA alignment range correctly");
-}if (torange.size () % 2 == 1) {
-throw Clazz.innerTypeInstance (jalview.io.FeaturesFile.InvalidGFF3FieldException, this, null, attr, set, "Couldn't parse the protein alignment range correctly");
-}var frommap =  Clazz.newIntArray (fromrange.size (), 0);
-var tomap =  Clazz.newIntArray (torange.size (), 0);
-var p = 0;
-for (var ip, $ip = fromrange.iterator (); $ip.hasNext () && ((ip = $ip.next ()) || true);) {
-frommap[p++] = ip.intValue ();
-}
-p = 0;
-for (var ip, $ip = torange.iterator (); $ip.hasNext () && ((ip = $ip.next ()) || true);) {
-tomap[p++] = ip.intValue ();
-}
-return  new jalview.util.MapList (frommap, tomap, 3, 1);
-}, $fz.isPrivate = true, $fz), "java.util.Map,~S,~N");
-Clazz.defineMethod (c$, "findNames", 
-($fz = function (align, newseqs, relaxedIdMatching, list) {
-var found =  new java.util.ArrayList ();
-for (var seqId, $seqId = list.iterator (); $seqId.hasNext () && ((seqId = $seqId.next ()) || true);) {
-var seq = this.findName (align, seqId, relaxedIdMatching, newseqs);
-if (seq != null) {
-found.add (seq);
-}}
-return found;
-}, $fz.isPrivate = true, $fz), "jalview.datamodel.AlignmentI,java.util.List,~B,java.util.List");
-Clazz.defineMethod (c$, "resetMatcher", 
-($fz = function () {
-this.lastmatchedAl = null;
-this.matcher = null;
-}, $fz.isPrivate = true, $fz));
-Clazz.defineMethod (c$, "findName", 
-($fz = function (align, seqId, relaxedIdMatching, newseqs) {
-var match = null;
-if (relaxedIdMatching) {
-if (this.lastmatchedAl !== align) {
-this.matcher =  new jalview.analysis.SequenceIdMatcher ((this.lastmatchedAl = align).getSequencesArray ());
-if (newseqs != null) {
-this.matcher.addAll (newseqs);
-}}match = this.matcher.findIdMatch (seqId);
-} else {
-match = align.findName (seqId, true);
-if (match == null && newseqs != null) {
-for (var m, $m = newseqs.iterator (); $m.hasNext () && ((m = $m.next ()) || true);) {
-if (seqId.equals (m.getName ())) {
-return m;
-}}
-}}if (match == null && newseqs != null) {
-match =  new jalview.datamodel.SequenceDummy (seqId);
-if (relaxedIdMatching) {
-this.matcher.addAll (java.util.Arrays.asList ( Clazz.newArray (-1, [match])));
-}newseqs.add (match);
-}return match;
-}, $fz.isPrivate = true, $fz), "jalview.datamodel.AlignmentI,~S,~B,java.util.List");
-Clazz.defineMethod (c$, "parseDescriptionHTML", 
-function (sf, removeHTML) {
-if (sf.getDescription () == null) {
-return;
-}var parsed =  new jalview.util.ParseHtmlBodyAndLinks (sf.getDescription (), removeHTML, this.newline);
-sf.description = (removeHTML) ? parsed.getNonHtmlContent () : sf.description;
-for (var link, $link = parsed.getLinks ().iterator (); $link.hasNext () && ((link = $link.next ()) || true);) {
-sf.addLink (link);
-}
-}, "jalview.datamodel.SequenceFeature,~B");
-Clazz.defineMethod (c$, "printJalviewFormat", 
-function (seqs, visible) {
-return this.printJalviewFormat (seqs, visible, true, true);
-}, "~A,java.util.Map");
-Clazz.defineMethod (c$, "printJalviewFormat", 
-function (seqs, visible, visOnly, nonpos) {
-var out =  new StringBuffer ();
-var next;
-var featuresGen = false;
-if (visOnly && !nonpos && (visible == null || visible.size () < 1)) {
-return "No Features Visible";
-}if (visible != null && visOnly) {
-var en = visible.keySet ().iterator ();
-var type;
-var color;
-while (en.hasNext ()) {
-type = en.next ().toString ();
-if (Clazz.instanceOf (visible.get (type), jalview.schemes.GraduatedColor)) {
-var gc = visible.get (type);
-color = (gc.isColourByLabel () ? "label|" : "") + jalview.util.Format.getHexString (gc.getMinColor ()) + "|" + jalview.util.Format.getHexString (gc.getMaxColor ()) + (gc.isAutoScale () ? "|" : "|abso|") + gc.getMin () + "|" + gc.getMax () + "|";
-if (gc.getThreshType () != -1) {
-if (gc.getThreshType () == 0) {
-color += "below";
-} else {
-if (gc.getThreshType () != 1) {
-System.err.println ("WARNING: Unsupported threshold type (" + gc.getThreshType () + ") : Assuming 'above'");
-}color += "above";
-}color += "|" + gc.getThresh ();
-} else {
-color += "none";
-}} else if (Clazz.instanceOf (visible.get (type), java.awt.Color)) {
-color = jalview.util.Format.getHexString (visible.get (type));
-} else {
-color = jalview.util.Format.getHexString ( new java.awt.Color (Integer.parseInt (visible.get (type).toString ())));
-}out.append (type);
-out.append ("\t");
-out.append (color);
-out.append (this.newline);
-}
-}var groups =  new java.util.Vector ();
-var groupIndex = 0;
-var isnonpos = false;
-for (var i = 0; i < seqs.length; i++) {
-next = seqs[i].getSequenceFeatures ();
-if (next != null) {
-for (var j = 0; j < next.length; j++) {
-isnonpos = next[j].begin == 0 && next[j].end == 0;
-if ((!nonpos && isnonpos) || (!isnonpos && visOnly && !visible.containsKey (next[j].type))) {
-continue;
-}if (next[j].featureGroup != null && !groups.contains (next[j].featureGroup)) {
-groups.addElement (next[j].featureGroup);
-}}
-}}
-var group = null;
-do {
-if (groups.size () > 0 && groupIndex < groups.size ()) {
-group = groups.elementAt (groupIndex).toString ();
-out.append (this.newline);
-out.append ("STARTGROUP\t");
-out.append (group);
-out.append (this.newline);
-} else {
-group = null;
-}for (var i = 0; i < seqs.length; i++) {
-next = seqs[i].getSequenceFeatures ();
-if (next != null) {
-for (var j = 0; j < next.length; j++) {
-isnonpos = next[j].begin == 0 && next[j].end == 0;
-if ((!nonpos && isnonpos) || (!isnonpos && visOnly && !visible.containsKey (next[j].type))) {
-continue;
-}if (group != null && (next[j].featureGroup == null || !next[j].featureGroup.equals (group))) {
-continue;
-}if (group == null && next[j].featureGroup != null) {
-continue;
-}featuresGen = true;
-if (next[j].description == null || next[j].description.equals ("")) {
-out.append (next[j].type + "\t");
-} else {
-if (next[j].links != null && next[j].getDescription ().indexOf ("<html>") == -1) {
-out.append ("<html>");
-}out.append (next[j].description + " ");
-if (next[j].links != null) {
-for (var l = 0; l < next[j].links.size (); l++) {
-var label = next[j].links.elementAt (l).toString ();
-var href = label.substring (label.indexOf ("|") + 1);
-label = label.substring (0, label.indexOf ("|"));
-if (next[j].description.indexOf (href) == -1) {
-out.append ("<a href=\"" + href + "\">" + label + "</a>");
-}}
-if (next[j].getDescription ().indexOf ("</html>") == -1) {
-out.append ("</html>");
-}}out.append ("\t");
-}out.append (seqs[i].getName ());
-out.append ("\t-1\t");
-out.append ("" + next[j].begin);
-out.append ("\t");
-out.append ("" + next[j].end);
-out.append ("\t");
-out.append (next[j].type);
-if (!Float.isNaN (next[j].score)) {
-out.append ("\t");
-out.append (next[j].score);
-}out.append (this.newline);
-}
-}}
-if (group != null) {
-out.append ("ENDGROUP\t");
-out.append (group);
-out.append (this.newline);
-groupIndex++;
-} else {
-break;
-}} while (groupIndex < groups.size () + 1);
-if (!featuresGen) {
-return "No Features Visible";
-}return out.toString ();
-}, "~A,java.util.Map,~B,~B");
-Clazz.defineMethod (c$, "printGFFFormat", 
-function (seqs, visible) {
-return this.printGFFFormat (seqs, visible, true, true);
-}, "~A,java.util.Map");
-Clazz.defineMethod (c$, "printGFFFormat", 
-function (seqs, visible, visOnly, nonpos) {
-var out =  new StringBuffer ();
-var next;
-var source;
-var isnonpos;
-for (var i = 0; i < seqs.length; i++) {
-if (seqs[i].getSequenceFeatures () != null) {
-next = seqs[i].getSequenceFeatures ();
-for (var j = 0; j < next.length; j++) {
-isnonpos = next[j].begin == 0 && next[j].end == 0;
-if ((!nonpos && isnonpos) || (!isnonpos && visOnly && !visible.containsKey (next[j].type))) {
-continue;
-}source = next[j].featureGroup;
-if (source == null) {
-source = next[j].getDescription ();
-}out.append (seqs[i].getName ());
-out.append ("\t");
-out.append (source);
-out.append ("\t");
-out.append (next[j].type);
-out.append ("\t");
-out.append ("" + next[j].begin);
-out.append ("\t");
-out.append ("" + next[j].end);
-out.append ("\t");
-out.append (next[j].score);
-out.append ("\t");
-if (next[j].getValue ("STRAND") != null) {
-out.append (next[j].getValue ("STRAND"));
-out.append ("\t");
-} else {
-out.append (".\t");
-}if (next[j].getValue ("FRAME") != null) {
-out.append (next[j].getValue ("FRAME"));
-} else {
-out.append (".");
-}if (next[j].getValue ("ATTRIBUTES") != null) {
-out.append (next[j].getValue ("ATTRIBUTES"));
-}out.append (this.newline);
-}
-}}
-return out.toString ();
-}, "~A,java.util.Map,~B,~B");
-Clazz.defineMethod (c$, "parse", 
-function () {
-});
-Clazz.overrideMethod (c$, "print", 
-function () {
-return "USE printGFFFormat() or printJalviewFormat()";
-});
-c$.$FeaturesFile$InvalidGFF3FieldException$ = function () {
-Clazz.pu$h ();
-c$ = Clazz.decorateAsClass (function () {
-Clazz.prepareCallback (this, arguments);
-this.field = null;
-this.value = null;
-Clazz.instantialize (this, arguments);
-}, jalview.io.FeaturesFile, "InvalidGFF3FieldException", Exception);
-Clazz.makeConstructor (c$, 
-function (a, b, c) {
-Clazz.superConstructor (this, jalview.io.FeaturesFile.InvalidGFF3FieldException, [c + " (Field was " + a + " and value was " + b.get (a).toString ()]);
-this.field = a;
-this.value = b.get (a).toString ();
-}, "~S,java.util.Map,~S");
-c$ = Clazz.p0p ();
-};
-Clazz.pu$h ();
-c$ = Clazz.declareType (jalview.io.FeaturesFile, "GffPragmas", Enum);
-Clazz.defineEnumConstant (c$, "gff_version", 0, []);
-Clazz.defineEnumConstant (c$, "sequence_region", 1, []);
-Clazz.defineEnumConstant (c$, "feature_ontology", 2, []);
-Clazz.defineEnumConstant (c$, "attribute_ontology", 3, []);
-Clazz.defineEnumConstant (c$, "source_ontology", 4, []);
-Clazz.defineEnumConstant (c$, "species_build", 5, []);
-Clazz.defineEnumConstant (c$, "fasta", 6, []);
-Clazz.defineEnumConstant (c$, "hash", 7, []);
-c$ = Clazz.p0p ();
-Clazz.defineStatics (c$,
-"GFFPRAGMA", null);
-{
-jalview.io.FeaturesFile.GFFPRAGMA =  new java.util.HashMap ();
-jalview.io.FeaturesFile.GFFPRAGMA.put ("sequence-region", jalview.io.FeaturesFile.GffPragmas.sequence_region);
-jalview.io.FeaturesFile.GFFPRAGMA.put ("feature-ontology", jalview.io.FeaturesFile.GffPragmas.feature_ontology);
-jalview.io.FeaturesFile.GFFPRAGMA.put ("#", jalview.io.FeaturesFile.GffPragmas.hash);
-jalview.io.FeaturesFile.GFFPRAGMA.put ("fasta", jalview.io.FeaturesFile.GffPragmas.fasta);
-jalview.io.FeaturesFile.GFFPRAGMA.put ("species-build", jalview.io.FeaturesFile.GffPragmas.species_build);
-jalview.io.FeaturesFile.GFFPRAGMA.put ("source-ontology", jalview.io.FeaturesFile.GffPragmas.source_ontology);
-jalview.io.FeaturesFile.GFFPRAGMA.put ("attribute-ontology", jalview.io.FeaturesFile.GffPragmas.attribute_ontology);
-}});
+Clazz.declarePackage ("jalview.io");\r
+Clazz.load (["jalview.io.AlignFile", "java.lang.Enum", "$.Exception"], "jalview.io.FeaturesFile", ["jalview.analysis.SequenceIdMatcher", "jalview.datamodel.AlignedCodonFrame", "$.SequenceDummy", "$.SequenceFeature", "jalview.jsdev.GenericFileAdapter", "jalview.schemes.GraduatedColor", "$.UserColourScheme", "jalview.util.Format", "$.MapList", "$.ParseHtmlBodyAndLinks", "java.awt.Color", "java.lang.Float", "$.StringBuffer", "java.util.ArrayList", "$.Arrays", "$.HashMap", "$.Hashtable", "$.StringTokenizer", "$.Vector"], function () {\r
+c$ = Clazz.decorateAsClass (function () {\r
+this.doGffSource = true;\r
+this.gffversion = 0;\r
+if (!Clazz.isClassDefined ("jalview.io.FeaturesFile.InvalidGFF3FieldException")) {\r
+jalview.io.FeaturesFile.$FeaturesFile$InvalidGFF3FieldException$ ();\r
+}\r
+this.lastmatchedAl = null;\r
+this.matcher = null;\r
+Clazz.instantialize (this, arguments);\r
+}, jalview.io, "FeaturesFile", jalview.io.AlignFile);\r
+Clazz.makeConstructor (c$, \r
+function () {\r
+Clazz.superConstructor (this, jalview.io.FeaturesFile, []);\r
+});\r
+Clazz.defineMethod (c$, "parse", \r
+function (align, colours, removeHTML) {\r
+return this.parse (align, colours, null, removeHTML, false);\r
+}, "jalview.datamodel.AlignmentI,java.util.Hashtable,~B");\r
+Clazz.defineMethod (c$, "parse", \r
+function (align, colours, removeHTML, relaxedIdMatching) {\r
+return this.parse (align, colours, null, removeHTML, relaxedIdMatching);\r
+}, "jalview.datamodel.AlignmentI,java.util.Map,~B,~B");\r
+Clazz.defineMethod (c$, "parse", \r
+function (align, colours, featureLink, removeHTML) {\r
+return this.parse (align, colours, featureLink, removeHTML, false);\r
+}, "jalview.datamodel.AlignmentI,java.util.Map,java.util.Map,~B");\r
+Clazz.defineMethod (c$, "parse", \r
+function (align, colours, featureLink, removeHTML, relaxedIdmatching) {\r
+var line = null;\r
+try {\r
+var seq = null;\r
+var newseqs =  new java.util.ArrayList ();\r
+var type;\r
+var desc;\r
+var token = null;\r
+var index;\r
+var start;\r
+var end;\r
+var score;\r
+var st;\r
+var sf;\r
+var featureGroup = null;\r
+var groupLink = null;\r
+var typeLink =  new java.util.Hashtable ();\r
+var GFFFile = true;\r
+var gffProps =  new java.util.HashMap ();\r
+while ((line = this.nextLine ()) != null) {\r
+if (line.startsWith ("#")) {\r
+if (line.startsWith ("##")) {\r
+this.processGffPragma (line, gffProps, align, newseqs);\r
+line = "";\r
+}continue;\r
+}st =  new java.util.StringTokenizer (line, "\t");\r
+if (st.countTokens () == 1) {\r
+if (line.trim ().equalsIgnoreCase ("GFF")) {\r
+GFFFile = true;\r
+continue;\r
+}}if (st.countTokens () > 1 && st.countTokens () < 4) {\r
+GFFFile = false;\r
+type = st.nextToken ();\r
+if (type.equalsIgnoreCase ("startgroup")) {\r
+featureGroup = st.nextToken ();\r
+if (st.hasMoreElements ()) {\r
+groupLink = st.nextToken ();\r
+featureLink.put (featureGroup, groupLink);\r
+}} else if (type.equalsIgnoreCase ("endgroup")) {\r
+st.nextToken ();\r
+featureGroup = null;\r
+groupLink = null;\r
+} else {\r
+var colour = null;\r
+var colscheme = st.nextToken ();\r
+if (colscheme.indexOf ("|") > -1 || colscheme.trim ().equalsIgnoreCase ("label")) {\r
+var gcol =  new java.util.StringTokenizer (colscheme, "|", true);\r
+var threshtype = -1;\r
+var min = 1.4E-45;\r
+var max = 3.4028235E38;\r
+var threshval = NaN;\r
+var labelCol = false;\r
+var mincol = gcol.nextToken ();\r
+if (mincol === "|") {\r
+System.err.println ("Expected either 'label' or a colour specification in the line: " + line);\r
+continue;\r
+}var maxcol = null;\r
+if (mincol.toLowerCase ().indexOf ("label") == 0) {\r
+labelCol = true;\r
+mincol = (gcol.hasMoreTokens () ? gcol.nextToken () : null);\r
+mincol = (gcol.hasMoreTokens () ? gcol.nextToken () : null);\r
+}var abso = null;\r
+var minval;\r
+var maxval;\r
+if (mincol != null) {\r
+if (mincol.equals ("|")) {\r
+mincol = "";\r
+} else {\r
+gcol.nextToken ();\r
+}maxcol = gcol.nextToken ();\r
+if (maxcol.equals ("|")) {\r
+maxcol = "";\r
+} else {\r
+gcol.nextToken ();\r
+}abso = gcol.nextToken ();\r
+gcol.nextToken ();\r
+if (abso.toLowerCase ().indexOf ("abso") != 0) {\r
+minval = abso;\r
+abso = null;\r
+} else {\r
+minval = gcol.nextToken ();\r
+gcol.nextToken ();\r
+}maxval = gcol.nextToken ();\r
+if (gcol.hasMoreTokens ()) {\r
+gcol.nextToken ();\r
+}try {\r
+if (minval.length > 0) {\r
+min =  new Float (minval).floatValue ();\r
+}} catch (e) {\r
+if (Clazz.exceptionOf (e, Exception)) {\r
+System.err.println ("Couldn't parse the minimum value for graduated colour for type (" + colscheme + ") - did you misspell 'auto' for the optional automatic colour switch ?");\r
+e.printStackTrace ();\r
+} else {\r
+throw e;\r
+}\r
+}\r
+try {\r
+if (maxval.length > 0) {\r
+max =  new Float (maxval).floatValue ();\r
+}} catch (e) {\r
+if (Clazz.exceptionOf (e, Exception)) {\r
+System.err.println ("Couldn't parse the maximum value for graduated colour for type (" + colscheme + ")");\r
+e.printStackTrace ();\r
+} else {\r
+throw e;\r
+}\r
+}\r
+} else {\r
+mincol = "FFFFFF";\r
+maxcol = "000000";\r
+}try {\r
+colour =  new jalview.schemes.GraduatedColor ( new jalview.schemes.UserColourScheme (mincol).findColour ('A'),  new jalview.schemes.UserColourScheme (maxcol).findColour ('A'), min, max);\r
+} catch (e) {\r
+if (Clazz.exceptionOf (e, Exception)) {\r
+System.err.println ("Couldn't parse the graduated colour scheme (" + colscheme + ")");\r
+e.printStackTrace ();\r
+} else {\r
+throw e;\r
+}\r
+}\r
+if (colour != null) {\r
+(colour).setColourByLabel (labelCol);\r
+(colour).setAutoScaled (abso == null);\r
+var ttype = null;\r
+var tval = null;\r
+if (gcol.hasMoreTokens ()) {\r
+ttype = gcol.nextToken ();\r
+if (ttype.toLowerCase ().startsWith ("below")) {\r
+(colour).setThreshType (0);\r
+} else if (ttype.toLowerCase ().startsWith ("above")) {\r
+(colour).setThreshType (1);\r
+} else {\r
+(colour).setThreshType (-1);\r
+if (!ttype.toLowerCase ().startsWith ("no")) {\r
+System.err.println ("Ignoring unrecognised threshold type : " + ttype);\r
+}}}if ((colour).getThreshType () != -1) {\r
+try {\r
+gcol.nextToken ();\r
+tval = gcol.nextToken ();\r
+(colour).setThresh ( new Float (tval).floatValue ());\r
+} catch (e) {\r
+if (Clazz.exceptionOf (e, Exception)) {\r
+System.err.println ("Couldn't parse threshold value as a float: (" + tval + ")");\r
+e.printStackTrace ();\r
+} else {\r
+throw e;\r
+}\r
+}\r
+}if (gcol.hasMoreTokens ()) {\r
+System.err.println ("Ignoring additional tokens in parameters in graduated colour specification\n");\r
+while (gcol.hasMoreTokens ()) {\r
+System.err.println ("|" + gcol.nextToken ());\r
+}\r
+System.err.println ("\n");\r
+}}} else {\r
+var ucs =  new jalview.schemes.UserColourScheme (colscheme);\r
+colour = ucs.findColour ('A');\r
+}if (colour != null) {\r
+colours.put (type, colour);\r
+}if (st.hasMoreElements ()) {\r
+var link = st.nextToken ();\r
+typeLink.put (type, link);\r
+if (featureLink == null) {\r
+featureLink =  new java.util.Hashtable ();\r
+}featureLink.put (type, link);\r
+}}continue;\r
+}var seqId = "";\r
+while (st.hasMoreElements ()) {\r
+if (GFFFile) {\r
+seqId = token = st.nextToken ();\r
+seq = this.findName (align, seqId, relaxedIdmatching, newseqs);\r
+if (seq != null) {\r
+desc = st.nextToken ();\r
+var group = null;\r
+if (this.doGffSource && desc.indexOf (' ') == -1) {\r
+group =  String.instantialize (desc);\r
+}type = st.nextToken ();\r
+try {\r
+var stt = st.nextToken ();\r
+if (stt.length == 0 || stt.equals ("-")) {\r
+start = 0;\r
+} else {\r
+start = Integer.parseInt (stt);\r
+}} catch (ex) {\r
+if (Clazz.exceptionOf (ex, NumberFormatException)) {\r
+start = 0;\r
+} else {\r
+throw ex;\r
+}\r
+}\r
+try {\r
+var stt = st.nextToken ();\r
+if (stt.length == 0 || stt.equals ("-")) {\r
+end = 0;\r
+} else {\r
+end = Integer.parseInt (stt);\r
+}} catch (ex) {\r
+if (Clazz.exceptionOf (ex, NumberFormatException)) {\r
+end = 0;\r
+} else {\r
+throw ex;\r
+}\r
+}\r
+if (end == 0) {\r
+start = 0;\r
+}try {\r
+score =  new Float (st.nextToken ()).floatValue ();\r
+} catch (ex) {\r
+if (Clazz.exceptionOf (ex, NumberFormatException)) {\r
+score = 0;\r
+} else {\r
+throw ex;\r
+}\r
+}\r
+sf =  new jalview.datamodel.SequenceFeature (type, desc, start, end, score, group);\r
+try {\r
+sf.setValue ("STRAND", st.nextToken ());\r
+sf.setValue ("FRAME", st.nextToken ());\r
+} catch (ex) {\r
+if (Clazz.exceptionOf (ex, Exception)) {\r
+} else {\r
+throw ex;\r
+}\r
+}\r
+if (st.hasMoreTokens ()) {\r
+var attributes =  new StringBuffer ();\r
+var sep = false;\r
+while (st.hasMoreTokens ()) {\r
+attributes.append ((sep ? "\t" : "") + st.nextElement ());\r
+sep = true;\r
+}\r
+sf.setValue ("ATTRIBUTES", attributes.toString ());\r
+}if (this.processOrAddSeqFeature (align, newseqs, seq, sf, GFFFile, relaxedIdmatching)) {\r
+while ((seq = align.findName (seq, seqId, true)) != null) {\r
+seq.addSequenceFeature ( new jalview.datamodel.SequenceFeature (sf));\r
+}\r
+}break;\r
+}}if (GFFFile && seq == null) {\r
+desc = token;\r
+} else {\r
+desc = st.nextToken ();\r
+}if (!st.hasMoreTokens ()) {\r
+System.err.println ("DEBUG: Run out of tokens when trying to identify the destination for the feature.. giving up.");\r
+return false;\r
+}token = st.nextToken ();\r
+if (!token.equals ("ID_NOT_SPECIFIED")) {\r
+seq = this.findName (align, seqId = token, relaxedIdmatching, null);\r
+st.nextToken ();\r
+} else {\r
+seqId = null;\r
+try {\r
+index = Integer.parseInt (st.nextToken ());\r
+seq = align.getSequenceAt (index);\r
+} catch (ex) {\r
+if (Clazz.exceptionOf (ex, NumberFormatException)) {\r
+seq = null;\r
+} else {\r
+throw ex;\r
+}\r
+}\r
+}if (seq == null) {\r
+System.out.println ("Sequence not found: " + line);\r
+break;\r
+}start = Integer.parseInt (st.nextToken ());\r
+end = Integer.parseInt (st.nextToken ());\r
+type = st.nextToken ();\r
+if (!colours.containsKey (type)) {\r
+var ucs =  new jalview.schemes.UserColourScheme (type);\r
+colours.put (type, ucs.findColour ('A'));\r
+}sf =  new jalview.datamodel.SequenceFeature (type, desc, "", start, end, featureGroup);\r
+if (st.hasMoreTokens ()) {\r
+try {\r
+score =  new Float (st.nextToken ()).floatValue ();\r
+} catch (ex) {\r
+if (Clazz.exceptionOf (ex, NumberFormatException)) {\r
+score = 0;\r
+} else {\r
+throw ex;\r
+}\r
+}\r
+sf.setScore (score);\r
+}if (groupLink != null && removeHTML) {\r
+sf.addLink (groupLink);\r
+sf.description += "%LINK%";\r
+}if (typeLink.containsKey (type) && removeHTML) {\r
+sf.addLink (typeLink.get (type).toString ());\r
+sf.description += "%LINK%";\r
+}this.parseDescriptionHTML (sf, removeHTML);\r
+seq.addSequenceFeature (sf);\r
+while (seqId != null && (seq = align.findName (seq, seqId, false)) != null) {\r
+seq.addSequenceFeature ( new jalview.datamodel.SequenceFeature (sf));\r
+}\r
+GFFFile = false;\r
+}\r
+}\r
+this.resetMatcher ();\r
+} catch (ex) {\r
+if (Clazz.exceptionOf (ex, Exception)) {\r
+this.warningMessage = ((this.warningMessage == null) ? "" : this.warningMessage) + "Parsing error at\n" + line;\r
+System.out.println ("Error parsing feature file: " + ex + "\n" + line);\r
+ex.printStackTrace (System.err);\r
+this.resetMatcher ();\r
+return false;\r
+} else {\r
+throw ex;\r
+}\r
+}\r
+return true;\r
+}, "jalview.datamodel.AlignmentI,java.util.Map,java.util.Map,~B,~B");\r
+Clazz.defineMethod (c$, "processGffPragma", \r
+($fz = function (line, gffProps, align, newseqs) {\r
+var spacepos = line.indexOf (' ');\r
+var pragma = spacepos == -1 ? line.substring (2).trim () : line.substring (2, spacepos);\r
+var gffpragma = jalview.io.FeaturesFile.GFFPRAGMA.get (pragma.toLowerCase ());\r
+if (gffpragma == null) {\r
+return;\r
+}switch (gffpragma) {\r
+case jalview.io.FeaturesFile.GffPragmas.gff_version:\r
+try {\r
+this.gffversion = Integer.parseInt (line.substring (spacepos + 1));\r
+} finally {\r
+}\r
+break;\r
+case jalview.io.FeaturesFile.GffPragmas.feature_ontology:\r
+break;\r
+case jalview.io.FeaturesFile.GffPragmas.attribute_ontology:\r
+break;\r
+case jalview.io.FeaturesFile.GffPragmas.source_ontology:\r
+break;\r
+case jalview.io.FeaturesFile.GffPragmas.species_build:\r
+break;\r
+case jalview.io.FeaturesFile.GffPragmas.hash:\r
+break;\r
+case jalview.io.FeaturesFile.GffPragmas.fasta:\r
+this.process_as_fasta (align, newseqs);\r
+break;\r
+default:\r
+System.err.println ("Ignoring unknown pragma:\n" + line);\r
+}\r
+}, $fz.isPrivate = true, $fz), "~S,java.util.Map,jalview.datamodel.AlignmentI,java.util.ArrayList");\r
+Clazz.defineMethod (c$, "process_as_fasta", \r
+($fz = function (align, newseqs) {\r
+try {\r
+this.mark ();\r
+} catch (q) {\r
+if (Clazz.exceptionOf (q, java.io.IOException)) {\r
+} else {\r
+throw q;\r
+}\r
+}\r
+var parser = jalview.jsdev.GenericFileAdapter.getFile ("FastaFile", []);\r
+var includedseqs = parser.getSeqs ();\r
+var smatcher =  new jalview.analysis.SequenceIdMatcher (newseqs);\r
+for (var p = 0, pSize = includedseqs.size (); p < pSize; p++) {\r
+var dummyseq = smatcher.findIdMatch (includedseqs.get (p));\r
+if (dummyseq != null) {\r
+var mseq = includedseqs.get (p);\r
+if (Clazz.instanceOf (dummyseq, jalview.datamodel.SequenceDummy)) {\r
+(dummyseq).become (mseq);\r
+includedseqs.set (p, dummyseq);\r
+}}}\r
+for (var seq, $seq = includedseqs.iterator (); $seq.hasNext () && ((seq = $seq.next ()) || true);) {\r
+align.addSequence (seq);\r
+}\r
+}, $fz.isPrivate = true, $fz), "jalview.datamodel.AlignmentI,java.util.List");\r
+Clazz.defineMethod (c$, "processOrAddSeqFeature", \r
+function (align, newseqs, seq, sf, gFFFile, relaxedIdMatching) {\r
+var attr = sf.getValue ("ATTRIBUTES");\r
+var add = true;\r
+if (gFFFile && attr != null) {\r
+var nattr = 8;\r
+for (var attset, $attset = 0, $$attset = attr.$plit ("\t"); $attset < $$attset.length && ((attset = $$attset[$attset]) || true); $attset++) {\r
+if (attset == null || attset.trim ().length == 0) {\r
+continue;\r
+}nattr++;\r
+var set =  new java.util.HashMap ();\r
+for (var pair, $pair = 0, $$pair = attset.trim ().$plit (";"); $pair < $$pair.length && ((pair = $$pair[$pair]) || true); $pair++) {\r
+pair = pair.trim ();\r
+if (pair.length == 0) {\r
+continue;\r
+}var eqpos = pair.indexOf ('=');\r
+var sppos = pair.indexOf (' ');\r
+var key = null;\r
+var value = null;\r
+if (sppos > -1 && (eqpos == -1 || sppos < eqpos)) {\r
+key = pair.substring (0, sppos);\r
+value = pair.substring (sppos + 1);\r
+} else {\r
+if (eqpos > -1 && (sppos == -1 || eqpos < sppos)) {\r
+key = pair.substring (0, eqpos);\r
+value = pair.substring (eqpos + 1);\r
+} else {\r
+key = pair;\r
+}}if (key != null) {\r
+var vals = set.get (key);\r
+if (vals == null) {\r
+vals =  new java.util.ArrayList ();\r
+set.put (key, vals);\r
+}if (value != null) {\r
+vals.add (value.trim ());\r
+}}}\r
+try {\r
+add = new Boolean (add & this.processGffKey (set, nattr, seq, sf, align, newseqs, relaxedIdMatching)).valueOf ();\r
+} catch (ivfe) {\r
+if (Clazz.exceptionOf (ivfe, jalview.io.FeaturesFile.InvalidGFF3FieldException)) {\r
+System.err.println (ivfe);\r
+} else {\r
+throw ivfe;\r
+}\r
+}\r
+}\r
+}if (add) {\r
+seq.addSequenceFeature (sf);\r
+}return add;\r
+}, "jalview.datamodel.AlignmentI,java.util.List,jalview.datamodel.SequenceI,jalview.datamodel.SequenceFeature,~B,~B");\r
+Clazz.defineMethod (c$, "processGffKey", \r
+function (set, nattr, seq, sf, align, newseqs, relaxedIdMatching) {\r
+var attr;\r
+if (sf.getType ().equals ("similarity")) {\r
+var strand = sf.getStrand ();\r
+var querySeq = this.findNames (align, newseqs, relaxedIdMatching, set.get (attr = "Query"));\r
+if (querySeq == null || querySeq.size () != 1) {\r
+throw Clazz.innerTypeInstance (jalview.io.FeaturesFile.InvalidGFF3FieldException, this, null, attr, set, "Expecting exactly one sequence in Query field (got " + set.get (attr) + ")");\r
+}if (set.containsKey (attr = "Align")) {\r
+var alco =  new jalview.datamodel.AlignedCodonFrame ();\r
+var codonmapping = this.constructCodonMappingFromAlign (set, attr, strand);\r
+alco.addMap (seq, querySeq.get (0), codonmapping);\r
+align.addCodonFrame (alco);\r
+return false;\r
+}}return true;\r
+}, "java.util.Map,~N,jalview.datamodel.SequenceI,jalview.datamodel.SequenceFeature,jalview.datamodel.AlignmentI,java.util.List,~B");\r
+Clazz.defineMethod (c$, "constructCodonMappingFromAlign", \r
+($fz = function (set, attr, strand) {\r
+if (strand == 0) {\r
+throw Clazz.innerTypeInstance (jalview.io.FeaturesFile.InvalidGFF3FieldException, this, null, attr, set, "Invalid strand for a codon mapping (cannot be 0)");\r
+}var fromrange =  new java.util.ArrayList ();\r
+var torange =  new java.util.ArrayList ();\r
+var lastppos = 0;\r
+var lastpframe = 0;\r
+for (var range, $range = set.get (attr).iterator (); $range.hasNext () && ((range = $range.next ()) || true);) {\r
+var ints =  new java.util.ArrayList ();\r
+var st =  new java.util.StringTokenizer (range, " ");\r
+while (st.hasMoreTokens ()) {\r
+var num = st.nextToken ();\r
+try {\r
+ints.add ( new Integer (num));\r
+} catch (nfe) {\r
+if (Clazz.exceptionOf (nfe, NumberFormatException)) {\r
+throw Clazz.innerTypeInstance (jalview.io.FeaturesFile.InvalidGFF3FieldException, this, null, attr, set, "Invalid number in field " + num);\r
+} else {\r
+throw nfe;\r
+}\r
+}\r
+}\r
+if (ints.size () != 3) {\r
+throw Clazz.innerTypeInstance (jalview.io.FeaturesFile.InvalidGFF3FieldException, this, null, attr, set, "Invalid number of fields for this attribute (" + ints.size () + ")");\r
+}fromrange.add ( new Integer (ints.get (0).intValue ()));\r
+fromrange.add ( new Integer (ints.get (0).intValue () + strand * ints.get (2).intValue ()));\r
+if (ints.get (1).equals (new Integer (lastppos)) && lastpframe > 0) {\r
+lastppos += (ints.get (2)).intValue () / 3;\r
+lastpframe = (ints.get (2)).intValue () % 3;\r
+torange.set (torange.size () - 1,  new Integer (lastppos));\r
+} else {\r
+torange.add (ints.get (1));\r
+lastppos = (ints.get (1)).intValue () + (ints.get (2)).intValue () / 3;\r
+lastpframe = (ints.get (2)).intValue () % 3;\r
+torange.add ( new Integer (lastppos));\r
+}}\r
+if (fromrange.size () % 2 == 1) {\r
+throw Clazz.innerTypeInstance (jalview.io.FeaturesFile.InvalidGFF3FieldException, this, null, attr, set, "Couldn't parse the DNA alignment range correctly");\r
+}if (torange.size () % 2 == 1) {\r
+throw Clazz.innerTypeInstance (jalview.io.FeaturesFile.InvalidGFF3FieldException, this, null, attr, set, "Couldn't parse the protein alignment range correctly");\r
+}var frommap =  Clazz.newIntArray (fromrange.size (), 0);\r
+var tomap =  Clazz.newIntArray (torange.size (), 0);\r
+var p = 0;\r
+for (var ip, $ip = fromrange.iterator (); $ip.hasNext () && ((ip = $ip.next ()) || true);) {\r
+frommap[p++] = ip.intValue ();\r
+}\r
+p = 0;\r
+for (var ip, $ip = torange.iterator (); $ip.hasNext () && ((ip = $ip.next ()) || true);) {\r
+tomap[p++] = ip.intValue ();\r
+}\r
+return  new jalview.util.MapList (frommap, tomap, 3, 1);\r
+}, $fz.isPrivate = true, $fz), "java.util.Map,~S,~N");\r
+Clazz.defineMethod (c$, "findNames", \r
+($fz = function (align, newseqs, relaxedIdMatching, list) {\r
+var found =  new java.util.ArrayList ();\r
+for (var seqId, $seqId = list.iterator (); $seqId.hasNext () && ((seqId = $seqId.next ()) || true);) {\r
+var seq = this.findName (align, seqId, relaxedIdMatching, newseqs);\r
+if (seq != null) {\r
+found.add (seq);\r
+}}\r
+return found;\r
+}, $fz.isPrivate = true, $fz), "jalview.datamodel.AlignmentI,java.util.List,~B,java.util.List");\r
+Clazz.defineMethod (c$, "resetMatcher", \r
+($fz = function () {\r
+this.lastmatchedAl = null;\r
+this.matcher = null;\r
+}, $fz.isPrivate = true, $fz));\r
+Clazz.defineMethod (c$, "findName", \r
+($fz = function (align, seqId, relaxedIdMatching, newseqs) {\r
+var match = null;\r
+if (relaxedIdMatching) {\r
+if (this.lastmatchedAl !== align) {\r
+this.matcher =  new jalview.analysis.SequenceIdMatcher ((this.lastmatchedAl = align).getSequencesArray ());\r
+if (newseqs != null) {\r
+this.matcher.addAll (newseqs);\r
+}}match = this.matcher.findIdMatch (seqId);\r
+} else {\r
+match = align.findName (seqId, true);\r
+if (match == null && newseqs != null) {\r
+for (var m, $m = newseqs.iterator (); $m.hasNext () && ((m = $m.next ()) || true);) {\r
+if (seqId.equals (m.getName ())) {\r
+return m;\r
+}}\r
+}}if (match == null && newseqs != null) {\r
+match =  new jalview.datamodel.SequenceDummy (seqId);\r
+if (relaxedIdMatching) {\r
+this.matcher.addAll (java.util.Arrays.asList ( Clazz.newArray (-1, [match])));\r
+}newseqs.add (match);\r
+}return match;\r
+}, $fz.isPrivate = true, $fz), "jalview.datamodel.AlignmentI,~S,~B,java.util.List");\r
+Clazz.defineMethod (c$, "parseDescriptionHTML", \r
+function (sf, removeHTML) {\r
+if (sf.getDescription () == null) {\r
+return;\r
+}var parsed =  new jalview.util.ParseHtmlBodyAndLinks (sf.getDescription (), removeHTML, this.newline);\r
+sf.description = (removeHTML) ? parsed.getNonHtmlContent () : sf.description;\r
+for (var link, $link = parsed.getLinks ().iterator (); $link.hasNext () && ((link = $link.next ()) || true);) {\r
+sf.addLink (link);\r
+}\r
+}, "jalview.datamodel.SequenceFeature,~B");\r
+Clazz.defineMethod (c$, "printJalviewFormat", \r
+function (seqs, visible) {\r
+return this.printJalviewFormat (seqs, visible, true, true);\r
+}, "~A,java.util.Map");\r
+Clazz.defineMethod (c$, "printJalviewFormat", \r
+function (seqs, visible, visOnly, nonpos) {\r
+var out =  new StringBuffer ();\r
+var next;\r
+var featuresGen = false;\r
+if (visOnly && !nonpos && (visible == null || visible.size () < 1)) {\r
+return "No Features Visible";\r
+}if (visible != null && visOnly) {\r
+var en = visible.keySet ().iterator ();\r
+var type;\r
+var color;\r
+while (en.hasNext ()) {\r
+type = en.next ().toString ();\r
+if (Clazz.instanceOf (visible.get (type), jalview.schemes.GraduatedColor)) {\r
+var gc = visible.get (type);\r
+color = (gc.isColourByLabel () ? "label|" : "") + jalview.util.Format.getHexString (gc.getMinColor ()) + "|" + jalview.util.Format.getHexString (gc.getMaxColor ()) + (gc.isAutoScale () ? "|" : "|abso|") + gc.getMin () + "|" + gc.getMax () + "|";\r
+if (gc.getThreshType () != -1) {\r
+if (gc.getThreshType () == 0) {\r
+color += "below";\r
+} else {\r
+if (gc.getThreshType () != 1) {\r
+System.err.println ("WARNING: Unsupported threshold type (" + gc.getThreshType () + ") : Assuming 'above'");\r
+}color += "above";\r
+}color += "|" + gc.getThresh ();\r
+} else {\r
+color += "none";\r
+}} else if (Clazz.instanceOf (visible.get (type), java.awt.Color)) {\r
+color = jalview.util.Format.getHexString (visible.get (type));\r
+} else {\r
+color = jalview.util.Format.getHexString ( new java.awt.Color (Integer.parseInt (visible.get (type).toString ())));\r
+}out.append (type);\r
+out.append ("\t");\r
+out.append (color);\r
+out.append (this.newline);\r
+}\r
+}var groups =  new java.util.Vector ();\r
+var groupIndex = 0;\r
+var isnonpos = false;\r
+for (var i = 0; i < seqs.length; i++) {\r
+next = seqs[i].getSequenceFeatures ();\r
+if (next != null) {\r
+for (var j = 0; j < next.length; j++) {\r
+isnonpos = next[j].begin == 0 && next[j].end == 0;\r
+if ((!nonpos && isnonpos) || (!isnonpos && visOnly && !visible.containsKey (next[j].type))) {\r
+continue;\r
+}if (next[j].featureGroup != null && !groups.contains (next[j].featureGroup)) {\r
+groups.addElement (next[j].featureGroup);\r
+}}\r
+}}\r
+var group = null;\r
+do {\r
+if (groups.size () > 0 && groupIndex < groups.size ()) {\r
+group = groups.elementAt (groupIndex).toString ();\r
+out.append (this.newline);\r
+out.append ("STARTGROUP\t");\r
+out.append (group);\r
+out.append (this.newline);\r
+} else {\r
+group = null;\r
+}for (var i = 0; i < seqs.length; i++) {\r
+next = seqs[i].getSequenceFeatures ();\r
+if (next != null) {\r
+for (var j = 0; j < next.length; j++) {\r
+isnonpos = next[j].begin == 0 && next[j].end == 0;\r
+if ((!nonpos && isnonpos) || (!isnonpos && visOnly && !visible.containsKey (next[j].type))) {\r
+continue;\r
+}if (group != null && (next[j].featureGroup == null || !next[j].featureGroup.equals (group))) {\r
+continue;\r
+}if (group == null && next[j].featureGroup != null) {\r
+continue;\r
+}featuresGen = true;\r
+if (next[j].description == null || next[j].description.equals ("")) {\r
+out.append (next[j].type + "\t");\r
+} else {\r
+if (next[j].links != null && next[j].getDescription ().indexOf ("<html>") == -1) {\r
+out.append ("<html>");\r
+}out.append (next[j].description + " ");\r
+if (next[j].links != null) {\r
+for (var l = 0; l < next[j].links.size (); l++) {\r
+var label = next[j].links.elementAt (l).toString ();\r
+var href = label.substring (label.indexOf ("|") + 1);\r
+label = label.substring (0, label.indexOf ("|"));\r
+if (next[j].description.indexOf (href) == -1) {\r
+out.append ("<a href=\"" + href + "\">" + label + "</a>");\r
+}}\r
+if (next[j].getDescription ().indexOf ("</html>") == -1) {\r
+out.append ("</html>");\r
+}}out.append ("\t");\r
+}out.append (seqs[i].getName ());\r
+out.append ("\t-1\t");\r
+out.append ("" + next[j].begin);\r
+out.append ("\t");\r
+out.append ("" + next[j].end);\r
+out.append ("\t");\r
+out.append (next[j].type);\r
+if (!Float.isNaN (next[j].score)) {\r
+out.append ("\t");\r
+out.append (next[j].score);\r
+}out.append (this.newline);\r
+}\r
+}}\r
+if (group != null) {\r
+out.append ("ENDGROUP\t");\r
+out.append (group);\r
+out.append (this.newline);\r
+groupIndex++;\r
+} else {\r
+break;\r
+}} while (groupIndex < groups.size () + 1);\r
+if (!featuresGen) {\r
+return "No Features Visible";\r
+}return out.toString ();\r
+}, "~A,java.util.Map,~B,~B");\r
+Clazz.defineMethod (c$, "printGFFFormat", \r
+function (seqs, visible) {\r
+return this.printGFFFormat (seqs, visible, true, true);\r
+}, "~A,java.util.Map");\r
+Clazz.defineMethod (c$, "printGFFFormat", \r
+function (seqs, visible, visOnly, nonpos) {\r
+var out =  new StringBuffer ();\r
+var next;\r
+var source;\r
+var isnonpos;\r
+for (var i = 0; i < seqs.length; i++) {\r
+if (seqs[i].getSequenceFeatures () != null) {\r
+next = seqs[i].getSequenceFeatures ();\r
+for (var j = 0; j < next.length; j++) {\r
+isnonpos = next[j].begin == 0 && next[j].end == 0;\r
+if ((!nonpos && isnonpos) || (!isnonpos && visOnly && !visible.containsKey (next[j].type))) {\r
+continue;\r
+}source = next[j].featureGroup;\r
+if (source == null) {\r
+source = next[j].getDescription ();\r
+}out.append (seqs[i].getName ());\r
+out.append ("\t");\r
+out.append (source);\r
+out.append ("\t");\r
+out.append (next[j].type);\r
+out.append ("\t");\r
+out.append ("" + next[j].begin);\r
+out.append ("\t");\r
+out.append ("" + next[j].end);\r
+out.append ("\t");\r
+out.append (next[j].score);\r
+out.append ("\t");\r
+if (next[j].getValue ("STRAND") != null) {\r
+out.append (next[j].getValue ("STRAND"));\r
+out.append ("\t");\r
+} else {\r
+out.append (".\t");\r
+}if (next[j].getValue ("FRAME") != null) {\r
+out.append (next[j].getValue ("FRAME"));\r
+} else {\r
+out.append (".");\r
+}if (next[j].getValue ("ATTRIBUTES") != null) {\r
+out.append (next[j].getValue ("ATTRIBUTES"));\r
+}out.append (this.newline);\r
+}\r
+}}\r
+return out.toString ();\r
+}, "~A,java.util.Map,~B,~B");\r
+Clazz.defineMethod (c$, "parse", \r
+function () {\r
+});\r
+Clazz.overrideMethod (c$, "print", \r
+function () {\r
+return "USE printGFFFormat() or printJalviewFormat()";\r
+});\r
+c$.$FeaturesFile$InvalidGFF3FieldException$ = function () {\r
+Clazz.pu$h ();\r
+c$ = Clazz.decorateAsClass (function () {\r
+Clazz.prepareCallback (this, arguments);\r
+this.field = null;\r
+this.value = null;\r
+Clazz.instantialize (this, arguments);\r
+}, jalview.io.FeaturesFile, "InvalidGFF3FieldException", Exception);\r
+Clazz.makeConstructor (c$, \r
+function (a, b, c) {\r
+Clazz.superConstructor (this, jalview.io.FeaturesFile.InvalidGFF3FieldException, [c + " (Field was " + a + " and value was " + b.get (a).toString ()]);\r
+this.field = a;\r
+this.value = b.get (a).toString ();\r
+}, "~S,java.util.Map,~S");\r
+c$ = Clazz.p0p ();\r
+};\r
+Clazz.pu$h ();\r
+c$ = Clazz.declareType (jalview.io.FeaturesFile, "GffPragmas", Enum);\r
+Clazz.defineEnumConstant (c$, "gff_version", 0, []);\r
+Clazz.defineEnumConstant (c$, "sequence_region", 1, []);\r
+Clazz.defineEnumConstant (c$, "feature_ontology", 2, []);\r
+Clazz.defineEnumConstant (c$, "attribute_ontology", 3, []);\r
+Clazz.defineEnumConstant (c$, "source_ontology", 4, []);\r
+Clazz.defineEnumConstant (c$, "species_build", 5, []);\r
+Clazz.defineEnumConstant (c$, "fasta", 6, []);\r
+Clazz.defineEnumConstant (c$, "hash", 7, []);\r
+c$ = Clazz.p0p ();\r
+Clazz.defineStatics (c$,\r
+"GFFPRAGMA", null);\r
+{\r
+jalview.io.FeaturesFile.GFFPRAGMA =  new java.util.HashMap ();\r
+jalview.io.FeaturesFile.GFFPRAGMA.put ("sequence-region", jalview.io.FeaturesFile.GffPragmas.sequence_region);\r
+jalview.io.FeaturesFile.GFFPRAGMA.put ("feature-ontology", jalview.io.FeaturesFile.GffPragmas.feature_ontology);\r
+jalview.io.FeaturesFile.GFFPRAGMA.put ("#", jalview.io.FeaturesFile.GffPragmas.hash);\r
+jalview.io.FeaturesFile.GFFPRAGMA.put ("fasta", jalview.io.FeaturesFile.GffPragmas.fasta);\r
+jalview.io.FeaturesFile.GFFPRAGMA.put ("species-build", jalview.io.FeaturesFile.GffPragmas.species_build);\r
+jalview.io.FeaturesFile.GFFPRAGMA.put ("source-ontology", jalview.io.FeaturesFile.GffPragmas.source_ontology);\r
+jalview.io.FeaturesFile.GFFPRAGMA.put ("attribute-ontology", jalview.io.FeaturesFile.GffPragmas.attribute_ontology);\r
+}});\r