X-Git-Url: http://source.jalview.org/gitweb/?p=jalviewjs.git;a=blobdiff_plain;f=bin%2Fjalview%2Fio%2FFeaturesFile.js;h=458787bd1732ff0ebca5c918ddec8745f669864c;hp=7bdc9f99953cf338976191af5b66ff67916a0290;hb=7301a2415adab88038b291fc54caeeb3a5a47a44;hpb=6154cb57a6eac3bb1344b8342495f5bb701ee921
diff --git a/bin/jalview/io/FeaturesFile.js b/bin/jalview/io/FeaturesFile.js
index 7bdc9f9..458787b 100644
--- a/bin/jalview/io/FeaturesFile.js
+++ b/bin/jalview/io/FeaturesFile.js
@@ -1,772 +1,772 @@
-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 ("") == -1) {
-out.append ("");
-}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 ("" + label + "");
-}}
-if (next[j].getDescription ().indexOf ("") == -1) {
-out.append ("");
-}}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");
+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 ("") == -1) {
+out.append ("");
+}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 ("" + label + "");
+}}
+if (next[j].getDescription ().indexOf ("") == -1) {
+out.append ("");
+}}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);
+}});